From bb2725f1bc604797b066eef9abbf8f5bf86971db Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Mon, 18 Mar 2024 14:43:56 +0100 Subject: [PATCH 001/704] Initial commit on orphan branch From 6553642d5d246b8708c09bbd3faa4db5313acaed Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Mon, 18 Mar 2024 15:09:17 +0100 Subject: [PATCH 002/704] Second initial commit. --- .gitignore | 0 LICENSE | 21 +++++++++++++++++++++ Makefile | 0 README.md | 13 +++++++++++++ include/edit.h | 3 +++ python/ext/wrapper.c | 36 ++++++++++++++++++++++++++++++++++++ python/include | 1 + python/setup.py | 18 ++++++++++++++++++ python/src | 1 + python/tests/test_edit.py | 3 +++ src/edit.c | 5 +++++ 11 files changed, 101 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 Makefile create mode 100644 README.md create mode 100644 include/edit.h create mode 100644 python/ext/wrapper.c create mode 120000 python/include create mode 100644 python/setup.py create mode 120000 python/src create mode 100644 python/tests/test_edit.py create mode 100644 src/edit.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..9adf916 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Leiden University Medical Center + +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. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..e69de29 diff --git a/README.md b/README.md new file mode 100644 index 0000000..61eb89f --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +mutalyzer-algebra +================= +A Boolean Algebra for Genetic Variants + +A set of Boolean relations: equivalence; containment, i.e., either a +variant is fully contained in another or a variant fully contains another; +overlap, i.e., two variants have (at least) one common element; and +disjoint, i.e., no common elements that allows for a comprehensive +classification of the relation for every pair of variants by taking all +minimal Longest Common Subsequence (LCS) alignments into account. + +[Jonathan K. Vis, Mark A. Santcroos, Walter A. Kosters and Jeroen F.J. Laros. +"A Boolean Algebra for Genetic Variants." In: *Bioinformatics* (2023).](https://doi.org/10.1093/bioinformatics/btad001) diff --git a/include/edit.h b/include/edit.h new file mode 100644 index 0000000..8cb577e --- /dev/null +++ b/include/edit.h @@ -0,0 +1,3 @@ +#include + +size_t varalg_edit(size_t const lhs, size_t const rhs); diff --git a/python/ext/wrapper.c b/python/ext/wrapper.c new file mode 100644 index 0000000..4742262 --- /dev/null +++ b/python/ext/wrapper.c @@ -0,0 +1,36 @@ +#define PY_SSIZE_T_CLEAN +#include + +#include "../include/edit.h" // varalg_edit + + +static PyObject* edit(PyObject *self, PyObject* args, PyObject * kwargs){ + (void) self; + size_t lhs = 0; + size_t rhs = 40; + static char const * keywords[] = {"lhs", "rhs", NULL}; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|i", (char **) keywords, &lhs, &rhs)){ + return NULL; + } + + return Py_BuildValue("i", varalg_edit(lhs, rhs)); +} + + +static PyMethodDef methods[] = { + {"edit", (PyCFunction)(void(*)(void)) edit, METH_VARARGS | METH_KEYWORDS, "Calculate edit distance"}, + {NULL, NULL, 0, NULL} +}; + + +static struct PyModuleDef algebra = { + .m_base = PyModuleDef_HEAD_INIT, + .m_name = "algebra", + .m_doc = "Variant Algebra", + .m_size = -1, + .m_methods = methods, +}; + +PyMODINIT_FUNC PyInit_algebra(void){ + return PyModule_Create(&algebra); +} diff --git a/python/include b/python/include new file mode 120000 index 0000000..f5030fe --- /dev/null +++ b/python/include @@ -0,0 +1 @@ +../include \ No newline at end of file diff --git a/python/setup.py b/python/setup.py new file mode 100644 index 0000000..e9f55d2 --- /dev/null +++ b/python/setup.py @@ -0,0 +1,18 @@ +from setuptools import setup, Extension + +setup( + name = 'variant-algebra', + ext_modules = [ + Extension('algebra', + sources = [ + 'src/edit.c', + 'ext/wrapper.c', + ], + extra_compile_args = [ + "-Wextra", + "-Wpedantic", + "-std=c11", + ], + ) + ], +) diff --git a/python/src b/python/src new file mode 120000 index 0000000..5cd551c --- /dev/null +++ b/python/src @@ -0,0 +1 @@ +../src \ No newline at end of file diff --git a/python/tests/test_edit.py b/python/tests/test_edit.py new file mode 100644 index 0000000..2d942fd --- /dev/null +++ b/python/tests/test_edit.py @@ -0,0 +1,3 @@ +from algebra import edit + +print(edit("aa")) diff --git a/src/edit.c b/src/edit.c new file mode 100644 index 0000000..d3786b5 --- /dev/null +++ b/src/edit.c @@ -0,0 +1,5 @@ +#include + +size_t varalg_edit(size_t const lhs, size_t const rhs) { + return lhs + rhs; +} From 7d20a9963f70ff81c7c7779861158bdcf9b29655 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 19 Mar 2024 15:15:42 +0100 Subject: [PATCH 003/704] POC submodule imports --- python/.gitignore | 3 +++ python/ext/wrapper.c | 63 ++++++++++++++++++++++++++++++++++++-------- python/setup.py | 9 ++++--- 3 files changed, 60 insertions(+), 15 deletions(-) create mode 100644 python/.gitignore diff --git a/python/.gitignore b/python/.gitignore new file mode 100644 index 0000000..604f7d8 --- /dev/null +++ b/python/.gitignore @@ -0,0 +1,3 @@ +*.egg-info/ +build/ +venv/ diff --git a/python/ext/wrapper.c b/python/ext/wrapper.c index 4742262..450bf9f 100644 --- a/python/ext/wrapper.c +++ b/python/ext/wrapper.c @@ -1,29 +1,36 @@ #define PY_SSIZE_T_CLEAN #include +#include // NULL, size_t + #include "../include/edit.h" // varalg_edit -static PyObject* edit(PyObject *self, PyObject* args, PyObject * kwargs){ +static PyObject* +edit(PyObject* self, PyObject* args, PyObject* kwargs) +{ (void) self; + size_t lhs = 0; size_t rhs = 40; - static char const * keywords[] = {"lhs", "rhs", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|i", (char **) keywords, &lhs, &rhs)){ + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|i", (char*[3]) {"lhs", "rhs", NULL}, &lhs, &rhs)) + { return NULL; - } + } // if return Py_BuildValue("i", varalg_edit(lhs, rhs)); -} +} // edit -static PyMethodDef methods[] = { - {"edit", (PyCFunction)(void(*)(void)) edit, METH_VARARGS | METH_KEYWORDS, "Calculate edit distance"}, +static PyMethodDef methods[] = +{ + {"edit", (PyCFunction) (void(*)(void)) edit, METH_VARARGS | METH_KEYWORDS, "Calculate edit distance"}, {NULL, NULL, 0, NULL} }; -static struct PyModuleDef algebra = { +static struct PyModuleDef algebra = +{ .m_base = PyModuleDef_HEAD_INIT, .m_name = "algebra", .m_doc = "Variant Algebra", @@ -31,6 +38,40 @@ static struct PyModuleDef algebra = { .m_methods = methods, }; -PyMODINIT_FUNC PyInit_algebra(void){ - return PyModule_Create(&algebra); -} + +static struct PyModuleDef lcs = +{ + .m_base = PyModuleDef_HEAD_INIT, + .m_name = "algebra.lcs", + .m_doc = "LCS", + .m_size = -1, + .m_methods = methods, +}; + + +PyMODINIT_FUNC +PyInit_algebra(void) +{ + PyObject* algebra_module = PyModule_Create(&algebra); + if (algebra_module == NULL) + { + PyErr_SetString(PyExc_ImportError, ""); + return NULL; + } // if + + PyObject* lcs_module = PyModule_Create(&lcs); + if (lcs_module == NULL) + { + PyErr_SetString(PyExc_ImportError, ""); + return NULL; + } // if + + PyDict_SetItemString(PyImport_GetModuleDict(), lcs.m_name, lcs_module); + if (PyModule_AddObject(algebra_module, "lcs", lcs_module) < 0) + { + PyErr_SetString(PyExc_ImportError, ""); + return NULL; + } // if + + return algebra_module; +} // PyInit_algebra diff --git a/python/setup.py b/python/setup.py index e9f55d2..0a0d83a 100644 --- a/python/setup.py +++ b/python/setup.py @@ -1,12 +1,13 @@ from setuptools import setup, Extension + setup( - name = 'variant-algebra', + name = "algebra", ext_modules = [ - Extension('algebra', + Extension("algebra", sources = [ - 'src/edit.c', - 'ext/wrapper.c', + "src/edit.c", + "ext/wrapper.c", ], extra_compile_args = [ "-Wextra", From 0ea3189485a99ee5b7724738d8510db4d07e6614 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 19 Mar 2024 15:33:35 +0100 Subject: [PATCH 004/704] Pytest --- python/.gitignore | 1 + python/tests/test_edit.py | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/python/.gitignore b/python/.gitignore index 604f7d8..5b692d3 100644 --- a/python/.gitignore +++ b/python/.gitignore @@ -1,3 +1,4 @@ +__pycache__/ *.egg-info/ build/ venv/ diff --git a/python/tests/test_edit.py b/python/tests/test_edit.py index 2d942fd..8100e1c 100644 --- a/python/tests/test_edit.py +++ b/python/tests/test_edit.py @@ -1,3 +1,5 @@ -from algebra import edit +from algebra.lcs import edit -print(edit("aa")) + +def test_edit(): + assert edit(4, 5) == 9 From aaddfc74d5e7fd35b10f10c7562878f2c9de8530 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 19 Mar 2024 16:55:02 +0100 Subject: [PATCH 005/704] C style and include guards --- include/edit.h | 20 +++++++++++++++++++- python/ext/wrapper.c | 2 +- src/edit.c | 11 ++++++++--- 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/include/edit.h b/include/edit.h index 8cb577e..f64f3d3 100644 --- a/include/edit.h +++ b/include/edit.h @@ -1,3 +1,21 @@ +#ifndef VARALG_EDIT_H +#define VARALG_EDIT_H + +#ifdef __cplusplus +extern "C" +{ +#endif + + #include -size_t varalg_edit(size_t const lhs, size_t const rhs); + +size_t +varalg_edit(size_t const lhs, size_t const rhs); + + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif diff --git a/python/ext/wrapper.c b/python/ext/wrapper.c index 450bf9f..a2fc402 100644 --- a/python/ext/wrapper.c +++ b/python/ext/wrapper.c @@ -3,7 +3,7 @@ #include // NULL, size_t -#include "../include/edit.h" // varalg_edit +#include "../include/edit.h" // varalg_edit static PyObject* diff --git a/src/edit.c b/src/edit.c index d3786b5..2a690da 100644 --- a/src/edit.c +++ b/src/edit.c @@ -1,5 +1,10 @@ -#include +#include // size_t -size_t varalg_edit(size_t const lhs, size_t const rhs) { +#include "../include/edit.h" // varalg_edit + + +size_t +varalg_edit(size_t const lhs, size_t const rhs) +{ return lhs + rhs; -} +} // varalg_edit From 15afb6b00194ad5c36aa1b56f2e4d3e6396b020c Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 19 Mar 2024 16:55:50 +0100 Subject: [PATCH 006/704] Javascript/wasm exports --- js/.gitignore | 1 + js/Makefile | 9 +++ js/algebra.js | 16 ++++++ js/http_server.py | 29 ++++++++++ js/index.html | 12 ++++ js/main.js | 4 ++ js/wasm.h | 55 ++++++++++++++++++ js/wasm.js | 144 ++++++++++++++++++++++++++++++++++++++++++++++ js/wrapper.c | 15 +++++ 9 files changed, 285 insertions(+) create mode 100644 js/.gitignore create mode 100644 js/Makefile create mode 100644 js/algebra.js create mode 100644 js/http_server.py create mode 100644 js/index.html create mode 100644 js/main.js create mode 100644 js/wasm.h create mode 100644 js/wasm.js create mode 100644 js/wrapper.c diff --git a/js/.gitignore b/js/.gitignore new file mode 100644 index 0000000..19e1bce --- /dev/null +++ b/js/.gitignore @@ -0,0 +1 @@ +*.wasm diff --git a/js/Makefile b/js/Makefile new file mode 100644 index 0000000..39322cd --- /dev/null +++ b/js/Makefile @@ -0,0 +1,9 @@ +CC = clang + +CFLAGS = -std=c99 -Wall -Wextra -Wpedantic -O3 \ + --target=wasm32 -nostdlib \ + -Wl,--no-entry, -Wl,--allow-undefined, -Wl,--import-memory, \ + -Wl,--export=__heap_base + +algebra.wasm: wrapper.c wasm.h Makefile + $(CC) $(CFLAGS) -o $@ ../src/edit.c $< diff --git a/js/algebra.js b/js/algebra.js new file mode 100644 index 0000000..49013f8 --- /dev/null +++ b/js/algebra.js @@ -0,0 +1,16 @@ +import { wasmInstance } from "./wasm.js"; + + +export const algebra = {}; + + +await wasmInstance("./algebra.wasm").then(wasm => { + algebra.edit = function(lhs, rhs) { + return wasm.exports.edit(lhs, rhs ?? 42); + }, +}); + + + + + diff --git a/js/http_server.py b/js/http_server.py new file mode 100644 index 0000000..b101866 --- /dev/null +++ b/js/http_server.py @@ -0,0 +1,29 @@ +from http.server import SimpleHTTPRequestHandler +from socketserver import TCPServer +import sys + + +def main(): + class HttpRequestHandler(SimpleHTTPRequestHandler): + extensions_map = { + "" : "application/octet-stream", + ".html": "text/html", + ".js" : "application/x-javascript", + ".wasm": "application/wasm", + } + + port = 8000 + if len(sys.argv) > 1: + port = int(sys.argv[1]) + + with TCPServer(("localhost", port), HttpRequestHandler) as httpd: + server_ip, server_port = httpd.server_address + print(f"Serving HTTP on {server_ip} port {server_port} (http://{server_ip}:{server_port}/) ...", file=sys.stderr) + try: + httpd.serve_forever() + except KeyboardInterrupt: + print("Keyboard interrupt received, exiting.", file=sys.stderr) + + +if __name__ == "__main__": + main() diff --git a/js/index.html b/js/index.html new file mode 100644 index 0000000..773e4ab --- /dev/null +++ b/js/index.html @@ -0,0 +1,12 @@ + + + + + + WASM sandbox + + + + + + diff --git a/js/main.js b/js/main.js new file mode 100644 index 0000000..0c83e8c --- /dev/null +++ b/js/main.js @@ -0,0 +1,4 @@ +import { algebra } from "./algebra.js"; + + +console.log(algebra.edit(4)); diff --git a/js/wasm.h b/js/wasm.h new file mode 100644 index 0000000..ca073ed --- /dev/null +++ b/js/wasm.h @@ -0,0 +1,55 @@ +#ifndef WASM_H +#define WASM_H + + +#include // size_t + + +#define WASM_EXPORT(name) __attribute__((export_name(name))) + + +extern void console_log(size_t, char const*); + +extern void free(void*); +extern void* malloc(size_t); + + +WASM_EXPORT("__word_size") +size_t +__word_size(void) +{ + return sizeof(size_t); +} // __word_size + + +void* +calloc(size_t count, size_t size) +{ + return malloc(count * size); +} // calloc + + +__attribute__((noinline)) +void* +realloc(void* ptr, size_t size) +{ + free(ptr); + return malloc(size); +} // realloc + + +void* +memcpy(void* dest, void const* src, size_t n) +{ + char* bdest = dest; + char const* bsrc = src; + + for (size_t i = 0; i < n; ++i) + { + bdest[i] = bsrc[i]; + } // for + return dest; +} // memcpy + + +#endif diff --git a/js/wasm.js b/js/wasm.js new file mode 100644 index 0000000..4af1123 --- /dev/null +++ b/js/wasm.js @@ -0,0 +1,144 @@ +export function wasmInstance(path, initial_pages=2) { + const utf8decoder = new TextDecoder(); + let heap_blocks; + + const imports = { env : { + memory: new WebAssembly.Memory({ + initial: initial_pages, + }), + + console_log: function(len, msg) { + if (len === 0) { + console.log(msg); + return; + } // if + console.log(utf8decoder.decode(new Uint8Array(imports.env.memory.buffer, msg, len))); + }, + + free: function(address) { + console.groupCollapsed(`free(0x${address.toString(16)})`); + if (address === null || address === 0) { + console.log("freeing null"); + console.groupEnd(); + return; + } // if + const len = heap_blocks.length; + for (let idx = 0; idx < len; ++idx) { + let heap_block = heap_blocks[idx]; + if (heap_block.address === address) { + console.log(`found heap block ${idx}`); + if (heap_block.free) { + console.warn(`double free at 0x${address.toString(16)}`); + console.groupEnd(); + return; + } // if + heap_block.free = true; + if (idx > 0 && heap_blocks[idx - 1].free) { + console.log(`coalesce with heap block ${idx - 1}`); + heap_blocks[idx - 1].size += heap_block.size; + heap_blocks.splice(idx, 1); + idx -= 1; + heap_block = heap_blocks[idx]; + } // if + if (idx < len - 1 && heap_blocks[idx + 1].free) { + console.log(`coalesce with heap block ${idx + 1}`); + heap_blocks[idx + 1].address = heap_block.address; + heap_blocks[idx + 1].size += heap_block.size; + heap_blocks.splice(idx, 1); + } // if + console.log("heap_blocks:", JSON.parse(JSON.stringify(heap_blocks))); + console.groupEnd(); + return; + } // if + } // for + console.warn(`illegal free at 0x${address.toString(16)}`); + console.groupEnd(); + }, + + malloc: function(size) { + console.groupCollapsed(`malloc(${size})`); + if (size <= 0) { + console.warn("invalid size"); + console.groupEnd(); + return null; + } // if + const word_size = imports.env.word_size; + if (size % word_size > 0) { + size += word_size - size % word_size; + } // if + console.log(`for ${word_size}-byte aligned ${size} bytes`); + const len = heap_blocks.length; + for (let idx = 0; idx < len; ++idx) { + const heap_block = heap_blocks[idx]; + const diff = heap_block.size - size; + if (heap_block.free && diff >= 0) { + console.log(`found suitable heap block ${idx}`); + heap_block.free = false; + const fragment_size = 0; + if (diff > fragment_size) { + console.log(`splitting ${size} bytes from heap block ${idx}`); + heap_block.size = size; + heap_blocks.splice(idx + 1, 0, { + address: heap_block.address + size, + size: diff, + free: true, + }); + } // if + console.log("heap blocks:", JSON.parse(JSON.stringify(heap_blocks))); + console.log(`address: 0x${heap_block.address.toString(16)}`); + console.groupEnd(); + return heap_block.address; + } // if + } // for + const page_size = 1 << 16; + const pages = Math.floor(size / page_size + 1); + console.log(`grow memory with ${pages} 16KiB pages`); + const memory = imports.env.memory; + try { + memory.grow(pages); + } // try + catch(error) { + console.warn("out of memory"); + console.groupEnd(); + return null; + } // catch + const buffer = memory.buffer; + const buffer_size = buffer.byteLength; + memory.words = new Uint32Array(buffer, 0, buffer_size / env.word_size); + memory.bytes = new Uint8Array(buffer, 0, buffer_size); + console.log(`total memory: ${memory.buffer.byteLength / (1024 * 1024)} MiB`); + const heap_block = heap_blocks[heap_blocks.length - 1]; + heap_blocks.push({ + address: heap_block.address + heap_block.size, + size: pages * page_size, + free: true, + }); + console.log("heap blocks:", JSON.parse(JSON.stringify(heap_blocks))); + console.groupEnd(); + return imports.env.malloc(size); + }, + }}; // imports + + return WebAssembly.instantiateStreaming(fetch(path), imports).then(obj => { + const env = imports.env; + const memory = env.memory; + const buffer = memory.buffer; + const buffer_size = buffer.byteLength; + const exports = obj.instance.exports; + const word_size = env.word_size = exports.__word_size(); + const heap_base = exports.__heap_base; + console.assert(word_size === 4); // For now we assume wasm32 + console.assert(heap_base % word_size === 0); + heap_blocks = [{ + address: heap_base.value, + size: buffer_size - heap_base, + free: true, + }]; + memory.words = new Uint32Array(buffer, 0, buffer_size / word_size); + memory.bytes = new Uint8Array(buffer, 0, buffer_size); + return { + env: env, + exports: exports, + }; + }); +} // wasmInstance diff --git a/js/wrapper.c b/js/wrapper.c new file mode 100644 index 0000000..9aaccf7 --- /dev/null +++ b/js/wrapper.c @@ -0,0 +1,15 @@ +#include // NULL, size_t + +#include "wasm.h" // WASM_EXPORT + +#include "../include/edit.h" // varalg_edit + + +WASM_EXPORT("edit") +size_t +edit_wrap(size_t const lhs, size_t const rhs) +{ + console_log(13, "Hello, World!"); + + return varalg_edit(lhs, rhs); +} // edit_wrap From 73627177b8e3a2b2467a34b45201e00d66766d42 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 19 Mar 2024 16:58:25 +0100 Subject: [PATCH 007/704] Submodules --- js/algebra.js | 8 +++++--- js/main.js | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/js/algebra.js b/js/algebra.js index 49013f8..8726dd5 100644 --- a/js/algebra.js +++ b/js/algebra.js @@ -5,9 +5,11 @@ export const algebra = {}; await wasmInstance("./algebra.wasm").then(wasm => { - algebra.edit = function(lhs, rhs) { - return wasm.exports.edit(lhs, rhs ?? 42); - }, + algebra.lcs = { + edit: function(lhs, rhs) { + return wasm.exports.edit(lhs, rhs ?? 42); + }, + }; }); diff --git a/js/main.js b/js/main.js index 0c83e8c..70ce01d 100644 --- a/js/main.js +++ b/js/main.js @@ -1,4 +1,4 @@ import { algebra } from "./algebra.js"; -console.log(algebra.edit(4)); +console.log(algebra.lcs.edit(4)); From 4d93fa0d37cbeee2247ea273c85f81218c89ef60 Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 20 Mar 2024 08:32:21 +0100 Subject: [PATCH 008/704] No favicon 404s --- js/index.html | 17 ++++++++--------- js/wrapper.c | 1 - 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/js/index.html b/js/index.html index 773e4ab..a0b01e1 100644 --- a/js/index.html +++ b/js/index.html @@ -1,12 +1,11 @@ - - - - WASM sandbox - - - - - + + + +WASM Algebra sandbox + + + + diff --git a/js/wrapper.c b/js/wrapper.c index 9aaccf7..876ad20 100644 --- a/js/wrapper.c +++ b/js/wrapper.c @@ -1,7 +1,6 @@ #include // NULL, size_t #include "wasm.h" // WASM_EXPORT - #include "../include/edit.h" // varalg_edit From 599e0c7b186bcf2bb377eb04a7bcdd4bd9ab8c1d Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 21 Mar 2024 10:57:23 +0100 Subject: [PATCH 009/704] Python packaging with C extentions --- python/README.md | 0 python/algebra/__init__.py | 4 ++ python/algebra/__main__.py | 13 ++++++ python/algebra/lcs/__init__.py | 4 ++ python/ext/algebra_ext.c | 40 ++++++++++++++++++ python/ext/lcs_ext.c | 44 +++++++++++++++++++ python/ext/wrapper.c | 77 ---------------------------------- python/setup.cfg | 24 +++++++++++ python/setup.py | 24 +++++------ 9 files changed, 140 insertions(+), 90 deletions(-) create mode 100644 python/README.md create mode 100644 python/algebra/__init__.py create mode 100644 python/algebra/__main__.py create mode 100644 python/algebra/lcs/__init__.py create mode 100644 python/ext/algebra_ext.c create mode 100644 python/ext/lcs_ext.c delete mode 100644 python/ext/wrapper.c create mode 100644 python/setup.cfg diff --git a/python/README.md b/python/README.md new file mode 100644 index 0000000..e69de29 diff --git a/python/algebra/__init__.py b/python/algebra/__init__.py new file mode 100644 index 0000000..f2919ce --- /dev/null +++ b/python/algebra/__init__.py @@ -0,0 +1,4 @@ +"""A Boolean Algebra for Genetic Variants.""" + + +from algebra_ext import hello diff --git a/python/algebra/__main__.py b/python/algebra/__main__.py new file mode 100644 index 0000000..58313a2 --- /dev/null +++ b/python/algebra/__main__.py @@ -0,0 +1,13 @@ +"""Entry point for the Algebra package. + +Provides a command-line interface to interact with sequences and variants +to determine their relations. +""" + + +def main(): + pass + + +if __name__ == "__main__": + main() diff --git a/python/algebra/lcs/__init__.py b/python/algebra/lcs/__init__.py new file mode 100644 index 0000000..7650271 --- /dev/null +++ b/python/algebra/lcs/__init__.py @@ -0,0 +1,4 @@ +"""Longest Common Subsequence alignments.""" + + +from lcs_ext import edit diff --git a/python/ext/algebra_ext.c b/python/ext/algebra_ext.c new file mode 100644 index 0000000..be11d63 --- /dev/null +++ b/python/ext/algebra_ext.c @@ -0,0 +1,40 @@ +#define PY_SSIZE_T_CLEAN +#include // Py* + +#include // NULL, size_t + + +static PyObject* +hello(PyObject* self, PyObject* args, PyObject* kwargs) +{ + (void) self; + + size_t lhs = 0; + size_t rhs = 40; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|i:hello", (char*[3]) {"lhs", "rhs", NULL}, &lhs, &rhs)) + { + return NULL; + } // if + + return Py_BuildValue("i", lhs * rhs); +} // hello + + +static struct PyModuleDef def = +{ + .m_base = PyModuleDef_HEAD_INIT, + .m_name = "algebra_ext", + .m_doc = "Algebra C extension", + .m_size = -1, + .m_methods = (PyMethodDef[]) { + {"hello", (PyCFunction) (void(*)(void)) hello, METH_VARARGS | METH_KEYWORDS, "Hello from parent"}, + {NULL, NULL, 0, NULL} + }, +}; + + +PyMODINIT_FUNC +PyInit_algebra_ext(void) +{ + return PyModule_Create(&def); +} // PyInit_algebra_ext diff --git a/python/ext/lcs_ext.c b/python/ext/lcs_ext.c new file mode 100644 index 0000000..8231655 --- /dev/null +++ b/python/ext/lcs_ext.c @@ -0,0 +1,44 @@ +#define PY_SSIZE_T_CLEAN +#include // Py* + +#include // NULL, size_t + +#include "../include/edit.h" // varalg_edit + + +static PyObject* +edit(PyObject* self, PyObject* args, PyObject* kwargs) +{ + (void) self; + + size_t lhs = 0; + size_t rhs = 40; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|i:edit", (char*[3]) {"lhs", "rhs", NULL}, &lhs, &rhs)) + { + return NULL; + } // if + + return Py_BuildValue("i", varalg_edit(lhs, rhs)); +} // edit + + +static PyModuleDef def = +{ + .m_base = PyModuleDef_HEAD_INIT, + .m_name = "lcs_ext", + .m_doc = "LCS C extension", + .m_size = -1, + .m_methods = (PyMethodDef[]) + { + {"edit", (PyCFunction) (void(*)(void)) edit, METH_VARARGS | METH_KEYWORDS, "Calculate the simple edit distance between two strings."}, + {NULL, NULL, 0, NULL} + }, +}; + + +PyMODINIT_FUNC +PyInit_lcs_ext(void) +{ + + return PyModule_Create(&def); +} // PyInit_lcs_ext diff --git a/python/ext/wrapper.c b/python/ext/wrapper.c deleted file mode 100644 index a2fc402..0000000 --- a/python/ext/wrapper.c +++ /dev/null @@ -1,77 +0,0 @@ -#define PY_SSIZE_T_CLEAN -#include - -#include // NULL, size_t - -#include "../include/edit.h" // varalg_edit - - -static PyObject* -edit(PyObject* self, PyObject* args, PyObject* kwargs) -{ - (void) self; - - size_t lhs = 0; - size_t rhs = 40; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|i", (char*[3]) {"lhs", "rhs", NULL}, &lhs, &rhs)) - { - return NULL; - } // if - - return Py_BuildValue("i", varalg_edit(lhs, rhs)); -} // edit - - -static PyMethodDef methods[] = -{ - {"edit", (PyCFunction) (void(*)(void)) edit, METH_VARARGS | METH_KEYWORDS, "Calculate edit distance"}, - {NULL, NULL, 0, NULL} -}; - - -static struct PyModuleDef algebra = -{ - .m_base = PyModuleDef_HEAD_INIT, - .m_name = "algebra", - .m_doc = "Variant Algebra", - .m_size = -1, - .m_methods = methods, -}; - - -static struct PyModuleDef lcs = -{ - .m_base = PyModuleDef_HEAD_INIT, - .m_name = "algebra.lcs", - .m_doc = "LCS", - .m_size = -1, - .m_methods = methods, -}; - - -PyMODINIT_FUNC -PyInit_algebra(void) -{ - PyObject* algebra_module = PyModule_Create(&algebra); - if (algebra_module == NULL) - { - PyErr_SetString(PyExc_ImportError, ""); - return NULL; - } // if - - PyObject* lcs_module = PyModule_Create(&lcs); - if (lcs_module == NULL) - { - PyErr_SetString(PyExc_ImportError, ""); - return NULL; - } // if - - PyDict_SetItemString(PyImport_GetModuleDict(), lcs.m_name, lcs_module); - if (PyModule_AddObject(algebra_module, "lcs", lcs_module) < 0) - { - PyErr_SetString(PyExc_ImportError, ""); - return NULL; - } // if - - return algebra_module; -} // PyInit_algebra diff --git a/python/setup.cfg b/python/setup.cfg new file mode 100644 index 0000000..b43f4b1 --- /dev/null +++ b/python/setup.cfg @@ -0,0 +1,24 @@ +[metadata] +name = mutalyzer-algebra +version = 2.0.0 +description = A Boolean Algebra for Genetic Variants +long_description = file: README.md +long_description_content_type = text/markdown +author = Mark A. Santcroos, Jonathan K. Vis +author_email = m.a.santcroos@lumc.nl, j.k.vis@lumc.nl +url = https://github.com/mutalyzer/algebra +keywords = algebra, genomics, graph, string, genetics, extractor, edit-distance, dna, variants, alignment, compare, sequence, lcs, relations, hgvs +license = MIT +classifiers = + Intended Audience :: Science/Research + Intended Audience :: Developers + Operating System :: OS Independent + Programming Language :: Python :: 3 + Topic :: Scientific/Engineering :: Bio-Informatics + +[options] +packages = find: + +[options.entry_points] +console_scripts = + algebra = algebra.__main__:main diff --git a/python/setup.py b/python/setup.py index 0a0d83a..68dac53 100644 --- a/python/setup.py +++ b/python/setup.py @@ -1,19 +1,17 @@ -from setuptools import setup, Extension +from setuptools import Extension, setup setup( - name = "algebra", ext_modules = [ - Extension("algebra", - sources = [ - "src/edit.c", - "ext/wrapper.c", - ], - extra_compile_args = [ - "-Wextra", - "-Wpedantic", - "-std=c11", - ], - ) + Extension("algebra_ext", + sources=[ + "ext/algebra_ext.c" + ], + ), + Extension("lcs_ext", + sources=[ + "ext/lcs_ext.c", "src/edit.c" + ], + ), ], ) From 88fd99d343cadf49c73899fac50d223ef0a56742 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 21 Mar 2024 11:02:20 +0100 Subject: [PATCH 010/704] Compile args --- python/setup.py | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/python/setup.py b/python/setup.py index 68dac53..11385f2 100644 --- a/python/setup.py +++ b/python/setup.py @@ -1,17 +1,23 @@ from setuptools import Extension, setup +compile_args = [ + "-Wextra", + "-Wpedantic", + "-std=c99", +] + + setup( ext_modules = [ - Extension("algebra_ext", + Extension("algebra_ext", extra_compile_args=compile_args, sources=[ "ext/algebra_ext.c" - ], - ), - Extension("lcs_ext", + ]), + Extension("lcs_ext", extra_compile_args=compile_args, sources=[ - "ext/lcs_ext.c", "src/edit.c" - ], - ), + "ext/lcs_ext.c", + "src/edit.c" + ]), ], ) From 2158a79a59a15c42e6fa9a18bf72edde222c1552 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 21 Mar 2024 16:30:37 +0100 Subject: [PATCH 011/704] Javascript modules --- {js => javascript}/.gitignore | 0 {js => javascript}/Makefile | 5 +++-- {js => javascript}/http_server.py | 0 {js => javascript}/index.html | 0 javascript/main.js | 7 +++++++ javascript/modules/algebra.js | 10 ++++++++++ javascript/modules/algebra/lcs.js | 12 ++++++++++++ {js => javascript/modules}/wasm.js | 0 {js => javascript/wasm}/wasm.h | 0 {js => javascript/wasm}/wrapper.c | 6 +++--- js/algebra.js | 18 ------------------ js/main.js | 4 ---- 12 files changed, 35 insertions(+), 27 deletions(-) rename {js => javascript}/.gitignore (100%) rename {js => javascript}/Makefile (74%) rename {js => javascript}/http_server.py (100%) rename {js => javascript}/index.html (100%) create mode 100644 javascript/main.js create mode 100644 javascript/modules/algebra.js create mode 100644 javascript/modules/algebra/lcs.js rename {js => javascript/modules}/wasm.js (100%) rename {js => javascript/wasm}/wasm.h (100%) rename {js => javascript/wasm}/wrapper.c (62%) delete mode 100644 js/algebra.js delete mode 100644 js/main.js diff --git a/js/.gitignore b/javascript/.gitignore similarity index 100% rename from js/.gitignore rename to javascript/.gitignore diff --git a/js/Makefile b/javascript/Makefile similarity index 74% rename from js/Makefile rename to javascript/Makefile index 39322cd..690f790 100644 --- a/js/Makefile +++ b/javascript/Makefile @@ -1,9 +1,10 @@ -CC = clang +CC = clang-15 CFLAGS = -std=c99 -Wall -Wextra -Wpedantic -O3 \ --target=wasm32 -nostdlib \ -Wl,--no-entry, -Wl,--allow-undefined, -Wl,--import-memory, \ -Wl,--export=__heap_base -algebra.wasm: wrapper.c wasm.h Makefile +algebra.wasm: wasm/wrapper.c wasm/wasm.h Makefile $(CC) $(CFLAGS) -o $@ ../src/edit.c $< + chmod -X $@ diff --git a/js/http_server.py b/javascript/http_server.py similarity index 100% rename from js/http_server.py rename to javascript/http_server.py diff --git a/js/index.html b/javascript/index.html similarity index 100% rename from js/index.html rename to javascript/index.html diff --git a/javascript/main.js b/javascript/main.js new file mode 100644 index 0000000..e0d457b --- /dev/null +++ b/javascript/main.js @@ -0,0 +1,7 @@ +import { algebra } from "./modules/algebra.js"; +import { edit } from "./modules/algebra/lcs.js"; + + +console.log(algebra.hello(5)); +console.log(algebra.lcs.edit(4)); +console.log(edit(4, 2)); diff --git a/javascript/modules/algebra.js b/javascript/modules/algebra.js new file mode 100644 index 0000000..2e52d33 --- /dev/null +++ b/javascript/modules/algebra.js @@ -0,0 +1,10 @@ +import { wasmInstance } from "./wasm.js"; +import * as lcs from "./algebra/lcs.js"; + + +export const algebra = await wasmInstance("./algebra.wasm").then(wasm => { + return { + lcs, + hello: (lhs, rhs) => lhs * (rhs ?? 42), + }; +}); diff --git a/javascript/modules/algebra/lcs.js b/javascript/modules/algebra/lcs.js new file mode 100644 index 0000000..60e5111 --- /dev/null +++ b/javascript/modules/algebra/lcs.js @@ -0,0 +1,12 @@ +import { wasmInstance } from "../wasm.js"; + + +let edit; + + +await wasmInstance("./algebra.wasm").then(wasm => { + edit = (lhs, rhs) => wasm.exports.edit(lhs, rhs ?? 42); +}); + + +export { edit }; diff --git a/js/wasm.js b/javascript/modules/wasm.js similarity index 100% rename from js/wasm.js rename to javascript/modules/wasm.js diff --git a/js/wasm.h b/javascript/wasm/wasm.h similarity index 100% rename from js/wasm.h rename to javascript/wasm/wasm.h diff --git a/js/wrapper.c b/javascript/wasm/wrapper.c similarity index 62% rename from js/wrapper.c rename to javascript/wasm/wrapper.c index 876ad20..6ba9e6d 100644 --- a/js/wrapper.c +++ b/javascript/wasm/wrapper.c @@ -1,14 +1,14 @@ #include // NULL, size_t #include "wasm.h" // WASM_EXPORT -#include "../include/edit.h" // varalg_edit +#include "../../include/edit.h" // varalg_edit WASM_EXPORT("edit") size_t -edit_wrap(size_t const lhs, size_t const rhs) +edit(size_t const lhs, size_t const rhs) { console_log(13, "Hello, World!"); return varalg_edit(lhs, rhs); -} // edit_wrap +} // edit diff --git a/js/algebra.js b/js/algebra.js deleted file mode 100644 index 8726dd5..0000000 --- a/js/algebra.js +++ /dev/null @@ -1,18 +0,0 @@ -import { wasmInstance } from "./wasm.js"; - - -export const algebra = {}; - - -await wasmInstance("./algebra.wasm").then(wasm => { - algebra.lcs = { - edit: function(lhs, rhs) { - return wasm.exports.edit(lhs, rhs ?? 42); - }, - }; -}); - - - - - diff --git a/js/main.js b/js/main.js deleted file mode 100644 index 70ce01d..0000000 --- a/js/main.js +++ /dev/null @@ -1,4 +0,0 @@ -import { algebra } from "./algebra.js"; - - -console.log(algebra.lcs.edit(4)); From c2ebacc9901da0bda378ee73001a86589de1ea71 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 21 Mar 2024 19:10:24 +0100 Subject: [PATCH 012/704] Fixed out of scope variable --- javascript/modules/wasm.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/modules/wasm.js b/javascript/modules/wasm.js index 4af1123..a292ecf 100644 --- a/javascript/modules/wasm.js +++ b/javascript/modules/wasm.js @@ -104,7 +104,7 @@ export function wasmInstance(path, initial_pages=2) { } // catch const buffer = memory.buffer; const buffer_size = buffer.byteLength; - memory.words = new Uint32Array(buffer, 0, buffer_size / env.word_size); + memory.words = new Uint32Array(buffer, 0, buffer_size / word_size); memory.bytes = new Uint8Array(buffer, 0, buffer_size); console.log(`total memory: ${memory.buffer.byteLength / (1024 * 1024)} MiB`); const heap_block = heap_blocks[heap_blocks.length - 1]; From 9bff2c4c01763c61facd33548a413107af3dcc7b Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 21 Mar 2024 19:16:57 +0100 Subject: [PATCH 013/704] Simplify single symbol export --- javascript/modules/algebra/lcs.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/javascript/modules/algebra/lcs.js b/javascript/modules/algebra/lcs.js index 60e5111..7f584bc 100644 --- a/javascript/modules/algebra/lcs.js +++ b/javascript/modules/algebra/lcs.js @@ -1,12 +1,9 @@ import { wasmInstance } from "../wasm.js"; -let edit; +export let edit; await wasmInstance("./algebra.wasm").then(wasm => { edit = (lhs, rhs) => wasm.exports.edit(lhs, rhs ?? 42); }); - - -export { edit }; From dd9414baeee1fa5184c5bf4b28153fb7790f205a Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 21 Mar 2024 19:21:58 +0100 Subject: [PATCH 014/704] console log for numbers --- javascript/modules/wasm.js | 4 ++-- javascript/wasm/wrapper.c | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/javascript/modules/wasm.js b/javascript/modules/wasm.js index a292ecf..2306021 100644 --- a/javascript/modules/wasm.js +++ b/javascript/modules/wasm.js @@ -8,8 +8,8 @@ export function wasmInstance(path, initial_pages=2) { }), console_log: function(len, msg) { - if (len === 0) { - console.log(msg); + if (msg === 0) { + console.log(len); return; } // if console.log(utf8decoder.decode(new Uint8Array(imports.env.memory.buffer, msg, len))); diff --git a/javascript/wasm/wrapper.c b/javascript/wasm/wrapper.c index 6ba9e6d..6f1c3c5 100644 --- a/javascript/wasm/wrapper.c +++ b/javascript/wasm/wrapper.c @@ -9,6 +9,7 @@ size_t edit(size_t const lhs, size_t const rhs) { console_log(13, "Hello, World!"); + console_log(42, NULL); return varalg_edit(lhs, rhs); } // edit From 45084684d69f2821d8854d8aee125529b68f3430 Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 29 Mar 2024 15:45:53 +0100 Subject: [PATCH 015/704] C unit tests with coverage --- .gitignore | 6 ++ Makefile | 41 +++++++++ include/parser.h | 24 +++++ src/main.c | 20 ++++ src/parser.c | 99 ++++++++++++++++++++ tests/test_parser.c | 219 ++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 409 insertions(+) create mode 100644 include/parser.h create mode 100644 src/main.c create mode 100644 src/parser.c create mode 100644 tests/test_parser.c diff --git a/.gitignore b/.gitignore index e69de29..c65c979 100644 --- a/.gitignore +++ b/.gitignore @@ -0,0 +1,6 @@ +*.o +*.d +*.out +*.gcda +*.gcno +*.gcov diff --git a/Makefile b/Makefile index e69de29..13bb1be 100644 --- a/Makefile +++ b/Makefile @@ -0,0 +1,41 @@ +SRC_DIR = src +TEST_DIR = tests + +SOURCES = $(sort $(shell find $(SRC_DIR) -name '*.c')) +OBJECTS = $(SOURCES:.c=.o) +DEPS = $(OBJECTS:.o=.d) + +TARGET = a.out + +TESTS = $(sort $(shell find $(TEST_DIR) -name 'test_*.c')) + +CC = gcc +CFLAGS = -std=c11 -march=native -Wall -Wextra -Wpedantic -O0 -g -DDEBUG + +.PHONY: all check clean + +all: $(TARGET) + + +check: CFLAGS += --coverage -fprofile-arcs -fprofile-dir=$(TEST_DIR) +check: $(TESTS:.c=.out) + valgrind -q ./$^ + gcov $(^:.out=.gcda) + mv *.gcov $(TEST_DIR) + + +clean: + $(RM) $(TARGET) $(OBJECTS) $(DEPS) $(TESTS:.c=.out) $(TEST_DIR)/*.gcno $(TEST_DIR)/*.gcda $(TEST_DIR)/*.gcov + + +$(TARGET): $(OBJECTS) + $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $^ + +-include $(DEPS) + +%.o: %.c + $(CC) $(CFLAGS) $(CPPFLAGS) -MMD -o $@ -c $< + +%.out: %.c + $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $< + mv *.gcno $(TEST_DIR) diff --git a/include/parser.h b/include/parser.h new file mode 100644 index 0000000..c9e58a2 --- /dev/null +++ b/include/parser.h @@ -0,0 +1,24 @@ +#ifndef PARSER_H +#define PARSER_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include // size_t + + +size_t +va_parse_hgvs(size_t const len, char const expression[static len]); + + +size_t +va_parse_spdi(size_t const len, char const expression[static len]); + + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..90b97b8 --- /dev/null +++ b/src/main.c @@ -0,0 +1,20 @@ +#include // stderr, fprintf, printf +#include // EXIT_* +#include // strlen + +#include "../include/parser.h" // va_parse_* + + +int +main(int argc, char* argv[argc + 1]) +{ + if (argc < 2) + { + fprintf(stderr, "usage %s hgvs\n", argv[0]); + return EXIT_FAILURE; + } // if + + printf("%zu\n", va_parse_hgvs(strlen(argv[1]), argv[1])); + + return EXIT_SUCCESS; +} // main diff --git a/src/parser.c b/src/parser.c new file mode 100644 index 0000000..516382d --- /dev/null +++ b/src/parser.c @@ -0,0 +1,99 @@ +#include // bool +#include // size_t +#include // uint32_t + +#include "../include/parser.h" // va_parse_* + + +static inline bool +is_digit(char const ch) +{ + return ch >= '0' && ch <= '9'; +} // is_digit + + +static inline bool +is_dna_nucleotide(char const ch) +{ + return ch == 'A' || ch == 'C' || ch == 'G' || ch == 'T'; +} // is_dna_nucleotide + + +static size_t +match_number(size_t const len, char const expression[static len], + uint32_t* const num) +{ + size_t idx = 0; + while (idx < len && is_digit(expression[idx])) + { + *num = *num * 10 + expression[idx] - '0'; // OVERFLOW + idx += 1; + } // while + return idx; +} // match_number + + +static size_t +match_sequence(size_t const len, char const expression[static len]) +{ + size_t idx = 0; + while (idx < len && is_dna_nucleotide(expression[idx])) + { + idx += 1; + } // while + return idx; +} // match_sequence + + +static size_t +match_location(size_t const len, char const expression[static len], + uint32_t* const start, uint32_t* const end) +{ + size_t idx = match_number(len, expression, start); + if (idx == 0) + { + return 0; // expected number + } // if + if (expression[idx] == '_') + { + idx += 1; + size_t const tok = match_number(len - idx, expression + idx, end); + if (tok == 0) + { + return 0; // expected number + } // if + if (*start >= *end) + { + return 0; // invalid range + } // if + return idx + tok; + } // if + *end = *start; + return idx; +} // match_location + + +static size_t +match(size_t const len, char const expression[static len], char const word[static 1]) +{ + size_t idx = 0; + while (idx < len && word[idx] != '\0' && expression[idx] == word[idx]) + { + idx += 1; + } // while + return word[idx] == '\0' ? idx : 0; +} // match + + +size_t +va_parse_hgvs(size_t const len, char const expression[static len]) +{ + return match(len, expression, "hgvs"); +} // va_parse_hgvs + + +size_t +va_parse_spdi(size_t const len, char const expression[static len]) +{ + return match(len, expression, "spdi"); +} // va_parse_spdi diff --git a/tests/test_parser.c b/tests/test_parser.c new file mode 100644 index 0000000..71d3df2 --- /dev/null +++ b/tests/test_parser.c @@ -0,0 +1,219 @@ +#include // assert +#include // bool, false, true +#include // NULL, size_t +#include // UINT32_MAX, uint32_t +#include // stderr, fprintf +#include // EXIT_SUCCESS + + +#include "../src/parser.c" + + +static void +test_is_digit(void) +{ + static struct { + char const ch; + bool const expected; + } const tests[] = + { + { '\0', false}, + { '/', false}, + { '0', true}, + { '1', true}, + { '2', true}, + { '3', true}, + { '4', true}, + { '5', true}, + { '6', true}, + { '7', true}, + { '8', true}, + { '9', true}, + { ':', false}, + { 'a', false}, + { 'A', false}, + {'\xFF', false}, + }; // TESTS + + fprintf(stderr, "%s:%s: ", __FILE__, __func__); + for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) + { + assert(tests[i].expected == is_digit(tests[i].ch)); + fprintf(stderr, "."); + } // for + fprintf(stderr, " passed\n"); +} // test_is_digit + + +static void +test_is_dna_nucleotide(void) +{ + static struct { + char const ch; + bool const expected; + } const tests[] = + { + { '\0', false}, + { '0', false}, + { 'a', false}, + { 'A', true}, + { 'C', true}, + { 'G', true}, + { 'T', true}, + { 'B', false}, + {'\xFF', false}, + }; // TESTS + + fprintf(stderr, "%s:%s: ", __FILE__, __func__); + for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) + { + assert(tests[i].expected == is_dna_nucleotide(tests[i].ch)); + fprintf(stderr, "."); + } // for + fprintf(stderr, " passed\n"); +} // test_is_dna_nucleotide + + +static void +test_match_number(void) +{ + static struct { + size_t const len; + char const* const expression; + size_t const matched; + uint32_t const expected; + } const tests[] = + { + { 0, NULL, 0, 0}, + { 0, "", 0, 0}, + { 1, "1", 1, 1}, + {10, "10", 2, 10}, // saved by \0 + { 1, "10", 1, 1}, + {10, "123a123a12", 3, 123}, + { 5, "-1000", 0, 0}, + {10, "1234567890", 10, 1234567890}, + {10, "4294967295", 10, UINT32_MAX}, + {10, "4294967296", 10, 0}, // overflow + }; // TESTS + + fprintf(stderr, "%s:%s: ", __FILE__, __func__); + for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) + { + uint32_t num = 0; + size_t const tok = match_number(tests[i].len, tests[i].expression, &num); + assert(tok == tests[i].matched); + assert(num == tests[i].expected); + fprintf(stderr, "."); + } // for + fprintf(stderr, " passed\n"); +} // test_match_number + + +static void +test_match_sequence(void) +{ + static struct { + size_t const len; + char const* const expression; + size_t const matched; + } const tests[] = + { + {0, NULL, 0}, + {0, "", 0}, + {1, "A", 1}, + {4, "ACGT", 4}, + {4, "acgt", 0}, + }; // TESTS + + fprintf(stderr, "%s:%s: ", __FILE__, __func__); + for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) + { + size_t const tok = match_sequence(tests[i].len, tests[i].expression); + assert(tok == tests[i].matched); + fprintf(stderr, "."); + } // for + fprintf(stderr, " passed\n"); +} // test_match_sequence + + +static void +test_match_location(void) +{ + static struct { + size_t const len; + char const* const expression; + size_t const matched; + uint32_t const expected_start; + uint32_t const expected_end; + } const tests[] = + { + { 0, NULL, 0, 0, 0}, + { 0, "", 0, 0, 0}, + { 1, "0", 1, 0, 0}, + { 1, "1", 1, 1, 1}, + { 1, "a", 0, 0, 0}, + { 2, "9a", 1, 9, 9}, + { 3, "0_1", 3, 0, 1}, + { 2, "0_", 0, 0, 0}, + { 3, "0_a", 0, 0, 0}, + { 3, "1_1", 0, 1, 1}, + { 3, "1_0", 0, 1, 0}, + {10, "1234_56789", 10, 1234, 56789}, + }; // TESTS + + fprintf(stderr, "%s:%s: ", __FILE__, __func__); + for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) + { + uint32_t start = 0; + uint32_t end = 0; + size_t const tok = match_location(tests[i].len, tests[i].expression, &start, &end); + assert(tok == tests[i].matched); + assert(start == tests[i].expected_start); + assert(end == tests[i].expected_end); + fprintf(stderr, "."); + } // for + fprintf(stderr, " passed\n"); +} // test_match_location + + +static void +test_match(void) +{ + static struct { + size_t const len; + char const* const expression; + char const* const word; + size_t const matched; + } const tests[] = + { + { 0, NULL, "", 0}, + { 0, "", "", 0}, + { 1, "a", "", 0}, + { 1, "a", "aa", 0}, + { 1, "a", "a", 1}, + { 3, "del", "del", 3}, + { 8, "deletion", "del", 3}, + }; // TESTS + + fprintf(stderr, "%s:%s: ", __FILE__, __func__); + for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) + { + size_t const tok = match(tests[i].len, tests[i].expression, tests[i].word); + assert(tok == tests[i].matched); + fprintf(stderr, "."); + } // for + fprintf(stderr, " passed\n"); +} // test_match + + +int +main(void) +{ + test_is_digit(); + test_is_dna_nucleotide(); + test_match_number(); + test_match_sequence(); + test_match_location(); + test_match(); + return EXIT_SUCCESS; +} // main From 8b9076f6bb9c35dab3392a5348893e6082169e53 Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 29 Mar 2024 16:04:11 +0100 Subject: [PATCH 016/704] Coverage options --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 13bb1be..68ce1b0 100644 --- a/Makefile +++ b/Makefile @@ -17,10 +17,10 @@ CFLAGS = -std=c11 -march=native -Wall -Wextra -Wpedantic -O0 -g -DDEBUG all: $(TARGET) -check: CFLAGS += --coverage -fprofile-arcs -fprofile-dir=$(TEST_DIR) +check: CFLAGS += -ftest-coverage -fprofile-arcs -fprofile-dir=$(TEST_DIR) -fkeep-inline-functions -fkeep-static-functions check: $(TESTS:.c=.out) valgrind -q ./$^ - gcov $(^:.out=.gcda) + gcov $(^:.out=.gcno) mv *.gcov $(TEST_DIR) From f89c2b5968ca3d44701fca38327f7700a5d8768c Mon Sep 17 00:00:00 2001 From: jkvis Date: Sat, 6 Apr 2024 22:16:08 +0200 Subject: [PATCH 017/704] Improved build system including tests --- .gitignore | 1 + Makefile | 64 +++++++++----- include/variant.h | 30 +++++++ src/main.c | 4 +- src/parser.c | 203 ++++++++++++++++++++++++++++++++++++++++++- src/variant.c | 10 +++ tests/test_parser.c | 181 +++++++++++++++++++++++++++++++++++--- tests/test_variant.c | 41 +++++++++ 8 files changed, 494 insertions(+), 40 deletions(-) create mode 100644 include/variant.h create mode 100644 src/variant.c create mode 100644 tests/test_variant.c diff --git a/.gitignore b/.gitignore index c65c979..9aec59f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +*.dSYM/ *.o *.d *.out diff --git a/Makefile b/Makefile index 68ce1b0..00b5e94 100644 --- a/Makefile +++ b/Makefile @@ -1,41 +1,63 @@ -SRC_DIR = src -TEST_DIR = tests +SRC_DIR = src +TEST_DIR = tests -SOURCES = $(sort $(shell find $(SRC_DIR) -name '*.c')) -OBJECTS = $(SOURCES:.c=.o) -DEPS = $(OBJECTS:.o=.d) +SOURCES = $(wildcard $(SRC_DIR)/*.c) +OBJECTS = $(SOURCES:.c=.o) +DEPS = $(SOURCES:.c=.d) +TESTS = $(wildcard $(TEST_DIR)/*.c) +TEST_BINS = $(TESTS:.c=.out) +TEST_DEPS = $(TESTS:.c=.d) +TEST_GCNOS = $(TESTS:.c=.gcno) +TEST_GCDAS = $(TESTS:.c=.gcda) +TEST_COVS = $(TESTS:.c=.c.gcov) -TARGET = a.out - -TESTS = $(sort $(shell find $(TEST_DIR) -name 'test_*.c')) +TARGET = a.out CC = gcc -CFLAGS = -std=c11 -march=native -Wall -Wextra -Wpedantic -O0 -g -DDEBUG +CFLAGS = -std=c11 -march=native -Wall -Wextra -Wpedantic + + +.PHONY: check clean debug release + -.PHONY: all check clean +debug: CFLAGS+=-O0 -g -DDEBUG +release: CFLAGS+=-O3 -DNDEBUG -all: $(TARGET) +debug release: $(TARGET) -check: CFLAGS += -ftest-coverage -fprofile-arcs -fprofile-dir=$(TEST_DIR) -fkeep-inline-functions -fkeep-static-functions -check: $(TESTS:.c=.out) - valgrind -q ./$^ - gcov $(^:.out=.gcno) - mv *.gcov $(TEST_DIR) + +check: CFLAGS+=-O0 -g -DDEBUG -ftest-coverage -fprofile-arcs \ + #-fkeep-inline-functions -fkeep-static-functions +check: $(TEST_BINS) $(TESTS_GCNOS) $(TEST_GCDAS) $(TEST_COVS) clean: - $(RM) $(TARGET) $(OBJECTS) $(DEPS) $(TESTS:.c=.out) $(TEST_DIR)/*.gcno $(TEST_DIR)/*.gcda $(TEST_DIR)/*.gcov + $(RM) $(TARGET) $(OBJECTS) $(DEPS) \ + $(TEST_BINS) $(TEST_DEPS) $(TEST_GCNOS) $(TEST_GCDAS) \ + $(TEST_DIR)/*.c.gcov $(TARGET): $(OBJECTS) $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $^ + +-include $(TEST_DEPS) + +%.out: %.c + $(CC) $(CFLAGS) $(CPPFLAGS) -MMD -o $@ $< + mv $(notdir $(@:.out=.gcno)) $(TEST_DIR) + +%.gcda: %.out + ./$< + mv $(notdir $@) $(TEST_DIR) + +%.c.gcov: %.gcda + gcov $< + mv *.c.gcov $(TEST_DIR) + + -include $(DEPS) %.o: %.c $(CC) $(CFLAGS) $(CPPFLAGS) -MMD -o $@ -c $< - -%.out: %.c - $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $< - mv *.gcno $(TEST_DIR) diff --git a/include/variant.h b/include/variant.h new file mode 100644 index 0000000..c2d1d2f --- /dev/null +++ b/include/variant.h @@ -0,0 +1,30 @@ +#ifndef VARIANT_H +#define VARIANT_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include // size_t +#include // uint32_t + + +typedef struct VA_Variant +{ + uint32_t start; + uint32_t end; + uint32_t obs_start; + uint32_t obs_end; +} VA_Variant; + + +size_t +va_variant_len(VA_Variant const variant); + + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif diff --git a/src/main.c b/src/main.c index 90b97b8..3b41ef0 100644 --- a/src/main.c +++ b/src/main.c @@ -10,11 +10,11 @@ main(int argc, char* argv[argc + 1]) { if (argc < 2) { - fprintf(stderr, "usage %s hgvs\n", argv[0]); + fprintf(stderr, "usage %s expression\n", argv[0]); return EXIT_FAILURE; } // if - printf("%zu\n", va_parse_hgvs(strlen(argv[1]), argv[1])); + printf("%zu\n", va_parse_spdi(strlen(argv[1]), argv[1])); return EXIT_SUCCESS; } // main diff --git a/src/parser.c b/src/parser.c index 516382d..366b7f9 100644 --- a/src/parser.c +++ b/src/parser.c @@ -2,7 +2,8 @@ #include // size_t #include // uint32_t -#include "../include/parser.h" // va_parse_* +#include "../include/parser.h" // va_parse_* +#include "../include/variant.h" // VA_Variant static inline bool @@ -54,7 +55,7 @@ match_location(size_t const len, char const expression[static len], { return 0; // expected number } // if - if (expression[idx] == '_') + if (idx < len && expression[idx] == '_') { idx += 1; size_t const tok = match_number(len - idx, expression + idx, end); @@ -85,15 +86,209 @@ match(size_t const len, char const expression[static len], char const word[stati } // match +static size_t +match_until(size_t const len, char const expression[static len], char const delim) +{ + size_t idx = 0; + while (idx < len && expression[idx] != delim) + { + idx += 1; + } // while + return idx < len && expression[idx] == delim ? idx : 0; +} // match_until + + +static size_t +match_variant(size_t const len, char const expression[static len], + VA_Variant* const variant) +{ + size_t idx = match_location(len, expression, &variant->start, &variant->end); + if (idx == 0) + { + return 0; // expected location + } // if + + size_t tok = match(len - idx, expression + idx, "del"); + if (tok != 0) + { + if (variant->start == 0) + { + return 0; // invalid location + } // if + idx += tok; + + // optional sequence + idx += match_sequence(len - idx, expression + idx); + + tok = match(len - idx, expression + idx, "ins"); + if (tok != 0) + { + idx += tok; + + tok = match_sequence(len - idx, expression + idx); + if (tok == 0) + { + return 0; // expected sequence; + } // if + + return idx + tok; + } // if + + return idx; + } // if + + tok = match(len - idx, expression + idx, "ins"); + if (tok != 0) + { + if (variant->end - variant->start != 1) + { + return 0; // expected 1-interval + } // if + idx += tok; + variant->end = variant->start; + + tok = match_sequence(len - idx, expression + idx); + if (tok == 0) + { + return 0; // expected sequence + } // if + + return idx + tok; + } // if + + // optional sequence + idx += match_sequence(len - idx, expression + idx); + + if (idx < len && expression[idx] == '>') + { + idx += 1; // '>' + + tok = match_sequence(len - idx, expression + idx); + if (tok == 0) + { + return 0; // expected sequence + } // if + + return idx + tok; + } // if + + return 0; +} // match_variant + + size_t va_parse_hgvs(size_t const len, char const expression[static len]) { - return match(len, expression, "hgvs"); + size_t idx = match_until(len, expression, ':'); + if (idx >= len) + { + return 0; // expected ':' + } // if + if (idx > 0) + { + idx += 1; // ':' + } // if + + VA_Variant variant = {0}; + + idx += match(len - idx, expression + idx, "g."); + + if (idx < len && expression[idx] == '=') + { + idx += 1; + return idx == len ? idx : 0; + } // if + + if (idx < len && expression[idx] == '[') + { + idx += 1; + + size_t tok = match_variant(len - idx, expression + idx, &variant); + if (tok == 0) + { + return 0; // expected variant + } // if + idx += tok; + + while (idx < len && expression[idx] == ';') + { + idx += 1; // ';' + + tok = match_variant(len - idx, expression + idx, &variant); + if (tok == 0) + { + return 0; // expected variant + } // if + idx += tok; + } // while + + if (idx >= len || expression[idx] != ']') + { + return 0; // expected ']' + } // if + idx += 1; // ']' + + return idx == len ? idx : 0; + } // if + + size_t tok = match_variant(len - idx, expression + idx, &variant); + if (tok == 0) + { + return 0; // expected variant + } // if + + return idx + tok; } // va_parse_hgvs size_t va_parse_spdi(size_t const len, char const expression[static len]) { - return match(len, expression, "spdi"); + size_t idx = match_until(len, expression, ':'); + if (idx >= len) + { + return 0; // expected ':' + } // if + idx += 1; // ':' + + uint32_t pos = 0; + size_t tok = match_number(len - idx, expression + idx, &pos); + if (tok == 0) + { + return 0; // expected number (location) + } // if + idx += tok; + + if (idx >= len || expression[idx] != ':') + { + return 0; // expected ':' + } // if + idx += 1; + + uint32_t del = 0; + tok = match_number(len - idx, expression + idx, &del); + if (tok == 0) + { + tok = match_sequence(len - idx, expression + idx); + if (tok == 0) + { + return 0; // expected number (length) or sequence + } // if + } // if + idx += tok; + + if (idx >= len || expression[idx] != ':') + { + return 0; // expected ':' + } // if + idx += 1; + + tok = match_sequence(len - idx, expression + idx); + if (tok == 0) + { + return 0; // expected sequence + } // if + idx += tok; + + return idx == len ? idx : 0; } // va_parse_spdi diff --git a/src/variant.c b/src/variant.c new file mode 100644 index 0000000..c0e9f4c --- /dev/null +++ b/src/variant.c @@ -0,0 +1,10 @@ +#include // size_t + +#include "../include/variant.h" // VA_*, va_* + + +size_t +va_variant_len(VA_Variant const variant) +{ + return variant.end - variant.start + variant.obs_end - variant.obs_start; +} // va_variant_len diff --git a/tests/test_parser.c b/tests/test_parser.c index 71d3df2..66b8673 100644 --- a/tests/test_parser.c +++ b/tests/test_parser.c @@ -33,7 +33,7 @@ test_is_digit(void) { 'a', false}, { 'A', false}, {'\xFF', false}, - }; // TESTS + }; // tests fprintf(stderr, "%s:%s: ", __FILE__, __func__); for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) @@ -62,7 +62,7 @@ test_is_dna_nucleotide(void) { 'T', true}, { 'B', false}, {'\xFF', false}, - }; // TESTS + }; // tests fprintf(stderr, "%s:%s: ", __FILE__, __func__); for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) @@ -94,7 +94,7 @@ test_match_number(void) {10, "1234567890", 10, 1234567890}, {10, "4294967295", 10, UINT32_MAX}, {10, "4294967296", 10, 0}, // overflow - }; // TESTS + }; // tests fprintf(stderr, "%s:%s: ", __FILE__, __func__); for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) @@ -123,7 +123,7 @@ test_match_sequence(void) {1, "A", 1}, {4, "ACGT", 4}, {4, "acgt", 0}, - }; // TESTS + }; // tests fprintf(stderr, "%s:%s: ", __FILE__, __func__); for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) @@ -159,7 +159,7 @@ test_match_location(void) { 3, "1_1", 0, 1, 1}, { 3, "1_0", 0, 1, 0}, {10, "1234_56789", 10, 1234, 56789}, - }; // TESTS + }; // tests fprintf(stderr, "%s:%s: ", __FILE__, __func__); for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) @@ -186,14 +186,14 @@ test_match(void) size_t const matched; } const tests[] = { - { 0, NULL, "", 0}, - { 0, "", "", 0}, - { 1, "a", "", 0}, - { 1, "a", "aa", 0}, - { 1, "a", "a", 1}, - { 3, "del", "del", 3}, - { 8, "deletion", "del", 3}, - }; // TESTS + {0, NULL, "", 0}, + {0, "", "", 0}, + {1, "a", "", 0}, + {1, "a", "aa", 0}, + {1, "a", "a", 1}, + {3, "del", "del", 3}, + {8, "deletion", "del", 3}, + }; // tests fprintf(stderr, "%s:%s: ", __FILE__, __func__); for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) @@ -206,6 +206,157 @@ test_match(void) } // test_match +static void +test_match_until(void) +{ + static struct { + size_t const len; + char const* const expression; + char const delim; + size_t const matched; + } const tests[] = + { + {0, NULL, '\0', 0}, + {0, "", '\0', 0}, + {1, "1", ':', 0}, + {1, ":", ':', 0}, + {8, "AATT:ATT", ':', 4}, + {3, ":::", ':', 0}, + }; // tests + + fprintf(stderr, "%s:%s: ", __FILE__, __func__); + for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) + { + size_t const tok = match_until(tests[i].len, tests[i].expression, tests[i].delim); + assert(tok == tests[i].matched); + fprintf(stderr, "."); + } // for + fprintf(stderr, " passed\n"); +} // test_match_until + + +static void +test_match_variant(void) +{ + static struct { + size_t const len; + char const* const expression; + size_t const matched; + } const tests[] = + { + {0, NULL, 0}, + {0, "", 0}, + {1, "1", 0}, + {4, "1del", 4}, + {4, "0del", 0}, + {5, "1delT", 5}, + {7, "1delins", 0}, + {8, "1delinsA", 8}, + {9, "1delAinsA", 9}, + {6, "1_2ins", 0}, + {4, "1ins", 0}, + {6, "0_1ins", 0}, + {6, "1_3ins", 0}, + {7, "1_2insT", 7}, + {2, "1>", 0}, + {3, "1A>", 0}, + {4, "1A>T", 4}, + }; // tests + + fprintf(stderr, "%s:%s: ", __FILE__, __func__); + for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) + { + size_t const tok = va_parse_hgvs(tests[i].len, tests[i].expression); + assert(tok == tests[i].matched); + fprintf(stderr, "."); + } // for + fprintf(stderr, " passed\n"); +} // test_match_variant + + +static void +test_va_parse_hgvs(void) +{ + static struct { + size_t const len; + char const* const expression; + size_t const matched; + } const tests[] = + { + { 0, NULL, 0}, + { 0, "", 0}, + { 1, "A", 0}, + { 1, ":", 0}, + { 1, "g", 0}, + { 2, "g.", 0}, + { 3, ":g.", 0}, + { 1, "1", 0}, + { 3, "A:1", 0}, + { 5, "A:g.1", 0}, + { 7, "A:g.1_2", 0}, + { 1, "=", 1}, + { 3, "g.=", 3}, + { 4, "1del", 4}, + { 6, "g.1del", 6}, + { 6, "A:1del", 6}, + { 8, "A:g.1del", 8}, + { 1, "[", 0}, + { 5, "[1del", 0}, + { 6, "[1del;", 0}, + { 6, "[1del]", 6}, + {10, "[1del;2del", 0}, + {11, "[1del;2del]", 11}, + {10, "[1del2del]", 0}, + }; // tests + + fprintf(stderr, "%s:%s: ", __FILE__, __func__); + for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) + { + size_t const tok = va_parse_hgvs(tests[i].len, tests[i].expression); + assert(tok == tests[i].matched); + fprintf(stderr, "."); + } // for + fprintf(stderr, " passed\n"); +} // test_va_parse_hgvs + + +static void +test_va_parse_spdi(void) +{ + static struct { + size_t const len; + char const* const expression; + size_t const matched; + } const tests[] = + { + {0, NULL, 0}, + {0, "", 0}, + {1, "A", 0}, + {1, ":", 0}, + {2, "A:", 0}, + {3, "A:1", 0}, + {4, "A:1:", 0}, + {5, "A:1:1", 0}, + {5, "A:1:A", 0}, + {6, "A:1:1:", 0}, + {6, "A:1:A:", 0}, + {7, "A:1:1:A", 7}, + {7, "A:1:A:A", 7}, + {8, "A:1:A:A ", 0}, + {6, ":1:A:A", 6}, + }; // tests + + fprintf(stderr, "%s:%s: ", __FILE__, __func__); + for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) + { + size_t const tok = va_parse_spdi(tests[i].len, tests[i].expression); + assert(tok == tests[i].matched); + fprintf(stderr, "."); + } // for + fprintf(stderr, " passed\n"); +} // test_va_parse_spdi + + int main(void) { @@ -215,5 +366,9 @@ main(void) test_match_sequence(); test_match_location(); test_match(); + test_match_until(); + test_match_variant(); + test_va_parse_hgvs(); + test_va_parse_spdi(); return EXIT_SUCCESS; } // main diff --git a/tests/test_variant.c b/tests/test_variant.c new file mode 100644 index 0000000..f7ec69b --- /dev/null +++ b/tests/test_variant.c @@ -0,0 +1,41 @@ +#include // assert +#include // size_t +#include // stderr, fprintf +#include // EXIT_SUCCESS + + +#include "../src/variant.c" + + +static void +test_va_variant_len(void) +{ + static struct { + VA_Variant const variant; + size_t const len; + } const tests[] = + { + {{0}, 0}, + {{.start=0, .end=0, .obs_start=0, .obs_end=0}, 0}, + {{.start=0, .end=1, .obs_start=0, .obs_end=0}, 1}, + {{.start=0, .end=0, .obs_start=0, .obs_end=1}, 1}, + {{.start=0, .end=1, .obs_start=0, .obs_end=1}, 2}, + }; // tests + + fprintf(stderr, "%s:%s: ", __FILE__, __func__); + for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) + { + size_t const len = va_variant_len(tests[i].variant); + assert(len == tests[i].len); + fprintf(stderr, "."); + } // for + fprintf(stderr, " passed\n"); +} // test_va_variant_len + + +int +main(void) +{ + test_va_variant_len(); + return EXIT_SUCCESS; +} // main From 330f2569e6c5227741724591d321d568a75fac5b Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 8 Apr 2024 15:22:20 +0200 Subject: [PATCH 018/704] Memcheck in tests --- Makefile | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 00b5e94..2bbb205 100644 --- a/Makefile +++ b/Makefile @@ -13,22 +13,24 @@ TEST_COVS = $(TESTS:.c=.c.gcov) TARGET = a.out -CC = gcc -CFLAGS = -std=c11 -march=native -Wall -Wextra -Wpedantic +CC = gcc +CFLAGS = -std=c11 -march=native -Wall -Wextra -Wpedantic + +MEMCHECK = valgrind -q --leak-check=full --error-exitcode=1 .PHONY: check clean debug release debug: CFLAGS+=-O0 -g -DDEBUG -release: CFLAGS+=-O3 -DNDEBUG +release: CFLAGS+=-O3 debug release: $(TARGET) check: CFLAGS+=-O0 -g -DDEBUG -ftest-coverage -fprofile-arcs \ - #-fkeep-inline-functions -fkeep-static-functions + -fkeep-inline-functions -fkeep-static-functions check: $(TEST_BINS) $(TESTS_GCNOS) $(TEST_GCDAS) $(TEST_COVS) @@ -49,7 +51,7 @@ $(TARGET): $(OBJECTS) mv $(notdir $(@:.out=.gcno)) $(TEST_DIR) %.gcda: %.out - ./$< + $(MEMCHECK) ./$< mv $(notdir $@) $(TEST_DIR) %.c.gcov: %.gcda From c818eafb444545016a97dca91483ac5da931daf3 Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 8 Apr 2024 15:24:01 +0200 Subject: [PATCH 019/704] Variant equals --- include/variant.h | 5 +++++ src/variant.c | 9 +++++++++ tests/test_variant.c | 40 +++++++++++++++++++++++++++++++++++----- 3 files changed, 49 insertions(+), 5 deletions(-) diff --git a/include/variant.h b/include/variant.h index c2d1d2f..d8c9f7d 100644 --- a/include/variant.h +++ b/include/variant.h @@ -6,6 +6,7 @@ extern "C" { #endif +#include // bool #include // size_t #include // uint32_t @@ -19,6 +20,10 @@ typedef struct VA_Variant } VA_Variant; +bool +va_variant_eq(VA_Variant const lhs, VA_Variant const rhs); + + size_t va_variant_len(VA_Variant const variant); diff --git a/src/variant.c b/src/variant.c index c0e9f4c..fa2f810 100644 --- a/src/variant.c +++ b/src/variant.c @@ -1,8 +1,17 @@ +#include // bool #include // size_t #include "../include/variant.h" // VA_*, va_* +bool +va_variant_eq(VA_Variant const lhs, VA_Variant const rhs) +{ + return lhs.start == rhs.start && lhs.end == rhs.end && + lhs.obs_start == rhs.obs_start && lhs.obs_end == rhs.obs_end; +} // va_variant_eq + + size_t va_variant_len(VA_Variant const variant) { diff --git a/tests/test_variant.c b/tests/test_variant.c index f7ec69b..eb1b363 100644 --- a/tests/test_variant.c +++ b/tests/test_variant.c @@ -1,4 +1,5 @@ #include // assert +#include // bool, false, true #include // size_t #include // stderr, fprintf #include // EXIT_SUCCESS @@ -7,6 +8,34 @@ #include "../src/variant.c" +static void +test_va_variant_eq(void) +{ + static struct { + VA_Variant const lhs; + VA_Variant const rhs; + bool const eq; + } const tests[] = + { + { {0}, {0}, true}, + {{0, 0, 0, 0}, {0, 0, 0, 0}, true}, + {{0, 0, 0, 0}, {0, 0, 0, 1}, false}, + {{0, 0, 0, 0}, {0, 0, 1, 0}, false}, + {{0, 0, 0, 0}, {0, 1, 0, 0}, false}, + {{0, 0, 0, 0}, {1, 0, 0, 0}, false}, + }; // tests + + fprintf(stderr, "%s:%s: ", __FILE__, __func__); + for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) + { + bool const eq = va_variant_eq(tests[i].lhs, tests[i].rhs); + assert(eq == tests[i].eq); + fprintf(stderr, "."); + } // for + fprintf(stderr, " passed\n"); +} // test_va_variant_eq + + static void test_va_variant_len(void) { @@ -15,11 +44,11 @@ test_va_variant_len(void) size_t const len; } const tests[] = { - {{0}, 0}, - {{.start=0, .end=0, .obs_start=0, .obs_end=0}, 0}, - {{.start=0, .end=1, .obs_start=0, .obs_end=0}, 1}, - {{.start=0, .end=0, .obs_start=0, .obs_end=1}, 1}, - {{.start=0, .end=1, .obs_start=0, .obs_end=1}, 2}, + { {0}, 0}, + {{0, 0, 0, 0}, 0}, + {{0, 1, 0, 0}, 1}, + {{0, 0, 0, 1}, 1}, + {{0, 1, 0, 1}, 2}, }; // tests fprintf(stderr, "%s:%s: ", __FILE__, __func__); @@ -36,6 +65,7 @@ test_va_variant_len(void) int main(void) { + test_va_variant_eq(); test_va_variant_len(); return EXIT_SUCCESS; } // main From 01bc6d8934e02ed8a94ec7063b52beab76a1d4f5 Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 8 Apr 2024 15:24:30 +0200 Subject: [PATCH 020/704] Parser returns variant arrays --- include/parser.h | 8 ++- src/main.c | 7 +- src/parser.c | 73 ++++++++++++------- tests/test_parser.c | 170 ++++++++++++++++++++++++++------------------ 4 files changed, 160 insertions(+), 98 deletions(-) diff --git a/include/parser.h b/include/parser.h index c9e58a2..56c7779 100644 --- a/include/parser.h +++ b/include/parser.h @@ -8,13 +8,17 @@ extern "C" #include // size_t +#include "variant.h" // VA_Variant + size_t -va_parse_hgvs(size_t const len, char const expression[static len]); +va_parse_hgvs(size_t const len, char const expression[static len], + size_t const len_var, VA_Variant variants[static len_var]); size_t -va_parse_spdi(size_t const len, char const expression[static len]); +va_parse_spdi(size_t const len, char const expression[static len], + VA_Variant variants[static 1]); #ifdef __cplusplus diff --git a/src/main.c b/src/main.c index 3b41ef0..8c0a414 100644 --- a/src/main.c +++ b/src/main.c @@ -2,7 +2,8 @@ #include // EXIT_* #include // strlen -#include "../include/parser.h" // va_parse_* +#include "../include/parser.h" // va_parse_* +#include "../include/variant.h" // VA_Variant int @@ -14,7 +15,9 @@ main(int argc, char* argv[argc + 1]) return EXIT_FAILURE; } // if - printf("%zu\n", va_parse_spdi(strlen(argv[1]), argv[1])); + VA_Variant variants[1] = {{0}}; + + printf("%zu\n", va_parse_spdi(strlen(argv[1]), argv[1], variants)); return EXIT_SUCCESS; } // main diff --git a/src/parser.c b/src/parser.c index 366b7f9..633987f 100644 --- a/src/parser.c +++ b/src/parser.c @@ -116,6 +116,7 @@ match_variant(size_t const len, char const expression[static len], return 0; // invalid location } // if idx += tok; + variant->start -= 1; // optional sequence idx += match_sequence(len - idx, expression + idx); @@ -125,13 +126,15 @@ match_variant(size_t const len, char const expression[static len], { idx += tok; + variant->obs_start = idx; // OVERFLOW tok = match_sequence(len - idx, expression + idx); if (tok == 0) { return 0; // expected sequence; } // if + idx += tok; - return idx + tok; + variant->obs_end = idx; // OVERFLOW } // if return idx; @@ -147,14 +150,23 @@ match_variant(size_t const len, char const expression[static len], idx += tok; variant->end = variant->start; + variant->obs_start = idx; // OVERFLOW tok = match_sequence(len - idx, expression + idx); if (tok == 0) { return 0; // expected sequence } // if + idx += tok; + variant->obs_end = idx; // OVERFLOW - return idx + tok; + return idx; + } // if + + if (variant->start == 0) + { + return 0; // invalid location } // if + variant->start -= 1; // optional sequence idx += match_sequence(len - idx, expression + idx); @@ -163,13 +175,16 @@ match_variant(size_t const len, char const expression[static len], { idx += 1; // '>' + variant->obs_start = idx; // OVERFLOW tok = match_sequence(len - idx, expression + idx); if (tok == 0) { return 0; // expected sequence } // if + idx += tok; + variant->obs_end = idx; // OVERFLOW - return idx + tok; + return idx; } // if return 0; @@ -177,7 +192,8 @@ match_variant(size_t const len, char const expression[static len], size_t -va_parse_hgvs(size_t const len, char const expression[static len]) +va_parse_hgvs(size_t const len, char const expression[static len], + size_t const len_var, VA_Variant variants[static len_var]) { size_t idx = match_until(len, expression, ':'); if (idx >= len) @@ -188,38 +204,36 @@ va_parse_hgvs(size_t const len, char const expression[static len]) { idx += 1; // ':' } // if - - VA_Variant variant = {0}; - idx += match(len - idx, expression + idx, "g."); - if (idx < len && expression[idx] == '=') - { - idx += 1; - return idx == len ? idx : 0; - } // if - if (idx < len && expression[idx] == '[') { idx += 1; - size_t tok = match_variant(len - idx, expression + idx, &variant); + size_t tok = match_variant(len - idx, expression + idx, &variants[0]); if (tok == 0) { return 0; // expected variant } // if idx += tok; + size_t count = 1; while (idx < len && expression[idx] == ';') { idx += 1; // ';' - tok = match_variant(len - idx, expression + idx, &variant); + if (count >= len_var) + { + return 0; // too many variants + } // if + + tok = match_variant(len - idx, expression + idx, &variants[count]); if (tok == 0) { return 0; // expected variant } // if idx += tok; + count += 1; } // while if (idx >= len || expression[idx] != ']') @@ -228,22 +242,31 @@ va_parse_hgvs(size_t const len, char const expression[static len]) } // if idx += 1; // ']' - return idx == len ? idx : 0; + return idx == len ? count : 0; } // if - size_t tok = match_variant(len - idx, expression + idx, &variant); + if (idx < len && expression[idx] == '=') + { + idx += 1; + return idx == len; + } // if + + size_t tok = match_variant(len - idx, expression + idx, &variants[0]); if (tok == 0) { return 0; // expected variant } // if + idx += tok; - return idx + tok; + return idx == len; } // va_parse_hgvs size_t -va_parse_spdi(size_t const len, char const expression[static len]) +va_parse_spdi(size_t const len, char const expression[static len], + VA_Variant variants[static 1]) { + // sequence size_t idx = match_until(len, expression, ':'); if (idx >= len) { @@ -251,8 +274,7 @@ va_parse_spdi(size_t const len, char const expression[static len]) } // if idx += 1; // ':' - uint32_t pos = 0; - size_t tok = match_number(len - idx, expression + idx, &pos); + size_t tok = match_number(len - idx, expression + idx, &variants[0].start); if (tok == 0) { return 0; // expected number (location) @@ -265,8 +287,7 @@ va_parse_spdi(size_t const len, char const expression[static len]) } // if idx += 1; - uint32_t del = 0; - tok = match_number(len - idx, expression + idx, &del); + tok = match_number(len - idx, expression + idx, &variants[0].end); if (tok == 0) { tok = match_sequence(len - idx, expression + idx); @@ -274,8 +295,10 @@ va_parse_spdi(size_t const len, char const expression[static len]) { return 0; // expected number (length) or sequence } // if + variants[0].end = tok; // OVERFLOW } // if idx += tok; + variants[0].end += variants[0].start; if (idx >= len || expression[idx] != ':') { @@ -283,12 +306,14 @@ va_parse_spdi(size_t const len, char const expression[static len]) } // if idx += 1; + variants[0].obs_start = idx; // OVERFLOW tok = match_sequence(len - idx, expression + idx); if (tok == 0) { return 0; // expected sequence } // if idx += tok; + variants[0].obs_end = idx; - return idx == len ? idx : 0; + return idx == len; } // va_parse_spdi diff --git a/tests/test_parser.c b/tests/test_parser.c index 66b8673..365ec40 100644 --- a/tests/test_parser.c +++ b/tests/test_parser.c @@ -9,6 +9,17 @@ #include "../src/parser.c" +#define MAX_VARIANTS 2 + + +static inline bool +variant_eq(VA_Variant const lhs, VA_Variant const rhs) +{ + return lhs.start == rhs.start && lhs.end == rhs.end && + lhs.obs_start == rhs.obs_start && lhs.obs_end == rhs.obs_end; +} // variant_eq + + static void test_is_digit(void) { @@ -123,6 +134,7 @@ test_match_sequence(void) {1, "A", 1}, {4, "ACGT", 4}, {4, "acgt", 0}, + {4, "ACgt", 2}, }; // tests fprintf(stderr, "%s:%s: ", __FILE__, __func__); @@ -186,13 +198,14 @@ test_match(void) size_t const matched; } const tests[] = { - {0, NULL, "", 0}, - {0, "", "", 0}, - {1, "a", "", 0}, - {1, "a", "aa", 0}, - {1, "a", "a", 1}, - {3, "del", "del", 3}, - {8, "deletion", "del", 3}, + {0, NULL, "", 0}, + {0, "", "", 0}, + {1, "a", "", 0}, + {1, "a", "aa", 0}, + {1, "a", "a", 1}, + {3, "del", "del", 3}, + {8, "deletion", "del", 3}, + {3, "del", "deletion", 0}, }; // tests fprintf(stderr, "%s:%s: ", __FILE__, __func__); @@ -242,32 +255,37 @@ test_match_variant(void) size_t const len; char const* const expression; size_t const matched; + VA_Variant const variant; } const tests[] = { - {0, NULL, 0}, - {0, "", 0}, - {1, "1", 0}, - {4, "1del", 4}, - {4, "0del", 0}, - {5, "1delT", 5}, - {7, "1delins", 0}, - {8, "1delinsA", 8}, - {9, "1delAinsA", 9}, - {6, "1_2ins", 0}, - {4, "1ins", 0}, - {6, "0_1ins", 0}, - {6, "1_3ins", 0}, - {7, "1_2insT", 7}, - {2, "1>", 0}, - {3, "1A>", 0}, - {4, "1A>T", 4}, + {0, NULL, 0, {0}}, + {0, "", 0, {0}}, + {1, "1", 0, {0, 1, 0, 0}}, + {4, "1del", 4, {0, 1, 0, 0}}, + {4, "0del", 0, {0}}, + {5, "1delT", 5, {0, 1, 0, 0}}, + {7, "1delins", 0, {0, 1, 7, 0}}, + {8, "1delinsA", 8, {0, 1, 7, 8}}, + {9, "1delAinsA", 9, {0, 1, 8, 9}}, + {6, "1_2ins", 0, {1, 1, 6, 0}}, + {4, "1ins", 0, {1, 1, 0, 0}}, + {6, "0_1ins", 0, {0, 0, 6, 0}}, + {7, "0_1insA", 7, {0, 0, 6, 7}}, + {6, "1_3ins", 0, {1, 3, 0, 0}}, + {7, "1_2insT", 7, {1, 1, 6, 7}}, + {2, "0>", 0, {0}}, + {2, "1>", 0, {0, 1, 2, 0}}, + {3, "1A>", 0, {0, 1, 3, 0}}, + {4, "1A>T", 4, {0, 1, 3, 4}}, }; // tests fprintf(stderr, "%s:%s: ", __FILE__, __func__); for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) { - size_t const tok = va_parse_hgvs(tests[i].len, tests[i].expression); + VA_Variant var = {0}; + size_t const tok = match_variant(tests[i].len, tests[i].expression, &var); assert(tok == tests[i].matched); + assert(variant_eq(var, tests[i].variant)); fprintf(stderr, "."); } // for fprintf(stderr, " passed\n"); @@ -280,40 +298,49 @@ test_va_parse_hgvs(void) static struct { size_t const len; char const* const expression; - size_t const matched; + size_t const count; + VA_Variant const variants[MAX_VARIANTS]; } const tests[] = { - { 0, NULL, 0}, - { 0, "", 0}, - { 1, "A", 0}, - { 1, ":", 0}, - { 1, "g", 0}, - { 2, "g.", 0}, - { 3, ":g.", 0}, - { 1, "1", 0}, - { 3, "A:1", 0}, - { 5, "A:g.1", 0}, - { 7, "A:g.1_2", 0}, - { 1, "=", 1}, - { 3, "g.=", 3}, - { 4, "1del", 4}, - { 6, "g.1del", 6}, - { 6, "A:1del", 6}, - { 8, "A:g.1del", 8}, - { 1, "[", 0}, - { 5, "[1del", 0}, - { 6, "[1del;", 0}, - { 6, "[1del]", 6}, - {10, "[1del;2del", 0}, - {11, "[1del;2del]", 11}, - {10, "[1del2del]", 0}, + { 0, NULL, 0, {{0}}}, + { 0, "", 0, {{0}}}, + { 1, "A", 0, {{0}}}, + { 1, ":", 0, {{0}}}, + { 1, "g", 0, {{0}}}, + { 2, "g.", 0, {{0}}}, + { 3, ":g.", 0, {{0}}}, + { 1, "1", 0, {{0}}}, + { 3, "A:1", 0, {{0}}}, + { 5, "A:g.1", 0, {{0}}}, + { 7, "A:g.1_2", 0, {{0}}}, + { 1, "=", 1, {{0}}}, + { 3, "g.=", 1, {{0}}}, + { 4, "1del", 1, {{0, 1, 0, 0}}}, + { 6, "g.1del", 1, {{0, 1, 0, 0}}}, + { 6, "A:1del", 1, {{0, 1, 0, 0}}}, + { 8, "A:g.1del", 1, {{0, 1, 0, 0}}}, + { 5, "1del ", 0, {{0}}}, + { 1, "[", 0, {{0}}}, + { 5, "[1del", 0, {{0}}}, + { 6, "[1del;", 0, {{0}}}, + { 6, "[1del]", 1, {{0, 1, 0, 0}}}, + { 7, "[1del] ", 0, {{0}}}, + {10, "[1del;2del", 0, {{0}}}, + {11, "[1del;2del]", 2, {{0, 1, 0, 0}, {1, 2, 0, 0}}}, + {10, "[1del2del]", 0, {{0}}}, + {16, "[1del;2del;3del]", 0, {{0}}}, }; // tests fprintf(stderr, "%s:%s: ", __FILE__, __func__); for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) { - size_t const tok = va_parse_hgvs(tests[i].len, tests[i].expression); - assert(tok == tests[i].matched); + VA_Variant variants[MAX_VARIANTS] = {{0}}; + size_t const tok = va_parse_hgvs(tests[i].len, tests[i].expression, MAX_VARIANTS, variants); + assert(tok == tests[i].count); + for (size_t j = 0; j < tests[i].count; ++j) + { + assert(variant_eq(variants[j], tests[i].variants[j])); + } // for fprintf(stderr, "."); } // for fprintf(stderr, " passed\n"); @@ -326,31 +353,34 @@ test_va_parse_spdi(void) static struct { size_t const len; char const* const expression; - size_t const matched; + size_t const count; + VA_Variant const variant; } const tests[] = { - {0, NULL, 0}, - {0, "", 0}, - {1, "A", 0}, - {1, ":", 0}, - {2, "A:", 0}, - {3, "A:1", 0}, - {4, "A:1:", 0}, - {5, "A:1:1", 0}, - {5, "A:1:A", 0}, - {6, "A:1:1:", 0}, - {6, "A:1:A:", 0}, - {7, "A:1:1:A", 7}, - {7, "A:1:A:A", 7}, - {8, "A:1:A:A ", 0}, - {6, ":1:A:A", 6}, + {0, NULL, 0, {0}}, + {0, "", 0, {0}}, + {1, "A", 0, {0}}, + {1, ":", 0, {0}}, + {2, "A:", 0, {0}}, + {3, "A:1", 0, {1, 0, 0, 0}}, + {4, "A:1:", 0, {1, 0, 0, 0}}, + {5, "A:1:1", 0, {1, 2, 0, 0}}, + {5, "A:1:A", 0, {1, 2, 0, 0}}, + {6, "A:1:1:", 0, {1, 2, 6, 0}}, + {6, "A:1:A:", 0, {1, 2, 6, 0}}, + {7, "A:1:1:A", 1, {1, 2, 6, 7}}, + {7, "A:1:A:A", 1, {1, 2, 6, 7}}, + {8, "A:1:A:A ", 0, {1, 2, 6, 7}}, + {6, ":1:A:A", 1, {1, 2, 5, 6}}, }; // tests fprintf(stderr, "%s:%s: ", __FILE__, __func__); for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) { - size_t const tok = va_parse_spdi(tests[i].len, tests[i].expression); - assert(tok == tests[i].matched); + VA_Variant variants[1] = {{0}}; + size_t const tok = va_parse_spdi(tests[i].len, tests[i].expression, variants); + assert(tok == tests[i].count); + assert(variant_eq(variants[0], tests[i].variant)); fprintf(stderr, "."); } // for fprintf(stderr, " passed\n"); From edb52b2c031f26bccfc931a09f21105628c0f55b Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 9 Apr 2024 08:25:06 +0200 Subject: [PATCH 021/704] Use strncmp in tests --- tests/test_parser.c | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/tests/test_parser.c b/tests/test_parser.c index 365ec40..391a01c 100644 --- a/tests/test_parser.c +++ b/tests/test_parser.c @@ -4,6 +4,7 @@ #include // UINT32_MAX, uint32_t #include // stderr, fprintf #include // EXIT_SUCCESS +#include // memcmp #include "../src/parser.c" @@ -12,14 +13,6 @@ #define MAX_VARIANTS 2 -static inline bool -variant_eq(VA_Variant const lhs, VA_Variant const rhs) -{ - return lhs.start == rhs.start && lhs.end == rhs.end && - lhs.obs_start == rhs.obs_start && lhs.obs_end == rhs.obs_end; -} // variant_eq - - static void test_is_digit(void) { @@ -282,10 +275,10 @@ test_match_variant(void) fprintf(stderr, "%s:%s: ", __FILE__, __func__); for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) { - VA_Variant var = {0}; - size_t const tok = match_variant(tests[i].len, tests[i].expression, &var); + VA_Variant variant = {0}; + size_t const tok = match_variant(tests[i].len, tests[i].expression, &variant); assert(tok == tests[i].matched); - assert(variant_eq(var, tests[i].variant)); + assert(memcmp(&variant, &tests[i].variant, sizeof(variant)) == 0); fprintf(stderr, "."); } // for fprintf(stderr, " passed\n"); @@ -337,10 +330,7 @@ test_va_parse_hgvs(void) VA_Variant variants[MAX_VARIANTS] = {{0}}; size_t const tok = va_parse_hgvs(tests[i].len, tests[i].expression, MAX_VARIANTS, variants); assert(tok == tests[i].count); - for (size_t j = 0; j < tests[i].count; ++j) - { - assert(variant_eq(variants[j], tests[i].variants[j])); - } // for + assert(memcmp(&variants, &tests[i].variants, sizeof(variants[0]) * tests[i].count) == 0); fprintf(stderr, "."); } // for fprintf(stderr, " passed\n"); @@ -354,7 +344,7 @@ test_va_parse_spdi(void) size_t const len; char const* const expression; size_t const count; - VA_Variant const variant; + VA_Variant const variants; } const tests[] = { {0, NULL, 0, {0}}, @@ -380,7 +370,7 @@ test_va_parse_spdi(void) VA_Variant variants[1] = {{0}}; size_t const tok = va_parse_spdi(tests[i].len, tests[i].expression, variants); assert(tok == tests[i].count); - assert(variant_eq(variants[0], tests[i].variant)); + assert(memcmp(&variants, &tests[i].variants, sizeof(variants[0])) == 0); fprintf(stderr, "."); } // for fprintf(stderr, " passed\n"); From 3e5f2775909c524379a9fc498c38e74e9146441c Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 9 Apr 2024 08:25:39 +0200 Subject: [PATCH 022/704] WIP patch --- include/variant.h | 7 +++++++ src/variant.c | 50 ++++++++++++++++++++++++++++++++++++++++++++ tests/test_variant.c | 38 +++++++++++++++++++++++++++++++++ 3 files changed, 95 insertions(+) diff --git a/include/variant.h b/include/variant.h index d8c9f7d..b31a8d0 100644 --- a/include/variant.h +++ b/include/variant.h @@ -28,6 +28,13 @@ size_t va_variant_len(VA_Variant const variant); +size_t +va_patch(size_t const len_ref, char const reference[static len_ref], + size_t const len_obs, char const observed[static len_obs], + size_t const len_var, VA_Variant const variants[len_var], + size_t const len, char string[static len]); + + #ifdef __cplusplus } // extern "C" #endif diff --git a/src/variant.c b/src/variant.c index fa2f810..b678090 100644 --- a/src/variant.c +++ b/src/variant.c @@ -4,6 +4,17 @@ #include "../include/variant.h" // VA_*, va_* +static void +string_copy(size_t const len, char const source[static len], + char dest[static len]) +{ + for (size_t i = 0; i < len; ++i) + { + dest[i] = source[i]; + } // for +} // string_copy + + bool va_variant_eq(VA_Variant const lhs, VA_Variant const rhs) { @@ -17,3 +28,42 @@ va_variant_len(VA_Variant const variant) { return variant.end - variant.start + variant.obs_end - variant.obs_start; } // va_variant_len + + +size_t +va_patch(size_t const len_ref, char const reference[static len_ref], + size_t const len_obs, char const observed[static len_obs], + size_t const len_var, VA_Variant const variants[len_var], + size_t const len, char string[static len]) +{ + size_t idx = 0; + size_t start = 0; + for (size_t i = 0; i < len_var; ++i) + { + size_t len_slice = variants[i].start - start; + if (len - idx < len_slice) + { + return 0; // not enough space + } // if + string_copy(len_slice, reference + start, string + idx); + idx += len_slice; + + len_slice = variants[i].obs_end - variants[i].obs_start; + if (len - idx < len_slice) + { + return 0; // not enough space + } // if + string_copy(len_slice, observed + variants[i].obs_start, string + idx); + idx += len_slice; + + start = variants[i].end; + } // for + + size_t const len_slice = len_ref - start; + if (len - idx < len_slice) + { + return 0; // not enough space + } // if + string_copy(len_slice, reference + start, string + idx); + return idx + len_slice; +} // va_patch diff --git a/tests/test_variant.c b/tests/test_variant.c index eb1b363..33ac162 100644 --- a/tests/test_variant.c +++ b/tests/test_variant.c @@ -3,6 +3,7 @@ #include // size_t #include // stderr, fprintf #include // EXIT_SUCCESS +#include // strncmp #include "../src/variant.c" @@ -62,10 +63,47 @@ test_va_variant_len(void) } // test_va_variant_len +static void +test_va_patch(void) +{ + static struct { + size_t const len_ref; + char const* const reference; + size_t const len_obs; + char const* const observed; + size_t const len_var; + VA_Variant const variants[256]; + char const* const expected; + } const tests[] = + { + {5, "AAAAA", 0, "", 0, {{0}}, "AAAAA"}, + {5, "AAAAA", 0, "", 1, {{0, 1, 0, 0}}, "AAAA"}, + {5, "AAAAA", 1, "T", 1, {{0, 1, 0, 1}}, "TAAAA"}, + {5, "AAAAA", 1, "T", 1, {{2, 3, 0, 1}}, "AATAA"}, + {5, "AAAAA", 1, "T", 1, {{8, 9, 0, 1}}, ""}, + }; // tests + + fprintf(stderr, "%s:%s: ", __FILE__, __func__); + for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) + { + char buffer[5] = {'\0'}; + size_t const len = va_patch(tests[i].len_ref, tests[i].reference, + tests[i].len_obs, tests[i].observed, + tests[i].len_var, tests[i].variants, + 5, buffer); + //printf("%zu\n", len); + assert(strncmp(buffer, tests[i].expected, len) == 0); + fprintf(stderr, "."); + } // for + fprintf(stderr, " passed\n"); +} // test_va_patch + + int main(void) { test_va_variant_eq(); test_va_variant_len(); + test_va_patch(); return EXIT_SUCCESS; } // main From 1c3ac63c8aa0a0881c61183d05d412651b21d7d8 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 9 Apr 2024 10:09:59 +0200 Subject: [PATCH 023/704] Updated to gcc>=11 --- Makefile | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 2bbb205..99c54a0 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ TEST_COVS = $(TESTS:.c=.c.gcov) TARGET = a.out -CC = gcc +CC = gcc-11 CFLAGS = -std=c11 -march=native -Wall -Wextra -Wpedantic MEMCHECK = valgrind -q --leak-check=full --error-exitcode=1 @@ -29,7 +29,7 @@ release: CFLAGS+=-O3 debug release: $(TARGET) -check: CFLAGS+=-O0 -g -DDEBUG -ftest-coverage -fprofile-arcs \ +check: CFLAGS+=-O0 -g -DDEBUG -ftest-coverage -fprofile-arcs -dumpbase '' \ -fkeep-inline-functions -fkeep-static-functions check: $(TEST_BINS) $(TESTS_GCNOS) $(TEST_GCDAS) $(TEST_COVS) @@ -48,15 +48,12 @@ $(TARGET): $(OBJECTS) %.out: %.c $(CC) $(CFLAGS) $(CPPFLAGS) -MMD -o $@ $< - mv $(notdir $(@:.out=.gcno)) $(TEST_DIR) %.gcda: %.out $(MEMCHECK) ./$< - mv $(notdir $@) $(TEST_DIR) %.c.gcov: %.gcda - gcov $< - mv *.c.gcov $(TEST_DIR) + cd $(TEST_DIR) && gcov $(notdir $<) -include $(DEPS) From 6b0ef36c41f9e40ea8ecac8ced496d6af94ea000 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 9 Apr 2024 10:18:58 +0200 Subject: [PATCH 024/704] Fix gcov run dir --- Makefile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 99c54a0..bdbc595 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ TEST_COVS = $(TESTS:.c=.c.gcov) TARGET = a.out CC = gcc-11 -CFLAGS = -std=c11 -march=native -Wall -Wextra -Wpedantic +CFLAGS = -std=c11 -march=native -Wall -Wextra -Wpedantic -fanalyzer MEMCHECK = valgrind -q --leak-check=full --error-exitcode=1 @@ -53,7 +53,8 @@ $(TARGET): $(OBJECTS) $(MEMCHECK) ./$< %.c.gcov: %.gcda - cd $(TEST_DIR) && gcov $(notdir $<) + gcov $< + mv *.c.gcov $(TEST_DIR) -include $(DEPS) From b26f291ea1a8bb965172b47373ef7dd189a7f908 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 9 Apr 2024 16:18:52 +0200 Subject: [PATCH 025/704] WIP patch --- src/variant.c | 24 +++++++++++++++++------- tests/test_variant.c | 14 +++++++++----- 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/src/variant.c b/src/variant.c index b678090..87e7503 100644 --- a/src/variant.c +++ b/src/variant.c @@ -5,8 +5,8 @@ static void -string_copy(size_t const len, char const source[static len], - char dest[static len]) +string_copy(size_t const len, char const source[static restrict len], + char dest[static restrict len]) { for (size_t i = 0; i < len; ++i) { @@ -31,10 +31,10 @@ va_variant_len(VA_Variant const variant) size_t -va_patch(size_t const len_ref, char const reference[static len_ref], - size_t const len_obs, char const observed[static len_obs], +va_patch(size_t const len_ref, char const reference[static restrict len_ref], + size_t const len_obs, char const observed[static restrict len_obs], size_t const len_var, VA_Variant const variants[len_var], - size_t const len, char string[static len]) + size_t const len, char string[static restrict len]) { size_t idx = 0; size_t start = 0; @@ -43,15 +43,25 @@ va_patch(size_t const len_ref, char const reference[static len_ref], size_t len_slice = variants[i].start - start; if (len - idx < len_slice) { - return 0; // not enough space + return 0; // not enough space in dest + } // if + if (len_ref - start < len_slice) + { + return 0; // not in reference } // if string_copy(len_slice, reference + start, string + idx); idx += len_slice; len_slice = variants[i].obs_end - variants[i].obs_start; + printf("%zu\n", len_slice); + printf("%zu\n", idx); if (len - idx < len_slice) { - return 0; // not enough space + return 0; // not enough space in dest + } // if + if (len_obs - variants[i].obs_start < len_slice) + { + return 0; // not in observed } // if string_copy(len_slice, observed + variants[i].obs_start, string + idx); idx += len_slice; diff --git a/tests/test_variant.c b/tests/test_variant.c index 33ac162..5ab8569 100644 --- a/tests/test_variant.c +++ b/tests/test_variant.c @@ -76,11 +76,15 @@ test_va_patch(void) char const* const expected; } const tests[] = { - {5, "AAAAA", 0, "", 0, {{0}}, "AAAAA"}, - {5, "AAAAA", 0, "", 1, {{0, 1, 0, 0}}, "AAAA"}, - {5, "AAAAA", 1, "T", 1, {{0, 1, 0, 1}}, "TAAAA"}, - {5, "AAAAA", 1, "T", 1, {{2, 3, 0, 1}}, "AATAA"}, - {5, "AAAAA", 1, "T", 1, {{8, 9, 0, 1}}, ""}, + {5, "AAAAA", 0, "", 0, {{0, 0, 0, 0}}, "AAAAA"}, + {5, "AAAAA", 0, "", 1, {{0, 1, 0, 0}}, "AAAA"}, + {5, "AAAAA", 1, "T", 1, {{0, 1, 0, 1}}, "TAAAA"}, + {5, "AAAAA", 1, "T", 1, {{2, 3, 0, 1}}, "AATAA"}, + {5, "AAAAA", 1, "T", 1, {{8, 9, 0, 1}}, ""}, + {5, "AAAAA", 1, "T", 1, {{0, 0, 0, 1}}, ""}, + {3, "AAA", 0, "", 1, {{4, 5, 0, 0}}, ""}, + {5, "AAAAA", 0, "", 1, {{1, 1, 0, 1}}, ""}, + {5, "AAAAA", 2, "TT", 1, {{4, 4, 0, 2}}, ""}, }; // tests fprintf(stderr, "%s:%s: ", __FILE__, __func__); From 6b5460120c0f3a0041b84b0dac7af8a7b3c2d819 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 9 Apr 2024 16:27:51 +0200 Subject: [PATCH 026/704] Removed debug info --- src/variant.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/variant.c b/src/variant.c index 87e7503..67dabd4 100644 --- a/src/variant.c +++ b/src/variant.c @@ -53,8 +53,6 @@ va_patch(size_t const len_ref, char const reference[static restrict len_ref], idx += len_slice; len_slice = variants[i].obs_end - variants[i].obs_start; - printf("%zu\n", len_slice); - printf("%zu\n", idx); if (len - idx < len_slice) { return 0; // not enough space in dest From f4673a60e6bbc40985c53feec7f05d552920f462 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 9 Apr 2024 17:02:20 +0200 Subject: [PATCH 027/704] WIP Python extension --- include/edit.h | 21 --------------- python/algebra/__init__.py | 2 +- python/algebra/lcs/__init__.py | 4 --- python/algebra/variants/__init__.py | 5 ++++ python/ext/algebra_ext.c | 42 ++++++++++++++++++++++++----- python/setup.py | 23 +++++++--------- src/edit.c | 10 ------- 7 files changed, 50 insertions(+), 57 deletions(-) delete mode 100644 include/edit.h delete mode 100644 python/algebra/lcs/__init__.py create mode 100644 python/algebra/variants/__init__.py delete mode 100644 src/edit.c diff --git a/include/edit.h b/include/edit.h deleted file mode 100644 index f64f3d3..0000000 --- a/include/edit.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef VARALG_EDIT_H -#define VARALG_EDIT_H - -#ifdef __cplusplus -extern "C" -{ -#endif - - -#include - - -size_t -varalg_edit(size_t const lhs, size_t const rhs); - - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif diff --git a/python/algebra/__init__.py b/python/algebra/__init__.py index f2919ce..faf5a50 100644 --- a/python/algebra/__init__.py +++ b/python/algebra/__init__.py @@ -1,4 +1,4 @@ """A Boolean Algebra for Genetic Variants.""" -from algebra_ext import hello +#from algebra_ext import Variant diff --git a/python/algebra/lcs/__init__.py b/python/algebra/lcs/__init__.py deleted file mode 100644 index 7650271..0000000 --- a/python/algebra/lcs/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -"""Longest Common Subsequence alignments.""" - - -from lcs_ext import edit diff --git a/python/algebra/variants/__init__.py b/python/algebra/variants/__init__.py new file mode 100644 index 0000000..0dbaa4a --- /dev/null +++ b/python/algebra/variants/__init__.py @@ -0,0 +1,5 @@ +"""Variant model and parsers.""" + + +from algebra_ext import parse_hgvs, parse_spdi + diff --git a/python/ext/algebra_ext.c b/python/ext/algebra_ext.c index be11d63..c45a9b9 100644 --- a/python/ext/algebra_ext.c +++ b/python/ext/algebra_ext.c @@ -3,21 +3,48 @@ #include // NULL, size_t +#include "../include/parser.h" // va_parse_* +#include "../include/variant.h" // VA_Variant + static PyObject* -hello(PyObject* self, PyObject* args, PyObject* kwargs) +parse_hgvs(PyObject* self, PyObject* args, PyObject* kwargs) { (void) self; - size_t lhs = 0; - size_t rhs = 40; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|i:hello", (char*[3]) {"lhs", "rhs", NULL}, &lhs, &rhs)) + char const* expression = NULL; + size_t len = 0; + char const* reference = NULL; + size_t len_ref = 0; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#|z#:parse_hgvs", (char*[3]) {"expression", "reference", NULL}, &expression, &len, &reference, &len_ref)) { return NULL; } // if - return Py_BuildValue("i", lhs * rhs); -} // hello + VA_Variant variants[256] = {{0}}; + size_t const count = va_parse_hgvs(len, expression, 256, variants); + + return Py_BuildValue("i", count); +} // parse_hgvs + + +static PyObject* +parse_spdi(PyObject* self, PyObject* args, PyObject* kwargs) +{ + (void) self; + + char const* expression = NULL; + size_t len = 0; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#:parse_spdi", (char*[2]) {"expression", NULL}, &expression, &len)) + { + return NULL; + } // if + + VA_Variant variants[1] = {{0}}; + size_t const count = va_parse_spdi(len, expression, variants); + + return Py_BuildValue("i", count); +} // parse_spdi static struct PyModuleDef def = @@ -27,7 +54,8 @@ static struct PyModuleDef def = .m_doc = "Algebra C extension", .m_size = -1, .m_methods = (PyMethodDef[]) { - {"hello", (PyCFunction) (void(*)(void)) hello, METH_VARARGS | METH_KEYWORDS, "Hello from parent"}, + {"parse_hgvs", (PyCFunction) (void(*)(void)) parse_hgvs, METH_VARARGS | METH_KEYWORDS, "Parse HGVS expression"}, + {"parse_spdi", (PyCFunction) (void(*)(void)) parse_spdi, METH_VARARGS | METH_KEYWORDS, "Parse SPDI expression"}, {NULL, NULL, 0, NULL} }, }; diff --git a/python/setup.py b/python/setup.py index 11385f2..39b1b14 100644 --- a/python/setup.py +++ b/python/setup.py @@ -1,23 +1,18 @@ from setuptools import Extension, setup -compile_args = [ - "-Wextra", - "-Wpedantic", - "-std=c99", -] - - setup( ext_modules = [ - Extension("algebra_ext", extra_compile_args=compile_args, - sources=[ - "ext/algebra_ext.c" - ]), - Extension("lcs_ext", extra_compile_args=compile_args, + Extension("algebra_ext", + extra_compile_args=[ + "-Wextra", + "-Wpedantic", + "-std=c11", + ], sources=[ - "ext/lcs_ext.c", - "src/edit.c" + "ext/algebra_ext.c", + "src/parser.c", + "src/variant.c", ]), ], ) diff --git a/src/edit.c b/src/edit.c deleted file mode 100644 index 2a690da..0000000 --- a/src/edit.c +++ /dev/null @@ -1,10 +0,0 @@ -#include // size_t - -#include "../include/edit.h" // varalg_edit - - -size_t -varalg_edit(size_t const lhs, size_t const rhs) -{ - return lhs + rhs; -} // varalg_edit From 33c553113268e778a7271590873b96b97ed67d77 Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 10 Apr 2024 09:54:58 +0200 Subject: [PATCH 028/704] gcov version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index bdbc595..ed4fb77 100644 --- a/Makefile +++ b/Makefile @@ -53,7 +53,7 @@ $(TARGET): $(OBJECTS) $(MEMCHECK) ./$< %.c.gcov: %.gcda - gcov $< + gcov-11 $< mv *.c.gcov $(TEST_DIR) From 17b41fb19afac3882942b0baaeff4daf86d7aad1 Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 22 Apr 2024 12:38:07 +0200 Subject: [PATCH 029/704] Dynamic array --- include/alloc.h | 23 +++++++++++++++++++ include/array.h | 46 +++++++++++++++++++++++++++++++++++++ include/variant.h | 2 +- python/ext/algebra_ext.c | 8 +++---- src/array.c | 49 ++++++++++++++++++++++++++++++++++++++++ src/main.c | 42 ++++++++++++++++++++++++---------- 6 files changed, 153 insertions(+), 17 deletions(-) create mode 100644 include/alloc.h create mode 100644 include/array.h create mode 100644 src/array.c diff --git a/include/alloc.h b/include/alloc.h new file mode 100644 index 0000000..0edfdfd --- /dev/null +++ b/include/alloc.h @@ -0,0 +1,23 @@ +#ifndef ALLOC_H +#define ALLOC_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include // size_t + + +typedef struct +{ + void* (*alloc)(void* const context, void* const ptr, size_t const old_size, size_t const size); + void* context; +} VA_Allocator; + + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif diff --git a/include/array.h b/include/array.h new file mode 100644 index 0000000..ad7f612 --- /dev/null +++ b/include/array.h @@ -0,0 +1,46 @@ +#ifndef ARRAY_H +#define ARRAY_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include // size_t + +#include "alloc.h" // VA_Allocator + + +typedef struct +{ + VA_Allocator const* allocator; + size_t capacity; + size_t item_size; + size_t length; +} VA_Array; + + +void* +va_array_init(VA_Allocator const* const allocator, size_t const capacity, size_t const item_size); + + +void* +va_array_ensure(void* const self, size_t const count); + + +void* +va_array_destroy(void* const self); + + +#define \ +va_array_append(self, value) ( \ + (self) = va_array_ensure(self, 1), \ + (self)[((VA_Array*)(self) - 1)->length] = (value), \ + &(self)[((VA_Array*)(self) - 1)->length++]) + + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif diff --git a/include/variant.h b/include/variant.h index b31a8d0..56a37fb 100644 --- a/include/variant.h +++ b/include/variant.h @@ -11,7 +11,7 @@ extern "C" #include // uint32_t -typedef struct VA_Variant +typedef struct { uint32_t start; uint32_t end; diff --git a/python/ext/algebra_ext.c b/python/ext/algebra_ext.c index c45a9b9..f696fa2 100644 --- a/python/ext/algebra_ext.c +++ b/python/ext/algebra_ext.c @@ -8,7 +8,7 @@ static PyObject* -parse_hgvs(PyObject* self, PyObject* args, PyObject* kwargs) +parse_hgvs(PyObject* const self, PyObject* const args, PyObject* const kwargs) { (void) self; @@ -29,7 +29,7 @@ parse_hgvs(PyObject* self, PyObject* args, PyObject* kwargs) static PyObject* -parse_spdi(PyObject* self, PyObject* args, PyObject* kwargs) +parse_spdi(PyObject* const self, PyObject* const args, PyObject* const kwargs) { (void) self; @@ -47,7 +47,7 @@ parse_spdi(PyObject* self, PyObject* args, PyObject* kwargs) } // parse_spdi -static struct PyModuleDef def = +static struct PyModuleDef const def = { .m_base = PyModuleDef_HEAD_INIT, .m_name = "algebra_ext", @@ -56,7 +56,7 @@ static struct PyModuleDef def = .m_methods = (PyMethodDef[]) { {"parse_hgvs", (PyCFunction) (void(*)(void)) parse_hgvs, METH_VARARGS | METH_KEYWORDS, "Parse HGVS expression"}, {"parse_spdi", (PyCFunction) (void(*)(void)) parse_spdi, METH_VARARGS | METH_KEYWORDS, "Parse SPDI expression"}, - {NULL, NULL, 0, NULL} + {NULL, NULL, 0, NULL} // sentinel }, }; diff --git a/src/array.c b/src/array.c new file mode 100644 index 0000000..d69e204 --- /dev/null +++ b/src/array.c @@ -0,0 +1,49 @@ +#include // NULL, size_t + +#include "../include/alloc.h" // VA_Allocator +#include "../include/array.h" // VA_Array, va_array_* + + +void* +va_array_init(VA_Allocator const* const allocator, size_t const capacity, size_t const item_size) +{ + VA_Array* const header = allocator->alloc(allocator->context, NULL, 0, sizeof(*header) + capacity * item_size); // OVERFLOW + if (header == NULL) + { + return NULL; + } // if + header->allocator = allocator; + header->capacity = capacity; + header->item_size = item_size; + header->length = 0; + return header + 1; +} // va_array_init + + +void* +va_array_ensure(void* const self, size_t const count) +{ + VA_Array* header = (VA_Array*)(self) - 1; + size_t const free = header->capacity - header->length; + if (free >= count) + { + return self; + } // if + + size_t const capacity = count - free > 2 * header->capacity ? count - free + 16 / header->item_size : 2 * header->capacity; // OVERFLOW + header = header->allocator->alloc(header->allocator->context, header, sizeof(*header) + header->capacity * header->item_size, sizeof(*header) + capacity * header->item_size); + if (header == NULL) + { + return NULL; + } // if + header->capacity += capacity; + return header + 1; +} // va_array_ensure + + +void* +va_array_destroy(void* const self) +{ + VA_Array* const header = (VA_Array*)(self) - 1; + return header->allocator->alloc(header->allocator->context, header, sizeof(*header) + header->capacity * header->item_size, 0); +} // va_array_destroy diff --git a/src/main.c b/src/main.c index 8c0a414..fc2bb93 100644 --- a/src/main.c +++ b/src/main.c @@ -1,23 +1,41 @@ -#include // stderr, fprintf, printf -#include // EXIT_* -#include // strlen +#include // NULL, size_t +#include // stderr, printf +#include // EXIT_*, free, realloc -#include "../include/parser.h" // va_parse_* -#include "../include/variant.h" // VA_Variant +#include "../include/alloc.h" // VA_Allocator +#include "../include/array.h" // va_array_* -int -main(int argc, char* argv[argc + 1]) +static inline void* +std_alloc(void* const context, void* const ptr, size_t const old_size, size_t const size) { - if (argc < 2) + (void) context; + (void) old_size; + if (size == 0) { - fprintf(stderr, "usage %s expression\n", argv[0]); - return EXIT_FAILURE; + free(ptr); + return NULL; } // if + return realloc(ptr, size); +} // std_alloc + + +static VA_Allocator const std_allocator = { .alloc = std_alloc }; + + +int +main(int argc, char* argv[argc + 1]) +{ + (void) argv; + + int* a = va_array_init(&std_allocator, 1, sizeof(*a)); + + va_array_append(a, 42); + va_array_append(a, 43); - VA_Variant variants[1] = {{0}}; + printf("%d\n", a[1]); - printf("%zu\n", va_parse_spdi(strlen(argv[1]), argv[1], variants)); + a = va_array_destroy(a); return EXIT_SUCCESS; } // main From d81252251563c7ae380a313ffbcb33bad18ff870 Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 22 Apr 2024 16:33:35 +0200 Subject: [PATCH 030/704] Fixed capacity in arrays --- Makefile | 2 +- src/array.c | 6 ++++-- src/main.c | 4 ++-- tests/test_array.c | 37 +++++++++++++++++++++++++++++++++++++ 4 files changed, 44 insertions(+), 5 deletions(-) create mode 100644 tests/test_array.c diff --git a/Makefile b/Makefile index ed4fb77..6ecf6bc 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ TEST_COVS = $(TESTS:.c=.c.gcov) TARGET = a.out CC = gcc-11 -CFLAGS = -std=c11 -march=native -Wall -Wextra -Wpedantic -fanalyzer +CFLAGS = -std=c99 -march=native -Wall -Wextra -Wpedantic -fanalyzer MEMCHECK = valgrind -q --leak-check=full --error-exitcode=1 diff --git a/src/array.c b/src/array.c index d69e204..762f68f 100644 --- a/src/array.c +++ b/src/array.c @@ -30,8 +30,10 @@ va_array_ensure(void* const self, size_t const count) return self; } // if - size_t const capacity = count - free > 2 * header->capacity ? count - free + 16 / header->item_size : 2 * header->capacity; // OVERFLOW - header = header->allocator->alloc(header->allocator->context, header, sizeof(*header) + header->capacity * header->item_size, sizeof(*header) + capacity * header->item_size); + // TODO: proper reallocation scheme + static size_t const extra = 16; + size_t const capacity = count - free + extra > 2 * header->capacity ? count - free + extra : 2 * header->capacity; // OVERFLOW + header = header->allocator->alloc(header->allocator->context, header, sizeof(*header) + header->capacity * header->item_size, sizeof(*header) + (header->capacity + capacity) * header->item_size); if (header == NULL) { return NULL; diff --git a/src/main.c b/src/main.c index fc2bb93..b4565c5 100644 --- a/src/main.c +++ b/src/main.c @@ -29,11 +29,11 @@ main(int argc, char* argv[argc + 1]) (void) argv; int* a = va_array_init(&std_allocator, 1, sizeof(*a)); - va_array_append(a, 42); va_array_append(a, 43); + va_array_append(a, 44); - printf("%d\n", a[1]); + printf("%d\n", a[2]); a = va_array_destroy(a); diff --git a/tests/test_array.c b/tests/test_array.c new file mode 100644 index 0000000..b7d7951 --- /dev/null +++ b/tests/test_array.c @@ -0,0 +1,37 @@ +#include // NULL, size_t +#include // EXIT_SUCCESS, free, realloc + +#include "../include/alloc.h" // VA_Allocator + + +#include "../src/array.c" + + +static inline void* +std_alloc(void* const context, void* const ptr, size_t const old_size, size_t const size) +{ + (void) context; + (void) old_size; + if (size == 0) + { + free(ptr); + return NULL; + } // if + return realloc(ptr, size); +} // std_alloc + + +static VA_Allocator const std_allocator = { .alloc = std_alloc }; + + +int +main(void) +{ + int* a = va_array_init(&std_allocator, 1, sizeof(*a)); + va_array_append(a, 42); + va_array_append(a, 43); + va_array_append(a, 44); + a = va_array_destroy(a); + + return EXIT_SUCCESS; +} // main From b516cadee80d72b6a09b63171913afebfbf0100c Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 22 Apr 2024 20:21:36 +0200 Subject: [PATCH 031/704] Style --- include/array.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/array.h b/include/array.h index ad7f612..70ea066 100644 --- a/include/array.h +++ b/include/array.h @@ -36,7 +36,8 @@ va_array_destroy(void* const self); va_array_append(self, value) ( \ (self) = va_array_ensure(self, 1), \ (self)[((VA_Array*)(self) - 1)->length] = (value), \ - &(self)[((VA_Array*)(self) - 1)->length++]) + &(self)[((VA_Array*)(self) - 1)->length++] \ +) // va_array_append #ifdef __cplusplus From 10a3961284d5c40c55dcb11c034e36ea01805263 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 23 Apr 2024 14:56:16 +0200 Subject: [PATCH 032/704] Removed allocator + simple dynamic growth --- include/array.h | 13 ++-- src/array.c | 38 +++++---- src/main.c | 33 +------- tests/test_array.c | 190 +++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 213 insertions(+), 61 deletions(-) diff --git a/include/array.h b/include/array.h index 70ea066..5c48540 100644 --- a/include/array.h +++ b/include/array.h @@ -13,7 +13,6 @@ extern "C" typedef struct { - VA_Allocator const* allocator; size_t capacity; size_t item_size; size_t length; @@ -25,18 +24,18 @@ va_array_init(VA_Allocator const* const allocator, size_t const capacity, size_t void* -va_array_ensure(void* const self, size_t const count); +va_array_ensure(VA_Allocator const* const allocator, void* const ptr, size_t const count); void* -va_array_destroy(void* const self); +va_array_destroy(VA_Allocator const* const allocator, void* const ptr); #define \ -va_array_append(self, value) ( \ - (self) = va_array_ensure(self, 1), \ - (self)[((VA_Array*)(self) - 1)->length] = (value), \ - &(self)[((VA_Array*)(self) - 1)->length++] \ +va_array_append(allocator, ptr, value) ( \ + (ptr) = va_array_ensure(allocator, ptr, 1), \ + (ptr)[((VA_Array*)(ptr) - 1)->length] = (value), \ + &(ptr)[((VA_Array*)(ptr) - 1)->length++] \ ) // va_array_append diff --git a/src/array.c b/src/array.c index 762f68f..063c403 100644 --- a/src/array.c +++ b/src/array.c @@ -7,13 +7,13 @@ void* va_array_init(VA_Allocator const* const allocator, size_t const capacity, size_t const item_size) { - VA_Array* const header = allocator->alloc(allocator->context, NULL, 0, sizeof(*header) + capacity * item_size); // OVERFLOW + size_t const min_capacity = capacity < 4 ? 4 : capacity; + VA_Array* const header = allocator->alloc(allocator->context, NULL, 0, sizeof(*header) + min_capacity * item_size); // OVERFLOW if (header == NULL) { return NULL; } // if - header->allocator = allocator; - header->capacity = capacity; + header->capacity = min_capacity; header->item_size = item_size; header->length = 0; return header + 1; @@ -21,31 +21,37 @@ va_array_init(VA_Allocator const* const allocator, size_t const capacity, size_t void* -va_array_ensure(void* const self, size_t const count) +va_array_ensure(VA_Allocator const* const allocator, void* const ptr, size_t const count) { - VA_Array* header = (VA_Array*)(self) - 1; - size_t const free = header->capacity - header->length; - if (free >= count) + VA_Array* header = (VA_Array*)(ptr) - 1; + if (header->capacity - header->length >= count) { - return self; + return ptr; } // if - // TODO: proper reallocation scheme - static size_t const extra = 16; - size_t const capacity = count - free + extra > 2 * header->capacity ? count - free + extra : 2 * header->capacity; // OVERFLOW - header = header->allocator->alloc(header->allocator->context, header, sizeof(*header) + header->capacity * header->item_size, sizeof(*header) + (header->capacity + capacity) * header->item_size); + size_t const old_size = sizeof(*header) + header->capacity * header->item_size; + header->capacity *= 2; // OVERFLOW + while (header->capacity - header->length < count) + { + header->capacity *= 2; // OVERFLOW + } // while + + header = allocator->alloc(allocator->context, header, old_size, sizeof(*header) + header->capacity * header->item_size); // OVERFLOW if (header == NULL) { return NULL; } // if - header->capacity += capacity; return header + 1; } // va_array_ensure void* -va_array_destroy(void* const self) +va_array_destroy(VA_Allocator const* const allocator, void* const ptr) { - VA_Array* const header = (VA_Array*)(self) - 1; - return header->allocator->alloc(header->allocator->context, header, sizeof(*header) + header->capacity * header->item_size, 0); + if (ptr == NULL) + { + return NULL; + } // if + VA_Array* const header = (VA_Array*)(ptr) - 1; + return allocator->alloc(allocator->context, header, sizeof(*header) + header->capacity * header->item_size, 0); } // va_array_destroy diff --git a/src/main.c b/src/main.c index b4565c5..753f5f5 100644 --- a/src/main.c +++ b/src/main.c @@ -1,26 +1,4 @@ -#include // NULL, size_t -#include // stderr, printf -#include // EXIT_*, free, realloc - -#include "../include/alloc.h" // VA_Allocator -#include "../include/array.h" // va_array_* - - -static inline void* -std_alloc(void* const context, void* const ptr, size_t const old_size, size_t const size) -{ - (void) context; - (void) old_size; - if (size == 0) - { - free(ptr); - return NULL; - } // if - return realloc(ptr, size); -} // std_alloc - - -static VA_Allocator const std_allocator = { .alloc = std_alloc }; +#include // EXIT_* int @@ -28,14 +6,5 @@ main(int argc, char* argv[argc + 1]) { (void) argv; - int* a = va_array_init(&std_allocator, 1, sizeof(*a)); - va_array_append(a, 42); - va_array_append(a, 43); - va_array_append(a, 44); - - printf("%d\n", a[2]); - - a = va_array_destroy(a); - return EXIT_SUCCESS; } // main diff --git a/tests/test_array.c b/tests/test_array.c index b7d7951..4c8f4f9 100644 --- a/tests/test_array.c +++ b/tests/test_array.c @@ -1,5 +1,9 @@ +#include // assert #include // NULL, size_t +#include // uint32_t +#include // stderr, fprintf #include // EXIT_SUCCESS, free, realloc +#include // memcmp #include "../include/alloc.h" // VA_Allocator @@ -21,17 +25,191 @@ std_alloc(void* const context, void* const ptr, size_t const old_size, size_t co } // std_alloc +static inline void* +null_alloc(void* const context, void* const ptr, size_t const old_size, size_t const size) +{ + (void) context; + (void) ptr; + (void) old_size; + (void) size; + return NULL; +} // null_alloc + + static VA_Allocator const std_allocator = { .alloc = std_alloc }; +static VA_Allocator const null_allocator = { .alloc = null_alloc }; + + +static void +test_va_array_init(void) +{ + static struct { + VA_Allocator const* const allocator; + size_t const capacity; + VA_Array const header; + } const tests[] = + { + {&std_allocator, 0, { 4, 4, 0}}, + {&std_allocator, 1, { 4, 4, 0}}, + {&std_allocator, 4, { 4, 4, 0}}, + {&std_allocator, 5, { 5, 4, 0}}, + {&std_allocator, 100, {100, 4, 0}}, + }; // tests + + fprintf(stderr, "%s:%s: ", __FILE__, __func__); + for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) + { + uint32_t* array = va_array_init(tests[i].allocator, tests[i].capacity, sizeof(*array)); + assert(memcmp(((VA_Array*) array) - 1, &tests[i].header, sizeof(tests[i].header)) == 0); + array = va_array_destroy(tests[i].allocator, array); + fprintf(stderr, "."); + } // for + fprintf(stderr, " passed\n"); +} // test_va_array_init + + +static void +test_va_array_init_null(void) +{ + static struct { + size_t const capacity; + } const tests[] = + { + {1}, + }; // tests + + fprintf(stderr, "%s:%s: ", __FILE__, __func__); + for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) + { + assert(va_array_init(&null_allocator, tests[i].capacity, sizeof(uint32_t)) == NULL); + fprintf(stderr, "."); + } // for + fprintf(stderr, " passed\n"); +} // test_va_array_init_null + + +static void +test_va_array_ensure(void) +{ + static struct { + VA_Allocator const* const allocator; + size_t const capacity; + size_t const count; + VA_Array const header; + } const tests[] = + { + {&std_allocator, 0, 0, { 4, 4, 0}}, + {&std_allocator, 0, 1, { 4, 4, 0}}, + {&std_allocator, 0, 4, { 4, 4, 0}}, + {&std_allocator, 0, 5, { 8, 4, 0}}, + {&std_allocator, 100, 100, {100, 4, 0}}, + {&std_allocator, 100, 101, {200, 4, 0}}, + {&std_allocator, 0, 100, {128, 4, 0}}, + }; // tests + + fprintf(stderr, "%s:%s: ", __FILE__, __func__); + for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) + { + uint32_t* array = va_array_init(tests[i].allocator, tests[i].capacity, sizeof(*array)); + array = va_array_ensure(tests[i].allocator, array, tests[i].count); + assert(memcmp(((VA_Array*) array) - 1, &tests[i].header, sizeof(tests[i].header)) == 0); + array = va_array_destroy(tests[i].allocator, array); + fprintf(stderr, "."); + } // for + fprintf(stderr, " passed\n"); +} // test_va_array_ensure + + +static void +test_va_array_ensure_null(void) +{ + static struct { + size_t const capacity; + size_t const count; + } const tests[] = + { + {0, 5}, + }; // tests + + fprintf(stderr, "%s:%s: ", __FILE__, __func__); + for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) + { + uint32_t* array = va_array_init(&std_allocator, tests[i].capacity, sizeof(*array)); + assert(va_array_ensure(&null_allocator, array, tests[i].count) == NULL); + array = va_array_destroy(&std_allocator, array); + fprintf(stderr, "."); + } // for + fprintf(stderr, " passed\n"); +} // test_va_array_ensure_null + + +static void +test_va_array_destroy(void) +{ + static struct { + VA_Allocator const* const allocator; + size_t const capacity; + } const tests[] = + { + {&std_allocator, 0}, + {&null_allocator, 0}, + }; // tests + + fprintf(stderr, "%s:%s: ", __FILE__, __func__); + for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) + { + uint32_t* array = va_array_init(tests[i].allocator, tests[i].capacity, sizeof(*array)); + array = va_array_destroy(&std_allocator, array); + assert(array == NULL); + fprintf(stderr, "."); + } // for + fprintf(stderr, " passed\n"); +} // test_va_array_destroy + + +static void +test_va_array_append(void) +{ + static struct { + VA_Allocator const* const allocator; + size_t const capacity; + uint32_t const count; + VA_Array const header; + } const tests[] = + { + {&std_allocator, 0, 0, { 4, 4, 0}}, + {&std_allocator, 0, 10, {16, 4, 10}}, + {&std_allocator, 5, 10, {10, 4, 10}}, + }; // tests + + fprintf(stderr, "%s:%s: ", __FILE__, __func__); + for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) + { + uint32_t* array = va_array_init(tests[i].allocator, tests[i].capacity, sizeof(*array)); + for (uint32_t j = 0; j < tests[i].count; ++j) + { + va_array_append(tests[i].allocator, array, j); + } // for + assert(memcmp(((VA_Array*) array) - 1, &tests[i].header, sizeof(tests[i].header)) == 0); + for (uint32_t j = 0; j < tests[i].count; ++j) + { + assert(array[j] == j); + } // for + array = va_array_destroy(&std_allocator, array); + fprintf(stderr, "."); + } // for + fprintf(stderr, " passed\n"); +} // test_va_array_append int main(void) { - int* a = va_array_init(&std_allocator, 1, sizeof(*a)); - va_array_append(a, 42); - va_array_append(a, 43); - va_array_append(a, 44); - a = va_array_destroy(a); - + test_va_array_init(); + test_va_array_init_null(); + test_va_array_ensure(); + test_va_array_ensure_null(); + test_va_array_destroy(); + test_va_array_append(); return EXIT_SUCCESS; } // main From ac77fe3ec358f1b82e34705cffa3bcd68864c65e Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 23 Apr 2024 17:01:43 +0200 Subject: [PATCH 033/704] WIP strings --- include/std_alloc.h | 31 +++++++++++++++++++++++++++++++ include/string.h | 33 +++++++++++++++++++++++++++++++++ src/main.c | 35 +++++++++++++++++++++++++++++++++++ src/string.c | 33 +++++++++++++++++++++++++++++++++ tests/test_array.c | 18 ++---------------- 5 files changed, 134 insertions(+), 16 deletions(-) create mode 100644 include/std_alloc.h create mode 100644 include/string.h create mode 100644 src/string.c diff --git a/include/std_alloc.h b/include/std_alloc.h new file mode 100644 index 0000000..bbbd53f --- /dev/null +++ b/include/std_alloc.h @@ -0,0 +1,31 @@ +#ifndef STD_ALLOC_H +#define STD_ALLOC_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include // NULL, size_t +#include // realloc + +#include "alloc.h" // VA_Allocator + + +static inline void* +std_alloc(void* const context, void* const ptr, size_t const old_size, size_t const size) +{ + (void) context; + (void) old_size; + return realloc(ptr, size); +} // std_alloc + + +static VA_Allocator const std_allocator = { .alloc = std_alloc }; + + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif diff --git a/include/string.h b/include/string.h new file mode 100644 index 0000000..20f8534 --- /dev/null +++ b/include/string.h @@ -0,0 +1,33 @@ +#ifndef STRING_H +#define STRING_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include // size_t + +#include "alloc.h" // VA_Allocator + + +typedef struct +{ + size_t length; + char* data; +} VA_String; + + +VA_String +va_string_concat(VA_Allocator const* const allocator, VA_String lhs, VA_String const rhs); + + +VA_String +va_string_slice(VA_Allocator const* const allocator, VA_String const string, size_t const start, size_t const end); + + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif diff --git a/src/main.c b/src/main.c index 753f5f5..311f570 100644 --- a/src/main.c +++ b/src/main.c @@ -1,10 +1,45 @@ +#include // size_t +#include // printf #include // EXIT_* +#include "../include/alloc.h" // VA_Allocator +#include "../include/array.h" // va_array_* +#include "../include/string.h" // VA_String, va_string_* +#include "../include/variant.h" // VA_Variant +#include "../include/std_alloc.h" // std_allocator + + +static VA_String +patch(VA_String const reference, size_t const len, VA_Variant variants[len], VA_String const external) +{ + VA_String observed = {0, NULL}; + + size_t start = 0; + for (size_t i = 0; i < len; ++i) + { + observed = va_string_concat(&std_allocator, observed, (VA_String) {variants[i].start - start, reference.data + start}); + observed = va_string_concat(&std_allocator, observed, (VA_String) {variants[i].obs_end - variants[i].obs_start, external.data + variants[i].obs_start}); + start = variants[i].end; + } // for + + if (start < reference.length) + { + observed = va_string_concat(&std_allocator, observed, (VA_String) {reference.length - start, reference.data + start}); + } // if + return observed; +} // patch + int main(int argc, char* argv[argc + 1]) { (void) argv; + VA_String const observed = patch((VA_String) {10, "ATTACCATTA"}, 1, (VA_Variant[]) {{3, 4, 0, 1}}, (VA_String) {1, "G"}); + + printf("%.*s\n", (int) observed.length, observed.data); + + std_allocator.alloc(NULL, observed.data, 0, 0); + return EXIT_SUCCESS; } // main diff --git a/src/string.c b/src/string.c new file mode 100644 index 0000000..0a04f6b --- /dev/null +++ b/src/string.c @@ -0,0 +1,33 @@ +#include // NULL, size_t + +#include "../include/alloc.h" // VA_Allocator +#include "../include/string.h" // VA_String, va_string_* + + +VA_String +va_string_concat(VA_Allocator const* const allocator, VA_String lhs, VA_String const rhs) +{ + lhs.data = allocator->alloc(allocator->context, lhs.data, lhs.length, lhs.length + rhs.length); // OVERFLOW + if (lhs.data == NULL) + { + return (VA_String) {0, NULL}; + } // if + + for (size_t i = 0; i < rhs.length; ++i) + { + lhs.data[lhs.length + i] = rhs.data[i]; + } // for + lhs.length += rhs.length; + return lhs; +} // va_string_concat + + +VA_String +va_string_slice(VA_Allocator const* const allocator, VA_String const string, size_t const start, size_t const end) +{ + (void) allocator; + (void) string; + (void) start; + (void) end; + return (VA_String) {0, NULL}; +} // va_string_slice diff --git a/tests/test_array.c b/tests/test_array.c index 4c8f4f9..9587284 100644 --- a/tests/test_array.c +++ b/tests/test_array.c @@ -5,26 +5,13 @@ #include // EXIT_SUCCESS, free, realloc #include // memcmp -#include "../include/alloc.h" // VA_Allocator +#include "../include/alloc.h" // VA_Allocator +#include "../include/std_alloc.h" // std_allocator #include "../src/array.c" -static inline void* -std_alloc(void* const context, void* const ptr, size_t const old_size, size_t const size) -{ - (void) context; - (void) old_size; - if (size == 0) - { - free(ptr); - return NULL; - } // if - return realloc(ptr, size); -} // std_alloc - - static inline void* null_alloc(void* const context, void* const ptr, size_t const old_size, size_t const size) { @@ -36,7 +23,6 @@ null_alloc(void* const context, void* const ptr, size_t const old_size, size_t c } // null_alloc -static VA_Allocator const std_allocator = { .alloc = std_alloc }; static VA_Allocator const null_allocator = { .alloc = null_alloc }; From 2f96a46aedf231e448d7298081aa47f26b913779 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 23 Apr 2024 20:35:35 +0200 Subject: [PATCH 034/704] WIP tests for strings --- src/main.c | 2 +- src/string.c | 19 +++++++++---- tests/test_array.c | 2 +- tests/test_string.c | 69 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 85 insertions(+), 7 deletions(-) create mode 100644 tests/test_string.c diff --git a/src/main.c b/src/main.c index 311f570..1949f15 100644 --- a/src/main.c +++ b/src/main.c @@ -1,4 +1,4 @@ -#include // size_t +#include // NULL, size_t #include // printf #include // EXIT_* diff --git a/src/string.c b/src/string.c index 0a04f6b..01ee39c 100644 --- a/src/string.c +++ b/src/string.c @@ -25,9 +25,18 @@ va_string_concat(VA_Allocator const* const allocator, VA_String lhs, VA_String c VA_String va_string_slice(VA_Allocator const* const allocator, VA_String const string, size_t const start, size_t const end) { - (void) allocator; - (void) string; - (void) start; - (void) end; - return (VA_String) {0, NULL}; + size_t const clamped_end = end > string.length ? string.length : end; + size_t const clamped_start = start > clamped_end ? clamped_end : start; + + VA_String slice = {clamped_end - clamped_start, allocator->alloc(allocator->context, NULL, 0, clamped_end - clamped_start)}; + if (slice.data == NULL) + { + return (VA_String) {0, NULL}; + } // if + + for (size_t i = 0; i < slice.length; ++i) + { + slice.data[i] = string.data[clamped_start + i]; + } // for + return slice; } // va_string_slice diff --git a/tests/test_array.c b/tests/test_array.c index 9587284..8e68d10 100644 --- a/tests/test_array.c +++ b/tests/test_array.c @@ -2,7 +2,7 @@ #include // NULL, size_t #include // uint32_t #include // stderr, fprintf -#include // EXIT_SUCCESS, free, realloc +#include // EXIT_SUCCESS #include // memcmp #include "../include/alloc.h" // VA_Allocator diff --git a/tests/test_string.c b/tests/test_string.c new file mode 100644 index 0000000..cdffddc --- /dev/null +++ b/tests/test_string.c @@ -0,0 +1,69 @@ +#include // assert +#include // NULL, size_t +#include // stderr, fprintf +#include // EXIT_SUCCESS +#include // memcmp + +#include "../include/alloc.h" // VA_Allocator +#include "../include/std_alloc.h" // std_allocator + + +#include "../src/string.c" + + +static void +test_va_string_concat(void) +{ + static struct { + VA_Allocator const* const allocator; + VA_String lhs; + VA_String const rhs; + VA_String const expected; + } const tests[] = + { + {&std_allocator, {0, NULL}, {0, NULL}, {0, NULL}}, + }; // tests + + fprintf(stderr, "%s:%s: ", __FILE__, __func__); + for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) + { + VA_String const result = va_string_concat(tests[i].allocator, tests[i].lhs, tests[i].rhs); + assert(memcmp(result.data, tests[i].expected.data, tests[i].expected.length) == 0); + fprintf(stderr, "."); + } // for + fprintf(stderr, " passed\n"); +} // test_va_string_concat + + +static void +test_va_string_slice(void) +{ + static struct { + VA_Allocator const* const allocator; + VA_String const string; + size_t const start; + size_t const end; + VA_String const expected; + } const tests[] = + { + {&std_allocator, {0, NULL}, 0, 0, {0, NULL}}, + }; // tests + + fprintf(stderr, "%s:%s: ", __FILE__, __func__); + for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) + { + VA_String const result = va_string_slice(tests[i].allocator, tests[i].string, tests[i].start, tests[i].end); + assert(memcmp(result.data, tests[i].expected.data, tests[i].expected.length) == 0); + fprintf(stderr, "."); + } // for + fprintf(stderr, " passed\n"); +} // test_va_string_slice + + +int +main(void) +{ + test_va_string_concat(); + test_va_string_slice(); + return EXIT_SUCCESS; +} // main From a14f8b2decd494781d5c7fcfc7bf508579fae53f Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 24 Apr 2024 14:57:44 +0200 Subject: [PATCH 035/704] Realloc with size 0; fixed tests --- include/std_alloc.h | 7 ++++++- tests/test_string.c | 18 ++++++++++++++++-- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/include/std_alloc.h b/include/std_alloc.h index bbbd53f..7e72afe 100644 --- a/include/std_alloc.h +++ b/include/std_alloc.h @@ -7,7 +7,7 @@ extern "C" #endif #include // NULL, size_t -#include // realloc +#include // free, realloc #include "alloc.h" // VA_Allocator @@ -17,6 +17,11 @@ std_alloc(void* const context, void* const ptr, size_t const old_size, size_t co { (void) context; (void) old_size; + if (size == 0) + { + free(ptr); + return NULL; + } // if return realloc(ptr, size); } // std_alloc diff --git a/tests/test_string.c b/tests/test_string.c index cdffddc..7fe242b 100644 --- a/tests/test_string.c +++ b/tests/test_string.c @@ -28,7 +28,14 @@ test_va_string_concat(void) for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) { VA_String const result = va_string_concat(tests[i].allocator, tests[i].lhs, tests[i].rhs); - assert(memcmp(result.data, tests[i].expected.data, tests[i].expected.length) == 0); + if (result.data == NULL || tests[i].expected.data == NULL) + { + assert(tests[i].expected.data == NULL); + } // if + else + { + assert(memcmp(result.data, tests[i].expected.data, tests[i].expected.length) == 0); + } // else fprintf(stderr, "."); } // for fprintf(stderr, " passed\n"); @@ -53,7 +60,14 @@ test_va_string_slice(void) for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) { VA_String const result = va_string_slice(tests[i].allocator, tests[i].string, tests[i].start, tests[i].end); - assert(memcmp(result.data, tests[i].expected.data, tests[i].expected.length) == 0); + if (result.data == NULL || tests[i].expected.data == NULL) + { + assert(tests[i].expected.data == NULL); + } // if + else + { + assert(memcmp(result.data, tests[i].expected.data, tests[i].expected.length) == 0); + } // else fprintf(stderr, "."); } // for fprintf(stderr, " passed\n"); From 914c95ed00a9e714bb3dfbe6682d96e98bf5e480 Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 24 Apr 2024 16:16:44 +0200 Subject: [PATCH 036/704] More tests on strings --- tests/test_string.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/test_string.c b/tests/test_string.c index 7fe242b..d2353da 100644 --- a/tests/test_string.c +++ b/tests/test_string.c @@ -22,6 +22,7 @@ test_va_string_concat(void) } const tests[] = { {&std_allocator, {0, NULL}, {0, NULL}, {0, NULL}}, + {&std_allocator, {0, NULL}, {1, "A"}, {1, "A"}}, }; // tests fprintf(stderr, "%s:%s: ", __FILE__, __func__); @@ -35,6 +36,7 @@ test_va_string_concat(void) else { assert(memcmp(result.data, tests[i].expected.data, tests[i].expected.length) == 0); + tests[i].allocator->alloc(tests[i].allocator->context, result.data, result.length, 0); } // else fprintf(stderr, "."); } // for @@ -54,6 +56,8 @@ test_va_string_slice(void) } const tests[] = { {&std_allocator, {0, NULL}, 0, 0, {0, NULL}}, + {&std_allocator, {1, "A"}, 0, 0, {0, NULL}}, + {&std_allocator, {1, "A"}, 0, 1, {1, "A"}}, }; // tests fprintf(stderr, "%s:%s: ", __FILE__, __func__); @@ -67,6 +71,7 @@ test_va_string_slice(void) else { assert(memcmp(result.data, tests[i].expected.data, tests[i].expected.length) == 0); + tests[i].allocator->alloc(tests[i].allocator->context, result.data, result.length, 0); } // else fprintf(stderr, "."); } // for From 529668a8a38313de2138fdbfbacd055f447c0273 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 2 May 2024 16:37:42 +0200 Subject: [PATCH 037/704] gcov also for headers --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 6ecf6bc..29f2573 100644 --- a/Makefile +++ b/Makefile @@ -37,7 +37,7 @@ check: $(TEST_BINS) $(TESTS_GCNOS) $(TEST_GCDAS) $(TEST_COVS) clean: $(RM) $(TARGET) $(OBJECTS) $(DEPS) \ $(TEST_BINS) $(TEST_DEPS) $(TEST_GCNOS) $(TEST_GCDAS) \ - $(TEST_DIR)/*.c.gcov + $(TEST_DIR)/*.gcov $(TARGET): $(OBJECTS) @@ -54,7 +54,7 @@ $(TARGET): $(OBJECTS) %.c.gcov: %.gcda gcov-11 $< - mv *.c.gcov $(TEST_DIR) + mv *.gcov $(TEST_DIR) -include $(DEPS) From efcaf41c2f48d993e4ce498e5a8369f29755b03f Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 2 May 2024 16:38:00 +0200 Subject: [PATCH 038/704] Simple static bump allocator --- src/main.c | 83 +++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 63 insertions(+), 20 deletions(-) diff --git a/src/main.c b/src/main.c index 1949f15..3552938 100644 --- a/src/main.c +++ b/src/main.c @@ -3,31 +3,69 @@ #include // EXIT_* #include "../include/alloc.h" // VA_Allocator -#include "../include/array.h" // va_array_* -#include "../include/string.h" // VA_String, va_string_* -#include "../include/variant.h" // VA_Variant -#include "../include/std_alloc.h" // std_allocator +#include "../include/array.h" // VA_Array -static VA_String -patch(VA_String const reference, size_t const len, VA_Variant variants[len], VA_String const external) +#define KiB(size) ((size_t) size * 1024ULL) +#define MiB(size) (KiB(size) * 1024ULL) +#define GiB(size) (MiB(size) * 1024ULL) + + +typedef struct +{ + size_t _size; + size_t free; + char buffer[MiB(50)]; +} Static_Buffer; + + +static Static_Buffer static_buffer = { ._size = sizeof(static_buffer) }; + + +static void* +static_alloc(void* const context, void* const ptr, size_t const old_size, size_t const size) { - VA_String observed = {0, NULL}; + Static_Buffer* const buffer = (Static_Buffer*) context; + + if (size == 0) + { + return NULL; + } // if - size_t start = 0; - for (size_t i = 0; i < len; ++i) + if (old_size >= size) { - observed = va_string_concat(&std_allocator, observed, (VA_String) {variants[i].start - start, reference.data + start}); - observed = va_string_concat(&std_allocator, observed, (VA_String) {variants[i].obs_end - variants[i].obs_start, external.data + variants[i].obs_start}); - start = variants[i].end; - } // for + return ptr; + } // if - if (start < reference.length) + if (ptr != NULL && old_size > 0) { - observed = va_string_concat(&std_allocator, observed, (VA_String) {reference.length - start, reference.data + start}); + if (sizeof(buffer->buffer) - buffer->free < old_size) + { + return NULL; // OOM + } // if + char const* const src = ptr; + for (size_t i = 0; i < old_size; ++i) + { + buffer->buffer[buffer->free + i] = src[i]; + } // for } // if - return observed; -} // patch + + if (sizeof(buffer->buffer) - buffer->free < size) + { + return NULL; // OOM + } // if + + void* const here = buffer->buffer + buffer->free; + buffer->free += size; + return here; +} // static_alloc + + +static VA_Allocator const static_allocator = +{ + static_alloc, + &static_buffer +}; int @@ -35,11 +73,16 @@ main(int argc, char* argv[argc + 1]) { (void) argv; - VA_String const observed = patch((VA_String) {10, "ATTACCATTA"}, 1, (VA_Variant[]) {{3, 4, 0, 1}}, (VA_String) {1, "G"}); - printf("%.*s\n", (int) observed.length, observed.data); + int* a = va_array_init(&static_allocator, 100, sizeof(*a)); + + a[0] = 42; + + printf("%p\n", (void*) a); + printf("%d\n", a[0]); + printf("%d\n", a[1]); - std_allocator.alloc(NULL, observed.data, 0, 0); + a = va_array_destroy(&static_allocator, a); return EXIT_SUCCESS; } // main From ee162938139202acdcaadcea34713e291f02735a Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 9 May 2024 12:49:08 +0200 Subject: [PATCH 039/704] rename --- src/main.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main.c b/src/main.c index 3552938..95735e4 100644 --- a/src/main.c +++ b/src/main.c @@ -15,7 +15,7 @@ typedef struct { size_t _size; size_t free; - char buffer[MiB(50)]; + char data[MiB(50)]; } Static_Buffer; @@ -39,23 +39,23 @@ static_alloc(void* const context, void* const ptr, size_t const old_size, size_t if (ptr != NULL && old_size > 0) { - if (sizeof(buffer->buffer) - buffer->free < old_size) + if (sizeof(buffer->data) - buffer->free < old_size) { return NULL; // OOM } // if char const* const src = ptr; for (size_t i = 0; i < old_size; ++i) { - buffer->buffer[buffer->free + i] = src[i]; + buffer->data[buffer->free + i] = src[i]; } // for } // if - if (sizeof(buffer->buffer) - buffer->free < size) + if (sizeof(buffer->data) - buffer->free < size) { return NULL; // OOM } // if - void* const here = buffer->buffer + buffer->free; + void* const here = buffer->data + buffer->free; buffer->free += size; return here; } // static_alloc From 2e0dcde9b8d183479141a665691ed5ad1ae8fb39 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 9 May 2024 12:49:24 +0200 Subject: [PATCH 040/704] WIP: wu alignments --- wu.c | 263 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 263 insertions(+) create mode 100644 wu.c diff --git a/wu.c b/wu.c new file mode 100644 index 0000000..89c8086 --- /dev/null +++ b/wu.c @@ -0,0 +1,263 @@ +#include // assert +#include // imaxabs +#include // NULL, ptrdiff_t, size_t +#include // stderr, fprintf, printf +#include // EXIT_*, free, malloc +#include // strlen + + +static size_t count = 0; + + +static inline size_t +wu_snake(size_t const m, + char const a[static m], + size_t const n, + char const b[static n], + ptrdiff_t const k, + ptrdiff_t const lower, + ptrdiff_t const upper) +{ + size_t col = lower > upper ? lower : upper; + size_t row = col - k; + while (row < m && col < n && a[row] == b[col]) + { + count += 1; + row += 1; + col += 1; + } // while + if (row < m && col < n) + { + count += 1; + } // if + return col; +} // wu_snake + + +static size_t +wu_compare(size_t const m, + char const a[static m], + size_t const n, + char const b[static n]) +{ + ptrdiff_t const delta = n - m; + size_t const offset = m + 1; + size_t const size = m + n + 3; + ptrdiff_t* const fp = malloc(size * sizeof(*fp)); + if (fp == NULL) + { + return -1; + } // if + + for (size_t i = 0; i < size; ++i) + { + fp[i] = -1; + } // for + + size_t p = 0; + while ((size_t) fp[delta + offset] != n) + { + for (ptrdiff_t k = -p; k <= delta - 1; ++k) + { + fp[k + offset] = wu_snake(m, a, n, b, k, fp[k - 1 + offset] + 1, fp[k + 1 + offset]); + } // for + for (ptrdiff_t k = delta + p; k >= delta + 1; --k) + { + fp[k + offset] = wu_snake(m, a, n, b, k, fp[k - 1 + offset] + 1, fp[k + 1 + offset]); + } // for + fp[delta + offset] = wu_snake(m, a, n, b, delta, fp[delta - 1 + offset] + 1, fp[delta + 1 + offset]); + p += 1; + } // while +/* + for (size_t i = 1; i < size - 1; ++i) + { + if (fp[i] > 0) + { + printf("%zu ", fp[i]); + } // if + } // for + printf("\n"); +*/ + free(fp); + + return delta + 2 * (p - 1); +} // wu_compare + + +static inline size_t +umax(size_t const a, size_t const b) +{ + return a > b ? a : b; +} // umax + + +static size_t +expand(size_t const len_ref, + char const reference[static len_ref], + size_t const len_obs, + char const observed[static len_obs], + ptrdiff_t const idx, + size_t const offset, + size_t const diagonals[static len_ref + len_obs + 3]) +{ + size_t row; + size_t col; + size_t end; + if (idx > 0) + { + row = diagonals[offset + idx]; + col = row + idx; + end = umax(diagonals[offset + idx - 1] - 1, diagonals[offset + idx + 1]); + } // if + else if (idx < 0) + { + col = diagonals[offset + idx]; + row = col - idx; + end = umax(diagonals[offset + idx - 1], diagonals[offset + idx + 1] - 1); + } // if + else + { + row = diagonals[offset + idx]; + col = row + idx; + end = umax(diagonals[offset + idx - 1], diagonals[offset + idx + 1]); + } // else + + row += end - diagonals[offset + idx]; + col += end - diagonals[offset + idx]; + + size_t steps = end + 1; + while (row < len_ref && col < len_obs && reference[row] == observed[col]) + { + count += 1; + row += 1; + col += 1; + steps += 1; + } // while + if (row < len_ref && col < len_obs) + { + count += 1; + } // if + + return steps; +} // expand + + +static size_t +edit(size_t const len_ref, + char const reference[static len_ref], + size_t const len_obs, + char const observed[static len_obs]) +{ + ptrdiff_t const delta = len_obs - len_ref; + size_t const offset = len_ref + 1; + size_t const size = len_ref + len_obs + 3; + + size_t* const diagonals = calloc(size, sizeof(*diagonals)); + if (diagonals == NULL) + { + return -1; + } // if + + size_t const lower = delta > 0 ? 0 : delta; + size_t const upper = delta > 0 ? delta : 0; + + size_t const len = umax(len_ref, len_obs) - imaxabs(delta); + size_t it = 0; + while (diagonals[offset + delta] <= len) + { + for (ptrdiff_t idx = lower - it; idx < delta; ++idx) + { + diagonals[offset + idx] = expand(len_ref, reference, len_obs, observed, idx, offset, diagonals); + } // for + for (ptrdiff_t idx = upper + it; idx > delta; --idx) + { + diagonals[offset + idx] = expand(len_ref, reference, len_obs, observed, idx, offset, diagonals); + } // for + diagonals[offset + delta] = expand(len_ref, reference, len_obs, observed, delta, offset, diagonals); + + it += 1; + } // while + + free(diagonals); + + return imaxabs(delta) + 2 * it - 2; +} // edit + + +static void +test_wu_compare(void) +{ + static struct + { + char const* const a; + char const* const b; + size_t const distance; + size_t const count; + } const tests[] = + { + { "", "", 0, 0}, + { "a", "a", 0, 1}, + { "a", "b", 2, 1}, + { "abcf", "abcdf", 1, 5}, + { "abcdf", "abcf", 1, 5}, + { "aa", "aaaaaaaaa", 7, 2}, + { "aaaaaaaaa", "aa", 7, 2}, + { "acbdeacbed", "acebdabbabed", 6, 23}, + {"acebdabbabed", "acbdeacbed", 6, 23}, + { "ACCTGACT", "ATCTTACTT", 5, 17}, + { "ATCTTACTT", "ACCTGACT", 5, 17}, + }; + + fprintf(stderr, "%s:%s: ", __FILE__, __func__); + for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) + { + size_t const m = strlen(tests[i].a); + size_t const n = strlen(tests[i].b); + + count = 0; + size_t const distance = m > n ? + wu_compare(n, tests[i].b, m, tests[i].a) : + wu_compare(m, tests[i].a, n, tests[i].b); + assert(distance == tests[i].distance); + assert(count == tests[i].count); + + count = 0; + size_t const edit_distance = edit(m, tests[i].a, n, tests[i].b); + assert(edit_distance == tests[i].distance); + assert(count == tests[i].count); + + fprintf(stderr, "."); + } // for + fprintf(stderr, " passed\n"); +} // test_wu_compare + + +int +main(int argc, char* argv[argc + 1]) +{ + test_wu_compare(); + + if (argc < 3) + { + fprintf(stderr, "usage: %s reference observed\n", argv[0]); + return EXIT_FAILURE; + } // if + + size_t const m = strlen(argv[1]); + size_t const n = strlen(argv[2]); + count = 0; + size_t const distance = m > n ? + wu_compare(n, argv[2], m, argv[1]) : + wu_compare(m, argv[1], n, argv[2]); + printf(" wu distance: %zu (%zu)\n", distance, count); + if (m > n) + { + printf("swapped\n"); + } // if + + count = 0; + size_t const edit_distance = edit(m, argv[1], n, argv[2]); + printf("edit distance: %zu (%zu)\n", edit_distance, count); + + return EXIT_SUCCESS; +} // main From 08e26b9cc762849d5b30e36c37e5505e6e8dd78e Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 9 May 2024 14:21:23 +0200 Subject: [PATCH 041/704] Added zeroing for std allocator --- include/std_alloc.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/include/std_alloc.h b/include/std_alloc.h index 7e72afe..acf3425 100644 --- a/include/std_alloc.h +++ b/include/std_alloc.h @@ -8,6 +8,7 @@ extern "C" #include // NULL, size_t #include // free, realloc +#include // memset #include "alloc.h" // VA_Allocator @@ -22,7 +23,12 @@ std_alloc(void* const context, void* const ptr, size_t const old_size, size_t co free(ptr); return NULL; } // if - return realloc(ptr, size); + char* const here = realloc(ptr, size); + if (size > old_size) + { + (void) memset(here + old_size, 0, size - old_size); + } // if + return here; } // std_alloc From 44b86d0f6c7ae457dcea413f8ae1881cfb596ab5 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 9 May 2024 14:21:51 +0200 Subject: [PATCH 042/704] Alignment with allocators --- wu.c | 38 +++++++++++++++----------------------- 1 file changed, 15 insertions(+), 23 deletions(-) diff --git a/wu.c b/wu.c index 89c8086..a720871 100644 --- a/wu.c +++ b/wu.c @@ -5,6 +5,9 @@ #include // EXIT_*, free, malloc #include // strlen +#include "include/alloc.h" // VA_Allocator +#include "include/std_alloc.h" // std_allocator + static size_t count = 0; @@ -68,16 +71,7 @@ wu_compare(size_t const m, fp[delta + offset] = wu_snake(m, a, n, b, delta, fp[delta - 1 + offset] + 1, fp[delta + 1 + offset]); p += 1; } // while -/* - for (size_t i = 1; i < size - 1; ++i) - { - if (fp[i] > 0) - { - printf("%zu ", fp[i]); - } // if - } // for - printf("\n"); -*/ + free(fp); return delta + 2 * (p - 1); @@ -143,7 +137,8 @@ expand(size_t const len_ref, static size_t -edit(size_t const len_ref, +edit(VA_Allocator const* const allocator, + size_t const len_ref, char const reference[static len_ref], size_t const len_obs, char const observed[static len_obs]) @@ -152,7 +147,7 @@ edit(size_t const len_ref, size_t const offset = len_ref + 1; size_t const size = len_ref + len_obs + 3; - size_t* const diagonals = calloc(size, sizeof(*diagonals)); + size_t* const diagonals = allocator->alloc(allocator->context, NULL, 0, size * sizeof(*diagonals)); if (diagonals == NULL) { return -1; @@ -178,7 +173,7 @@ edit(size_t const len_ref, it += 1; } // while - free(diagonals); + allocator->alloc(allocator->context, diagonals, size * sizeof(*diagonals), 0); return imaxabs(delta) + 2 * it - 2; } // edit @@ -215,14 +210,14 @@ test_wu_compare(void) size_t const n = strlen(tests[i].b); count = 0; - size_t const distance = m > n ? + size_t const wu_distance = m > n ? wu_compare(n, tests[i].b, m, tests[i].a) : wu_compare(m, tests[i].a, n, tests[i].b); - assert(distance == tests[i].distance); + assert(wu_distance == tests[i].distance); assert(count == tests[i].count); count = 0; - size_t const edit_distance = edit(m, tests[i].a, n, tests[i].b); + size_t const edit_distance = edit(&std_allocator, m, tests[i].a, n, tests[i].b); assert(edit_distance == tests[i].distance); assert(count == tests[i].count); @@ -245,18 +240,15 @@ main(int argc, char* argv[argc + 1]) size_t const m = strlen(argv[1]); size_t const n = strlen(argv[2]); + count = 0; - size_t const distance = m > n ? + size_t const wu_distance = m > n ? wu_compare(n, argv[2], m, argv[1]) : wu_compare(m, argv[1], n, argv[2]); - printf(" wu distance: %zu (%zu)\n", distance, count); - if (m > n) - { - printf("swapped\n"); - } // if + printf(" wu distance: %zu (%zu)\n", wu_distance, count); count = 0; - size_t const edit_distance = edit(m, argv[1], n, argv[2]); + size_t const edit_distance = edit(&std_allocator, m, argv[1], n, argv[2]); printf("edit distance: %zu (%zu)\n", edit_distance, count); return EXIT_SUCCESS; From 688416e24e26cf7fcfed188c5c597704c56eb645 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 9 May 2024 15:52:50 +0200 Subject: [PATCH 043/704] WIP: wu alignment with allocators --- include/array.h | 6 +- include/static_alloc.h | 81 +++++++++++++ include/std_alloc.h | 6 +- include/string.h | 4 +- src/array.c | 6 +- src/main.c | 264 +++++++++++++++++++++++++++++++++-------- src/string.c | 4 +- tests/test_array.c | 42 +++---- tests/test_string.c | 12 +- wu.c | 255 --------------------------------------- 10 files changed, 337 insertions(+), 343 deletions(-) create mode 100644 include/static_alloc.h delete mode 100644 wu.c diff --git a/include/array.h b/include/array.h index 5c48540..28d89e7 100644 --- a/include/array.h +++ b/include/array.h @@ -20,15 +20,15 @@ typedef struct void* -va_array_init(VA_Allocator const* const allocator, size_t const capacity, size_t const item_size); +va_array_init(VA_Allocator const allocator[static 1], size_t const capacity, size_t const item_size); void* -va_array_ensure(VA_Allocator const* const allocator, void* const ptr, size_t const count); +va_array_ensure(VA_Allocator const allocator[static 1], void* const ptr, size_t const count); void* -va_array_destroy(VA_Allocator const* const allocator, void* const ptr); +va_array_destroy(VA_Allocator const allocator[static 1], void* const ptr); #define \ diff --git a/include/static_alloc.h b/include/static_alloc.h new file mode 100644 index 0000000..5d3a6e5 --- /dev/null +++ b/include/static_alloc.h @@ -0,0 +1,81 @@ +#ifndef STATIC_ALLOC_H +#define STATIC_ALLOC_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include // NULL, size_t + + +#define KiB(size) ((size_t) size * 1024ULL) +#define MiB(size) (KiB(size) * 1024ULL) +#define GiB(size) (MiB(size) * 1024ULL) + + +#define VA_STATIC_BUFFER_SIZE MiB(50) + + +typedef struct +{ + size_t _size; + size_t free; + char data[VA_STATIC_BUFFER_SIZE]; +} VA_Static_Buffer; + + +static VA_Static_Buffer va_static_buffer = { ._size = sizeof(va_static_buffer) }; + + +static void* +va_static_alloc(void* const context, void* const ptr, size_t const old_size, size_t const size) +{ + VA_Static_Buffer* const buffer = (VA_Static_Buffer*) context; + + if (size == 0) + { + return NULL; + } // if + + if (old_size >= size) + { + return ptr; + } // if + + if (ptr != NULL && old_size > 0) + { + if (sizeof(buffer->data) - buffer->free < old_size) + { + return NULL; // OOM + } // if + char const* const src = ptr; + for (size_t i = 0; i < old_size; ++i) + { + buffer->data[buffer->free + i] = src[i]; + } // for + } // if + + if (sizeof(buffer->data) - buffer->free < size) + { + return NULL; // OOM + } // if + + void* const here = buffer->data + buffer->free; + buffer->free += size; + return here; +} // va_static_alloc + + +static VA_Allocator const va_static_allocator = +{ + va_static_alloc, + &va_static_buffer +}; + + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif diff --git a/include/std_alloc.h b/include/std_alloc.h index acf3425..5aea274 100644 --- a/include/std_alloc.h +++ b/include/std_alloc.h @@ -14,7 +14,7 @@ extern "C" static inline void* -std_alloc(void* const context, void* const ptr, size_t const old_size, size_t const size) +va_std_alloc(void* const context, void* const ptr, size_t const old_size, size_t const size) { (void) context; (void) old_size; @@ -29,10 +29,10 @@ std_alloc(void* const context, void* const ptr, size_t const old_size, size_t co (void) memset(here + old_size, 0, size - old_size); } // if return here; -} // std_alloc +} // va_std_alloc -static VA_Allocator const std_allocator = { .alloc = std_alloc }; +static VA_Allocator const va_std_allocator = { .alloc = va_std_alloc }; #ifdef __cplusplus diff --git a/include/string.h b/include/string.h index 20f8534..7c59e17 100644 --- a/include/string.h +++ b/include/string.h @@ -19,11 +19,11 @@ typedef struct VA_String -va_string_concat(VA_Allocator const* const allocator, VA_String lhs, VA_String const rhs); +va_string_concat(VA_Allocator const allocator[static 1], VA_String lhs, VA_String const rhs); VA_String -va_string_slice(VA_Allocator const* const allocator, VA_String const string, size_t const start, size_t const end); +va_string_slice(VA_Allocator const allocator[static 1], VA_String const string, size_t const start, size_t const end); #ifdef __cplusplus diff --git a/src/array.c b/src/array.c index 063c403..ce1383e 100644 --- a/src/array.c +++ b/src/array.c @@ -5,7 +5,7 @@ void* -va_array_init(VA_Allocator const* const allocator, size_t const capacity, size_t const item_size) +va_array_init(VA_Allocator const allocator[static 1], size_t const capacity, size_t const item_size) { size_t const min_capacity = capacity < 4 ? 4 : capacity; VA_Array* const header = allocator->alloc(allocator->context, NULL, 0, sizeof(*header) + min_capacity * item_size); // OVERFLOW @@ -21,7 +21,7 @@ va_array_init(VA_Allocator const* const allocator, size_t const capacity, size_t void* -va_array_ensure(VA_Allocator const* const allocator, void* const ptr, size_t const count) +va_array_ensure(VA_Allocator const allocator[static 1], void* const ptr, size_t const count) { VA_Array* header = (VA_Array*)(ptr) - 1; if (header->capacity - header->length >= count) @@ -46,7 +46,7 @@ va_array_ensure(VA_Allocator const* const allocator, void* const ptr, size_t con void* -va_array_destroy(VA_Allocator const* const allocator, void* const ptr) +va_array_destroy(VA_Allocator const allocator[static 1], void* const ptr) { if (ptr == NULL) { diff --git a/src/main.c b/src/main.c index 95735e4..1871bf2 100644 --- a/src/main.c +++ b/src/main.c @@ -1,88 +1,256 @@ -#include // NULL, size_t -#include // printf +#include // assert +#include // imaxabs +#include // NULL, ptrdiff_t, size_t +#include // stderr, fprintf, printf #include // EXIT_* +#include // strlen -#include "../include/alloc.h" // VA_Allocator -#include "../include/array.h" // VA_Array +#include "../include/alloc.h" // VA_Allocator +#include "../include/static_alloc.h" // va_static_allocator -#define KiB(size) ((size_t) size * 1024ULL) -#define MiB(size) (KiB(size) * 1024ULL) -#define GiB(size) (MiB(size) * 1024ULL) +static size_t count = 0; -typedef struct +static inline size_t +wu_snake(size_t const m, + char const a[static m], + size_t const n, + char const b[static n], + ptrdiff_t const k, + ptrdiff_t const lower, + ptrdiff_t const upper) { - size_t _size; - size_t free; - char data[MiB(50)]; -} Static_Buffer; + size_t col = lower > upper ? lower : upper; + size_t row = col - k; + while (row < m && col < n && a[row] == b[col]) + { + count += 1; + row += 1; + col += 1; + } // while + if (row < m && col < n) + { + count += 1; + } // if + return col; +} // wu_snake -static Static_Buffer static_buffer = { ._size = sizeof(static_buffer) }; +static size_t +wu_compare(VA_Allocator const allocator[static 1], + size_t const m, + char const a[static m], + size_t const n, + char const b[static n]) +{ + ptrdiff_t const delta = n - m; + size_t const offset = m + 1; + size_t const size = m + n + 3; + ptrdiff_t* const fp = allocator->alloc(allocator->context, NULL, 0, size * sizeof(*fp)); + if (fp == NULL) + { + return -1; + } // if + for (size_t i = 0; i < size; ++i) + { + fp[i] = -1; + } // for -static void* -static_alloc(void* const context, void* const ptr, size_t const old_size, size_t const size) + size_t p = 0; + while ((size_t) fp[delta + offset] != n) + { + for (ptrdiff_t k = -p; k <= delta - 1; ++k) + { + fp[k + offset] = wu_snake(m, a, n, b, k, fp[k - 1 + offset] + 1, fp[k + 1 + offset]); + } // for + for (ptrdiff_t k = delta + p; k >= delta + 1; --k) + { + fp[k + offset] = wu_snake(m, a, n, b, k, fp[k - 1 + offset] + 1, fp[k + 1 + offset]); + } // for + fp[delta + offset] = wu_snake(m, a, n, b, delta, fp[delta - 1 + offset] + 1, fp[delta + 1 + offset]); + p += 1; + } // while + + allocator->alloc(allocator->context, fp, size * sizeof(*fp), 0); + + return delta + 2 * (p - 1); +} // wu_compare + + +static inline size_t +umax(size_t const a, size_t const b) { - Static_Buffer* const buffer = (Static_Buffer*) context; + return a > b ? a : b; +} // umax + + +static size_t +expand(size_t const len_ref, + char const reference[static len_ref], + size_t const len_obs, + char const observed[static len_obs], + ptrdiff_t const idx, + size_t const offset, + size_t const diagonals[static len_ref + len_obs + 3]) +{ + size_t row; + size_t col; + size_t end; + if (idx > 0) + { + row = diagonals[offset + idx]; + col = row + idx; + end = umax(diagonals[offset + idx - 1] - 1, diagonals[offset + idx + 1]); + } // if + else if (idx < 0) + { + col = diagonals[offset + idx]; + row = col - idx; + end = umax(diagonals[offset + idx - 1], diagonals[offset + idx + 1] - 1); + } // if + else + { + row = diagonals[offset + idx]; + col = row + idx; + end = umax(diagonals[offset + idx - 1], diagonals[offset + idx + 1]); + } // else + + row += end - diagonals[offset + idx]; + col += end - diagonals[offset + idx]; - if (size == 0) + size_t steps = end + 1; + while (row < len_ref && col < len_obs && reference[row] == observed[col]) + { + count += 1; + row += 1; + col += 1; + steps += 1; + } // while + if (row < len_ref && col < len_obs) { - return NULL; + count += 1; } // if - if (old_size >= size) + return steps; +} // expand + + +static size_t +edit(VA_Allocator const allocator[static 1], + size_t const len_ref, + char const reference[static len_ref], + size_t const len_obs, + char const observed[static len_obs]) +{ + ptrdiff_t const delta = len_obs - len_ref; + size_t const offset = len_ref + 1; + size_t const size = len_ref + len_obs + 3; + + size_t* const diagonals = allocator->alloc(allocator->context, NULL, 0, size * sizeof(*diagonals)); + if (diagonals == NULL) { - return ptr; + return -1; } // if - if (ptr != NULL && old_size > 0) + size_t const lower = delta > 0 ? 0 : delta; + size_t const upper = delta > 0 ? delta : 0; + + size_t const len = umax(len_ref, len_obs) - imaxabs(delta); + size_t it = 0; + while (diagonals[offset + delta] <= len) { - if (sizeof(buffer->data) - buffer->free < old_size) + for (ptrdiff_t idx = lower - it; idx < delta; ++idx) { - return NULL; // OOM - } // if - char const* const src = ptr; - for (size_t i = 0; i < old_size; ++i) + diagonals[offset + idx] = expand(len_ref, reference, len_obs, observed, idx, offset, diagonals); + } // for + for (ptrdiff_t idx = upper + it; idx > delta; --idx) { - buffer->data[buffer->free + i] = src[i]; + diagonals[offset + idx] = expand(len_ref, reference, len_obs, observed, idx, offset, diagonals); } // for - } // if + diagonals[offset + delta] = expand(len_ref, reference, len_obs, observed, delta, offset, diagonals); - if (sizeof(buffer->data) - buffer->free < size) - { - return NULL; // OOM - } // if + it += 1; + } // while - void* const here = buffer->data + buffer->free; - buffer->free += size; - return here; -} // static_alloc + allocator->alloc(allocator->context, diagonals, size * sizeof(*diagonals), 0); + return imaxabs(delta) + 2 * it - 2; +} // edit -static VA_Allocator const static_allocator = + +static void +test_wu_compare(void) { - static_alloc, - &static_buffer -}; + static struct + { + char const* const a; + char const* const b; + size_t const distance; + size_t const count; + } const tests[] = + { + { "", "", 0, 0}, + { "a", "a", 0, 1}, + { "a", "b", 2, 1}, + { "abcf", "abcdf", 1, 5}, + { "abcdf", "abcf", 1, 5}, + { "aa", "aaaaaaaaa", 7, 2}, + { "aaaaaaaaa", "aa", 7, 2}, + { "acbdeacbed", "acebdabbabed", 6, 23}, + {"acebdabbabed", "acbdeacbed", 6, 23}, + { "ACCTGACT", "ATCTTACTT", 5, 17}, + { "ATCTTACTT", "ACCTGACT", 5, 17}, + }; + + fprintf(stderr, "%s:%s: ", __FILE__, __func__); + for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) + { + size_t const m = strlen(tests[i].a); + size_t const n = strlen(tests[i].b); + + count = 0; + size_t const wu_distance = m > n ? + wu_compare(&va_static_allocator, n, tests[i].b, m, tests[i].a) : + wu_compare(&va_static_allocator, m, tests[i].a, n, tests[i].b); + assert(wu_distance == tests[i].distance); + assert(count == tests[i].count); + + count = 0; + size_t const edit_distance = edit(&va_static_allocator, m, tests[i].a, n, tests[i].b); + assert(edit_distance == tests[i].distance); + assert(count == tests[i].count); + + fprintf(stderr, "."); + } // for + fprintf(stderr, " passed\n"); +} // test_wu_compare int main(int argc, char* argv[argc + 1]) { - (void) argv; - + test_wu_compare(); - int* a = va_array_init(&static_allocator, 100, sizeof(*a)); + if (argc < 3) + { + fprintf(stderr, "usage: %s reference observed\n", argv[0]); + return EXIT_FAILURE; + } // if - a[0] = 42; + size_t const m = strlen(argv[1]); + size_t const n = strlen(argv[2]); - printf("%p\n", (void*) a); - printf("%d\n", a[0]); - printf("%d\n", a[1]); + count = 0; + size_t const wu_distance = m > n ? + wu_compare(&va_static_allocator, n, argv[2], m, argv[1]) : + wu_compare(&va_static_allocator, m, argv[1], n, argv[2]); + printf(" wu distance: %zu (%zu)\n", wu_distance, count); - a = va_array_destroy(&static_allocator, a); + count = 0; + size_t const edit_distance = edit(&va_static_allocator, m, argv[1], n, argv[2]); + printf("edit distance: %zu (%zu)\n", edit_distance, count); return EXIT_SUCCESS; } // main diff --git a/src/string.c b/src/string.c index 01ee39c..21f0cbd 100644 --- a/src/string.c +++ b/src/string.c @@ -5,7 +5,7 @@ VA_String -va_string_concat(VA_Allocator const* const allocator, VA_String lhs, VA_String const rhs) +va_string_concat(VA_Allocator const allocator[static 1], VA_String lhs, VA_String const rhs) { lhs.data = allocator->alloc(allocator->context, lhs.data, lhs.length, lhs.length + rhs.length); // OVERFLOW if (lhs.data == NULL) @@ -23,7 +23,7 @@ va_string_concat(VA_Allocator const* const allocator, VA_String lhs, VA_String c VA_String -va_string_slice(VA_Allocator const* const allocator, VA_String const string, size_t const start, size_t const end) +va_string_slice(VA_Allocator const allocator[static 1], VA_String const string, size_t const start, size_t const end) { size_t const clamped_end = end > string.length ? string.length : end; size_t const clamped_start = start > clamped_end ? clamped_end : start; diff --git a/tests/test_array.c b/tests/test_array.c index 8e68d10..07a3231 100644 --- a/tests/test_array.c +++ b/tests/test_array.c @@ -6,7 +6,7 @@ #include // memcmp #include "../include/alloc.h" // VA_Allocator -#include "../include/std_alloc.h" // std_allocator +#include "../include/std_alloc.h" // va_std_allocator #include "../src/array.c" @@ -35,11 +35,11 @@ test_va_array_init(void) VA_Array const header; } const tests[] = { - {&std_allocator, 0, { 4, 4, 0}}, - {&std_allocator, 1, { 4, 4, 0}}, - {&std_allocator, 4, { 4, 4, 0}}, - {&std_allocator, 5, { 5, 4, 0}}, - {&std_allocator, 100, {100, 4, 0}}, + {&va_std_allocator, 0, { 4, 4, 0}}, + {&va_std_allocator, 1, { 4, 4, 0}}, + {&va_std_allocator, 4, { 4, 4, 0}}, + {&va_std_allocator, 5, { 5, 4, 0}}, + {&va_std_allocator, 100, {100, 4, 0}}, }; // tests fprintf(stderr, "%s:%s: ", __FILE__, __func__); @@ -84,13 +84,13 @@ test_va_array_ensure(void) VA_Array const header; } const tests[] = { - {&std_allocator, 0, 0, { 4, 4, 0}}, - {&std_allocator, 0, 1, { 4, 4, 0}}, - {&std_allocator, 0, 4, { 4, 4, 0}}, - {&std_allocator, 0, 5, { 8, 4, 0}}, - {&std_allocator, 100, 100, {100, 4, 0}}, - {&std_allocator, 100, 101, {200, 4, 0}}, - {&std_allocator, 0, 100, {128, 4, 0}}, + {&va_std_allocator, 0, 0, { 4, 4, 0}}, + {&va_std_allocator, 0, 1, { 4, 4, 0}}, + {&va_std_allocator, 0, 4, { 4, 4, 0}}, + {&va_std_allocator, 0, 5, { 8, 4, 0}}, + {&va_std_allocator, 100, 100, {100, 4, 0}}, + {&va_std_allocator, 100, 101, {200, 4, 0}}, + {&va_std_allocator, 0, 100, {128, 4, 0}}, }; // tests fprintf(stderr, "%s:%s: ", __FILE__, __func__); @@ -120,9 +120,9 @@ test_va_array_ensure_null(void) fprintf(stderr, "%s:%s: ", __FILE__, __func__); for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) { - uint32_t* array = va_array_init(&std_allocator, tests[i].capacity, sizeof(*array)); + uint32_t* array = va_array_init(&va_std_allocator, tests[i].capacity, sizeof(*array)); assert(va_array_ensure(&null_allocator, array, tests[i].count) == NULL); - array = va_array_destroy(&std_allocator, array); + array = va_array_destroy(&va_std_allocator, array); fprintf(stderr, "."); } // for fprintf(stderr, " passed\n"); @@ -137,7 +137,7 @@ test_va_array_destroy(void) size_t const capacity; } const tests[] = { - {&std_allocator, 0}, + {&va_std_allocator, 0}, {&null_allocator, 0}, }; // tests @@ -145,7 +145,7 @@ test_va_array_destroy(void) for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) { uint32_t* array = va_array_init(tests[i].allocator, tests[i].capacity, sizeof(*array)); - array = va_array_destroy(&std_allocator, array); + array = va_array_destroy(tests[i].allocator, array); assert(array == NULL); fprintf(stderr, "."); } // for @@ -163,9 +163,9 @@ test_va_array_append(void) VA_Array const header; } const tests[] = { - {&std_allocator, 0, 0, { 4, 4, 0}}, - {&std_allocator, 0, 10, {16, 4, 10}}, - {&std_allocator, 5, 10, {10, 4, 10}}, + {&va_std_allocator, 0, 0, { 4, 4, 0}}, + {&va_std_allocator, 0, 10, {16, 4, 10}}, + {&va_std_allocator, 5, 10, {10, 4, 10}}, }; // tests fprintf(stderr, "%s:%s: ", __FILE__, __func__); @@ -181,7 +181,7 @@ test_va_array_append(void) { assert(array[j] == j); } // for - array = va_array_destroy(&std_allocator, array); + array = va_array_destroy(tests[i].allocator, array); fprintf(stderr, "."); } // for fprintf(stderr, " passed\n"); diff --git a/tests/test_string.c b/tests/test_string.c index d2353da..f710bb8 100644 --- a/tests/test_string.c +++ b/tests/test_string.c @@ -5,7 +5,7 @@ #include // memcmp #include "../include/alloc.h" // VA_Allocator -#include "../include/std_alloc.h" // std_allocator +#include "../include/std_alloc.h" // va_std_allocator #include "../src/string.c" @@ -21,8 +21,8 @@ test_va_string_concat(void) VA_String const expected; } const tests[] = { - {&std_allocator, {0, NULL}, {0, NULL}, {0, NULL}}, - {&std_allocator, {0, NULL}, {1, "A"}, {1, "A"}}, + {&va_std_allocator, {0, NULL}, {0, NULL}, {0, NULL}}, + {&va_std_allocator, {0, NULL}, {1, "A"}, {1, "A"}}, }; // tests fprintf(stderr, "%s:%s: ", __FILE__, __func__); @@ -55,9 +55,9 @@ test_va_string_slice(void) VA_String const expected; } const tests[] = { - {&std_allocator, {0, NULL}, 0, 0, {0, NULL}}, - {&std_allocator, {1, "A"}, 0, 0, {0, NULL}}, - {&std_allocator, {1, "A"}, 0, 1, {1, "A"}}, + {&va_std_allocator, {0, NULL}, 0, 0, {0, NULL}}, + {&va_std_allocator, {1, "A"}, 0, 0, {0, NULL}}, + {&va_std_allocator, {1, "A"}, 0, 1, {1, "A"}}, }; // tests fprintf(stderr, "%s:%s: ", __FILE__, __func__); diff --git a/wu.c b/wu.c deleted file mode 100644 index a720871..0000000 --- a/wu.c +++ /dev/null @@ -1,255 +0,0 @@ -#include // assert -#include // imaxabs -#include // NULL, ptrdiff_t, size_t -#include // stderr, fprintf, printf -#include // EXIT_*, free, malloc -#include // strlen - -#include "include/alloc.h" // VA_Allocator -#include "include/std_alloc.h" // std_allocator - - -static size_t count = 0; - - -static inline size_t -wu_snake(size_t const m, - char const a[static m], - size_t const n, - char const b[static n], - ptrdiff_t const k, - ptrdiff_t const lower, - ptrdiff_t const upper) -{ - size_t col = lower > upper ? lower : upper; - size_t row = col - k; - while (row < m && col < n && a[row] == b[col]) - { - count += 1; - row += 1; - col += 1; - } // while - if (row < m && col < n) - { - count += 1; - } // if - return col; -} // wu_snake - - -static size_t -wu_compare(size_t const m, - char const a[static m], - size_t const n, - char const b[static n]) -{ - ptrdiff_t const delta = n - m; - size_t const offset = m + 1; - size_t const size = m + n + 3; - ptrdiff_t* const fp = malloc(size * sizeof(*fp)); - if (fp == NULL) - { - return -1; - } // if - - for (size_t i = 0; i < size; ++i) - { - fp[i] = -1; - } // for - - size_t p = 0; - while ((size_t) fp[delta + offset] != n) - { - for (ptrdiff_t k = -p; k <= delta - 1; ++k) - { - fp[k + offset] = wu_snake(m, a, n, b, k, fp[k - 1 + offset] + 1, fp[k + 1 + offset]); - } // for - for (ptrdiff_t k = delta + p; k >= delta + 1; --k) - { - fp[k + offset] = wu_snake(m, a, n, b, k, fp[k - 1 + offset] + 1, fp[k + 1 + offset]); - } // for - fp[delta + offset] = wu_snake(m, a, n, b, delta, fp[delta - 1 + offset] + 1, fp[delta + 1 + offset]); - p += 1; - } // while - - free(fp); - - return delta + 2 * (p - 1); -} // wu_compare - - -static inline size_t -umax(size_t const a, size_t const b) -{ - return a > b ? a : b; -} // umax - - -static size_t -expand(size_t const len_ref, - char const reference[static len_ref], - size_t const len_obs, - char const observed[static len_obs], - ptrdiff_t const idx, - size_t const offset, - size_t const diagonals[static len_ref + len_obs + 3]) -{ - size_t row; - size_t col; - size_t end; - if (idx > 0) - { - row = diagonals[offset + idx]; - col = row + idx; - end = umax(diagonals[offset + idx - 1] - 1, diagonals[offset + idx + 1]); - } // if - else if (idx < 0) - { - col = diagonals[offset + idx]; - row = col - idx; - end = umax(diagonals[offset + idx - 1], diagonals[offset + idx + 1] - 1); - } // if - else - { - row = diagonals[offset + idx]; - col = row + idx; - end = umax(diagonals[offset + idx - 1], diagonals[offset + idx + 1]); - } // else - - row += end - diagonals[offset + idx]; - col += end - diagonals[offset + idx]; - - size_t steps = end + 1; - while (row < len_ref && col < len_obs && reference[row] == observed[col]) - { - count += 1; - row += 1; - col += 1; - steps += 1; - } // while - if (row < len_ref && col < len_obs) - { - count += 1; - } // if - - return steps; -} // expand - - -static size_t -edit(VA_Allocator const* const allocator, - size_t const len_ref, - char const reference[static len_ref], - size_t const len_obs, - char const observed[static len_obs]) -{ - ptrdiff_t const delta = len_obs - len_ref; - size_t const offset = len_ref + 1; - size_t const size = len_ref + len_obs + 3; - - size_t* const diagonals = allocator->alloc(allocator->context, NULL, 0, size * sizeof(*diagonals)); - if (diagonals == NULL) - { - return -1; - } // if - - size_t const lower = delta > 0 ? 0 : delta; - size_t const upper = delta > 0 ? delta : 0; - - size_t const len = umax(len_ref, len_obs) - imaxabs(delta); - size_t it = 0; - while (diagonals[offset + delta] <= len) - { - for (ptrdiff_t idx = lower - it; idx < delta; ++idx) - { - diagonals[offset + idx] = expand(len_ref, reference, len_obs, observed, idx, offset, diagonals); - } // for - for (ptrdiff_t idx = upper + it; idx > delta; --idx) - { - diagonals[offset + idx] = expand(len_ref, reference, len_obs, observed, idx, offset, diagonals); - } // for - diagonals[offset + delta] = expand(len_ref, reference, len_obs, observed, delta, offset, diagonals); - - it += 1; - } // while - - allocator->alloc(allocator->context, diagonals, size * sizeof(*diagonals), 0); - - return imaxabs(delta) + 2 * it - 2; -} // edit - - -static void -test_wu_compare(void) -{ - static struct - { - char const* const a; - char const* const b; - size_t const distance; - size_t const count; - } const tests[] = - { - { "", "", 0, 0}, - { "a", "a", 0, 1}, - { "a", "b", 2, 1}, - { "abcf", "abcdf", 1, 5}, - { "abcdf", "abcf", 1, 5}, - { "aa", "aaaaaaaaa", 7, 2}, - { "aaaaaaaaa", "aa", 7, 2}, - { "acbdeacbed", "acebdabbabed", 6, 23}, - {"acebdabbabed", "acbdeacbed", 6, 23}, - { "ACCTGACT", "ATCTTACTT", 5, 17}, - { "ATCTTACTT", "ACCTGACT", 5, 17}, - }; - - fprintf(stderr, "%s:%s: ", __FILE__, __func__); - for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) - { - size_t const m = strlen(tests[i].a); - size_t const n = strlen(tests[i].b); - - count = 0; - size_t const wu_distance = m > n ? - wu_compare(n, tests[i].b, m, tests[i].a) : - wu_compare(m, tests[i].a, n, tests[i].b); - assert(wu_distance == tests[i].distance); - assert(count == tests[i].count); - - count = 0; - size_t const edit_distance = edit(&std_allocator, m, tests[i].a, n, tests[i].b); - assert(edit_distance == tests[i].distance); - assert(count == tests[i].count); - - fprintf(stderr, "."); - } // for - fprintf(stderr, " passed\n"); -} // test_wu_compare - - -int -main(int argc, char* argv[argc + 1]) -{ - test_wu_compare(); - - if (argc < 3) - { - fprintf(stderr, "usage: %s reference observed\n", argv[0]); - return EXIT_FAILURE; - } // if - - size_t const m = strlen(argv[1]); - size_t const n = strlen(argv[2]); - - count = 0; - size_t const wu_distance = m > n ? - wu_compare(n, argv[2], m, argv[1]) : - wu_compare(m, argv[1], n, argv[2]); - printf(" wu distance: %zu (%zu)\n", wu_distance, count); - - count = 0; - size_t const edit_distance = edit(&std_allocator, m, argv[1], n, argv[2]); - printf("edit distance: %zu (%zu)\n", edit_distance, count); - - return EXIT_SUCCESS; -} // main From 5e1c1415b91aea967f66159862737ddf206caeba Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 9 May 2024 19:29:01 +0200 Subject: [PATCH 044/704] WIP: all lcs --- src/main.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/main.c b/src/main.c index 1871bf2..898b3f4 100644 --- a/src/main.c +++ b/src/main.c @@ -14,12 +14,12 @@ static size_t count = 0; static inline size_t wu_snake(size_t const m, - char const a[static m], - size_t const n, - char const b[static n], - ptrdiff_t const k, - ptrdiff_t const lower, - ptrdiff_t const upper) + char const a[static m], + size_t const n, + char const b[static n], + ptrdiff_t const k, + ptrdiff_t const lower, + ptrdiff_t const upper) { size_t col = lower > upper ? lower : upper; size_t row = col - k; @@ -117,8 +117,20 @@ expand(size_t const len_ref, end = umax(diagonals[offset + idx - 1], diagonals[offset + idx + 1]); } // else +#ifdef VA_ALL_LCS + for (size_t i = diagonals[offset + idx]; i < end; ++i) + { + if (reference[row] == observed[col]) + { + count += 1; + } // if + row += 1; + col += 1; + } // for +#else row += end - diagonals[offset + idx]; col += end - diagonals[offset + idx]; +#endif size_t steps = end + 1; while (row < len_ref && col < len_obs && reference[row] == observed[col]) From 5bb6a859e32f43cb61645e21c79b3a3b8757c0f9 Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 10 May 2024 16:45:27 +0200 Subject: [PATCH 045/704] Restrict for char pointers --- src/main.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/main.c b/src/main.c index 898b3f4..43eae35 100644 --- a/src/main.c +++ b/src/main.c @@ -14,9 +14,9 @@ static size_t count = 0; static inline size_t wu_snake(size_t const m, - char const a[static m], + char const a[static restrict m], size_t const n, - char const b[static n], + char const b[static restrict n], ptrdiff_t const k, ptrdiff_t const lower, ptrdiff_t const upper) @@ -38,16 +38,16 @@ wu_snake(size_t const m, static size_t -wu_compare(VA_Allocator const allocator[static 1], +wu_compare(VA_Allocator const allocator[static restrict 1], size_t const m, - char const a[static m], + char const a[static restrict m], size_t const n, - char const b[static n]) + char const b[static restrict n]) { ptrdiff_t const delta = n - m; size_t const offset = m + 1; size_t const size = m + n + 3; - ptrdiff_t* const fp = allocator->alloc(allocator->context, NULL, 0, size * sizeof(*fp)); + ptrdiff_t* const restrict fp = allocator->alloc(allocator->context, NULL, 0, size * sizeof(*fp)); if (fp == NULL) { return -1; @@ -88,12 +88,12 @@ umax(size_t const a, size_t const b) static size_t expand(size_t const len_ref, - char const reference[static len_ref], + char const reference[static restrict len_ref], size_t const len_obs, - char const observed[static len_obs], + char const observed[static restrict len_obs], ptrdiff_t const idx, size_t const offset, - size_t const diagonals[static len_ref + len_obs + 3]) + size_t const diagonals[static restrict len_ref + len_obs + 3]) { size_t row; size_t col; @@ -150,17 +150,17 @@ expand(size_t const len_ref, static size_t -edit(VA_Allocator const allocator[static 1], +edit(VA_Allocator const allocator[static restrict 1], size_t const len_ref, - char const reference[static len_ref], + char const reference[static restrict len_ref], size_t const len_obs, - char const observed[static len_obs]) + char const observed[static restrict len_obs]) { ptrdiff_t const delta = len_obs - len_ref; size_t const offset = len_ref + 1; size_t const size = len_ref + len_obs + 3; - size_t* const diagonals = allocator->alloc(allocator->context, NULL, 0, size * sizeof(*diagonals)); + size_t* const restrict diagonals = allocator->alloc(allocator->context, NULL, 0, size * sizeof(*diagonals)); if (diagonals == NULL) { return -1; @@ -197,8 +197,8 @@ test_wu_compare(void) { static struct { - char const* const a; - char const* const b; + char const* const restrict a; + char const* const restrict b; size_t const distance; size_t const count; } const tests[] = From a33ce7bf160389eece9abe09de7f308ccdabfda1 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 14 May 2024 14:45:34 +0200 Subject: [PATCH 046/704] WIP compressed nodes --- src/main.c | 65 +++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 55 insertions(+), 10 deletions(-) diff --git a/src/main.c b/src/main.c index 43eae35..0275707 100644 --- a/src/main.c +++ b/src/main.c @@ -1,5 +1,6 @@ #include // assert #include // imaxabs +#include // bool, false, true #include // NULL, ptrdiff_t, size_t #include // stderr, fprintf, printf #include // EXIT_* @@ -93,7 +94,9 @@ expand(size_t const len_ref, char const observed[static restrict len_obs], ptrdiff_t const idx, size_t const offset, - size_t const diagonals[static restrict len_ref + len_obs + 3]) + size_t const diagonals[static restrict len_ref + len_obs + 3], + ptrdiff_t const delta, + size_t const it) { size_t row; size_t col; @@ -117,22 +120,62 @@ expand(size_t const len_ref, end = umax(diagonals[offset + idx - 1], diagonals[offset + idx + 1]); } // else + size_t steps = end + 1; + #ifdef VA_ALL_LCS + bool matching = false; + size_t match_row = 0; + size_t match_col = 0; + for (size_t i = diagonals[offset + idx]; i < end; ++i) { if (reference[row] == observed[col]) { - count += 1; + if (!matching) + { + match_row = row; + match_col = col; + matching = true; + } // if } // if + else if (matching) + { + ptrdiff_t const d_row = len_ref - row; + ptrdiff_t const d_col = len_obs - col; + size_t const lcs_pos = (row + col - imaxabs(delta) - 2 * it + imaxabs(d_row - d_col)) / 2 - 1; + printf("%zu: (%zu, %zu, %zu)\n", lcs_pos, match_row, match_col, row - match_row); + matching = false; + } // if + count += 1; row += 1; col += 1; } // for + + if (!matching) + { + match_row = row; + match_col = col; + } // if + while (row < len_ref && col < len_obs && reference[row] == observed[col]) + { + matching = true; + count += 1; + row += 1; + col += 1; + steps += 1; + } // while + if (matching) + { + ptrdiff_t const d_row = len_ref - row; + ptrdiff_t const d_col = len_obs - col; + size_t const lcs_pos = (row + col - imaxabs(delta) - 2 * it + imaxabs(d_row - d_col)) / 2 - 1; + printf("%zu: (%zu, %zu, %zu)\n", lcs_pos, match_row, match_col, row - match_row); + } // if #else + (void) delta; + (void) it; row += end - diagonals[offset + idx]; col += end - diagonals[offset + idx]; -#endif - - size_t steps = end + 1; while (row < len_ref && col < len_obs && reference[row] == observed[col]) { count += 1; @@ -140,6 +183,8 @@ expand(size_t const len_ref, col += 1; steps += 1; } // while +#endif + if (row < len_ref && col < len_obs) { count += 1; @@ -175,13 +220,13 @@ edit(VA_Allocator const allocator[static restrict 1], { for (ptrdiff_t idx = lower - it; idx < delta; ++idx) { - diagonals[offset + idx] = expand(len_ref, reference, len_obs, observed, idx, offset, diagonals); + diagonals[offset + idx] = expand(len_ref, reference, len_obs, observed, idx, offset, diagonals, delta, it); } // for for (ptrdiff_t idx = upper + it; idx > delta; --idx) { - diagonals[offset + idx] = expand(len_ref, reference, len_obs, observed, idx, offset, diagonals); + diagonals[offset + idx] = expand(len_ref, reference, len_obs, observed, idx, offset, diagonals, delta, it); } // for - diagonals[offset + delta] = expand(len_ref, reference, len_obs, observed, delta, offset, diagonals); + diagonals[offset + delta] = expand(len_ref, reference, len_obs, observed, delta, offset, diagonals, delta, it); it += 1; } // while @@ -232,7 +277,7 @@ test_wu_compare(void) count = 0; size_t const edit_distance = edit(&va_static_allocator, m, tests[i].a, n, tests[i].b); assert(edit_distance == tests[i].distance); - assert(count == tests[i].count); + //assert(count == tests[i].count); fprintf(stderr, "."); } // for @@ -243,7 +288,7 @@ test_wu_compare(void) int main(int argc, char* argv[argc + 1]) { - test_wu_compare(); + //test_wu_compare(); if (argc < 3) { From e11a0a851efcd9b7c85e0ea3bd9a5b5b5e839c3e Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 14 May 2024 17:08:17 +0200 Subject: [PATCH 047/704] WIP: LCS nodes --- src/main.c | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/src/main.c b/src/main.c index 0275707..31f4d8a 100644 --- a/src/main.c +++ b/src/main.c @@ -7,7 +7,9 @@ #include // strlen #include "../include/alloc.h" // VA_Allocator +#include "../include/array.h" // #include "../include/static_alloc.h" // va_static_allocator +#include "../include/std_alloc.h" // va_std_allocator static size_t count = 0; @@ -80,6 +82,14 @@ wu_compare(VA_Allocator const allocator[static restrict 1], } // wu_compare +typedef struct +{ + size_t row; + size_t col; + size_t length; +} VA_LCS_Node; + + static inline size_t umax(size_t const a, size_t const b) { @@ -87,6 +97,13 @@ umax(size_t const a, size_t const b) } // umax +static inline size_t +umin(size_t const a, size_t const b) +{ + return a < b ? a : b; +} // umin + + static size_t expand(size_t const len_ref, char const reference[static restrict len_ref], @@ -143,7 +160,8 @@ expand(size_t const len_ref, ptrdiff_t const d_row = len_ref - row; ptrdiff_t const d_col = len_obs - col; size_t const lcs_pos = (row + col - imaxabs(delta) - 2 * it + imaxabs(d_row - d_col)) / 2 - 1; - printf("%zu: (%zu, %zu, %zu)\n", lcs_pos, match_row, match_col, row - match_row); + size_t const length = row - match_row; + printf("%zu: (%zu, %zu, %zu):: %zu\n", lcs_pos, match_row, match_col, length, lcs_pos + 1 - length); matching = false; } // if count += 1; @@ -169,7 +187,8 @@ expand(size_t const len_ref, ptrdiff_t const d_row = len_ref - row; ptrdiff_t const d_col = len_obs - col; size_t const lcs_pos = (row + col - imaxabs(delta) - 2 * it + imaxabs(d_row - d_col)) / 2 - 1; - printf("%zu: (%zu, %zu, %zu)\n", lcs_pos, match_row, match_col, row - match_row); + size_t const length = row - match_row; + printf("%zu: (%zu, %zu, %zu):: %zu\n", lcs_pos, match_row, match_col, length, lcs_pos + 1 - length); } // if #else (void) delta; @@ -211,6 +230,13 @@ edit(VA_Allocator const allocator[static restrict 1], return -1; } // if + VA_LCS_Node* const lcs_nodes = allocator->alloc(allocator->context, NULL, 0, umin(len_ref, len_obs) * sizeof(*lcs_nodes)); + if (lcs_nodes == NULL) + { + allocator->alloc(allocator->context, diagonals, size * sizeof(*diagonals), 0); + return -1; + } // if + size_t const lower = delta > 0 ? 0 : delta; size_t const upper = delta > 0 ? delta : 0; @@ -306,7 +332,7 @@ main(int argc, char* argv[argc + 1]) printf(" wu distance: %zu (%zu)\n", wu_distance, count); count = 0; - size_t const edit_distance = edit(&va_static_allocator, m, argv[1], n, argv[2]); + size_t const edit_distance = edit(&va_std_allocator, m, argv[1], n, argv[2]); printf("edit distance: %zu (%zu)\n", edit_distance, count); return EXIT_SUCCESS; From 53ffea33b06971a8fa0684da3419327671d10ae6 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 4 Jun 2024 09:58:25 +0200 Subject: [PATCH 048/704] Restrict void pointers --- include/alloc.h | 2 +- include/array.h | 4 ++-- include/static_alloc.h | 8 ++++---- include/std_alloc.h | 4 ++-- src/array.c | 4 ++-- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/include/alloc.h b/include/alloc.h index 0edfdfd..0e9a68c 100644 --- a/include/alloc.h +++ b/include/alloc.h @@ -11,7 +11,7 @@ extern "C" typedef struct { - void* (*alloc)(void* const context, void* const ptr, size_t const old_size, size_t const size); + void* (*alloc)(void* const restrict context, void* const restrict ptr, size_t const old_size, size_t const size); void* context; } VA_Allocator; diff --git a/include/array.h b/include/array.h index 28d89e7..5566b8c 100644 --- a/include/array.h +++ b/include/array.h @@ -24,11 +24,11 @@ va_array_init(VA_Allocator const allocator[static 1], size_t const capacity, siz void* -va_array_ensure(VA_Allocator const allocator[static 1], void* const ptr, size_t const count); +va_array_ensure(VA_Allocator const allocator[static restrict 1], void* const restrict ptr, size_t const count); void* -va_array_destroy(VA_Allocator const allocator[static 1], void* const ptr); +va_array_destroy(VA_Allocator const allocator[static restrict 1], void* const restrict ptr); #define \ diff --git a/include/static_alloc.h b/include/static_alloc.h index 5d3a6e5..1031f4b 100644 --- a/include/static_alloc.h +++ b/include/static_alloc.h @@ -29,9 +29,9 @@ static VA_Static_Buffer va_static_buffer = { ._size = sizeof(va_static_buffer) } static void* -va_static_alloc(void* const context, void* const ptr, size_t const old_size, size_t const size) +va_static_alloc(void* const restrict context, void* const restrict ptr, size_t const old_size, size_t const size) { - VA_Static_Buffer* const buffer = (VA_Static_Buffer*) context; + VA_Static_Buffer* const restrict buffer = (VA_Static_Buffer*) context; if (size == 0) { @@ -49,7 +49,7 @@ va_static_alloc(void* const context, void* const ptr, size_t const old_size, siz { return NULL; // OOM } // if - char const* const src = ptr; + char const* const restrict src = ptr; for (size_t i = 0; i < old_size; ++i) { buffer->data[buffer->free + i] = src[i]; @@ -61,7 +61,7 @@ va_static_alloc(void* const context, void* const ptr, size_t const old_size, siz return NULL; // OOM } // if - void* const here = buffer->data + buffer->free; + void* const restrict here = buffer->data + buffer->free; buffer->free += size; return here; } // va_static_alloc diff --git a/include/std_alloc.h b/include/std_alloc.h index 5aea274..b9e9ce9 100644 --- a/include/std_alloc.h +++ b/include/std_alloc.h @@ -14,7 +14,7 @@ extern "C" static inline void* -va_std_alloc(void* const context, void* const ptr, size_t const old_size, size_t const size) +va_std_alloc(void* const restrict context, void* const restrict ptr, size_t const old_size, size_t const size) { (void) context; (void) old_size; @@ -23,7 +23,7 @@ va_std_alloc(void* const context, void* const ptr, size_t const old_size, size_t free(ptr); return NULL; } // if - char* const here = realloc(ptr, size); + char* const restrict here = realloc(ptr, size); if (size > old_size) { (void) memset(here + old_size, 0, size - old_size); diff --git a/src/array.c b/src/array.c index ce1383e..72cc4b8 100644 --- a/src/array.c +++ b/src/array.c @@ -21,7 +21,7 @@ va_array_init(VA_Allocator const allocator[static 1], size_t const capacity, siz void* -va_array_ensure(VA_Allocator const allocator[static 1], void* const ptr, size_t const count) +va_array_ensure(VA_Allocator const allocator[static restrict 1], void* const restrict ptr, size_t const count) { VA_Array* header = (VA_Array*)(ptr) - 1; if (header->capacity - header->length >= count) @@ -46,7 +46,7 @@ va_array_ensure(VA_Allocator const allocator[static 1], void* const ptr, size_t void* -va_array_destroy(VA_Allocator const allocator[static 1], void* const ptr) +va_array_destroy(VA_Allocator const allocator[static restrict 1], void* const restrict ptr) { if (ptr == NULL) { From 6576b9a2d5174e17ba03bfe6bc32e99876f7cb1f Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 4 Jun 2024 11:44:09 +0200 Subject: [PATCH 049/704] WIP LCS nodes --- src/main.c | 127 +++++++++++++++++++++-------------------------------- 1 file changed, 51 insertions(+), 76 deletions(-) diff --git a/src/main.c b/src/main.c index 31f4d8a..d122002 100644 --- a/src/main.c +++ b/src/main.c @@ -104,49 +104,55 @@ umin(size_t const a, size_t const b) } // umin +typedef struct +{ + size_t const len_ref; + char const* const restrict reference; + size_t const len_obs; + char const* const restrict observed; + size_t* const restrict diagonals; +} Expand_Context; + + static size_t -expand(size_t const len_ref, - char const reference[static restrict len_ref], - size_t const len_obs, - char const observed[static restrict len_obs], +expand(Expand_Context const context, ptrdiff_t const idx, - size_t const offset, - size_t const diagonals[static restrict len_ref + len_obs + 3], - ptrdiff_t const delta, - size_t const it) + size_t const p) { + ptrdiff_t const delta = context.len_obs - context.len_ref; + size_t const offset = context.len_ref + 1; + size_t row; size_t col; size_t end; if (idx > 0) { - row = diagonals[offset + idx]; + row = context.diagonals[offset + idx]; col = row + idx; - end = umax(diagonals[offset + idx - 1] - 1, diagonals[offset + idx + 1]); + end = umax(context.diagonals[offset + idx - 1] - 1, context.diagonals[offset + idx + 1]); } // if else if (idx < 0) { - col = diagonals[offset + idx]; + col = context.diagonals[offset + idx]; row = col - idx; - end = umax(diagonals[offset + idx - 1], diagonals[offset + idx + 1] - 1); + end = umax(context.diagonals[offset + idx - 1], context.diagonals[offset + idx + 1] - 1); } // if else { - row = diagonals[offset + idx]; + row = context.diagonals[offset + idx]; col = row + idx; - end = umax(diagonals[offset + idx - 1], diagonals[offset + idx + 1]); + end = umax(context.diagonals[offset + idx - 1], context.diagonals[offset + idx + 1]); } // else size_t steps = end + 1; -#ifdef VA_ALL_LCS bool matching = false; size_t match_row = 0; size_t match_col = 0; - for (size_t i = diagonals[offset + idx]; i < end; ++i) + for (size_t i = context.diagonals[offset + idx]; i < end; ++i) { - if (reference[row] == observed[col]) + if (context.reference[row] == context.observed[col]) { if (!matching) { @@ -157,14 +163,13 @@ expand(size_t const len_ref, } // if else if (matching) { - ptrdiff_t const d_row = len_ref - row; - ptrdiff_t const d_col = len_obs - col; - size_t const lcs_pos = (row + col - imaxabs(delta) - 2 * it + imaxabs(d_row - d_col)) / 2 - 1; + ptrdiff_t const d_row = context.len_ref - row; + ptrdiff_t const d_col = context.len_obs - col; + size_t const lcs_pos = (row + col - imaxabs(delta) - 2 * p + imaxabs(d_row - d_col)) / 2 - 1; size_t const length = row - match_row; - printf("%zu: (%zu, %zu, %zu):: %zu\n", lcs_pos, match_row, match_col, length, lcs_pos + 1 - length); + printf("%2zu: (%zu, %zu, %zu)\n", lcs_pos, match_row, match_col, length); matching = false; } // if - count += 1; row += 1; col += 1; } // for @@ -174,39 +179,20 @@ expand(size_t const len_ref, match_row = row; match_col = col; } // if - while (row < len_ref && col < len_obs && reference[row] == observed[col]) + while (row < context.len_ref && col < context.len_obs && context.reference[row] == context.observed[col]) { matching = true; - count += 1; row += 1; col += 1; steps += 1; } // while if (matching) { - ptrdiff_t const d_row = len_ref - row; - ptrdiff_t const d_col = len_obs - col; - size_t const lcs_pos = (row + col - imaxabs(delta) - 2 * it + imaxabs(d_row - d_col)) / 2 - 1; + ptrdiff_t const d_row = context.len_ref - row; + ptrdiff_t const d_col = context.len_obs - col; + size_t const lcs_pos = (row + col - imaxabs(delta) - 2 * p + imaxabs(d_row - d_col)) / 2 - 1; size_t const length = row - match_row; - printf("%zu: (%zu, %zu, %zu):: %zu\n", lcs_pos, match_row, match_col, length, lcs_pos + 1 - length); - } // if -#else - (void) delta; - (void) it; - row += end - diagonals[offset + idx]; - col += end - diagonals[offset + idx]; - while (row < len_ref && col < len_obs && reference[row] == observed[col]) - { - count += 1; - row += 1; - col += 1; - steps += 1; - } // while -#endif - - if (row < len_ref && col < len_obs) - { - count += 1; + printf("%2zu: (%zu, %zu, %zu)\n", lcs_pos, match_row, match_col, length); } // if return steps; @@ -224,16 +210,16 @@ edit(VA_Allocator const allocator[static restrict 1], size_t const offset = len_ref + 1; size_t const size = len_ref + len_obs + 3; - size_t* const restrict diagonals = allocator->alloc(allocator->context, NULL, 0, size * sizeof(*diagonals)); - if (diagonals == NULL) + Expand_Context const context = { - return -1; - } // if - - VA_LCS_Node* const lcs_nodes = allocator->alloc(allocator->context, NULL, 0, umin(len_ref, len_obs) * sizeof(*lcs_nodes)); - if (lcs_nodes == NULL) + len_ref, + reference, + len_obs, + observed, + .diagonals = allocator->alloc(allocator->context, NULL, 0, size * sizeof(*context.diagonals)), + }; + if (context.diagonals == NULL) { - allocator->alloc(allocator->context, diagonals, size * sizeof(*diagonals), 0); return -1; } // if @@ -241,25 +227,25 @@ edit(VA_Allocator const allocator[static restrict 1], size_t const upper = delta > 0 ? delta : 0; size_t const len = umax(len_ref, len_obs) - imaxabs(delta); - size_t it = 0; - while (diagonals[offset + delta] <= len) + size_t p = 0; + while (context.diagonals[offset + delta] <= len) { - for (ptrdiff_t idx = lower - it; idx < delta; ++idx) + for (ptrdiff_t idx = lower - p; idx < delta; ++idx) { - diagonals[offset + idx] = expand(len_ref, reference, len_obs, observed, idx, offset, diagonals, delta, it); + context.diagonals[offset + idx] = expand(context, idx, p); } // for - for (ptrdiff_t idx = upper + it; idx > delta; --idx) + for (ptrdiff_t idx = upper + p; idx > delta; --idx) { - diagonals[offset + idx] = expand(len_ref, reference, len_obs, observed, idx, offset, diagonals, delta, it); + context.diagonals[offset + idx] = expand(context, idx, p); } // for - diagonals[offset + delta] = expand(len_ref, reference, len_obs, observed, delta, offset, diagonals, delta, it); + context.diagonals[offset + delta] = expand(context, delta, p); - it += 1; + p += 1; } // while - allocator->alloc(allocator->context, diagonals, size * sizeof(*diagonals), 0); + allocator->alloc(allocator->context, context.diagonals, size * sizeof(*context.diagonals), 0); - return imaxabs(delta) + 2 * it - 2; + return imaxabs(delta) + 2 * p - 2; } // edit @@ -300,11 +286,6 @@ test_wu_compare(void) assert(wu_distance == tests[i].distance); assert(count == tests[i].count); - count = 0; - size_t const edit_distance = edit(&va_static_allocator, m, tests[i].a, n, tests[i].b); - assert(edit_distance == tests[i].distance); - //assert(count == tests[i].count); - fprintf(stderr, "."); } // for fprintf(stderr, " passed\n"); @@ -314,7 +295,7 @@ test_wu_compare(void) int main(int argc, char* argv[argc + 1]) { - //test_wu_compare(); + test_wu_compare(); if (argc < 3) { @@ -325,12 +306,6 @@ main(int argc, char* argv[argc + 1]) size_t const m = strlen(argv[1]); size_t const n = strlen(argv[2]); - count = 0; - size_t const wu_distance = m > n ? - wu_compare(&va_static_allocator, n, argv[2], m, argv[1]) : - wu_compare(&va_static_allocator, m, argv[1], n, argv[2]); - printf(" wu distance: %zu (%zu)\n", wu_distance, count); - count = 0; size_t const edit_distance = edit(&va_std_allocator, m, argv[1], n, argv[2]); printf("edit distance: %zu (%zu)\n", edit_distance, count); From f28f27c01c31445db35fc08b227358d815d82927 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 6 Jun 2024 15:12:21 +0200 Subject: [PATCH 050/704] Added length interface to array --- include/array.h | 4 ++++ src/array.c | 13 ++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/include/array.h b/include/array.h index 5566b8c..f15cd31 100644 --- a/include/array.h +++ b/include/array.h @@ -31,6 +31,10 @@ void* va_array_destroy(VA_Allocator const allocator[static restrict 1], void* const restrict ptr); +size_t +va_array_length(void* const ptr); + + #define \ va_array_append(allocator, ptr, value) ( \ (ptr) = va_array_ensure(allocator, ptr, 1), \ diff --git a/src/array.c b/src/array.c index 72cc4b8..79a5da5 100644 --- a/src/array.c +++ b/src/array.c @@ -23,7 +23,7 @@ va_array_init(VA_Allocator const allocator[static 1], size_t const capacity, siz void* va_array_ensure(VA_Allocator const allocator[static restrict 1], void* const restrict ptr, size_t const count) { - VA_Array* header = (VA_Array*)(ptr) - 1; + VA_Array* header = (VA_Array*) (ptr) - 1; if (header->capacity - header->length >= count) { return ptr; @@ -55,3 +55,14 @@ va_array_destroy(VA_Allocator const allocator[static restrict 1], void* const re VA_Array* const header = (VA_Array*)(ptr) - 1; return allocator->alloc(allocator->context, header, sizeof(*header) + header->capacity * header->item_size, 0); } // va_array_destroy + + +inline size_t +va_array_length(void* const ptr) +{ + if (ptr == NULL) + { + return 0; + } // if + return ((VA_Array*) (ptr) - 1)->length; +} // va_array_length From d9d3a9467c24bfc388291607b574c86d78e83a50 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 6 Jun 2024 15:12:53 +0200 Subject: [PATCH 051/704] Tests for array length --- tests/test_array.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/tests/test_array.c b/tests/test_array.c index 07a3231..8fb5228 100644 --- a/tests/test_array.c +++ b/tests/test_array.c @@ -153,6 +153,30 @@ test_va_array_destroy(void) } // test_va_array_destroy +static void +test_va_array_length(void) +{ + static struct { + VA_Allocator const* const allocator; + size_t const capacity; + } const tests[] = + { + {&va_std_allocator, 0}, + {&null_allocator, 0}, + }; // tests + + fprintf(stderr, "%s:%s: ", __FILE__, __func__); + for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) + { + uint32_t* array = va_array_init(tests[i].allocator, tests[i].capacity, sizeof(*array)); + assert(va_array_length(array) == 0); + array = va_array_destroy(tests[i].allocator, array); + fprintf(stderr, "."); + } // for + fprintf(stderr, " passed\n"); +} // test_va_array_length + + static void test_va_array_append(void) { @@ -196,6 +220,7 @@ main(void) test_va_array_ensure(); test_va_array_ensure_null(); test_va_array_destroy(); + test_va_array_length(); test_va_array_append(); return EXIT_SUCCESS; } // main From 5b266a2cff807e94711326232ac4e44cc2c76fc6 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 6 Jun 2024 15:13:19 +0200 Subject: [PATCH 052/704] 'Working' LCS nodes structure --- src/main.c | 66 +++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 53 insertions(+), 13 deletions(-) diff --git a/src/main.c b/src/main.c index d122002..f03a59e 100644 --- a/src/main.c +++ b/src/main.c @@ -7,7 +7,7 @@ #include // strlen #include "../include/alloc.h" // VA_Allocator -#include "../include/array.h" // +#include "../include/array.h" // va_array_* #include "../include/static_alloc.h" // va_static_allocator #include "../include/std_alloc.h" // va_std_allocator @@ -87,7 +87,7 @@ typedef struct size_t row; size_t col; size_t length; -} VA_LCS_Node; +} LCS_Node; static inline size_t @@ -106,18 +106,21 @@ umin(size_t const a, size_t const b) typedef struct { + VA_Allocator const* const restrict allocator; size_t const len_ref; char const* const restrict reference; size_t const len_obs; char const* const restrict observed; size_t* const restrict diagonals; -} Expand_Context; + LCS_Node** const restrict lcs_nodes; +} Context; static size_t -expand(Expand_Context const context, +expand(Context const context, ptrdiff_t const idx, - size_t const p) + size_t const p, + size_t* const max_lcs_pos) { ptrdiff_t const delta = context.len_obs - context.len_ref; size_t const offset = context.len_ref + 1; @@ -166,8 +169,16 @@ expand(Expand_Context const context, ptrdiff_t const d_row = context.len_ref - row; ptrdiff_t const d_col = context.len_obs - col; size_t const lcs_pos = (row + col - imaxabs(delta) - 2 * p + imaxabs(d_row - d_col)) / 2 - 1; + if (lcs_pos > *max_lcs_pos) + { + *max_lcs_pos = lcs_pos + 1; + } // if size_t const length = row - match_row; - printf("%2zu: (%zu, %zu, %zu)\n", lcs_pos, match_row, match_col, length); + if (context.lcs_nodes[lcs_pos] == NULL) + { + context.lcs_nodes[lcs_pos] = va_array_init(context.allocator, 1, sizeof(*context.lcs_nodes[lcs_pos])); + } // if + va_array_append(context.allocator, context.lcs_nodes[lcs_pos], ((LCS_Node) {match_row, match_col, length})); matching = false; } // if row += 1; @@ -191,8 +202,16 @@ expand(Expand_Context const context, ptrdiff_t const d_row = context.len_ref - row; ptrdiff_t const d_col = context.len_obs - col; size_t const lcs_pos = (row + col - imaxabs(delta) - 2 * p + imaxabs(d_row - d_col)) / 2 - 1; + if (lcs_pos > *max_lcs_pos) + { + *max_lcs_pos = lcs_pos + 1; + } // if size_t const length = row - match_row; - printf("%2zu: (%zu, %zu, %zu)\n", lcs_pos, match_row, match_col, length); + if (context.lcs_nodes[lcs_pos] == NULL) + { + context.lcs_nodes[lcs_pos] = va_array_init(context.allocator, 1, sizeof(*context.lcs_nodes[lcs_pos])); + } // if + va_array_append(context.allocator, context.lcs_nodes[lcs_pos], ((LCS_Node) {match_row, match_col, length})); } // if return steps; @@ -210,16 +229,20 @@ edit(VA_Allocator const allocator[static restrict 1], size_t const offset = len_ref + 1; size_t const size = len_ref + len_obs + 3; - Expand_Context const context = + Context const context = { + allocator, len_ref, reference, len_obs, observed, .diagonals = allocator->alloc(allocator->context, NULL, 0, size * sizeof(*context.diagonals)), + .lcs_nodes = allocator->alloc(allocator->context, NULL, 0, umin(len_ref, len_obs) * sizeof(*context.lcs_nodes)), }; - if (context.diagonals == NULL) + if (context.diagonals == NULL || context.lcs_nodes == NULL) { + allocator->alloc(allocator->context, context.diagonals, size * sizeof(*context.diagonals), 0); + allocator->alloc(allocator->context, context.lcs_nodes, umin(len_ref, len_obs) * sizeof(*context.lcs_nodes), 0); return -1; } // if @@ -228,23 +251,40 @@ edit(VA_Allocator const allocator[static restrict 1], size_t const len = umax(len_ref, len_obs) - imaxabs(delta); size_t p = 0; + size_t max_lcs_pos = 0; while (context.diagonals[offset + delta] <= len) { for (ptrdiff_t idx = lower - p; idx < delta; ++idx) { - context.diagonals[offset + idx] = expand(context, idx, p); + context.diagonals[offset + idx] = expand(context, idx, p, &max_lcs_pos); } // for for (ptrdiff_t idx = upper + p; idx > delta; --idx) { - context.diagonals[offset + idx] = expand(context, idx, p); + context.diagonals[offset + idx] = expand(context, idx, p, &max_lcs_pos); } // for - context.diagonals[offset + delta] = expand(context, delta, p); + context.diagonals[offset + delta] = expand(context, delta, p, &max_lcs_pos); p += 1; } // while allocator->alloc(allocator->context, context.diagonals, size * sizeof(*context.diagonals), 0); + for (size_t i = 0; i < max_lcs_pos; ++i) + { + if (context.lcs_nodes[i] != NULL) + { + printf("%zu: ", i); + for (size_t j = 0; j < va_array_length(context.lcs_nodes[i]); ++j) + { + printf("(%zu, %zu, %zu) ", context.lcs_nodes[i][j].row, context.lcs_nodes[i][j].col, context.lcs_nodes[i][j].length); + } // for + printf("\n"); + } // if + context.lcs_nodes[i] = va_array_destroy(allocator, context.lcs_nodes[i]); + } // for + + allocator->alloc(allocator->context, context.lcs_nodes, umin(len_ref, len_obs) * sizeof(*context.lcs_nodes), 0); + return imaxabs(delta) + 2 * p - 2; } // edit @@ -295,7 +335,7 @@ test_wu_compare(void) int main(int argc, char* argv[argc + 1]) { - test_wu_compare(); + // test_wu_compare(); if (argc < 3) { From a0b169013419275de2be6f55e80b30ee974063aa Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 10 Jun 2024 20:25:50 +0200 Subject: [PATCH 053/704] Dynamic array with insert --- include/array.h | 35 +++++---- include/std_alloc.h | 16 +++-- src/array.c | 93 ++++++++++++++---------- src/main.c | 18 ++--- tests/test_array.c | 171 +++++++++----------------------------------- 5 files changed, 131 insertions(+), 202 deletions(-) diff --git a/include/array.h b/include/array.h index f15cd31..450eb9d 100644 --- a/include/array.h +++ b/include/array.h @@ -6,7 +6,7 @@ extern "C" { #endif -#include // size_t +#include // NULL, size_t #include "alloc.h" // VA_Allocator @@ -14,33 +14,42 @@ extern "C" typedef struct { size_t capacity; - size_t item_size; size_t length; } VA_Array; void* -va_array_init(VA_Allocator const allocator[static 1], size_t const capacity, size_t const item_size); +va_array_init(VA_Allocator const allocator, size_t const capcity, size_t const item_size); -void* -va_array_ensure(VA_Allocator const allocator[static restrict 1], void* const restrict ptr, size_t const count); +VA_Array* +va_array_header(void* const ptr); + + +size_t +va_array_length(void* const ptr); void* -va_array_destroy(VA_Allocator const allocator[static restrict 1], void* const restrict ptr); +va_array_grow(VA_Allocator const allocator, void* const restrict ptr, size_t const capacity, size_t const item_size); size_t -va_array_length(void* const ptr); +va_array_shift(void* const ptr, size_t const index, size_t const item_size); + + +#define va_array_destroy(allocator, ptr) ((ptr) == NULL ? NULL : allocator.alloc(allocator.context, va_array_header(ptr), va_array_header(ptr)->capacity * sizeof(*(ptr)), 0)) + + +#define va_array_insert(allocator, ptr, value, index) do { \ + (ptr) = va_array_grow(allocator, ptr, 1, sizeof(*ptr)); \ + if ((ptr) == NULL) break; \ + (ptr)[va_array_shift(ptr, index, sizeof(*ptr))] = (value); \ + ++va_array_header(ptr)->length; \ +} while (0) -#define \ -va_array_append(allocator, ptr, value) ( \ - (ptr) = va_array_ensure(allocator, ptr, 1), \ - (ptr)[((VA_Array*)(ptr) - 1)->length] = (value), \ - &(ptr)[((VA_Array*)(ptr) - 1)->length++] \ -) // va_array_append +#define va_array_append(allocator, ptr, value) va_array_insert(allocator, ptr, value, va_array_length(ptr)) #ifdef __cplusplus diff --git a/include/std_alloc.h b/include/std_alloc.h index b9e9ce9..2412cd0 100644 --- a/include/std_alloc.h +++ b/include/std_alloc.h @@ -16,19 +16,25 @@ extern "C" static inline void* va_std_alloc(void* const restrict context, void* const restrict ptr, size_t const old_size, size_t const size) { - (void) context; - (void) old_size; if (size == 0) { free(ptr); return NULL; } // if - char* const restrict here = realloc(ptr, size); + + (void) context; + + char* const restrict new_ptr = realloc(ptr, size); + if (new_ptr == NULL) + { + return NULL; // OOM + } // if + if (size > old_size) { - (void) memset(here + old_size, 0, size - old_size); + (void) memset(new_ptr + old_size, 0, size - old_size); } // if - return here; + return new_ptr; } // va_std_alloc diff --git a/src/array.c b/src/array.c index 79a5da5..b8164fe 100644 --- a/src/array.c +++ b/src/array.c @@ -4,65 +4,82 @@ #include "../include/array.h" // VA_Array, va_array_* -void* -va_array_init(VA_Allocator const allocator[static 1], size_t const capacity, size_t const item_size) +inline void* +va_array_init(VA_Allocator const allocator, size_t const capacity, size_t const item_size) { - size_t const min_capacity = capacity < 4 ? 4 : capacity; - VA_Array* const header = allocator->alloc(allocator->context, NULL, 0, sizeof(*header) + min_capacity * item_size); // OVERFLOW - if (header == NULL) - { - return NULL; - } // if - header->capacity = min_capacity; - header->item_size = item_size; - header->length = 0; - return header + 1; + return va_array_grow(allocator, NULL, capacity, item_size); } // va_array_init +inline VA_Array* +va_array_header(void* const ptr) +{ + return (VA_Array*) (ptr) - 1; +} // va_array_header + + +inline size_t +va_array_length(void* const ptr) +{ + return ptr == NULL ? 0 : va_array_header(ptr)->length; +} // va_array_length + + void* -va_array_ensure(VA_Allocator const allocator[static restrict 1], void* const restrict ptr, size_t const count) +va_array_grow(VA_Allocator const allocator, void* const restrict ptr, size_t const capacity, size_t const item_size) { - VA_Array* header = (VA_Array*) (ptr) - 1; - if (header->capacity - header->length >= count) + if (capacity == 0) + { + return ptr; + } // if + + if (ptr == NULL) + { + VA_Array* const restrict header = allocator.alloc(allocator.context, NULL, 0, sizeof(*header) + capacity * item_size); // OVERFLOW + if (header == NULL) + { + return NULL; // OOM + } // if + header->capacity = capacity; + header->length = 0; + return header + 1; + } // if + + VA_Array* restrict header = va_array_header(ptr); + if (header->capacity - header->length >= capacity) { return ptr; } // if - size_t const old_size = sizeof(*header) + header->capacity * header->item_size; - header->capacity *= 2; // OVERFLOW - while (header->capacity - header->length < count) + size_t new_capacity = header->capacity * 2; // OVERFLOW + while (new_capacity < capacity) { - header->capacity *= 2; // OVERFLOW + new_capacity *= 2; // OVERFLOW } // while - header = allocator->alloc(allocator->context, header, old_size, sizeof(*header) + header->capacity * header->item_size); // OVERFLOW + header = allocator.alloc(allocator.context, header, sizeof(*header) + header->capacity * item_size, sizeof(*header) * new_capacity * item_size); if (header == NULL) { - return NULL; + return NULL; // OOM } // if + + header->capacity = new_capacity; return header + 1; -} // va_array_ensure +} // va_array_grow -void* -va_array_destroy(VA_Allocator const allocator[static restrict 1], void* const restrict ptr) +size_t +va_array_shift(void* const ptr, size_t const index, size_t const item_size) { - if (ptr == NULL) + size_t const length = va_array_length(ptr); + if (index >= length) { - return NULL; + return length; } // if - VA_Array* const header = (VA_Array*)(ptr) - 1; - return allocator->alloc(allocator->context, header, sizeof(*header) + header->capacity * header->item_size, 0); -} // va_array_destroy - -inline size_t -va_array_length(void* const ptr) -{ - if (ptr == NULL) + for (size_t i = 0; i < (length - index) * item_size; ++i) { - return 0; - } // if - return ((VA_Array*) (ptr) - 1)->length; -} // va_array_length + ((char*) ptr)[length * item_size + item_size - 1 - i] = ((char*) ptr)[length * item_size - 1 - i]; + } // for + return index; +} // va_array_shift diff --git a/src/main.c b/src/main.c index f03a59e..f957f7b 100644 --- a/src/main.c +++ b/src/main.c @@ -106,7 +106,7 @@ umin(size_t const a, size_t const b) typedef struct { - VA_Allocator const* const restrict allocator; + VA_Allocator const allocator; size_t const len_ref; char const* const restrict reference; size_t const len_obs; @@ -219,7 +219,7 @@ expand(Context const context, static size_t -edit(VA_Allocator const allocator[static restrict 1], +edit(VA_Allocator const allocator, size_t const len_ref, char const reference[static restrict len_ref], size_t const len_obs, @@ -236,13 +236,13 @@ edit(VA_Allocator const allocator[static restrict 1], reference, len_obs, observed, - .diagonals = allocator->alloc(allocator->context, NULL, 0, size * sizeof(*context.diagonals)), - .lcs_nodes = allocator->alloc(allocator->context, NULL, 0, umin(len_ref, len_obs) * sizeof(*context.lcs_nodes)), + .diagonals = allocator.alloc(allocator.context, NULL, 0, size * sizeof(*context.diagonals)), + .lcs_nodes = allocator.alloc(allocator.context, NULL, 0, umin(len_ref, len_obs) * sizeof(*context.lcs_nodes)), }; if (context.diagonals == NULL || context.lcs_nodes == NULL) { - allocator->alloc(allocator->context, context.diagonals, size * sizeof(*context.diagonals), 0); - allocator->alloc(allocator->context, context.lcs_nodes, umin(len_ref, len_obs) * sizeof(*context.lcs_nodes), 0); + allocator.alloc(allocator.context, context.diagonals, size * sizeof(*context.diagonals), 0); + allocator.alloc(allocator.context, context.lcs_nodes, umin(len_ref, len_obs) * sizeof(*context.lcs_nodes), 0); return -1; } // if @@ -267,7 +267,7 @@ edit(VA_Allocator const allocator[static restrict 1], p += 1; } // while - allocator->alloc(allocator->context, context.diagonals, size * sizeof(*context.diagonals), 0); + allocator.alloc(allocator.context, context.diagonals, size * sizeof(*context.diagonals), 0); for (size_t i = 0; i < max_lcs_pos; ++i) { @@ -283,7 +283,7 @@ edit(VA_Allocator const allocator[static restrict 1], context.lcs_nodes[i] = va_array_destroy(allocator, context.lcs_nodes[i]); } // for - allocator->alloc(allocator->context, context.lcs_nodes, umin(len_ref, len_obs) * sizeof(*context.lcs_nodes), 0); + allocator.alloc(allocator.context, context.lcs_nodes, umin(len_ref, len_obs) * sizeof(*context.lcs_nodes), 0); return imaxabs(delta) + 2 * p - 2; } // edit @@ -347,7 +347,7 @@ main(int argc, char* argv[argc + 1]) size_t const n = strlen(argv[2]); count = 0; - size_t const edit_distance = edit(&va_std_allocator, m, argv[1], n, argv[2]); + size_t const edit_distance = edit(va_std_allocator, m, argv[1], n, argv[2]); printf("edit distance: %zu (%zu)\n", edit_distance, count); return EXIT_SUCCESS; diff --git a/tests/test_array.c b/tests/test_array.c index 8fb5228..acf53a5 100644 --- a/tests/test_array.c +++ b/tests/test_array.c @@ -13,7 +13,7 @@ static inline void* -null_alloc(void* const context, void* const ptr, size_t const old_size, size_t const size) +null_alloc(void* const restrict context, void* const restrict ptr, size_t const old_size, size_t const size) { (void) context; (void) ptr; @@ -30,24 +30,22 @@ static void test_va_array_init(void) { static struct { - VA_Allocator const* const allocator; size_t const capacity; VA_Array const header; } const tests[] = { - {&va_std_allocator, 0, { 4, 4, 0}}, - {&va_std_allocator, 1, { 4, 4, 0}}, - {&va_std_allocator, 4, { 4, 4, 0}}, - {&va_std_allocator, 5, { 5, 4, 0}}, - {&va_std_allocator, 100, {100, 4, 0}}, + { 1, { 1, 0}}, + { 10, { 10, 0}}, + {100, {100, 0}}, }; // tests fprintf(stderr, "%s:%s: ", __FILE__, __func__); for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) { - uint32_t* array = va_array_init(tests[i].allocator, tests[i].capacity, sizeof(*array)); - assert(memcmp(((VA_Array*) array) - 1, &tests[i].header, sizeof(tests[i].header)) == 0); - array = va_array_destroy(tests[i].allocator, array); + uint32_t* array = va_array_init(va_std_allocator, tests[i].capacity, sizeof(*array)); + assert(memcmp(va_array_header(array), &tests[i].header, sizeof(tests[i].header)) == 0); + array = va_array_destroy(va_std_allocator, array); + assert(array == NULL); fprintf(stderr, "."); } // for fprintf(stderr, " passed\n"); @@ -55,159 +53,61 @@ test_va_array_init(void) static void -test_va_array_init_null(void) -{ - static struct { - size_t const capacity; - } const tests[] = - { - {1}, - }; // tests - - fprintf(stderr, "%s:%s: ", __FILE__, __func__); - for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) - { - assert(va_array_init(&null_allocator, tests[i].capacity, sizeof(uint32_t)) == NULL); - fprintf(stderr, "."); - } // for - fprintf(stderr, " passed\n"); -} // test_va_array_init_null - - -static void -test_va_array_ensure(void) -{ - static struct { - VA_Allocator const* const allocator; - size_t const capacity; - size_t const count; - VA_Array const header; - } const tests[] = - { - {&va_std_allocator, 0, 0, { 4, 4, 0}}, - {&va_std_allocator, 0, 1, { 4, 4, 0}}, - {&va_std_allocator, 0, 4, { 4, 4, 0}}, - {&va_std_allocator, 0, 5, { 8, 4, 0}}, - {&va_std_allocator, 100, 100, {100, 4, 0}}, - {&va_std_allocator, 100, 101, {200, 4, 0}}, - {&va_std_allocator, 0, 100, {128, 4, 0}}, - }; // tests - - fprintf(stderr, "%s:%s: ", __FILE__, __func__); - for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) - { - uint32_t* array = va_array_init(tests[i].allocator, tests[i].capacity, sizeof(*array)); - array = va_array_ensure(tests[i].allocator, array, tests[i].count); - assert(memcmp(((VA_Array*) array) - 1, &tests[i].header, sizeof(tests[i].header)) == 0); - array = va_array_destroy(tests[i].allocator, array); - fprintf(stderr, "."); - } // for - fprintf(stderr, " passed\n"); -} // test_va_array_ensure - - -static void -test_va_array_ensure_null(void) -{ - static struct { - size_t const capacity; - size_t const count; - } const tests[] = - { - {0, 5}, - }; // tests - - fprintf(stderr, "%s:%s: ", __FILE__, __func__); - for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) - { - uint32_t* array = va_array_init(&va_std_allocator, tests[i].capacity, sizeof(*array)); - assert(va_array_ensure(&null_allocator, array, tests[i].count) == NULL); - array = va_array_destroy(&va_std_allocator, array); - fprintf(stderr, "."); - } // for - fprintf(stderr, " passed\n"); -} // test_va_array_ensure_null - - -static void -test_va_array_destroy(void) +test_va_array_init_zero(void) { static struct { - VA_Allocator const* const allocator; + VA_Allocator const allocator; size_t const capacity; } const tests[] = { - {&va_std_allocator, 0}, - {&null_allocator, 0}, + {va_std_allocator, 0}, + {null_allocator, 0}, }; // tests fprintf(stderr, "%s:%s: ", __FILE__, __func__); for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) { uint32_t* array = va_array_init(tests[i].allocator, tests[i].capacity, sizeof(*array)); + assert(array == NULL); array = va_array_destroy(tests[i].allocator, array); assert(array == NULL); fprintf(stderr, "."); } // for fprintf(stderr, " passed\n"); -} // test_va_array_destroy +} // test_va_array_init_zero static void -test_va_array_length(void) +test_va_array_init_null(void) { - static struct { - VA_Allocator const* const allocator; - size_t const capacity; - } const tests[] = - { - {&va_std_allocator, 0}, - {&null_allocator, 0}, - }; // tests - fprintf(stderr, "%s:%s: ", __FILE__, __func__); - for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) - { - uint32_t* array = va_array_init(tests[i].allocator, tests[i].capacity, sizeof(*array)); - assert(va_array_length(array) == 0); - array = va_array_destroy(tests[i].allocator, array); - fprintf(stderr, "."); - } // for + uint32_t* array = va_array_init(null_allocator, 100, sizeof(*array)); + assert(array == NULL); + array = va_array_destroy(null_allocator, array); + assert(array == NULL); + fprintf(stderr, "."); fprintf(stderr, " passed\n"); -} // test_va_array_length +} // test_va_array_init_null static void test_va_array_append(void) { - static struct { - VA_Allocator const* const allocator; - size_t const capacity; - uint32_t const count; - VA_Array const header; - } const tests[] = - { - {&va_std_allocator, 0, 0, { 4, 4, 0}}, - {&va_std_allocator, 0, 10, {16, 4, 10}}, - {&va_std_allocator, 5, 10, {10, 4, 10}}, - }; // tests - + uint32_t const n = 100; fprintf(stderr, "%s:%s: ", __FILE__, __func__); - for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) + uint32_t* array = NULL; + for (uint32_t i = 0; i < n; ++i) { - uint32_t* array = va_array_init(tests[i].allocator, tests[i].capacity, sizeof(*array)); - for (uint32_t j = 0; j < tests[i].count; ++j) - { - va_array_append(tests[i].allocator, array, j); - } // for - assert(memcmp(((VA_Array*) array) - 1, &tests[i].header, sizeof(tests[i].header)) == 0); - for (uint32_t j = 0; j < tests[i].count; ++j) - { - assert(array[j] == j); - } // for - array = va_array_destroy(tests[i].allocator, array); - fprintf(stderr, "."); + va_array_append(va_std_allocator, array, i); + } // for + assert(va_array_length(array) == n); + for (uint32_t i = 0; i < va_array_length(array); ++i) + { + assert(array[i] == i); } // for + array = va_array_destroy(va_std_allocator, array); + assert(array == NULL); + fprintf(stderr, "."); fprintf(stderr, " passed\n"); } // test_va_array_append @@ -216,11 +116,8 @@ int main(void) { test_va_array_init(); + test_va_array_init_zero(); test_va_array_init_null(); - test_va_array_ensure(); - test_va_array_ensure_null(); - test_va_array_destroy(); - test_va_array_length(); test_va_array_append(); return EXIT_SUCCESS; } // main From d2b3bf74d2a5057aaa4648b774e40ef67ea856cf Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 11 Jun 2024 11:21:24 +0200 Subject: [PATCH 054/704] WIP: LCS nodes for large variant --- include/static_alloc.h | 6 +-- include/string.h | 33 -------------- src/main.c | 100 +++++++++++++++++++++++++---------------- src/string.c | 42 ----------------- tests/test_string.c | 88 ------------------------------------ 5 files changed, 64 insertions(+), 205 deletions(-) delete mode 100644 include/string.h delete mode 100644 src/string.c delete mode 100644 tests/test_string.c diff --git a/include/static_alloc.h b/include/static_alloc.h index 1031f4b..d5be1dd 100644 --- a/include/static_alloc.h +++ b/include/static_alloc.h @@ -31,7 +31,7 @@ static VA_Static_Buffer va_static_buffer = { ._size = sizeof(va_static_buffer) } static void* va_static_alloc(void* const restrict context, void* const restrict ptr, size_t const old_size, size_t const size) { - VA_Static_Buffer* const restrict buffer = (VA_Static_Buffer*) context; + VA_Static_Buffer* const restrict buffer = context; if (size == 0) { @@ -61,9 +61,9 @@ va_static_alloc(void* const restrict context, void* const restrict ptr, size_t c return NULL; // OOM } // if - void* const restrict here = buffer->data + buffer->free; + void* const restrict new_ptr = buffer->data + buffer->free; buffer->free += size; - return here; + return new_ptr; } // va_static_alloc diff --git a/include/string.h b/include/string.h deleted file mode 100644 index 7c59e17..0000000 --- a/include/string.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef STRING_H -#define STRING_H - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include // size_t - -#include "alloc.h" // VA_Allocator - - -typedef struct -{ - size_t length; - char* data; -} VA_String; - - -VA_String -va_string_concat(VA_Allocator const allocator[static 1], VA_String lhs, VA_String const rhs); - - -VA_String -va_string_slice(VA_Allocator const allocator[static 1], VA_String const string, size_t const start, size_t const end); - - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif diff --git a/src/main.c b/src/main.c index f957f7b..2926d55 100644 --- a/src/main.c +++ b/src/main.c @@ -8,13 +8,9 @@ #include "../include/alloc.h" // VA_Allocator #include "../include/array.h" // va_array_* -#include "../include/static_alloc.h" // va_static_allocator #include "../include/std_alloc.h" // va_std_allocator -static size_t count = 0; - - static inline size_t wu_snake(size_t const m, char const a[static restrict m], @@ -28,20 +24,15 @@ wu_snake(size_t const m, size_t row = col - k; while (row < m && col < n && a[row] == b[col]) { - count += 1; row += 1; col += 1; } // while - if (row < m && col < n) - { - count += 1; - } // if return col; } // wu_snake static size_t -wu_compare(VA_Allocator const allocator[static restrict 1], +wu_compare(VA_Allocator const allocator, size_t const m, char const a[static restrict m], size_t const n, @@ -50,7 +41,7 @@ wu_compare(VA_Allocator const allocator[static restrict 1], ptrdiff_t const delta = n - m; size_t const offset = m + 1; size_t const size = m + n + 3; - ptrdiff_t* const restrict fp = allocator->alloc(allocator->context, NULL, 0, size * sizeof(*fp)); + ptrdiff_t* const restrict fp = allocator.alloc(allocator.context, NULL, 0, size * sizeof(*fp)); if (fp == NULL) { return -1; @@ -76,7 +67,7 @@ wu_compare(VA_Allocator const allocator[static restrict 1], p += 1; } // while - allocator->alloc(allocator->context, fp, size * sizeof(*fp), 0); + allocator.alloc(allocator.context, fp, size * sizeof(*fp), 0); return delta + 2 * (p - 1); } // wu_compare @@ -223,7 +214,8 @@ edit(VA_Allocator const allocator, size_t const len_ref, char const reference[static restrict len_ref], size_t const len_obs, - char const observed[static restrict len_obs]) + char const observed[static restrict len_obs], + LCS_Node*** restrict lcs_nodes) { ptrdiff_t const delta = len_obs - len_ref; size_t const offset = len_ref + 1; @@ -269,23 +261,9 @@ edit(VA_Allocator const allocator, allocator.alloc(allocator.context, context.diagonals, size * sizeof(*context.diagonals), 0); - for (size_t i = 0; i < max_lcs_pos; ++i) - { - if (context.lcs_nodes[i] != NULL) - { - printf("%zu: ", i); - for (size_t j = 0; j < va_array_length(context.lcs_nodes[i]); ++j) - { - printf("(%zu, %zu, %zu) ", context.lcs_nodes[i][j].row, context.lcs_nodes[i][j].col, context.lcs_nodes[i][j].length); - } // for - printf("\n"); - } // if - context.lcs_nodes[i] = va_array_destroy(allocator, context.lcs_nodes[i]); - } // for - - allocator.alloc(allocator.context, context.lcs_nodes, umin(len_ref, len_obs) * sizeof(*context.lcs_nodes), 0); - - return imaxabs(delta) + 2 * p - 2; + // transfer ownership + *lcs_nodes = allocator.alloc(allocator.context, context.lcs_nodes, umin(len_ref, len_obs) * sizeof(*context.lcs_nodes), max_lcs_pos * sizeof(*context.lcs_nodes)); + return max_lcs_pos; } // edit @@ -319,12 +297,10 @@ test_wu_compare(void) size_t const m = strlen(tests[i].a); size_t const n = strlen(tests[i].b); - count = 0; size_t const wu_distance = m > n ? - wu_compare(&va_static_allocator, n, tests[i].b, m, tests[i].a) : - wu_compare(&va_static_allocator, m, tests[i].a, n, tests[i].b); + wu_compare(va_std_allocator, n, tests[i].b, m, tests[i].a) : + wu_compare(va_std_allocator, m, tests[i].a, n, tests[i].b); assert(wu_distance == tests[i].distance); - assert(count == tests[i].count); fprintf(stderr, "."); } // for @@ -332,10 +308,45 @@ test_wu_compare(void) } // test_wu_compare +static void +test_large(void) +{ + char const* const restrict reference = "ATTCTATCTTCTGTCTACATAAGATGTCATACTAGAGGGCATATCTGCAATGTATACATATTATCTTTTCCAGCATGCATTCAGTTGTGTTGGAATAATTTATGTACACCTTTATAAACGCTGAGCCTCACAAGAGCCATGTGCCACGTATTGTTTTCTTACTACTTTTTGGGATACCTGGCACGTAATAGACACTCATTGAAAGTTTCCTAATGAATGAAGTACAAAGATAAAACAAGTTATAGACTGATTCTTTTGAGCTGTCAAGGTTGTAAATAGACTTTTGCTCAATCAATTCAAATGGTGGCAGGTAGTGGGGGTAGAGGGATTGGTATGAAAAACATAAGCTTTCAGAACTCCTGTGTTTATTTTTAGAATGTCAACTGCTTGAGTGTTTTTAACTCTGTGGTATCTGAACTATCTTCTCTAACTGCAGGTTGGGCTCAGATCTGTGATAGAACAGTTTCCTGGGAAGCTTGACTTTGTCCTTGTGGATGGGGGCTGTGTCCTAAGCCATGGCCACAAGCAGTTGATGTGCTTGGCTAGATCTGTTCTCAGTAAGGCGAAGATCTTGCTGCTTGATGAACCCAGTGCTCATTTGGATCCAGTGTGAGTTTCAGATGTTCTGTTACTTAATAGCACAGTGGGAACAGAATCATTATGCCTGCTTCATGGTGACACATATTTCTATTAGGCTGTCATGTCTGCGTGTGGGGGTCTCCCCCAAGATATGAAATAATTGCCCAGTGGAAATGAGCATAAATGCATATTTCCTTGCTAAGAGTCTTGTGTTTTCTTCCGAAGATAGTTTTTAGTTTCATACAAACTCTTCCCCCTTGTCAACACATGATGAAGCTTTTAAATACATGGGCCTAATCTGATCCTTATGATTTGCCTTTGTATCCCATTTATACCATAAGCATGTTTATAGCCCCAAATAAAGAAGTACTGGTGATTCTACATAATGAAAAATGTACTCATTTATTAAAGTTTCTTTGAAATATTTGTCCTGTTTATTTATGGATACTTAGAGTCTACCCCATGGTTGAAAAGCTGATTGTGGCTAACGCTATATCAACATTATGTGAAAAGAACTTAAAGAAATAAGTAATTTAAAGAGATAATAGAACAATAGACATATTATCAAGGTAAATACAGATCATTACTGTTCTGTGATATTATGTGTGGTATTTTCTTTCTTTTCTAGAACATACCAAATAATTAGAAGAACTCTAAAACAAGCATTTGCTGATTGCACAGTAATTCTCTGTGAACACAGGATAGAAGCAATGCTGGAATGCCAACAATTTTTGGTGAGTCTTTATAACTTTACTTAAGATCTCATTGCCCTTGTAATTCTTGATAACAATCTCACATGTGATAGTTCCTGCAAATTGCAACAATGTACAAGTTCTTTTCAAAAATATGTATCATACAGCCATCCAGCTTTACTCAAAATAGCTGCACAAGTTTTTCACTTTGATCTGAGCCATGTGGTGAGGTTGAAATATAGTAAATCTAAAATGGCAGCATATTACTAAGTTATGTTTATAAATAGGATATATATACTTTTTGAGCCCTTTATTTGGGGACCAAGTCATACAAAATACTCTACTGTTTAAGATTTTAAAAAAGGTCCCTGTGATTCTTTCAATAACTAAATGTCCCATGGATGTGGTCTGGGACAGGCCTAGTTGTCTTACAGTCTGATTTATGGTATTAATGACAAAGTTGAGAGGCACATTTCATTTTT"; + char const* const restrict observed = "ATTCTATCTTCTGTCTACATAAGATGTCATACTAGAGGGCATATCTGCAATGTATACATATTATCTTTTCCAGCATGCATTCAGTTGTGTTGGAATAATTTATGTACACCTTTATAAACGCTGAGCCTCACAAGAGCCATGTGCCACGTATTGTTTTCTTACTACTTTTTGGGATACCTGGCACGTAATAGACACTCATTGAAAGTTTCCTAATGAATGAAGTACAAAGATAAAACAAGTTATAGACTGATTCTTTTGAGCTGTCAAGGTTGTAAATAGACTTTTGCTCAATCAATTCAAATGGTGGCAGGTAGTGGGGGTAGAGGGATTGGTATGAAAAACATAAGCTTTCAGAACTCCTGTGTTTATTTTTAGAATGTCAACTGCTTGAGTGTTTTTAACTCTGTGGTATCTGAACTATCTTCTCTAACTGCAGGTGAGTCTTTATAACTTTACTTAAGATCTCATTGCCCTTGTAATTCTTGATAACAATCTCACATGTGATAGTTCCTGCAAATTGCAACAATGTACAAGTTCTTTTCAAAAATATGTATCATACAGCCATCCAGCTTTACTCAAAATAGCTGCACAAGTTTTTCACTTTGATCTGAGCCATGTGGTGAGGTTGAAATATAGTAAATCTAAAATGGCAGCATATTACTAAGTTATGTTTATAAATAGGATATATATACTTTTTGAGCCCTTTATTTGGGGACCAAGTCATACAAAATACTCTACTGTTTAAGATTTTAAAAAAGGTCCCTGTGATTCTTTCAATAACTAAATGTCCCATGGATGTGGTCTGGGACAGGCCTAGTTGTCTTACAGTCTGATTTATGGTATTAATGACAAAGTTGAGAGGCACATTTCATTTTT"; + size_t const len_ref = strlen(reference); + size_t const len_obs = strlen(observed); + + LCS_Node** lcs_nodes = NULL; + size_t const len_lcs = edit(va_std_allocator, len_ref, reference, len_obs, observed, &lcs_nodes); + if (lcs_nodes == NULL) + { + printf("OOM\n"); + return; + } // if + printf("len lcs: %zu\n", len_lcs); + for (size_t i = 0; i < len_lcs; ++i) + { + //printf(" %zu (%zu): ", i, va_array_length(lcs_nodes[i])); + for (size_t j = 0; j < va_array_length(lcs_nodes[i]); ++j) + { + //printf("(%zu, %zu, %zu) ", lcs_nodes[i][j].row, lcs_nodes[i][j].col, lcs_nodes[i][j].length); + } // for + //printf("\n"); + lcs_nodes[i] = va_array_destroy(va_std_allocator, lcs_nodes[i]); + } // for + lcs_nodes = va_std_allocator.alloc(va_std_allocator.context, lcs_nodes, len_lcs * sizeof(*lcs_nodes), 0); +} // test_large + + int -main(int argc, char* argv[argc + 1]) +main(int argc, char* argv[static argc + 1]) { - // test_wu_compare(); + test_large(); + return 0; + + + + test_wu_compare(); if (argc < 3) { @@ -346,9 +357,20 @@ main(int argc, char* argv[argc + 1]) size_t const m = strlen(argv[1]); size_t const n = strlen(argv[2]); - count = 0; - size_t const edit_distance = edit(va_std_allocator, m, argv[1], n, argv[2]); - printf("edit distance: %zu (%zu)\n", edit_distance, count); + LCS_Node** lcs_nodes = NULL; + size_t const len_lcs = edit(va_std_allocator, m, argv[1], n, argv[2], &lcs_nodes); + printf("len lcs: %zu\n", len_lcs); + for (size_t i = 0; i < len_lcs; ++i) + { + printf(" %zu (%zu): ", i, va_array_length(lcs_nodes[i])); + for (size_t j = 0; j < va_array_length(lcs_nodes[i]); ++j) + { + printf("(%zu, %zu, %zu) ", lcs_nodes[i][j].row, lcs_nodes[i][j].col, lcs_nodes[i][j].length); + } // for + printf("\n"); + lcs_nodes[i] = va_array_destroy(va_std_allocator, lcs_nodes[i]); + } // for + lcs_nodes = va_std_allocator.alloc(va_std_allocator.context, lcs_nodes, len_lcs * sizeof(*lcs_nodes), 0); return EXIT_SUCCESS; } // main diff --git a/src/string.c b/src/string.c deleted file mode 100644 index 21f0cbd..0000000 --- a/src/string.c +++ /dev/null @@ -1,42 +0,0 @@ -#include // NULL, size_t - -#include "../include/alloc.h" // VA_Allocator -#include "../include/string.h" // VA_String, va_string_* - - -VA_String -va_string_concat(VA_Allocator const allocator[static 1], VA_String lhs, VA_String const rhs) -{ - lhs.data = allocator->alloc(allocator->context, lhs.data, lhs.length, lhs.length + rhs.length); // OVERFLOW - if (lhs.data == NULL) - { - return (VA_String) {0, NULL}; - } // if - - for (size_t i = 0; i < rhs.length; ++i) - { - lhs.data[lhs.length + i] = rhs.data[i]; - } // for - lhs.length += rhs.length; - return lhs; -} // va_string_concat - - -VA_String -va_string_slice(VA_Allocator const allocator[static 1], VA_String const string, size_t const start, size_t const end) -{ - size_t const clamped_end = end > string.length ? string.length : end; - size_t const clamped_start = start > clamped_end ? clamped_end : start; - - VA_String slice = {clamped_end - clamped_start, allocator->alloc(allocator->context, NULL, 0, clamped_end - clamped_start)}; - if (slice.data == NULL) - { - return (VA_String) {0, NULL}; - } // if - - for (size_t i = 0; i < slice.length; ++i) - { - slice.data[i] = string.data[clamped_start + i]; - } // for - return slice; -} // va_string_slice diff --git a/tests/test_string.c b/tests/test_string.c deleted file mode 100644 index f710bb8..0000000 --- a/tests/test_string.c +++ /dev/null @@ -1,88 +0,0 @@ -#include // assert -#include // NULL, size_t -#include // stderr, fprintf -#include // EXIT_SUCCESS -#include // memcmp - -#include "../include/alloc.h" // VA_Allocator -#include "../include/std_alloc.h" // va_std_allocator - - -#include "../src/string.c" - - -static void -test_va_string_concat(void) -{ - static struct { - VA_Allocator const* const allocator; - VA_String lhs; - VA_String const rhs; - VA_String const expected; - } const tests[] = - { - {&va_std_allocator, {0, NULL}, {0, NULL}, {0, NULL}}, - {&va_std_allocator, {0, NULL}, {1, "A"}, {1, "A"}}, - }; // tests - - fprintf(stderr, "%s:%s: ", __FILE__, __func__); - for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) - { - VA_String const result = va_string_concat(tests[i].allocator, tests[i].lhs, tests[i].rhs); - if (result.data == NULL || tests[i].expected.data == NULL) - { - assert(tests[i].expected.data == NULL); - } // if - else - { - assert(memcmp(result.data, tests[i].expected.data, tests[i].expected.length) == 0); - tests[i].allocator->alloc(tests[i].allocator->context, result.data, result.length, 0); - } // else - fprintf(stderr, "."); - } // for - fprintf(stderr, " passed\n"); -} // test_va_string_concat - - -static void -test_va_string_slice(void) -{ - static struct { - VA_Allocator const* const allocator; - VA_String const string; - size_t const start; - size_t const end; - VA_String const expected; - } const tests[] = - { - {&va_std_allocator, {0, NULL}, 0, 0, {0, NULL}}, - {&va_std_allocator, {1, "A"}, 0, 0, {0, NULL}}, - {&va_std_allocator, {1, "A"}, 0, 1, {1, "A"}}, - }; // tests - - fprintf(stderr, "%s:%s: ", __FILE__, __func__); - for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) - { - VA_String const result = va_string_slice(tests[i].allocator, tests[i].string, tests[i].start, tests[i].end); - if (result.data == NULL || tests[i].expected.data == NULL) - { - assert(tests[i].expected.data == NULL); - } // if - else - { - assert(memcmp(result.data, tests[i].expected.data, tests[i].expected.length) == 0); - tests[i].allocator->alloc(tests[i].allocator->context, result.data, result.length, 0); - } // else - fprintf(stderr, "."); - } // for - fprintf(stderr, " passed\n"); -} // test_va_string_slice - - -int -main(void) -{ - test_va_string_concat(); - test_va_string_slice(); - return EXIT_SUCCESS; -} // main From 397ef5c927020fb6276713fddc03e558064e0b9b Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 11 Jun 2024 15:52:56 +0200 Subject: [PATCH 055/704] Edit distance module --- include/edit.h | 43 +++++++ src/edit.c | 269 ++++++++++++++++++++++++++++++++++++++ src/main.c | 322 ++-------------------------------------------- tests/test_edit.c | 60 +++++++++ 4 files changed, 380 insertions(+), 314 deletions(-) create mode 100644 include/edit.h create mode 100644 src/edit.c create mode 100644 tests/test_edit.c diff --git a/include/edit.h b/include/edit.h new file mode 100644 index 0000000..68c40f6 --- /dev/null +++ b/include/edit.h @@ -0,0 +1,43 @@ +#ifndef EDIT_H +#define EDIT_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include // size_t + +#include "alloc.h" // VA_Allocator + + +typedef struct +{ + size_t row; + size_t col; + size_t length; +} VA_LCS_Node; + + +size_t +va_edit_distance_only(VA_Allocator const allocator, + size_t const len_ref, + char const reference[static restrict len_ref], + size_t const len_obs, + char const observed[static restrict len_obs]); + + +size_t +va_edit(VA_Allocator const allocator, + size_t const len_ref, + char const reference[static restrict len_ref], + size_t const len_obs, + char const observed[static restrict len_obs], + VA_LCS_Node*** restrict lcs_nodes); + + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif diff --git a/src/edit.c b/src/edit.c new file mode 100644 index 0000000..e217741 --- /dev/null +++ b/src/edit.c @@ -0,0 +1,269 @@ +#include // imaxabs +#include // bool, false, true +#include // NULL, ptrdiff_t, size_t + +#include "../include/alloc.h" // VA_Allocator +#include "../include/array.h" // va_array_* +#include "../include/edit.h" // VA_LCS_Node, va_edit* + + +static inline size_t +wu_snake(size_t const m, + char const a[static restrict m], + size_t const n, + char const b[static restrict n], + ptrdiff_t const k, + ptrdiff_t const lower, + ptrdiff_t const upper) +{ + size_t col = lower > upper ? lower : upper; + size_t row = col - k; + while (row < m && col < n && a[row] == b[col]) + { + row += 1; + col += 1; + } // while + return col; +} // wu_snake + + +static size_t +wu_compare(VA_Allocator const allocator, + size_t const m, + char const a[static restrict m], + size_t const n, + char const b[static restrict n]) +{ + ptrdiff_t const delta = n - m; + size_t const offset = m + 1; + size_t const size = m + n + 3; + ptrdiff_t* const restrict fp = allocator.alloc(allocator.context, NULL, 0, size * sizeof(*fp)); + if (fp == NULL) + { + return -1; + } // if + + for (size_t i = 0; i < size; ++i) + { + fp[i] = -1; + } // for + + size_t p = 0; + while ((size_t) fp[delta + offset] != n) + { + for (ptrdiff_t k = -p; k <= delta - 1; ++k) + { + fp[k + offset] = wu_snake(m, a, n, b, k, fp[k - 1 + offset] + 1, fp[k + 1 + offset]); + } // for + for (ptrdiff_t k = delta + p; k >= delta + 1; --k) + { + fp[k + offset] = wu_snake(m, a, n, b, k, fp[k - 1 + offset] + 1, fp[k + 1 + offset]); + } // for + fp[delta + offset] = wu_snake(m, a, n, b, delta, fp[delta - 1 + offset] + 1, fp[delta + 1 + offset]); + p += 1; + } // while + + allocator.alloc(allocator.context, fp, size * sizeof(*fp), 0); + + return delta + 2 * (p - 1); +} // wu_compare + + +size_t +va_edit_distance_only(VA_Allocator const allocator, + size_t const len_ref, + char const reference[static restrict len_ref], + size_t const len_obs, + char const observed[static restrict len_obs]) +{ + return len_ref > len_obs ? + wu_compare(allocator, len_obs, observed, len_ref, reference) : + wu_compare(allocator, len_ref, reference, len_obs, observed); +} // va_edit_distance_only + + +static inline size_t +umax(size_t const a, size_t const b) +{ + return a > b ? a : b; +} // umax + + +static inline size_t +umin(size_t const a, size_t const b) +{ + return a < b ? a : b; +} // umin + + +typedef struct +{ + VA_Allocator const allocator; + size_t const len_ref; + char const* const restrict reference; + size_t const len_obs; + char const* const restrict observed; + size_t* const restrict diagonals; + VA_LCS_Node** const restrict lcs_nodes; +} Context; + + +static size_t +expand(Context const context, + ptrdiff_t const idx, + size_t const p, + size_t* const len_lcs) +{ + ptrdiff_t const delta = context.len_obs - context.len_ref; + size_t const offset = context.len_ref + 1; + + size_t row; + size_t col; + size_t end; + if (idx > 0) + { + row = context.diagonals[offset + idx]; + col = row + idx; + end = umax(context.diagonals[offset + idx - 1] - 1, context.diagonals[offset + idx + 1]); + } // if + else if (idx < 0) + { + col = context.diagonals[offset + idx]; + row = col - idx; + end = umax(context.diagonals[offset + idx - 1], context.diagonals[offset + idx + 1] - 1); + } // if + else + { + row = context.diagonals[offset + idx]; + col = row + idx; + end = umax(context.diagonals[offset + idx - 1], context.diagonals[offset + idx + 1]); + } // else + + size_t steps = end + 1; + + bool matching = false; + size_t match_row = 0; + size_t match_col = 0; + + for (size_t i = context.diagonals[offset + idx]; i < end; ++i) + { + if (context.reference[row] == context.observed[col]) + { + if (!matching) + { + match_row = row; + match_col = col; + matching = true; + } // if + } // if + else if (matching) + { + ptrdiff_t const d_row = context.len_ref - row; + ptrdiff_t const d_col = context.len_obs - col; + size_t const lcs_pos = (row + col - imaxabs(delta) - 2 * p + imaxabs(d_row - d_col)) / 2 - 1; + if (lcs_pos > *len_lcs) + { + *len_lcs = lcs_pos + 1; + } // if + size_t const length = row - match_row; + if (context.lcs_nodes[lcs_pos] == NULL) + { + context.lcs_nodes[lcs_pos] = va_array_init(context.allocator, 1, sizeof(*context.lcs_nodes[lcs_pos])); + } // if + va_array_append(context.allocator, context.lcs_nodes[lcs_pos], ((VA_LCS_Node) {match_row, match_col, length})); + matching = false; + } // if + row += 1; + col += 1; + } // for + + if (!matching) + { + match_row = row; + match_col = col; + } // if + while (row < context.len_ref && col < context.len_obs && context.reference[row] == context.observed[col]) + { + matching = true; + row += 1; + col += 1; + steps += 1; + } // while + if (matching) + { + ptrdiff_t const d_row = context.len_ref - row; + ptrdiff_t const d_col = context.len_obs - col; + size_t const lcs_pos = (row + col - imaxabs(delta) - 2 * p + imaxabs(d_row - d_col)) / 2 - 1; + if (lcs_pos > *len_lcs) + { + *len_lcs = lcs_pos + 1; + } // if + size_t const length = row - match_row; + if (context.lcs_nodes[lcs_pos] == NULL) + { + context.lcs_nodes[lcs_pos] = va_array_init(context.allocator, 1, sizeof(*context.lcs_nodes[lcs_pos])); + } // if + va_array_append(context.allocator, context.lcs_nodes[lcs_pos], ((VA_LCS_Node) {match_row, match_col, length})); + } // if + + return steps; +} // expand + + +size_t +va_edit(VA_Allocator const allocator, + size_t const len_ref, + char const reference[static restrict len_ref], + size_t const len_obs, + char const observed[static restrict len_obs], + VA_LCS_Node*** restrict lcs_nodes) +{ + ptrdiff_t const delta = len_obs - len_ref; + size_t const offset = len_ref + 1; + size_t const size = len_ref + len_obs + 3; + + Context const context = + { + allocator, + len_ref, + reference, + len_obs, + observed, + .diagonals = allocator.alloc(allocator.context, NULL, 0, size * sizeof(*context.diagonals)), + .lcs_nodes = allocator.alloc(allocator.context, NULL, 0, umin(len_ref, len_obs) * sizeof(*context.lcs_nodes)), + }; + if (context.diagonals == NULL || context.lcs_nodes == NULL) + { + allocator.alloc(allocator.context, context.diagonals, size * sizeof(*context.diagonals), 0); + allocator.alloc(allocator.context, context.lcs_nodes, umin(len_ref, len_obs) * sizeof(*context.lcs_nodes), 0); + return -1; + } // if + + size_t const lower = delta > 0 ? 0 : delta; + size_t const upper = delta > 0 ? delta : 0; + + size_t const len = umax(len_ref, len_obs) - imaxabs(delta); + size_t p = 0; + size_t max_lcs_pos = 0; + while (context.diagonals[offset + delta] <= len) + { + for (ptrdiff_t idx = lower - p; idx < delta; ++idx) + { + context.diagonals[offset + idx] = expand(context, idx, p, &max_lcs_pos); + } // for + for (ptrdiff_t idx = upper + p; idx > delta; --idx) + { + context.diagonals[offset + idx] = expand(context, idx, p, &max_lcs_pos); + } // for + context.diagonals[offset + delta] = expand(context, delta, p, &max_lcs_pos); + + p += 1; + } // while + + allocator.alloc(allocator.context, context.diagonals, size * sizeof(*context.diagonals), 0); + + // transfer ownership + *lcs_nodes = allocator.alloc(allocator.context, context.lcs_nodes, umin(len_ref, len_obs) * sizeof(*context.lcs_nodes), max_lcs_pos * sizeof(*context.lcs_nodes)); + return max_lcs_pos; +} // va_edit + diff --git a/src/main.c b/src/main.c index 2926d55..3c49500 100644 --- a/src/main.c +++ b/src/main.c @@ -1,313 +1,12 @@ -#include // assert -#include // imaxabs -#include // bool, false, true -#include // NULL, ptrdiff_t, size_t #include // stderr, fprintf, printf #include // EXIT_* #include // strlen -#include "../include/alloc.h" // VA_Allocator #include "../include/array.h" // va_array_* +#include "../include/edit.h" // va_edit #include "../include/std_alloc.h" // va_std_allocator -static inline size_t -wu_snake(size_t const m, - char const a[static restrict m], - size_t const n, - char const b[static restrict n], - ptrdiff_t const k, - ptrdiff_t const lower, - ptrdiff_t const upper) -{ - size_t col = lower > upper ? lower : upper; - size_t row = col - k; - while (row < m && col < n && a[row] == b[col]) - { - row += 1; - col += 1; - } // while - return col; -} // wu_snake - - -static size_t -wu_compare(VA_Allocator const allocator, - size_t const m, - char const a[static restrict m], - size_t const n, - char const b[static restrict n]) -{ - ptrdiff_t const delta = n - m; - size_t const offset = m + 1; - size_t const size = m + n + 3; - ptrdiff_t* const restrict fp = allocator.alloc(allocator.context, NULL, 0, size * sizeof(*fp)); - if (fp == NULL) - { - return -1; - } // if - - for (size_t i = 0; i < size; ++i) - { - fp[i] = -1; - } // for - - size_t p = 0; - while ((size_t) fp[delta + offset] != n) - { - for (ptrdiff_t k = -p; k <= delta - 1; ++k) - { - fp[k + offset] = wu_snake(m, a, n, b, k, fp[k - 1 + offset] + 1, fp[k + 1 + offset]); - } // for - for (ptrdiff_t k = delta + p; k >= delta + 1; --k) - { - fp[k + offset] = wu_snake(m, a, n, b, k, fp[k - 1 + offset] + 1, fp[k + 1 + offset]); - } // for - fp[delta + offset] = wu_snake(m, a, n, b, delta, fp[delta - 1 + offset] + 1, fp[delta + 1 + offset]); - p += 1; - } // while - - allocator.alloc(allocator.context, fp, size * sizeof(*fp), 0); - - return delta + 2 * (p - 1); -} // wu_compare - - -typedef struct -{ - size_t row; - size_t col; - size_t length; -} LCS_Node; - - -static inline size_t -umax(size_t const a, size_t const b) -{ - return a > b ? a : b; -} // umax - - -static inline size_t -umin(size_t const a, size_t const b) -{ - return a < b ? a : b; -} // umin - - -typedef struct -{ - VA_Allocator const allocator; - size_t const len_ref; - char const* const restrict reference; - size_t const len_obs; - char const* const restrict observed; - size_t* const restrict diagonals; - LCS_Node** const restrict lcs_nodes; -} Context; - - -static size_t -expand(Context const context, - ptrdiff_t const idx, - size_t const p, - size_t* const max_lcs_pos) -{ - ptrdiff_t const delta = context.len_obs - context.len_ref; - size_t const offset = context.len_ref + 1; - - size_t row; - size_t col; - size_t end; - if (idx > 0) - { - row = context.diagonals[offset + idx]; - col = row + idx; - end = umax(context.diagonals[offset + idx - 1] - 1, context.diagonals[offset + idx + 1]); - } // if - else if (idx < 0) - { - col = context.diagonals[offset + idx]; - row = col - idx; - end = umax(context.diagonals[offset + idx - 1], context.diagonals[offset + idx + 1] - 1); - } // if - else - { - row = context.diagonals[offset + idx]; - col = row + idx; - end = umax(context.diagonals[offset + idx - 1], context.diagonals[offset + idx + 1]); - } // else - - size_t steps = end + 1; - - bool matching = false; - size_t match_row = 0; - size_t match_col = 0; - - for (size_t i = context.diagonals[offset + idx]; i < end; ++i) - { - if (context.reference[row] == context.observed[col]) - { - if (!matching) - { - match_row = row; - match_col = col; - matching = true; - } // if - } // if - else if (matching) - { - ptrdiff_t const d_row = context.len_ref - row; - ptrdiff_t const d_col = context.len_obs - col; - size_t const lcs_pos = (row + col - imaxabs(delta) - 2 * p + imaxabs(d_row - d_col)) / 2 - 1; - if (lcs_pos > *max_lcs_pos) - { - *max_lcs_pos = lcs_pos + 1; - } // if - size_t const length = row - match_row; - if (context.lcs_nodes[lcs_pos] == NULL) - { - context.lcs_nodes[lcs_pos] = va_array_init(context.allocator, 1, sizeof(*context.lcs_nodes[lcs_pos])); - } // if - va_array_append(context.allocator, context.lcs_nodes[lcs_pos], ((LCS_Node) {match_row, match_col, length})); - matching = false; - } // if - row += 1; - col += 1; - } // for - - if (!matching) - { - match_row = row; - match_col = col; - } // if - while (row < context.len_ref && col < context.len_obs && context.reference[row] == context.observed[col]) - { - matching = true; - row += 1; - col += 1; - steps += 1; - } // while - if (matching) - { - ptrdiff_t const d_row = context.len_ref - row; - ptrdiff_t const d_col = context.len_obs - col; - size_t const lcs_pos = (row + col - imaxabs(delta) - 2 * p + imaxabs(d_row - d_col)) / 2 - 1; - if (lcs_pos > *max_lcs_pos) - { - *max_lcs_pos = lcs_pos + 1; - } // if - size_t const length = row - match_row; - if (context.lcs_nodes[lcs_pos] == NULL) - { - context.lcs_nodes[lcs_pos] = va_array_init(context.allocator, 1, sizeof(*context.lcs_nodes[lcs_pos])); - } // if - va_array_append(context.allocator, context.lcs_nodes[lcs_pos], ((LCS_Node) {match_row, match_col, length})); - } // if - - return steps; -} // expand - - -static size_t -edit(VA_Allocator const allocator, - size_t const len_ref, - char const reference[static restrict len_ref], - size_t const len_obs, - char const observed[static restrict len_obs], - LCS_Node*** restrict lcs_nodes) -{ - ptrdiff_t const delta = len_obs - len_ref; - size_t const offset = len_ref + 1; - size_t const size = len_ref + len_obs + 3; - - Context const context = - { - allocator, - len_ref, - reference, - len_obs, - observed, - .diagonals = allocator.alloc(allocator.context, NULL, 0, size * sizeof(*context.diagonals)), - .lcs_nodes = allocator.alloc(allocator.context, NULL, 0, umin(len_ref, len_obs) * sizeof(*context.lcs_nodes)), - }; - if (context.diagonals == NULL || context.lcs_nodes == NULL) - { - allocator.alloc(allocator.context, context.diagonals, size * sizeof(*context.diagonals), 0); - allocator.alloc(allocator.context, context.lcs_nodes, umin(len_ref, len_obs) * sizeof(*context.lcs_nodes), 0); - return -1; - } // if - - size_t const lower = delta > 0 ? 0 : delta; - size_t const upper = delta > 0 ? delta : 0; - - size_t const len = umax(len_ref, len_obs) - imaxabs(delta); - size_t p = 0; - size_t max_lcs_pos = 0; - while (context.diagonals[offset + delta] <= len) - { - for (ptrdiff_t idx = lower - p; idx < delta; ++idx) - { - context.diagonals[offset + idx] = expand(context, idx, p, &max_lcs_pos); - } // for - for (ptrdiff_t idx = upper + p; idx > delta; --idx) - { - context.diagonals[offset + idx] = expand(context, idx, p, &max_lcs_pos); - } // for - context.diagonals[offset + delta] = expand(context, delta, p, &max_lcs_pos); - - p += 1; - } // while - - allocator.alloc(allocator.context, context.diagonals, size * sizeof(*context.diagonals), 0); - - // transfer ownership - *lcs_nodes = allocator.alloc(allocator.context, context.lcs_nodes, umin(len_ref, len_obs) * sizeof(*context.lcs_nodes), max_lcs_pos * sizeof(*context.lcs_nodes)); - return max_lcs_pos; -} // edit - - -static void -test_wu_compare(void) -{ - static struct - { - char const* const restrict a; - char const* const restrict b; - size_t const distance; - size_t const count; - } const tests[] = - { - { "", "", 0, 0}, - { "a", "a", 0, 1}, - { "a", "b", 2, 1}, - { "abcf", "abcdf", 1, 5}, - { "abcdf", "abcf", 1, 5}, - { "aa", "aaaaaaaaa", 7, 2}, - { "aaaaaaaaa", "aa", 7, 2}, - { "acbdeacbed", "acebdabbabed", 6, 23}, - {"acebdabbabed", "acbdeacbed", 6, 23}, - { "ACCTGACT", "ATCTTACTT", 5, 17}, - { "ATCTTACTT", "ACCTGACT", 5, 17}, - }; - - fprintf(stderr, "%s:%s: ", __FILE__, __func__); - for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) - { - size_t const m = strlen(tests[i].a); - size_t const n = strlen(tests[i].b); - - size_t const wu_distance = m > n ? - wu_compare(va_std_allocator, n, tests[i].b, m, tests[i].a) : - wu_compare(va_std_allocator, m, tests[i].a, n, tests[i].b); - assert(wu_distance == tests[i].distance); - - fprintf(stderr, "."); - } // for - fprintf(stderr, " passed\n"); -} // test_wu_compare - - static void test_large(void) { @@ -316,8 +15,8 @@ test_large(void) size_t const len_ref = strlen(reference); size_t const len_obs = strlen(observed); - LCS_Node** lcs_nodes = NULL; - size_t const len_lcs = edit(va_std_allocator, len_ref, reference, len_obs, observed, &lcs_nodes); + VA_LCS_Node** lcs_nodes = NULL; + size_t const len_lcs = va_edit(va_std_allocator, len_ref, reference, len_obs, observed, &lcs_nodes); if (lcs_nodes == NULL) { printf("OOM\n"); @@ -326,12 +25,12 @@ test_large(void) printf("len lcs: %zu\n", len_lcs); for (size_t i = 0; i < len_lcs; ++i) { - //printf(" %zu (%zu): ", i, va_array_length(lcs_nodes[i])); + printf(" %zu (%zu): ", i, va_array_length(lcs_nodes[i])); for (size_t j = 0; j < va_array_length(lcs_nodes[i]); ++j) { - //printf("(%zu, %zu, %zu) ", lcs_nodes[i][j].row, lcs_nodes[i][j].col, lcs_nodes[i][j].length); + printf("(%zu, %zu, %zu) ", lcs_nodes[i][j].row, lcs_nodes[i][j].col, lcs_nodes[i][j].length); } // for - //printf("\n"); + printf("\n"); lcs_nodes[i] = va_array_destroy(va_std_allocator, lcs_nodes[i]); } // for lcs_nodes = va_std_allocator.alloc(va_std_allocator.context, lcs_nodes, len_lcs * sizeof(*lcs_nodes), 0); @@ -342,11 +41,6 @@ int main(int argc, char* argv[static argc + 1]) { test_large(); - return 0; - - - - test_wu_compare(); if (argc < 3) { @@ -357,8 +51,8 @@ main(int argc, char* argv[static argc + 1]) size_t const m = strlen(argv[1]); size_t const n = strlen(argv[2]); - LCS_Node** lcs_nodes = NULL; - size_t const len_lcs = edit(va_std_allocator, m, argv[1], n, argv[2], &lcs_nodes); + VA_LCS_Node** lcs_nodes = NULL; + size_t const len_lcs = va_edit(va_std_allocator, m, argv[1], n, argv[2], &lcs_nodes); printf("len lcs: %zu\n", len_lcs); for (size_t i = 0; i < len_lcs; ++i) { diff --git a/tests/test_edit.c b/tests/test_edit.c new file mode 100644 index 0000000..b4403ba --- /dev/null +++ b/tests/test_edit.c @@ -0,0 +1,60 @@ +#include // assert +#include // size_t +#include // stderr, fprintf +#include // EXIT_SUCCESS +#include // strlen + +#include "../include/alloc.h" // VA_Allocator +#include "../include/std_alloc.h" // va_std_allocator + + +#include "../src/array.c" +#include "../src/edit.c" + + +static void +test_wu_compare(void) +{ + static struct + { + char const* const restrict a; + char const* const restrict b; + size_t const distance; + } const tests[] = + { + { "", "", 0}, + { "a", "a", 0}, + { "a", "b", 2}, + { "abcf", "abcdf", 1}, + { "abcdf", "abcf", 1}, + { "aa", "aaaaaaaaa", 7}, + { "aaaaaaaaa", "aa", 7}, + { "acbdeacbed", "acebdabbabed", 6}, + {"acebdabbabed", "acbdeacbed", 6}, + { "ACCTGACT", "ATCTTACTT", 5}, + { "ATCTTACTT", "ACCTGACT", 5}, + }; + + fprintf(stderr, "%s:%s: ", __FILE__, __func__); + for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) + { + size_t const m = strlen(tests[i].a); + size_t const n = strlen(tests[i].b); + + size_t const wu_distance = m > n ? + wu_compare(va_std_allocator, n, tests[i].b, m, tests[i].a) : + wu_compare(va_std_allocator, m, tests[i].a, n, tests[i].b); + assert(wu_distance == tests[i].distance); + + fprintf(stderr, "."); + } // for + fprintf(stderr, " passed\n"); +} // test_wu_compare + + +int +main(void) +{ + test_wu_compare(); + return EXIT_SUCCESS; +} // main From c97ec5dedadf770e26804201697c939f6cabb553 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 13 Jun 2024 09:14:43 +0200 Subject: [PATCH 056/704] Typo --- include/array.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/array.h b/include/array.h index 450eb9d..d098309 100644 --- a/include/array.h +++ b/include/array.h @@ -19,7 +19,7 @@ typedef struct void* -va_array_init(VA_Allocator const allocator, size_t const capcity, size_t const item_size); +va_array_init(VA_Allocator const allocator, size_t const capacity, size_t const item_size); VA_Array* From 23717ab14d92cc76a2c5306a08e0e357c8523637 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 13 Jun 2024 13:50:56 +0200 Subject: [PATCH 057/704] WIP: build_graph --- include/edit.h | 2 + src/edit.c | 4 +- src/main.c | 173 ++++++++++++++++++++++++++++++++++++++++--------- 3 files changed, 147 insertions(+), 32 deletions(-) diff --git a/include/edit.h b/include/edit.h index 68c40f6..1812224 100644 --- a/include/edit.h +++ b/include/edit.h @@ -16,6 +16,8 @@ typedef struct size_t row; size_t col; size_t length; + size_t incoming; + size_t idx; } VA_LCS_Node; diff --git a/src/edit.c b/src/edit.c index e217741..77e4093 100644 --- a/src/edit.c +++ b/src/edit.c @@ -170,7 +170,7 @@ expand(Context const context, { context.lcs_nodes[lcs_pos] = va_array_init(context.allocator, 1, sizeof(*context.lcs_nodes[lcs_pos])); } // if - va_array_append(context.allocator, context.lcs_nodes[lcs_pos], ((VA_LCS_Node) {match_row, match_col, length})); + va_array_append(context.allocator, context.lcs_nodes[lcs_pos], ((VA_LCS_Node) {.row = match_row, .col = match_col, .length = length})); matching = false; } // if row += 1; @@ -203,7 +203,7 @@ expand(Context const context, { context.lcs_nodes[lcs_pos] = va_array_init(context.allocator, 1, sizeof(*context.lcs_nodes[lcs_pos])); } // if - va_array_append(context.allocator, context.lcs_nodes[lcs_pos], ((VA_LCS_Node) {match_row, match_col, length})); + va_array_append(context.allocator, context.lcs_nodes[lcs_pos], ((VA_LCS_Node) {.row = match_row, .col = match_col, .length = length})); } // if return steps; diff --git a/src/main.c b/src/main.c index 3c49500..d4cc10f 100644 --- a/src/main.c +++ b/src/main.c @@ -2,46 +2,166 @@ #include // EXIT_* #include // strlen +#include "../include/alloc.h" // VA_Allocator #include "../include/array.h" // va_array_* #include "../include/edit.h" // va_edit #include "../include/std_alloc.h" // va_std_allocator +#include "../include/variant.h" // VA_Variant + + +typedef struct +{ + size_t node; + VA_Variant variant; +} Edge; + + +typedef struct +{ + size_t row; + size_t col; + size_t length; + Edge* edges; +} Node; + + +typedef struct +{ + Node* nodes; +} Graph; + + +static inline size_t +add_node(VA_Allocator const allocator, Graph* const graph, size_t const row, size_t const col, size_t const length) +{ + va_array_append(allocator, graph->nodes, ((Node) {row, col, length, NULL})); + return va_array_length(graph->nodes); +} // add_node + + +static inline void +add_edge(VA_Allocator const allocator, Graph* const graph, size_t const source, size_t const sink, VA_Variant const variant) +{ + va_array_append(allocator, graph->nodes[source].edges, ((Edge) {sink, variant})); +} // add_edge static void -test_large(void) +to_dot(Graph const* const graph, char const observed[static 1]) { - char const* const restrict reference = "ATTCTATCTTCTGTCTACATAAGATGTCATACTAGAGGGCATATCTGCAATGTATACATATTATCTTTTCCAGCATGCATTCAGTTGTGTTGGAATAATTTATGTACACCTTTATAAACGCTGAGCCTCACAAGAGCCATGTGCCACGTATTGTTTTCTTACTACTTTTTGGGATACCTGGCACGTAATAGACACTCATTGAAAGTTTCCTAATGAATGAAGTACAAAGATAAAACAAGTTATAGACTGATTCTTTTGAGCTGTCAAGGTTGTAAATAGACTTTTGCTCAATCAATTCAAATGGTGGCAGGTAGTGGGGGTAGAGGGATTGGTATGAAAAACATAAGCTTTCAGAACTCCTGTGTTTATTTTTAGAATGTCAACTGCTTGAGTGTTTTTAACTCTGTGGTATCTGAACTATCTTCTCTAACTGCAGGTTGGGCTCAGATCTGTGATAGAACAGTTTCCTGGGAAGCTTGACTTTGTCCTTGTGGATGGGGGCTGTGTCCTAAGCCATGGCCACAAGCAGTTGATGTGCTTGGCTAGATCTGTTCTCAGTAAGGCGAAGATCTTGCTGCTTGATGAACCCAGTGCTCATTTGGATCCAGTGTGAGTTTCAGATGTTCTGTTACTTAATAGCACAGTGGGAACAGAATCATTATGCCTGCTTCATGGTGACACATATTTCTATTAGGCTGTCATGTCTGCGTGTGGGGGTCTCCCCCAAGATATGAAATAATTGCCCAGTGGAAATGAGCATAAATGCATATTTCCTTGCTAAGAGTCTTGTGTTTTCTTCCGAAGATAGTTTTTAGTTTCATACAAACTCTTCCCCCTTGTCAACACATGATGAAGCTTTTAAATACATGGGCCTAATCTGATCCTTATGATTTGCCTTTGTATCCCATTTATACCATAAGCATGTTTATAGCCCCAAATAAAGAAGTACTGGTGATTCTACATAATGAAAAATGTACTCATTTATTAAAGTTTCTTTGAAATATTTGTCCTGTTTATTTATGGATACTTAGAGTCTACCCCATGGTTGAAAAGCTGATTGTGGCTAACGCTATATCAACATTATGTGAAAAGAACTTAAAGAAATAAGTAATTTAAAGAGATAATAGAACAATAGACATATTATCAAGGTAAATACAGATCATTACTGTTCTGTGATATTATGTGTGGTATTTTCTTTCTTTTCTAGAACATACCAAATAATTAGAAGAACTCTAAAACAAGCATTTGCTGATTGCACAGTAATTCTCTGTGAACACAGGATAGAAGCAATGCTGGAATGCCAACAATTTTTGGTGAGTCTTTATAACTTTACTTAAGATCTCATTGCCCTTGTAATTCTTGATAACAATCTCACATGTGATAGTTCCTGCAAATTGCAACAATGTACAAGTTCTTTTCAAAAATATGTATCATACAGCCATCCAGCTTTACTCAAAATAGCTGCACAAGTTTTTCACTTTGATCTGAGCCATGTGGTGAGGTTGAAATATAGTAAATCTAAAATGGCAGCATATTACTAAGTTATGTTTATAAATAGGATATATATACTTTTTGAGCCCTTTATTTGGGGACCAAGTCATACAAAATACTCTACTGTTTAAGATTTTAAAAAAGGTCCCTGTGATTCTTTCAATAACTAAATGTCCCATGGATGTGGTCTGGGACAGGCCTAGTTGTCTTACAGTCTGATTTATGGTATTAATGACAAAGTTGAGAGGCACATTTCATTTTT"; - char const* const restrict observed = "ATTCTATCTTCTGTCTACATAAGATGTCATACTAGAGGGCATATCTGCAATGTATACATATTATCTTTTCCAGCATGCATTCAGTTGTGTTGGAATAATTTATGTACACCTTTATAAACGCTGAGCCTCACAAGAGCCATGTGCCACGTATTGTTTTCTTACTACTTTTTGGGATACCTGGCACGTAATAGACACTCATTGAAAGTTTCCTAATGAATGAAGTACAAAGATAAAACAAGTTATAGACTGATTCTTTTGAGCTGTCAAGGTTGTAAATAGACTTTTGCTCAATCAATTCAAATGGTGGCAGGTAGTGGGGGTAGAGGGATTGGTATGAAAAACATAAGCTTTCAGAACTCCTGTGTTTATTTTTAGAATGTCAACTGCTTGAGTGTTTTTAACTCTGTGGTATCTGAACTATCTTCTCTAACTGCAGGTGAGTCTTTATAACTTTACTTAAGATCTCATTGCCCTTGTAATTCTTGATAACAATCTCACATGTGATAGTTCCTGCAAATTGCAACAATGTACAAGTTCTTTTCAAAAATATGTATCATACAGCCATCCAGCTTTACTCAAAATAGCTGCACAAGTTTTTCACTTTGATCTGAGCCATGTGGTGAGGTTGAAATATAGTAAATCTAAAATGGCAGCATATTACTAAGTTATGTTTATAAATAGGATATATATACTTTTTGAGCCCTTTATTTGGGGACCAAGTCATACAAAATACTCTACTGTTTAAGATTTTAAAAAAGGTCCCTGTGATTCTTTCAATAACTAAATGTCCCATGGATGTGGTCTGGGACAGGCCTAGTTGTCTTACAGTCTGATTTATGGTATTAATGACAAAGTTGAGAGGCACATTTCATTTTT"; - size_t const len_ref = strlen(reference); - size_t const len_obs = strlen(observed); + if (graph->nodes == NULL) + { + return; + } // if + for (size_t i = 0; i < va_array_length(graph->nodes); ++i) + { + printf("s%zu[label=\"(%zu, %zu, %zu)\"]\n", i, graph->nodes[i].row, graph->nodes[i].col, graph->nodes[i].length); + } // for - VA_LCS_Node** lcs_nodes = NULL; - size_t const len_lcs = va_edit(va_std_allocator, len_ref, reference, len_obs, observed, &lcs_nodes); - if (lcs_nodes == NULL) + for (size_t i = 0; i < va_array_length(graph->nodes); ++i) + { + for (size_t j = 0; j < va_array_length(graph->nodes[i].edges); ++j) + { + size_t const len = graph->nodes[i].edges[j].variant.obs_end - graph->nodes[i].edges[j].variant.obs_start; + printf("s%zu->s%zu[label=\"%u:%u/%.*s\"]\n", i, graph->nodes[i].edges[j].node, graph->nodes[i].edges[j].variant.start, graph->nodes[i].edges[j].variant.end, (int) len, observed + graph->nodes[i].edges[j].variant.obs_start); + } // for + } // for +} // to_dot + + +static void +destroy(VA_Allocator const allocator, Graph* const graph) +{ + if (graph->nodes == NULL) { - printf("OOM\n"); return; } // if - printf("len lcs: %zu\n", len_lcs); + for (size_t i = 0; i < va_array_length(graph->nodes); ++i) + { + graph->nodes[i].edges = va_array_destroy(allocator, graph->nodes[i].edges); + } // for + graph->nodes = va_array_destroy(allocator, graph->nodes); +} // destroy + + +static void +doit(VA_Allocator const allocator, Graph* const graph, VA_LCS_Node const sink, VA_LCS_Node* const sources, size_t const shift) +{ + for (size_t i = 0; i < va_array_length(sources); ++i) + { + if (sources[i].row + sources[i].length < sink.row + sink.length && sources[i].col + sources[i].length < sink.col + sink.length) + { + VA_Variant const variant = {sources[i].row + sources[i].length, sink.row + sink.length - 1, sources[i].col + sources[i].length - shift, sink.col + sink.length - 1 - shift}; + printf("(%zu, %zu, %zu) -> (%zu, %zu, %zu)\n", sources[i].row, sources[i].col, sources[i].length, sink.row, sink.col, sink.length); + + if (sources[i].idx == 0) + { + sources[i].idx = add_node(allocator, graph, sources[i].row, sources[i].col, sources[i].length); + } // if + + add_edge(allocator, graph, sources[i].idx - 1, sink.idx - 1, variant); + + } // if + } // for +} // doit + + +static Graph +build_graph(VA_Allocator const allocator, + size_t const len_ref, char const reference[static len_ref], + size_t const len_obs, char const observed[static len_obs], + size_t const len_lcs, VA_LCS_Node* lcs_nodes[static len_lcs], + size_t const shift) +{ + (void) reference; + (void) observed; + + Graph graph = {NULL}; + + if (len_lcs == 0 || lcs_nodes == NULL) + { + return graph; // FIXME: create default graph + } // if + + printf("%zu\n", len_lcs); + + VA_LCS_Node sink = lcs_nodes[len_lcs - 1][va_array_length(lcs_nodes[len_lcs - 1]) - 1]; + if (sink.row + sink.length == len_ref + shift && sink.col + sink.length == len_obs + shift) + { + va_array_header(lcs_nodes[len_lcs - 1])->length -= 1; // del + sink.length += 1; + } // if + else + { + sink = (VA_LCS_Node) {.row = len_ref + shift, .col = len_obs + shift, .length = 1}; + } // else + + printf("sink: (%zu, %zu, %zu)\n", sink.row, sink.col, sink.length); + + sink.idx = add_node(allocator, &graph, sink.row, sink.col, sink.length - 1); + doit(allocator, &graph, sink, lcs_nodes[len_lcs - 1], shift); + for (size_t i = 0; i < len_lcs; ++i) { - printf(" %zu (%zu): ", i, va_array_length(lcs_nodes[i])); - for (size_t j = 0; j < va_array_length(lcs_nodes[i]); ++j) + size_t const idx = len_lcs - 1 - i; + printf("%zu (%zu): ", idx, va_array_length(lcs_nodes[idx])); + for (size_t j = 0; j < va_array_length(lcs_nodes[idx]); ++j) { - printf("(%zu, %zu, %zu) ", lcs_nodes[i][j].row, lcs_nodes[i][j].col, lcs_nodes[i][j].length); + printf("(%zu, %zu, %zu) ", lcs_nodes[idx][j].row, lcs_nodes[idx][j].col, lcs_nodes[idx][j].length); } // for printf("\n"); - lcs_nodes[i] = va_array_destroy(va_std_allocator, lcs_nodes[i]); + lcs_nodes[idx] = va_array_destroy(allocator, lcs_nodes[idx]); } // for - lcs_nodes = va_std_allocator.alloc(va_std_allocator.context, lcs_nodes, len_lcs * sizeof(*lcs_nodes), 0); -} // test_large + + lcs_nodes = allocator.alloc(allocator.context, lcs_nodes, len_lcs * sizeof(*lcs_nodes), 0); + + return graph; +} // build_graph int main(int argc, char* argv[static argc + 1]) { - test_large(); - if (argc < 3) { fprintf(stderr, "usage: %s reference observed\n", argv[0]); @@ -53,18 +173,11 @@ main(int argc, char* argv[static argc + 1]) VA_LCS_Node** lcs_nodes = NULL; size_t const len_lcs = va_edit(va_std_allocator, m, argv[1], n, argv[2], &lcs_nodes); - printf("len lcs: %zu\n", len_lcs); - for (size_t i = 0; i < len_lcs; ++i) - { - printf(" %zu (%zu): ", i, va_array_length(lcs_nodes[i])); - for (size_t j = 0; j < va_array_length(lcs_nodes[i]); ++j) - { - printf("(%zu, %zu, %zu) ", lcs_nodes[i][j].row, lcs_nodes[i][j].col, lcs_nodes[i][j].length); - } // for - printf("\n"); - lcs_nodes[i] = va_array_destroy(va_std_allocator, lcs_nodes[i]); - } // for - lcs_nodes = va_std_allocator.alloc(va_std_allocator.context, lcs_nodes, len_lcs * sizeof(*lcs_nodes), 0); + Graph graph = build_graph(va_std_allocator, m, argv[1], n, argv[2], len_lcs, lcs_nodes, 0); + + to_dot(&graph, argv[2]); + + destroy(va_std_allocator, &graph); return EXIT_SUCCESS; } // main From 2022029768d2bc0f713d83bd946080d96a7e7471 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 13 Jun 2024 16:04:27 +0200 Subject: [PATCH 058/704] WIP: build_graph --- src/main.c | 71 ++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 56 insertions(+), 15 deletions(-) diff --git a/src/main.c b/src/main.c index d4cc10f..a3a4abc 100644 --- a/src/main.c +++ b/src/main.c @@ -84,9 +84,10 @@ destroy(VA_Allocator const allocator, Graph* const graph) } // destroy -static void -doit(VA_Allocator const allocator, Graph* const graph, VA_LCS_Node const sink, VA_LCS_Node* const sources, size_t const shift) +static size_t +doit(VA_Allocator const allocator, Graph* const graph, VA_LCS_Node const sink, VA_LCS_Node* const sources, size_t const lcs_idx, size_t const shift) { + size_t idx = 0; for (size_t i = 0; i < va_array_length(sources); ++i) { if (sources[i].row + sources[i].length < sink.row + sink.length && sources[i].col + sources[i].length < sink.col + sink.length) @@ -94,15 +95,35 @@ doit(VA_Allocator const allocator, Graph* const graph, VA_LCS_Node const sink, V VA_Variant const variant = {sources[i].row + sources[i].length, sink.row + sink.length - 1, sources[i].col + sources[i].length - shift, sink.col + sink.length - 1 - shift}; printf("(%zu, %zu, %zu) -> (%zu, %zu, %zu)\n", sources[i].row, sources[i].col, sources[i].length, sink.row, sink.col, sink.length); - if (sources[i].idx == 0) + if (sources[i].incoming == lcs_idx) { - sources[i].idx = add_node(allocator, graph, sources[i].row, sources[i].col, sources[i].length); + printf("SPLIT: (%zu, %zu, %zu)\n", sources[i].row, sources[i].col, sources[i].length); + size_t const split_idx = sources[i].idx - 1; + sources[i].idx = add_node(allocator, graph, sources[i].row, sources[i].col, graph->nodes[split_idx].length); + + graph->nodes[sources[i].idx - 1].edges = va_array_init(allocator, va_array_length(graph->nodes[split_idx].edges) + 1, sizeof(*graph->nodes[sources[i].idx].edges)); + for (size_t j = 0; j < va_array_length(graph->nodes[split_idx].edges); ++j) + { + va_array_append(allocator, graph->nodes[sources[i].idx - 1].edges, graph->nodes[split_idx].edges[j]); + } // for + add_edge(allocator, graph, sources[i].idx - 1, sink.idx - 1, variant); + + graph->nodes[split_idx].row += sources[i].length; + graph->nodes[split_idx].col += sources[i].length; + graph->nodes[split_idx].length -= sources[i].length; } // if - - add_edge(allocator, graph, sources[i].idx - 1, sink.idx - 1, variant); - + else + { + if (sources[i].idx == 0) + { + sources[i].idx = add_node(allocator, graph, sources[i].row, sources[i].col, sources[i].length); + } // if + add_edge(allocator, graph, sources[i].idx - 1, sink.idx - 1, variant); + } // else + idx = i + 1; } // if } // for + return idx; } // doit @@ -139,20 +160,40 @@ build_graph(VA_Allocator const allocator, printf("sink: (%zu, %zu, %zu)\n", sink.row, sink.col, sink.length); sink.idx = add_node(allocator, &graph, sink.row, sink.col, sink.length - 1); - doit(allocator, &graph, sink, lcs_nodes[len_lcs - 1], shift); + size_t const here = doit(allocator, &graph, sink, lcs_nodes[len_lcs - 1], len_lcs - 1, shift); + if (sink.length > 1) + { + sink.length -= 1; + sink.incoming = len_lcs - 1; + va_array_insert(allocator, lcs_nodes[len_lcs - 1], sink, here); + } // if - for (size_t i = 0; i < len_lcs; ++i) + for (size_t i = len_lcs - 1; i >= 1; --i) { - size_t const idx = len_lcs - 1 - i; - printf("%zu (%zu): ", idx, va_array_length(lcs_nodes[idx])); - for (size_t j = 0; j < va_array_length(lcs_nodes[idx]); ++j) + printf("idx %zu\n", i); + for (size_t j = 0; j < va_array_length(lcs_nodes[i]); ++j) { - printf("(%zu, %zu, %zu) ", lcs_nodes[idx][j].row, lcs_nodes[idx][j].col, lcs_nodes[idx][j].length); + if (lcs_nodes[i][j].idx == 0) + { + continue; + } // if + size_t const here = doit(allocator, &graph, lcs_nodes[i][j], lcs_nodes[i - 1], i, shift); + if (lcs_nodes[i][j].length > 1) + { + lcs_nodes[i][j].length -= 1; + if (here > 0) + { + lcs_nodes[i][j].incoming = i; + } // if + va_array_insert(allocator, lcs_nodes[i - 1], lcs_nodes[i][j], here); + } // if } // for - printf("\n"); - lcs_nodes[idx] = va_array_destroy(allocator, lcs_nodes[idx]); + lcs_nodes[i] = va_array_destroy(allocator, lcs_nodes[i]); } // for + lcs_nodes[0] = va_array_destroy(allocator, lcs_nodes[0]); + + lcs_nodes = allocator.alloc(allocator.context, lcs_nodes, len_lcs * sizeof(*lcs_nodes), 0); return graph; From 0f88fffe247b868f3d9b1486943c972a9c227c9f Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 13 Jun 2024 17:31:22 +0200 Subject: [PATCH 059/704] WIP: build_graph and to_dot --- src/main.c | 42 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/src/main.c b/src/main.c index a3a4abc..4a720bf 100644 --- a/src/main.c +++ b/src/main.c @@ -49,13 +49,22 @@ add_edge(VA_Allocator const allocator, Graph* const graph, size_t const source, static void to_dot(Graph const* const graph, char const observed[static 1]) { + printf("digraph{\nrankdir=LR\nedge[fontname=monospace]\nnode[fixedsize=true,fontname=serif,shape=circle,width=1]\nsi[shape=point,width=.1]\n"); if (graph->nodes == NULL) { + printf("}\n"); return; } // if for (size_t i = 0; i < va_array_length(graph->nodes); ++i) { - printf("s%zu[label=\"(%zu, %zu, %zu)\"]\n", i, graph->nodes[i].row, graph->nodes[i].col, graph->nodes[i].length); + if (va_array_length(graph->nodes[i].edges) == 0) + { + printf("s%zu[label=\"(%zu, %zu, %zu)\",peripheries=2]\n", i, graph->nodes[i].row, graph->nodes[i].col, graph->nodes[i].length); + } // if + else + { + printf("s%zu[label=\"(%zu, %zu, %zu)\"]\n", i, graph->nodes[i].row, graph->nodes[i].col, graph->nodes[i].length); + } // else } // for for (size_t i = 0; i < va_array_length(graph->nodes); ++i) @@ -66,6 +75,7 @@ to_dot(Graph const* const graph, char const observed[static 1]) printf("s%zu->s%zu[label=\"%u:%u/%.*s\"]\n", i, graph->nodes[i].edges[j].node, graph->nodes[i].edges[j].variant.start, graph->nodes[i].edges[j].variant.end, (int) len, observed + graph->nodes[i].edges[j].variant.obs_start); } // for } // for + printf("}\n"); } // to_dot @@ -191,8 +201,36 @@ build_graph(VA_Allocator const allocator, lcs_nodes[i] = va_array_destroy(allocator, lcs_nodes[i]); } // for - lcs_nodes[0] = va_array_destroy(allocator, lcs_nodes[0]); + VA_LCS_Node source = lcs_nodes[0][0]; + + printf("source: (%zu, %zu, %zu)\n", source.row, source.col, source.length); + size_t start = 0; + if (source.row == shift && source.col == shift) + { + // assert source.idx != 0 + start = 1; + } // if + else + { + source = (VA_LCS_Node) {.row = shift, .col = shift, .length = 0}; + source.idx = add_node(allocator, &graph, shift, shift, 0); + } // else + + for (size_t i = start; i < va_array_length(lcs_nodes[0]); ++i) + { + if (lcs_nodes[0][i].idx == 0) + { + continue; + } // if + if (source.row < lcs_nodes[0][i].row + lcs_nodes[0][i].length && source.col < lcs_nodes[0][i].col + lcs_nodes[0][i].length) + { + VA_Variant const variant = {source.row, lcs_nodes[0][i].row + lcs_nodes[0][i].length - 1, source.col - shift, lcs_nodes[0][i].col + lcs_nodes[0][i].length - 1 - shift}; + printf("(%zu, %zu, %zu) -> (%zu, %zu, %zu)\n", source.row, source.col, source.length, lcs_nodes[0][i].row, lcs_nodes[0][i].col, lcs_nodes[0][i].length); + add_edge(allocator, &graph, source.idx - 1, lcs_nodes[0][i].idx - 1, variant); + } // if + } // for + lcs_nodes[0] = va_array_destroy(allocator, lcs_nodes[0]); lcs_nodes = allocator.alloc(allocator.context, lcs_nodes, len_lcs * sizeof(*lcs_nodes), 0); From 580a83a88f54f652a8670a66e2c57ba831a9f267 Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 14 Jun 2024 13:03:32 +0200 Subject: [PATCH 060/704] Smaller integers --- include/edit.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/include/edit.h b/include/edit.h index 1812224..e7c09eb 100644 --- a/include/edit.h +++ b/include/edit.h @@ -7,17 +7,18 @@ extern "C" #endif #include // size_t +#include // uint32_t #include "alloc.h" // VA_Allocator typedef struct { - size_t row; - size_t col; - size_t length; - size_t incoming; - size_t idx; + uint32_t row; + uint32_t col; + uint32_t length; + uint32_t incoming; + uint32_t idx; } VA_LCS_Node; From dab426abb4f28941eef6615ad7eb55cbbc23a1c9 Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 14 Jun 2024 13:04:46 +0200 Subject: [PATCH 061/704] WIP: embedded edges are problematic --- src/main.c | 61 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 38 insertions(+), 23 deletions(-) diff --git a/src/main.c b/src/main.c index 4a720bf..9eca14a 100644 --- a/src/main.c +++ b/src/main.c @@ -1,3 +1,5 @@ +#include // NULL, size_t +#include // uint32_t #include // stderr, fprintf, printf #include // EXIT_* #include // strlen @@ -11,16 +13,16 @@ typedef struct { - size_t node; + uint32_t node; VA_Variant variant; } Edge; typedef struct { - size_t row; - size_t col; - size_t length; + uint32_t row; + uint32_t col; + uint32_t length; Edge* edges; } Node; @@ -47,7 +49,7 @@ add_edge(VA_Allocator const allocator, Graph* const graph, size_t const source, static void -to_dot(Graph const* const graph, char const observed[static 1]) +to_dot(Graph const* const graph, size_t const len_obs, char const observed[static len_obs]) { printf("digraph{\nrankdir=LR\nedge[fontname=monospace]\nnode[fixedsize=true,fontname=serif,shape=circle,width=1]\nsi[shape=point,width=.1]\n"); if (graph->nodes == NULL) @@ -59,11 +61,11 @@ to_dot(Graph const* const graph, char const observed[static 1]) { if (va_array_length(graph->nodes[i].edges) == 0) { - printf("s%zu[label=\"(%zu, %zu, %zu)\",peripheries=2]\n", i, graph->nodes[i].row, graph->nodes[i].col, graph->nodes[i].length); + printf("s%zu[label=\"(%u, %u, %u)\",peripheries=2]\n", i, graph->nodes[i].row, graph->nodes[i].col, graph->nodes[i].length); } // if else { - printf("s%zu[label=\"(%zu, %zu, %zu)\"]\n", i, graph->nodes[i].row, graph->nodes[i].col, graph->nodes[i].length); + printf("s%zu[label=\"(%u, %u, %u)\"]\n", i, graph->nodes[i].row, graph->nodes[i].col, graph->nodes[i].length); } // else } // for @@ -72,7 +74,7 @@ to_dot(Graph const* const graph, char const observed[static 1]) for (size_t j = 0; j < va_array_length(graph->nodes[i].edges); ++j) { size_t const len = graph->nodes[i].edges[j].variant.obs_end - graph->nodes[i].edges[j].variant.obs_start; - printf("s%zu->s%zu[label=\"%u:%u/%.*s\"]\n", i, graph->nodes[i].edges[j].node, graph->nodes[i].edges[j].variant.start, graph->nodes[i].edges[j].variant.end, (int) len, observed + graph->nodes[i].edges[j].variant.obs_start); + printf("s%zu->s%u[label=\"%u:%u/%.*s\"]\n", i, graph->nodes[i].edges[j].node, graph->nodes[i].edges[j].variant.start, graph->nodes[i].edges[j].variant.end, (int) len, observed + graph->nodes[i].edges[j].variant.obs_start); } // for } // for printf("}\n"); @@ -103,20 +105,22 @@ doit(VA_Allocator const allocator, Graph* const graph, VA_LCS_Node const sink, V if (sources[i].row + sources[i].length < sink.row + sink.length && sources[i].col + sources[i].length < sink.col + sink.length) { VA_Variant const variant = {sources[i].row + sources[i].length, sink.row + sink.length - 1, sources[i].col + sources[i].length - shift, sink.col + sink.length - 1 - shift}; - printf("(%zu, %zu, %zu) -> (%zu, %zu, %zu)\n", sources[i].row, sources[i].col, sources[i].length, sink.row, sink.col, sink.length); + //printf("(%u, %u, %u) -> (%u, %u, %u)\n", sources[i].row, sources[i].col, sources[i].length, sink.row, sink.col, sink.length); if (sources[i].incoming == lcs_idx) { - printf("SPLIT: (%zu, %zu, %zu)\n", sources[i].row, sources[i].col, sources[i].length); + //printf("SPLIT: (%u, %u, %u)\n", sources[i].row, sources[i].col, sources[i].length); size_t const split_idx = sources[i].idx - 1; sources[i].idx = add_node(allocator, graph, sources[i].row, sources[i].col, graph->nodes[split_idx].length); + /* graph->nodes[sources[i].idx - 1].edges = va_array_init(allocator, va_array_length(graph->nodes[split_idx].edges) + 1, sizeof(*graph->nodes[sources[i].idx].edges)); for (size_t j = 0; j < va_array_length(graph->nodes[split_idx].edges); ++j) { va_array_append(allocator, graph->nodes[sources[i].idx - 1].edges, graph->nodes[split_idx].edges[j]); } // for add_edge(allocator, graph, sources[i].idx - 1, sink.idx - 1, variant); + */ graph->nodes[split_idx].row += sources[i].length; graph->nodes[split_idx].col += sources[i].length; @@ -128,7 +132,7 @@ doit(VA_Allocator const allocator, Graph* const graph, VA_LCS_Node const sink, V { sources[i].idx = add_node(allocator, graph, sources[i].row, sources[i].col, sources[i].length); } // if - add_edge(allocator, graph, sources[i].idx - 1, sink.idx - 1, variant); + //add_edge(allocator, graph, sources[i].idx - 1, sink.idx - 1, variant); } // else idx = i + 1; } // if @@ -154,7 +158,7 @@ build_graph(VA_Allocator const allocator, return graph; // FIXME: create default graph } // if - printf("%zu\n", len_lcs); + //printf("%zu\n", len_lcs); VA_LCS_Node sink = lcs_nodes[len_lcs - 1][va_array_length(lcs_nodes[len_lcs - 1]) - 1]; if (sink.row + sink.length == len_ref + shift && sink.col + sink.length == len_obs + shift) @@ -167,7 +171,7 @@ build_graph(VA_Allocator const allocator, sink = (VA_LCS_Node) {.row = len_ref + shift, .col = len_obs + shift, .length = 1}; } // else - printf("sink: (%zu, %zu, %zu)\n", sink.row, sink.col, sink.length); + //printf("sink: (%u, %u, %u)\n", sink.row, sink.col, sink.length); sink.idx = add_node(allocator, &graph, sink.row, sink.col, sink.length - 1); size_t const here = doit(allocator, &graph, sink, lcs_nodes[len_lcs - 1], len_lcs - 1, shift); @@ -180,7 +184,7 @@ build_graph(VA_Allocator const allocator, for (size_t i = len_lcs - 1; i >= 1; --i) { - printf("idx %zu\n", i); + //printf("idx %zu\n", i); for (size_t j = 0; j < va_array_length(lcs_nodes[i]); ++j) { if (lcs_nodes[i][j].idx == 0) @@ -203,7 +207,7 @@ build_graph(VA_Allocator const allocator, VA_LCS_Node source = lcs_nodes[0][0]; - printf("source: (%zu, %zu, %zu)\n", source.row, source.col, source.length); + //printf("source: (%u, %u, %u)\n", source.row, source.col, source.length); size_t start = 0; if (source.row == shift && source.col == shift) { @@ -226,8 +230,8 @@ build_graph(VA_Allocator const allocator, if (source.row < lcs_nodes[0][i].row + lcs_nodes[0][i].length && source.col < lcs_nodes[0][i].col + lcs_nodes[0][i].length) { VA_Variant const variant = {source.row, lcs_nodes[0][i].row + lcs_nodes[0][i].length - 1, source.col - shift, lcs_nodes[0][i].col + lcs_nodes[0][i].length - 1 - shift}; - printf("(%zu, %zu, %zu) -> (%zu, %zu, %zu)\n", source.row, source.col, source.length, lcs_nodes[0][i].row, lcs_nodes[0][i].col, lcs_nodes[0][i].length); - add_edge(allocator, &graph, source.idx - 1, lcs_nodes[0][i].idx - 1, variant); + //printf("(%u, %u, %u) -> (%u, %u, %u)\n", source.row, source.col, source.length, lcs_nodes[0][i].row, lcs_nodes[0][i].col, lcs_nodes[0][i].length); + //add_edge(allocator, &graph, source.idx - 1, lcs_nodes[0][i].idx - 1, variant); } // if } // for lcs_nodes[0] = va_array_destroy(allocator, lcs_nodes[0]); @@ -241,20 +245,31 @@ build_graph(VA_Allocator const allocator, int main(int argc, char* argv[static argc + 1]) { + + (void) argv; + char const* const restrict reference = "ATTCTATCTTCTGTCTACATAAGATGTCATACTAGAGGGCATATCTGCAATGTATACATATTATCTTTTCCAGCATGCATTCAGTTGTGTTGGAATAATTTATGTACACCTTTATAAACGCTGAGCCTCACAAGAGCCATGTGCCACGTATTGTTTTCTTACTACTTTTTGGGATACCTGGCACGTAATAGACACTCATTGAAAGTTTCCTAATGAATGAAGTACAAAGATAAAACAAGTTATAGACTGATTCTTTTGAGCTGTCAAGGTTGTAAATAGACTTTTGCTCAATCAATTCAAATGGTGGCAGGTAGTGGGGGTAGAGGGATTGGTATGAAAAACATAAGCTTTCAGAACTCCTGTGTTTATTTTTAGAATGTCAACTGCTTGAGTGTTTTTAACTCTGTGGTATCTGAACTATCTTCTCTAACTGCAGGTTGGGCTCAGATCTGTGATAGAACAGTTTCCTGGGAAGCTTGACTTTGTCCTTGTGGATGGGGGCTGTGTCCTAAGCCATGGCCACAAGCAGTTGATGTGCTTGGCTAGATCTGTTCTCAGTAAGGCGAAGATCTTGCTGCTTGATGAACCCAGTGCTCATTTGGATCCAGTGTGAGTTTCAGATGTTCTGTTACTTAATAGCACAGTGGGAACAGAATCATTATGCCTGCTTCATGGTGACACATATTTCTATTAGGCTGTCATGTCTGCGTGTGGGGGTCTCCCCCAAGATATGAAATAATTGCCCAGTGGAAATGAGCATAAATGCATATTTCCTTGCTAAGAGTCTTGTGTTTTCTTCCGAAGATAGTTTTTAGTTTCATACAAACTCTTCCCCCTTGTCAACACATGATGAAGCTTTTAAATACATGGGCCTAATCTGATCCTTATGATTTGCCTTTGTATCCCATTTATACCATAAGCATGTTTATAGCCCCAAATAAAGAAGTACTGGTGATTCTACATAATGAAAAATGTACTCATTTATTAAAGTTTCTTTGAAATATTTGTCCTGTTTATTTATGGATACTTAGAGTCTACCCCATGGTTGAAAAGCTGATTGTGGCTAACGCTATATCAACATTATGTGAAAAGAACTTAAAGAAATAAGTAATTTAAAGAGATAATAGAACAATAGACATATTATCAAGGTAAATACAGATCATTACTGTTCTGTGATATTATGTGTGGTATTTTCTTTCTTTTCTAGAACATACCAAATAATTAGAAGAACTCTAAAACAAGCATTTGCTGATTGCACAGTAATTCTCTGTGAACACAGGATAGAAGCAATGCTGGAATGCCAACAATTTTTGGTGAGTCTTTATAACTTTACTTAAGATCTCATTGCCCTTGTAATTCTTGATAACAATCTCACATGTGATAGTTCCTGCAAATTGCAACAATGTACAAGTTCTTTTCAAAAATATGTATCATACAGCCATCCAGCTTTACTCAAAATAGCTGCACAAGTTTTTCACTTTGATCTGAGCCATGTGGTGAGGTTGAAATATAGTAAATCTAAAATGGCAGCATATTACTAAGTTATGTTTATAAATAGGATATATATACTTTTTGAGCCCTTTATTTGGGGACCAAGTCATACAAAATACTCTACTGTTTAAGATTTTAAAAAAGGTCCCTGTGATTCTTTCAATAACTAAATGTCCCATGGATGTGGTCTGGGACAGGCCTAGTTGTCTTACAGTCTGATTTATGGTATTAATGACAAAGTTGAGAGGCACATTTCATTTTT"; + char const* const restrict observed = "ATTCTATCTTCTGTCTACATAAGATGTCATACTAGAGGGCATATCTGCAATGTATACATATTATCTTTTCCAGCATGCATTCAGTTGTGTTGGAATAATTTATGTACACCTTTATAAACGCTGAGCCTCACAAGAGCCATGTGCCACGTATTGTTTTCTTACTACTTTTTGGGATACCTGGCACGTAATAGACACTCATTGAAAGTTTCCTAATGAATGAAGTACAAAGATAAAACAAGTTATAGACTGATTCTTTTGAGCTGTCAAGGTTGTAAATAGACTTTTGCTCAATCAATTCAAATGGTGGCAGGTAGTGGGGGTAGAGGGATTGGTATGAAAAACATAAGCTTTCAGAACTCCTGTGTTTATTTTTAGAATGTCAACTGCTTGAGTGTTTTTAACTCTGTGGTATCTGAACTATCTTCTCTAACTGCAGGTGAGTCTTTATAACTTTACTTAAGATCTCATTGCCCTTGTAATTCTTGATAACAATCTCACATGTGATAGTTCCTGCAAATTGCAACAATGTACAAGTTCTTTTCAAAAATATGTATCATACAGCCATCCAGCTTTACTCAAAATAGCTGCACAAGTTTTTCACTTTGATCTGAGCCATGTGGTGAGGTTGAAATATAGTAAATCTAAAATGGCAGCATATTACTAAGTTATGTTTATAAATAGGATATATATACTTTTTGAGCCCTTTATTTGGGGACCAAGTCATACAAAATACTCTACTGTTTAAGATTTTAAAAAAGGTCCCTGTGATTCTTTCAATAACTAAATGTCCCATGGATGTGGTCTGGGACAGGCCTAGTTGTCTTACAGTCTGATTTATGGTATTAATGACAAAGTTGAGAGGCACATTTCATTTTT"; +/* + + if (argc < 3) { fprintf(stderr, "usage: %s reference observed\n", argv[0]); return EXIT_FAILURE; } // if - - size_t const m = strlen(argv[1]); - size_t const n = strlen(argv[2]); + char const* const restrict reference = argv[1]; + char const* const restrict observed = argv[2]; +*/ + size_t const len_ref = strlen(reference); + size_t const len_obs = strlen(observed); VA_LCS_Node** lcs_nodes = NULL; - size_t const len_lcs = va_edit(va_std_allocator, m, argv[1], n, argv[2], &lcs_nodes); - Graph graph = build_graph(va_std_allocator, m, argv[1], n, argv[2], len_lcs, lcs_nodes, 0); + size_t const len_lcs = va_edit(va_std_allocator, len_ref, reference, len_obs, observed, &lcs_nodes); + printf("%zu\n", len_lcs); + + Graph graph = build_graph(va_std_allocator, len_ref, reference, len_obs, observed, len_lcs, lcs_nodes, 0); - to_dot(&graph, argv[2]); + to_dot(&graph, len_obs, observed); destroy(va_std_allocator, &graph); From c3d769d9d2cd972e6a97458285475e663ce967b3 Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 14 Jun 2024 13:41:24 +0200 Subject: [PATCH 062/704] WIP: flat edges are also problematic --- src/main.c | 56 ++++++++++++++++++++---------------------------------- 1 file changed, 21 insertions(+), 35 deletions(-) diff --git a/src/main.c b/src/main.c index 9eca14a..8359086 100644 --- a/src/main.c +++ b/src/main.c @@ -13,7 +13,8 @@ typedef struct { - uint32_t node; + uint32_t source; + uint32_t sink; VA_Variant variant; } Edge; @@ -23,28 +24,29 @@ typedef struct uint32_t row; uint32_t col; uint32_t length; - Edge* edges; } Node; typedef struct { Node* nodes; + Edge* edges; } Graph; static inline size_t add_node(VA_Allocator const allocator, Graph* const graph, size_t const row, size_t const col, size_t const length) { - va_array_append(allocator, graph->nodes, ((Node) {row, col, length, NULL})); + va_array_append(allocator, graph->nodes, ((Node) {row, col, length})); return va_array_length(graph->nodes); } // add_node -static inline void +static inline size_t add_edge(VA_Allocator const allocator, Graph* const graph, size_t const source, size_t const sink, VA_Variant const variant) { - va_array_append(allocator, graph->nodes[source].edges, ((Edge) {sink, variant})); + va_array_append(allocator, graph->edges, ((Edge) {source, sink, variant})); + return va_array_length(graph->edges); } // add_edge @@ -59,23 +61,13 @@ to_dot(Graph const* const graph, size_t const len_obs, char const observed[stati } // if for (size_t i = 0; i < va_array_length(graph->nodes); ++i) { - if (va_array_length(graph->nodes[i].edges) == 0) - { - printf("s%zu[label=\"(%u, %u, %u)\",peripheries=2]\n", i, graph->nodes[i].row, graph->nodes[i].col, graph->nodes[i].length); - } // if - else - { - printf("s%zu[label=\"(%u, %u, %u)\"]\n", i, graph->nodes[i].row, graph->nodes[i].col, graph->nodes[i].length); - } // else + printf("s%zu[label=\"(%u, %u, %u)\"]\n", i, graph->nodes[i].row, graph->nodes[i].col, graph->nodes[i].length); } // for - for (size_t i = 0; i < va_array_length(graph->nodes); ++i) + for (size_t i = 0; i < va_array_length(graph->edges); ++i) { - for (size_t j = 0; j < va_array_length(graph->nodes[i].edges); ++j) - { - size_t const len = graph->nodes[i].edges[j].variant.obs_end - graph->nodes[i].edges[j].variant.obs_start; - printf("s%zu->s%u[label=\"%u:%u/%.*s\"]\n", i, graph->nodes[i].edges[j].node, graph->nodes[i].edges[j].variant.start, graph->nodes[i].edges[j].variant.end, (int) len, observed + graph->nodes[i].edges[j].variant.obs_start); - } // for + size_t const len = graph->edges[i].variant.obs_end - graph->edges[i].variant.obs_start; + printf("s%u->s%u[label=\"%u:%u/%.*s\"]\n", graph->edges[i].source, graph->edges[i].sink, graph->edges[i].variant.start, graph->edges[i].variant.end, (int) len, observed + graph->edges[i].variant.obs_start); } // for printf("}\n"); } // to_dot @@ -84,15 +76,8 @@ to_dot(Graph const* const graph, size_t const len_obs, char const observed[stati static void destroy(VA_Allocator const allocator, Graph* const graph) { - if (graph->nodes == NULL) - { - return; - } // if - for (size_t i = 0; i < va_array_length(graph->nodes); ++i) - { - graph->nodes[i].edges = va_array_destroy(allocator, graph->nodes[i].edges); - } // for graph->nodes = va_array_destroy(allocator, graph->nodes); + graph->edges = va_array_destroy(allocator, graph->edges); } // destroy @@ -113,14 +98,14 @@ doit(VA_Allocator const allocator, Graph* const graph, VA_LCS_Node const sink, V size_t const split_idx = sources[i].idx - 1; sources[i].idx = add_node(allocator, graph, sources[i].row, sources[i].col, graph->nodes[split_idx].length); - /* - graph->nodes[sources[i].idx - 1].edges = va_array_init(allocator, va_array_length(graph->nodes[split_idx].edges) + 1, sizeof(*graph->nodes[sources[i].idx].edges)); - for (size_t j = 0; j < va_array_length(graph->nodes[split_idx].edges); ++j) + for (size_t j = 0; j < va_array_length(graph->edges); ++j) { - va_array_append(allocator, graph->nodes[sources[i].idx - 1].edges, graph->nodes[split_idx].edges[j]); + if (graph->edges[j].source == split_idx) + { + add_edge(allocator, graph, sources[i].idx - 1, graph->edges[j].sink, graph->edges[j].variant); + } // if } // for add_edge(allocator, graph, sources[i].idx - 1, sink.idx - 1, variant); - */ graph->nodes[split_idx].row += sources[i].length; graph->nodes[split_idx].col += sources[i].length; @@ -132,7 +117,7 @@ doit(VA_Allocator const allocator, Graph* const graph, VA_LCS_Node const sink, V { sources[i].idx = add_node(allocator, graph, sources[i].row, sources[i].col, sources[i].length); } // if - //add_edge(allocator, graph, sources[i].idx - 1, sink.idx - 1, variant); + add_edge(allocator, graph, sources[i].idx - 1, sink.idx - 1, variant); } // else idx = i + 1; } // if @@ -231,7 +216,7 @@ build_graph(VA_Allocator const allocator, { VA_Variant const variant = {source.row, lcs_nodes[0][i].row + lcs_nodes[0][i].length - 1, source.col - shift, lcs_nodes[0][i].col + lcs_nodes[0][i].length - 1 - shift}; //printf("(%u, %u, %u) -> (%u, %u, %u)\n", source.row, source.col, source.length, lcs_nodes[0][i].row, lcs_nodes[0][i].col, lcs_nodes[0][i].length); - //add_edge(allocator, &graph, source.idx - 1, lcs_nodes[0][i].idx - 1, variant); + add_edge(allocator, &graph, source.idx - 1, lcs_nodes[0][i].idx - 1, variant); } // if } // for lcs_nodes[0] = va_array_destroy(allocator, lcs_nodes[0]); @@ -246,12 +231,13 @@ int main(int argc, char* argv[static argc + 1]) { + (void) argv; char const* const restrict reference = "ATTCTATCTTCTGTCTACATAAGATGTCATACTAGAGGGCATATCTGCAATGTATACATATTATCTTTTCCAGCATGCATTCAGTTGTGTTGGAATAATTTATGTACACCTTTATAAACGCTGAGCCTCACAAGAGCCATGTGCCACGTATTGTTTTCTTACTACTTTTTGGGATACCTGGCACGTAATAGACACTCATTGAAAGTTTCCTAATGAATGAAGTACAAAGATAAAACAAGTTATAGACTGATTCTTTTGAGCTGTCAAGGTTGTAAATAGACTTTTGCTCAATCAATTCAAATGGTGGCAGGTAGTGGGGGTAGAGGGATTGGTATGAAAAACATAAGCTTTCAGAACTCCTGTGTTTATTTTTAGAATGTCAACTGCTTGAGTGTTTTTAACTCTGTGGTATCTGAACTATCTTCTCTAACTGCAGGTTGGGCTCAGATCTGTGATAGAACAGTTTCCTGGGAAGCTTGACTTTGTCCTTGTGGATGGGGGCTGTGTCCTAAGCCATGGCCACAAGCAGTTGATGTGCTTGGCTAGATCTGTTCTCAGTAAGGCGAAGATCTTGCTGCTTGATGAACCCAGTGCTCATTTGGATCCAGTGTGAGTTTCAGATGTTCTGTTACTTAATAGCACAGTGGGAACAGAATCATTATGCCTGCTTCATGGTGACACATATTTCTATTAGGCTGTCATGTCTGCGTGTGGGGGTCTCCCCCAAGATATGAAATAATTGCCCAGTGGAAATGAGCATAAATGCATATTTCCTTGCTAAGAGTCTTGTGTTTTCTTCCGAAGATAGTTTTTAGTTTCATACAAACTCTTCCCCCTTGTCAACACATGATGAAGCTTTTAAATACATGGGCCTAATCTGATCCTTATGATTTGCCTTTGTATCCCATTTATACCATAAGCATGTTTATAGCCCCAAATAAAGAAGTACTGGTGATTCTACATAATGAAAAATGTACTCATTTATTAAAGTTTCTTTGAAATATTTGTCCTGTTTATTTATGGATACTTAGAGTCTACCCCATGGTTGAAAAGCTGATTGTGGCTAACGCTATATCAACATTATGTGAAAAGAACTTAAAGAAATAAGTAATTTAAAGAGATAATAGAACAATAGACATATTATCAAGGTAAATACAGATCATTACTGTTCTGTGATATTATGTGTGGTATTTTCTTTCTTTTCTAGAACATACCAAATAATTAGAAGAACTCTAAAACAAGCATTTGCTGATTGCACAGTAATTCTCTGTGAACACAGGATAGAAGCAATGCTGGAATGCCAACAATTTTTGGTGAGTCTTTATAACTTTACTTAAGATCTCATTGCCCTTGTAATTCTTGATAACAATCTCACATGTGATAGTTCCTGCAAATTGCAACAATGTACAAGTTCTTTTCAAAAATATGTATCATACAGCCATCCAGCTTTACTCAAAATAGCTGCACAAGTTTTTCACTTTGATCTGAGCCATGTGGTGAGGTTGAAATATAGTAAATCTAAAATGGCAGCATATTACTAAGTTATGTTTATAAATAGGATATATATACTTTTTGAGCCCTTTATTTGGGGACCAAGTCATACAAAATACTCTACTGTTTAAGATTTTAAAAAAGGTCCCTGTGATTCTTTCAATAACTAAATGTCCCATGGATGTGGTCTGGGACAGGCCTAGTTGTCTTACAGTCTGATTTATGGTATTAATGACAAAGTTGAGAGGCACATTTCATTTTT"; char const* const restrict observed = "ATTCTATCTTCTGTCTACATAAGATGTCATACTAGAGGGCATATCTGCAATGTATACATATTATCTTTTCCAGCATGCATTCAGTTGTGTTGGAATAATTTATGTACACCTTTATAAACGCTGAGCCTCACAAGAGCCATGTGCCACGTATTGTTTTCTTACTACTTTTTGGGATACCTGGCACGTAATAGACACTCATTGAAAGTTTCCTAATGAATGAAGTACAAAGATAAAACAAGTTATAGACTGATTCTTTTGAGCTGTCAAGGTTGTAAATAGACTTTTGCTCAATCAATTCAAATGGTGGCAGGTAGTGGGGGTAGAGGGATTGGTATGAAAAACATAAGCTTTCAGAACTCCTGTGTTTATTTTTAGAATGTCAACTGCTTGAGTGTTTTTAACTCTGTGGTATCTGAACTATCTTCTCTAACTGCAGGTGAGTCTTTATAACTTTACTTAAGATCTCATTGCCCTTGTAATTCTTGATAACAATCTCACATGTGATAGTTCCTGCAAATTGCAACAATGTACAAGTTCTTTTCAAAAATATGTATCATACAGCCATCCAGCTTTACTCAAAATAGCTGCACAAGTTTTTCACTTTGATCTGAGCCATGTGGTGAGGTTGAAATATAGTAAATCTAAAATGGCAGCATATTACTAAGTTATGTTTATAAATAGGATATATATACTTTTTGAGCCCTTTATTTGGGGACCAAGTCATACAAAATACTCTACTGTTTAAGATTTTAAAAAAGGTCCCTGTGATTCTTTCAATAACTAAATGTCCCATGGATGTGGTCTGGGACAGGCCTAGTTGTCTTACAGTCTGATTTATGGTATTAATGACAAAGTTGAGAGGCACATTTCATTTTT"; -/* +/* if (argc < 3) { fprintf(stderr, "usage: %s reference observed\n", argv[0]); From ff49e3dca9c67b4c6ef5e07dfedfdd9820338eb6 Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 14 Jun 2024 13:51:03 +0200 Subject: [PATCH 063/704] WIP: lambda-edges for the win --- src/main.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/main.c b/src/main.c index 8359086..e075f1b 100644 --- a/src/main.c +++ b/src/main.c @@ -98,13 +98,8 @@ doit(VA_Allocator const allocator, Graph* const graph, VA_LCS_Node const sink, V size_t const split_idx = sources[i].idx - 1; sources[i].idx = add_node(allocator, graph, sources[i].row, sources[i].col, graph->nodes[split_idx].length); - for (size_t j = 0; j < va_array_length(graph->edges); ++j) - { - if (graph->edges[j].source == split_idx) - { - add_edge(allocator, graph, sources[i].idx - 1, graph->edges[j].sink, graph->edges[j].variant); - } // if - } // for + // lambda-edge + add_edge(allocator, graph, sources[i].idx - 1, split_idx, (VA_Variant) {0, 0, 0, 0}); add_edge(allocator, graph, sources[i].idx - 1, sink.idx - 1, variant); graph->nodes[split_idx].row += sources[i].length; @@ -231,12 +226,10 @@ int main(int argc, char* argv[static argc + 1]) { - (void) argv; char const* const restrict reference = "ATTCTATCTTCTGTCTACATAAGATGTCATACTAGAGGGCATATCTGCAATGTATACATATTATCTTTTCCAGCATGCATTCAGTTGTGTTGGAATAATTTATGTACACCTTTATAAACGCTGAGCCTCACAAGAGCCATGTGCCACGTATTGTTTTCTTACTACTTTTTGGGATACCTGGCACGTAATAGACACTCATTGAAAGTTTCCTAATGAATGAAGTACAAAGATAAAACAAGTTATAGACTGATTCTTTTGAGCTGTCAAGGTTGTAAATAGACTTTTGCTCAATCAATTCAAATGGTGGCAGGTAGTGGGGGTAGAGGGATTGGTATGAAAAACATAAGCTTTCAGAACTCCTGTGTTTATTTTTAGAATGTCAACTGCTTGAGTGTTTTTAACTCTGTGGTATCTGAACTATCTTCTCTAACTGCAGGTTGGGCTCAGATCTGTGATAGAACAGTTTCCTGGGAAGCTTGACTTTGTCCTTGTGGATGGGGGCTGTGTCCTAAGCCATGGCCACAAGCAGTTGATGTGCTTGGCTAGATCTGTTCTCAGTAAGGCGAAGATCTTGCTGCTTGATGAACCCAGTGCTCATTTGGATCCAGTGTGAGTTTCAGATGTTCTGTTACTTAATAGCACAGTGGGAACAGAATCATTATGCCTGCTTCATGGTGACACATATTTCTATTAGGCTGTCATGTCTGCGTGTGGGGGTCTCCCCCAAGATATGAAATAATTGCCCAGTGGAAATGAGCATAAATGCATATTTCCTTGCTAAGAGTCTTGTGTTTTCTTCCGAAGATAGTTTTTAGTTTCATACAAACTCTTCCCCCTTGTCAACACATGATGAAGCTTTTAAATACATGGGCCTAATCTGATCCTTATGATTTGCCTTTGTATCCCATTTATACCATAAGCATGTTTATAGCCCCAAATAAAGAAGTACTGGTGATTCTACATAATGAAAAATGTACTCATTTATTAAAGTTTCTTTGAAATATTTGTCCTGTTTATTTATGGATACTTAGAGTCTACCCCATGGTTGAAAAGCTGATTGTGGCTAACGCTATATCAACATTATGTGAAAAGAACTTAAAGAAATAAGTAATTTAAAGAGATAATAGAACAATAGACATATTATCAAGGTAAATACAGATCATTACTGTTCTGTGATATTATGTGTGGTATTTTCTTTCTTTTCTAGAACATACCAAATAATTAGAAGAACTCTAAAACAAGCATTTGCTGATTGCACAGTAATTCTCTGTGAACACAGGATAGAAGCAATGCTGGAATGCCAACAATTTTTGGTGAGTCTTTATAACTTTACTTAAGATCTCATTGCCCTTGTAATTCTTGATAACAATCTCACATGTGATAGTTCCTGCAAATTGCAACAATGTACAAGTTCTTTTCAAAAATATGTATCATACAGCCATCCAGCTTTACTCAAAATAGCTGCACAAGTTTTTCACTTTGATCTGAGCCATGTGGTGAGGTTGAAATATAGTAAATCTAAAATGGCAGCATATTACTAAGTTATGTTTATAAATAGGATATATATACTTTTTGAGCCCTTTATTTGGGGACCAAGTCATACAAAATACTCTACTGTTTAAGATTTTAAAAAAGGTCCCTGTGATTCTTTCAATAACTAAATGTCCCATGGATGTGGTCTGGGACAGGCCTAGTTGTCTTACAGTCTGATTTATGGTATTAATGACAAAGTTGAGAGGCACATTTCATTTTT"; char const* const restrict observed = "ATTCTATCTTCTGTCTACATAAGATGTCATACTAGAGGGCATATCTGCAATGTATACATATTATCTTTTCCAGCATGCATTCAGTTGTGTTGGAATAATTTATGTACACCTTTATAAACGCTGAGCCTCACAAGAGCCATGTGCCACGTATTGTTTTCTTACTACTTTTTGGGATACCTGGCACGTAATAGACACTCATTGAAAGTTTCCTAATGAATGAAGTACAAAGATAAAACAAGTTATAGACTGATTCTTTTGAGCTGTCAAGGTTGTAAATAGACTTTTGCTCAATCAATTCAAATGGTGGCAGGTAGTGGGGGTAGAGGGATTGGTATGAAAAACATAAGCTTTCAGAACTCCTGTGTTTATTTTTAGAATGTCAACTGCTTGAGTGTTTTTAACTCTGTGGTATCTGAACTATCTTCTCTAACTGCAGGTGAGTCTTTATAACTTTACTTAAGATCTCATTGCCCTTGTAATTCTTGATAACAATCTCACATGTGATAGTTCCTGCAAATTGCAACAATGTACAAGTTCTTTTCAAAAATATGTATCATACAGCCATCCAGCTTTACTCAAAATAGCTGCACAAGTTTTTCACTTTGATCTGAGCCATGTGGTGAGGTTGAAATATAGTAAATCTAAAATGGCAGCATATTACTAAGTTATGTTTATAAATAGGATATATATACTTTTTGAGCCCTTTATTTGGGGACCAAGTCATACAAAATACTCTACTGTTTAAGATTTTAAAAAAGGTCCCTGTGATTCTTTCAATAACTAAATGTCCCATGGATGTGGTCTGGGACAGGCCTAGTTGTCTTACAGTCTGATTTATGGTATTAATGACAAAGTTGAGAGGCACATTTCATTTTT"; - /* if (argc < 3) { From 58c1fa676ea269535659877f8e7940952ae8fdab Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 14 Jun 2024 14:05:58 +0200 Subject: [PATCH 064/704] Pretty to_dot --- src/main.c | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/src/main.c b/src/main.c index e075f1b..7b33c47 100644 --- a/src/main.c +++ b/src/main.c @@ -61,13 +61,29 @@ to_dot(Graph const* const graph, size_t const len_obs, char const observed[stati } // if for (size_t i = 0; i < va_array_length(graph->nodes); ++i) { - printf("s%zu[label=\"(%u, %u, %u)\"]\n", i, graph->nodes[i].row, graph->nodes[i].col, graph->nodes[i].length); + if (i == 0) + { + printf("s%zu[label=\"(%u, %u, %u)\",peripheries=2]\n", i, graph->nodes[i].row, graph->nodes[i].col, graph->nodes[i].length); + } // if + else + { + printf("s%zu[label=\"(%u, %u, %u)\"]\n", i, graph->nodes[i].row, graph->nodes[i].col, graph->nodes[i].length); + } // else } // for + printf("si->s%zu\n", va_array_length(graph->nodes) - 1); + for (size_t i = 0; i < va_array_length(graph->edges); ++i) { - size_t const len = graph->edges[i].variant.obs_end - graph->edges[i].variant.obs_start; - printf("s%u->s%u[label=\"%u:%u/%.*s\"]\n", graph->edges[i].source, graph->edges[i].sink, graph->edges[i].variant.start, graph->edges[i].variant.end, (int) len, observed + graph->edges[i].variant.obs_start); + if (va_variant_len(graph->edges[i].variant) == 0) + { + printf("s%u->s%u[label=\"λ\",style=dashed]\n", graph->edges[i].source, graph->edges[i].sink); + } // if + else + { + size_t const len = graph->edges[i].variant.obs_end - graph->edges[i].variant.obs_start; + printf("s%u->s%u[label=\"%u:%u/%.*s\"]\n", graph->edges[i].source, graph->edges[i].sink, graph->edges[i].variant.start, graph->edges[i].variant.end, (int) len, observed + graph->edges[i].variant.obs_start); + } // else } // for printf("}\n"); } // to_dot @@ -226,11 +242,12 @@ int main(int argc, char* argv[static argc + 1]) { +/* (void) argv; char const* const restrict reference = "ATTCTATCTTCTGTCTACATAAGATGTCATACTAGAGGGCATATCTGCAATGTATACATATTATCTTTTCCAGCATGCATTCAGTTGTGTTGGAATAATTTATGTACACCTTTATAAACGCTGAGCCTCACAAGAGCCATGTGCCACGTATTGTTTTCTTACTACTTTTTGGGATACCTGGCACGTAATAGACACTCATTGAAAGTTTCCTAATGAATGAAGTACAAAGATAAAACAAGTTATAGACTGATTCTTTTGAGCTGTCAAGGTTGTAAATAGACTTTTGCTCAATCAATTCAAATGGTGGCAGGTAGTGGGGGTAGAGGGATTGGTATGAAAAACATAAGCTTTCAGAACTCCTGTGTTTATTTTTAGAATGTCAACTGCTTGAGTGTTTTTAACTCTGTGGTATCTGAACTATCTTCTCTAACTGCAGGTTGGGCTCAGATCTGTGATAGAACAGTTTCCTGGGAAGCTTGACTTTGTCCTTGTGGATGGGGGCTGTGTCCTAAGCCATGGCCACAAGCAGTTGATGTGCTTGGCTAGATCTGTTCTCAGTAAGGCGAAGATCTTGCTGCTTGATGAACCCAGTGCTCATTTGGATCCAGTGTGAGTTTCAGATGTTCTGTTACTTAATAGCACAGTGGGAACAGAATCATTATGCCTGCTTCATGGTGACACATATTTCTATTAGGCTGTCATGTCTGCGTGTGGGGGTCTCCCCCAAGATATGAAATAATTGCCCAGTGGAAATGAGCATAAATGCATATTTCCTTGCTAAGAGTCTTGTGTTTTCTTCCGAAGATAGTTTTTAGTTTCATACAAACTCTTCCCCCTTGTCAACACATGATGAAGCTTTTAAATACATGGGCCTAATCTGATCCTTATGATTTGCCTTTGTATCCCATTTATACCATAAGCATGTTTATAGCCCCAAATAAAGAAGTACTGGTGATTCTACATAATGAAAAATGTACTCATTTATTAAAGTTTCTTTGAAATATTTGTCCTGTTTATTTATGGATACTTAGAGTCTACCCCATGGTTGAAAAGCTGATTGTGGCTAACGCTATATCAACATTATGTGAAAAGAACTTAAAGAAATAAGTAATTTAAAGAGATAATAGAACAATAGACATATTATCAAGGTAAATACAGATCATTACTGTTCTGTGATATTATGTGTGGTATTTTCTTTCTTTTCTAGAACATACCAAATAATTAGAAGAACTCTAAAACAAGCATTTGCTGATTGCACAGTAATTCTCTGTGAACACAGGATAGAAGCAATGCTGGAATGCCAACAATTTTTGGTGAGTCTTTATAACTTTACTTAAGATCTCATTGCCCTTGTAATTCTTGATAACAATCTCACATGTGATAGTTCCTGCAAATTGCAACAATGTACAAGTTCTTTTCAAAAATATGTATCATACAGCCATCCAGCTTTACTCAAAATAGCTGCACAAGTTTTTCACTTTGATCTGAGCCATGTGGTGAGGTTGAAATATAGTAAATCTAAAATGGCAGCATATTACTAAGTTATGTTTATAAATAGGATATATATACTTTTTGAGCCCTTTATTTGGGGACCAAGTCATACAAAATACTCTACTGTTTAAGATTTTAAAAAAGGTCCCTGTGATTCTTTCAATAACTAAATGTCCCATGGATGTGGTCTGGGACAGGCCTAGTTGTCTTACAGTCTGATTTATGGTATTAATGACAAAGTTGAGAGGCACATTTCATTTTT"; char const* const restrict observed = "ATTCTATCTTCTGTCTACATAAGATGTCATACTAGAGGGCATATCTGCAATGTATACATATTATCTTTTCCAGCATGCATTCAGTTGTGTTGGAATAATTTATGTACACCTTTATAAACGCTGAGCCTCACAAGAGCCATGTGCCACGTATTGTTTTCTTACTACTTTTTGGGATACCTGGCACGTAATAGACACTCATTGAAAGTTTCCTAATGAATGAAGTACAAAGATAAAACAAGTTATAGACTGATTCTTTTGAGCTGTCAAGGTTGTAAATAGACTTTTGCTCAATCAATTCAAATGGTGGCAGGTAGTGGGGGTAGAGGGATTGGTATGAAAAACATAAGCTTTCAGAACTCCTGTGTTTATTTTTAGAATGTCAACTGCTTGAGTGTTTTTAACTCTGTGGTATCTGAACTATCTTCTCTAACTGCAGGTGAGTCTTTATAACTTTACTTAAGATCTCATTGCCCTTGTAATTCTTGATAACAATCTCACATGTGATAGTTCCTGCAAATTGCAACAATGTACAAGTTCTTTTCAAAAATATGTATCATACAGCCATCCAGCTTTACTCAAAATAGCTGCACAAGTTTTTCACTTTGATCTGAGCCATGTGGTGAGGTTGAAATATAGTAAATCTAAAATGGCAGCATATTACTAAGTTATGTTTATAAATAGGATATATATACTTTTTGAGCCCTTTATTTGGGGACCAAGTCATACAAAATACTCTACTGTTTAAGATTTTAAAAAAGGTCCCTGTGATTCTTTCAATAACTAAATGTCCCATGGATGTGGTCTGGGACAGGCCTAGTTGTCTTACAGTCTGATTTATGGTATTAATGACAAAGTTGAGAGGCACATTTCATTTTT"; +*/ -/* if (argc < 3) { fprintf(stderr, "usage: %s reference observed\n", argv[0]); @@ -238,7 +255,7 @@ main(int argc, char* argv[static argc + 1]) } // if char const* const restrict reference = argv[1]; char const* const restrict observed = argv[2]; -*/ + size_t const len_ref = strlen(reference); size_t const len_obs = strlen(observed); From 2f8ac0eaff5f0a6214599cfd8c1f443815d9cde3 Mon Sep 17 00:00:00 2001 From: jkvis Date: Sat, 15 Jun 2024 14:22:11 +0200 Subject: [PATCH 065/704] Snapshot large del benchmark --- benchmark.txt | 42 ++++++++++++++++++++++++++++++++++++++++++ include/std_alloc.h | 3 +++ src/edit.c | 14 ++++++++++++-- src/main.c | 19 +++++++++++-------- 4 files changed, 68 insertions(+), 10 deletions(-) create mode 100644 benchmark.txt diff --git a/benchmark.txt b/benchmark.txt new file mode 100644 index 0000000..d48c22e --- /dev/null +++ b/benchmark.txt @@ -0,0 +1,42 @@ +Empty main + +Python +9,768 kB + +C +1,260 kB + + +LCS alignment +len lcs 876 (136 empty) +102641 {row, col, length} @ 12 b = 1,231,692 b + +Python +0:00.33 +32,688 kB + + +C (no pre alloc) +0:00.03 +20,528 kB + +C (256 pre alloc) +0:00.02 +3,276 kB (256 * (876 - 136)) @ 12 b = 2,273,280 b + + +LCS graph +71,858 nodes 8,096,506 edges (19,823 splits) + +Python +0:37.77 +1,792,004 kB + +C (only nodes) +0:00.03 +4,940 kB + +C (flat lamdba edges: 5,894,814) (pre alloc makes no difference) +0:00.13 +142,468 kB + diff --git a/include/std_alloc.h b/include/std_alloc.h index 2412cd0..cea0673 100644 --- a/include/std_alloc.h +++ b/include/std_alloc.h @@ -23,6 +23,7 @@ va_std_alloc(void* const restrict context, void* const restrict ptr, size_t cons } // if (void) context; + (void) old_size; char* const restrict new_ptr = realloc(ptr, size); if (new_ptr == NULL) @@ -30,10 +31,12 @@ va_std_alloc(void* const restrict context, void* const restrict ptr, size_t cons return NULL; // OOM } // if + /* if (size > old_size) { (void) memset(new_ptr + old_size, 0, size - old_size); } // if + */ return new_ptr; } // va_std_alloc diff --git a/src/edit.c b/src/edit.c index 77e4093..0043dd9 100644 --- a/src/edit.c +++ b/src/edit.c @@ -168,7 +168,7 @@ expand(Context const context, size_t const length = row - match_row; if (context.lcs_nodes[lcs_pos] == NULL) { - context.lcs_nodes[lcs_pos] = va_array_init(context.allocator, 1, sizeof(*context.lcs_nodes[lcs_pos])); + context.lcs_nodes[lcs_pos] = va_array_init(context.allocator, 256, sizeof(*context.lcs_nodes[lcs_pos])); } // if va_array_append(context.allocator, context.lcs_nodes[lcs_pos], ((VA_LCS_Node) {.row = match_row, .col = match_col, .length = length})); matching = false; @@ -201,7 +201,7 @@ expand(Context const context, size_t const length = row - match_row; if (context.lcs_nodes[lcs_pos] == NULL) { - context.lcs_nodes[lcs_pos] = va_array_init(context.allocator, 1, sizeof(*context.lcs_nodes[lcs_pos])); + context.lcs_nodes[lcs_pos] = va_array_init(context.allocator, 256, sizeof(*context.lcs_nodes[lcs_pos])); } // if va_array_append(context.allocator, context.lcs_nodes[lcs_pos], ((VA_LCS_Node) {.row = match_row, .col = match_col, .length = length})); } // if @@ -239,6 +239,16 @@ va_edit(VA_Allocator const allocator, return -1; } // if + for (size_t i = 0; i < size; ++i) + { + context.diagonals[i] = 0; + } // for + + for (size_t i = 0; i < umin(len_ref, len_obs); ++i) + { + context.lcs_nodes[i] = NULL; + } // for + size_t const lower = delta > 0 ? 0 : delta; size_t const upper = delta > 0 ? delta : 0; diff --git a/src/main.c b/src/main.c index 7b33c47..a639313 100644 --- a/src/main.c +++ b/src/main.c @@ -113,6 +113,7 @@ doit(VA_Allocator const allocator, Graph* const graph, VA_LCS_Node const sink, V //printf("SPLIT: (%u, %u, %u)\n", sources[i].row, sources[i].col, sources[i].length); size_t const split_idx = sources[i].idx - 1; sources[i].idx = add_node(allocator, graph, sources[i].row, sources[i].col, graph->nodes[split_idx].length); + sources[i].incoming = 0; // lambda-edge add_edge(allocator, graph, sources[i].idx - 1, split_idx, (VA_Variant) {0, 0, 0, 0}); @@ -147,7 +148,10 @@ build_graph(VA_Allocator const allocator, (void) reference; (void) observed; - Graph graph = {NULL}; + Graph graph = { + va_array_init(allocator, 102641, sizeof(*graph.nodes)), + va_array_init(allocator, 5894814, sizeof(*graph.edges)), + }; if (len_lcs == 0 || lcs_nodes == NULL) { @@ -242,12 +246,11 @@ int main(int argc, char* argv[static argc + 1]) { -/* (void) argv; char const* const restrict reference = "ATTCTATCTTCTGTCTACATAAGATGTCATACTAGAGGGCATATCTGCAATGTATACATATTATCTTTTCCAGCATGCATTCAGTTGTGTTGGAATAATTTATGTACACCTTTATAAACGCTGAGCCTCACAAGAGCCATGTGCCACGTATTGTTTTCTTACTACTTTTTGGGATACCTGGCACGTAATAGACACTCATTGAAAGTTTCCTAATGAATGAAGTACAAAGATAAAACAAGTTATAGACTGATTCTTTTGAGCTGTCAAGGTTGTAAATAGACTTTTGCTCAATCAATTCAAATGGTGGCAGGTAGTGGGGGTAGAGGGATTGGTATGAAAAACATAAGCTTTCAGAACTCCTGTGTTTATTTTTAGAATGTCAACTGCTTGAGTGTTTTTAACTCTGTGGTATCTGAACTATCTTCTCTAACTGCAGGTTGGGCTCAGATCTGTGATAGAACAGTTTCCTGGGAAGCTTGACTTTGTCCTTGTGGATGGGGGCTGTGTCCTAAGCCATGGCCACAAGCAGTTGATGTGCTTGGCTAGATCTGTTCTCAGTAAGGCGAAGATCTTGCTGCTTGATGAACCCAGTGCTCATTTGGATCCAGTGTGAGTTTCAGATGTTCTGTTACTTAATAGCACAGTGGGAACAGAATCATTATGCCTGCTTCATGGTGACACATATTTCTATTAGGCTGTCATGTCTGCGTGTGGGGGTCTCCCCCAAGATATGAAATAATTGCCCAGTGGAAATGAGCATAAATGCATATTTCCTTGCTAAGAGTCTTGTGTTTTCTTCCGAAGATAGTTTTTAGTTTCATACAAACTCTTCCCCCTTGTCAACACATGATGAAGCTTTTAAATACATGGGCCTAATCTGATCCTTATGATTTGCCTTTGTATCCCATTTATACCATAAGCATGTTTATAGCCCCAAATAAAGAAGTACTGGTGATTCTACATAATGAAAAATGTACTCATTTATTAAAGTTTCTTTGAAATATTTGTCCTGTTTATTTATGGATACTTAGAGTCTACCCCATGGTTGAAAAGCTGATTGTGGCTAACGCTATATCAACATTATGTGAAAAGAACTTAAAGAAATAAGTAATTTAAAGAGATAATAGAACAATAGACATATTATCAAGGTAAATACAGATCATTACTGTTCTGTGATATTATGTGTGGTATTTTCTTTCTTTTCTAGAACATACCAAATAATTAGAAGAACTCTAAAACAAGCATTTGCTGATTGCACAGTAATTCTCTGTGAACACAGGATAGAAGCAATGCTGGAATGCCAACAATTTTTGGTGAGTCTTTATAACTTTACTTAAGATCTCATTGCCCTTGTAATTCTTGATAACAATCTCACATGTGATAGTTCCTGCAAATTGCAACAATGTACAAGTTCTTTTCAAAAATATGTATCATACAGCCATCCAGCTTTACTCAAAATAGCTGCACAAGTTTTTCACTTTGATCTGAGCCATGTGGTGAGGTTGAAATATAGTAAATCTAAAATGGCAGCATATTACTAAGTTATGTTTATAAATAGGATATATATACTTTTTGAGCCCTTTATTTGGGGACCAAGTCATACAAAATACTCTACTGTTTAAGATTTTAAAAAAGGTCCCTGTGATTCTTTCAATAACTAAATGTCCCATGGATGTGGTCTGGGACAGGCCTAGTTGTCTTACAGTCTGATTTATGGTATTAATGACAAAGTTGAGAGGCACATTTCATTTTT"; char const* const restrict observed = "ATTCTATCTTCTGTCTACATAAGATGTCATACTAGAGGGCATATCTGCAATGTATACATATTATCTTTTCCAGCATGCATTCAGTTGTGTTGGAATAATTTATGTACACCTTTATAAACGCTGAGCCTCACAAGAGCCATGTGCCACGTATTGTTTTCTTACTACTTTTTGGGATACCTGGCACGTAATAGACACTCATTGAAAGTTTCCTAATGAATGAAGTACAAAGATAAAACAAGTTATAGACTGATTCTTTTGAGCTGTCAAGGTTGTAAATAGACTTTTGCTCAATCAATTCAAATGGTGGCAGGTAGTGGGGGTAGAGGGATTGGTATGAAAAACATAAGCTTTCAGAACTCCTGTGTTTATTTTTAGAATGTCAACTGCTTGAGTGTTTTTAACTCTGTGGTATCTGAACTATCTTCTCTAACTGCAGGTGAGTCTTTATAACTTTACTTAAGATCTCATTGCCCTTGTAATTCTTGATAACAATCTCACATGTGATAGTTCCTGCAAATTGCAACAATGTACAAGTTCTTTTCAAAAATATGTATCATACAGCCATCCAGCTTTACTCAAAATAGCTGCACAAGTTTTTCACTTTGATCTGAGCCATGTGGTGAGGTTGAAATATAGTAAATCTAAAATGGCAGCATATTACTAAGTTATGTTTATAAATAGGATATATATACTTTTTGAGCCCTTTATTTGGGGACCAAGTCATACAAAATACTCTACTGTTTAAGATTTTAAAAAAGGTCCCTGTGATTCTTTCAATAACTAAATGTCCCATGGATGTGGTCTGGGACAGGCCTAGTTGTCTTACAGTCTGATTTATGGTATTAATGACAAAGTTGAGAGGCACATTTCATTTTT"; -*/ +/* if (argc < 3) { fprintf(stderr, "usage: %s reference observed\n", argv[0]); @@ -255,18 +258,18 @@ main(int argc, char* argv[static argc + 1]) } // if char const* const restrict reference = argv[1]; char const* const restrict observed = argv[2]; - +*/ size_t const len_ref = strlen(reference); size_t const len_obs = strlen(observed); VA_LCS_Node** lcs_nodes = NULL; size_t const len_lcs = va_edit(va_std_allocator, len_ref, reference, len_obs, observed, &lcs_nodes); - printf("%zu\n", len_lcs); - Graph graph = build_graph(va_std_allocator, len_ref, reference, len_obs, observed, len_lcs, lcs_nodes, 0); - +/* to_dot(&graph, len_obs, observed); - +*/ + printf("%zu\n", va_array_length(graph.nodes)); + printf("%zu\n", va_array_length(graph.edges)); destroy(va_std_allocator, &graph); return EXIT_SUCCESS; From 989a8d60370938e831207dfec799b884fd773545 Mon Sep 17 00:00:00 2001 From: jkvis Date: Sat, 15 Jun 2024 16:53:40 +0200 Subject: [PATCH 066/704] Typos --- benchmark.txt | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/benchmark.txt b/benchmark.txt index d48c22e..c68f595 100644 --- a/benchmark.txt +++ b/benchmark.txt @@ -9,20 +9,19 @@ C LCS alignment len lcs 876 (136 empty) -102641 {row, col, length} @ 12 b = 1,231,692 b +102641 {row, col, length} @ 12 b = 1,231,692 b Python 0:00.33 32,688 kB - C (no pre alloc) 0:00.03 20,528 kB C (256 pre alloc) 0:00.02 -3,276 kB (256 * (876 - 136)) @ 12 b = 2,273,280 b +3,276 kB (256 * (876 - 136)) @ 12 b = 2,273,280 b LCS graph @@ -36,7 +35,6 @@ C (only nodes) 0:00.03 4,940 kB -C (flat lamdba edges: 5,894,814) (pre alloc makes no difference) +C (flat lambda edges: 5,894,814) (pre alloc makes no difference) 0:00.13 142,468 kB - From 72110d23185f8eb4021fa34082923f25297a8a49 Mon Sep 17 00:00:00 2001 From: jkvis Date: Sat, 15 Jun 2024 22:22:23 +0200 Subject: [PATCH 067/704] No precise pre allocation --- src/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.c b/src/main.c index a639313..0838651 100644 --- a/src/main.c +++ b/src/main.c @@ -149,8 +149,8 @@ build_graph(VA_Allocator const allocator, (void) observed; Graph graph = { - va_array_init(allocator, 102641, sizeof(*graph.nodes)), - va_array_init(allocator, 5894814, sizeof(*graph.edges)), + va_array_init(allocator, 256 * len_lcs, sizeof(*graph.nodes)), + NULL, }; if (len_lcs == 0 || lcs_nodes == NULL) From 2e5c4e59b07fb64a31946a56065e05826d6aa055 Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 21 Jun 2024 12:17:24 +0200 Subject: [PATCH 068/704] WIP nodes with edges --- src/edit.c | 4 +-- src/main.c | 82 ++++++++++++++++++++---------------------------------- 2 files changed, 32 insertions(+), 54 deletions(-) diff --git a/src/edit.c b/src/edit.c index 0043dd9..acb84d2 100644 --- a/src/edit.c +++ b/src/edit.c @@ -170,7 +170,7 @@ expand(Context const context, { context.lcs_nodes[lcs_pos] = va_array_init(context.allocator, 256, sizeof(*context.lcs_nodes[lcs_pos])); } // if - va_array_append(context.allocator, context.lcs_nodes[lcs_pos], ((VA_LCS_Node) {.row = match_row, .col = match_col, .length = length})); + va_array_append(context.allocator, context.lcs_nodes[lcs_pos], ((VA_LCS_Node) {match_row, match_col, length, 0, -1})); matching = false; } // if row += 1; @@ -203,7 +203,7 @@ expand(Context const context, { context.lcs_nodes[lcs_pos] = va_array_init(context.allocator, 256, sizeof(*context.lcs_nodes[lcs_pos])); } // if - va_array_append(context.allocator, context.lcs_nodes[lcs_pos], ((VA_LCS_Node) {.row = match_row, .col = match_col, .length = length})); + va_array_append(context.allocator, context.lcs_nodes[lcs_pos], ((VA_LCS_Node) {match_row, match_col, length, 0, -1})); } // if return steps; diff --git a/src/main.c b/src/main.c index 0838651..b7e3ed9 100644 --- a/src/main.c +++ b/src/main.c @@ -13,8 +13,8 @@ typedef struct { - uint32_t source; uint32_t sink; + uint32_t next; VA_Variant variant; } Edge; @@ -24,6 +24,8 @@ typedef struct uint32_t row; uint32_t col; uint32_t length; + uint32_t edges; + uint32_t lambda; } Node; @@ -37,55 +39,32 @@ typedef struct static inline size_t add_node(VA_Allocator const allocator, Graph* const graph, size_t const row, size_t const col, size_t const length) { - va_array_append(allocator, graph->nodes, ((Node) {row, col, length})); - return va_array_length(graph->nodes); + va_array_append(allocator, graph->nodes, ((Node) {row, col, length, -1, -1})); + return va_array_length(graph->nodes) - 1; } // add_node static inline size_t -add_edge(VA_Allocator const allocator, Graph* const graph, size_t const source, size_t const sink, VA_Variant const variant) +add_edge(VA_Allocator const allocator, Graph* const graph, size_t const sink, size_t const next, VA_Variant const variant) { - va_array_append(allocator, graph->edges, ((Edge) {source, sink, variant})); - return va_array_length(graph->edges); + va_array_append(allocator, graph->edges, ((Edge) {sink, next, variant})); + return va_array_length(graph->edges) - 1; } // add_edge static void -to_dot(Graph const* const graph, size_t const len_obs, char const observed[static len_obs]) +to_dot(Graph const graph, size_t const len_obs, char const observed[static len_obs]) { - printf("digraph{\nrankdir=LR\nedge[fontname=monospace]\nnode[fixedsize=true,fontname=serif,shape=circle,width=1]\nsi[shape=point,width=.1]\n"); - if (graph->nodes == NULL) - { - printf("}\n"); - return; - } // if - for (size_t i = 0; i < va_array_length(graph->nodes); ++i) + printf("%zu\n", va_array_length(graph.nodes)); + for (size_t i = 0; i < va_array_length(graph.nodes); ++i) { - if (i == 0) - { - printf("s%zu[label=\"(%u, %u, %u)\",peripheries=2]\n", i, graph->nodes[i].row, graph->nodes[i].col, graph->nodes[i].length); - } // if - else - { - printf("s%zu[label=\"(%u, %u, %u)\"]\n", i, graph->nodes[i].row, graph->nodes[i].col, graph->nodes[i].length); - } // else + printf(" %zu: (%u, %u, %u), %u, %u\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, graph.nodes[i].edges,graph.nodes[i].lambda); } // for - - printf("si->s%zu\n", va_array_length(graph->nodes) - 1); - - for (size_t i = 0; i < va_array_length(graph->edges); ++i) + printf("%zu\n", va_array_length(graph.edges)); + for (size_t i = 0; i < va_array_length(graph.edges); ++i) { - if (va_variant_len(graph->edges[i].variant) == 0) - { - printf("s%u->s%u[label=\"λ\",style=dashed]\n", graph->edges[i].source, graph->edges[i].sink); - } // if - else - { - size_t const len = graph->edges[i].variant.obs_end - graph->edges[i].variant.obs_start; - printf("s%u->s%u[label=\"%u:%u/%.*s\"]\n", graph->edges[i].source, graph->edges[i].sink, graph->edges[i].variant.start, graph->edges[i].variant.end, (int) len, observed + graph->edges[i].variant.obs_start); - } // else + printf(" %zu: %u, (%u:%u/%.*s), %u\n", i, graph.edges[i].sink, graph.edges[i].variant.start, graph.edges[i].variant.end, (int) graph.edges[i].variant.obs_end - graph.edges[i].variant.obs_start, observed + graph.edges[i].variant.obs_start, graph.edges[i].next); } // for - printf("}\n"); } // to_dot @@ -111,13 +90,14 @@ doit(VA_Allocator const allocator, Graph* const graph, VA_LCS_Node const sink, V if (sources[i].incoming == lcs_idx) { //printf("SPLIT: (%u, %u, %u)\n", sources[i].row, sources[i].col, sources[i].length); - size_t const split_idx = sources[i].idx - 1; + size_t const split_idx = sources[i].idx; sources[i].idx = add_node(allocator, graph, sources[i].row, sources[i].col, graph->nodes[split_idx].length); sources[i].incoming = 0; // lambda-edge - add_edge(allocator, graph, sources[i].idx - 1, split_idx, (VA_Variant) {0, 0, 0, 0}); - add_edge(allocator, graph, sources[i].idx - 1, sink.idx - 1, variant); + graph->nodes[sources[i].idx].lambda = split_idx; + + graph->nodes[sources[i].idx].edges = add_edge(allocator, graph, sink.idx, graph->nodes[sources[i].idx].edges , variant); graph->nodes[split_idx].row += sources[i].length; graph->nodes[split_idx].col += sources[i].length; @@ -125,11 +105,11 @@ doit(VA_Allocator const allocator, Graph* const graph, VA_LCS_Node const sink, V } // if else { - if (sources[i].idx == 0) + if (sources[i].idx == (uint32_t) -1) { sources[i].idx = add_node(allocator, graph, sources[i].row, sources[i].col, sources[i].length); } // if - add_edge(allocator, graph, sources[i].idx - 1, sink.idx - 1, variant); + graph->nodes[sources[i].idx].edges = add_edge(allocator, graph, sink.idx, graph->nodes[sources[i].idx].edges, variant); } // else idx = i + 1; } // if @@ -187,7 +167,7 @@ build_graph(VA_Allocator const allocator, //printf("idx %zu\n", i); for (size_t j = 0; j < va_array_length(lcs_nodes[i]); ++j) { - if (lcs_nodes[i][j].idx == 0) + if (lcs_nodes[i][j].idx == (uint32_t) -1) { continue; } // if @@ -222,7 +202,7 @@ build_graph(VA_Allocator const allocator, for (size_t i = start; i < va_array_length(lcs_nodes[0]); ++i) { - if (lcs_nodes[0][i].idx == 0) + if (lcs_nodes[0][i].idx == (uint32_t) -1) { continue; } // if @@ -231,7 +211,7 @@ build_graph(VA_Allocator const allocator, { VA_Variant const variant = {source.row, lcs_nodes[0][i].row + lcs_nodes[0][i].length - 1, source.col - shift, lcs_nodes[0][i].col + lcs_nodes[0][i].length - 1 - shift}; //printf("(%u, %u, %u) -> (%u, %u, %u)\n", source.row, source.col, source.length, lcs_nodes[0][i].row, lcs_nodes[0][i].col, lcs_nodes[0][i].length); - add_edge(allocator, &graph, source.idx - 1, lcs_nodes[0][i].idx - 1, variant); + graph.nodes[source.idx].edges = add_edge(allocator, &graph, lcs_nodes[0][i].idx, graph.nodes[source.idx].edges, variant); } // if } // for lcs_nodes[0] = va_array_destroy(allocator, lcs_nodes[0]); @@ -245,12 +225,12 @@ build_graph(VA_Allocator const allocator, int main(int argc, char* argv[static argc + 1]) { - +/* (void) argv; char const* const restrict reference = "ATTCTATCTTCTGTCTACATAAGATGTCATACTAGAGGGCATATCTGCAATGTATACATATTATCTTTTCCAGCATGCATTCAGTTGTGTTGGAATAATTTATGTACACCTTTATAAACGCTGAGCCTCACAAGAGCCATGTGCCACGTATTGTTTTCTTACTACTTTTTGGGATACCTGGCACGTAATAGACACTCATTGAAAGTTTCCTAATGAATGAAGTACAAAGATAAAACAAGTTATAGACTGATTCTTTTGAGCTGTCAAGGTTGTAAATAGACTTTTGCTCAATCAATTCAAATGGTGGCAGGTAGTGGGGGTAGAGGGATTGGTATGAAAAACATAAGCTTTCAGAACTCCTGTGTTTATTTTTAGAATGTCAACTGCTTGAGTGTTTTTAACTCTGTGGTATCTGAACTATCTTCTCTAACTGCAGGTTGGGCTCAGATCTGTGATAGAACAGTTTCCTGGGAAGCTTGACTTTGTCCTTGTGGATGGGGGCTGTGTCCTAAGCCATGGCCACAAGCAGTTGATGTGCTTGGCTAGATCTGTTCTCAGTAAGGCGAAGATCTTGCTGCTTGATGAACCCAGTGCTCATTTGGATCCAGTGTGAGTTTCAGATGTTCTGTTACTTAATAGCACAGTGGGAACAGAATCATTATGCCTGCTTCATGGTGACACATATTTCTATTAGGCTGTCATGTCTGCGTGTGGGGGTCTCCCCCAAGATATGAAATAATTGCCCAGTGGAAATGAGCATAAATGCATATTTCCTTGCTAAGAGTCTTGTGTTTTCTTCCGAAGATAGTTTTTAGTTTCATACAAACTCTTCCCCCTTGTCAACACATGATGAAGCTTTTAAATACATGGGCCTAATCTGATCCTTATGATTTGCCTTTGTATCCCATTTATACCATAAGCATGTTTATAGCCCCAAATAAAGAAGTACTGGTGATTCTACATAATGAAAAATGTACTCATTTATTAAAGTTTCTTTGAAATATTTGTCCTGTTTATTTATGGATACTTAGAGTCTACCCCATGGTTGAAAAGCTGATTGTGGCTAACGCTATATCAACATTATGTGAAAAGAACTTAAAGAAATAAGTAATTTAAAGAGATAATAGAACAATAGACATATTATCAAGGTAAATACAGATCATTACTGTTCTGTGATATTATGTGTGGTATTTTCTTTCTTTTCTAGAACATACCAAATAATTAGAAGAACTCTAAAACAAGCATTTGCTGATTGCACAGTAATTCTCTGTGAACACAGGATAGAAGCAATGCTGGAATGCCAACAATTTTTGGTGAGTCTTTATAACTTTACTTAAGATCTCATTGCCCTTGTAATTCTTGATAACAATCTCACATGTGATAGTTCCTGCAAATTGCAACAATGTACAAGTTCTTTTCAAAAATATGTATCATACAGCCATCCAGCTTTACTCAAAATAGCTGCACAAGTTTTTCACTTTGATCTGAGCCATGTGGTGAGGTTGAAATATAGTAAATCTAAAATGGCAGCATATTACTAAGTTATGTTTATAAATAGGATATATATACTTTTTGAGCCCTTTATTTGGGGACCAAGTCATACAAAATACTCTACTGTTTAAGATTTTAAAAAAGGTCCCTGTGATTCTTTCAATAACTAAATGTCCCATGGATGTGGTCTGGGACAGGCCTAGTTGTCTTACAGTCTGATTTATGGTATTAATGACAAAGTTGAGAGGCACATTTCATTTTT"; char const* const restrict observed = "ATTCTATCTTCTGTCTACATAAGATGTCATACTAGAGGGCATATCTGCAATGTATACATATTATCTTTTCCAGCATGCATTCAGTTGTGTTGGAATAATTTATGTACACCTTTATAAACGCTGAGCCTCACAAGAGCCATGTGCCACGTATTGTTTTCTTACTACTTTTTGGGATACCTGGCACGTAATAGACACTCATTGAAAGTTTCCTAATGAATGAAGTACAAAGATAAAACAAGTTATAGACTGATTCTTTTGAGCTGTCAAGGTTGTAAATAGACTTTTGCTCAATCAATTCAAATGGTGGCAGGTAGTGGGGGTAGAGGGATTGGTATGAAAAACATAAGCTTTCAGAACTCCTGTGTTTATTTTTAGAATGTCAACTGCTTGAGTGTTTTTAACTCTGTGGTATCTGAACTATCTTCTCTAACTGCAGGTGAGTCTTTATAACTTTACTTAAGATCTCATTGCCCTTGTAATTCTTGATAACAATCTCACATGTGATAGTTCCTGCAAATTGCAACAATGTACAAGTTCTTTTCAAAAATATGTATCATACAGCCATCCAGCTTTACTCAAAATAGCTGCACAAGTTTTTCACTTTGATCTGAGCCATGTGGTGAGGTTGAAATATAGTAAATCTAAAATGGCAGCATATTACTAAGTTATGTTTATAAATAGGATATATATACTTTTTGAGCCCTTTATTTGGGGACCAAGTCATACAAAATACTCTACTGTTTAAGATTTTAAAAAAGGTCCCTGTGATTCTTTCAATAACTAAATGTCCCATGGATGTGGTCTGGGACAGGCCTAGTTGTCTTACAGTCTGATTTATGGTATTAATGACAAAGTTGAGAGGCACATTTCATTTTT"; +*/ -/* if (argc < 3) { fprintf(stderr, "usage: %s reference observed\n", argv[0]); @@ -258,18 +238,16 @@ main(int argc, char* argv[static argc + 1]) } // if char const* const restrict reference = argv[1]; char const* const restrict observed = argv[2]; -*/ + size_t const len_ref = strlen(reference); size_t const len_obs = strlen(observed); VA_LCS_Node** lcs_nodes = NULL; size_t const len_lcs = va_edit(va_std_allocator, len_ref, reference, len_obs, observed, &lcs_nodes); Graph graph = build_graph(va_std_allocator, len_ref, reference, len_obs, observed, len_lcs, lcs_nodes, 0); -/* - to_dot(&graph, len_obs, observed); -*/ - printf("%zu\n", va_array_length(graph.nodes)); - printf("%zu\n", va_array_length(graph.edges)); + + to_dot(graph, len_obs, observed); + destroy(va_std_allocator, &graph); return EXIT_SUCCESS; From 0b5e78eb3f4361652adf80de29aed9e53b1a8db1 Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 21 Jun 2024 21:42:38 +0200 Subject: [PATCH 069/704] WIP to_dot --- src/main.c | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/src/main.c b/src/main.c index b7e3ed9..b5bb88f 100644 --- a/src/main.c +++ b/src/main.c @@ -33,6 +33,7 @@ typedef struct { Node* nodes; Edge* edges; + uint32_t source; } Graph; @@ -55,16 +56,29 @@ add_edge(VA_Allocator const allocator, Graph* const graph, size_t const sink, si static void to_dot(Graph const graph, size_t const len_obs, char const observed[static len_obs]) { - printf("%zu\n", va_array_length(graph.nodes)); + printf("digraph{\nrankdir=LR\nedge[fontname=monospace]\nnode[fixedsize=true,fontname=serif,shape=circle,width=1]\nsi[shape=point,width=.1]\n"); + printf("si->s%u\n", graph.source); for (size_t i = 0; i < va_array_length(graph.nodes); ++i) { - printf(" %zu: (%u, %u, %u), %u, %u\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, graph.nodes[i].edges,graph.nodes[i].lambda); - } // for - printf("%zu\n", va_array_length(graph.edges)); - for (size_t i = 0; i < va_array_length(graph.edges); ++i) - { - printf(" %zu: %u, (%u:%u/%.*s), %u\n", i, graph.edges[i].sink, graph.edges[i].variant.start, graph.edges[i].variant.end, (int) graph.edges[i].variant.obs_end - graph.edges[i].variant.obs_start, observed + graph.edges[i].variant.obs_start, graph.edges[i].next); + if (graph.nodes[i].edges == (uint32_t) -1) + { + // FIXME: always node 0 + printf("s%zu[label=\"(%u, %u, %u)\",peripheries=2]\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length); + } // if + else + { + printf("s%zu[label=\"(%u, %u, %u)\"]\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length); + } // else + + for (size_t j = i; j != (uint32_t) -1; j = graph.nodes[j].lambda) + { + for (size_t k = graph.nodes[j].edges; k != (uint32_t) -1; k = graph.edges[k].next) + { + printf("s%zu->s%u[label=\"%u:%u/%.*s\"]\n", i, graph.edges[k].sink, graph.edges[k].variant.start, graph.edges[k].variant.end, (int) graph.edges[k].variant.obs_end - graph.edges[k].variant.obs_start, observed + graph.edges[k].variant.obs_start); + } // for + } // for } // for + printf("}\n"); } // to_dot @@ -131,6 +145,7 @@ build_graph(VA_Allocator const allocator, Graph graph = { va_array_init(allocator, 256 * len_lcs, sizeof(*graph.nodes)), NULL, + 0, }; if (len_lcs == 0 || lcs_nodes == NULL) @@ -218,6 +233,8 @@ build_graph(VA_Allocator const allocator, lcs_nodes = allocator.alloc(allocator.context, lcs_nodes, len_lcs * sizeof(*lcs_nodes), 0); + graph.source = source.idx; + return graph; } // build_graph From 77d8a99101f5d9a3869f8813c07ef5a8ace6fbfc Mon Sep 17 00:00:00 2001 From: jkvis Date: Sat, 29 Jun 2024 13:06:54 +0200 Subject: [PATCH 070/704] WIP: forward edge lists --- src/main.c | 65 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 43 insertions(+), 22 deletions(-) diff --git a/src/main.c b/src/main.c index b5bb88f..db0d8b2 100644 --- a/src/main.c +++ b/src/main.c @@ -13,9 +13,9 @@ typedef struct { + VA_Variant variant; uint32_t sink; uint32_t next; - VA_Variant variant; } Edge; @@ -24,7 +24,11 @@ typedef struct uint32_t row; uint32_t col; uint32_t length; - uint32_t edges; + struct + { + uint32_t head; + uint32_t tail; + } edges; uint32_t lambda; } Node; @@ -40,26 +44,38 @@ typedef struct static inline size_t add_node(VA_Allocator const allocator, Graph* const graph, size_t const row, size_t const col, size_t const length) { - va_array_append(allocator, graph->nodes, ((Node) {row, col, length, -1, -1})); + va_array_append(allocator, graph->nodes, ((Node) {row, col, length, {-1, -1}, -1})); return va_array_length(graph->nodes) - 1; } // add_node -static inline size_t -add_edge(VA_Allocator const allocator, Graph* const graph, size_t const sink, size_t const next, VA_Variant const variant) +static inline void +add_edge(VA_Allocator const allocator, Graph* const graph, size_t const source, size_t const sink, VA_Variant const variant) { - va_array_append(allocator, graph->edges, ((Edge) {sink, next, variant})); - return va_array_length(graph->edges) - 1; + va_array_append(allocator, graph->edges, ((Edge) {variant, sink, -1})); + size_t const idx = va_array_length(graph->edges) - 1; + + if (graph->nodes[source].edges.head == (uint32_t) -1) + { + graph->nodes[source].edges.tail = graph->nodes[source].edges.head = idx; + } // if + else + { + graph->nodes[source].edges.tail = graph->edges[graph->nodes[source].edges.tail].next = idx; + } // else } // add_edge -static void +static size_t to_dot(Graph const graph, size_t const len_obs, char const observed[static len_obs]) { - printf("digraph{\nrankdir=LR\nedge[fontname=monospace]\nnode[fixedsize=true,fontname=serif,shape=circle,width=1]\nsi[shape=point,width=.1]\n"); - printf("si->s%u\n", graph.source); + (void) observed; + size_t count = 0; + //printf("digraph{\nrankdir=LR\nedge[fontname=monospace]\nnode[fixedsize=true,fontname=serif,shape=circle,width=1]\nsi[shape=point,width=.1]\n"); + //printf("si->s%u\n", graph.source); for (size_t i = 0; i < va_array_length(graph.nodes); ++i) { + /* if (graph.nodes[i].edges == (uint32_t) -1) { // FIXME: always node 0 @@ -69,16 +85,19 @@ to_dot(Graph const graph, size_t const len_obs, char const observed[static len_o { printf("s%zu[label=\"(%u, %u, %u)\"]\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length); } // else - + */ for (size_t j = i; j != (uint32_t) -1; j = graph.nodes[j].lambda) { - for (size_t k = graph.nodes[j].edges; k != (uint32_t) -1; k = graph.edges[k].next) + for (size_t k = graph.nodes[j].edges.head; k != (uint32_t) -1; k = graph.edges[k].next) { - printf("s%zu->s%u[label=\"%u:%u/%.*s\"]\n", i, graph.edges[k].sink, graph.edges[k].variant.start, graph.edges[k].variant.end, (int) graph.edges[k].variant.obs_end - graph.edges[k].variant.obs_start, observed + graph.edges[k].variant.obs_start); + printf("%zu\n", k); + //printf("s%zu->s%u[label=\"%u:%u/%.*s\"]\n", i, graph.edges[k].sink, graph.edges[k].variant.start, graph.edges[k].variant.end, (int) graph.edges[k].variant.obs_end - graph.edges[k].variant.obs_start, observed + graph.edges[k].variant.obs_start); + count += 1; } // for } // for } // for - printf("}\n"); + //printf("}\n"); + return count; } // to_dot @@ -111,7 +130,7 @@ doit(VA_Allocator const allocator, Graph* const graph, VA_LCS_Node const sink, V // lambda-edge graph->nodes[sources[i].idx].lambda = split_idx; - graph->nodes[sources[i].idx].edges = add_edge(allocator, graph, sink.idx, graph->nodes[sources[i].idx].edges , variant); + add_edge(allocator, graph, sources[i].idx, sink.idx, variant); graph->nodes[split_idx].row += sources[i].length; graph->nodes[split_idx].col += sources[i].length; @@ -123,7 +142,7 @@ doit(VA_Allocator const allocator, Graph* const graph, VA_LCS_Node const sink, V { sources[i].idx = add_node(allocator, graph, sources[i].row, sources[i].col, sources[i].length); } // if - graph->nodes[sources[i].idx].edges = add_edge(allocator, graph, sink.idx, graph->nodes[sources[i].idx].edges, variant); + add_edge(allocator, graph, sources[i].idx, sink.idx, variant); } // else idx = i + 1; } // if @@ -206,7 +225,7 @@ build_graph(VA_Allocator const allocator, size_t start = 0; if (source.row == shift && source.col == shift) { - // assert source.idx != 0 + // assert source.idx != -1 start = 1; } // if else @@ -226,7 +245,7 @@ build_graph(VA_Allocator const allocator, { VA_Variant const variant = {source.row, lcs_nodes[0][i].row + lcs_nodes[0][i].length - 1, source.col - shift, lcs_nodes[0][i].col + lcs_nodes[0][i].length - 1 - shift}; //printf("(%u, %u, %u) -> (%u, %u, %u)\n", source.row, source.col, source.length, lcs_nodes[0][i].row, lcs_nodes[0][i].col, lcs_nodes[0][i].length); - graph.nodes[source.idx].edges = add_edge(allocator, &graph, lcs_nodes[0][i].idx, graph.nodes[source.idx].edges, variant); + add_edge(allocator, &graph, source.idx, lcs_nodes[0][i].idx, variant); } // if } // for lcs_nodes[0] = va_array_destroy(allocator, lcs_nodes[0]); @@ -242,12 +261,12 @@ build_graph(VA_Allocator const allocator, int main(int argc, char* argv[static argc + 1]) { -/* + (void) argv; char const* const restrict reference = "ATTCTATCTTCTGTCTACATAAGATGTCATACTAGAGGGCATATCTGCAATGTATACATATTATCTTTTCCAGCATGCATTCAGTTGTGTTGGAATAATTTATGTACACCTTTATAAACGCTGAGCCTCACAAGAGCCATGTGCCACGTATTGTTTTCTTACTACTTTTTGGGATACCTGGCACGTAATAGACACTCATTGAAAGTTTCCTAATGAATGAAGTACAAAGATAAAACAAGTTATAGACTGATTCTTTTGAGCTGTCAAGGTTGTAAATAGACTTTTGCTCAATCAATTCAAATGGTGGCAGGTAGTGGGGGTAGAGGGATTGGTATGAAAAACATAAGCTTTCAGAACTCCTGTGTTTATTTTTAGAATGTCAACTGCTTGAGTGTTTTTAACTCTGTGGTATCTGAACTATCTTCTCTAACTGCAGGTTGGGCTCAGATCTGTGATAGAACAGTTTCCTGGGAAGCTTGACTTTGTCCTTGTGGATGGGGGCTGTGTCCTAAGCCATGGCCACAAGCAGTTGATGTGCTTGGCTAGATCTGTTCTCAGTAAGGCGAAGATCTTGCTGCTTGATGAACCCAGTGCTCATTTGGATCCAGTGTGAGTTTCAGATGTTCTGTTACTTAATAGCACAGTGGGAACAGAATCATTATGCCTGCTTCATGGTGACACATATTTCTATTAGGCTGTCATGTCTGCGTGTGGGGGTCTCCCCCAAGATATGAAATAATTGCCCAGTGGAAATGAGCATAAATGCATATTTCCTTGCTAAGAGTCTTGTGTTTTCTTCCGAAGATAGTTTTTAGTTTCATACAAACTCTTCCCCCTTGTCAACACATGATGAAGCTTTTAAATACATGGGCCTAATCTGATCCTTATGATTTGCCTTTGTATCCCATTTATACCATAAGCATGTTTATAGCCCCAAATAAAGAAGTACTGGTGATTCTACATAATGAAAAATGTACTCATTTATTAAAGTTTCTTTGAAATATTTGTCCTGTTTATTTATGGATACTTAGAGTCTACCCCATGGTTGAAAAGCTGATTGTGGCTAACGCTATATCAACATTATGTGAAAAGAACTTAAAGAAATAAGTAATTTAAAGAGATAATAGAACAATAGACATATTATCAAGGTAAATACAGATCATTACTGTTCTGTGATATTATGTGTGGTATTTTCTTTCTTTTCTAGAACATACCAAATAATTAGAAGAACTCTAAAACAAGCATTTGCTGATTGCACAGTAATTCTCTGTGAACACAGGATAGAAGCAATGCTGGAATGCCAACAATTTTTGGTGAGTCTTTATAACTTTACTTAAGATCTCATTGCCCTTGTAATTCTTGATAACAATCTCACATGTGATAGTTCCTGCAAATTGCAACAATGTACAAGTTCTTTTCAAAAATATGTATCATACAGCCATCCAGCTTTACTCAAAATAGCTGCACAAGTTTTTCACTTTGATCTGAGCCATGTGGTGAGGTTGAAATATAGTAAATCTAAAATGGCAGCATATTACTAAGTTATGTTTATAAATAGGATATATATACTTTTTGAGCCCTTTATTTGGGGACCAAGTCATACAAAATACTCTACTGTTTAAGATTTTAAAAAAGGTCCCTGTGATTCTTTCAATAACTAAATGTCCCATGGATGTGGTCTGGGACAGGCCTAGTTGTCTTACAGTCTGATTTATGGTATTAATGACAAAGTTGAGAGGCACATTTCATTTTT"; char const* const restrict observed = "ATTCTATCTTCTGTCTACATAAGATGTCATACTAGAGGGCATATCTGCAATGTATACATATTATCTTTTCCAGCATGCATTCAGTTGTGTTGGAATAATTTATGTACACCTTTATAAACGCTGAGCCTCACAAGAGCCATGTGCCACGTATTGTTTTCTTACTACTTTTTGGGATACCTGGCACGTAATAGACACTCATTGAAAGTTTCCTAATGAATGAAGTACAAAGATAAAACAAGTTATAGACTGATTCTTTTGAGCTGTCAAGGTTGTAAATAGACTTTTGCTCAATCAATTCAAATGGTGGCAGGTAGTGGGGGTAGAGGGATTGGTATGAAAAACATAAGCTTTCAGAACTCCTGTGTTTATTTTTAGAATGTCAACTGCTTGAGTGTTTTTAACTCTGTGGTATCTGAACTATCTTCTCTAACTGCAGGTGAGTCTTTATAACTTTACTTAAGATCTCATTGCCCTTGTAATTCTTGATAACAATCTCACATGTGATAGTTCCTGCAAATTGCAACAATGTACAAGTTCTTTTCAAAAATATGTATCATACAGCCATCCAGCTTTACTCAAAATAGCTGCACAAGTTTTTCACTTTGATCTGAGCCATGTGGTGAGGTTGAAATATAGTAAATCTAAAATGGCAGCATATTACTAAGTTATGTTTATAAATAGGATATATATACTTTTTGAGCCCTTTATTTGGGGACCAAGTCATACAAAATACTCTACTGTTTAAGATTTTAAAAAAGGTCCCTGTGATTCTTTCAATAACTAAATGTCCCATGGATGTGGTCTGGGACAGGCCTAGTTGTCTTACAGTCTGATTTATGGTATTAATGACAAAGTTGAGAGGCACATTTCATTTTT"; -*/ +/* if (argc < 3) { fprintf(stderr, "usage: %s reference observed\n", argv[0]); @@ -255,7 +274,7 @@ main(int argc, char* argv[static argc + 1]) } // if char const* const restrict reference = argv[1]; char const* const restrict observed = argv[2]; - +*/ size_t const len_ref = strlen(reference); size_t const len_obs = strlen(observed); @@ -263,7 +282,9 @@ main(int argc, char* argv[static argc + 1]) size_t const len_lcs = va_edit(va_std_allocator, len_ref, reference, len_obs, observed, &lcs_nodes); Graph graph = build_graph(va_std_allocator, len_ref, reference, len_obs, observed, len_lcs, lcs_nodes, 0); - to_dot(graph, len_obs, observed); + printf("%zu\n", va_array_length(graph.nodes)); + printf("%zu\n", va_array_length(graph.edges)); + printf("%zu\n", to_dot(graph, len_obs, observed)); destroy(va_std_allocator, &graph); From 72ed76ac014ac2cc1d27a27101cd82b35019a3af Mon Sep 17 00:00:00 2001 From: jkvis Date: Sat, 29 Jun 2024 13:51:47 +0200 Subject: [PATCH 071/704] WIP: arrays of edges in nodes --- src/main.c | 34 ++++++++++------------------------ 1 file changed, 10 insertions(+), 24 deletions(-) diff --git a/src/main.c b/src/main.c index db0d8b2..2b21d4f 100644 --- a/src/main.c +++ b/src/main.c @@ -15,20 +15,15 @@ typedef struct { VA_Variant variant; uint32_t sink; - uint32_t next; } Edge; typedef struct { + Edge* edges; uint32_t row; uint32_t col; uint32_t length; - struct - { - uint32_t head; - uint32_t tail; - } edges; uint32_t lambda; } Node; @@ -36,7 +31,6 @@ typedef struct typedef struct { Node* nodes; - Edge* edges; uint32_t source; } Graph; @@ -44,7 +38,7 @@ typedef struct static inline size_t add_node(VA_Allocator const allocator, Graph* const graph, size_t const row, size_t const col, size_t const length) { - va_array_append(allocator, graph->nodes, ((Node) {row, col, length, {-1, -1}, -1})); + va_array_append(allocator, graph->nodes, ((Node) {va_array_init(allocator, 256, sizeof(Edge)), row, col, length, -1})); return va_array_length(graph->nodes) - 1; } // add_node @@ -52,17 +46,7 @@ add_node(VA_Allocator const allocator, Graph* const graph, size_t const row, siz static inline void add_edge(VA_Allocator const allocator, Graph* const graph, size_t const source, size_t const sink, VA_Variant const variant) { - va_array_append(allocator, graph->edges, ((Edge) {variant, sink, -1})); - size_t const idx = va_array_length(graph->edges) - 1; - - if (graph->nodes[source].edges.head == (uint32_t) -1) - { - graph->nodes[source].edges.tail = graph->nodes[source].edges.head = idx; - } // if - else - { - graph->nodes[source].edges.tail = graph->edges[graph->nodes[source].edges.tail].next = idx; - } // else + va_array_append(allocator, graph->nodes[source].edges, ((Edge) {variant, sink})); } // add_edge @@ -88,9 +72,9 @@ to_dot(Graph const graph, size_t const len_obs, char const observed[static len_o */ for (size_t j = i; j != (uint32_t) -1; j = graph.nodes[j].lambda) { - for (size_t k = graph.nodes[j].edges.head; k != (uint32_t) -1; k = graph.edges[k].next) + for (size_t k = 0; k < va_array_length(graph.nodes[j].edges); ++k) { - printf("%zu\n", k); + //printf("%zu\n", k); //printf("s%zu->s%u[label=\"%u:%u/%.*s\"]\n", i, graph.edges[k].sink, graph.edges[k].variant.start, graph.edges[k].variant.end, (int) graph.edges[k].variant.obs_end - graph.edges[k].variant.obs_start, observed + graph.edges[k].variant.obs_start); count += 1; } // for @@ -104,8 +88,11 @@ to_dot(Graph const graph, size_t const len_obs, char const observed[static len_o static void destroy(VA_Allocator const allocator, Graph* const graph) { + for (size_t i = 0; i < va_array_length(graph->nodes); ++i) + { + graph->nodes[i].edges = va_array_destroy(allocator, graph->nodes[i].edges); + } // for graph->nodes = va_array_destroy(allocator, graph->nodes); - graph->edges = va_array_destroy(allocator, graph->edges); } // destroy @@ -163,7 +150,6 @@ build_graph(VA_Allocator const allocator, Graph graph = { va_array_init(allocator, 256 * len_lcs, sizeof(*graph.nodes)), - NULL, 0, }; @@ -283,7 +269,7 @@ main(int argc, char* argv[static argc + 1]) Graph graph = build_graph(va_std_allocator, len_ref, reference, len_obs, observed, len_lcs, lcs_nodes, 0); printf("%zu\n", va_array_length(graph.nodes)); - printf("%zu\n", va_array_length(graph.edges)); + //printf("%zu\n", va_array_length(graph.edges)); printf("%zu\n", to_dot(graph, len_obs, observed)); destroy(va_std_allocator, &graph); From 49404d22beac4f003a9de72f9badef4bce531c5f Mon Sep 17 00:00:00 2001 From: jkvis Date: Sat, 29 Jun 2024 15:16:02 +0200 Subject: [PATCH 072/704] Revert "WIP: arrays of edges in nodes" This reverts commit 72ed76ac014ac2cc1d27a27101cd82b35019a3af. --- src/main.c | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/src/main.c b/src/main.c index 2b21d4f..db0d8b2 100644 --- a/src/main.c +++ b/src/main.c @@ -15,15 +15,20 @@ typedef struct { VA_Variant variant; uint32_t sink; + uint32_t next; } Edge; typedef struct { - Edge* edges; uint32_t row; uint32_t col; uint32_t length; + struct + { + uint32_t head; + uint32_t tail; + } edges; uint32_t lambda; } Node; @@ -31,6 +36,7 @@ typedef struct typedef struct { Node* nodes; + Edge* edges; uint32_t source; } Graph; @@ -38,7 +44,7 @@ typedef struct static inline size_t add_node(VA_Allocator const allocator, Graph* const graph, size_t const row, size_t const col, size_t const length) { - va_array_append(allocator, graph->nodes, ((Node) {va_array_init(allocator, 256, sizeof(Edge)), row, col, length, -1})); + va_array_append(allocator, graph->nodes, ((Node) {row, col, length, {-1, -1}, -1})); return va_array_length(graph->nodes) - 1; } // add_node @@ -46,7 +52,17 @@ add_node(VA_Allocator const allocator, Graph* const graph, size_t const row, siz static inline void add_edge(VA_Allocator const allocator, Graph* const graph, size_t const source, size_t const sink, VA_Variant const variant) { - va_array_append(allocator, graph->nodes[source].edges, ((Edge) {variant, sink})); + va_array_append(allocator, graph->edges, ((Edge) {variant, sink, -1})); + size_t const idx = va_array_length(graph->edges) - 1; + + if (graph->nodes[source].edges.head == (uint32_t) -1) + { + graph->nodes[source].edges.tail = graph->nodes[source].edges.head = idx; + } // if + else + { + graph->nodes[source].edges.tail = graph->edges[graph->nodes[source].edges.tail].next = idx; + } // else } // add_edge @@ -72,9 +88,9 @@ to_dot(Graph const graph, size_t const len_obs, char const observed[static len_o */ for (size_t j = i; j != (uint32_t) -1; j = graph.nodes[j].lambda) { - for (size_t k = 0; k < va_array_length(graph.nodes[j].edges); ++k) + for (size_t k = graph.nodes[j].edges.head; k != (uint32_t) -1; k = graph.edges[k].next) { - //printf("%zu\n", k); + printf("%zu\n", k); //printf("s%zu->s%u[label=\"%u:%u/%.*s\"]\n", i, graph.edges[k].sink, graph.edges[k].variant.start, graph.edges[k].variant.end, (int) graph.edges[k].variant.obs_end - graph.edges[k].variant.obs_start, observed + graph.edges[k].variant.obs_start); count += 1; } // for @@ -88,11 +104,8 @@ to_dot(Graph const graph, size_t const len_obs, char const observed[static len_o static void destroy(VA_Allocator const allocator, Graph* const graph) { - for (size_t i = 0; i < va_array_length(graph->nodes); ++i) - { - graph->nodes[i].edges = va_array_destroy(allocator, graph->nodes[i].edges); - } // for graph->nodes = va_array_destroy(allocator, graph->nodes); + graph->edges = va_array_destroy(allocator, graph->edges); } // destroy @@ -150,6 +163,7 @@ build_graph(VA_Allocator const allocator, Graph graph = { va_array_init(allocator, 256 * len_lcs, sizeof(*graph.nodes)), + NULL, 0, }; @@ -269,7 +283,7 @@ main(int argc, char* argv[static argc + 1]) Graph graph = build_graph(va_std_allocator, len_ref, reference, len_obs, observed, len_lcs, lcs_nodes, 0); printf("%zu\n", va_array_length(graph.nodes)); - //printf("%zu\n", va_array_length(graph.edges)); + printf("%zu\n", va_array_length(graph.edges)); printf("%zu\n", to_dot(graph, len_obs, observed)); destroy(va_std_allocator, &graph); From d1be9768960f705491d06d5e067cf5572c176c89 Mon Sep 17 00:00:00 2001 From: jkvis Date: Sat, 29 Jun 2024 15:16:42 +0200 Subject: [PATCH 073/704] Revert "WIP: forward edge lists" This reverts commit 77d8a99101f5d9a3869f8813c07ef5a8ace6fbfc. --- src/main.c | 65 ++++++++++++++++++------------------------------------ 1 file changed, 22 insertions(+), 43 deletions(-) diff --git a/src/main.c b/src/main.c index db0d8b2..b5bb88f 100644 --- a/src/main.c +++ b/src/main.c @@ -13,9 +13,9 @@ typedef struct { - VA_Variant variant; uint32_t sink; uint32_t next; + VA_Variant variant; } Edge; @@ -24,11 +24,7 @@ typedef struct uint32_t row; uint32_t col; uint32_t length; - struct - { - uint32_t head; - uint32_t tail; - } edges; + uint32_t edges; uint32_t lambda; } Node; @@ -44,38 +40,26 @@ typedef struct static inline size_t add_node(VA_Allocator const allocator, Graph* const graph, size_t const row, size_t const col, size_t const length) { - va_array_append(allocator, graph->nodes, ((Node) {row, col, length, {-1, -1}, -1})); + va_array_append(allocator, graph->nodes, ((Node) {row, col, length, -1, -1})); return va_array_length(graph->nodes) - 1; } // add_node -static inline void -add_edge(VA_Allocator const allocator, Graph* const graph, size_t const source, size_t const sink, VA_Variant const variant) +static inline size_t +add_edge(VA_Allocator const allocator, Graph* const graph, size_t const sink, size_t const next, VA_Variant const variant) { - va_array_append(allocator, graph->edges, ((Edge) {variant, sink, -1})); - size_t const idx = va_array_length(graph->edges) - 1; - - if (graph->nodes[source].edges.head == (uint32_t) -1) - { - graph->nodes[source].edges.tail = graph->nodes[source].edges.head = idx; - } // if - else - { - graph->nodes[source].edges.tail = graph->edges[graph->nodes[source].edges.tail].next = idx; - } // else + va_array_append(allocator, graph->edges, ((Edge) {sink, next, variant})); + return va_array_length(graph->edges) - 1; } // add_edge -static size_t +static void to_dot(Graph const graph, size_t const len_obs, char const observed[static len_obs]) { - (void) observed; - size_t count = 0; - //printf("digraph{\nrankdir=LR\nedge[fontname=monospace]\nnode[fixedsize=true,fontname=serif,shape=circle,width=1]\nsi[shape=point,width=.1]\n"); - //printf("si->s%u\n", graph.source); + printf("digraph{\nrankdir=LR\nedge[fontname=monospace]\nnode[fixedsize=true,fontname=serif,shape=circle,width=1]\nsi[shape=point,width=.1]\n"); + printf("si->s%u\n", graph.source); for (size_t i = 0; i < va_array_length(graph.nodes); ++i) { - /* if (graph.nodes[i].edges == (uint32_t) -1) { // FIXME: always node 0 @@ -85,19 +69,16 @@ to_dot(Graph const graph, size_t const len_obs, char const observed[static len_o { printf("s%zu[label=\"(%u, %u, %u)\"]\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length); } // else - */ + for (size_t j = i; j != (uint32_t) -1; j = graph.nodes[j].lambda) { - for (size_t k = graph.nodes[j].edges.head; k != (uint32_t) -1; k = graph.edges[k].next) + for (size_t k = graph.nodes[j].edges; k != (uint32_t) -1; k = graph.edges[k].next) { - printf("%zu\n", k); - //printf("s%zu->s%u[label=\"%u:%u/%.*s\"]\n", i, graph.edges[k].sink, graph.edges[k].variant.start, graph.edges[k].variant.end, (int) graph.edges[k].variant.obs_end - graph.edges[k].variant.obs_start, observed + graph.edges[k].variant.obs_start); - count += 1; + printf("s%zu->s%u[label=\"%u:%u/%.*s\"]\n", i, graph.edges[k].sink, graph.edges[k].variant.start, graph.edges[k].variant.end, (int) graph.edges[k].variant.obs_end - graph.edges[k].variant.obs_start, observed + graph.edges[k].variant.obs_start); } // for } // for } // for - //printf("}\n"); - return count; + printf("}\n"); } // to_dot @@ -130,7 +111,7 @@ doit(VA_Allocator const allocator, Graph* const graph, VA_LCS_Node const sink, V // lambda-edge graph->nodes[sources[i].idx].lambda = split_idx; - add_edge(allocator, graph, sources[i].idx, sink.idx, variant); + graph->nodes[sources[i].idx].edges = add_edge(allocator, graph, sink.idx, graph->nodes[sources[i].idx].edges , variant); graph->nodes[split_idx].row += sources[i].length; graph->nodes[split_idx].col += sources[i].length; @@ -142,7 +123,7 @@ doit(VA_Allocator const allocator, Graph* const graph, VA_LCS_Node const sink, V { sources[i].idx = add_node(allocator, graph, sources[i].row, sources[i].col, sources[i].length); } // if - add_edge(allocator, graph, sources[i].idx, sink.idx, variant); + graph->nodes[sources[i].idx].edges = add_edge(allocator, graph, sink.idx, graph->nodes[sources[i].idx].edges, variant); } // else idx = i + 1; } // if @@ -225,7 +206,7 @@ build_graph(VA_Allocator const allocator, size_t start = 0; if (source.row == shift && source.col == shift) { - // assert source.idx != -1 + // assert source.idx != 0 start = 1; } // if else @@ -245,7 +226,7 @@ build_graph(VA_Allocator const allocator, { VA_Variant const variant = {source.row, lcs_nodes[0][i].row + lcs_nodes[0][i].length - 1, source.col - shift, lcs_nodes[0][i].col + lcs_nodes[0][i].length - 1 - shift}; //printf("(%u, %u, %u) -> (%u, %u, %u)\n", source.row, source.col, source.length, lcs_nodes[0][i].row, lcs_nodes[0][i].col, lcs_nodes[0][i].length); - add_edge(allocator, &graph, source.idx, lcs_nodes[0][i].idx, variant); + graph.nodes[source.idx].edges = add_edge(allocator, &graph, lcs_nodes[0][i].idx, graph.nodes[source.idx].edges, variant); } // if } // for lcs_nodes[0] = va_array_destroy(allocator, lcs_nodes[0]); @@ -261,12 +242,12 @@ build_graph(VA_Allocator const allocator, int main(int argc, char* argv[static argc + 1]) { - +/* (void) argv; char const* const restrict reference = "ATTCTATCTTCTGTCTACATAAGATGTCATACTAGAGGGCATATCTGCAATGTATACATATTATCTTTTCCAGCATGCATTCAGTTGTGTTGGAATAATTTATGTACACCTTTATAAACGCTGAGCCTCACAAGAGCCATGTGCCACGTATTGTTTTCTTACTACTTTTTGGGATACCTGGCACGTAATAGACACTCATTGAAAGTTTCCTAATGAATGAAGTACAAAGATAAAACAAGTTATAGACTGATTCTTTTGAGCTGTCAAGGTTGTAAATAGACTTTTGCTCAATCAATTCAAATGGTGGCAGGTAGTGGGGGTAGAGGGATTGGTATGAAAAACATAAGCTTTCAGAACTCCTGTGTTTATTTTTAGAATGTCAACTGCTTGAGTGTTTTTAACTCTGTGGTATCTGAACTATCTTCTCTAACTGCAGGTTGGGCTCAGATCTGTGATAGAACAGTTTCCTGGGAAGCTTGACTTTGTCCTTGTGGATGGGGGCTGTGTCCTAAGCCATGGCCACAAGCAGTTGATGTGCTTGGCTAGATCTGTTCTCAGTAAGGCGAAGATCTTGCTGCTTGATGAACCCAGTGCTCATTTGGATCCAGTGTGAGTTTCAGATGTTCTGTTACTTAATAGCACAGTGGGAACAGAATCATTATGCCTGCTTCATGGTGACACATATTTCTATTAGGCTGTCATGTCTGCGTGTGGGGGTCTCCCCCAAGATATGAAATAATTGCCCAGTGGAAATGAGCATAAATGCATATTTCCTTGCTAAGAGTCTTGTGTTTTCTTCCGAAGATAGTTTTTAGTTTCATACAAACTCTTCCCCCTTGTCAACACATGATGAAGCTTTTAAATACATGGGCCTAATCTGATCCTTATGATTTGCCTTTGTATCCCATTTATACCATAAGCATGTTTATAGCCCCAAATAAAGAAGTACTGGTGATTCTACATAATGAAAAATGTACTCATTTATTAAAGTTTCTTTGAAATATTTGTCCTGTTTATTTATGGATACTTAGAGTCTACCCCATGGTTGAAAAGCTGATTGTGGCTAACGCTATATCAACATTATGTGAAAAGAACTTAAAGAAATAAGTAATTTAAAGAGATAATAGAACAATAGACATATTATCAAGGTAAATACAGATCATTACTGTTCTGTGATATTATGTGTGGTATTTTCTTTCTTTTCTAGAACATACCAAATAATTAGAAGAACTCTAAAACAAGCATTTGCTGATTGCACAGTAATTCTCTGTGAACACAGGATAGAAGCAATGCTGGAATGCCAACAATTTTTGGTGAGTCTTTATAACTTTACTTAAGATCTCATTGCCCTTGTAATTCTTGATAACAATCTCACATGTGATAGTTCCTGCAAATTGCAACAATGTACAAGTTCTTTTCAAAAATATGTATCATACAGCCATCCAGCTTTACTCAAAATAGCTGCACAAGTTTTTCACTTTGATCTGAGCCATGTGGTGAGGTTGAAATATAGTAAATCTAAAATGGCAGCATATTACTAAGTTATGTTTATAAATAGGATATATATACTTTTTGAGCCCTTTATTTGGGGACCAAGTCATACAAAATACTCTACTGTTTAAGATTTTAAAAAAGGTCCCTGTGATTCTTTCAATAACTAAATGTCCCATGGATGTGGTCTGGGACAGGCCTAGTTGTCTTACAGTCTGATTTATGGTATTAATGACAAAGTTGAGAGGCACATTTCATTTTT"; char const* const restrict observed = "ATTCTATCTTCTGTCTACATAAGATGTCATACTAGAGGGCATATCTGCAATGTATACATATTATCTTTTCCAGCATGCATTCAGTTGTGTTGGAATAATTTATGTACACCTTTATAAACGCTGAGCCTCACAAGAGCCATGTGCCACGTATTGTTTTCTTACTACTTTTTGGGATACCTGGCACGTAATAGACACTCATTGAAAGTTTCCTAATGAATGAAGTACAAAGATAAAACAAGTTATAGACTGATTCTTTTGAGCTGTCAAGGTTGTAAATAGACTTTTGCTCAATCAATTCAAATGGTGGCAGGTAGTGGGGGTAGAGGGATTGGTATGAAAAACATAAGCTTTCAGAACTCCTGTGTTTATTTTTAGAATGTCAACTGCTTGAGTGTTTTTAACTCTGTGGTATCTGAACTATCTTCTCTAACTGCAGGTGAGTCTTTATAACTTTACTTAAGATCTCATTGCCCTTGTAATTCTTGATAACAATCTCACATGTGATAGTTCCTGCAAATTGCAACAATGTACAAGTTCTTTTCAAAAATATGTATCATACAGCCATCCAGCTTTACTCAAAATAGCTGCACAAGTTTTTCACTTTGATCTGAGCCATGTGGTGAGGTTGAAATATAGTAAATCTAAAATGGCAGCATATTACTAAGTTATGTTTATAAATAGGATATATATACTTTTTGAGCCCTTTATTTGGGGACCAAGTCATACAAAATACTCTACTGTTTAAGATTTTAAAAAAGGTCCCTGTGATTCTTTCAATAACTAAATGTCCCATGGATGTGGTCTGGGACAGGCCTAGTTGTCTTACAGTCTGATTTATGGTATTAATGACAAAGTTGAGAGGCACATTTCATTTTT"; +*/ -/* if (argc < 3) { fprintf(stderr, "usage: %s reference observed\n", argv[0]); @@ -274,7 +255,7 @@ main(int argc, char* argv[static argc + 1]) } // if char const* const restrict reference = argv[1]; char const* const restrict observed = argv[2]; -*/ + size_t const len_ref = strlen(reference); size_t const len_obs = strlen(observed); @@ -282,9 +263,7 @@ main(int argc, char* argv[static argc + 1]) size_t const len_lcs = va_edit(va_std_allocator, len_ref, reference, len_obs, observed, &lcs_nodes); Graph graph = build_graph(va_std_allocator, len_ref, reference, len_obs, observed, len_lcs, lcs_nodes, 0); - printf("%zu\n", va_array_length(graph.nodes)); - printf("%zu\n", va_array_length(graph.edges)); - printf("%zu\n", to_dot(graph, len_obs, observed)); + to_dot(graph, len_obs, observed); destroy(va_std_allocator, &graph); From cf03d64f829543c09362d051859e0151787600cc Mon Sep 17 00:00:00 2001 From: jkvis Date: Sat, 29 Jun 2024 15:22:40 +0200 Subject: [PATCH 074/704] WIP: simple reorder --- src/main.c | 59 ++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 48 insertions(+), 11 deletions(-) diff --git a/src/main.c b/src/main.c index b5bb88f..98fc140 100644 --- a/src/main.c +++ b/src/main.c @@ -53,32 +53,36 @@ add_edge(VA_Allocator const allocator, Graph* const graph, size_t const sink, si } // add_edge -static void +static size_t to_dot(Graph const graph, size_t const len_obs, char const observed[static len_obs]) { - printf("digraph{\nrankdir=LR\nedge[fontname=monospace]\nnode[fixedsize=true,fontname=serif,shape=circle,width=1]\nsi[shape=point,width=.1]\n"); - printf("si->s%u\n", graph.source); + (void) observed; + size_t count = 0; + //printf("digraph{\nrankdir=LR\nedge[fontname=monospace]\nnode[fixedsize=true,fontname=serif,shape=circle,width=1]\nsi[shape=point,width=.1]\n"); + //printf("si->s%u\n", graph.source); for (size_t i = 0; i < va_array_length(graph.nodes); ++i) { if (graph.nodes[i].edges == (uint32_t) -1) { // FIXME: always node 0 - printf("s%zu[label=\"(%u, %u, %u)\",peripheries=2]\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length); + //printf("s%zu[label=\"(%u, %u, %u)\",peripheries=2]\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length); } // if else { - printf("s%zu[label=\"(%u, %u, %u)\"]\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length); + //printf("s%zu[label=\"(%u, %u, %u)\"]\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length); } // else for (size_t j = i; j != (uint32_t) -1; j = graph.nodes[j].lambda) { for (size_t k = graph.nodes[j].edges; k != (uint32_t) -1; k = graph.edges[k].next) { - printf("s%zu->s%u[label=\"%u:%u/%.*s\"]\n", i, graph.edges[k].sink, graph.edges[k].variant.start, graph.edges[k].variant.end, (int) graph.edges[k].variant.obs_end - graph.edges[k].variant.obs_start, observed + graph.edges[k].variant.obs_start); + //printf("s%zu->s%u[label=\"%u:%u/%.*s\"]\n", i, graph.edges[k].sink, graph.edges[k].variant.start, graph.edges[k].variant.end, (int) graph.edges[k].variant.obs_end - graph.edges[k].variant.obs_start, observed + graph.edges[k].variant.obs_start); + count += 1; } // for } // for } // for - printf("}\n"); + //printf("}\n"); + return count; } // to_dot @@ -239,15 +243,40 @@ build_graph(VA_Allocator const allocator, } // build_graph +static Graph +reorder(VA_Allocator const allocator, Graph const graph) +{ + Graph new_graph = + { + va_array_init(allocator, va_array_length(graph.nodes), sizeof(*new_graph.nodes)), + va_array_init(allocator, va_array_length(graph.edges), sizeof(*new_graph.edges)), + graph.source, + }; + + for (size_t i = 0; i < va_array_length(graph.nodes); ++i) + { + add_node(allocator, &new_graph, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length); + + new_graph.nodes[i].lambda = graph.nodes[i].lambda; + new_graph.nodes[i].edges = -1; + for (size_t j = graph.nodes[i].edges; j != (uint32_t) -1; j = graph.edges[j].next) + { + new_graph.nodes[i].edges = add_edge(allocator, &new_graph, graph.edges[j].sink, new_graph.nodes[i].edges, graph.edges[j].variant); + } // for + } // for + return new_graph; +} // reorder + + int main(int argc, char* argv[static argc + 1]) { -/* + (void) argv; char const* const restrict reference = "ATTCTATCTTCTGTCTACATAAGATGTCATACTAGAGGGCATATCTGCAATGTATACATATTATCTTTTCCAGCATGCATTCAGTTGTGTTGGAATAATTTATGTACACCTTTATAAACGCTGAGCCTCACAAGAGCCATGTGCCACGTATTGTTTTCTTACTACTTTTTGGGATACCTGGCACGTAATAGACACTCATTGAAAGTTTCCTAATGAATGAAGTACAAAGATAAAACAAGTTATAGACTGATTCTTTTGAGCTGTCAAGGTTGTAAATAGACTTTTGCTCAATCAATTCAAATGGTGGCAGGTAGTGGGGGTAGAGGGATTGGTATGAAAAACATAAGCTTTCAGAACTCCTGTGTTTATTTTTAGAATGTCAACTGCTTGAGTGTTTTTAACTCTGTGGTATCTGAACTATCTTCTCTAACTGCAGGTTGGGCTCAGATCTGTGATAGAACAGTTTCCTGGGAAGCTTGACTTTGTCCTTGTGGATGGGGGCTGTGTCCTAAGCCATGGCCACAAGCAGTTGATGTGCTTGGCTAGATCTGTTCTCAGTAAGGCGAAGATCTTGCTGCTTGATGAACCCAGTGCTCATTTGGATCCAGTGTGAGTTTCAGATGTTCTGTTACTTAATAGCACAGTGGGAACAGAATCATTATGCCTGCTTCATGGTGACACATATTTCTATTAGGCTGTCATGTCTGCGTGTGGGGGTCTCCCCCAAGATATGAAATAATTGCCCAGTGGAAATGAGCATAAATGCATATTTCCTTGCTAAGAGTCTTGTGTTTTCTTCCGAAGATAGTTTTTAGTTTCATACAAACTCTTCCCCCTTGTCAACACATGATGAAGCTTTTAAATACATGGGCCTAATCTGATCCTTATGATTTGCCTTTGTATCCCATTTATACCATAAGCATGTTTATAGCCCCAAATAAAGAAGTACTGGTGATTCTACATAATGAAAAATGTACTCATTTATTAAAGTTTCTTTGAAATATTTGTCCTGTTTATTTATGGATACTTAGAGTCTACCCCATGGTTGAAAAGCTGATTGTGGCTAACGCTATATCAACATTATGTGAAAAGAACTTAAAGAAATAAGTAATTTAAAGAGATAATAGAACAATAGACATATTATCAAGGTAAATACAGATCATTACTGTTCTGTGATATTATGTGTGGTATTTTCTTTCTTTTCTAGAACATACCAAATAATTAGAAGAACTCTAAAACAAGCATTTGCTGATTGCACAGTAATTCTCTGTGAACACAGGATAGAAGCAATGCTGGAATGCCAACAATTTTTGGTGAGTCTTTATAACTTTACTTAAGATCTCATTGCCCTTGTAATTCTTGATAACAATCTCACATGTGATAGTTCCTGCAAATTGCAACAATGTACAAGTTCTTTTCAAAAATATGTATCATACAGCCATCCAGCTTTACTCAAAATAGCTGCACAAGTTTTTCACTTTGATCTGAGCCATGTGGTGAGGTTGAAATATAGTAAATCTAAAATGGCAGCATATTACTAAGTTATGTTTATAAATAGGATATATATACTTTTTGAGCCCTTTATTTGGGGACCAAGTCATACAAAATACTCTACTGTTTAAGATTTTAAAAAAGGTCCCTGTGATTCTTTCAATAACTAAATGTCCCATGGATGTGGTCTGGGACAGGCCTAGTTGTCTTACAGTCTGATTTATGGTATTAATGACAAAGTTGAGAGGCACATTTCATTTTT"; char const* const restrict observed = "ATTCTATCTTCTGTCTACATAAGATGTCATACTAGAGGGCATATCTGCAATGTATACATATTATCTTTTCCAGCATGCATTCAGTTGTGTTGGAATAATTTATGTACACCTTTATAAACGCTGAGCCTCACAAGAGCCATGTGCCACGTATTGTTTTCTTACTACTTTTTGGGATACCTGGCACGTAATAGACACTCATTGAAAGTTTCCTAATGAATGAAGTACAAAGATAAAACAAGTTATAGACTGATTCTTTTGAGCTGTCAAGGTTGTAAATAGACTTTTGCTCAATCAATTCAAATGGTGGCAGGTAGTGGGGGTAGAGGGATTGGTATGAAAAACATAAGCTTTCAGAACTCCTGTGTTTATTTTTAGAATGTCAACTGCTTGAGTGTTTTTAACTCTGTGGTATCTGAACTATCTTCTCTAACTGCAGGTGAGTCTTTATAACTTTACTTAAGATCTCATTGCCCTTGTAATTCTTGATAACAATCTCACATGTGATAGTTCCTGCAAATTGCAACAATGTACAAGTTCTTTTCAAAAATATGTATCATACAGCCATCCAGCTTTACTCAAAATAGCTGCACAAGTTTTTCACTTTGATCTGAGCCATGTGGTGAGGTTGAAATATAGTAAATCTAAAATGGCAGCATATTACTAAGTTATGTTTATAAATAGGATATATATACTTTTTGAGCCCTTTATTTGGGGACCAAGTCATACAAAATACTCTACTGTTTAAGATTTTAAAAAAGGTCCCTGTGATTCTTTCAATAACTAAATGTCCCATGGATGTGGTCTGGGACAGGCCTAGTTGTCTTACAGTCTGATTTATGGTATTAATGACAAAGTTGAGAGGCACATTTCATTTTT"; -*/ +/* if (argc < 3) { fprintf(stderr, "usage: %s reference observed\n", argv[0]); @@ -255,7 +284,7 @@ main(int argc, char* argv[static argc + 1]) } // if char const* const restrict reference = argv[1]; char const* const restrict observed = argv[2]; - +*/ size_t const len_ref = strlen(reference); size_t const len_obs = strlen(observed); @@ -263,9 +292,17 @@ main(int argc, char* argv[static argc + 1]) size_t const len_lcs = va_edit(va_std_allocator, len_ref, reference, len_obs, observed, &lcs_nodes); Graph graph = build_graph(va_std_allocator, len_ref, reference, len_obs, observed, len_lcs, lcs_nodes, 0); - to_dot(graph, len_obs, observed); + //printf("%zu\n", va_array_length(graph.nodes)); + //printf("%zu\n", va_array_length(graph.edges)); + //printf("%zu\n", to_dot(graph, len_obs, observed)); + + Graph new_graph = reorder(va_std_allocator, graph); + printf("%zu\n", va_array_length(new_graph.nodes)); + printf("%zu\n", va_array_length(new_graph.edges)); + printf("%zu\n", to_dot(new_graph, len_obs, observed)); destroy(va_std_allocator, &graph); + destroy(va_std_allocator, &new_graph); return EXIT_SUCCESS; } // main From da20020641f5bfea290d0998e970007ed5e1cb8a Mon Sep 17 00:00:00 2001 From: jkvis Date: Sat, 29 Jun 2024 15:54:20 +0200 Subject: [PATCH 075/704] WIP: more benchmark stats --- benchmark.txt | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/benchmark.txt b/benchmark.txt index c68f595..fa6d0e3 100644 --- a/benchmark.txt +++ b/benchmark.txt @@ -35,6 +35,33 @@ C (only nodes) 0:00.03 4,940 kB -C (flat lambda edges: 5,894,814) (pre alloc makes no difference) +C (flat lambda edges: 5,874,991) (pre alloc makes no difference) 0:00.13 142,468 kB + + +LCS edge count + +flat edge stack order +0:00.33 +142,476 kB + +flat edge stack order + reorder +0:00.31 +279,328 kB + +flat edge list order +0:00.33 +143,072 kB + +nested edge arrays (256 pre alloc) +0:00.23 +355,548 kB + +nested edge arrays (150 pre alloc) +0:00.21 +279,752 kB + +nested edge arrays (no pre alloc) +0:01.00 +1,739,728 kB From 176f14601909ef5b50c16b977ad31e0952ad411b Mon Sep 17 00:00:00 2001 From: jkvis Date: Sat, 29 Jun 2024 17:11:28 +0200 Subject: [PATCH 076/704] WIP: more benchmarking --- benchmark.txt | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/benchmark.txt b/benchmark.txt index fa6d0e3..afa272e 100644 --- a/benchmark.txt +++ b/benchmark.txt @@ -9,7 +9,7 @@ C LCS alignment len lcs 876 (136 empty) -102641 {row, col, length} @ 12 b = 1,231,692 b +102641 {row, col, length} @ 12 b = 1,231,692 b Python 0:00.33 @@ -21,7 +21,7 @@ C (no pre alloc) C (256 pre alloc) 0:00.02 -3,276 kB (256 * (876 - 136)) @ 12 b = 2,273,280 b +3,276 kB (256 * (876 - 136)) @ 12 b = 2,273,280 b LCS graph @@ -35,11 +35,37 @@ C (only nodes) 0:00.03 4,940 kB -C (flat lambda edges: 5,874,991) (pre alloc makes no difference) +C (flat lambda edges: 5,874,991) (pre alloc makes no difference) 0:00.13 142,468 kB +LCS construction + +flat edge stack order +0:00.13 +142,468 kB + +flat edge stack order + reorder +0:00.26 +279,412 kB + +flat edge list order +0:00.13 +142,948 kB + +nested edge arrays (256 pre alloc) +0:00.21 +355,336 kB + +nested edge arrays (150 pre alloc) +0:00.19 +279,468 kB + +nested edge arrays (no pre alloc) +0:00.98 +1,739,560 kB + LCS edge count flat edge stack order From 14fa89b047c6998d4c3e88545112d9db1df93846 Mon Sep 17 00:00:00 2001 From: jkvis Date: Sat, 29 Jun 2024 17:45:14 +0200 Subject: [PATCH 077/704] WIP: graph traversal datastructures --- include/bitset.h | 38 ++++++++++++++++++++++++++ include/queue.h | 38 ++++++++++++++++++++++++++ src/bitset.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++ src/queue.c | 61 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 207 insertions(+) create mode 100644 include/bitset.h create mode 100644 include/queue.h create mode 100644 src/bitset.c create mode 100644 src/queue.c diff --git a/include/bitset.h b/include/bitset.h new file mode 100644 index 0000000..bd89bd6 --- /dev/null +++ b/include/bitset.h @@ -0,0 +1,38 @@ +#ifndef BITSET_H +#define BITSET_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include // bool +#include // size_t + +#include "alloc.h" // VA_Allocator + + +typedef struct VA_Bitset VA_Bitset; + + +VA_Bitset* +va_bitset_init(VA_Allocator const allocator, size_t const capacity); + + +VA_Bitset* +va_bitset_destroy(VA_Allocator const allocator, VA_Bitset* const bitset); + + +VA_Bitset* +va_bitset_set(VA_Bitset* const bitset, size_t const index); + + +bool +va_bitset_test(VA_Bitset const* const bitset, size_t const index); + + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif diff --git a/include/queue.h b/include/queue.h new file mode 100644 index 0000000..228f09d --- /dev/null +++ b/include/queue.h @@ -0,0 +1,38 @@ +#ifndef QUEUE_H +#define QUEUE_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include // size_t +#include // uint32_t + +#include "alloc.h" // VA_Allocator + + +typedef struct VA_Queue VA_Queue; + + +VA_Queue* +va_queue_init(VA_Allocator const allocator, size_t const capacity); + + +VA_Queue* +va_queue_destroy(VA_Allocator const allocator, VA_Queue* const queue); + + +uint32_t +va_queue_dequeue(VA_Queue* const queue); + + +void +va_queue_enqueue(VA_Queue* const queue, uint32_t const value); + + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif diff --git a/src/bitset.c b/src/bitset.c new file mode 100644 index 0000000..56082b4 --- /dev/null +++ b/src/bitset.c @@ -0,0 +1,70 @@ +#include // CHAR_BIT +#include // bool, false +#include // NULL, size_t + +#include "../include/alloc.h" // VA_Allocator +#include "../include/bitset.h" // va_bitset_* + + +struct VA_Bitset +{ + size_t capacity; + size_t data[]; +}; + + +inline VA_Bitset* +va_bitset_init(VA_Allocator const allocator, size_t const capacity) +{ + size_t const size = sizeof((VA_Bitset) {0}.data[0]) * CHAR_BIT; + size_t const slots = (capacity + size - 1) / size; + VA_Bitset* const bitset = allocator.alloc(allocator.context, NULL, 0, sizeof(*bitset) + slots * size); // OVERFLOW + if (bitset == NULL) + { + return NULL; // OOM + } // if + bitset->capacity = capacity; + for (size_t i = 0; i < slots; ++i) + { + bitset->data[i] = 0; + } // for + return bitset; +} // va_bitset_init + + +inline VA_Bitset* +va_bitset_destroy(VA_Allocator const allocator, VA_Bitset* const bitset) +{ + if (bitset == NULL) + { + return NULL; + } // if + size_t const size = sizeof(bitset->data[0]) * CHAR_BIT; + size_t const slots = (bitset->capacity + size - 1) / size; + return allocator.alloc(allocator.context, bitset, sizeof(*bitset) + slots * size, 0); +} // va_bitset_destroy + + +inline VA_Bitset* +va_bitset_set(VA_Bitset* const bitset, size_t const index) +{ + if (bitset == NULL || bitset->capacity <= index) + { + return bitset; + } // if + size_t const size = sizeof(bitset->data[0]) * CHAR_BIT; + bitset->data[index / size] |= ((size_t) 1) << (index % size); + return bitset; +} // va_bitset_set + + +inline bool +va_bitset_test(VA_Bitset const* const bitset, size_t const index) +{ + if (bitset == NULL || bitset->capacity <= index) + { + return false; + } // if + size_t const size = sizeof(bitset->data[0]) * CHAR_BIT; + return bitset->data[index / size] & (((size_t) 1) << (index % size)); +} // va_bitset_test diff --git a/src/queue.c b/src/queue.c new file mode 100644 index 0000000..0f51e67 --- /dev/null +++ b/src/queue.c @@ -0,0 +1,61 @@ +#include // NULL, size_t +#include // uint32_t + +#include "../include/alloc.h" // VA_Allocator +#include "../include/queue.h" // va_queue_* + + +struct VA_Queue +{ + size_t head; + size_t tail; + size_t capacity; + uint32_t data[]; +}; + + +inline VA_Queue* +va_queue_init(VA_Allocator const allocator, size_t const capacity) +{ + VA_Queue* const queue = allocator.alloc(allocator.context, NULL, 0, sizeof(*queue) + capacity * sizeof(*queue->data)); // OVERFLOW + if (queue == NULL) + { + return NULL; // OOM + } // if + queue->head = 0; + queue->tail = 0; + queue->capacity = capacity; + return queue; +} // va_queue_init + + +inline VA_Queue* +va_queue_destroy(VA_Allocator const allocator, VA_Queue* const queue) +{ + return allocator.alloc(allocator.context, queue, sizeof(*queue) + queue->capacity * sizeof(*queue->data), 0); +} // va_queue_destroy + + +inline uint32_t +va_queue_dequeue(VA_Queue* const queue) +{ + if (queue->head == queue->tail) + { + return -1; // UNDERFLOW + } // if + uint32_t const value = queue->data[queue->head]; + queue->head = (queue->head + 1) % queue->capacity; + return value; +} // va_queue_dequeue + + +inline void +va_queue_enqueue(VA_Queue* const queue, uint32_t const value) +{ + if ((queue->tail + 1) % queue->capacity == queue->head) + { + return; // OVERFLOW + } // if + queue->data[queue->tail] = value; + queue->tail = (queue->tail + 1) % queue->capacity; +} // va_queue_enqueue From 317c86f82d062d9ef36aed6c607cbfd919093985 Mon Sep 17 00:00:00 2001 From: jkvis Date: Sat, 29 Jun 2024 22:38:40 +0200 Subject: [PATCH 078/704] WIP: BFS not working --- include/bitset.h | 8 ++++---- include/queue.h | 11 ++++++++--- src/bitset.c | 41 +++++++++++++++++++------------------- src/main.c | 51 +++++++++++++++++++++++++++++++++++++----------- src/queue.c | 40 ++++++++++++++++++++++--------------- 5 files changed, 96 insertions(+), 55 deletions(-) diff --git a/include/bitset.h b/include/bitset.h index bd89bd6..6e4a767 100644 --- a/include/bitset.h +++ b/include/bitset.h @@ -20,15 +20,15 @@ va_bitset_init(VA_Allocator const allocator, size_t const capacity); VA_Bitset* -va_bitset_destroy(VA_Allocator const allocator, VA_Bitset* const bitset); +va_bitset_destroy(VA_Allocator const allocator, VA_Bitset* const self); -VA_Bitset* -va_bitset_set(VA_Bitset* const bitset, size_t const index); +void +va_bitset_set(VA_Bitset* const self, size_t const index); bool -va_bitset_test(VA_Bitset const* const bitset, size_t const index); +va_bitset_test(VA_Bitset const* const self, size_t const index); #ifdef __cplusplus diff --git a/include/queue.h b/include/queue.h index 228f09d..f8e1f69 100644 --- a/include/queue.h +++ b/include/queue.h @@ -6,6 +6,7 @@ extern "C" { #endif +#include // bool #include // size_t #include // uint32_t @@ -20,15 +21,19 @@ va_queue_init(VA_Allocator const allocator, size_t const capacity); VA_Queue* -va_queue_destroy(VA_Allocator const allocator, VA_Queue* const queue); +va_queue_destroy(VA_Allocator const allocator, VA_Queue* const self); uint32_t -va_queue_dequeue(VA_Queue* const queue); +va_queue_dequeue(VA_Queue* const self); void -va_queue_enqueue(VA_Queue* const queue, uint32_t const value); +va_queue_enqueue(VA_Queue* const self, uint32_t const value); + + +bool +va_queue_is_empty(VA_Queue const* const self); #ifdef __cplusplus diff --git a/src/bitset.c b/src/bitset.c index 56082b4..b49125e 100644 --- a/src/bitset.c +++ b/src/bitset.c @@ -18,53 +18,52 @@ va_bitset_init(VA_Allocator const allocator, size_t const capacity) { size_t const size = sizeof((VA_Bitset) {0}.data[0]) * CHAR_BIT; size_t const slots = (capacity + size - 1) / size; - VA_Bitset* const bitset = allocator.alloc(allocator.context, NULL, 0, sizeof(*bitset) + slots * size); // OVERFLOW - if (bitset == NULL) + VA_Bitset* const self = allocator.alloc(allocator.context, NULL, 0, sizeof(*self) + slots * size); // OVERFLOW + if (self == NULL) { return NULL; // OOM } // if - bitset->capacity = capacity; + self->capacity = capacity; for (size_t i = 0; i < slots; ++i) { - bitset->data[i] = 0; + self->data[i] = 0; } // for - return bitset; + return self; } // va_bitset_init inline VA_Bitset* -va_bitset_destroy(VA_Allocator const allocator, VA_Bitset* const bitset) +va_bitset_destroy(VA_Allocator const allocator, VA_Bitset* const self) { - if (bitset == NULL) + if (self == NULL) { return NULL; } // if - size_t const size = sizeof(bitset->data[0]) * CHAR_BIT; - size_t const slots = (bitset->capacity + size - 1) / size; - return allocator.alloc(allocator.context, bitset, sizeof(*bitset) + slots * size, 0); + size_t const size = sizeof(self->data[0]) * CHAR_BIT; + size_t const slots = (self->capacity + size - 1) / size; + return allocator.alloc(allocator.context, self, sizeof(*self) + slots * size, 0); } // va_bitset_destroy -inline VA_Bitset* -va_bitset_set(VA_Bitset* const bitset, size_t const index) +inline void +va_bitset_set(VA_Bitset* const self, size_t const index) { - if (bitset == NULL || bitset->capacity <= index) + if (self == NULL || self->capacity <= index) { - return bitset; + return; } // if - size_t const size = sizeof(bitset->data[0]) * CHAR_BIT; - bitset->data[index / size] |= ((size_t) 1) << (index % size); - return bitset; + size_t const size = sizeof(self->data[0]) * CHAR_BIT; + self->data[index / size] |= ((size_t) 1) << (index % size); } // va_bitset_set inline bool -va_bitset_test(VA_Bitset const* const bitset, size_t const index) +va_bitset_test(VA_Bitset const* const self, size_t const index) { - if (bitset == NULL || bitset->capacity <= index) + if (self == NULL || self->capacity <= index) { return false; } // if - size_t const size = sizeof(bitset->data[0]) * CHAR_BIT; - return bitset->data[index / size] & (((size_t) 1) << (index % size)); + size_t const size = sizeof(self->data[0]) * CHAR_BIT; + return self->data[index / size] & (((size_t) 1) << (index % size)); } // va_bitset_test diff --git a/src/main.c b/src/main.c index 98fc140..19118d5 100644 --- a/src/main.c +++ b/src/main.c @@ -6,7 +6,9 @@ #include "../include/alloc.h" // VA_Allocator #include "../include/array.h" // va_array_* +#include "../include/bitset.h" // VA_Bitset, va_bitset_* #include "../include/edit.h" // va_edit +#include "../include/queue.h" // VA_Queue, va_queue_* #include "../include/std_alloc.h" // va_std_allocator #include "../include/variant.h" // VA_Variant @@ -72,9 +74,9 @@ to_dot(Graph const graph, size_t const len_obs, char const observed[static len_o //printf("s%zu[label=\"(%u, %u, %u)\"]\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length); } // else - for (size_t j = i; j != (uint32_t) -1; j = graph.nodes[j].lambda) + for (uint32_t j = i; j != (uint32_t) -1; j = graph.nodes[j].lambda) { - for (size_t k = graph.nodes[j].edges; k != (uint32_t) -1; k = graph.edges[k].next) + for (uint32_t k = graph.nodes[j].edges; k != (uint32_t) -1; k = graph.edges[k].next) { //printf("s%zu->s%u[label=\"%u:%u/%.*s\"]\n", i, graph.edges[k].sink, graph.edges[k].variant.start, graph.edges[k].variant.end, (int) graph.edges[k].variant.obs_end - graph.edges[k].variant.obs_start, observed + graph.edges[k].variant.obs_start); count += 1; @@ -259,7 +261,7 @@ reorder(VA_Allocator const allocator, Graph const graph) new_graph.nodes[i].lambda = graph.nodes[i].lambda; new_graph.nodes[i].edges = -1; - for (size_t j = graph.nodes[i].edges; j != (uint32_t) -1; j = graph.edges[j].next) + for (uint32_t j = graph.nodes[i].edges; j != (uint32_t) -1; j = graph.edges[j].next) { new_graph.nodes[i].edges = add_edge(allocator, &new_graph, graph.edges[j].sink, new_graph.nodes[i].edges, graph.edges[j].variant); } // for @@ -268,6 +270,40 @@ reorder(VA_Allocator const allocator, Graph const graph) } // reorder +static size_t +bfs_traversal(Graph const graph) +{ + size_t count = 0; + VA_Bitset* visited = va_bitset_init(va_std_allocator, va_array_length(graph.nodes)); + VA_Queue* queue = va_queue_init(va_std_allocator, va_array_length(graph.nodes)); + + va_queue_enqueue(queue, graph.source); + while (!va_queue_is_empty(queue)) + { + uint32_t const source = va_queue_dequeue(queue); + if (va_bitset_test(visited, source)) + { + continue; + } // if + + count += 1; + for (uint32_t i = source; i != (uint32_t) -1; i = graph.nodes[i].lambda) + { + for (uint32_t j = graph.nodes[i].edges; j != (uint32_t) -1; j = graph.edges[j].next) + { + va_queue_enqueue(queue, graph.edges[j].sink); + } // for + } // for + + va_bitset_set(visited, source); + } // while + + queue = va_queue_destroy(va_std_allocator, queue); + visited = va_bitset_destroy(va_std_allocator, visited); + return count; +} // bfs_traversal + + int main(int argc, char* argv[static argc + 1]) { @@ -292,17 +328,10 @@ main(int argc, char* argv[static argc + 1]) size_t const len_lcs = va_edit(va_std_allocator, len_ref, reference, len_obs, observed, &lcs_nodes); Graph graph = build_graph(va_std_allocator, len_ref, reference, len_obs, observed, len_lcs, lcs_nodes, 0); - //printf("%zu\n", va_array_length(graph.nodes)); - //printf("%zu\n", va_array_length(graph.edges)); - //printf("%zu\n", to_dot(graph, len_obs, observed)); + printf("%zu\n", bfs_traversal(graph)); - Graph new_graph = reorder(va_std_allocator, graph); - printf("%zu\n", va_array_length(new_graph.nodes)); - printf("%zu\n", va_array_length(new_graph.edges)); - printf("%zu\n", to_dot(new_graph, len_obs, observed)); destroy(va_std_allocator, &graph); - destroy(va_std_allocator, &new_graph); return EXIT_SUCCESS; } // main diff --git a/src/queue.c b/src/queue.c index 0f51e67..a99ce41 100644 --- a/src/queue.c +++ b/src/queue.c @@ -1,3 +1,4 @@ +#include // bool #include // NULL, size_t #include // uint32_t @@ -17,45 +18,52 @@ struct VA_Queue inline VA_Queue* va_queue_init(VA_Allocator const allocator, size_t const capacity) { - VA_Queue* const queue = allocator.alloc(allocator.context, NULL, 0, sizeof(*queue) + capacity * sizeof(*queue->data)); // OVERFLOW - if (queue == NULL) + VA_Queue* const self = allocator.alloc(allocator.context, NULL, 0, sizeof(*self) + capacity * sizeof(*self->data)); // OVERFLOW + if (self == NULL) { return NULL; // OOM } // if - queue->head = 0; - queue->tail = 0; - queue->capacity = capacity; - return queue; + self->head = 0; + self->tail = 0; + self->capacity = capacity; + return self; } // va_queue_init inline VA_Queue* -va_queue_destroy(VA_Allocator const allocator, VA_Queue* const queue) +va_queue_destroy(VA_Allocator const allocator, VA_Queue* const self) { - return allocator.alloc(allocator.context, queue, sizeof(*queue) + queue->capacity * sizeof(*queue->data), 0); + return allocator.alloc(allocator.context, self, sizeof(*self) + self->capacity * sizeof(self->data[0]), 0); } // va_queue_destroy inline uint32_t -va_queue_dequeue(VA_Queue* const queue) +va_queue_dequeue(VA_Queue* const self) { - if (queue->head == queue->tail) + if (self->head == self->tail) { return -1; // UNDERFLOW } // if - uint32_t const value = queue->data[queue->head]; - queue->head = (queue->head + 1) % queue->capacity; + uint32_t const value = self->data[self->head]; + self->head = (self->head + 1) % self->capacity; return value; } // va_queue_dequeue inline void -va_queue_enqueue(VA_Queue* const queue, uint32_t const value) +va_queue_enqueue(VA_Queue* const self, uint32_t const value) { - if ((queue->tail + 1) % queue->capacity == queue->head) + if ((self->tail + 1) % self->capacity == self->head) { return; // OVERFLOW } // if - queue->data[queue->tail] = value; - queue->tail = (queue->tail + 1) % queue->capacity; + self->data[self->tail] = value; + self->tail = (self->tail + 1) % self->capacity; } // va_queue_enqueue + + +inline bool +va_queue_is_empty(VA_Queue const* const self) +{ + return self->head == self->tail; +} // va_queue_is_empty From 2e1ce1dc198511eb053434536dc2e2dec8619bca Mon Sep 17 00:00:00 2001 From: jkvis Date: Sun, 30 Jun 2024 10:06:09 +0200 Subject: [PATCH 079/704] WIP: queue overflow --- include/queue.h | 2 +- src/main.c | 49 ++++++++++++++++++++++++++++++++++++++++++------- src/queue.c | 5 +++-- 3 files changed, 46 insertions(+), 10 deletions(-) diff --git a/include/queue.h b/include/queue.h index f8e1f69..d9c12bd 100644 --- a/include/queue.h +++ b/include/queue.h @@ -28,7 +28,7 @@ uint32_t va_queue_dequeue(VA_Queue* const self); -void +bool va_queue_enqueue(VA_Queue* const self, uint32_t const value); diff --git a/src/main.c b/src/main.c index 19118d5..f58dfca 100644 --- a/src/main.c +++ b/src/main.c @@ -271,33 +271,68 @@ reorder(VA_Allocator const allocator, Graph const graph) static size_t -bfs_traversal(Graph const graph) +bfs_traversal(Graph const graph, size_t const len_obs, char const observed[static len_obs]) { + (void) observed; size_t count = 0; VA_Bitset* visited = va_bitset_init(va_std_allocator, va_array_length(graph.nodes)); - VA_Queue* queue = va_queue_init(va_std_allocator, va_array_length(graph.nodes)); + VA_Queue* queue = va_queue_init(va_std_allocator, 2 * va_array_length(graph.nodes)); + + //printf("digraph{\nrankdir=LR\nedge[fontname=monospace]\nnode[fixedsize=true,fontname=serif,shape=circle,width=1]\nsi[shape=point,width=.1]\n"); + //printf("si->s%u\n", graph.source); va_queue_enqueue(queue, graph.source); while (!va_queue_is_empty(queue)) { uint32_t const source = va_queue_dequeue(queue); + if (source == (uint32_t) -1) + { + printf("UNDERFLOW\n"); + } // if if (va_bitset_test(visited, source)) { continue; } // if + va_bitset_set(visited, source); + + /* + if (graph.nodes[source].edges == (uint32_t) -1) + { + printf("s%u[label=\"(%u, %u, %u)\",peripheries=2]\n", source, graph.nodes[source].row, graph.nodes[source].col, graph.nodes[source].length); + } // if + else + { + printf("s%u[label=\"(%u, %u, %u)\"]\n", source, graph.nodes[source].row, graph.nodes[source].col, graph.nodes[source].length); + } // else + */ - count += 1; for (uint32_t i = source; i != (uint32_t) -1; i = graph.nodes[i].lambda) { + if (!va_bitset_test(visited, i)) + { + if (!va_queue_enqueue(queue, i)) + { + printf("OVERFLOW (lambda)\n"); + } // if + } // if for (uint32_t j = graph.nodes[i].edges; j != (uint32_t) -1; j = graph.edges[j].next) { - va_queue_enqueue(queue, graph.edges[j].sink); + count += 1; + //printf("s%u->s%u[label=\"%u:%u/%.*s\"]\n", source, graph.edges[j].sink, graph.edges[j].variant.start, graph.edges[j].variant.end, (int) graph.edges[j].variant.obs_end - graph.edges[j].variant.obs_start, observed + graph.edges[j].variant.obs_start); + if (!va_bitset_test(visited, graph.edges[j].sink)) + { + if (!va_queue_enqueue(queue, graph.edges[j].sink)) + { + printf("OVERFLOW\n"); + } // if + } // if } // for } // for - va_bitset_set(visited, source); } // while + //printf("}\n"); + queue = va_queue_destroy(va_std_allocator, queue); visited = va_bitset_destroy(va_std_allocator, visited); return count; @@ -328,8 +363,8 @@ main(int argc, char* argv[static argc + 1]) size_t const len_lcs = va_edit(va_std_allocator, len_ref, reference, len_obs, observed, &lcs_nodes); Graph graph = build_graph(va_std_allocator, len_ref, reference, len_obs, observed, len_lcs, lcs_nodes, 0); - printf("%zu\n", bfs_traversal(graph)); - + printf("%zu\n", bfs_traversal(graph, len_obs, observed)); + printf("%zu\n", to_dot(graph, len_obs, observed)); destroy(va_std_allocator, &graph); diff --git a/src/queue.c b/src/queue.c index a99ce41..08d2928 100644 --- a/src/queue.c +++ b/src/queue.c @@ -50,15 +50,16 @@ va_queue_dequeue(VA_Queue* const self) } // va_queue_dequeue -inline void +inline bool va_queue_enqueue(VA_Queue* const self, uint32_t const value) { if ((self->tail + 1) % self->capacity == self->head) { - return; // OVERFLOW + return false; // OVERFLOW } // if self->data[self->tail] = value; self->tail = (self->tail + 1) % self->capacity; + return true; } // va_queue_enqueue From 00a13f0ac7143c9dc5e940797a946e5e99053bae Mon Sep 17 00:00:00 2001 From: jkvis Date: Sun, 30 Jun 2024 12:17:10 +0200 Subject: [PATCH 080/704] BFS traversal --- src/main.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/main.c b/src/main.c index f58dfca..f76bb37 100644 --- a/src/main.c +++ b/src/main.c @@ -275,12 +275,13 @@ bfs_traversal(Graph const graph, size_t const len_obs, char const observed[stati { (void) observed; size_t count = 0; - VA_Bitset* visited = va_bitset_init(va_std_allocator, va_array_length(graph.nodes)); - VA_Queue* queue = va_queue_init(va_std_allocator, 2 * va_array_length(graph.nodes)); + VA_Bitset* scheduled = va_bitset_init(va_std_allocator, va_array_length(graph.nodes)); + VA_Queue* queue = va_queue_init(va_std_allocator, va_array_length(graph.nodes)); //printf("digraph{\nrankdir=LR\nedge[fontname=monospace]\nnode[fixedsize=true,fontname=serif,shape=circle,width=1]\nsi[shape=point,width=.1]\n"); //printf("si->s%u\n", graph.source); + va_bitset_set(scheduled, graph.source); va_queue_enqueue(queue, graph.source); while (!va_queue_is_empty(queue)) { @@ -289,11 +290,6 @@ bfs_traversal(Graph const graph, size_t const len_obs, char const observed[stati { printf("UNDERFLOW\n"); } // if - if (va_bitset_test(visited, source)) - { - continue; - } // if - va_bitset_set(visited, source); /* if (graph.nodes[source].edges == (uint32_t) -1) @@ -308,8 +304,9 @@ bfs_traversal(Graph const graph, size_t const len_obs, char const observed[stati for (uint32_t i = source; i != (uint32_t) -1; i = graph.nodes[i].lambda) { - if (!va_bitset_test(visited, i)) + if (!va_bitset_test(scheduled, i)) { + va_bitset_set(scheduled, i); if (!va_queue_enqueue(queue, i)) { printf("OVERFLOW (lambda)\n"); @@ -319,8 +316,9 @@ bfs_traversal(Graph const graph, size_t const len_obs, char const observed[stati { count += 1; //printf("s%u->s%u[label=\"%u:%u/%.*s\"]\n", source, graph.edges[j].sink, graph.edges[j].variant.start, graph.edges[j].variant.end, (int) graph.edges[j].variant.obs_end - graph.edges[j].variant.obs_start, observed + graph.edges[j].variant.obs_start); - if (!va_bitset_test(visited, graph.edges[j].sink)) + if (!va_bitset_test(scheduled, graph.edges[j].sink)) { + va_bitset_set(scheduled, graph.edges[j].sink); if (!va_queue_enqueue(queue, graph.edges[j].sink)) { printf("OVERFLOW\n"); @@ -334,7 +332,7 @@ bfs_traversal(Graph const graph, size_t const len_obs, char const observed[stati //printf("}\n"); queue = va_queue_destroy(va_std_allocator, queue); - visited = va_bitset_destroy(va_std_allocator, visited); + scheduled = va_bitset_destroy(va_std_allocator, scheduled); return count; } // bfs_traversal From 8c9cc5aa6c19b25d04e1bca48dabbd95538760ef Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 4 Jul 2024 11:20:06 +0200 Subject: [PATCH 081/704] Fixed off by one in LCS nodes --- src/edit.c | 4 ++-- src/main.c | 46 +++++++++++++++++++++++----------------------- src/queue.c | 2 +- 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/edit.c b/src/edit.c index acb84d2..13dadec 100644 --- a/src/edit.c +++ b/src/edit.c @@ -161,7 +161,7 @@ expand(Context const context, ptrdiff_t const d_row = context.len_ref - row; ptrdiff_t const d_col = context.len_obs - col; size_t const lcs_pos = (row + col - imaxabs(delta) - 2 * p + imaxabs(d_row - d_col)) / 2 - 1; - if (lcs_pos > *len_lcs) + if (lcs_pos + 1 > *len_lcs) { *len_lcs = lcs_pos + 1; } // if @@ -194,7 +194,7 @@ expand(Context const context, ptrdiff_t const d_row = context.len_ref - row; ptrdiff_t const d_col = context.len_obs - col; size_t const lcs_pos = (row + col - imaxabs(delta) - 2 * p + imaxabs(d_row - d_col)) / 2 - 1; - if (lcs_pos > *len_lcs) + if (lcs_pos + 1 > *len_lcs) { *len_lcs = lcs_pos + 1; } // if diff --git a/src/main.c b/src/main.c index f76bb37..7f8319b 100644 --- a/src/main.c +++ b/src/main.c @@ -278,20 +278,15 @@ bfs_traversal(Graph const graph, size_t const len_obs, char const observed[stati VA_Bitset* scheduled = va_bitset_init(va_std_allocator, va_array_length(graph.nodes)); VA_Queue* queue = va_queue_init(va_std_allocator, va_array_length(graph.nodes)); - //printf("digraph{\nrankdir=LR\nedge[fontname=monospace]\nnode[fixedsize=true,fontname=serif,shape=circle,width=1]\nsi[shape=point,width=.1]\n"); - //printf("si->s%u\n", graph.source); + printf("digraph{\nrankdir=LR\nedge[fontname=monospace]\nnode[fixedsize=true,fontname=serif,shape=circle,width=1]\nsi[shape=point,width=.1]\n"); + printf("si->s%u\n", graph.source); va_bitset_set(scheduled, graph.source); va_queue_enqueue(queue, graph.source); while (!va_queue_is_empty(queue)) { uint32_t const source = va_queue_dequeue(queue); - if (source == (uint32_t) -1) - { - printf("UNDERFLOW\n"); - } // if - /* if (graph.nodes[source].edges == (uint32_t) -1) { printf("s%u[label=\"(%u, %u, %u)\",peripheries=2]\n", source, graph.nodes[source].row, graph.nodes[source].col, graph.nodes[source].length); @@ -300,36 +295,28 @@ bfs_traversal(Graph const graph, size_t const len_obs, char const observed[stati { printf("s%u[label=\"(%u, %u, %u)\"]\n", source, graph.nodes[source].row, graph.nodes[source].col, graph.nodes[source].length); } // else - */ for (uint32_t i = source; i != (uint32_t) -1; i = graph.nodes[i].lambda) { if (!va_bitset_test(scheduled, i)) { va_bitset_set(scheduled, i); - if (!va_queue_enqueue(queue, i)) - { - printf("OVERFLOW (lambda)\n"); - } // if + va_queue_enqueue(queue, i); // OVERFLOW } // if for (uint32_t j = graph.nodes[i].edges; j != (uint32_t) -1; j = graph.edges[j].next) { count += 1; - //printf("s%u->s%u[label=\"%u:%u/%.*s\"]\n", source, graph.edges[j].sink, graph.edges[j].variant.start, graph.edges[j].variant.end, (int) graph.edges[j].variant.obs_end - graph.edges[j].variant.obs_start, observed + graph.edges[j].variant.obs_start); + printf("s%u->s%u[label=\"%u:%u/%.*s\"]\n", source, graph.edges[j].sink, graph.edges[j].variant.start, graph.edges[j].variant.end, (int) graph.edges[j].variant.obs_end - graph.edges[j].variant.obs_start, observed + graph.edges[j].variant.obs_start); if (!va_bitset_test(scheduled, graph.edges[j].sink)) { va_bitset_set(scheduled, graph.edges[j].sink); - if (!va_queue_enqueue(queue, graph.edges[j].sink)) - { - printf("OVERFLOW\n"); - } // if + va_queue_enqueue(queue, graph.edges[j].sink); // OVERFLOW } // if } // for } // for - } // while - //printf("}\n"); + printf("}\n"); queue = va_queue_destroy(va_std_allocator, queue); scheduled = va_bitset_destroy(va_std_allocator, scheduled); @@ -340,12 +327,12 @@ bfs_traversal(Graph const graph, size_t const len_obs, char const observed[stati int main(int argc, char* argv[static argc + 1]) { - +/* (void) argv; char const* const restrict reference = "ATTCTATCTTCTGTCTACATAAGATGTCATACTAGAGGGCATATCTGCAATGTATACATATTATCTTTTCCAGCATGCATTCAGTTGTGTTGGAATAATTTATGTACACCTTTATAAACGCTGAGCCTCACAAGAGCCATGTGCCACGTATTGTTTTCTTACTACTTTTTGGGATACCTGGCACGTAATAGACACTCATTGAAAGTTTCCTAATGAATGAAGTACAAAGATAAAACAAGTTATAGACTGATTCTTTTGAGCTGTCAAGGTTGTAAATAGACTTTTGCTCAATCAATTCAAATGGTGGCAGGTAGTGGGGGTAGAGGGATTGGTATGAAAAACATAAGCTTTCAGAACTCCTGTGTTTATTTTTAGAATGTCAACTGCTTGAGTGTTTTTAACTCTGTGGTATCTGAACTATCTTCTCTAACTGCAGGTTGGGCTCAGATCTGTGATAGAACAGTTTCCTGGGAAGCTTGACTTTGTCCTTGTGGATGGGGGCTGTGTCCTAAGCCATGGCCACAAGCAGTTGATGTGCTTGGCTAGATCTGTTCTCAGTAAGGCGAAGATCTTGCTGCTTGATGAACCCAGTGCTCATTTGGATCCAGTGTGAGTTTCAGATGTTCTGTTACTTAATAGCACAGTGGGAACAGAATCATTATGCCTGCTTCATGGTGACACATATTTCTATTAGGCTGTCATGTCTGCGTGTGGGGGTCTCCCCCAAGATATGAAATAATTGCCCAGTGGAAATGAGCATAAATGCATATTTCCTTGCTAAGAGTCTTGTGTTTTCTTCCGAAGATAGTTTTTAGTTTCATACAAACTCTTCCCCCTTGTCAACACATGATGAAGCTTTTAAATACATGGGCCTAATCTGATCCTTATGATTTGCCTTTGTATCCCATTTATACCATAAGCATGTTTATAGCCCCAAATAAAGAAGTACTGGTGATTCTACATAATGAAAAATGTACTCATTTATTAAAGTTTCTTTGAAATATTTGTCCTGTTTATTTATGGATACTTAGAGTCTACCCCATGGTTGAAAAGCTGATTGTGGCTAACGCTATATCAACATTATGTGAAAAGAACTTAAAGAAATAAGTAATTTAAAGAGATAATAGAACAATAGACATATTATCAAGGTAAATACAGATCATTACTGTTCTGTGATATTATGTGTGGTATTTTCTTTCTTTTCTAGAACATACCAAATAATTAGAAGAACTCTAAAACAAGCATTTGCTGATTGCACAGTAATTCTCTGTGAACACAGGATAGAAGCAATGCTGGAATGCCAACAATTTTTGGTGAGTCTTTATAACTTTACTTAAGATCTCATTGCCCTTGTAATTCTTGATAACAATCTCACATGTGATAGTTCCTGCAAATTGCAACAATGTACAAGTTCTTTTCAAAAATATGTATCATACAGCCATCCAGCTTTACTCAAAATAGCTGCACAAGTTTTTCACTTTGATCTGAGCCATGTGGTGAGGTTGAAATATAGTAAATCTAAAATGGCAGCATATTACTAAGTTATGTTTATAAATAGGATATATATACTTTTTGAGCCCTTTATTTGGGGACCAAGTCATACAAAATACTCTACTGTTTAAGATTTTAAAAAAGGTCCCTGTGATTCTTTCAATAACTAAATGTCCCATGGATGTGGTCTGGGACAGGCCTAGTTGTCTTACAGTCTGATTTATGGTATTAATGACAAAGTTGAGAGGCACATTTCATTTTT"; char const* const restrict observed = "ATTCTATCTTCTGTCTACATAAGATGTCATACTAGAGGGCATATCTGCAATGTATACATATTATCTTTTCCAGCATGCATTCAGTTGTGTTGGAATAATTTATGTACACCTTTATAAACGCTGAGCCTCACAAGAGCCATGTGCCACGTATTGTTTTCTTACTACTTTTTGGGATACCTGGCACGTAATAGACACTCATTGAAAGTTTCCTAATGAATGAAGTACAAAGATAAAACAAGTTATAGACTGATTCTTTTGAGCTGTCAAGGTTGTAAATAGACTTTTGCTCAATCAATTCAAATGGTGGCAGGTAGTGGGGGTAGAGGGATTGGTATGAAAAACATAAGCTTTCAGAACTCCTGTGTTTATTTTTAGAATGTCAACTGCTTGAGTGTTTTTAACTCTGTGGTATCTGAACTATCTTCTCTAACTGCAGGTGAGTCTTTATAACTTTACTTAAGATCTCATTGCCCTTGTAATTCTTGATAACAATCTCACATGTGATAGTTCCTGCAAATTGCAACAATGTACAAGTTCTTTTCAAAAATATGTATCATACAGCCATCCAGCTTTACTCAAAATAGCTGCACAAGTTTTTCACTTTGATCTGAGCCATGTGGTGAGGTTGAAATATAGTAAATCTAAAATGGCAGCATATTACTAAGTTATGTTTATAAATAGGATATATATACTTTTTGAGCCCTTTATTTGGGGACCAAGTCATACAAAATACTCTACTGTTTAAGATTTTAAAAAAGGTCCCTGTGATTCTTTCAATAACTAAATGTCCCATGGATGTGGTCTGGGACAGGCCTAGTTGTCTTACAGTCTGATTTATGGTATTAATGACAAAGTTGAGAGGCACATTTCATTTTT"; +*/ -/* if (argc < 3) { fprintf(stderr, "usage: %s reference observed\n", argv[0]); @@ -353,16 +340,29 @@ main(int argc, char* argv[static argc + 1]) } // if char const* const restrict reference = argv[1]; char const* const restrict observed = argv[2]; -*/ + size_t const len_ref = strlen(reference); size_t const len_obs = strlen(observed); VA_LCS_Node** lcs_nodes = NULL; size_t const len_lcs = va_edit(va_std_allocator, len_ref, reference, len_obs, observed, &lcs_nodes); + /* + printf("%zu\n", len_lcs); + for (size_t i = 0; i < len_lcs; ++i) + { + printf("%zu: ", i); + for (size_t j = 0; j < va_array_length(lcs_nodes[i]); ++j) + { + printf("(%u, %u, %u) ", lcs_nodes[i][j].row, lcs_nodes[i][j].col, lcs_nodes[i][j].length); + } // for + printf("\n"); + } // for + */ + Graph graph = build_graph(va_std_allocator, len_ref, reference, len_obs, observed, len_lcs, lcs_nodes, 0); printf("%zu\n", bfs_traversal(graph, len_obs, observed)); - printf("%zu\n", to_dot(graph, len_obs, observed)); + //printf("%zu\n", to_dot(graph, len_obs, observed)); destroy(va_std_allocator, &graph); diff --git a/src/queue.c b/src/queue.c index 08d2928..9ddfa1d 100644 --- a/src/queue.c +++ b/src/queue.c @@ -1,4 +1,4 @@ -#include // bool +#include // bool, false, true #include // NULL, size_t #include // uint32_t From 5f2eadbbb5144b5443bfd82e01ecf2a117a96c8a Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 1 Aug 2024 23:37:31 +0200 Subject: [PATCH 082/704] WIP: alternative bfs traversal --- src/main.c | 159 +++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 118 insertions(+), 41 deletions(-) diff --git a/src/main.c b/src/main.c index 7f8319b..44abb3e 100644 --- a/src/main.c +++ b/src/main.c @@ -15,7 +15,7 @@ typedef struct { - uint32_t sink; + uint32_t tail; uint32_t next; VA_Variant variant; } Edge; @@ -48,9 +48,9 @@ add_node(VA_Allocator const allocator, Graph* const graph, size_t const row, siz static inline size_t -add_edge(VA_Allocator const allocator, Graph* const graph, size_t const sink, size_t const next, VA_Variant const variant) +add_edge(VA_Allocator const allocator, Graph* const graph, size_t const tail, size_t const next, VA_Variant const variant) { - va_array_append(allocator, graph->edges, ((Edge) {sink, next, variant})); + va_array_append(allocator, graph->edges, ((Edge) {tail, next, variant})); return va_array_length(graph->edges) - 1; } // add_edge @@ -60,30 +60,30 @@ to_dot(Graph const graph, size_t const len_obs, char const observed[static len_o { (void) observed; size_t count = 0; - //printf("digraph{\nrankdir=LR\nedge[fontname=monospace]\nnode[fixedsize=true,fontname=serif,shape=circle,width=1]\nsi[shape=point,width=.1]\n"); - //printf("si->s%u\n", graph.source); + printf("digraph{\nrankdir=LR\nedge[fontname=monospace]\nnode[fixedsize=true,fontname=serif,shape=circle,width=1]\nsi[shape=point,width=.1]\n"); + printf("si->s%u\n", graph.source); for (size_t i = 0; i < va_array_length(graph.nodes); ++i) { if (graph.nodes[i].edges == (uint32_t) -1) { // FIXME: always node 0 - //printf("s%zu[label=\"(%u, %u, %u)\",peripheries=2]\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length); + printf("s%zu[label=\"(%u, %u, %u)\",peripheries=2]\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length); } // if else { - //printf("s%zu[label=\"(%u, %u, %u)\"]\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length); + printf("s%zu[label=\"(%u, %u, %u)\"]\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length); } // else for (uint32_t j = i; j != (uint32_t) -1; j = graph.nodes[j].lambda) { for (uint32_t k = graph.nodes[j].edges; k != (uint32_t) -1; k = graph.edges[k].next) { - //printf("s%zu->s%u[label=\"%u:%u/%.*s\"]\n", i, graph.edges[k].sink, graph.edges[k].variant.start, graph.edges[k].variant.end, (int) graph.edges[k].variant.obs_end - graph.edges[k].variant.obs_start, observed + graph.edges[k].variant.obs_start); + printf("s%zu->s%u[label=\"%u:%u/%.*s\"]\n", i, graph.edges[k].tail, graph.edges[k].variant.start, graph.edges[k].variant.end, (int) graph.edges[k].variant.obs_end - graph.edges[k].variant.obs_start, observed + graph.edges[k].variant.obs_start); count += 1; } // for } // for } // for - //printf("}\n"); + printf("}\n"); return count; } // to_dot @@ -97,39 +97,39 @@ destroy(VA_Allocator const allocator, Graph* const graph) static size_t -doit(VA_Allocator const allocator, Graph* const graph, VA_LCS_Node const sink, VA_LCS_Node* const sources, size_t const lcs_idx, size_t const shift) +doit(VA_Allocator const allocator, Graph* const graph, VA_LCS_Node const tail, VA_LCS_Node* const heads, size_t const lcs_idx, size_t const shift) { size_t idx = 0; - for (size_t i = 0; i < va_array_length(sources); ++i) + for (size_t i = 0; i < va_array_length(heads); ++i) { - if (sources[i].row + sources[i].length < sink.row + sink.length && sources[i].col + sources[i].length < sink.col + sink.length) + if (heads[i].row + heads[i].length < tail.row + tail.length && heads[i].col + heads[i].length < tail.col + tail.length) { - VA_Variant const variant = {sources[i].row + sources[i].length, sink.row + sink.length - 1, sources[i].col + sources[i].length - shift, sink.col + sink.length - 1 - shift}; - //printf("(%u, %u, %u) -> (%u, %u, %u)\n", sources[i].row, sources[i].col, sources[i].length, sink.row, sink.col, sink.length); + VA_Variant const variant = {heads[i].row + heads[i].length, tail.row + tail.length - 1, heads[i].col + heads[i].length - shift, tail.col + tail.length - 1 - shift}; + //printf("(%u, %u, %u) -> (%u, %u, %u)\n", heads[i].row, heads[i].col, heads[i].length, tail.row, tail.col, tail.length); - if (sources[i].incoming == lcs_idx) + if (heads[i].incoming == lcs_idx) { - //printf("SPLIT: (%u, %u, %u)\n", sources[i].row, sources[i].col, sources[i].length); - size_t const split_idx = sources[i].idx; - sources[i].idx = add_node(allocator, graph, sources[i].row, sources[i].col, graph->nodes[split_idx].length); - sources[i].incoming = 0; + //printf("SPLIT: (%u, %u, %u)\n", heads[i].row, heads[i].col, heads[i].length); + size_t const split_idx = heads[i].idx; + heads[i].idx = add_node(allocator, graph, heads[i].row, heads[i].col, graph->nodes[split_idx].length); + heads[i].incoming = 0; // lambda-edge - graph->nodes[sources[i].idx].lambda = split_idx; + graph->nodes[heads[i].idx].lambda = split_idx; - graph->nodes[sources[i].idx].edges = add_edge(allocator, graph, sink.idx, graph->nodes[sources[i].idx].edges , variant); + graph->nodes[heads[i].idx].edges = add_edge(allocator, graph, tail.idx, graph->nodes[heads[i].idx].edges , variant); - graph->nodes[split_idx].row += sources[i].length; - graph->nodes[split_idx].col += sources[i].length; - graph->nodes[split_idx].length -= sources[i].length; + graph->nodes[split_idx].row += heads[i].length; + graph->nodes[split_idx].col += heads[i].length; + graph->nodes[split_idx].length -= heads[i].length; } // if else { - if (sources[i].idx == (uint32_t) -1) + if (heads[i].idx == (uint32_t) -1) { - sources[i].idx = add_node(allocator, graph, sources[i].row, sources[i].col, sources[i].length); + heads[i].idx = add_node(allocator, graph, heads[i].row, heads[i].col, heads[i].length); } // if - graph->nodes[sources[i].idx].edges = add_edge(allocator, graph, sink.idx, graph->nodes[sources[i].idx].edges, variant); + graph->nodes[heads[i].idx].edges = add_edge(allocator, graph, tail.idx, graph->nodes[heads[i].idx].edges, variant); } // else idx = i + 1; } // if @@ -149,7 +149,8 @@ build_graph(VA_Allocator const allocator, (void) observed; Graph graph = { - va_array_init(allocator, 256 * len_lcs, sizeof(*graph.nodes)), + //va_array_init(allocator, 256 * len_lcs, sizeof(*graph.nodes)), // FIXME: we know the number of lcs nodes + NULL, NULL, 0, }; @@ -263,7 +264,7 @@ reorder(VA_Allocator const allocator, Graph const graph) new_graph.nodes[i].edges = -1; for (uint32_t j = graph.nodes[i].edges; j != (uint32_t) -1; j = graph.edges[j].next) { - new_graph.nodes[i].edges = add_edge(allocator, &new_graph, graph.edges[j].sink, new_graph.nodes[i].edges, graph.edges[j].variant); + new_graph.nodes[i].edges = add_edge(allocator, &new_graph, graph.edges[j].tail, new_graph.nodes[i].edges, graph.edges[j].variant); } // for } // for return new_graph; @@ -278,25 +279,29 @@ bfs_traversal(Graph const graph, size_t const len_obs, char const observed[stati VA_Bitset* scheduled = va_bitset_init(va_std_allocator, va_array_length(graph.nodes)); VA_Queue* queue = va_queue_init(va_std_allocator, va_array_length(graph.nodes)); + /* printf("digraph{\nrankdir=LR\nedge[fontname=monospace]\nnode[fixedsize=true,fontname=serif,shape=circle,width=1]\nsi[shape=point,width=.1]\n"); printf("si->s%u\n", graph.source); + */ va_bitset_set(scheduled, graph.source); va_queue_enqueue(queue, graph.source); while (!va_queue_is_empty(queue)) { - uint32_t const source = va_queue_dequeue(queue); + uint32_t const head = va_queue_dequeue(queue); - if (graph.nodes[source].edges == (uint32_t) -1) + /* + if (graph.nodes[head].edges == (uint32_t) -1) { - printf("s%u[label=\"(%u, %u, %u)\",peripheries=2]\n", source, graph.nodes[source].row, graph.nodes[source].col, graph.nodes[source].length); + printf("s%u[label=\"(%u, %u, %u)\",peripheries=2]\n", head, graph.nodes[head].row, graph.nodes[head].col, graph.nodes[head].length); } // if else { - printf("s%u[label=\"(%u, %u, %u)\"]\n", source, graph.nodes[source].row, graph.nodes[source].col, graph.nodes[source].length); + printf("s%u[label=\"(%u, %u, %u)\"]\n", head, graph.nodes[head].row, graph.nodes[head].col, graph.nodes[head].length); } // else + */ - for (uint32_t i = source; i != (uint32_t) -1; i = graph.nodes[i].lambda) + for (uint32_t i = head; i != (uint32_t) -1; i = graph.nodes[i].lambda) { if (!va_bitset_test(scheduled, i)) { @@ -306,17 +311,17 @@ bfs_traversal(Graph const graph, size_t const len_obs, char const observed[stati for (uint32_t j = graph.nodes[i].edges; j != (uint32_t) -1; j = graph.edges[j].next) { count += 1; - printf("s%u->s%u[label=\"%u:%u/%.*s\"]\n", source, graph.edges[j].sink, graph.edges[j].variant.start, graph.edges[j].variant.end, (int) graph.edges[j].variant.obs_end - graph.edges[j].variant.obs_start, observed + graph.edges[j].variant.obs_start); - if (!va_bitset_test(scheduled, graph.edges[j].sink)) + //printf("s%u->s%u[label=\"%u:%u/%.*s\"]\n", head, graph.edges[j].tail, graph.edges[j].variant.start, graph.edges[j].variant.end, (int) graph.edges[j].variant.obs_end - graph.edges[j].variant.obs_start, observed + graph.edges[j].variant.obs_start); + if (!va_bitset_test(scheduled, graph.edges[j].tail)) { - va_bitset_set(scheduled, graph.edges[j].sink); - va_queue_enqueue(queue, graph.edges[j].sink); // OVERFLOW + va_bitset_set(scheduled, graph.edges[j].tail); + va_queue_enqueue(queue, graph.edges[j].tail); // OVERFLOW } // if } // for } // for } // while - printf("}\n"); + //printf("}\n"); queue = va_queue_destroy(va_std_allocator, queue); scheduled = va_bitset_destroy(va_std_allocator, scheduled); @@ -324,6 +329,66 @@ bfs_traversal(Graph const graph, size_t const len_obs, char const observed[stati } // bfs_traversal +static size_t +bfs_traversal_alt(VA_Allocator const allocator, Graph const graph) +{ + struct + { + uint32_t depth; + uint32_t next; + }* queue = allocator.alloc(allocator.context, NULL, 0, sizeof(*queue) * va_array_length(graph.nodes)); + + for (size_t i = 0; i < va_array_length(graph.nodes); ++i) + { + queue[i].depth = 0; + queue[i].next = -1; + } // for + uint32_t head = graph.source; + uint32_t tail = graph.source; + + size_t count = 0; + + while (head != (uint32_t) -1) + { + printf("pop %u\n", head); + for (uint32_t i = head; i != (uint32_t) -1; i = graph.nodes[i].lambda) + { + if (i != head) + { + printf("lambda %u\n", i); + } // if + for (uint32_t j = graph.nodes[i].edges; j != (uint32_t) -1; j = graph.edges[j].next) + { + count += 1; + + if (queue[graph.edges[j].tail].depth > 0) + { + printf("skip %u\n", graph.edges[j].tail); + continue; + } // if + + printf("push %u\n", graph.edges[j].tail); + queue[graph.edges[j].tail].depth = queue[i].depth + 1; + queue[tail].next = graph.edges[j].tail; + tail = graph.edges[j].tail; + } // for + } // for + head = queue[head].next; + + printf(" # \tdepth\tnext\n"); + for (size_t i = 0; i < va_array_length(graph.nodes); ++i) + { + printf("%3zu:\t%5u\t%4d\n", i, queue[i].depth, queue[i].next); + } // for + printf("head: %d\ntail: %d\n", head, tail); + } // while + + queue = allocator.alloc(allocator.context, queue, sizeof(*queue) * va_array_length(graph.nodes), 0); + + return count; +} // bfs_traversal_alt + + int main(int argc, char* argv[static argc + 1]) { @@ -361,8 +426,20 @@ main(int argc, char* argv[static argc + 1]) Graph graph = build_graph(va_std_allocator, len_ref, reference, len_obs, observed, len_lcs, lcs_nodes, 0); - printf("%zu\n", bfs_traversal(graph, len_obs, observed)); - //printf("%zu\n", to_dot(graph, len_obs, observed)); + printf("%zu\n", to_dot(graph, len_obs, observed)); + + printf("nodes (%zu)\n #\t(row, col, len)\tedges\tlambda\n", va_array_length(graph.nodes)); + for (size_t i = 0; i < va_array_length(graph.nodes); ++i) + { + printf("%c%2zu:\t(%u, %u, %u)\t%5d\t%6d\n", i == graph.source ? '*' : ' ', i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, (signed) graph.nodes[i].edges, (signed) graph.nodes[i].lambda); + } // for + printf("edges (%zu)\n #\ttail\t\"start:end/seq\"\tnext\n", va_array_length(graph.edges)); + for (size_t i = 0; i < va_array_length(graph.edges); ++i) + { + printf("%3zu:\t%4u\t \"%u:%u/%.*s\"\t%4d\n", i, graph.edges[i].tail, graph.edges[i].variant.start, graph.edges[i].variant.end, (int) graph.edges[i].variant.obs_end - graph.edges[i].variant.obs_start, observed + graph.edges[i].variant.obs_start, (signed) graph.edges[i].next); + } // for + + printf("%zu\n", bfs_traversal_alt(va_std_allocator, graph)); destroy(va_std_allocator, &graph); From 23ff47a0519554f70d1c6bea58bfea5bda166112 Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 2 Aug 2024 12:03:54 +0200 Subject: [PATCH 083/704] Table-based traversal(s) --- include/bitset.h | 38 -------------- include/queue.h | 43 --------------- src/bitset.c | 69 ------------------------ src/edit.c | 1 - src/main.c | 134 +++++++++-------------------------------------- src/queue.c | 70 ------------------------- 6 files changed, 25 insertions(+), 330 deletions(-) delete mode 100644 include/bitset.h delete mode 100644 include/queue.h delete mode 100644 src/bitset.c delete mode 100644 src/queue.c diff --git a/include/bitset.h b/include/bitset.h deleted file mode 100644 index 6e4a767..0000000 --- a/include/bitset.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef BITSET_H -#define BITSET_H - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include // bool -#include // size_t - -#include "alloc.h" // VA_Allocator - - -typedef struct VA_Bitset VA_Bitset; - - -VA_Bitset* -va_bitset_init(VA_Allocator const allocator, size_t const capacity); - - -VA_Bitset* -va_bitset_destroy(VA_Allocator const allocator, VA_Bitset* const self); - - -void -va_bitset_set(VA_Bitset* const self, size_t const index); - - -bool -va_bitset_test(VA_Bitset const* const self, size_t const index); - - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif diff --git a/include/queue.h b/include/queue.h deleted file mode 100644 index d9c12bd..0000000 --- a/include/queue.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef QUEUE_H -#define QUEUE_H - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include // bool -#include // size_t -#include // uint32_t - -#include "alloc.h" // VA_Allocator - - -typedef struct VA_Queue VA_Queue; - - -VA_Queue* -va_queue_init(VA_Allocator const allocator, size_t const capacity); - - -VA_Queue* -va_queue_destroy(VA_Allocator const allocator, VA_Queue* const self); - - -uint32_t -va_queue_dequeue(VA_Queue* const self); - - -bool -va_queue_enqueue(VA_Queue* const self, uint32_t const value); - - -bool -va_queue_is_empty(VA_Queue const* const self); - - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif diff --git a/src/bitset.c b/src/bitset.c deleted file mode 100644 index b49125e..0000000 --- a/src/bitset.c +++ /dev/null @@ -1,69 +0,0 @@ -#include // CHAR_BIT -#include // bool, false -#include // NULL, size_t - -#include "../include/alloc.h" // VA_Allocator -#include "../include/bitset.h" // va_bitset_* - - -struct VA_Bitset -{ - size_t capacity; - size_t data[]; -}; - - -inline VA_Bitset* -va_bitset_init(VA_Allocator const allocator, size_t const capacity) -{ - size_t const size = sizeof((VA_Bitset) {0}.data[0]) * CHAR_BIT; - size_t const slots = (capacity + size - 1) / size; - VA_Bitset* const self = allocator.alloc(allocator.context, NULL, 0, sizeof(*self) + slots * size); // OVERFLOW - if (self == NULL) - { - return NULL; // OOM - } // if - self->capacity = capacity; - for (size_t i = 0; i < slots; ++i) - { - self->data[i] = 0; - } // for - return self; -} // va_bitset_init - - -inline VA_Bitset* -va_bitset_destroy(VA_Allocator const allocator, VA_Bitset* const self) -{ - if (self == NULL) - { - return NULL; - } // if - size_t const size = sizeof(self->data[0]) * CHAR_BIT; - size_t const slots = (self->capacity + size - 1) / size; - return allocator.alloc(allocator.context, self, sizeof(*self) + slots * size, 0); -} // va_bitset_destroy - - -inline void -va_bitset_set(VA_Bitset* const self, size_t const index) -{ - if (self == NULL || self->capacity <= index) - { - return; - } // if - size_t const size = sizeof(self->data[0]) * CHAR_BIT; - self->data[index / size] |= ((size_t) 1) << (index % size); -} // va_bitset_set - - -inline bool -va_bitset_test(VA_Bitset const* const self, size_t const index) -{ - if (self == NULL || self->capacity <= index) - { - return false; - } // if - size_t const size = sizeof(self->data[0]) * CHAR_BIT; - return self->data[index / size] & (((size_t) 1) << (index % size)); -} // va_bitset_test diff --git a/src/edit.c b/src/edit.c index 13dadec..e252374 100644 --- a/src/edit.c +++ b/src/edit.c @@ -276,4 +276,3 @@ va_edit(VA_Allocator const allocator, *lcs_nodes = allocator.alloc(allocator.context, context.lcs_nodes, umin(len_ref, len_obs) * sizeof(*context.lcs_nodes), max_lcs_pos * sizeof(*context.lcs_nodes)); return max_lcs_pos; } // va_edit - diff --git a/src/main.c b/src/main.c index 44abb3e..df0aef4 100644 --- a/src/main.c +++ b/src/main.c @@ -6,9 +6,7 @@ #include "../include/alloc.h" // VA_Allocator #include "../include/array.h" // va_array_* -#include "../include/bitset.h" // VA_Bitset, va_bitset_* #include "../include/edit.h" // va_edit -#include "../include/queue.h" // VA_Queue, va_queue_* #include "../include/std_alloc.h" // va_std_allocator #include "../include/variant.h" // VA_Variant @@ -55,39 +53,6 @@ add_edge(VA_Allocator const allocator, Graph* const graph, size_t const tail, si } // add_edge -static size_t -to_dot(Graph const graph, size_t const len_obs, char const observed[static len_obs]) -{ - (void) observed; - size_t count = 0; - printf("digraph{\nrankdir=LR\nedge[fontname=monospace]\nnode[fixedsize=true,fontname=serif,shape=circle,width=1]\nsi[shape=point,width=.1]\n"); - printf("si->s%u\n", graph.source); - for (size_t i = 0; i < va_array_length(graph.nodes); ++i) - { - if (graph.nodes[i].edges == (uint32_t) -1) - { - // FIXME: always node 0 - printf("s%zu[label=\"(%u, %u, %u)\",peripheries=2]\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length); - } // if - else - { - printf("s%zu[label=\"(%u, %u, %u)\"]\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length); - } // else - - for (uint32_t j = i; j != (uint32_t) -1; j = graph.nodes[j].lambda) - { - for (uint32_t k = graph.nodes[j].edges; k != (uint32_t) -1; k = graph.edges[k].next) - { - printf("s%zu->s%u[label=\"%u:%u/%.*s\"]\n", i, graph.edges[k].tail, graph.edges[k].variant.start, graph.edges[k].variant.end, (int) graph.edges[k].variant.obs_end - graph.edges[k].variant.obs_start, observed + graph.edges[k].variant.obs_start); - count += 1; - } // for - } // for - } // for - printf("}\n"); - return count; -} // to_dot - - static void destroy(VA_Allocator const allocator, Graph* const graph) { @@ -272,121 +237,70 @@ reorder(VA_Allocator const allocator, Graph const graph) static size_t -bfs_traversal(Graph const graph, size_t const len_obs, char const observed[static len_obs]) -{ - (void) observed; - size_t count = 0; - VA_Bitset* scheduled = va_bitset_init(va_std_allocator, va_array_length(graph.nodes)); - VA_Queue* queue = va_queue_init(va_std_allocator, va_array_length(graph.nodes)); - - /* - printf("digraph{\nrankdir=LR\nedge[fontname=monospace]\nnode[fixedsize=true,fontname=serif,shape=circle,width=1]\nsi[shape=point,width=.1]\n"); - printf("si->s%u\n", graph.source); - */ - - va_bitset_set(scheduled, graph.source); - va_queue_enqueue(queue, graph.source); - while (!va_queue_is_empty(queue)) - { - uint32_t const head = va_queue_dequeue(queue); - - /* - if (graph.nodes[head].edges == (uint32_t) -1) - { - printf("s%u[label=\"(%u, %u, %u)\",peripheries=2]\n", head, graph.nodes[head].row, graph.nodes[head].col, graph.nodes[head].length); - } // if - else - { - printf("s%u[label=\"(%u, %u, %u)\"]\n", head, graph.nodes[head].row, graph.nodes[head].col, graph.nodes[head].length); - } // else - */ - - for (uint32_t i = head; i != (uint32_t) -1; i = graph.nodes[i].lambda) - { - if (!va_bitset_test(scheduled, i)) - { - va_bitset_set(scheduled, i); - va_queue_enqueue(queue, i); // OVERFLOW - } // if - for (uint32_t j = graph.nodes[i].edges; j != (uint32_t) -1; j = graph.edges[j].next) - { - count += 1; - //printf("s%u->s%u[label=\"%u:%u/%.*s\"]\n", head, graph.edges[j].tail, graph.edges[j].variant.start, graph.edges[j].variant.end, (int) graph.edges[j].variant.obs_end - graph.edges[j].variant.obs_start, observed + graph.edges[j].variant.obs_start); - if (!va_bitset_test(scheduled, graph.edges[j].tail)) - { - va_bitset_set(scheduled, graph.edges[j].tail); - va_queue_enqueue(queue, graph.edges[j].tail); // OVERFLOW - } // if - } // for - } // for - } // while - - //printf("}\n"); - - queue = va_queue_destroy(va_std_allocator, queue); - scheduled = va_bitset_destroy(va_std_allocator, scheduled); - return count; -} // bfs_traversal - - -static size_t -bfs_traversal_alt(VA_Allocator const allocator, Graph const graph) +bfs_traversal(VA_Allocator const allocator, Graph const graph, size_t const len_obs, char const observed[static len_obs]) { struct { uint32_t depth; uint32_t next; - }* queue = allocator.alloc(allocator.context, NULL, 0, sizeof(*queue) * va_array_length(graph.nodes)); + }* table = allocator.alloc(allocator.context, NULL, 0, sizeof(*table) * va_array_length(graph.nodes)); for (size_t i = 0; i < va_array_length(graph.nodes); ++i) { - queue[i].depth = 0; - queue[i].next = -1; + table[i].depth = 0; + table[i].next = -1; } // for uint32_t head = graph.source; uint32_t tail = graph.source; size_t count = 0; + printf("digraph{\nrankdir=LR\nedge[fontname=monospace]\nnode[fixedsize=true,fontname=serif,shape=circle,width=1]\nsi[shape=point,width=.1]\n"); + printf("si->s%u\n", graph.source); while (head != (uint32_t) -1) { - printf("pop %u\n", head); + //printf("pop %u\n", head); for (uint32_t i = head; i != (uint32_t) -1; i = graph.nodes[i].lambda) { if (i != head) { - printf("lambda %u\n", i); + //printf("lambda %u\n", i); } // if for (uint32_t j = graph.nodes[i].edges; j != (uint32_t) -1; j = graph.edges[j].next) { count += 1; + printf("s%u->s%u[label=\"%u:%u/%.*s\"]\n", head, graph.edges[j].tail, graph.edges[j].variant.start, graph.edges[j].variant.end, (int) graph.edges[j].variant.obs_end - graph.edges[j].variant.obs_start, observed + graph.edges[j].variant.obs_start); - if (queue[graph.edges[j].tail].depth > 0) + if (table[graph.edges[j].tail].depth > 0) { - printf("skip %u\n", graph.edges[j].tail); + //printf("skip %u\n", graph.edges[j].tail); continue; } // if - printf("push %u\n", graph.edges[j].tail); - queue[graph.edges[j].tail].depth = queue[i].depth + 1; - queue[tail].next = graph.edges[j].tail; + //printf("push %u\n", graph.edges[j].tail); + table[graph.edges[j].tail].depth = table[i].depth + 1; + table[tail].next = graph.edges[j].tail; tail = graph.edges[j].tail; } // for } // for - head = queue[head].next; + head = table[head].next; + /* printf(" # \tdepth\tnext\n"); for (size_t i = 0; i < va_array_length(graph.nodes); ++i) { - printf("%3zu:\t%5u\t%4d\n", i, queue[i].depth, queue[i].next); + printf("%3zu:\t%5u\t%4d\n", i, table[i].depth, table[i].next); } // for printf("head: %d\ntail: %d\n", head, tail); + */ } // while - queue = allocator.alloc(allocator.context, queue, sizeof(*queue) * va_array_length(graph.nodes), 0); + printf("}\n"); + + table = allocator.alloc(allocator.context, table, sizeof(*table) * va_array_length(graph.nodes), 0); return count; -} // bfs_traversal_alt +} // bfs_traversal int @@ -426,6 +340,7 @@ main(int argc, char* argv[static argc + 1]) Graph graph = build_graph(va_std_allocator, len_ref, reference, len_obs, observed, len_lcs, lcs_nodes, 0); + /* printf("%zu\n", to_dot(graph, len_obs, observed)); printf("nodes (%zu)\n #\t(row, col, len)\tedges\tlambda\n", va_array_length(graph.nodes)); @@ -438,8 +353,9 @@ main(int argc, char* argv[static argc + 1]) { printf("%3zu:\t%4u\t \"%u:%u/%.*s\"\t%4d\n", i, graph.edges[i].tail, graph.edges[i].variant.start, graph.edges[i].variant.end, (int) graph.edges[i].variant.obs_end - graph.edges[i].variant.obs_start, observed + graph.edges[i].variant.obs_start, (signed) graph.edges[i].next); } // for + */ - printf("%zu\n", bfs_traversal_alt(va_std_allocator, graph)); + printf("%zu\n", bfs_traversal(va_std_allocator, graph, len_obs, observed)); destroy(va_std_allocator, &graph); diff --git a/src/queue.c b/src/queue.c deleted file mode 100644 index 9ddfa1d..0000000 --- a/src/queue.c +++ /dev/null @@ -1,70 +0,0 @@ -#include // bool, false, true -#include // NULL, size_t -#include // uint32_t - -#include "../include/alloc.h" // VA_Allocator -#include "../include/queue.h" // va_queue_* - - -struct VA_Queue -{ - size_t head; - size_t tail; - size_t capacity; - uint32_t data[]; -}; - - -inline VA_Queue* -va_queue_init(VA_Allocator const allocator, size_t const capacity) -{ - VA_Queue* const self = allocator.alloc(allocator.context, NULL, 0, sizeof(*self) + capacity * sizeof(*self->data)); // OVERFLOW - if (self == NULL) - { - return NULL; // OOM - } // if - self->head = 0; - self->tail = 0; - self->capacity = capacity; - return self; -} // va_queue_init - - -inline VA_Queue* -va_queue_destroy(VA_Allocator const allocator, VA_Queue* const self) -{ - return allocator.alloc(allocator.context, self, sizeof(*self) + self->capacity * sizeof(self->data[0]), 0); -} // va_queue_destroy - - -inline uint32_t -va_queue_dequeue(VA_Queue* const self) -{ - if (self->head == self->tail) - { - return -1; // UNDERFLOW - } // if - uint32_t const value = self->data[self->head]; - self->head = (self->head + 1) % self->capacity; - return value; -} // va_queue_dequeue - - -inline bool -va_queue_enqueue(VA_Queue* const self, uint32_t const value) -{ - if ((self->tail + 1) % self->capacity == self->head) - { - return false; // OVERFLOW - } // if - self->data[self->tail] = value; - self->tail = (self->tail + 1) % self->capacity; - return true; -} // va_queue_enqueue - - -inline bool -va_queue_is_empty(VA_Queue const* const self) -{ - return self->head == self->tail; -} // va_queue_is_empty From 9b4b42d57f9fb7823259b978733e51bf43b40688 Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 2 Aug 2024 12:35:05 +0200 Subject: [PATCH 084/704] Added node labels --- src/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main.c b/src/main.c index df0aef4..7c61470 100644 --- a/src/main.c +++ b/src/main.c @@ -262,6 +262,7 @@ bfs_traversal(VA_Allocator const allocator, Graph const graph, size_t const len_ //printf("pop %u\n", head); for (uint32_t i = head; i != (uint32_t) -1; i = graph.nodes[i].lambda) { + printf("s%u[label=\"(%u, %u, %u)\"%s]\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, graph.nodes[i].edges == (uint32_t) -1 ? ",peripheries=2" : ""); if (i != head) { //printf("lambda %u\n", i); From 3fa7892ee6eb2606d3a8cbadd793c711548ab1ed Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 5 Aug 2024 17:08:09 +0200 Subject: [PATCH 085/704] WIP: dfs (pre order) with generator --- src/main.c | 137 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 135 insertions(+), 2 deletions(-) diff --git a/src/main.c b/src/main.c index 7c61470..091a1bd 100644 --- a/src/main.c +++ b/src/main.c @@ -236,6 +236,128 @@ reorder(VA_Allocator const allocator, Graph const graph) } // reorder +static void +to_dot(Graph const graph, size_t const len_obs, char const observed[static len_obs]) +{ + printf("digraph{\nrankdir=LR\nedge[fontname=monospace]\nnode[fixedsize=true,fontname=serif,shape=circle,width=1]\nsi[shape=point,width=.1]\nsi->s%u\n", graph.source); + for (uint32_t i = 0; i < va_array_length(graph.nodes); ++i) + { + printf("s%u[label=\"(%u, %u, %u)\"%s]\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, graph.nodes[i].edges == (uint32_t) -1 ? ",peripheries=2" : ""); + if (graph.nodes[i].lambda != (uint32_t) -1) + { + printf("s%u->s%u[label=\"λ\",style=\"dashed\"]\n", i, graph.nodes[i].lambda); + } // if + for (uint32_t j = graph.nodes[i].edges; j != (uint32_t) -1; j = graph.edges[j].next) + { + printf("s%u->s%u[label=\"%u:%u/%.*s\"]\n", i, graph.edges[j].tail, graph.edges[j].variant.start, graph.edges[j].variant.end, (int) graph.edges[j].variant.obs_end - graph.edges[j].variant.obs_start, observed + graph.edges[j].variant.obs_start); + } // for + } // for + printf("}\n"); +} // to_dot + + +typedef struct +{ + uint32_t head; + uint32_t tail; + uint32_t length; + struct + { + uint32_t depth; + uint32_t next; + } table[]; +} Traversal_Generator; + + +static Traversal_Generator* +traversal_init(VA_Allocator const allocator, Graph const graph) +{ + uint32_t const length = va_array_length(graph.nodes); + Traversal_Generator* const generator = allocator.alloc(allocator.context, NULL, 0, sizeof(*generator) + sizeof(generator->table[0]) * length); + if (generator == NULL) + { + return NULL; + } // if + + for (uint32_t i = 0; i < length; ++i) + { + generator->table[i].depth = 0; + generator->table[i].next = -1; + } // for + generator->head = graph.source; + generator->tail = graph.source; + generator->length = length; + return generator; +} // traversal_init + + +static Traversal_Generator* +traversal_destroy(VA_Allocator const allocator, Traversal_Generator* self) +{ + if (self == NULL) + { + return NULL; + } // if + self = allocator.alloc(allocator.context, self, sizeof(*self) + sizeof(self->table[0]) * self->length, 0); + return self; +} // traversal_destroy + + +static uint32_t +traversal_next(Traversal_Generator* const self, Graph const graph) +{ + if (self == NULL) + { + return -1; + } // if + + uint32_t const head = self->head; + if (head == (uint32_t) -1) + { + return head; + } // if + + self->head = self->table[self->head].next; + + for (uint32_t i = graph.nodes[head].edges; i != (uint32_t) -1; i = graph.edges[i].next) + { + uint32_t const tail = graph.edges[i].tail; + + uint32_t iets = head; + for (uint32_t j = graph.nodes[tail].lambda; j != (uint32_t) -1; j = graph.nodes[j].lambda) + { + if (self->table[j].depth == 0) + { + //printf("push (lambda) %u\n", j); + self->table[j].depth = self->table[head].depth + 1; + self->table[j].next = self->table[iets].next; + self->table[iets].next = j; + iets = j; + } // if + } // for + + if (self->table[tail].depth == 0) + { + //printf("push %u\n", tail); + self->table[tail].depth = self->table[head].depth + 1; + self->table[tail].next = self->table[head].next; + self->table[head].next = tail; + self->head = tail; + } // if + } // for + + /* + printf(" #\tdepth\tnext\n"); + for (uint32_t i = 0; i < self->length; ++i) + { + printf("%2u:\t%5u\t%4d\n", i, self->table[i].depth, self->table[i].next); + } // for + printf("head: %d\ntail: %d\n", self->head, self->tail); + */ + return head; +} // traversal_next + + static size_t bfs_traversal(VA_Allocator const allocator, Graph const graph, size_t const len_obs, char const observed[static len_obs]) { @@ -343,6 +465,7 @@ main(int argc, char* argv[static argc + 1]) /* printf("%zu\n", to_dot(graph, len_obs, observed)); + */ printf("nodes (%zu)\n #\t(row, col, len)\tedges\tlambda\n", va_array_length(graph.nodes)); for (size_t i = 0; i < va_array_length(graph.nodes); ++i) @@ -354,9 +477,19 @@ main(int argc, char* argv[static argc + 1]) { printf("%3zu:\t%4u\t \"%u:%u/%.*s\"\t%4d\n", i, graph.edges[i].tail, graph.edges[i].variant.start, graph.edges[i].variant.end, (int) graph.edges[i].variant.obs_end - graph.edges[i].variant.obs_start, observed + graph.edges[i].variant.obs_start, (signed) graph.edges[i].next); } // for - */ - printf("%zu\n", bfs_traversal(va_std_allocator, graph, len_obs, observed)); + //printf("%zu\n", bfs_traversal(va_std_allocator, graph, len_obs, observed)); + + to_dot(graph, len_obs, observed); + + Traversal_Generator* gen = traversal_init(va_std_allocator, graph); + uint32_t node = traversal_next(gen, graph); + while (node != (uint32_t) -1) + { + printf("yield: %u\n", node); + node = traversal_next(gen, graph); + } // if + gen = traversal_destroy(va_std_allocator, gen); destroy(va_std_allocator, &graph); From 82538e23833ae47c03572fe5616d1b8777677aed Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 6 Aug 2024 16:19:03 +0200 Subject: [PATCH 086/704] WIP: recursive local supremal --- src/main.c | 115 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 113 insertions(+), 2 deletions(-) diff --git a/src/main.c b/src/main.c index 091a1bd..415588e 100644 --- a/src/main.c +++ b/src/main.c @@ -256,6 +256,115 @@ to_dot(Graph const graph, size_t const len_obs, char const observed[static len_o } // to_dot +typedef struct +{ + uint32_t post; + uint32_t rank; + uint32_t start; + uint32_t end; +} Post_Dom_Table; + + +static uint32_t +intersection(uint32_t lhs, uint32_t rhs, uint32_t const length, Post_Dom_Table const visited[static length]) +{ + while (lhs != rhs) + { + while (visited[lhs].rank > visited[rhs].rank) + { + lhs = visited[lhs].post; + } // while + while (visited[rhs].rank > visited[lhs].rank) + { + rhs = visited[rhs].post; + } // while + } // while + return lhs; +} // intersection + + +#define MAX(lhs, rhs) (lhs) > (rhs) ? (lhs) : (rhs) +#define MIN(lhs, rhs) (lhs) < (rhs) ? (lhs) : (rhs) + + +static void +post_dominators(Graph const graph, uint32_t const head, uint32_t* const rank, uint32_t const start, uint32_t const length, Post_Dom_Table visited[static length]) +{ + visited[head].post = -1; + visited[head].start = start; + visited[head].end = -1; + if (graph.nodes[head].lambda != (uint32_t) -1 && visited[graph.nodes[head].lambda].rank == (uint32_t) -1) + { + post_dominators(graph, graph.nodes[head].lambda, rank, start, length, visited); + visited[head].post = graph.nodes[head].lambda; + } // if + + for (uint32_t i = graph.nodes[head].edges; i != (uint32_t) -1; i = graph.edges[i].next) + { + if (visited[graph.edges[i].tail].rank == (uint32_t) -1) + { + post_dominators(graph, graph.edges[i].tail, rank, graph.edges[i].variant.end, length, visited); + } // if + else + { + visited[graph.edges[i].tail].start = MAX(visited[graph.edges[i].tail].start, graph.edges[i].variant.end); + } // else + + if (visited[head].post == (uint32_t) -1) + { + visited[head].post = graph.edges[i].tail; + visited[head].end = graph.edges[i].variant.start; + } // if + else + { + visited[head].post = intersection(visited[head].post, graph.edges[i].tail, length, visited); + visited[head].end = MIN(visited[head].end, graph.edges[i].variant.start); + } // else + } // for + + visited[head].rank = *rank; + *rank += 1; + printf("visit %u (%u): %d\n", head, visited[head].rank, visited[head].post); +} // post_dominators + + +static void +local_supremal(VA_Allocator const allocator, Graph const graph, size_t const len_obs, char const observed[static len_obs]) +{ + uint32_t const length = va_array_length(graph.nodes); + Post_Dom_Table* visited = allocator.alloc(allocator.context, NULL, 0, sizeof(*visited) * length); + if (visited == NULL) + { + return; + } // if + + for (uint32_t i = 0; i < length; ++i) + { + visited[i].rank = -1; + } // for + + post_dominators(graph, graph.source, &(uint32_t) {0}, 0, length, visited); + + printf(" # \tpost\trank\tstart\tend\n"); + for (uint32_t i = 0; i < length; ++i) + { + printf("%2u:\t%4d\t%4u\t%5u\t%3d\n", i, visited[i].post, visited[i].rank, visited[i].start, visited[i].end); + } // for + + uint32_t head = graph.source; + uint32_t shift = 0; + for (uint32_t tail = visited[head].post; tail != (uint32_t) -1; head = tail, tail = visited[head].post) + { + uint32_t const start = visited[head].end; + uint32_t const end = visited[tail].start; + VA_Variant const variant = {start, end, graph.nodes[head].col + start - graph.nodes[head].row - shift, graph.nodes[tail].col + end - graph.nodes[tail].row - shift}; + printf("%u:%u/%.*s\n", variant.start, variant.end, (int) variant.obs_end - variant.obs_start, observed + variant.obs_start); + } // for + + visited = allocator.alloc(allocator.context, visited, sizeof(*visited) * length, 0); +} // local_supremal + + typedef struct { uint32_t head; @@ -317,8 +426,6 @@ traversal_next(Traversal_Generator* const self, Graph const graph) return head; } // if - self->head = self->table[self->head].next; - for (uint32_t i = graph.nodes[head].edges; i != (uint32_t) -1; i = graph.edges[i].next) { uint32_t const tail = graph.edges[i].tail; @@ -482,6 +589,7 @@ main(int argc, char* argv[static argc + 1]) to_dot(graph, len_obs, observed); +/* Traversal_Generator* gen = traversal_init(va_std_allocator, graph); uint32_t node = traversal_next(gen, graph); while (node != (uint32_t) -1) @@ -490,6 +598,9 @@ main(int argc, char* argv[static argc + 1]) node = traversal_next(gen, graph); } // if gen = traversal_destroy(va_std_allocator, gen); +*/ + + local_supremal(va_std_allocator, graph, len_obs, observed); destroy(va_std_allocator, &graph); From b201fb3dbf207891f586412248c3e206f0a55bbd Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 6 Aug 2024 20:50:28 +0200 Subject: [PATCH 087/704] WIP: iterative post order traversal --- src/main.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/src/main.c b/src/main.c index 415588e..0dbacab 100644 --- a/src/main.c +++ b/src/main.c @@ -262,6 +262,10 @@ typedef struct uint32_t rank; uint32_t start; uint32_t end; + + + uint32_t edge; + uint32_t next; } Post_Dom_Table; @@ -365,6 +369,70 @@ local_supremal(VA_Allocator const allocator, Graph const graph, size_t const len } // local_supremal +static void +local_supremal_it(VA_Allocator const allocator, Graph const graph) +{ + uint32_t const length = va_array_length(graph.nodes); + Post_Dom_Table* visited = allocator.alloc(allocator.context, NULL, 0, sizeof(*visited) * length); + if (visited == NULL) + { + return; + } // if + + for (uint32_t i = 0; i < length; ++i) + { + visited[i].edge = -1; + visited[i].next = -1; + } // for + + uint32_t head = graph.source; + visited[head].edge = graph.nodes[head].edges; + + while (head != (uint32_t) -1) + { + uint32_t edge = visited[head].edge; + if (edge == (uint32_t) -1) + { + printf("visit %u\n", head); + head = visited[head].next; + } // if + else + { + uint32_t const lambda = graph.nodes[head].lambda; + if (visited[head].edge == graph.nodes[head].edges && + lambda != (uint32_t) -1 && visited[lambda].next == (uint32_t) -1) + { + visited[lambda].next = head; + visited[lambda].edge = graph.nodes[lambda].edges; + head = lambda; + continue; + } // if + + visited[head].edge = graph.edges[edge].next; + while (edge != (uint32_t) -1) + { + uint32_t const tail = graph.edges[edge].tail; + + if (visited[tail].next == (uint32_t) -1) + { + visited[tail].next = head; + visited[tail].edge = graph.nodes[tail].edges; + head = tail; + break; + } // if + edge = graph.edges[edge].next; + } // while + } // else + } // while + + visited = allocator.alloc(allocator.context, visited, sizeof(*visited) * length, 0); +} // local_supremal_it + +// AAAATA GAAAAGAAA +// AAT ACT +// AGAATTGCTTGAA AGGGTTAAA + + typedef struct { uint32_t head; @@ -601,6 +669,7 @@ main(int argc, char* argv[static argc + 1]) */ local_supremal(va_std_allocator, graph, len_obs, observed); + local_supremal_it(va_std_allocator, graph); destroy(va_std_allocator, &graph); From 253ec535b0bff54d6efed9d9cca0d6cf2b2583d4 Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 7 Aug 2024 16:34:06 +0200 Subject: [PATCH 088/704] WIP: iterative local supremals (post dom sets without lambda) --- src/main.c | 142 ++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 119 insertions(+), 23 deletions(-) diff --git a/src/main.c b/src/main.c index 0dbacab..cf2f731 100644 --- a/src/main.c +++ b/src/main.c @@ -272,6 +272,10 @@ typedef struct static uint32_t intersection(uint32_t lhs, uint32_t rhs, uint32_t const length, Post_Dom_Table const visited[static length]) { + if (lhs == (uint32_t) -1) + { + return rhs; + } // if while (lhs != rhs) { while (visited[lhs].rank > visited[rhs].rank) @@ -381,10 +385,12 @@ local_supremal_it(VA_Allocator const allocator, Graph const graph) for (uint32_t i = 0; i < length; ++i) { + visited[i].post = -1; visited[i].edge = -1; visited[i].next = -1; } // for + uint32_t rank = 0; uint32_t head = graph.source; visited[head].edge = graph.nodes[head].edges; @@ -394,39 +400,129 @@ local_supremal_it(VA_Allocator const allocator, Graph const graph) if (edge == (uint32_t) -1) { printf("visit %u\n", head); + visited[head].rank = rank; + rank += 1; head = visited[head].next; + continue; } // if - else + + uint32_t const lambda = graph.nodes[head].lambda; + if (visited[head].edge == graph.nodes[head].edges && + lambda != (uint32_t) -1 && visited[lambda].next == (uint32_t) -1) { - uint32_t const lambda = graph.nodes[head].lambda; - if (visited[head].edge == graph.nodes[head].edges && - lambda != (uint32_t) -1 && visited[lambda].next == (uint32_t) -1) + visited[head].post = lambda; + + visited[lambda].next = head; + visited[lambda].edge = graph.nodes[lambda].edges; + head = lambda; + continue; + } // if + + visited[head].edge = graph.edges[edge].next; + while (edge != (uint32_t) -1) + { + uint32_t const tail = graph.edges[edge].tail; + if (visited[tail].next == (uint32_t) -1) { - visited[lambda].next = head; - visited[lambda].edge = graph.nodes[lambda].edges; - head = lambda; - continue; + visited[tail].next = head; + visited[tail].edge = graph.nodes[tail].edges; + head = tail; + break; } // if + edge = graph.edges[edge].next; + } // while + } // while - visited[head].edge = graph.edges[edge].next; - while (edge != (uint32_t) -1) - { - uint32_t const tail = graph.edges[edge].tail; + printf(" # \tpost\trank\n"); + for (uint32_t i = 0; i < length; ++i) + { + printf("%2u:\t%4d\t%4u\n", i, visited[i].post, visited[i].rank); + } // for - if (visited[tail].next == (uint32_t) -1) - { - visited[tail].next = head; - visited[tail].edge = graph.nodes[tail].edges; - head = tail; - break; - } // if - edge = graph.edges[edge].next; - } // while + visited = allocator.alloc(allocator.context, visited, sizeof(*visited) * length, 0); +} // local_supremal_it + + +static void +local_supremal_it2(VA_Allocator const allocator, Graph const graph) +{ + uint32_t const length = va_array_length(graph.nodes); + Post_Dom_Table* visited = allocator.alloc(allocator.context, NULL, 0, sizeof(*visited) * length); + if (visited == NULL) + { + return; + } // if + + for (uint32_t i = 0; i < length; ++i) + { + visited[i].post = -1; + visited[i].rank = -1; + visited[i].edge = -1; + visited[i].next = -1; + } // for + + uint32_t rank = 0; + uint32_t head = graph.source; + + while (head != (uint32_t) -1) + { +next: + printf(" # \tpost\trank\tedge\tnext\n"); + for (uint32_t i = 0; i < length; ++i) + { + printf("%2u:\t%4d\t%4d\t%4d\t%4d\n", i, visited[i].post, visited[i].rank, visited[i].edge, visited[i].next); + } // for + printf("head: %d\n", head); + + if (visited[head].post == (uint32_t) -1) + { + printf("first time\n"); + visited[head].edge = graph.nodes[head].edges; + visited[head].post = -1; + } // if + else + { + uint32_t const post = intersection(visited[head].post, graph.edges[visited[head].edge].tail, length, visited); + printf("intersection %u & %u = %u\n", visited[head].post, graph.edges[visited[head].edge].tail, post); + visited[head].post = post; + visited[head].edge = graph.edges[visited[head].edge].next; } // else + + uint32_t edge = visited[head].edge; + while (edge != (uint32_t) -1) + { + uint32_t const tail = graph.edges[edge].tail; + printf("look at %d\n", tail); + if (visited[tail].next == (uint32_t) -1) + { + printf("push %u\n", tail); + visited[tail].next = head; + head = tail; + goto next; + } // if + uint32_t const post = intersection(visited[head].post, graph.edges[edge].tail, length, visited); + printf("intersection %u & %u = %u\n", visited[head].post, graph.edges[edge].tail, post); + visited[head].post = post; + edge = graph.edges[edge].next; + } // while + + printf("visit %u\n", head); + visited[head].rank = rank; + rank += 1; + head = visited[head].next; } // while + printf(" # \tpost\trank\tedge\tnext\n"); + for (uint32_t i = 0; i < length; ++i) + { + printf("%2u:\t%4d\t%4d\t%4d\t%4d\n", i, visited[i].post, visited[i].rank, visited[i].edge, visited[i].next); + } // for + printf("head: %d\n", head); + + visited = allocator.alloc(allocator.context, visited, sizeof(*visited) * length, 0); -} // local_supremal_it +} // local_supremal_it2 + // AAAATA GAAAAGAAA // AAT ACT @@ -669,7 +765,7 @@ main(int argc, char* argv[static argc + 1]) */ local_supremal(va_std_allocator, graph, len_obs, observed); - local_supremal_it(va_std_allocator, graph); + local_supremal_it2(va_std_allocator, graph); destroy(va_std_allocator, &graph); From 55ad48319069f6ca0653524fc7dfba8151a744eb Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 9 Aug 2024 11:09:10 +0200 Subject: [PATCH 089/704] WIP: iterative local supremal --- src/main.c | 114 ++++++++++------------------------------------------- 1 file changed, 21 insertions(+), 93 deletions(-) diff --git a/src/main.c b/src/main.c index cf2f731..3de7ea3 100644 --- a/src/main.c +++ b/src/main.c @@ -262,8 +262,6 @@ typedef struct uint32_t rank; uint32_t start; uint32_t end; - - uint32_t edge; uint32_t next; } Post_Dom_Table; @@ -386,8 +384,9 @@ local_supremal_it(VA_Allocator const allocator, Graph const graph) for (uint32_t i = 0; i < length; ++i) { visited[i].post = -1; - visited[i].edge = -1; visited[i].next = -1; + visited[i].start = 0; + visited[i].end = -1; } // for uint32_t rank = 0; @@ -396,10 +395,11 @@ local_supremal_it(VA_Allocator const allocator, Graph const graph) while (head != (uint32_t) -1) { + //printf("enter %u\n", head); uint32_t edge = visited[head].edge; if (edge == (uint32_t) -1) { - printf("visit %u\n", head); + //printf("visit %u\n", head); visited[head].rank = rank; rank += 1; head = visited[head].next; @@ -407,121 +407,47 @@ local_supremal_it(VA_Allocator const allocator, Graph const graph) } // if uint32_t const lambda = graph.nodes[head].lambda; - if (visited[head].edge == graph.nodes[head].edges && - lambda != (uint32_t) -1 && visited[lambda].next == (uint32_t) -1) + if (lambda != (uint32_t) -1 && visited[lambda].next == (uint32_t) -1) { - visited[head].post = lambda; - + visited[head].post = intersection(visited[head].post, lambda, length, visited); visited[lambda].next = head; visited[lambda].edge = graph.nodes[lambda].edges; head = lambda; continue; } // if - visited[head].edge = graph.edges[edge].next; - while (edge != (uint32_t) -1) - { - uint32_t const tail = graph.edges[edge].tail; - if (visited[tail].next == (uint32_t) -1) - { - visited[tail].next = head; - visited[tail].edge = graph.nodes[tail].edges; - head = tail; - break; - } // if - edge = graph.edges[edge].next; - } // while - } // while - - printf(" # \tpost\trank\n"); - for (uint32_t i = 0; i < length; ++i) - { - printf("%2u:\t%4d\t%4u\n", i, visited[i].post, visited[i].rank); - } // for - - visited = allocator.alloc(allocator.context, visited, sizeof(*visited) * length, 0); -} // local_supremal_it - - -static void -local_supremal_it2(VA_Allocator const allocator, Graph const graph) -{ - uint32_t const length = va_array_length(graph.nodes); - Post_Dom_Table* visited = allocator.alloc(allocator.context, NULL, 0, sizeof(*visited) * length); - if (visited == NULL) - { - return; - } // if - - for (uint32_t i = 0; i < length; ++i) - { - visited[i].post = -1; - visited[i].rank = -1; - visited[i].edge = -1; - visited[i].next = -1; - } // for - - uint32_t rank = 0; - uint32_t head = graph.source; + //printf("intersection %d, %u\n", visited[head].post, graph.edges[edge].tail); + visited[head].post = intersection(visited[head].post, graph.edges[edge].tail, length, visited); - while (head != (uint32_t) -1) - { -next: - printf(" # \tpost\trank\tedge\tnext\n"); - for (uint32_t i = 0; i < length; ++i) + if (visited[graph.edges[edge].tail].next != (uint32_t) -1) { - printf("%2u:\t%4d\t%4d\t%4d\t%4d\n", i, visited[i].post, visited[i].rank, visited[i].edge, visited[i].next); - } // for - printf("head: %d\n", head); - - if (visited[head].post == (uint32_t) -1) - { - printf("first time\n"); - visited[head].edge = graph.nodes[head].edges; - visited[head].post = -1; + visited[head].edge = graph.edges[edge].next; } // if - else - { - uint32_t const post = intersection(visited[head].post, graph.edges[visited[head].edge].tail, length, visited); - printf("intersection %u & %u = %u\n", visited[head].post, graph.edges[visited[head].edge].tail, post); - visited[head].post = post; - visited[head].edge = graph.edges[visited[head].edge].next; - } // else - - uint32_t edge = visited[head].edge; while (edge != (uint32_t) -1) { uint32_t const tail = graph.edges[edge].tail; - printf("look at %d\n", tail); + visited[head].end = MIN(visited[head].end, graph.edges[edge].variant.start); + visited[tail].start = MAX(visited[tail].start, graph.edges[edge].variant.end); if (visited[tail].next == (uint32_t) -1) { - printf("push %u\n", tail); visited[tail].next = head; + visited[tail].edge = graph.nodes[tail].edges; head = tail; - goto next; + break; } // if - uint32_t const post = intersection(visited[head].post, graph.edges[edge].tail, length, visited); - printf("intersection %u & %u = %u\n", visited[head].post, graph.edges[edge].tail, post); - visited[head].post = post; + visited[head].post = intersection(visited[head].post, tail, length, visited); edge = graph.edges[edge].next; } // while - - printf("visit %u\n", head); - visited[head].rank = rank; - rank += 1; - head = visited[head].next; } // while - printf(" # \tpost\trank\tedge\tnext\n"); + printf(" # \tpost\trank\tstart\tend\n"); for (uint32_t i = 0; i < length; ++i) { - printf("%2u:\t%4d\t%4d\t%4d\t%4d\n", i, visited[i].post, visited[i].rank, visited[i].edge, visited[i].next); + printf("%2u:\t%4d\t%4u\t%5u\t%3d\n", i, visited[i].post, visited[i].rank, visited[i].start, visited[i].end); } // for - printf("head: %d\n", head); - visited = allocator.alloc(allocator.context, visited, sizeof(*visited) * length, 0); -} // local_supremal_it2 +} // local_supremal_it // AAAATA GAAAAGAAA @@ -765,7 +691,9 @@ main(int argc, char* argv[static argc + 1]) */ local_supremal(va_std_allocator, graph, len_obs, observed); - local_supremal_it2(va_std_allocator, graph); + + printf("\n\n**** ITERATIVE ****\n"); + local_supremal_it(va_std_allocator, graph); destroy(va_std_allocator, &graph); From e2ff4faffdebe871881844e7c2cbe57637f3f531 Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 9 Aug 2024 11:11:21 +0200 Subject: [PATCH 090/704] WIP: local supremals --- src/main.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/main.c b/src/main.c index 3de7ea3..c34977f 100644 --- a/src/main.c +++ b/src/main.c @@ -372,7 +372,7 @@ local_supremal(VA_Allocator const allocator, Graph const graph, size_t const len static void -local_supremal_it(VA_Allocator const allocator, Graph const graph) +local_supremal_it(VA_Allocator const allocator, Graph const graph, size_t const len_obs, char const observed[static len_obs]) { uint32_t const length = va_array_length(graph.nodes); Post_Dom_Table* visited = allocator.alloc(allocator.context, NULL, 0, sizeof(*visited) * length); @@ -446,6 +446,16 @@ local_supremal_it(VA_Allocator const allocator, Graph const graph) printf("%2u:\t%4d\t%4u\t%5u\t%3d\n", i, visited[i].post, visited[i].rank, visited[i].start, visited[i].end); } // for + head = graph.source; + uint32_t shift = 0; + for (uint32_t tail = visited[head].post; tail != (uint32_t) -1; head = tail, tail = visited[head].post) + { + uint32_t const start = visited[head].end; + uint32_t const end = visited[tail].start; + VA_Variant const variant = {start, end, graph.nodes[head].col + start - graph.nodes[head].row - shift, graph.nodes[tail].col + end - graph.nodes[tail].row - shift}; + printf("%u:%u/%.*s\n", variant.start, variant.end, (int) variant.obs_end - variant.obs_start, observed + variant.obs_start); + } // for + visited = allocator.alloc(allocator.context, visited, sizeof(*visited) * length, 0); } // local_supremal_it @@ -691,9 +701,7 @@ main(int argc, char* argv[static argc + 1]) */ local_supremal(va_std_allocator, graph, len_obs, observed); - - printf("\n\n**** ITERATIVE ****\n"); - local_supremal_it(va_std_allocator, graph); + local_supremal_it(va_std_allocator, graph, len_obs, observed); destroy(va_std_allocator, &graph); From e7e418b454ad05f3d0b18062c1a0341013f7fcb7 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 13 Aug 2024 13:54:38 +0200 Subject: [PATCH 091/704] WIP: LCS graph / supremal / local supremal checked against Python --- src/main.c | 505 ++++++++++++++++++++++------------------------------- 1 file changed, 206 insertions(+), 299 deletions(-) diff --git a/src/main.c b/src/main.c index c34977f..3dd59b8 100644 --- a/src/main.c +++ b/src/main.c @@ -11,6 +11,10 @@ #include "../include/variant.h" // VA_Variant +#define MAX(lhs, rhs) (lhs) > (rhs) ? (lhs) : (rhs) +#define MIN(lhs, rhs) (lhs) < (rhs) ? (lhs) : (rhs) + + typedef struct { uint32_t tail; @@ -33,6 +37,7 @@ typedef struct { Node* nodes; Edge* edges; + VA_Variant supremal; uint32_t source; } Graph; @@ -53,7 +58,7 @@ add_edge(VA_Allocator const allocator, Graph* const graph, size_t const tail, si } // add_edge -static void +static inline void destroy(VA_Allocator const allocator, Graph* const graph) { graph->nodes = va_array_destroy(allocator, graph->nodes); @@ -61,72 +66,28 @@ destroy(VA_Allocator const allocator, Graph* const graph) } // destroy -static size_t -doit(VA_Allocator const allocator, Graph* const graph, VA_LCS_Node const tail, VA_LCS_Node* const heads, size_t const lcs_idx, size_t const shift) -{ - size_t idx = 0; - for (size_t i = 0; i < va_array_length(heads); ++i) - { - if (heads[i].row + heads[i].length < tail.row + tail.length && heads[i].col + heads[i].length < tail.col + tail.length) - { - VA_Variant const variant = {heads[i].row + heads[i].length, tail.row + tail.length - 1, heads[i].col + heads[i].length - shift, tail.col + tail.length - 1 - shift}; - //printf("(%u, %u, %u) -> (%u, %u, %u)\n", heads[i].row, heads[i].col, heads[i].length, tail.row, tail.col, tail.length); - - if (heads[i].incoming == lcs_idx) - { - //printf("SPLIT: (%u, %u, %u)\n", heads[i].row, heads[i].col, heads[i].length); - size_t const split_idx = heads[i].idx; - heads[i].idx = add_node(allocator, graph, heads[i].row, heads[i].col, graph->nodes[split_idx].length); - heads[i].incoming = 0; - - // lambda-edge - graph->nodes[heads[i].idx].lambda = split_idx; - - graph->nodes[heads[i].idx].edges = add_edge(allocator, graph, tail.idx, graph->nodes[heads[i].idx].edges , variant); - - graph->nodes[split_idx].row += heads[i].length; - graph->nodes[split_idx].col += heads[i].length; - graph->nodes[split_idx].length -= heads[i].length; - } // if - else - { - if (heads[i].idx == (uint32_t) -1) - { - heads[i].idx = add_node(allocator, graph, heads[i].row, heads[i].col, heads[i].length); - } // if - graph->nodes[heads[i].idx].edges = add_edge(allocator, graph, tail.idx, graph->nodes[heads[i].idx].edges, variant); - } // else - idx = i + 1; - } // if - } // for - return idx; -} // doit - - static Graph build_graph(VA_Allocator const allocator, - size_t const len_ref, char const reference[static len_ref], - size_t const len_obs, char const observed[static len_obs], + size_t const len_ref, size_t const len_obs, size_t const len_lcs, VA_LCS_Node* lcs_nodes[static len_lcs], size_t const shift) { - (void) reference; - (void) observed; - - Graph graph = { - //va_array_init(allocator, 256 * len_lcs, sizeof(*graph.nodes)), // FIXME: we know the number of lcs nodes - NULL, - NULL, - 0, - }; + Graph graph = {.nodes = NULL, .edges = NULL}; if (len_lcs == 0 || lcs_nodes == NULL) { - return graph; // FIXME: create default graph + graph.source = add_node(allocator, &graph, shift, shift, 0); + if (len_ref == 0 && len_obs == 0) + { + graph.supremal = (VA_Variant) {0, 0, 0, 0}; + return graph; + } // if + uint32_t const sink = add_node(allocator, &graph, len_ref, len_obs, 0); + graph.supremal = (VA_Variant) {shift, shift + len_ref, 0, len_obs}; + graph.nodes[graph.source].edges = add_edge(allocator, &graph, sink, -1, graph.supremal); + return graph; } // if - //printf("%zu\n", len_lcs); - VA_LCS_Node sink = lcs_nodes[len_lcs - 1][va_array_length(lcs_nodes[len_lcs - 1]) - 1]; if (sink.row + sink.length == len_ref + shift && sink.col + sink.length == len_obs + shift) { @@ -138,10 +99,22 @@ build_graph(VA_Allocator const allocator, sink = (VA_LCS_Node) {.row = len_ref + shift, .col = len_obs + shift, .length = 1}; } // else - //printf("sink: (%u, %u, %u)\n", sink.row, sink.col, sink.length); - + uint32_t max_sink = 0; sink.idx = add_node(allocator, &graph, sink.row, sink.col, sink.length - 1); - size_t const here = doit(allocator, &graph, sink, lcs_nodes[len_lcs - 1], len_lcs - 1, shift); + size_t here = 0; + VA_LCS_Node* const heads = lcs_nodes[len_lcs - 1]; + for (size_t i = 0; i < va_array_length(heads); ++i) + { + if (heads[i].row + heads[i].length < sink.row + sink.length && heads[i].col + heads[i].length < sink.col + sink.length) + { + VA_Variant const variant = {heads[i].row + heads[i].length, sink.row + sink.length - 1, heads[i].col + heads[i].length - shift, sink.col + sink.length - 1 - shift}; + max_sink = MAX(max_sink, sink.row + sink.length - 1); + heads[i].idx = add_node(allocator, &graph, heads[i].row, heads[i].col, heads[i].length); + graph.nodes[heads[i].idx].edges = add_edge(allocator, &graph, sink.idx, graph.nodes[heads[i].idx].edges, variant); + here = i + 1; + } // if + } // for + if (sink.length > 1) { sink.length -= 1; @@ -151,14 +124,50 @@ build_graph(VA_Allocator const allocator, for (size_t i = len_lcs - 1; i >= 1; --i) { - //printf("idx %zu\n", i); for (size_t j = 0; j < va_array_length(lcs_nodes[i]); ++j) { if (lcs_nodes[i][j].idx == (uint32_t) -1) { continue; } // if - size_t const here = doit(allocator, &graph, lcs_nodes[i][j], lcs_nodes[i - 1], i, shift); + + here = 0; + VA_LCS_Node const tail = lcs_nodes[i][j]; + VA_LCS_Node* const heads = lcs_nodes[i - 1]; + for (size_t k = 0; k < va_array_length(heads); ++k) + { + if (heads[k].row + heads[k].length < tail.row + tail.length && heads[k].col + heads[k].length < tail.col + tail.length) + { + VA_Variant const variant = {heads[k].row + heads[k].length, tail.row + tail.length - 1, heads[k].col + heads[k].length - shift, tail.col + tail.length - 1 - shift}; + max_sink = MAX(max_sink, tail.row + tail.length - 1); + + if (heads[k].incoming == i) + { + size_t const split_idx = heads[k].idx; + heads[k].idx = add_node(allocator, &graph, heads[k].row, heads[k].col, graph.nodes[split_idx].length); + heads[k].incoming = 0; + + // lambda-edge + graph.nodes[heads[k].idx].lambda = split_idx; + + graph.nodes[heads[k].idx].edges = add_edge(allocator, &graph, tail.idx, graph.nodes[heads[k].idx].edges, variant); + + graph.nodes[split_idx].row += heads[k].length; + graph.nodes[split_idx].col += heads[k].length; + graph.nodes[split_idx].length -= heads[k].length; + } // if + else + { + if (heads[k].idx == (uint32_t) -1) + { + heads[k].idx = add_node(allocator, &graph, heads[k].row, heads[k].col, heads[k].length); + } // if + graph.nodes[heads[k].idx].edges = add_edge(allocator, &graph, tail.idx, graph.nodes[heads[k].idx].edges, variant); + } // else + here = k + 1; + } // if + } // for + if (lcs_nodes[i][j].length > 1) { lcs_nodes[i][j].length -= 1; @@ -174,11 +183,9 @@ build_graph(VA_Allocator const allocator, VA_LCS_Node source = lcs_nodes[0][0]; - //printf("source: (%u, %u, %u)\n", source.row, source.col, source.length); size_t start = 0; if (source.row == shift && source.col == shift) { - // assert source.idx != 0 start = 1; } // if else @@ -197,62 +204,49 @@ build_graph(VA_Allocator const allocator, if (source.row < lcs_nodes[0][i].row + lcs_nodes[0][i].length && source.col < lcs_nodes[0][i].col + lcs_nodes[0][i].length) { VA_Variant const variant = {source.row, lcs_nodes[0][i].row + lcs_nodes[0][i].length - 1, source.col - shift, lcs_nodes[0][i].col + lcs_nodes[0][i].length - 1 - shift}; - //printf("(%u, %u, %u) -> (%u, %u, %u)\n", source.row, source.col, source.length, lcs_nodes[0][i].row, lcs_nodes[0][i].col, lcs_nodes[0][i].length); + max_sink = MAX(max_sink, lcs_nodes[0][i].row + lcs_nodes[0][i].length - 1); graph.nodes[source.idx].edges = add_edge(allocator, &graph, lcs_nodes[0][i].idx, graph.nodes[source.idx].edges, variant); } // if } // for lcs_nodes[0] = va_array_destroy(allocator, lcs_nodes[0]); - lcs_nodes = allocator.alloc(allocator.context, lcs_nodes, len_lcs * sizeof(*lcs_nodes), 0); + uint32_t min_source = max_sink; + for (uint32_t i = graph.nodes[source.idx].edges; i != (uint32_t) -1; i = graph.edges[i].next) + { + min_source = MIN(min_source, graph.edges[i].variant.start); + } // for + uint32_t const min_offset = min_source - graph.nodes[source.idx].row; + + graph.nodes[source.idx].row += min_offset; + graph.nodes[source.idx].col += min_offset; + graph.nodes[source.idx].length -= min_offset; + graph.nodes[sink.idx].length -= graph.nodes[sink.idx].row + graph.nodes[sink.idx].length - max_sink; + + graph.supremal = (VA_Variant) {min_source, max_sink, graph.nodes[source.idx].col - shift, graph.nodes[sink.idx].col + graph.nodes[sink.idx].length - shift}; graph.source = source.idx; return graph; } // build_graph -static Graph -reorder(VA_Allocator const allocator, Graph const graph) -{ - Graph new_graph = - { - va_array_init(allocator, va_array_length(graph.nodes), sizeof(*new_graph.nodes)), - va_array_init(allocator, va_array_length(graph.edges), sizeof(*new_graph.edges)), - graph.source, - }; - - for (size_t i = 0; i < va_array_length(graph.nodes); ++i) - { - add_node(allocator, &new_graph, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length); - - new_graph.nodes[i].lambda = graph.nodes[i].lambda; - new_graph.nodes[i].edges = -1; - for (uint32_t j = graph.nodes[i].edges; j != (uint32_t) -1; j = graph.edges[j].next) - { - new_graph.nodes[i].edges = add_edge(allocator, &new_graph, graph.edges[j].tail, new_graph.nodes[i].edges, graph.edges[j].variant); - } // for - } // for - return new_graph; -} // reorder - - static void to_dot(Graph const graph, size_t const len_obs, char const observed[static len_obs]) { - printf("digraph{\nrankdir=LR\nedge[fontname=monospace]\nnode[fixedsize=true,fontname=serif,shape=circle,width=1]\nsi[shape=point,width=.1]\nsi->s%u\n", graph.source); + fprintf(stderr, "digraph{\nrankdir=LR\nedge[fontname=monospace]\nnode[fixedsize=true,fontname=serif,shape=circle,width=1]\nsi[shape=point,width=.1]\nsi->s%u\n", graph.source); for (uint32_t i = 0; i < va_array_length(graph.nodes); ++i) { - printf("s%u[label=\"(%u, %u, %u)\"%s]\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, graph.nodes[i].edges == (uint32_t) -1 ? ",peripheries=2" : ""); + fprintf(stderr, "s%u[label=\"(%u, %u, %u)\"%s]\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, graph.nodes[i].edges == (uint32_t) -1 ? ",peripheries=2" : ""); if (graph.nodes[i].lambda != (uint32_t) -1) { - printf("s%u->s%u[label=\"λ\",style=\"dashed\"]\n", i, graph.nodes[i].lambda); + fprintf(stderr, "s%u->s%u[label=\"λ\",style=\"dashed\"]\n", i, graph.nodes[i].lambda); } // if for (uint32_t j = graph.nodes[i].edges; j != (uint32_t) -1; j = graph.edges[j].next) { - printf("s%u->s%u[label=\"%u:%u/%.*s\"]\n", i, graph.edges[j].tail, graph.edges[j].variant.start, graph.edges[j].variant.end, (int) graph.edges[j].variant.obs_end - graph.edges[j].variant.obs_start, observed + graph.edges[j].variant.obs_start); + fprintf(stderr, "s%u->s%u[label=\"%u:%u/%.*s\"]\n", i, graph.edges[j].tail, graph.edges[j].variant.start, graph.edges[j].variant.end, (int) graph.edges[j].variant.obs_end - graph.edges[j].variant.obs_start, observed + graph.edges[j].variant.obs_start); } // for } // for - printf("}\n"); + fprintf(stderr, "}\n"); } // to_dot @@ -264,11 +258,11 @@ typedef struct uint32_t end; uint32_t edge; uint32_t next; -} Post_Dom_Table; +} Post_Table; static uint32_t -intersection(uint32_t lhs, uint32_t rhs, uint32_t const length, Post_Dom_Table const visited[static length]) +intersection(uint32_t lhs, uint32_t rhs, size_t const length, Post_Table const visited[static length]) { if (lhs == (uint32_t) -1) { @@ -289,93 +283,11 @@ intersection(uint32_t lhs, uint32_t rhs, uint32_t const length, Post_Dom_Table c } // intersection -#define MAX(lhs, rhs) (lhs) > (rhs) ? (lhs) : (rhs) -#define MIN(lhs, rhs) (lhs) < (rhs) ? (lhs) : (rhs) - - -static void -post_dominators(Graph const graph, uint32_t const head, uint32_t* const rank, uint32_t const start, uint32_t const length, Post_Dom_Table visited[static length]) -{ - visited[head].post = -1; - visited[head].start = start; - visited[head].end = -1; - if (graph.nodes[head].lambda != (uint32_t) -1 && visited[graph.nodes[head].lambda].rank == (uint32_t) -1) - { - post_dominators(graph, graph.nodes[head].lambda, rank, start, length, visited); - visited[head].post = graph.nodes[head].lambda; - } // if - - for (uint32_t i = graph.nodes[head].edges; i != (uint32_t) -1; i = graph.edges[i].next) - { - if (visited[graph.edges[i].tail].rank == (uint32_t) -1) - { - post_dominators(graph, graph.edges[i].tail, rank, graph.edges[i].variant.end, length, visited); - } // if - else - { - visited[graph.edges[i].tail].start = MAX(visited[graph.edges[i].tail].start, graph.edges[i].variant.end); - } // else - - if (visited[head].post == (uint32_t) -1) - { - visited[head].post = graph.edges[i].tail; - visited[head].end = graph.edges[i].variant.start; - } // if - else - { - visited[head].post = intersection(visited[head].post, graph.edges[i].tail, length, visited); - visited[head].end = MIN(visited[head].end, graph.edges[i].variant.start); - } // else - } // for - - visited[head].rank = *rank; - *rank += 1; - printf("visit %u (%u): %d\n", head, visited[head].rank, visited[head].post); -} // post_dominators - - static void local_supremal(VA_Allocator const allocator, Graph const graph, size_t const len_obs, char const observed[static len_obs]) { uint32_t const length = va_array_length(graph.nodes); - Post_Dom_Table* visited = allocator.alloc(allocator.context, NULL, 0, sizeof(*visited) * length); - if (visited == NULL) - { - return; - } // if - - for (uint32_t i = 0; i < length; ++i) - { - visited[i].rank = -1; - } // for - - post_dominators(graph, graph.source, &(uint32_t) {0}, 0, length, visited); - - printf(" # \tpost\trank\tstart\tend\n"); - for (uint32_t i = 0; i < length; ++i) - { - printf("%2u:\t%4d\t%4u\t%5u\t%3d\n", i, visited[i].post, visited[i].rank, visited[i].start, visited[i].end); - } // for - - uint32_t head = graph.source; - uint32_t shift = 0; - for (uint32_t tail = visited[head].post; tail != (uint32_t) -1; head = tail, tail = visited[head].post) - { - uint32_t const start = visited[head].end; - uint32_t const end = visited[tail].start; - VA_Variant const variant = {start, end, graph.nodes[head].col + start - graph.nodes[head].row - shift, graph.nodes[tail].col + end - graph.nodes[tail].row - shift}; - printf("%u:%u/%.*s\n", variant.start, variant.end, (int) variant.obs_end - variant.obs_start, observed + variant.obs_start); - } // for - - visited = allocator.alloc(allocator.context, visited, sizeof(*visited) * length, 0); -} // local_supremal - - -static void -local_supremal_it(VA_Allocator const allocator, Graph const graph, size_t const len_obs, char const observed[static len_obs]) -{ - uint32_t const length = va_array_length(graph.nodes); - Post_Dom_Table* visited = allocator.alloc(allocator.context, NULL, 0, sizeof(*visited) * length); + Post_Table* visited = allocator.alloc(allocator.context, NULL, 0, sizeof(*visited) * length); if (visited == NULL) { return; @@ -384,9 +296,9 @@ local_supremal_it(VA_Allocator const allocator, Graph const graph, size_t const for (uint32_t i = 0; i < length; ++i) { visited[i].post = -1; - visited[i].next = -1; visited[i].start = 0; visited[i].end = -1; + visited[i].next = -1; } // for uint32_t rank = 0; @@ -395,32 +307,31 @@ local_supremal_it(VA_Allocator const allocator, Graph const graph, size_t const while (head != (uint32_t) -1) { - //printf("enter %u\n", head); uint32_t edge = visited[head].edge; if (edge == (uint32_t) -1) { - //printf("visit %u\n", head); + uint32_t const lambda = graph.nodes[head].lambda; + if (lambda != (uint32_t) -1) + { + if (visited[lambda].next == (uint32_t) -1) + { + visited[lambda].edge = graph.nodes[lambda].edges; + visited[lambda].next = head; + head = lambda; + continue; + } // if + visited[head].post = intersection(visited[head].post, lambda, length, visited); + } // if + visited[head].rank = rank; rank += 1; head = visited[head].next; continue; } // if - uint32_t const lambda = graph.nodes[head].lambda; - if (lambda != (uint32_t) -1 && visited[lambda].next == (uint32_t) -1) - { - visited[head].post = intersection(visited[head].post, lambda, length, visited); - visited[lambda].next = head; - visited[lambda].edge = graph.nodes[lambda].edges; - head = lambda; - continue; - } // if - - //printf("intersection %d, %u\n", visited[head].post, graph.edges[edge].tail); - visited[head].post = intersection(visited[head].post, graph.edges[edge].tail, length, visited); - if (visited[graph.edges[edge].tail].next != (uint32_t) -1) { + visited[head].post = intersection(visited[head].post, graph.edges[edge].tail, length, visited); visited[head].edge = graph.edges[edge].next; } // if while (edge != (uint32_t) -1) @@ -430,8 +341,8 @@ local_supremal_it(VA_Allocator const allocator, Graph const graph, size_t const visited[tail].start = MAX(visited[tail].start, graph.edges[edge].variant.end); if (visited[tail].next == (uint32_t) -1) { - visited[tail].next = head; visited[tail].edge = graph.nodes[tail].edges; + visited[tail].next = head; head = tail; break; } // if @@ -440,11 +351,13 @@ local_supremal_it(VA_Allocator const allocator, Graph const graph, size_t const } // while } // while + /* printf(" # \tpost\trank\tstart\tend\n"); for (uint32_t i = 0; i < length; ++i) { printf("%2u:\t%4d\t%4u\t%5u\t%3d\n", i, visited[i].post, visited[i].rank, visited[i].start, visited[i].end); } // for + */ head = graph.source; uint32_t shift = 0; @@ -453,116 +366,101 @@ local_supremal_it(VA_Allocator const allocator, Graph const graph, size_t const uint32_t const start = visited[head].end; uint32_t const end = visited[tail].start; VA_Variant const variant = {start, end, graph.nodes[head].col + start - graph.nodes[head].row - shift, graph.nodes[tail].col + end - graph.nodes[tail].row - shift}; - printf("%u:%u/%.*s\n", variant.start, variant.end, (int) variant.obs_end - variant.obs_start, observed + variant.obs_start); + if (head != graph.source) + { + printf(",\n"); + } // if + printf(" \"%u:%u/%.*s\"", variant.start, variant.end, (int) variant.obs_end - variant.obs_start, observed + variant.obs_start); } // for visited = allocator.alloc(allocator.context, visited, sizeof(*visited) * length, 0); -} // local_supremal_it - - -// AAAATA GAAAAGAAA -// AAT ACT -// AGAATTGCTTGAA AGGGTTAAA +} // local_supremal typedef struct { - uint32_t head; - uint32_t tail; - uint32_t length; - struct - { - uint32_t depth; - uint32_t next; - } table[]; -} Traversal_Generator; + uint32_t lca; + VA_Variant variant; + uint32_t depth; + uint32_t next; +} LCA_Table; -static Traversal_Generator* -traversal_init(VA_Allocator const allocator, Graph const graph) +static inline uint32_t +lca(uint32_t lhs, uint32_t rhs, size_t const length, LCA_Table const visited[static length]) { - uint32_t const length = va_array_length(graph.nodes); - Traversal_Generator* const generator = allocator.alloc(allocator.context, NULL, 0, sizeof(*generator) + sizeof(generator->table[0]) * length); - if (generator == NULL) - { - return NULL; - } // if - - for (uint32_t i = 0; i < length; ++i) + while (lhs != rhs) { - generator->table[i].depth = 0; - generator->table[i].next = -1; - } // for - generator->head = graph.source; - generator->tail = graph.source; - generator->length = length; - return generator; -} // traversal_init + lhs = visited[lhs].lca; + rhs = visited[rhs].lca; + } // while + return lhs; +} // lca -static Traversal_Generator* -traversal_destroy(VA_Allocator const allocator, Traversal_Generator* self) +static inline void +print_variant(VA_Variant const variant, size_t const len_obs, char const observed[static len_obs]) { - if (self == NULL) - { - return NULL; - } // if - self = allocator.alloc(allocator.context, self, sizeof(*self) + sizeof(self->table[0]) * self->length, 0); - return self; -} // traversal_destroy + printf("%u:%u/%.*s\n", variant.start, variant.end, (int) variant.obs_end - variant.obs_start, observed + variant.obs_start); +} // print_variant -static uint32_t -traversal_next(Traversal_Generator* const self, Graph const graph) +static void +canonical(VA_Allocator const allocator, Graph const graph, size_t const len_obs, char const observed[static len_obs]) { - if (self == NULL) + uint32_t const length = va_array_length(graph.nodes); + LCA_Table* visited = allocator.alloc(allocator.context, NULL, 0, sizeof(*visited) * length); + if (visited == NULL) { - return -1; + return; } // if - uint32_t const head = self->head; - if (head == (uint32_t) -1) + for (uint32_t i = 0; i < length; ++i) { - return head; - } // if + visited[i].lca = -1; + visited[i].depth = -1; + visited[i].next = -1; + } // for - for (uint32_t i = graph.nodes[head].edges; i != (uint32_t) -1; i = graph.edges[i].next) + visited[graph.source].depth = 0; + for (uint32_t head = graph.source, tail = graph.source; head != (uint32_t) -1; head = visited[head].next) { - uint32_t const tail = graph.edges[i].tail; - - uint32_t iets = head; - for (uint32_t j = graph.nodes[tail].lambda; j != (uint32_t) -1; j = graph.nodes[j].lambda) + printf("visit %u\n", head); + for (uint32_t edge = graph.nodes[head].edges; edge != (uint32_t) -1; edge = graph.edges[edge].next) { - if (self->table[j].depth == 0) + printf("look at %u\n", graph.edges[edge].tail); + if (visited[graph.edges[edge].tail].depth == (uint32_t) -1) { - //printf("push (lambda) %u\n", j); - self->table[j].depth = self->table[head].depth + 1; - self->table[j].next = self->table[iets].next; - self->table[iets].next = j; - iets = j; + visited[tail].next = graph.edges[edge].tail; + tail = graph.edges[edge].tail; + printf("push %u\n", tail); + visited[tail] = (LCA_Table) {head, graph.edges[edge].variant, visited[head].depth + 1, -1}; } // if - } // for + else if (visited[head].depth == visited[graph.edges[edge].tail].depth - 1) + { + uint32_t const common = lca(visited[graph.edges[edge].tail].lca, head, length, visited); + printf("lca %u, %u = %u\n", visited[graph.edges[edge].tail].lca, head, common); + + print_variant(visited[tail].variant, len_obs, observed); + print_variant(graph.edges[edge].variant, len_obs, observed); - if (self->table[tail].depth == 0) + visited[graph.edges[edge].tail].lca = common; + } // if + } // for + if (graph.nodes[head].lambda != (uint32_t) -1) { - //printf("push %u\n", tail); - self->table[tail].depth = self->table[head].depth + 1; - self->table[tail].next = self->table[head].next; - self->table[head].next = tail; - self->head = tail; + printf("lambda\n"); } // if } // for - /* - printf(" #\tdepth\tnext\n"); - for (uint32_t i = 0; i < self->length; ++i) + printf(" # \tlca\tdepth\tnext\n"); + for (uint32_t i = 0; i < length; ++i) { - printf("%2u:\t%5u\t%4d\n", i, self->table[i].depth, self->table[i].next); + printf("%2u:\t%3d\t%5d\t%4d\n", i, visited[i].lca, visited[i].depth, visited[i].next); } // for - printf("head: %d\ntail: %d\n", self->head, self->tail); - */ - return head; -} // traversal_next + + visited = allocator.alloc(allocator.context, visited, sizeof(*visited) * length, 0); +} // canonical static size_t @@ -583,23 +481,29 @@ bfs_traversal(VA_Allocator const allocator, Graph const graph, size_t const len_ uint32_t tail = graph.source; size_t count = 0; - printf("digraph{\nrankdir=LR\nedge[fontname=monospace]\nnode[fixedsize=true,fontname=serif,shape=circle,width=1]\nsi[shape=point,width=.1]\n"); - printf("si->s%u\n", graph.source); + //printf("digraph{\nrankdir=LR\nedge[fontname=monospace]\nnode[fixedsize=true,fontname=serif,shape=circle,width=1]\nsi[shape=point,width=.1]\n"); + //printf("si->s%u\n", graph.source); + printf(" \"edges\": [\n"); while (head != (uint32_t) -1) { //printf("pop %u\n", head); for (uint32_t i = head; i != (uint32_t) -1; i = graph.nodes[i].lambda) { - printf("s%u[label=\"(%u, %u, %u)\"%s]\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, graph.nodes[i].edges == (uint32_t) -1 ? ",peripheries=2" : ""); + //printf("s%u[label=\"(%u, %u, %u)\"%s]\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, graph.nodes[i].edges == (uint32_t) -1 ? ",peripheries=2" : ""); if (i != head) { //printf("lambda %u\n", i); } // if for (uint32_t j = graph.nodes[i].edges; j != (uint32_t) -1; j = graph.edges[j].next) { + if (count > 0) + { + printf(",\n"); + } // if count += 1; - printf("s%u->s%u[label=\"%u:%u/%.*s\"]\n", head, graph.edges[j].tail, graph.edges[j].variant.start, graph.edges[j].variant.end, (int) graph.edges[j].variant.obs_end - graph.edges[j].variant.obs_start, observed + graph.edges[j].variant.obs_start); + printf(" {\"head\": \"s%u\", \"tail\": \"s%u\", \"variant\": \"%u:%u/%.*s\"}", head, graph.edges[j].tail, graph.edges[j].variant.start, graph.edges[j].variant.end, (int) graph.edges[j].variant.obs_end - graph.edges[j].variant.obs_start, observed + graph.edges[j].variant.obs_start); + //printf("s%u->s%u[label=\"%u:%u/%.*s\"]\n", head, graph.edges[j].tail, graph.edges[j].variant.start, graph.edges[j].variant.end, (int) graph.edges[j].variant.obs_end - graph.edges[j].variant.obs_start, observed + graph.edges[j].variant.obs_start); if (table[graph.edges[j].tail].depth > 0) { @@ -625,7 +529,7 @@ bfs_traversal(VA_Allocator const allocator, Graph const graph, size_t const len_ */ } // while - printf("}\n"); + printf("\n ],\n"); table = allocator.alloc(allocator.context, table, sizeof(*table) * va_array_length(graph.nodes), 0); @@ -656,24 +560,24 @@ main(int argc, char* argv[static argc + 1]) VA_LCS_Node** lcs_nodes = NULL; size_t const len_lcs = va_edit(va_std_allocator, len_ref, reference, len_obs, observed, &lcs_nodes); /* - printf("%zu\n", len_lcs); + fprintf(stderr, "%zu\n", len_lcs); for (size_t i = 0; i < len_lcs; ++i) { - printf("%zu: ", i); + fprintf(stderr, "%zu: ", i); for (size_t j = 0; j < va_array_length(lcs_nodes[i]); ++j) { - printf("(%u, %u, %u) ", lcs_nodes[i][j].row, lcs_nodes[i][j].col, lcs_nodes[i][j].length); + fprintf(stderr, "(%u, %u, %u) ", lcs_nodes[i][j].row, lcs_nodes[i][j].col, lcs_nodes[i][j].length); } // for - printf("\n"); + fprintf(stderr, "\n"); } // for */ - Graph graph = build_graph(va_std_allocator, len_ref, reference, len_obs, observed, len_lcs, lcs_nodes, 0); + Graph graph = build_graph(va_std_allocator, len_ref, len_obs, len_lcs, lcs_nodes, 0); /* printf("%zu\n", to_dot(graph, len_obs, observed)); */ - +/* printf("nodes (%zu)\n #\t(row, col, len)\tedges\tlambda\n", va_array_length(graph.nodes)); for (size_t i = 0; i < va_array_length(graph.nodes); ++i) { @@ -685,23 +589,26 @@ main(int argc, char* argv[static argc + 1]) printf("%3zu:\t%4u\t \"%u:%u/%.*s\"\t%4d\n", i, graph.edges[i].tail, graph.edges[i].variant.start, graph.edges[i].variant.end, (int) graph.edges[i].variant.obs_end - graph.edges[i].variant.obs_start, observed + graph.edges[i].variant.obs_start, (signed) graph.edges[i].next); } // for - //printf("%zu\n", bfs_traversal(va_std_allocator, graph, len_obs, observed)); + local_supremal(va_std_allocator, graph, len_obs, observed); +*/ + //canonical(va_std_allocator, graph, len_obs, observed); - to_dot(graph, len_obs, observed); + //to_dot(graph, len_obs, observed); -/* - Traversal_Generator* gen = traversal_init(va_std_allocator, graph); - uint32_t node = traversal_next(gen, graph); - while (node != (uint32_t) -1) - { - printf("yield: %u\n", node); - node = traversal_next(gen, graph); - } // if - gen = traversal_destroy(va_std_allocator, gen); -*/ + printf("{\n \"source\": \"s%u\",\n \"nodes\": {\n", graph.source); + + for (uint32_t i = 0; i < va_array_length(graph.nodes); ++i) + { + printf(" \"s%u\": {\"row\": %u, \"col\": %u, \"length\": %u}%s\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, i < va_array_length(graph.nodes) - 1 ? "," : ""); + } // for + printf(" },\n"); + bfs_traversal(va_std_allocator, graph, len_obs, observed); + printf(" \"supremal\": \"%u:%u/%.*s\",\n", graph.supremal.start, graph.supremal.end, (int) graph.supremal.obs_end - graph.supremal.obs_start, observed + graph.supremal.obs_start); + printf(" \"local_supremal\": [\n"); local_supremal(va_std_allocator, graph, len_obs, observed); - local_supremal_it(va_std_allocator, graph, len_obs, observed); + printf("\n ]\n"); + printf("}"); destroy(va_std_allocator, &graph); From 799735a8ec28d981c5a90696db10990ec42315f0 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 13 Aug 2024 13:55:12 +0200 Subject: [PATCH 092/704] Test against Python implementation --- test.py | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 test.py diff --git a/test.py b/test.py new file mode 100644 index 0000000..17b3c0d --- /dev/null +++ b/test.py @@ -0,0 +1,71 @@ +import json +import random +import subprocess +import sys + +from algebra import LCSgraph +from algebra.extractor import local_supremal +from algebra.utils import random_sequence, to_dot + + +def main(): + prefix = "" + suffix = "" + debug = False + + if len(sys.argv) > 1: + reference = sys.argv[1] + observed = sys.argv[2] + debug = True + else: + if random.random() > 0.5: + prefix = random_sequence(1000) + suffix = random_sequence(1000) + reference = prefix + random_sequence(100) + suffix + observed = prefix + random_sequence(100) + suffix + + graph = LCSgraph.from_sequence(reference, observed); + if debug: + print("\n".join(to_dot(reference, graph, labels=False, hgvs=False))) + + valgrind = ["valgrind", "-q", "--leak-check=full", "--error-exitcode=1"] + stdout = subprocess.run(["./a.out", reference, observed], check=True, stdout=subprocess.PIPE).stdout.decode("utf-8") + + try: + cgraph = json.loads(stdout) + except json.decoder.JSONDecodeError as exc: + print(f'\"{stdout}\"') + raise exc + + assert str(graph.supremal) == cgraph["supremal"], f'supremals differ: {cgraph["supremal"]} vs {graph.supremal}' + + nodes = list(graph.nodes()) + edges = list(graph.bfs_traversal()); + + assert len(cgraph["nodes"]) == len(nodes), f'# cgraph nodes {len(cgraph["nodes"])} vs # graph nodes {len(nodes)}' + assert len(cgraph["edges"]) == len(edges), f'# cgraph edges {len(cgraph["edges"])} vs # graph edges {len(edgse)}' + + for cnode in cgraph["nodes"].values(): + try: + cnode["node"] = next(node for node in nodes if node == LCSgraph.Node(cnode["row"], cnode["col"], cnode["length"])) + except StopIteration: + raise ValueError(f'{cnode} not in graph nodes') from None + + for cedge in cgraph["edges"]: + head = cgraph["nodes"][cedge["head"]]["node"] + tail = cgraph["nodes"][cedge["tail"]]["node"] + try: + next((t, v) for t, v in head.edges if t == tail and str(v) == cedge["variant"]) + except StopIteration: + raise ValueError(f'{cedge} not in edges of {head}') from None + + assert len(cgraph["local_supremal"]) == len(local_supremal(reference, graph)), f'' + + for lhs, rhs in zip(cgraph["local_supremal"], local_supremal(reference, graph)): + assert lhs == str(rhs), f'local supremal element differ: {lhs} vs {rhs}' + + print("ok") + + +if __name__ == "__main__": + main() From 0e42eb0df41d0d9e0ebcca84bd0762c9d039fca2 Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 14 Aug 2024 16:18:20 +0200 Subject: [PATCH 093/704] WIP: hgvs-like extraction --- src/main.c | 140 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 84 insertions(+), 56 deletions(-) diff --git a/src/main.c b/src/main.c index 3dd59b8..18dacfa 100644 --- a/src/main.c +++ b/src/main.c @@ -11,8 +11,11 @@ #include "../include/variant.h" // VA_Variant -#define MAX(lhs, rhs) (lhs) > (rhs) ? (lhs) : (rhs) -#define MIN(lhs, rhs) (lhs) < (rhs) ? (lhs) : (rhs) +#define MAX(lhs, rhs) (((lhs) > (rhs)) ? (lhs) : (rhs)) +#define MIN(lhs, rhs) (((lhs) < (rhs)) ? (lhs) : (rhs)) + +#define print_variant(variant, observed) variant.start, variant.end, (int) variant.obs_end - variant.obs_start, observed + variant.obs_start +#define VAR_FMT "%u:%u/%.*s" typedef struct @@ -387,24 +390,35 @@ typedef struct static inline uint32_t -lca(uint32_t lhs, uint32_t rhs, size_t const length, LCA_Table const visited[static length]) +lca(uint32_t* const start, uint32_t lhs, uint32_t rhs, size_t const length, LCA_Table const visited[static length]) { + uint32_t lhs_start = visited[lhs].variant.start; + uint32_t rhs_start = visited[rhs].variant.start; while (lhs != rhs) { - lhs = visited[lhs].lca; - rhs = visited[rhs].lca; + if (visited[lhs].depth > visited[rhs].depth) + { + lhs = visited[lhs].lca; + lhs_start = visited[lhs].variant.start; + } // if + else if (visited[rhs].depth > visited[lhs].depth) + { + rhs = visited[rhs].lca; + rhs_start = visited[rhs].variant.start; + } // if + else + { + lhs = visited[lhs].lca; + lhs_start = visited[lhs].variant.start; + rhs = visited[rhs].lca; + rhs_start = visited[rhs].variant.start; + } // else } // while + *start = MIN(lhs_start, rhs_start); return lhs; } // lca -static inline void -print_variant(VA_Variant const variant, size_t const len_obs, char const observed[static len_obs]) -{ - printf("%u:%u/%.*s\n", variant.start, variant.end, (int) variant.obs_end - variant.obs_start, observed + variant.obs_start); -} // print_variant - - static void canonical(VA_Allocator const allocator, Graph const graph, size_t const len_obs, char const observed[static len_obs]) { @@ -417,46 +431,57 @@ canonical(VA_Allocator const allocator, Graph const graph, size_t const len_obs, for (uint32_t i = 0; i < length; ++i) { - visited[i].lca = -1; visited[i].depth = -1; - visited[i].next = -1; } // for - visited[graph.source].depth = 0; + uint32_t const shift = graph.nodes[graph.source].row; + + visited[graph.source] = (LCA_Table) {-1, (VA_Variant) {0, 0, 0, 0}, 0, -1}; for (uint32_t head = graph.source, tail = graph.source; head != (uint32_t) -1; head = visited[head].next) { - printf("visit %u\n", head); - for (uint32_t edge = graph.nodes[head].edges; edge != (uint32_t) -1; edge = graph.edges[edge].next) + fprintf(stderr, "enter %u\n", head); + uint32_t const lambda = graph.nodes[head].lambda; + if (lambda != (uint32_t) -1) { - printf("look at %u\n", graph.edges[edge].tail); - if (visited[graph.edges[edge].tail].depth == (uint32_t) -1) + fprintf(stderr, "push lambda %u\n", lambda); + visited[lambda] = (LCA_Table) {visited[head].lca, visited[head].variant, visited[head].depth, -1}; + visited[tail].next = lambda; + tail = lambda; + } // if + + for (uint32_t i = graph.nodes[head].edges; i != (uint32_t) -1; i = graph.edges[i].next) + { + uint32_t const edge_tail = graph.edges[i].tail; + if (visited[edge_tail].depth == (uint32_t) -1) { - visited[tail].next = graph.edges[edge].tail; - tail = graph.edges[edge].tail; - printf("push %u\n", tail); - visited[tail] = (LCA_Table) {head, graph.edges[edge].variant, visited[head].depth + 1, -1}; + fprintf(stderr, "push %u\n", edge_tail); + visited[edge_tail] = (LCA_Table) {head, graph.edges[i].variant, visited[head].depth + 1, -1}; + visited[tail].next = edge_tail; + tail = edge_tail; } // if - else if (visited[head].depth == visited[graph.edges[edge].tail].depth - 1) + else if (visited[head].depth == visited[edge_tail].depth - 1) { - uint32_t const common = lca(visited[graph.edges[edge].tail].lca, head, length, visited); - printf("lca %u, %u = %u\n", visited[graph.edges[edge].tail].lca, head, common); - - print_variant(visited[tail].variant, len_obs, observed); - print_variant(graph.edges[edge].variant, len_obs, observed); - - visited[graph.edges[edge].tail].lca = common; + fprintf(stderr, "update %u: lca(%u, %u)\n", edge_tail, head, visited[edge_tail].lca); + uint32_t const end = MAX(graph.edges[i].variant.end, visited[edge_tail].variant.end); + uint32_t start = 0; + uint32_t const common = lca(&start, head, visited[edge_tail].lca, length, visited); + VA_Variant const variant = {start, end, graph.nodes[common].col + start - graph.nodes[common].row - shift, graph.nodes[head].col + end - graph.nodes[head].row - shift}; + visited[edge_tail].lca = common; + visited[edge_tail].variant = (VA_Variant) {start, end, graph.nodes[common].col + start - graph.nodes[common].row, graph.nodes[head].col + end - graph.nodes[head].row}; + fprintf(stderr, "variant " VAR_FMT "\n", print_variant(variant, observed)); } // if + else + { + fprintf(stderr, "skip %u\n", edge_tail); + } // else } // for - if (graph.nodes[head].lambda != (uint32_t) -1) - { - printf("lambda\n"); - } // if + fprintf(stderr, "done with %u\n", head); } // for - printf(" # \tlca\tdepth\tnext\n"); + fprintf(stderr, " # \tlca\tvariant\tdepth\tnext\n"); for (uint32_t i = 0; i < length; ++i) { - printf("%2u:\t%3d\t%5d\t%4d\n", i, visited[i].lca, visited[i].depth, visited[i].next); + fprintf(stderr, "%2u:\t%3d\t" VAR_FMT "\t%5d\t%4d\n", i, visited[i].lca, print_variant(visited[i].variant, observed), visited[i].depth, visited[i].next); } // for visited = allocator.alloc(allocator.context, visited, sizeof(*visited) * length, 0); @@ -537,6 +562,24 @@ bfs_traversal(VA_Allocator const allocator, Graph const graph, size_t const len_ } // bfs_traversal +static void +to_json(Graph const graph, size_t const len_obs, char const observed[static len_obs]) +{ + printf("{\n \"source\": \"s%u\",\n \"nodes\": {\n", graph.source); + for (uint32_t i = 0; i < va_array_length(graph.nodes); ++i) + { + printf(" \"s%u\": {\"row\": %u, \"col\": %u, \"length\": %u}%s\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, i < va_array_length(graph.nodes) - 1 ? "," : ""); + } // for + printf(" },\n"); + bfs_traversal(va_std_allocator, graph, len_obs, observed); + printf(" \"supremal\": \"%u:%u/%.*s\",\n", graph.supremal.start, graph.supremal.end, (int) graph.supremal.obs_end - graph.supremal.obs_start, observed + graph.supremal.obs_start); + printf(" \"local_supremal\": [\n"); + local_supremal(va_std_allocator, graph, len_obs, observed); + printf("\n ]\n"); + printf("}"); +} // to_json + + int main(int argc, char* argv[static argc + 1]) { @@ -574,9 +617,6 @@ main(int argc, char* argv[static argc + 1]) Graph graph = build_graph(va_std_allocator, len_ref, len_obs, len_lcs, lcs_nodes, 0); - /* - printf("%zu\n", to_dot(graph, len_obs, observed)); - */ /* printf("nodes (%zu)\n #\t(row, col, len)\tedges\tlambda\n", va_array_length(graph.nodes)); for (size_t i = 0; i < va_array_length(graph.nodes); ++i) @@ -588,27 +628,15 @@ main(int argc, char* argv[static argc + 1]) { printf("%3zu:\t%4u\t \"%u:%u/%.*s\"\t%4d\n", i, graph.edges[i].tail, graph.edges[i].variant.start, graph.edges[i].variant.end, (int) graph.edges[i].variant.obs_end - graph.edges[i].variant.obs_start, observed + graph.edges[i].variant.obs_start, (signed) graph.edges[i].next); } // for - - local_supremal(va_std_allocator, graph, len_obs, observed); */ - //canonical(va_std_allocator, graph, len_obs, observed); - //to_dot(graph, len_obs, observed); + //local_supremal(va_std_allocator, graph, len_obs, observed); + canonical(va_std_allocator, graph, len_obs, observed); - printf("{\n \"source\": \"s%u\",\n \"nodes\": {\n", graph.source); + //to_dot(graph, len_obs, observed); - for (uint32_t i = 0; i < va_array_length(graph.nodes); ++i) - { - printf(" \"s%u\": {\"row\": %u, \"col\": %u, \"length\": %u}%s\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, i < va_array_length(graph.nodes) - 1 ? "," : ""); - } // for - printf(" },\n"); - bfs_traversal(va_std_allocator, graph, len_obs, observed); - printf(" \"supremal\": \"%u:%u/%.*s\",\n", graph.supremal.start, graph.supremal.end, (int) graph.supremal.obs_end - graph.supremal.obs_start, observed + graph.supremal.obs_start); - printf(" \"local_supremal\": [\n"); - local_supremal(va_std_allocator, graph, len_obs, observed); - printf("\n ]\n"); - printf("}"); + //to_json(graph, len_obs, observed); destroy(va_std_allocator, &graph); From 754cf5b9118b3fb93790ef1505d15472a99dba13 Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 14 Aug 2024 16:18:49 +0200 Subject: [PATCH 094/704] Print test instance --- test.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test.py b/test.py index 17b3c0d..c67a862 100644 --- a/test.py +++ b/test.py @@ -24,6 +24,8 @@ def main(): reference = prefix + random_sequence(100) + suffix observed = prefix + random_sequence(100) + suffix + print(reference, observed) + graph = LCSgraph.from_sequence(reference, observed); if debug: print("\n".join(to_dot(reference, graph, labels=False, hgvs=False))) From 46c639fc0b86f5b3f5eaab3a08b25844582bc362 Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 14 Aug 2024 20:11:30 +0200 Subject: [PATCH 095/704] WIP: canonical sometimes selects a wrong slice from observed --- src/main.c | 43 ++++++++++++++++++++++++++++++++++--------- test.py | 18 +++++++++++------- 2 files changed, 45 insertions(+), 16 deletions(-) diff --git a/src/main.c b/src/main.c index 18dacfa..f3b7c01 100644 --- a/src/main.c +++ b/src/main.c @@ -396,22 +396,20 @@ lca(uint32_t* const start, uint32_t lhs, uint32_t rhs, size_t const length, LCA_ uint32_t rhs_start = visited[rhs].variant.start; while (lhs != rhs) { + lhs_start = visited[lhs].variant.start; + rhs_start = visited[rhs].variant.start; if (visited[lhs].depth > visited[rhs].depth) { lhs = visited[lhs].lca; - lhs_start = visited[lhs].variant.start; } // if else if (visited[rhs].depth > visited[lhs].depth) { rhs = visited[rhs].lca; - rhs_start = visited[rhs].variant.start; } // if else { lhs = visited[lhs].lca; - lhs_start = visited[lhs].variant.start; rhs = visited[rhs].lca; - rhs_start = visited[rhs].variant.start; } // else } // while *start = MIN(lhs_start, rhs_start); @@ -437,6 +435,7 @@ canonical(VA_Allocator const allocator, Graph const graph, size_t const len_obs, uint32_t const shift = graph.nodes[graph.source].row; visited[graph.source] = (LCA_Table) {-1, (VA_Variant) {0, 0, 0, 0}, 0, -1}; + uint32_t sink = -1; for (uint32_t head = graph.source, tail = graph.source; head != (uint32_t) -1; head = visited[head].next) { fprintf(stderr, "enter %u\n", head); @@ -449,6 +448,11 @@ canonical(VA_Allocator const allocator, Graph const graph, size_t const len_obs, tail = lambda; } // if + if (graph.nodes[head].edges == (uint32_t) -1) + { + sink = head; + } // if + for (uint32_t i = graph.nodes[head].edges; i != (uint32_t) -1; i = graph.edges[i].next) { uint32_t const edge_tail = graph.edges[i].tail; @@ -465,6 +469,7 @@ canonical(VA_Allocator const allocator, Graph const graph, size_t const len_obs, uint32_t const end = MAX(graph.edges[i].variant.end, visited[edge_tail].variant.end); uint32_t start = 0; uint32_t const common = lca(&start, head, visited[edge_tail].lca, length, visited); + fprintf(stderr, "%u: %u--%u\n", common, start, end); VA_Variant const variant = {start, end, graph.nodes[common].col + start - graph.nodes[common].row - shift, graph.nodes[head].col + end - graph.nodes[head].row - shift}; visited[edge_tail].lca = common; visited[edge_tail].variant = (VA_Variant) {start, end, graph.nodes[common].col + start - graph.nodes[common].row, graph.nodes[head].col + end - graph.nodes[head].row}; @@ -484,6 +489,23 @@ canonical(VA_Allocator const allocator, Graph const graph, size_t const len_obs, fprintf(stderr, "%2u:\t%3d\t" VAR_FMT "\t%5d\t%4d\n", i, visited[i].lca, print_variant(visited[i].variant, observed), visited[i].depth, visited[i].next); } // for + size_t const n = visited[sink].depth - 1; + VA_Variant* variants = allocator.alloc(allocator.context, NULL, 0, sizeof(*variants) * n); + if (variants != NULL) + { + for (size_t i = 0; i < n; ++i) + { + variants[n - i - 1] = visited[sink].variant; + sink = visited[sink].lca; + } // for + + for (size_t i = 0; i < n; ++i) + { + printf(" \"" VAR_FMT "\"%s\n", print_variant(variants[i], observed), i < n - 1 ? "," : ""); + } // for + variants = allocator.alloc(allocator.context, variants, sizeof(*variants) * n, 0); + } // if + visited = allocator.alloc(allocator.context, visited, sizeof(*visited) * length, 0); } // canonical @@ -575,7 +597,10 @@ to_json(Graph const graph, size_t const len_obs, char const observed[static len_ printf(" \"supremal\": \"%u:%u/%.*s\",\n", graph.supremal.start, graph.supremal.end, (int) graph.supremal.obs_end - graph.supremal.obs_start, observed + graph.supremal.obs_start); printf(" \"local_supremal\": [\n"); local_supremal(va_std_allocator, graph, len_obs, observed); - printf("\n ]\n"); + printf("\n ],\n"); + printf(" \"canonical\": [\n"); + canonical(va_std_allocator, graph, len_obs, observed); + printf(" ]\n"); printf("}"); } // to_json @@ -630,13 +655,13 @@ main(int argc, char* argv[static argc + 1]) } // for */ - //local_supremal(va_std_allocator, graph, len_obs, observed); + //to_dot(graph, len_obs, observed); - canonical(va_std_allocator, graph, len_obs, observed); + //local_supremal(va_std_allocator, graph, len_obs, observed); - //to_dot(graph, len_obs, observed); + //canonical(va_std_allocator, graph, len_obs, observed); - //to_json(graph, len_obs, observed); + to_json(graph, len_obs, observed); destroy(va_std_allocator, &graph); diff --git a/test.py b/test.py index c67a862..858f9e0 100644 --- a/test.py +++ b/test.py @@ -5,6 +5,7 @@ from algebra import LCSgraph from algebra.extractor import local_supremal +from algebra.extractor.extractor import canonical from algebra.utils import random_sequence, to_dot @@ -18,20 +19,21 @@ def main(): observed = sys.argv[2] debug = True else: - if random.random() > 0.5: - prefix = random_sequence(1000) - suffix = random_sequence(1000) - reference = prefix + random_sequence(100) + suffix - observed = prefix + random_sequence(100) + suffix + #if random.random() > 0.5: + # prefix = random_sequence(1000) + # suffix = random_sequence(1000) + reference = prefix + random_sequence(20) + suffix + observed = prefix + random_sequence(20) + suffix print(reference, observed) graph = LCSgraph.from_sequence(reference, observed); + valgrind = [] if debug: print("\n".join(to_dot(reference, graph, labels=False, hgvs=False))) + valgrind = ["valgrind", "--leak-check=full", "--error-exitcode=1"] - valgrind = ["valgrind", "-q", "--leak-check=full", "--error-exitcode=1"] - stdout = subprocess.run(["./a.out", reference, observed], check=True, stdout=subprocess.PIPE).stdout.decode("utf-8") + stdout = subprocess.run([*valgrind, "./a.out", reference, observed], check=True, stdout=subprocess.PIPE).stdout.decode("utf-8") try: cgraph = json.loads(stdout) @@ -66,6 +68,8 @@ def main(): for lhs, rhs in zip(cgraph["local_supremal"], local_supremal(reference, graph)): assert lhs == str(rhs), f'local supremal element differ: {lhs} vs {rhs}' + print(cgraph["canonical"]) + print(canonical(graph)) print("ok") From 5f284670a12062d19d37fadbd50d487652e0eaa8 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 15 Aug 2024 17:00:05 +0200 Subject: [PATCH 096/704] WIP: canonical --- src/main.c | 143 +++++++++++++++++++++++++++++++---------------------- test.py | 19 ++++--- 2 files changed, 98 insertions(+), 64 deletions(-) diff --git a/src/main.c b/src/main.c index f3b7c01..2101c40 100644 --- a/src/main.c +++ b/src/main.c @@ -383,8 +383,9 @@ local_supremal(VA_Allocator const allocator, Graph const graph, size_t const len typedef struct { uint32_t lca; - VA_Variant variant; uint32_t depth; + uint32_t start; + uint32_t end; uint32_t next; } LCA_Table; @@ -392,22 +393,41 @@ typedef struct static inline uint32_t lca(uint32_t* const start, uint32_t lhs, uint32_t rhs, size_t const length, LCA_Table const visited[static length]) { - uint32_t lhs_start = visited[lhs].variant.start; - uint32_t rhs_start = visited[rhs].variant.start; + uint32_t lhs_start = *start; + uint32_t rhs_start = *start; while (lhs != rhs) { - lhs_start = visited[lhs].variant.start; - rhs_start = visited[rhs].variant.start; + fprintf(stderr, " lca %u (%d), %u (%d)\n", lhs, lhs_start, rhs, rhs_start); + if (visited[lhs].depth > visited[rhs].depth) { + fprintf(stderr, " left\n"); + lhs_start = visited[lhs].start; lhs = visited[lhs].lca; } // if else if (visited[rhs].depth > visited[lhs].depth) { + fprintf(stderr, " right\n"); + rhs_start = visited[rhs].start; rhs = visited[rhs].lca; } // if else { + /* + if (visited[lhs].lca == rhs) + { + lhs_start = visited[lhs].start; + lhs = rhs; + break; + } // if + else if (visited[rhs].lca == lhs) + { + break; + } // if + */ + fprintf(stderr, " both\n"); + lhs_start = visited[lhs].start; + rhs_start = visited[rhs].start; lhs = visited[lhs].lca; rhs = visited[rhs].lca; } // else @@ -430,82 +450,89 @@ canonical(VA_Allocator const allocator, Graph const graph, size_t const len_obs, for (uint32_t i = 0; i < length; ++i) { visited[i].depth = -1; + visited[i].next = -1; } // for - uint32_t const shift = graph.nodes[graph.source].row; - - visited[graph.source] = (LCA_Table) {-1, (VA_Variant) {0, 0, 0, 0}, 0, -1}; uint32_t sink = -1; + visited[graph.source] = (LCA_Table) {-1, 0, -1, -1, -1}; for (uint32_t head = graph.source, tail = graph.source; head != (uint32_t) -1; head = visited[head].next) { fprintf(stderr, "enter %u\n", head); - uint32_t const lambda = graph.nodes[head].lambda; - if (lambda != (uint32_t) -1) - { - fprintf(stderr, "push lambda %u\n", lambda); - visited[lambda] = (LCA_Table) {visited[head].lca, visited[head].variant, visited[head].depth, -1}; - visited[tail].next = lambda; - tail = lambda; - } // if - - if (graph.nodes[head].edges == (uint32_t) -1) - { - sink = head; - } // if - - for (uint32_t i = graph.nodes[head].edges; i != (uint32_t) -1; i = graph.edges[i].next) + for (uint32_t i = head; i != (uint32_t) -1; i = graph.nodes[i].lambda) { - uint32_t const edge_tail = graph.edges[i].tail; - if (visited[edge_tail].depth == (uint32_t) -1) + if (i != head) { - fprintf(stderr, "push %u\n", edge_tail); - visited[edge_tail] = (LCA_Table) {head, graph.edges[i].variant, visited[head].depth + 1, -1}; - visited[tail].next = edge_tail; - tail = edge_tail; + fprintf(stderr, " enter lambda %u\n", i); + if (visited[i].depth != visited[head].depth) + { + fprintf(stderr, " push lambda %u\n", i); + visited[i] = (LCA_Table) {head, visited[head].depth, visited[head].start, visited[head].end, visited[i].next}; + } // if + else + { + fprintf(stderr, " update lambda %u\n", i); + visited[i].lca = lca(&visited[i].start, head, visited[i].lca, length, visited); + visited[i].end = MAX(visited[i].end, visited[head].end); + fprintf(stderr, " lca = %u (%u, %u)\n", visited[i].lca, visited[i].start, visited[i].end); + } // else } // if - else if (visited[head].depth == visited[edge_tail].depth - 1) + + if (graph.nodes[i].edges == (uint32_t) -1) { - fprintf(stderr, "update %u: lca(%u, %u)\n", edge_tail, head, visited[edge_tail].lca); - uint32_t const end = MAX(graph.edges[i].variant.end, visited[edge_tail].variant.end); - uint32_t start = 0; - uint32_t const common = lca(&start, head, visited[edge_tail].lca, length, visited); - fprintf(stderr, "%u: %u--%u\n", common, start, end); - VA_Variant const variant = {start, end, graph.nodes[common].col + start - graph.nodes[common].row - shift, graph.nodes[head].col + end - graph.nodes[head].row - shift}; - visited[edge_tail].lca = common; - visited[edge_tail].variant = (VA_Variant) {start, end, graph.nodes[common].col + start - graph.nodes[common].row, graph.nodes[head].col + end - graph.nodes[head].row}; - fprintf(stderr, "variant " VAR_FMT "\n", print_variant(variant, observed)); + fprintf(stderr, " sink\n"); + sink = i; } // if - else + + for (uint32_t j = graph.nodes[i].edges; j != (uint32_t) -1; j = graph.edges[j].next) { - fprintf(stderr, "skip %u\n", edge_tail); - } // else + uint32_t const edge_tail = graph.edges[j].tail; + if (visited[edge_tail].depth == (uint32_t) -1) + { + fprintf(stderr, " push %u\n", edge_tail); + visited[edge_tail] = (LCA_Table) {i, visited[i].depth + 1, graph.edges[j].variant.start, graph.edges[j].variant.end, -1}; + visited[tail].next = edge_tail; + tail = edge_tail; + } // if + else if (visited[edge_tail].depth - 1 == visited[i].depth) + { + fprintf(stderr, " update %u\n", edge_tail); + visited[edge_tail].lca = lca(&visited[edge_tail].start, i, visited[edge_tail].lca, length, visited); + visited[edge_tail].end = MAX(visited[edge_tail].end, graph.edges[j].variant.end); + fprintf(stderr, " lca = %u (%u, %u)\n", visited[edge_tail].lca, visited[edge_tail].start, visited[edge_tail].end); + } // if + else + { + fprintf(stderr, " skip %u\n", edge_tail); + } // else + } // for } // for - fprintf(stderr, "done with %u\n", head); - } // for + } // while - fprintf(stderr, " # \tlca\tvariant\tdepth\tnext\n"); + fprintf(stderr, " # \tlca\tdepth\tstart\tend\tnext\n"); for (uint32_t i = 0; i < length; ++i) { - fprintf(stderr, "%2u:\t%3d\t" VAR_FMT "\t%5d\t%4d\n", i, visited[i].lca, print_variant(visited[i].variant, observed), visited[i].depth, visited[i].next); + fprintf(stderr, "%2u:\t%3d\t%5d\t%5d\t%3d\t%4d\n", i, visited[i].lca, visited[i].depth, visited[i].start, visited[i].end, visited[i].next); } // for - size_t const n = visited[sink].depth - 1; - VA_Variant* variants = allocator.alloc(allocator.context, NULL, 0, sizeof(*variants) * n); - if (variants != NULL) + VA_Variant* variants = NULL; + for (uint32_t tail = sink; tail != (uint32_t) -1 && visited[tail].lca != (uint32_t) -1; tail = visited[tail].lca) { - for (size_t i = 0; i < n; ++i) - { - variants[n - i - 1] = visited[sink].variant; - sink = visited[sink].lca; - } // for + uint32_t const head = visited[tail].lca; + uint32_t const start_offset = visited[tail].start - graph.nodes[head].row; + uint32_t const end_offset = visited[tail].end - graph.nodes[tail].row; + va_array_insert(va_std_allocator, variants, ((VA_Variant) {visited[tail].start, visited[tail].end, graph.nodes[head].col + start_offset, graph.nodes[tail].col + end_offset}), 0); + } // for - for (size_t i = 0; i < n; ++i) + if (variants != NULL) + { + for (size_t i = 0; i < va_array_length(variants); ++i) { - printf(" \"" VAR_FMT "\"%s\n", print_variant(variants[i], observed), i < n - 1 ? "," : ""); + printf(" \"" VAR_FMT "\"%s\n", print_variant(variants[i], observed), i < va_array_length(variants) - 1 ? "," : ""); } // for - variants = allocator.alloc(allocator.context, variants, sizeof(*variants) * n, 0); } // if + variants = va_array_destroy(va_std_allocator, variants); + visited = allocator.alloc(allocator.context, visited, sizeof(*visited) * length, 0); } // canonical @@ -655,7 +682,7 @@ main(int argc, char* argv[static argc + 1]) } // for */ - //to_dot(graph, len_obs, observed); + to_dot(graph, len_obs, observed); //local_supremal(va_std_allocator, graph, len_obs, observed); diff --git a/test.py b/test.py index 858f9e0..6d0ab5c 100644 --- a/test.py +++ b/test.py @@ -22,8 +22,8 @@ def main(): #if random.random() > 0.5: # prefix = random_sequence(1000) # suffix = random_sequence(1000) - reference = prefix + random_sequence(20) + suffix - observed = prefix + random_sequence(20) + suffix + reference = prefix + random_sequence(10) + suffix + observed = prefix + random_sequence(10) + suffix print(reference, observed) @@ -31,6 +31,7 @@ def main(): valgrind = [] if debug: print("\n".join(to_dot(reference, graph, labels=False, hgvs=False))) + print(canonical(graph)) valgrind = ["valgrind", "--leak-check=full", "--error-exitcode=1"] stdout = subprocess.run([*valgrind, "./a.out", reference, observed], check=True, stdout=subprocess.PIPE).stdout.decode("utf-8") @@ -63,13 +64,19 @@ def main(): except StopIteration: raise ValueError(f'{cedge} not in edges of {head}') from None - assert len(cgraph["local_supremal"]) == len(local_supremal(reference, graph)), f'' + assert len(cgraph["local_supremal"]) == len(local_supremal(reference, graph)), f'local supremal length' for lhs, rhs in zip(cgraph["local_supremal"], local_supremal(reference, graph)): - assert lhs == str(rhs), f'local supremal element differ: {lhs} vs {rhs}' + assert lhs == str(rhs), f'local supremal elements differ: {lhs} vs {rhs}' + + if debug: + print(cgraph["canonical"], canonical(graph)) + + assert len(cgraph["canonical"]) == len(canonical(graph)), f'canonical length' + + for lhs, rhs in zip(cgraph["canonical"], canonical(graph)): + assert lhs == str(rhs), f'canonical elements differ: {lhs} vs {rhs}' - print(cgraph["canonical"]) - print(canonical(graph)) print("ok") From c1072a2a05c3c000ccd4c4bb057bcd2d8905488e Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 16 Aug 2024 14:17:51 +0200 Subject: [PATCH 097/704] WIP: canonical --- src/main.c | 162 ++++++++++++++++++++++++++--------------------------- test.py | 8 +-- 2 files changed, 82 insertions(+), 88 deletions(-) diff --git a/src/main.c b/src/main.c index 2101c40..b661758 100644 --- a/src/main.c +++ b/src/main.c @@ -257,9 +257,9 @@ typedef struct { uint32_t post; uint32_t rank; + uint32_t edge; uint32_t start; uint32_t end; - uint32_t edge; uint32_t next; } Post_Table; @@ -373,7 +373,7 @@ local_supremal(VA_Allocator const allocator, Graph const graph, size_t const len { printf(",\n"); } // if - printf(" \"%u:%u/%.*s\"", variant.start, variant.end, (int) variant.obs_end - variant.obs_start, observed + variant.obs_start); + printf(" \"" VAR_FMT "\"", print_variant(variant, observed)); } // for visited = allocator.alloc(allocator.context, visited, sizeof(*visited) * length, 0); @@ -383,6 +383,7 @@ local_supremal(VA_Allocator const allocator, Graph const graph, size_t const len typedef struct { uint32_t lca; + uint32_t rank; uint32_t depth; uint32_t start; uint32_t end; @@ -399,38 +400,18 @@ lca(uint32_t* const start, uint32_t lhs, uint32_t rhs, size_t const length, LCA_ { fprintf(stderr, " lca %u (%d), %u (%d)\n", lhs, lhs_start, rhs, rhs_start); - if (visited[lhs].depth > visited[rhs].depth) + while (visited[lhs].rank > visited[rhs].rank) { fprintf(stderr, " left\n"); lhs_start = visited[lhs].start; lhs = visited[lhs].lca; } // if - else if (visited[rhs].depth > visited[lhs].depth) + while (visited[rhs].rank > visited[lhs].rank) { fprintf(stderr, " right\n"); rhs_start = visited[rhs].start; rhs = visited[rhs].lca; } // if - else - { - /* - if (visited[lhs].lca == rhs) - { - lhs_start = visited[lhs].start; - lhs = rhs; - break; - } // if - else if (visited[rhs].lca == lhs) - { - break; - } // if - */ - fprintf(stderr, " both\n"); - lhs_start = visited[lhs].start; - rhs_start = visited[rhs].start; - lhs = visited[lhs].lca; - rhs = visited[rhs].lca; - } // else } // while *start = MIN(lhs_start, rhs_start); return lhs; @@ -450,88 +431,101 @@ canonical(VA_Allocator const allocator, Graph const graph, size_t const len_obs, for (uint32_t i = 0; i < length; ++i) { visited[i].depth = -1; - visited[i].next = -1; } // for uint32_t sink = -1; - visited[graph.source] = (LCA_Table) {-1, 0, -1, -1, -1}; + visited[graph.source] = (LCA_Table) {-1, 0, 0, -1, -1, -1}; + uint32_t rank = 1; for (uint32_t head = graph.source, tail = graph.source; head != (uint32_t) -1; head = visited[head].next) { - fprintf(stderr, "enter %u\n", head); - for (uint32_t i = head; i != (uint32_t) -1; i = graph.nodes[i].lambda) + fprintf(stderr, "enter %u @ %u\n", head, visited[head].depth); + + if (graph.nodes[head].edges == (uint32_t) -1) { - if (i != head) + fprintf(stderr, " sink\n"); + sink = head; + continue; + } // if + + uint32_t const lambda = graph.nodes[head].lambda; + if (lambda != (uint32_t) -1) + { + if (visited[lambda].depth == (uint32_t) -1) { - fprintf(stderr, " enter lambda %u\n", i); - if (visited[i].depth != visited[head].depth) - { - fprintf(stderr, " push lambda %u\n", i); - visited[i] = (LCA_Table) {head, visited[head].depth, visited[head].start, visited[head].end, visited[i].next}; - } // if - else - { - fprintf(stderr, " update lambda %u\n", i); - visited[i].lca = lca(&visited[i].start, head, visited[i].lca, length, visited); - visited[i].end = MAX(visited[i].end, visited[head].end); - fprintf(stderr, " lca = %u (%u, %u)\n", visited[i].lca, visited[i].start, visited[i].end); - } // else + fprintf(stderr, " push lambda %u @ %u\n", lambda, visited[head].depth); + visited[lambda] = (LCA_Table) {head, rank, visited[head].depth, -1, -1, visited[head].next}; + rank += 1; + visited[head].next = lambda; } // if - - if (graph.nodes[i].edges == (uint32_t) -1) + else if (visited[lambda].depth == visited[head].depth) { - fprintf(stderr, " sink\n"); - sink = i; + fprintf(stderr, " update lambda %u @ %u\n", lambda, visited[head].depth); + fprintf(stderr, " lca(%u, %u)\n", visited[lambda].lca, head); + uint32_t start = visited[lambda].start; + uint32_t const c = lca(&start, visited[lambda].lca, head, length, visited); + fprintf(stderr, " = %u (%u:%u)\n", c, start, visited[lambda].end); + visited[lambda].lca = c; + visited[lambda].start = start; } // if + else + { + fprintf(stderr, " improve lambda %u @ %u\n", lambda, visited[head].depth); + visited[lambda] = (LCA_Table) {head, visited[lambda].rank, visited[head].depth, -1, -1, visited[head].next}; + visited[head].next = lambda; + } // else + } // if - for (uint32_t j = graph.nodes[i].edges; j != (uint32_t) -1; j = graph.edges[j].next) + for (uint32_t i = graph.nodes[head].edges; i != (uint32_t) -1; i = graph.edges[i].next) + { + uint32_t const edge_tail = graph.edges[i].tail; + if (visited[edge_tail].depth == (uint32_t) -1) { - uint32_t const edge_tail = graph.edges[j].tail; - if (visited[edge_tail].depth == (uint32_t) -1) - { - fprintf(stderr, " push %u\n", edge_tail); - visited[edge_tail] = (LCA_Table) {i, visited[i].depth + 1, graph.edges[j].variant.start, graph.edges[j].variant.end, -1}; - visited[tail].next = edge_tail; - tail = edge_tail; - } // if - else if (visited[edge_tail].depth - 1 == visited[i].depth) - { - fprintf(stderr, " update %u\n", edge_tail); - visited[edge_tail].lca = lca(&visited[edge_tail].start, i, visited[edge_tail].lca, length, visited); - visited[edge_tail].end = MAX(visited[edge_tail].end, graph.edges[j].variant.end); - fprintf(stderr, " lca = %u (%u, %u)\n", visited[edge_tail].lca, visited[edge_tail].start, visited[edge_tail].end); - } // if - else - { - fprintf(stderr, " skip %u\n", edge_tail); - } // else - } // for + fprintf(stderr, " push %u @ %u\n", edge_tail, visited[head].depth + 1); + visited[edge_tail] = (LCA_Table) {head, rank, visited[head].depth + 1, graph.edges[i].variant.start, graph.edges[i].variant.end, -1}; + rank += 1; + visited[tail].next = edge_tail; + tail = edge_tail; + } // if + else if (visited[edge_tail].depth - 1 == visited[head].depth) + { + fprintf(stderr, " update %u @ %u\n", edge_tail, visited[edge_tail].depth); + fprintf(stderr, " lca(%u, %u)\n", visited[edge_tail].lca, head); + uint32_t start = MIN(visited[edge_tail].start, graph.edges[i].variant.start); + uint32_t const c = lca(&start, visited[edge_tail].lca, head, length, visited); + visited[edge_tail].lca = c; + visited[edge_tail].start = start; + visited[edge_tail].end = MAX(visited[edge_tail].end, graph.edges[i].variant.end); + fprintf(stderr, " = %u (%u:%u)\n", c, start, visited[edge_tail].end); + } // if + else + { + fprintf(stderr, " skip %u @ %u\n", edge_tail, visited[edge_tail].depth); + } // else } // for - } // while + } // for - fprintf(stderr, " # \tlca\tdepth\tstart\tend\tnext\n"); + fprintf(stderr, " # \tlca\trank\tdepth\tstart\tend\tnext\n"); for (uint32_t i = 0; i < length; ++i) { - fprintf(stderr, "%2u:\t%3d\t%5d\t%5d\t%3d\t%4d\n", i, visited[i].lca, visited[i].depth, visited[i].start, visited[i].end, visited[i].next); + fprintf(stderr, "%2u:\t%3d\t%4u\t%5u\t%5d\t%3d\t%4d\n", i, visited[i].lca, visited[i].rank, visited[i].depth, visited[i].start, visited[i].end, visited[i].next); } // for - VA_Variant* variants = NULL; - for (uint32_t tail = sink; tail != (uint32_t) -1 && visited[tail].lca != (uint32_t) -1; tail = visited[tail].lca) + for (uint32_t tail = sink; tail != (uint32_t) -1; tail = visited[tail].lca) { uint32_t const head = visited[tail].lca; - uint32_t const start_offset = visited[tail].start - graph.nodes[head].row; - uint32_t const end_offset = visited[tail].end - graph.nodes[tail].row; - va_array_insert(va_std_allocator, variants, ((VA_Variant) {visited[tail].start, visited[tail].end, graph.nodes[head].col + start_offset, graph.nodes[tail].col + end_offset}), 0); - } // for - - if (variants != NULL) - { - for (size_t i = 0; i < va_array_length(variants); ++i) + if (head != (uint32_t) - 1 && visited[tail].start != (uint32_t) -1) { - printf(" \"" VAR_FMT "\"%s\n", print_variant(variants[i], observed), i < va_array_length(variants) - 1 ? "," : ""); - } // for - } // if + uint32_t const start_offset = visited[tail].start - graph.nodes[head].row; + uint32_t const end_offset = visited[tail].end - graph.nodes[tail].row; + VA_Variant const variant = {visited[tail].start, visited[tail].end, graph.nodes[head].col + start_offset, graph.nodes[tail].col + end_offset}; - variants = va_array_destroy(va_std_allocator, variants); + if (tail != sink) + { + printf(",\n"); + } // if + printf(" \"" VAR_FMT "\"", print_variant(variant, observed)); + } // if + } // while visited = allocator.alloc(allocator.context, visited, sizeof(*visited) * length, 0); } // canonical diff --git a/test.py b/test.py index 6d0ab5c..9ca97b0 100644 --- a/test.py +++ b/test.py @@ -22,8 +22,8 @@ def main(): #if random.random() > 0.5: # prefix = random_sequence(1000) # suffix = random_sequence(1000) - reference = prefix + random_sequence(10) + suffix - observed = prefix + random_sequence(10) + suffix + reference = prefix + random_sequence(12) + suffix + observed = prefix + random_sequence(12) + suffix print(reference, observed) @@ -70,11 +70,11 @@ def main(): assert lhs == str(rhs), f'local supremal elements differ: {lhs} vs {rhs}' if debug: - print(cgraph["canonical"], canonical(graph)) + print(list(reversed(cgraph["canonical"])), canonical(graph)) assert len(cgraph["canonical"]) == len(canonical(graph)), f'canonical length' - for lhs, rhs in zip(cgraph["canonical"], canonical(graph)): + for lhs, rhs in zip(reversed(cgraph["canonical"]), canonical(graph)): assert lhs == str(rhs), f'canonical elements differ: {lhs} vs {rhs}' print("ok") From 54eca786cba5d7b1369ceeff7b19aaba6e1edad0 Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 16 Aug 2024 15:05:43 +0200 Subject: [PATCH 098/704] WIP: some problems in canonical annotated --- src/main.c | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/src/main.c b/src/main.c index b661758..ff03a09 100644 --- a/src/main.c +++ b/src/main.c @@ -436,9 +436,10 @@ canonical(VA_Allocator const allocator, Graph const graph, size_t const len_obs, uint32_t sink = -1; visited[graph.source] = (LCA_Table) {-1, 0, 0, -1, -1, -1}; uint32_t rank = 1; + // main loop over a queue for (uint32_t head = graph.source, tail = graph.source; head != (uint32_t) -1; head = visited[head].next) { - fprintf(stderr, "enter %u @ %u\n", head, visited[head].depth); + fprintf(stderr, "pop %u @ %u\n", head, visited[head].depth); if (graph.nodes[head].edges == (uint32_t) -1) { @@ -452,6 +453,7 @@ canonical(VA_Allocator const allocator, Graph const graph, size_t const len_obs, { if (visited[lambda].depth == (uint32_t) -1) { + // add lambda in stack order fprintf(stderr, " push lambda %u @ %u\n", lambda, visited[head].depth); visited[lambda] = (LCA_Table) {head, rank, visited[head].depth, -1, -1, visited[head].next}; rank += 1; @@ -461,15 +463,26 @@ canonical(VA_Allocator const allocator, Graph const graph, size_t const len_obs, { fprintf(stderr, " update lambda %u @ %u\n", lambda, visited[head].depth); fprintf(stderr, " lca(%u, %u)\n", visited[lambda].lca, head); - uint32_t start = visited[lambda].start; - uint32_t const c = lca(&start, visited[lambda].lca, head, length, visited); - fprintf(stderr, " = %u (%u:%u)\n", c, start, visited[lambda].end); - visited[lambda].lca = c; - visited[lambda].start = start; + visited[lambda].lca = lca(&visited[lambda].start, visited[lambda].lca, head, length, visited); + + // FIXME: what is correct here? + // AGGCCG CGCAGCCTC ignores the common end position + // TAATTGGTAG CTATTCAG needs the common end position + + //visited[lambda].end = graph.nodes[head].row; // this simulates the empty variant on a lambda edge + + fprintf(stderr, " = %u (%u:%u)\n", visited[lambda].lca, visited[lambda].start, visited[lambda].end); } // if else { fprintf(stderr, " improve lambda %u @ %u\n", lambda, visited[head].depth); + + // FIXME: what about the original link to lambda? + // lambda is already in the queue and should be *moved* instead of added again (in stack order) + // if moving is difficult we can possibly skip nodes that are already processed (in the main loop) + // possibly related: + // INFINITE LOOP: CAGCGAGT CGTGTAAGGTGTACTGAAA + visited[lambda] = (LCA_Table) {head, visited[lambda].rank, visited[head].depth, -1, -1, visited[head].next}; visited[head].next = lambda; } // else @@ -480,6 +493,7 @@ canonical(VA_Allocator const allocator, Graph const graph, size_t const len_obs, uint32_t const edge_tail = graph.edges[i].tail; if (visited[edge_tail].depth == (uint32_t) -1) { + // add regular successors in queue order fprintf(stderr, " push %u @ %u\n", edge_tail, visited[head].depth + 1); visited[edge_tail] = (LCA_Table) {head, rank, visited[head].depth + 1, graph.edges[i].variant.start, graph.edges[i].variant.end, -1}; rank += 1; @@ -490,12 +504,10 @@ canonical(VA_Allocator const allocator, Graph const graph, size_t const len_obs, { fprintf(stderr, " update %u @ %u\n", edge_tail, visited[edge_tail].depth); fprintf(stderr, " lca(%u, %u)\n", visited[edge_tail].lca, head); - uint32_t start = MIN(visited[edge_tail].start, graph.edges[i].variant.start); - uint32_t const c = lca(&start, visited[edge_tail].lca, head, length, visited); - visited[edge_tail].lca = c; - visited[edge_tail].start = start; + visited[edge_tail].start = MIN(visited[edge_tail].start, graph.edges[i].variant.start); + visited[edge_tail].lca = lca(&visited[edge_tail].start, visited[edge_tail].lca, head, length, visited); visited[edge_tail].end = MAX(visited[edge_tail].end, graph.edges[i].variant.end); - fprintf(stderr, " = %u (%u:%u)\n", c, start, visited[edge_tail].end); + fprintf(stderr, " = %u (%u:%u)\n", visited[edge_tail].lca, visited[edge_tail].start, visited[edge_tail].end); } // if else { @@ -510,11 +522,13 @@ canonical(VA_Allocator const allocator, Graph const graph, size_t const len_obs, fprintf(stderr, "%2u:\t%3d\t%4u\t%5u\t%5d\t%3d\t%4d\n", i, visited[i].lca, visited[i].rank, visited[i].depth, visited[i].start, visited[i].end, visited[i].next); } // for + // the canonical variant is given in the reverse order (for now): the Python checker needs to reverse this list for (uint32_t tail = sink; tail != (uint32_t) -1; tail = visited[tail].lca) { uint32_t const head = visited[tail].lca; if (head != (uint32_t) - 1 && visited[tail].start != (uint32_t) -1) { + // we need to skip lambda edges: start && end == -1 uint32_t const start_offset = visited[tail].start - graph.nodes[head].row; uint32_t const end_offset = visited[tail].end - graph.nodes[tail].row; VA_Variant const variant = {visited[tail].start, visited[tail].end, graph.nodes[head].col + start_offset, graph.nodes[tail].col + end_offset}; From 1ff44bc805f90f6c8c7d05ca2537bd3c58932546 Mon Sep 17 00:00:00 2001 From: jkvis Date: Sat, 17 Aug 2024 10:41:41 +0200 Subject: [PATCH 099/704] A fix for out-of-order lambda's --- src/main.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main.c b/src/main.c index ff03a09..07a3af3 100644 --- a/src/main.c +++ b/src/main.c @@ -482,7 +482,15 @@ canonical(VA_Allocator const allocator, Graph const graph, size_t const len_obs, // if moving is difficult we can possibly skip nodes that are already processed (in the main loop) // possibly related: // INFINITE LOOP: CAGCGAGT CGTGTAAGGTGTACTGAAA + // FIXED by probing the visited table + // FIXME: how often does this occur? + uint32_t probe = head; + while (visited[probe].next != lambda) + { + probe = visited[probe].next; + } // while + visited[probe].next = visited[lambda].next; visited[lambda] = (LCA_Table) {head, visited[lambda].rank, visited[head].depth, -1, -1, visited[head].next}; visited[head].next = lambda; } // else From f0e0f293dda16861e79b129ea50fda794fb27071 Mon Sep 17 00:00:00 2001 From: jkvis Date: Sat, 17 Aug 2024 10:54:16 +0200 Subject: [PATCH 100/704] A better? fix for out-of-order lambda's --- src/main.c | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/src/main.c b/src/main.c index 07a3af3..df4ac20 100644 --- a/src/main.c +++ b/src/main.c @@ -387,6 +387,7 @@ typedef struct uint32_t depth; uint32_t start; uint32_t end; + uint32_t prev; uint32_t next; } LCA_Table; @@ -434,7 +435,7 @@ canonical(VA_Allocator const allocator, Graph const graph, size_t const len_obs, } // for uint32_t sink = -1; - visited[graph.source] = (LCA_Table) {-1, 0, 0, -1, -1, -1}; + visited[graph.source] = (LCA_Table) {-1, 0, 0, -1, -1, -1, -1}; uint32_t rank = 1; // main loop over a queue for (uint32_t head = graph.source, tail = graph.source; head != (uint32_t) -1; head = visited[head].next) @@ -455,7 +456,7 @@ canonical(VA_Allocator const allocator, Graph const graph, size_t const len_obs, { // add lambda in stack order fprintf(stderr, " push lambda %u @ %u\n", lambda, visited[head].depth); - visited[lambda] = (LCA_Table) {head, rank, visited[head].depth, -1, -1, visited[head].next}; + visited[lambda] = (LCA_Table) {head, rank, visited[head].depth, -1, -1, head, visited[head].next}; rank += 1; visited[head].next = lambda; } // if @@ -482,16 +483,10 @@ canonical(VA_Allocator const allocator, Graph const graph, size_t const len_obs, // if moving is difficult we can possibly skip nodes that are already processed (in the main loop) // possibly related: // INFINITE LOOP: CAGCGAGT CGTGTAAGGTGTACTGAAA - // FIXED by probing the visited table - // FIXME: how often does this occur? + // FIXED by double linked list - uint32_t probe = head; - while (visited[probe].next != lambda) - { - probe = visited[probe].next; - } // while - visited[probe].next = visited[lambda].next; - visited[lambda] = (LCA_Table) {head, visited[lambda].rank, visited[head].depth, -1, -1, visited[head].next}; + visited[visited[lambda].prev].next = visited[lambda].next; + visited[lambda] = (LCA_Table) {head, visited[lambda].rank, visited[head].depth, -1, -1, head, visited[head].next}; visited[head].next = lambda; } // else } // if @@ -503,7 +498,7 @@ canonical(VA_Allocator const allocator, Graph const graph, size_t const len_obs, { // add regular successors in queue order fprintf(stderr, " push %u @ %u\n", edge_tail, visited[head].depth + 1); - visited[edge_tail] = (LCA_Table) {head, rank, visited[head].depth + 1, graph.edges[i].variant.start, graph.edges[i].variant.end, -1}; + visited[edge_tail] = (LCA_Table) {head, rank, visited[head].depth + 1, graph.edges[i].variant.start, graph.edges[i].variant.end, tail, -1}; rank += 1; visited[tail].next = edge_tail; tail = edge_tail; @@ -524,10 +519,10 @@ canonical(VA_Allocator const allocator, Graph const graph, size_t const len_obs, } // for } // for - fprintf(stderr, " # \tlca\trank\tdepth\tstart\tend\tnext\n"); + fprintf(stderr, " # \tlca\trank\tdepth\tstart\tend\tprev\tnext\n"); for (uint32_t i = 0; i < length; ++i) { - fprintf(stderr, "%2u:\t%3d\t%4u\t%5u\t%5d\t%3d\t%4d\n", i, visited[i].lca, visited[i].rank, visited[i].depth, visited[i].start, visited[i].end, visited[i].next); + fprintf(stderr, "%2u:\t%3d\t%4u\t%5u\t%5d\t%3d\t%4d\t%4d\n", i, visited[i].lca, visited[i].rank, visited[i].depth, visited[i].start, visited[i].end, visited[i].prev, visited[i].next); } // for // the canonical variant is given in the reverse order (for now): the Python checker needs to reverse this list From 918e1f15eacad131027d8914a6a344d2bb73c2d6 Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 2 Sep 2024 08:29:49 +0200 Subject: [PATCH 101/704] Bug in allocator --- include/static_alloc.h | 2 +- include/std_alloc.h | 14 ++++---------- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/include/static_alloc.h b/include/static_alloc.h index d5be1dd..026bd6c 100644 --- a/include/static_alloc.h +++ b/include/static_alloc.h @@ -9,7 +9,7 @@ extern "C" #include // NULL, size_t -#define KiB(size) ((size_t) size * 1024ULL) +#define KiB(size) (((size_t) (size)) * 1024ULL) #define MiB(size) (KiB(size) * 1024ULL) #define GiB(size) (MiB(size) * 1024ULL) diff --git a/include/std_alloc.h b/include/std_alloc.h index cea0673..4cbdb4c 100644 --- a/include/std_alloc.h +++ b/include/std_alloc.h @@ -8,7 +8,6 @@ extern "C" #include // NULL, size_t #include // free, realloc -#include // memset #include "alloc.h" // VA_Allocator @@ -16,27 +15,22 @@ extern "C" static inline void* va_std_alloc(void* const restrict context, void* const restrict ptr, size_t const old_size, size_t const size) { + (void) context; + (void) old_size; + if (size == 0) { free(ptr); return NULL; } // if - (void) context; - (void) old_size; - char* const restrict new_ptr = realloc(ptr, size); if (new_ptr == NULL) { + free(ptr); return NULL; // OOM } // if - /* - if (size > old_size) - { - (void) memset(new_ptr + old_size, 0, size - old_size); - } // if - */ return new_ptr; } // va_std_alloc From 771326bc99f2babc08915ad0973c8def4b731ed9 Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 2 Sep 2024 13:28:29 +0200 Subject: [PATCH 102/704] Json layout --- src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.c b/src/main.c index df4ac20..dc69551 100644 --- a/src/main.c +++ b/src/main.c @@ -638,7 +638,7 @@ to_json(Graph const graph, size_t const len_obs, char const observed[static len_ printf("\n ],\n"); printf(" \"canonical\": [\n"); canonical(va_std_allocator, graph, len_obs, observed); - printf(" ]\n"); + printf("\n ]\n"); printf("}"); } // to_json From 7aec7dc9f093ff2149cc3963566b38ee3c9a2ec0 Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 2 Sep 2024 17:06:49 +0200 Subject: [PATCH 103/704] Fixed update tail when moving lambda --- src/main.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main.c b/src/main.c index dc69551..62f3ca5 100644 --- a/src/main.c +++ b/src/main.c @@ -483,8 +483,12 @@ canonical(VA_Allocator const allocator, Graph const graph, size_t const len_obs, // if moving is difficult we can possibly skip nodes that are already processed (in the main loop) // possibly related: // INFINITE LOOP: CAGCGAGT CGTGTAAGGTGTACTGAAA - // FIXED by double linked list + // FIXED by doubly linked list + if (lambda == tail) + { + tail = visited[lambda].prev; + } // if visited[visited[lambda].prev].next = visited[lambda].next; visited[lambda] = (LCA_Table) {head, visited[lambda].rank, visited[head].depth, -1, -1, head, visited[head].next}; visited[head].next = lambda; From b85fe7c4040b3705b8509a2913eed556b193b0fe Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 3 Sep 2024 09:27:57 +0200 Subject: [PATCH 104/704] Timeout for subprocess --- test.py | 48 ++++++++++++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 20 deletions(-) diff --git a/test.py b/test.py index 9ca97b0..7df8425 100644 --- a/test.py +++ b/test.py @@ -9,24 +9,7 @@ from algebra.utils import random_sequence, to_dot -def main(): - prefix = "" - suffix = "" - debug = False - - if len(sys.argv) > 1: - reference = sys.argv[1] - observed = sys.argv[2] - debug = True - else: - #if random.random() > 0.5: - # prefix = random_sequence(1000) - # suffix = random_sequence(1000) - reference = prefix + random_sequence(12) + suffix - observed = prefix + random_sequence(12) + suffix - - print(reference, observed) - +def check(reference, observed, debug=False, timeout=1): graph = LCSgraph.from_sequence(reference, observed); valgrind = [] if debug: @@ -34,7 +17,7 @@ def main(): print(canonical(graph)) valgrind = ["valgrind", "--leak-check=full", "--error-exitcode=1"] - stdout = subprocess.run([*valgrind, "./a.out", reference, observed], check=True, stdout=subprocess.PIPE).stdout.decode("utf-8") + stdout = subprocess.run([*valgrind, "./a.out", reference, observed], check=True, stdout=subprocess.PIPE, timeout=timeout).stdout.decode("utf-8") try: cgraph = json.loads(stdout) @@ -77,7 +60,32 @@ def main(): for lhs, rhs in zip(reversed(cgraph["canonical"]), canonical(graph)): assert lhs == str(rhs), f'canonical elements differ: {lhs} vs {rhs}' - print("ok") + +def main(): + if len(sys.argv) == 3: + return check(sys.argv[1], sys.argv[2], debug=True) + + failed = [] + n = 0 + while True: + prefix = "" + suffix = "" + #if random.random() > 0.5: + # prefix = random_sequence(1000) + # suffix = random_sequence(1000) + reference = prefix + random_sequence(12) + suffix + observed = prefix + random_sequence(12) + suffix + + try: + print(reference, observed) + check(reference, observed) + n += 1 + except Exception as exc: + failed.append({"reference": reference, "observed": observed, "exception": exc}) + break; + + print() + print(n, failed) if __name__ == "__main__": From 7df87c02f9bdd2f10ff86ab0ac21764371cb497f Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 3 Sep 2024 15:31:53 +0200 Subject: [PATCH 105/704] More testing on canonical --- src/main.c | 55 ++++++++++++++++++++++++++++++++++++++++++++---------- test.py | 21 +++++++++++++++------ 2 files changed, 60 insertions(+), 16 deletions(-) diff --git a/src/main.c b/src/main.c index 62f3ca5..96f16f9 100644 --- a/src/main.c +++ b/src/main.c @@ -419,6 +419,18 @@ lca(uint32_t* const start, uint32_t lhs, uint32_t rhs, size_t const length, LCA_ } // lca +static void +print_lca_table(size_t const length, LCA_Table const visited[static length], uint32_t const head, uint32_t const tail) +{ + fprintf(stderr, " # \tlca\trank\tdepth\tstart\tend\tprev\tnext\n"); + for (uint32_t i = 0; i < length; ++i) + { + fprintf(stderr, "%2u:\t%3d\t%4d\t%5d\t%5d\t%3d\t%4d\t%4d\n", i, visited[i].lca, visited[i].rank, visited[i].depth, visited[i].start, visited[i].end, visited[i].prev, visited[i].next); + } // for + fprintf(stderr, "head: %d\ntail: %d\n", head, tail); +} // print_lca_table + + static void canonical(VA_Allocator const allocator, Graph const graph, size_t const len_obs, char const observed[static len_obs]) { @@ -432,6 +444,14 @@ canonical(VA_Allocator const allocator, Graph const graph, size_t const len_obs, for (uint32_t i = 0; i < length; ++i) { visited[i].depth = -1; + + visited[i].lca = -1; + visited[i].rank = -1; + visited[i].start = -1; + visited[i].end = -1; + visited[i].prev = -1; + visited[i].next = -1; + } // for uint32_t sink = -1; @@ -456,6 +476,8 @@ canonical(VA_Allocator const allocator, Graph const graph, size_t const len_obs, { // add lambda in stack order fprintf(stderr, " push lambda %u @ %u\n", lambda, visited[head].depth); + + visited[visited[head].next].prev = lambda; visited[lambda] = (LCA_Table) {head, rank, visited[head].depth, -1, -1, head, visited[head].next}; rank += 1; visited[head].next = lambda; @@ -485,14 +507,29 @@ canonical(VA_Allocator const allocator, Graph const graph, size_t const len_obs, // INFINITE LOOP: CAGCGAGT CGTGTAAGGTGTACTGAAA // FIXED by doubly linked list - if (lambda == tail) + if (visited[head].next == lambda) { - tail = visited[lambda].prev; + visited[lambda] = (LCA_Table) {head, visited[lambda].rank, visited[head].depth, -1, -1, visited[lambda].prev, visited[lambda].next}; } // if - visited[visited[lambda].prev].next = visited[lambda].next; - visited[lambda] = (LCA_Table) {head, visited[lambda].rank, visited[head].depth, -1, -1, head, visited[head].next}; - visited[head].next = lambda; + else + { + if (lambda == tail) + { + tail = visited[lambda].prev; + } // if + else + { + visited[visited[lambda].next].prev = visited[lambda].prev; + } // else + visited[visited[head].next].prev = lambda; + visited[visited[lambda].prev].next = visited[lambda].next; + visited[lambda] = (LCA_Table) {head, visited[lambda].rank, visited[head].depth, -1, -1, head, visited[head].next}; + visited[head].next = lambda; + } // else } // else + + //print_lca_table(length, visited, head, tail); + } // if for (uint32_t i = graph.nodes[head].edges; i != (uint32_t) -1; i = graph.edges[i].next) @@ -520,14 +557,12 @@ canonical(VA_Allocator const allocator, Graph const graph, size_t const len_obs, { fprintf(stderr, " skip %u @ %u\n", edge_tail, visited[edge_tail].depth); } // else + + //print_lca_table(length, visited, head, tail); } // for } // for - fprintf(stderr, " # \tlca\trank\tdepth\tstart\tend\tprev\tnext\n"); - for (uint32_t i = 0; i < length; ++i) - { - fprintf(stderr, "%2u:\t%3d\t%4u\t%5u\t%5d\t%3d\t%4d\t%4d\n", i, visited[i].lca, visited[i].rank, visited[i].depth, visited[i].start, visited[i].end, visited[i].prev, visited[i].next); - } // for + print_lca_table(length, visited, -1, -1); // the canonical variant is given in the reverse order (for now): the Python checker needs to reverse this list for (uint32_t tail = sink; tail != (uint32_t) -1; tail = visited[tail].lca) diff --git a/test.py b/test.py index 7df8425..268afc9 100644 --- a/test.py +++ b/test.py @@ -1,5 +1,6 @@ import json import random +import signal import subprocess import sys @@ -9,8 +10,12 @@ from algebra.utils import random_sequence, to_dot +def handler(signum, frame): + raise KeyboardInterrupt + + def check(reference, observed, debug=False, timeout=1): - graph = LCSgraph.from_sequence(reference, observed); + graph = LCSgraph.from_sequence(reference, observed) valgrind = [] if debug: print("\n".join(to_dot(reference, graph, labels=False, hgvs=False))) @@ -28,10 +33,10 @@ def check(reference, observed, debug=False, timeout=1): assert str(graph.supremal) == cgraph["supremal"], f'supremals differ: {cgraph["supremal"]} vs {graph.supremal}' nodes = list(graph.nodes()) - edges = list(graph.bfs_traversal()); + edges = list(graph.bfs_traversal()) assert len(cgraph["nodes"]) == len(nodes), f'# cgraph nodes {len(cgraph["nodes"])} vs # graph nodes {len(nodes)}' - assert len(cgraph["edges"]) == len(edges), f'# cgraph edges {len(cgraph["edges"])} vs # graph edges {len(edgse)}' + assert len(cgraph["edges"]) == len(edges), f'# cgraph edges {len(cgraph["edges"])} vs # graph edges {len(edges)}' for cnode in cgraph["nodes"].values(): try: @@ -65,6 +70,8 @@ def main(): if len(sys.argv) == 3: return check(sys.argv[1], sys.argv[2], debug=True) + signal.signal(signal.SIGINT, handler) + failed = [] n = 0 while True: @@ -73,16 +80,18 @@ def main(): #if random.random() > 0.5: # prefix = random_sequence(1000) # suffix = random_sequence(1000) - reference = prefix + random_sequence(12) + suffix - observed = prefix + random_sequence(12) + suffix + reference = prefix + random_sequence(30) + suffix + observed = prefix + random_sequence(30) + suffix try: print(reference, observed) check(reference, observed) n += 1 + except KeyboardInterrupt: + break; except Exception as exc: failed.append({"reference": reference, "observed": observed, "exception": exc}) - break; + break print() print(n, failed) From e38054f9b73a740e2d3b7b117a4727cf0522ff6d Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 3 Sep 2024 16:52:51 +0200 Subject: [PATCH 106/704] Return of the ; --- test.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test.py b/test.py index 268afc9..cfe8f6f 100644 --- a/test.py +++ b/test.py @@ -83,12 +83,14 @@ def main(): reference = prefix + random_sequence(30) + suffix observed = prefix + random_sequence(30) + suffix + if n % 1_000 == 0: + print(n) + try: - print(reference, observed) check(reference, observed) n += 1 except KeyboardInterrupt: - break; + break except Exception as exc: failed.append({"reference": reference, "observed": observed, "exception": exc}) break From a4c4b7e15ade2a8196508b9fde77735354752d65 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Tue, 3 Sep 2024 17:00:45 +0200 Subject: [PATCH 107/704] Store examples for future generations. --- src/main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main.c b/src/main.c index 62f3ca5..e4cf93a 100644 --- a/src/main.c +++ b/src/main.c @@ -468,7 +468,9 @@ canonical(VA_Allocator const allocator, Graph const graph, size_t const len_obs, // FIXME: what is correct here? // AGGCCG CGCAGCCTC ignores the common end position + // ACAGGA CAAGGCG // TAATTGGTAG CTATTCAG needs the common end position + // TTAAG TAACA //visited[lambda].end = graph.nodes[head].row; // this simulates the empty variant on a lambda edge From 2a49d5c491c148d59b6402b3098f7103fabc3776 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Tue, 3 Sep 2024 17:02:06 +0200 Subject: [PATCH 108/704] Output lambda based graph as is. --- src/main.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/main.c b/src/main.c index e4cf93a..6afb39a 100644 --- a/src/main.c +++ b/src/main.c @@ -628,6 +628,41 @@ bfs_traversal(VA_Allocator const allocator, Graph const graph, size_t const len_ } // bfs_traversal +static void +to_dot_raw(Graph const graph, size_t const len_obs, char const observed[static len_obs]) +{ + printf(" \"edges\": [\n"); + size_t count = 0; + for (uint32_t i = 0; i < va_array_length(graph.nodes); ++i) + { +// fprintf(stderr, "s%u[label=\"(%u, %u, %u)\"%s]\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, graph.nodes[i].edges == (uint32_t) -1 ? ",peripheries=2" : ""); + if (graph.nodes[i].lambda != (uint32_t) -1) + { +// fprintf(stderr, "s%u->s%u[label=\"λ\",style=\"dashed\"]\n", i, graph.nodes[i].lambda); + if (count > 0) + { + printf(",\n"); + } // if + count += 1; + printf(" {\"head\": \"s%u\", \"tail\": \"s%u\", \"variant\": \"lambda\"}", i, graph.nodes[i].lambda); + } // if + for (uint32_t j = graph.nodes[i].edges; j != (uint32_t) -1; j = graph.edges[j].next) + { + if (count > 0) + { + printf(",\n"); + } // if + count += 1; + printf(" {\"head\": \"s%u\", \"tail\": \"s%u\", \"variant\": \"%u:%u/%.*s\"}", i, graph.edges[j].tail, graph.edges[j].variant.start, graph.edges[j].variant.end, (int) graph.edges[j].variant.obs_end - graph.edges[j].variant.obs_start, observed + graph.edges[j].variant.obs_start); +// fprintf(stderr, "s%u->s%u[label=\"%u:%u/%.*s\"]\n", i, graph.edges[j].tail, graph.edges[j].variant.start, graph.edges[j].variant.end, (int) graph.edges[j].variant.obs_end - graph.edges[j].variant.obs_start, observed + graph.edges[j].variant.obs_start); + } // for + } // for + printf("\n ],\n"); +} // to_dot + + + + static void to_json(Graph const graph, size_t const len_obs, char const observed[static len_obs]) { From ddd7ddd78917baecb2b61163f28137896bd6d61d Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Tue, 3 Sep 2024 17:09:32 +0200 Subject: [PATCH 109/704] Parametrize and properder name. --- src/main.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/main.c b/src/main.c index ff834af..2056e49 100644 --- a/src/main.c +++ b/src/main.c @@ -664,16 +664,14 @@ bfs_traversal(VA_Allocator const allocator, Graph const graph, size_t const len_ static void -to_dot_raw(Graph const graph, size_t const len_obs, char const observed[static len_obs]) +lambda_edges(Graph const graph, size_t const len_obs, char const observed[static len_obs]) { printf(" \"edges\": [\n"); size_t count = 0; for (uint32_t i = 0; i < va_array_length(graph.nodes); ++i) { -// fprintf(stderr, "s%u[label=\"(%u, %u, %u)\"%s]\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, graph.nodes[i].edges == (uint32_t) -1 ? ",peripheries=2" : ""); if (graph.nodes[i].lambda != (uint32_t) -1) { -// fprintf(stderr, "s%u->s%u[label=\"λ\",style=\"dashed\"]\n", i, graph.nodes[i].lambda); if (count > 0) { printf(",\n"); @@ -689,17 +687,14 @@ to_dot_raw(Graph const graph, size_t const len_obs, char const observed[static l } // if count += 1; printf(" {\"head\": \"s%u\", \"tail\": \"s%u\", \"variant\": \"%u:%u/%.*s\"}", i, graph.edges[j].tail, graph.edges[j].variant.start, graph.edges[j].variant.end, (int) graph.edges[j].variant.obs_end - graph.edges[j].variant.obs_start, observed + graph.edges[j].variant.obs_start); -// fprintf(stderr, "s%u->s%u[label=\"%u:%u/%.*s\"]\n", i, graph.edges[j].tail, graph.edges[j].variant.start, graph.edges[j].variant.end, (int) graph.edges[j].variant.obs_end - graph.edges[j].variant.obs_start, observed + graph.edges[j].variant.obs_start); } // for } // for printf("\n ],\n"); -} // to_dot - - +} // lambda_edges static void -to_json(Graph const graph, size_t const len_obs, char const observed[static len_obs]) +to_json(Graph const graph, size_t const len_obs, char const observed[static len_obs], bool lambda) { printf("{\n \"source\": \"s%u\",\n \"nodes\": {\n", graph.source); for (uint32_t i = 0; i < va_array_length(graph.nodes); ++i) @@ -707,7 +702,11 @@ to_json(Graph const graph, size_t const len_obs, char const observed[static len_ printf(" \"s%u\": {\"row\": %u, \"col\": %u, \"length\": %u}%s\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, i < va_array_length(graph.nodes) - 1 ? "," : ""); } // for printf(" },\n"); - bfs_traversal(va_std_allocator, graph, len_obs, observed); + if (lambda) { + lambda_edges(graph, len_obs, observed); + } else { + bfs_traversal(va_std_allocator, graph, len_obs, observed); + } printf(" \"supremal\": \"%u:%u/%.*s\",\n", graph.supremal.start, graph.supremal.end, (int) graph.supremal.obs_end - graph.supremal.obs_start, observed + graph.supremal.obs_start); printf(" \"local_supremal\": [\n"); local_supremal(va_std_allocator, graph, len_obs, observed); @@ -775,7 +774,7 @@ main(int argc, char* argv[static argc + 1]) //canonical(va_std_allocator, graph, len_obs, observed); - to_json(graph, len_obs, observed); + to_json(graph, len_obs, observed, false); destroy(va_std_allocator, &graph); From f3b0cbe3f7323870fbb9fa8236310147e5b3312c Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Wed, 4 Sep 2024 02:52:12 +0200 Subject: [PATCH 110/704] WIP networkx based extractor. --- q.py | 177 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 177 insertions(+) create mode 100644 q.py diff --git a/q.py b/q.py new file mode 100644 index 0000000..c4b4340 --- /dev/null +++ b/q.py @@ -0,0 +1,177 @@ +import json +import random +import subprocess +import sys + +from algebra import LCSgraph +from algebra.extractor import local_supremal +from algebra.extractor.extractor import canonical +from algebra.utils import random_sequence, to_dot + +from algebra.variants import Variant + + +from itertools import chain + +from functools import reduce + +import networkx as nx + + +def post_dominators(G, source): + def intersect(u, v): + while u != v: + while nodes[u]["dfn"] < nodes[v]["dfn"]: + u = nodes[u]["ipdom"] + while nodes[u]["dfn"] > nodes[v]["dfn"]: + v = nodes[v]["ipdom"] + return u + + nodes = {} + for idx, u in enumerate(nx.dfs_postorder_nodes(G, source)): + if not G.succ[u]: + nodes[u] = {"ipdom": u, "dfn": len(G.nodes()) - idx - 1} + else: + nodes[u] = {"ipdom": reduce(intersect, list(G.succ[u])), "dfn": len(G.nodes()) - idx - 1} + + return nodes + + + +def main(): + debug = False + + if len(sys.argv) > 1: + reference = sys.argv[1] + observed = sys.argv[2] + debug = True + else: + reference = random_sequence(32, 8) + observed = random_sequence(32, 8) + + print(reference, observed) + + stdout = subprocess.run(["./a.out", reference, observed], check=True, stdout=subprocess.PIPE).stdout.decode("utf-8") + try: + cgraph = json.loads(stdout) + except json.decoder.JSONDecodeError as exc: + print(f'\"{stdout}\"') + raise exc + + print(cgraph) + # print(cgraph["nodes"]) + # print(cgraph["edges"]) + + DG = nx.MultiDiGraph() + DG.add_nodes_from([(k, cgraph["nodes"][k]) for k in cgraph["nodes"]]) + DG.add_edges_from([(e['head'], e['tail'], {'variant': e['variant'], 'weight': 0 if e['variant'] == 'lambda' else 1}) for e in cgraph["edges"]]) + + # print(DG.nodes) + # print(DG.nodes["s0"]) + # + # print(DG.edges) + # print(DG.edges[('s1', 's2')]) + + # print(list(nx.all_shortest_paths(DG, "s7", "s0"))) + all_paths = nx.all_shortest_paths(DG, cgraph["source"], "s0", weight="weight") + # print("all paths", list(all_paths)) + # targets = [] + targets2 = [] + for x in set(chain(*all_paths)): + # targets.append(LCSgraph.Node(DG.nodes[x]["row"], DG.nodes[x]["col"], DG.nodes[x]["length"])) + targets2.append(x) + + # print("targets to keep", targets) + + to_remove2 = [] + for n in DG.nodes: + if n not in targets2: + to_remove2.append(n) + for n in to_remove2: + DG.remove_node(n) + + graph = LCSgraph.from_sequence(reference, observed) + # print("local supremal", local_supremal(reference, graph)) + + # print(list(graph.nodes())) + # x = graph.nodes() + # for y in x: + # print("edges", y.edges) + # + # to_remove = [] + # for z in y.edges: + # print("z", z) + # if z[0] not in targets: + # print("remove") + # to_remove.append(z) + # print("z", z) + # for q in to_remove: + # y.edges.remove(q) + # print("edges after", y.edges) + + + # print("remaining nodes", list(DG.nodes())) + # print("remaining edges", list(DG.edges())) + + # print(nx.dominance_frontiers(DG, cgraph["source"])) + # print(nx.dominance_frontiers(DG.reverse(), "s0")) + # print(nx.immediate_dominators(DG, cgraph["source"])) + # print(nx.immediate_dominators(DG.reverse(), "s0")) + i = nx.immediate_dominators(DG.reverse(), "s0") + print(i) + + lhs = cgraph["source"] + variant = [] + while lhs != i[lhs]: + rhs = i[lhs] + print(lhs, DG.nodes[lhs], rhs, DG.nodes[rhs]) + if (DG.nodes[lhs]["row"] + DG.nodes[lhs]["length"] == DG.nodes[rhs]["row"] + DG.nodes[rhs]["length"] and + DG.nodes[lhs]["col"] + DG.nodes[lhs]["length"] == DG.nodes[rhs]["col"] + DG.nodes[rhs]["length"]): + print("lambda?") + else: + print(DG.edges(lhs, data="variant")) + del_start = min([int(e[2].split(":")[0]) for e in filter(lambda e: e[2] != "lambda", DG.edges(lhs, data="variant"))]) + del_end = max([int(e[2].split(":")[1].split("/")[0]) for e in filter(lambda e: e[2] != "lambda", DG.in_edges(rhs, data="variant"))]) + # print("edge min", min([int(e[2].split(":")[0]) for e in chain(DG.edges(lhs, data="variant"), DG.edges(rhs, data="variant"))])) + + # del_end = max([int(e[2].split(":")[1].split("/")[0]) for e in filter(lambda e: e[2] != "lambda", chain(DG.edges(lhs, data="variant"), DG.edges(rhs, data="variant")))]) + + # print("rhs edge min", min([int(e[2].split(":")[0]) for e in DG.edges(rhs, data="variant")])) + # print("rhs edge min", min([int(e[2].split(":")[0].split("/")[0]) for e in DG.edges(rhs, data="variant")])) + # del_start = DG.nodes[lhs]["row"] + DG.nodes[lhs]["length"] + # del_start = min(DG.nodes[lhs]["row"] + DG.nodes[lhs]["length"], DG.nodes[rhs]["row"]) + # del_end = DG.nodes[rhs]["row"] + # del_end = max(DG.nodes[lhs]["row"] + DG.nodes[lhs]["length"], DG.nodes[rhs]["row"]) + # ins_start = DG.nodes[lhs]["col"] + DG.nodes[lhs]["length"] + # ins_start = DG.nodes[lhs]["col"] + ins_start = DG.nodes[lhs]["col"] + del_start - DG.nodes[lhs]["row"] + ins_end = DG.nodes[rhs]["col"] + del_end - DG.nodes[rhs]["row"] + # if lhs == "s2" and rhs == "s1": + # # observed[lca.col + start - lca.row - shift:node.col + end - node.row - shift]) + # # 21 28 27 + # # ins_start = 22 + # # ins_end = 24 + # print(DG.nodes[lhs]["col"], del_start, DG.nodes[lhs]["row"]) + # ins_start = DG.nodes[lhs]["col"] + del_start - DG.nodes[lhs]["row"] + # # 21 28 27 + # ins_end = 24 + print("del", del_start, del_end) + print("ins", ins_start, ins_end) + v = Variant(min(del_start, del_end), max(del_start, del_end), observed[min(ins_start, ins_end): max(ins_start, ins_end)]) + print(v) + variant.append(v) + lhs = rhs + print(variant) + + # G = nx.MultiDiGraph([(5, 2), (5, 4), (2, 3), (2, 0), (2, 1), (4, 2), (3, 0), (3, 0), (1, 0)]) + # for k, v in post_dominators(G, 5).items(): + # for k, v in post_dominators(DG, cgraph["source"]).items(): + # print(k, v) + + print(canonical(graph)) + + assert variant == canonical(graph) + + +if __name__ == "__main__": + main() From a9620629fd746d6e8a044326def48b8694614163 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Wed, 4 Sep 2024 03:13:55 +0200 Subject: [PATCH 111/704] Cleaned up and refactored. --- q.py | 152 ++++++++--------------------------------------------------- 1 file changed, 20 insertions(+), 132 deletions(-) diff --git a/q.py b/q.py index c4b4340..154f473 100644 --- a/q.py +++ b/q.py @@ -1,56 +1,27 @@ import json -import random import subprocess import sys -from algebra import LCSgraph -from algebra.extractor import local_supremal -from algebra.extractor.extractor import canonical -from algebra.utils import random_sequence, to_dot - -from algebra.variants import Variant - - from itertools import chain - -from functools import reduce - import networkx as nx - -def post_dominators(G, source): - def intersect(u, v): - while u != v: - while nodes[u]["dfn"] < nodes[v]["dfn"]: - u = nodes[u]["ipdom"] - while nodes[u]["dfn"] > nodes[v]["dfn"]: - v = nodes[v]["ipdom"] - return u - - nodes = {} - for idx, u in enumerate(nx.dfs_postorder_nodes(G, source)): - if not G.succ[u]: - nodes[u] = {"ipdom": u, "dfn": len(G.nodes()) - idx - 1} - else: - nodes[u] = {"ipdom": reduce(intersect, list(G.succ[u])), "dfn": len(G.nodes()) - idx - 1} - - return nodes - +from algebra import LCSgraph +from algebra.extractor.extractor import canonical +from algebra.utils import random_sequence +from algebra.variants import Variant def main(): - debug = False if len(sys.argv) > 1: reference = sys.argv[1] observed = sys.argv[2] - debug = True else: reference = random_sequence(32, 8) observed = random_sequence(32, 8) - print(reference, observed) + # Create graph in C stdout = subprocess.run(["./a.out", reference, observed], check=True, stdout=subprocess.PIPE).stdout.decode("utf-8") try: cgraph = json.loads(stdout) @@ -58,119 +29,36 @@ def main(): print(f'\"{stdout}\"') raise exc - print(cgraph) - # print(cgraph["nodes"]) - # print(cgraph["edges"]) - + # Convert C graph to NetworkX DG = nx.MultiDiGraph() DG.add_nodes_from([(k, cgraph["nodes"][k]) for k in cgraph["nodes"]]) DG.add_edges_from([(e['head'], e['tail'], {'variant': e['variant'], 'weight': 0 if e['variant'] == 'lambda' else 1}) for e in cgraph["edges"]]) - - # print(DG.nodes) - # print(DG.nodes["s0"]) - # - # print(DG.edges) - # print(DG.edges[('s1', 's2')]) - - # print(list(nx.all_shortest_paths(DG, "s7", "s0"))) all_paths = nx.all_shortest_paths(DG, cgraph["source"], "s0", weight="weight") - # print("all paths", list(all_paths)) - # targets = [] - targets2 = [] - for x in set(chain(*all_paths)): - # targets.append(LCSgraph.Node(DG.nodes[x]["row"], DG.nodes[x]["col"], DG.nodes[x]["length"])) - targets2.append(x) - - # print("targets to keep", targets) - - to_remove2 = [] - for n in DG.nodes: - if n not in targets2: - to_remove2.append(n) - for n in to_remove2: - DG.remove_node(n) - - graph = LCSgraph.from_sequence(reference, observed) - # print("local supremal", local_supremal(reference, graph)) + DG = DG.subgraph(set(chain(*all_paths))) - # print(list(graph.nodes())) - # x = graph.nodes() - # for y in x: - # print("edges", y.edges) - # - # to_remove = [] - # for z in y.edges: - # print("z", z) - # if z[0] not in targets: - # print("remove") - # to_remove.append(z) - # print("z", z) - # for q in to_remove: - # y.edges.remove(q) - # print("edges after", y.edges) - - - # print("remaining nodes", list(DG.nodes())) - # print("remaining edges", list(DG.edges())) - - # print(nx.dominance_frontiers(DG, cgraph["source"])) - # print(nx.dominance_frontiers(DG.reverse(), "s0")) - # print(nx.immediate_dominators(DG, cgraph["source"])) - # print(nx.immediate_dominators(DG.reverse(), "s0")) - i = nx.immediate_dominators(DG.reverse(), "s0") - print(i) + # Calculate the dominators on the reversed graph + postdoms = nx.immediate_dominators(DG.reverse(), "s0") + # Extract local supremals from reduced graph + local_supremal = [] lhs = cgraph["source"] - variant = [] - while lhs != i[lhs]: - rhs = i[lhs] - print(lhs, DG.nodes[lhs], rhs, DG.nodes[rhs]) - if (DG.nodes[lhs]["row"] + DG.nodes[lhs]["length"] == DG.nodes[rhs]["row"] + DG.nodes[rhs]["length"] and + while lhs != postdoms[lhs]: + rhs = postdoms[lhs] + if not (DG.nodes[lhs]["row"] + DG.nodes[lhs]["length"] == DG.nodes[rhs]["row"] + DG.nodes[rhs]["length"] and DG.nodes[lhs]["col"] + DG.nodes[lhs]["length"] == DG.nodes[rhs]["col"] + DG.nodes[rhs]["length"]): - print("lambda?") - else: - print(DG.edges(lhs, data="variant")) del_start = min([int(e[2].split(":")[0]) for e in filter(lambda e: e[2] != "lambda", DG.edges(lhs, data="variant"))]) del_end = max([int(e[2].split(":")[1].split("/")[0]) for e in filter(lambda e: e[2] != "lambda", DG.in_edges(rhs, data="variant"))]) - # print("edge min", min([int(e[2].split(":")[0]) for e in chain(DG.edges(lhs, data="variant"), DG.edges(rhs, data="variant"))])) - - # del_end = max([int(e[2].split(":")[1].split("/")[0]) for e in filter(lambda e: e[2] != "lambda", chain(DG.edges(lhs, data="variant"), DG.edges(rhs, data="variant")))]) - - # print("rhs edge min", min([int(e[2].split(":")[0]) for e in DG.edges(rhs, data="variant")])) - # print("rhs edge min", min([int(e[2].split(":")[0].split("/")[0]) for e in DG.edges(rhs, data="variant")])) - # del_start = DG.nodes[lhs]["row"] + DG.nodes[lhs]["length"] - # del_start = min(DG.nodes[lhs]["row"] + DG.nodes[lhs]["length"], DG.nodes[rhs]["row"]) - # del_end = DG.nodes[rhs]["row"] - # del_end = max(DG.nodes[lhs]["row"] + DG.nodes[lhs]["length"], DG.nodes[rhs]["row"]) - # ins_start = DG.nodes[lhs]["col"] + DG.nodes[lhs]["length"] - # ins_start = DG.nodes[lhs]["col"] ins_start = DG.nodes[lhs]["col"] + del_start - DG.nodes[lhs]["row"] ins_end = DG.nodes[rhs]["col"] + del_end - DG.nodes[rhs]["row"] - # if lhs == "s2" and rhs == "s1": - # # observed[lca.col + start - lca.row - shift:node.col + end - node.row - shift]) - # # 21 28 27 - # # ins_start = 22 - # # ins_end = 24 - # print(DG.nodes[lhs]["col"], del_start, DG.nodes[lhs]["row"]) - # ins_start = DG.nodes[lhs]["col"] + del_start - DG.nodes[lhs]["row"] - # # 21 28 27 - # ins_end = 24 - print("del", del_start, del_end) - print("ins", ins_start, ins_end) - v = Variant(min(del_start, del_end), max(del_start, del_end), observed[min(ins_start, ins_end): max(ins_start, ins_end)]) - print(v) - variant.append(v) + v = Variant(del_start, del_end, observed[ins_start: ins_end]) + local_supremal.append(v) lhs = rhs - print(variant) - - # G = nx.MultiDiGraph([(5, 2), (5, 4), (2, 3), (2, 0), (2, 1), (4, 2), (3, 0), (3, 0), (1, 0)]) - # for k, v in post_dominators(G, 5).items(): - # for k, v in post_dominators(DG, cgraph["source"]).items(): - # print(k, v) - print(canonical(graph)) + print(local_supremal) - assert variant == canonical(graph) + # Validate against original Python implementation + graph = LCSgraph.from_sequence(reference, observed) + assert local_supremal == canonical(graph) if __name__ == "__main__": From 5b6c9c82828522a932d4468f4e2e010dc195024d Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Wed, 4 Sep 2024 07:21:27 +0200 Subject: [PATCH 112/704] Deal with non-s0 sinks in shorter graphs. --- q.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/q.py b/q.py index 154f473..8e18dff 100644 --- a/q.py +++ b/q.py @@ -17,8 +17,8 @@ def main(): reference = sys.argv[1] observed = sys.argv[2] else: - reference = random_sequence(32, 8) - observed = random_sequence(32, 8) + reference = random_sequence(32, 0) + observed = random_sequence(32, 0) print(reference, observed) # Create graph in C @@ -29,6 +29,14 @@ def main(): print(f'\"{stdout}\"') raise exc + # Set source and guess sink + source = cgraph["source"] + i = iter(cgraph["nodes"]) + while True: + sink = next(i) + if sink != source: + break + # Convert C graph to NetworkX DG = nx.MultiDiGraph() DG.add_nodes_from([(k, cgraph["nodes"][k]) for k in cgraph["nodes"]]) @@ -37,11 +45,11 @@ def main(): DG = DG.subgraph(set(chain(*all_paths))) # Calculate the dominators on the reversed graph - postdoms = nx.immediate_dominators(DG.reverse(), "s0") + postdoms = nx.immediate_dominators(mdg.reverse(), sink) # Extract local supremals from reduced graph local_supremal = [] - lhs = cgraph["source"] + lhs = source while lhs != postdoms[lhs]: rhs = postdoms[lhs] if not (DG.nodes[lhs]["row"] + DG.nodes[lhs]["length"] == DG.nodes[rhs]["row"] + DG.nodes[rhs]["length"] and @@ -53,7 +61,6 @@ def main(): v = Variant(del_start, del_end, observed[ins_start: ins_end]) local_supremal.append(v) lhs = rhs - print(local_supremal) # Validate against original Python implementation From 0ae6ddff76828384a128a48b0203bc4ad8c81c28 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Wed, 4 Sep 2024 07:22:16 +0200 Subject: [PATCH 113/704] Rename DG variable. --- q.py | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/q.py b/q.py index 8e18dff..4955189 100644 --- a/q.py +++ b/q.py @@ -38,11 +38,13 @@ def main(): break # Convert C graph to NetworkX - DG = nx.MultiDiGraph() - DG.add_nodes_from([(k, cgraph["nodes"][k]) for k in cgraph["nodes"]]) - DG.add_edges_from([(e['head'], e['tail'], {'variant': e['variant'], 'weight': 0 if e['variant'] == 'lambda' else 1}) for e in cgraph["edges"]]) - all_paths = nx.all_shortest_paths(DG, cgraph["source"], "s0", weight="weight") - DG = DG.subgraph(set(chain(*all_paths))) + mdg = nx.MultiDiGraph() + mdg.add_nodes_from([(k, cgraph["nodes"][k]) for k in cgraph["nodes"]]) + mdg.add_edges_from([(e['head'], e['tail'], {'variant': e['variant'], 'weight': 0 if e['variant'] == 'lambda' else 1}) for e in cgraph["edges"]]) + + # Find all shortest paths and create a new subgraph with only those nodes + all_paths = nx.all_shortest_paths(mdg, source, sink, weight="weight") + mdg = mdg.subgraph(set(chain(*all_paths))) # Calculate the dominators on the reversed graph postdoms = nx.immediate_dominators(mdg.reverse(), sink) @@ -52,12 +54,12 @@ def main(): lhs = source while lhs != postdoms[lhs]: rhs = postdoms[lhs] - if not (DG.nodes[lhs]["row"] + DG.nodes[lhs]["length"] == DG.nodes[rhs]["row"] + DG.nodes[rhs]["length"] and - DG.nodes[lhs]["col"] + DG.nodes[lhs]["length"] == DG.nodes[rhs]["col"] + DG.nodes[rhs]["length"]): - del_start = min([int(e[2].split(":")[0]) for e in filter(lambda e: e[2] != "lambda", DG.edges(lhs, data="variant"))]) - del_end = max([int(e[2].split(":")[1].split("/")[0]) for e in filter(lambda e: e[2] != "lambda", DG.in_edges(rhs, data="variant"))]) - ins_start = DG.nodes[lhs]["col"] + del_start - DG.nodes[lhs]["row"] - ins_end = DG.nodes[rhs]["col"] + del_end - DG.nodes[rhs]["row"] + if not (mdg.nodes[lhs]["row"] + mdg.nodes[lhs]["length"] == mdg.nodes[rhs]["row"] + mdg.nodes[rhs]["length"] and + mdg.nodes[lhs]["col"] + mdg.nodes[lhs]["length"] == mdg.nodes[rhs]["col"] + mdg.nodes[rhs]["length"]): + del_start = min([int(e[2].split(":")[0]) for e in filter(lambda e: e[2] != "lambda", mdg.edges(lhs, data="variant"))]) + del_end = max([int(e[2].split(":")[1].split("/")[0]) for e in filter(lambda e: e[2] != "lambda", mdg.in_edges(rhs, data="variant"))]) + ins_start = mdg.nodes[lhs]["col"] + del_start - mdg.nodes[lhs]["row"] + ins_end = mdg.nodes[rhs]["col"] + del_end - mdg.nodes[rhs]["row"] v = Variant(del_start, del_end, observed[ins_start: ins_end]) local_supremal.append(v) lhs = rhs From 0ffb5d2184f8d214d6e0b88023240bc79ee596eb Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Wed, 4 Sep 2024 07:31:50 +0200 Subject: [PATCH 114/704] Turn into command line argument. --- q.py | 2 +- src/main.c | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/q.py b/q.py index 4955189..8f3ff73 100644 --- a/q.py +++ b/q.py @@ -22,7 +22,7 @@ def main(): print(reference, observed) # Create graph in C - stdout = subprocess.run(["./a.out", reference, observed], check=True, stdout=subprocess.PIPE).stdout.decode("utf-8") + stdout = subprocess.run(["./a.out", reference, observed, "true"], check=True, stdout=subprocess.PIPE).stdout.decode("utf-8") try: cgraph = json.loads(stdout) except json.decoder.JSONDecodeError as exc: diff --git a/src/main.c b/src/main.c index 2056e49..71adb5a 100644 --- a/src/main.c +++ b/src/main.c @@ -734,6 +734,11 @@ main(int argc, char* argv[static argc + 1]) } // if char const* const restrict reference = argv[1]; char const* const restrict observed = argv[2]; + bool lambda = false; + if (argc == 4) + { + lambda = (bool)argv[3]; + } size_t const len_ref = strlen(reference); size_t const len_obs = strlen(observed); @@ -774,7 +779,7 @@ main(int argc, char* argv[static argc + 1]) //canonical(va_std_allocator, graph, len_obs, observed); - to_json(graph, len_obs, observed, false); + to_json(graph, len_obs, observed, lambda); destroy(va_std_allocator, &graph); From 7f8861208141170a75163b095b8fa578dc629157 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Wed, 4 Sep 2024 07:57:55 +0200 Subject: [PATCH 115/704] Break out variant parsing. --- q.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/q.py b/q.py index 8f3ff73..107b06c 100644 --- a/q.py +++ b/q.py @@ -37,10 +37,19 @@ def main(): if sink != source: break + # Convert C string variant into Variant object + def str2var(desc): + if desc == "lambda": + return None + + start, remainder = desc.split(":") + end, inserted = remainder.split("/") + return Variant(int(start), int(end), inserted) + # Convert C graph to NetworkX mdg = nx.MultiDiGraph() mdg.add_nodes_from([(k, cgraph["nodes"][k]) for k in cgraph["nodes"]]) - mdg.add_edges_from([(e['head'], e['tail'], {'variant': e['variant'], 'weight': 0 if e['variant'] == 'lambda' else 1}) for e in cgraph["edges"]]) + mdg.add_edges_from([(e['head'], e['tail'], {'variant': str2var(e['variant']), 'weight': 0 if str(e['variant']) == 'lambda' else 1}) for e in cgraph["edges"]]) # Find all shortest paths and create a new subgraph with only those nodes all_paths = nx.all_shortest_paths(mdg, source, sink, weight="weight") @@ -56,8 +65,8 @@ def main(): rhs = postdoms[lhs] if not (mdg.nodes[lhs]["row"] + mdg.nodes[lhs]["length"] == mdg.nodes[rhs]["row"] + mdg.nodes[rhs]["length"] and mdg.nodes[lhs]["col"] + mdg.nodes[lhs]["length"] == mdg.nodes[rhs]["col"] + mdg.nodes[rhs]["length"]): - del_start = min([int(e[2].split(":")[0]) for e in filter(lambda e: e[2] != "lambda", mdg.edges(lhs, data="variant"))]) - del_end = max([int(e[2].split(":")[1].split("/")[0]) for e in filter(lambda e: e[2] != "lambda", mdg.in_edges(rhs, data="variant"))]) + del_start = min([e[2].start for e in filter(lambda e: e[2], mdg.edges(lhs, data="variant"))]) + del_end = max([e[2].end for e in filter(lambda e: e[2], mdg.in_edges(rhs, data="variant"))]) ins_start = mdg.nodes[lhs]["col"] + del_start - mdg.nodes[lhs]["row"] ins_end = mdg.nodes[rhs]["col"] + del_end - mdg.nodes[rhs]["row"] v = Variant(del_start, del_end, observed[ins_start: ins_end]) From 80e4a8eed84666a86af2954fe8640bf18284c360 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Wed, 4 Sep 2024 10:02:39 +0200 Subject: [PATCH 116/704] Fix for single node graphs. --- q.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/q.py b/q.py index 107b06c..e115ef5 100644 --- a/q.py +++ b/q.py @@ -33,7 +33,10 @@ def main(): source = cgraph["source"] i = iter(cgraph["nodes"]) while True: - sink = next(i) + try: + sink = next(i) + except StopIteration: + break if sink != source: break From 322167ee3b1e1b012e99147d320a6095bc8fba53 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Wed, 4 Sep 2024 10:56:39 +0200 Subject: [PATCH 117/704] Explicit direction of edges. --- q.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/q.py b/q.py index e115ef5..ed2d3c1 100644 --- a/q.py +++ b/q.py @@ -68,7 +68,7 @@ def str2var(desc): rhs = postdoms[lhs] if not (mdg.nodes[lhs]["row"] + mdg.nodes[lhs]["length"] == mdg.nodes[rhs]["row"] + mdg.nodes[rhs]["length"] and mdg.nodes[lhs]["col"] + mdg.nodes[lhs]["length"] == mdg.nodes[rhs]["col"] + mdg.nodes[rhs]["length"]): - del_start = min([e[2].start for e in filter(lambda e: e[2], mdg.edges(lhs, data="variant"))]) + del_start = min([e[2].start for e in filter(lambda e: e[2], mdg.out_edges(lhs, data="variant"))]) del_end = max([e[2].end for e in filter(lambda e: e[2], mdg.in_edges(rhs, data="variant"))]) ins_start = mdg.nodes[lhs]["col"] + del_start - mdg.nodes[lhs]["row"] ins_end = mdg.nodes[rhs]["col"] + del_end - mdg.nodes[rhs]["row"] From 51061051aff9177d78d4d000a66e63362dda6a71 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Wed, 4 Sep 2024 11:24:08 +0200 Subject: [PATCH 118/704] Merge networkx testing with test.py. --- q.py | 86 --------------------------------------------------------- test.py | 68 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 67 insertions(+), 87 deletions(-) delete mode 100644 q.py diff --git a/q.py b/q.py deleted file mode 100644 index ed2d3c1..0000000 --- a/q.py +++ /dev/null @@ -1,86 +0,0 @@ -import json -import subprocess -import sys - -from itertools import chain -import networkx as nx - -from algebra import LCSgraph -from algebra.extractor.extractor import canonical -from algebra.utils import random_sequence -from algebra.variants import Variant - - -def main(): - - if len(sys.argv) > 1: - reference = sys.argv[1] - observed = sys.argv[2] - else: - reference = random_sequence(32, 0) - observed = random_sequence(32, 0) - print(reference, observed) - - # Create graph in C - stdout = subprocess.run(["./a.out", reference, observed, "true"], check=True, stdout=subprocess.PIPE).stdout.decode("utf-8") - try: - cgraph = json.loads(stdout) - except json.decoder.JSONDecodeError as exc: - print(f'\"{stdout}\"') - raise exc - - # Set source and guess sink - source = cgraph["source"] - i = iter(cgraph["nodes"]) - while True: - try: - sink = next(i) - except StopIteration: - break - if sink != source: - break - - # Convert C string variant into Variant object - def str2var(desc): - if desc == "lambda": - return None - - start, remainder = desc.split(":") - end, inserted = remainder.split("/") - return Variant(int(start), int(end), inserted) - - # Convert C graph to NetworkX - mdg = nx.MultiDiGraph() - mdg.add_nodes_from([(k, cgraph["nodes"][k]) for k in cgraph["nodes"]]) - mdg.add_edges_from([(e['head'], e['tail'], {'variant': str2var(e['variant']), 'weight': 0 if str(e['variant']) == 'lambda' else 1}) for e in cgraph["edges"]]) - - # Find all shortest paths and create a new subgraph with only those nodes - all_paths = nx.all_shortest_paths(mdg, source, sink, weight="weight") - mdg = mdg.subgraph(set(chain(*all_paths))) - - # Calculate the dominators on the reversed graph - postdoms = nx.immediate_dominators(mdg.reverse(), sink) - - # Extract local supremals from reduced graph - local_supremal = [] - lhs = source - while lhs != postdoms[lhs]: - rhs = postdoms[lhs] - if not (mdg.nodes[lhs]["row"] + mdg.nodes[lhs]["length"] == mdg.nodes[rhs]["row"] + mdg.nodes[rhs]["length"] and - mdg.nodes[lhs]["col"] + mdg.nodes[lhs]["length"] == mdg.nodes[rhs]["col"] + mdg.nodes[rhs]["length"]): - del_start = min([e[2].start for e in filter(lambda e: e[2], mdg.out_edges(lhs, data="variant"))]) - del_end = max([e[2].end for e in filter(lambda e: e[2], mdg.in_edges(rhs, data="variant"))]) - ins_start = mdg.nodes[lhs]["col"] + del_start - mdg.nodes[lhs]["row"] - ins_end = mdg.nodes[rhs]["col"] + del_end - mdg.nodes[rhs]["row"] - v = Variant(del_start, del_end, observed[ins_start: ins_end]) - local_supremal.append(v) - lhs = rhs - print(local_supremal) - - # Validate against original Python implementation - graph = LCSgraph.from_sequence(reference, observed) - assert local_supremal == canonical(graph) - - -if __name__ == "__main__": - main() diff --git a/test.py b/test.py index cfe8f6f..0beb983 100644 --- a/test.py +++ b/test.py @@ -1,19 +1,84 @@ import json -import random +# import random import signal import subprocess import sys +from itertools import chain +import networkx as nx + from algebra import LCSgraph from algebra.extractor import local_supremal from algebra.extractor.extractor import canonical from algebra.utils import random_sequence, to_dot +from algebra.variants import Variant def handler(signum, frame): raise KeyboardInterrupt +def nx_extract(reference, observed): + # Create graph in C + stdout = subprocess.run(["./a.out", reference, observed, "true"], check=True, stdout=subprocess.PIPE).stdout.decode("utf-8") + try: + cgraph = json.loads(stdout) + except json.decoder.JSONDecodeError as exc: + print(f'\"{stdout}\"') + raise exc + + # Set source and guess sink + source = cgraph["source"] + i = iter(cgraph["nodes"]) + while True: + try: + sink = next(i) + except StopIteration: + break + if sink != source: + break + + # Convert C string variant into Variant object + def str2var(desc): + if desc == "lambda": + return None + + start, remainder = desc.split(":") + end, inserted = remainder.split("/") + return Variant(int(start), int(end), inserted) + + # Convert C graph to NetworkX + mdg = nx.MultiDiGraph() + mdg.add_nodes_from([(k, cgraph["nodes"][k]) for k in cgraph["nodes"]]) + mdg.add_edges_from([(e['head'], e['tail'], {'variant': str2var(e['variant']), 'weight': 0 if str(e['variant']) == 'lambda' else 1}) for e in cgraph["edges"]]) + + # Find all shortest paths and create a new subgraph with only those nodes + all_paths = nx.all_shortest_paths(mdg, source, sink, weight="weight") + mdg = mdg.subgraph(set(chain(*all_paths))) + + # Calculate the dominators on the reversed graph + postdoms = nx.immediate_dominators(mdg.reverse(), sink) + + # Extract local supremals from reduced graph + local_supremal = [] + lhs = source + while lhs != postdoms[lhs]: + rhs = postdoms[lhs] + if not (mdg.nodes[lhs]["row"] + mdg.nodes[lhs]["length"] == mdg.nodes[rhs]["row"] + mdg.nodes[rhs]["length"] and + mdg.nodes[lhs]["col"] + mdg.nodes[lhs]["length"] == mdg.nodes[rhs]["col"] + mdg.nodes[rhs]["length"]): + del_start = min([e[2].start for e in filter(lambda e: e[2], mdg.out_edges(lhs, data="variant"))]) + del_end = max([e[2].end for e in filter(lambda e: e[2], mdg.in_edges(rhs, data="variant"))]) + ins_start = mdg.nodes[lhs]["col"] + del_start - mdg.nodes[lhs]["row"] + ins_end = mdg.nodes[rhs]["col"] + del_end - mdg.nodes[rhs]["row"] + v = Variant(del_start, del_end, observed[ins_start: ins_end]) + local_supremal.append(v) + lhs = rhs + + # Validate against original Python implementation + for lhs, rhs in zip(reversed(cgraph["canonical"]), local_supremal): + assert lhs == str(rhs), f'canonical elements differ: {lhs} vs {rhs}' + + def check(reference, observed, debug=False, timeout=1): graph = LCSgraph.from_sequence(reference, observed) valgrind = [] @@ -88,6 +153,7 @@ def main(): try: check(reference, observed) + nx_extract(reference, observed) n += 1 except KeyboardInterrupt: break From e35cc267903543a85988c2528700ba5b80bc22c8 Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 4 Sep 2024 15:54:19 +0200 Subject: [PATCH 119/704] Clean up --- src/main.c | 44 ++++++++++++++++++-------------------------- test.py | 2 +- 2 files changed, 19 insertions(+), 27 deletions(-) diff --git a/src/main.c b/src/main.c index 71adb5a..9ad97d5 100644 --- a/src/main.c +++ b/src/main.c @@ -1,8 +1,9 @@ +#include // bool, false, true #include // NULL, size_t #include // uint32_t #include // stderr, fprintf, printf #include // EXIT_* -#include // strlen +#include // strlen, strncmp #include "../include/alloc.h" // VA_Allocator #include "../include/array.h" // va_array_* @@ -498,36 +499,27 @@ canonical(VA_Allocator const allocator, Graph const graph, size_t const len_obs, fprintf(stderr, " = %u (%u:%u)\n", visited[lambda].lca, visited[lambda].start, visited[lambda].end); } // if + else if (visited[head].next == lambda) + { + fprintf(stderr, " improve lambda in place %u @ %u\n", lambda, visited[head].depth); + visited[lambda] = (LCA_Table) {head, visited[lambda].rank, visited[head].depth, -1, -1, visited[lambda].prev, visited[lambda].next}; + } // if else { fprintf(stderr, " improve lambda %u @ %u\n", lambda, visited[head].depth); - // FIXME: what about the original link to lambda? - // lambda is already in the queue and should be *moved* instead of added again (in stack order) - // if moving is difficult we can possibly skip nodes that are already processed (in the main loop) - // possibly related: - // INFINITE LOOP: CAGCGAGT CGTGTAAGGTGTACTGAAA - // FIXED by doubly linked list - - if (visited[head].next == lambda) + if (lambda == tail) { - visited[lambda] = (LCA_Table) {head, visited[lambda].rank, visited[head].depth, -1, -1, visited[lambda].prev, visited[lambda].next}; + tail = visited[lambda].prev; } // if else { - if (lambda == tail) - { - tail = visited[lambda].prev; - } // if - else - { - visited[visited[lambda].next].prev = visited[lambda].prev; - } // else - visited[visited[head].next].prev = lambda; - visited[visited[lambda].prev].next = visited[lambda].next; - visited[lambda] = (LCA_Table) {head, visited[lambda].rank, visited[head].depth, -1, -1, head, visited[head].next}; - visited[head].next = lambda; + visited[visited[lambda].next].prev = visited[lambda].prev; } // else + visited[visited[head].next].prev = lambda; + visited[visited[lambda].prev].next = visited[lambda].next; + visited[lambda] = (LCA_Table) {head, visited[lambda].rank, visited[head].depth, -1, -1, head, visited[head].next}; + visited[head].next = lambda; } // else //print_lca_table(length, visited, head, tail); @@ -694,7 +686,7 @@ lambda_edges(Graph const graph, size_t const len_obs, char const observed[static static void -to_json(Graph const graph, size_t const len_obs, char const observed[static len_obs], bool lambda) +to_json(Graph const graph, size_t const len_obs, char const observed[static len_obs], bool const lambda) { printf("{\n \"source\": \"s%u\",\n \"nodes\": {\n", graph.source); for (uint32_t i = 0; i < va_array_length(graph.nodes); ++i) @@ -735,10 +727,10 @@ main(int argc, char* argv[static argc + 1]) char const* const restrict reference = argv[1]; char const* const restrict observed = argv[2]; bool lambda = false; - if (argc == 4) + if (argc == 4 && strncmp(argv[3], "true", 4) == 0) { - lambda = (bool)argv[3]; - } + lambda = true; + } // if size_t const len_ref = strlen(reference); size_t const len_obs = strlen(observed); diff --git a/test.py b/test.py index 0beb983..d65cdf6 100644 --- a/test.py +++ b/test.py @@ -79,7 +79,7 @@ def str2var(desc): assert lhs == str(rhs), f'canonical elements differ: {lhs} vs {rhs}' -def check(reference, observed, debug=False, timeout=1): +def check(reference, observed, debug=False, timeout=2): graph = LCSgraph.from_sequence(reference, observed) valgrind = [] if debug: From d4d150e9d771120b124e988a2f88d2dc6dc884f6 Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 23 Oct 2024 16:04:16 +0200 Subject: [PATCH 120/704] Adjust length when splitting --- src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.c b/src/main.c index 9ad97d5..1bd92f6 100644 --- a/src/main.c +++ b/src/main.c @@ -148,7 +148,7 @@ build_graph(VA_Allocator const allocator, if (heads[k].incoming == i) { size_t const split_idx = heads[k].idx; - heads[k].idx = add_node(allocator, &graph, heads[k].row, heads[k].col, graph.nodes[split_idx].length); + heads[k].idx = add_node(allocator, &graph, heads[k].row, heads[k].col, graph.nodes[split_idx].length - 1); heads[k].incoming = 0; // lambda-edge From 9b2ce61d448d425a94d9a631aa7acb4ae69f1445 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 29 Oct 2024 10:31:17 +0100 Subject: [PATCH 121/704] Reconstructing edges --- src/main.c | 42 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/src/main.c b/src/main.c index 1bd92f6..4c3d4c4 100644 --- a/src/main.c +++ b/src/main.c @@ -1,5 +1,5 @@ #include // bool, false, true -#include // NULL, size_t +#include // NULL, ptrdiff_t, size_t #include // uint32_t #include // stderr, fprintf, printf #include // EXIT_* @@ -237,13 +237,13 @@ build_graph(VA_Allocator const allocator, static void to_dot(Graph const graph, size_t const len_obs, char const observed[static len_obs]) { - fprintf(stderr, "digraph{\nrankdir=LR\nedge[fontname=monospace]\nnode[fixedsize=true,fontname=serif,shape=circle,width=1]\nsi[shape=point,width=.1]\nsi->s%u\n", graph.source); + fprintf(stderr, "digraph{\nrankdir=LR\nedge[fontname=monospace]\nnode[fixedsize=true,fontname=serif,shape=circle,width=1]\nsi[label=\"\",shape=none,width=0]\nsi->s%u\n", graph.source); for (uint32_t i = 0; i < va_array_length(graph.nodes); ++i) { fprintf(stderr, "s%u[label=\"(%u, %u, %u)\"%s]\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, graph.nodes[i].edges == (uint32_t) -1 ? ",peripheries=2" : ""); if (graph.nodes[i].lambda != (uint32_t) -1) { - fprintf(stderr, "s%u->s%u[label=\"λ\",style=\"dashed\"]\n", i, graph.nodes[i].lambda); + fprintf(stderr, "s%u->s%u[label=\"λ\",style=\"dashed\"]\n", i, graph.nodes[i].lambda); } // if for (uint32_t j = graph.nodes[i].edges; j != (uint32_t) -1; j = graph.edges[j].next) { @@ -771,7 +771,41 @@ main(int argc, char* argv[static argc + 1]) //canonical(va_std_allocator, graph, len_obs, observed); - to_json(graph, len_obs, observed, lambda); + //to_json(graph, len_obs, observed, lambda); + + for (uint32_t head = 0; head < va_array_length(graph.nodes); ++head) + { + for (uint32_t i = graph.nodes[head].edges; i != (uint32_t) -1; i = graph.edges[i].next) + { + uint32_t const tail = graph.edges[i].tail; + printf( + "(%u, %u, %u) -> (%u, %u, %u)\n", + graph.nodes[head].row, graph.nodes[head].col, graph.nodes[head].length, + graph.nodes[tail].row, graph.nodes[tail].col, graph.nodes[tail].length + ); + + ptrdiff_t const offset = MIN( + (ptrdiff_t) graph.nodes[tail].row - (ptrdiff_t) graph.nodes[head].row + (graph.nodes[head].length == 0), + (ptrdiff_t) graph.nodes[tail].col - (ptrdiff_t) graph.nodes[head].col + (graph.nodes[head].length == 0) + ) - 1; + + uint32_t const head_start = offset > 0 ? MIN(offset, graph.nodes[head].length - 1) : 0; + uint32_t const tail_start = offset < 0 ? MIN(-offset, graph.nodes[tail].length - 1) : 0; + uint32_t const length = MIN(graph.nodes[head].length - head_start + (graph.nodes[head].length == 0), graph.nodes[tail].length - tail_start + (graph.nodes[tail].length == 0)); + + //printf(" %zd: (%u, %u): %u\n", offset, head_start, tail_start, length); + + for (uint32_t j = 0; j < length; ++j) + { + VA_Variant const variant = {graph.nodes[head].row + head_start + j + (graph.nodes[head].length > 0), graph.nodes[tail].row + tail_start + j, graph.nodes[head].col + head_start + j + (graph.nodes[head].length > 0), graph.nodes[tail].col + tail_start + j}; + printf(" (%u, %u) -> (%u, %u) :: " VAR_FMT "\n", + graph.nodes[head].row + head_start + j, graph.nodes[head].col + head_start + j, + graph.nodes[tail].row + tail_start + j, graph.nodes[tail].col + tail_start + j, + print_variant(variant, observed) + ); + } // for + } // for + } // for destroy(va_std_allocator, &graph); From b78458c1b82a8378c5bde898196835a376b92a23 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 29 Oct 2024 11:42:50 +0100 Subject: [PATCH 122/704] Fix source and sink nodes --- src/main.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/main.c b/src/main.c index 4c3d4c4..6526b7e 100644 --- a/src/main.c +++ b/src/main.c @@ -783,21 +783,26 @@ main(int argc, char* argv[static argc + 1]) graph.nodes[head].row, graph.nodes[head].col, graph.nodes[head].length, graph.nodes[tail].row, graph.nodes[tail].col, graph.nodes[tail].length ); + bool const is_source = graph.source == head; + bool const is_sink = graph.nodes[tail].edges == (uint32_t) -1; - ptrdiff_t const offset = MIN( - (ptrdiff_t) graph.nodes[tail].row - (ptrdiff_t) graph.nodes[head].row + (graph.nodes[head].length == 0), - (ptrdiff_t) graph.nodes[tail].col - (ptrdiff_t) graph.nodes[head].col + (graph.nodes[head].length == 0) - ) - 1; + ptrdiff_t const row = (ptrdiff_t) graph.nodes[head].row - is_source; + ptrdiff_t const col = (ptrdiff_t) graph.nodes[head].col - is_source; + uint32_t const len = graph.nodes[head].length + is_source; - uint32_t const head_start = offset > 0 ? MIN(offset, graph.nodes[head].length - 1) : 0; + //printf("%zd, %zd, %u\n", row, col, len); + + ptrdiff_t const offset = MIN((ptrdiff_t) graph.nodes[tail].row - row, (ptrdiff_t) graph.nodes[tail].col - col) - 1; + + uint32_t const head_start = offset > 0 ? MIN(offset, len - 1) : 0; uint32_t const tail_start = offset < 0 ? MIN(-offset, graph.nodes[tail].length - 1) : 0; - uint32_t const length = MIN(graph.nodes[head].length - head_start + (graph.nodes[head].length == 0), graph.nodes[tail].length - tail_start + (graph.nodes[tail].length == 0)); + uint32_t const length = MIN(len - head_start, graph.nodes[tail].length - tail_start + is_sink); //printf(" %zd: (%u, %u): %u\n", offset, head_start, tail_start, length); for (uint32_t j = 0; j < length; ++j) { - VA_Variant const variant = {graph.nodes[head].row + head_start + j + (graph.nodes[head].length > 0), graph.nodes[tail].row + tail_start + j, graph.nodes[head].col + head_start + j + (graph.nodes[head].length > 0), graph.nodes[tail].col + tail_start + j}; + VA_Variant const variant = {graph.nodes[head].row + head_start + j + !is_source, graph.nodes[tail].row + tail_start + j, graph.nodes[head].col + head_start + j + !is_source, graph.nodes[tail].col + tail_start + j}; printf(" (%u, %u) -> (%u, %u) :: " VAR_FMT "\n", graph.nodes[head].row + head_start + j, graph.nodes[head].col + head_start + j, graph.nodes[tail].row + tail_start + j, graph.nodes[tail].col + tail_start + j, From 92949e75da1f38f3fa4e422211c99504547542a2 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 29 Oct 2024 11:50:58 +0100 Subject: [PATCH 123/704] Clean up --- src/main.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/main.c b/src/main.c index 6526b7e..670dc07 100644 --- a/src/main.c +++ b/src/main.c @@ -788,21 +788,29 @@ main(int argc, char* argv[static argc + 1]) ptrdiff_t const row = (ptrdiff_t) graph.nodes[head].row - is_source; ptrdiff_t const col = (ptrdiff_t) graph.nodes[head].col - is_source; - uint32_t const len = graph.nodes[head].length + is_source; + uint32_t const length = graph.nodes[head].length + is_source; - //printf("%zd, %zd, %u\n", row, col, len); + //printf("%zd, %zd, %u\n", row, col, length); - ptrdiff_t const offset = MIN((ptrdiff_t) graph.nodes[tail].row - row, (ptrdiff_t) graph.nodes[tail].col - col) - 1; - - uint32_t const head_start = offset > 0 ? MIN(offset, len - 1) : 0; + ptrdiff_t const offset = MIN( + (ptrdiff_t) graph.nodes[tail].row - row, + (ptrdiff_t) graph.nodes[tail].col - col + ) - 1; + uint32_t const head_start = offset > 0 ? MIN(offset, length - 1) : 0; uint32_t const tail_start = offset < 0 ? MIN(-offset, graph.nodes[tail].length - 1) : 0; - uint32_t const length = MIN(len - head_start, graph.nodes[tail].length - tail_start + is_sink); - //printf(" %zd: (%u, %u): %u\n", offset, head_start, tail_start, length); + //printf(" %zd: (%u, %u): %u\n", offset, head_start, tail_start); - for (uint32_t j = 0; j < length; ++j) + for (uint32_t j = 0; j < MIN(length - head_start, graph.nodes[tail].length - tail_start + is_sink); ++j) { - VA_Variant const variant = {graph.nodes[head].row + head_start + j + !is_source, graph.nodes[tail].row + tail_start + j, graph.nodes[head].col + head_start + j + !is_source, graph.nodes[tail].col + tail_start + j}; + VA_Variant const variant = + { + row + head_start + j + 1, + graph.nodes[tail].row + tail_start + j, + col + head_start + j + 1, + graph.nodes[tail].col + tail_start + j + }; + printf(" (%u, %u) -> (%u, %u) :: " VAR_FMT "\n", graph.nodes[head].row + head_start + j, graph.nodes[head].col + head_start + j, graph.nodes[tail].row + tail_start + j, graph.nodes[tail].col + tail_start + j, From bba7024705577ec4d333ff7e66a46d69998dc3a3 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 29 Oct 2024 13:14:06 +0100 Subject: [PATCH 124/704] No parallel edges --- src/main.c | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/src/main.c b/src/main.c index 670dc07..2f762a4 100644 --- a/src/main.c +++ b/src/main.c @@ -70,6 +70,25 @@ destroy(VA_Allocator const allocator, Graph* const graph) } // destroy +static bool +is_tail(Graph const graph, uint32_t const head, uint32_t const tail) +{ + if (head == (uint32_t) -1) + { + return false; + } // if + + for (uint32_t i = graph.nodes[head].edges; i != (uint32_t) -1; i = graph.edges[i].next) + { + if (graph.edges[i].tail == tail) + { + return true; + } // if + } // for + return false; +} // is_tail + + static Graph build_graph(VA_Allocator const allocator, size_t const len_ref, size_t const len_obs, @@ -142,9 +161,16 @@ build_graph(VA_Allocator const allocator, { if (heads[k].row + heads[k].length < tail.row + tail.length && heads[k].col + heads[k].length < tail.col + tail.length) { - VA_Variant const variant = {heads[k].row + heads[k].length, tail.row + tail.length - 1, heads[k].col + heads[k].length - shift, tail.col + tail.length - 1 - shift}; max_sink = MAX(max_sink, tail.row + tail.length - 1); + // FIXME: how efficient is this? + if (is_tail(graph, heads[k].idx, tail.idx)) + { + continue; + } // if + + VA_Variant const variant = {heads[k].row + heads[k].length, tail.row + tail.length - 1, heads[k].col + heads[k].length - shift, tail.col + tail.length - 1 - shift}; + if (heads[k].incoming == i) { size_t const split_idx = heads[k].idx; @@ -207,8 +233,15 @@ build_graph(VA_Allocator const allocator, if (source.row < lcs_nodes[0][i].row + lcs_nodes[0][i].length && source.col < lcs_nodes[0][i].col + lcs_nodes[0][i].length) { - VA_Variant const variant = {source.row, lcs_nodes[0][i].row + lcs_nodes[0][i].length - 1, source.col - shift, lcs_nodes[0][i].col + lcs_nodes[0][i].length - 1 - shift}; max_sink = MAX(max_sink, lcs_nodes[0][i].row + lcs_nodes[0][i].length - 1); + + // FIXME: how efficient is this? + if (is_tail(graph, source.idx, lcs_nodes[0][i].idx)) + { + continue; + } // if + + VA_Variant const variant = {source.row, lcs_nodes[0][i].row + lcs_nodes[0][i].length - 1, source.col - shift, lcs_nodes[0][i].col + lcs_nodes[0][i].length - 1 - shift}; graph.nodes[source.idx].edges = add_edge(allocator, &graph, lcs_nodes[0][i].idx, graph.nodes[source.idx].edges, variant); } // if } // for From dbfcf6136ba403ed48230dc03b4da1f61573e40c Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 29 Oct 2024 13:25:59 +0100 Subject: [PATCH 125/704] Efficient? deduplication of edges --- src/main.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main.c b/src/main.c index 2f762a4..d73d0e2 100644 --- a/src/main.c +++ b/src/main.c @@ -70,9 +70,12 @@ destroy(VA_Allocator const allocator, Graph* const graph) } // destroy -static bool +static inline bool is_tail(Graph const graph, uint32_t const head, uint32_t const tail) { + return head != (uint32_t) -1 && graph.edges[graph.nodes[head].edges].tail == tail; +/* + // FIXME: how efficient is this? if (head == (uint32_t) -1) { return false; @@ -86,6 +89,7 @@ is_tail(Graph const graph, uint32_t const head, uint32_t const tail) } // if } // for return false; +*/ } // is_tail @@ -163,7 +167,6 @@ build_graph(VA_Allocator const allocator, { max_sink = MAX(max_sink, tail.row + tail.length - 1); - // FIXME: how efficient is this? if (is_tail(graph, heads[k].idx, tail.idx)) { continue; @@ -235,7 +238,6 @@ build_graph(VA_Allocator const allocator, { max_sink = MAX(max_sink, lcs_nodes[0][i].row + lcs_nodes[0][i].length - 1); - // FIXME: how efficient is this? if (is_tail(graph, source.idx, lcs_nodes[0][i].idx)) { continue; From 34a179bc193b8c5c8b6d370f4c67523b6310ef12 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 29 Oct 2024 13:28:40 +0100 Subject: [PATCH 126/704] Fixed deduplication --- src/main.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main.c b/src/main.c index d73d0e2..ff5b1a6 100644 --- a/src/main.c +++ b/src/main.c @@ -73,7 +73,9 @@ destroy(VA_Allocator const allocator, Graph* const graph) static inline bool is_tail(Graph const graph, uint32_t const head, uint32_t const tail) { - return head != (uint32_t) -1 && graph.edges[graph.nodes[head].edges].tail == tail; + return head != (uint32_t) -1 && + graph.nodes[head].edges != (uint32_t) -1 && + graph.edges[graph.nodes[head].edges].tail == tail; /* // FIXME: how efficient is this? if (head == (uint32_t) -1) From 93bffd46bed244abafd36c2a45ed8bb9c30254ae Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 30 Oct 2024 20:08:17 +0100 Subject: [PATCH 127/704] Fixed split length --- src/main.c | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/src/main.c b/src/main.c index ff5b1a6..fbe44c0 100644 --- a/src/main.c +++ b/src/main.c @@ -73,6 +73,7 @@ destroy(VA_Allocator const allocator, Graph* const graph) static inline bool is_tail(Graph const graph, uint32_t const head, uint32_t const tail) { + return false; return head != (uint32_t) -1 && graph.nodes[head].edges != (uint32_t) -1 && graph.edges[graph.nodes[head].edges].tail == tail; @@ -136,6 +137,8 @@ build_graph(VA_Allocator const allocator, { if (heads[i].row + heads[i].length < sink.row + sink.length && heads[i].col + heads[i].length < sink.col + sink.length) { + printf("MAKE EDGE (%u %u %u) -> (%u %u %u)\n", heads[i].row, heads[i].col, heads[i].length, sink.row, sink.col, sink.length); + VA_Variant const variant = {heads[i].row + heads[i].length, sink.row + sink.length - 1, heads[i].col + heads[i].length - shift, sink.col + sink.length - 1 - shift}; max_sink = MAX(max_sink, sink.row + sink.length - 1); heads[i].idx = add_node(allocator, &graph, heads[i].row, heads[i].col, heads[i].length); @@ -149,10 +152,22 @@ build_graph(VA_Allocator const allocator, sink.length -= 1; sink.incoming = len_lcs - 1; va_array_insert(allocator, lcs_nodes[len_lcs - 1], sink, here); + + printf("INSERT (%u %u %u) here: %zu\n", sink.row, sink.col, sink.length, here); } // if for (size_t i = len_lcs - 1; i >= 1; --i) { + for (size_t j = 0; j < len_lcs; ++j) + { + printf("%zu: ", j); + for (size_t k = 0; k < va_array_length(lcs_nodes[j]); ++k) + { + printf("(%u %u %u) ", lcs_nodes[j][k].row, lcs_nodes[j][k].col, lcs_nodes[j][k].length); + } // for + printf("\n"); + } // for + for (size_t j = 0; j < va_array_length(lcs_nodes[i]); ++j) { if (lcs_nodes[i][j].idx == (uint32_t) -1) @@ -169,6 +184,8 @@ build_graph(VA_Allocator const allocator, { max_sink = MAX(max_sink, tail.row + tail.length - 1); + printf("MAKE EDGE (%u %u %u) -> (%u %u %u)\n", heads[k].row, heads[k].col, heads[k].length, tail.row, tail.col, tail.length); + if (is_tail(graph, heads[k].idx, tail.idx)) { continue; @@ -179,7 +196,7 @@ build_graph(VA_Allocator const allocator, if (heads[k].incoming == i) { size_t const split_idx = heads[k].idx; - heads[k].idx = add_node(allocator, &graph, heads[k].row, heads[k].col, graph.nodes[split_idx].length - 1); + heads[k].idx = add_node(allocator, &graph, heads[k].row, heads[k].col, heads[k].length); heads[k].incoming = 0; // lambda-edge @@ -211,11 +228,25 @@ build_graph(VA_Allocator const allocator, lcs_nodes[i][j].incoming = i; } // if va_array_insert(allocator, lcs_nodes[i - 1], lcs_nodes[i][j], here); + + printf("INSERT (%u %u %u) here: %zu\n", lcs_nodes[i][j].row, lcs_nodes[i][j].col, lcs_nodes[i][j].length, here); + } // if } // for lcs_nodes[i] = va_array_destroy(allocator, lcs_nodes[i]); } // for + for (size_t j = 0; j < len_lcs; ++j) + { + printf("%zu: ", j); + for (size_t k = 0; k < va_array_length(lcs_nodes[j]); ++k) + { + printf("(%u %u %u) ", lcs_nodes[j][k].row, lcs_nodes[j][k].col, lcs_nodes[j][k].length); + } // for + printf("\n"); + } // for + + VA_LCS_Node source = lcs_nodes[0][0]; size_t start = 0; @@ -240,6 +271,8 @@ build_graph(VA_Allocator const allocator, { max_sink = MAX(max_sink, lcs_nodes[0][i].row + lcs_nodes[0][i].length - 1); + printf("MAKE EDGE (%u %u %u) -> (%u %u %u)\n", source.row, source.col, source.length, lcs_nodes[0][i].row, lcs_nodes[0][i].col, lcs_nodes[0][i].length); + if (is_tail(graph, source.idx, lcs_nodes[0][i].idx)) { continue; From 25993468a6ed3deef8025115db295993341dc5d7 Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 4 Nov 2024 16:29:00 +0100 Subject: [PATCH 128/704] Towards checking regenerated edge labels --- src/main.c | 181 +++++++++++++++++++++++++---------------------------- 1 file changed, 84 insertions(+), 97 deletions(-) diff --git a/src/main.c b/src/main.c index fbe44c0..e18e8a4 100644 --- a/src/main.c +++ b/src/main.c @@ -70,32 +70,6 @@ destroy(VA_Allocator const allocator, Graph* const graph) } // destroy -static inline bool -is_tail(Graph const graph, uint32_t const head, uint32_t const tail) -{ - return false; - return head != (uint32_t) -1 && - graph.nodes[head].edges != (uint32_t) -1 && - graph.edges[graph.nodes[head].edges].tail == tail; -/* - // FIXME: how efficient is this? - if (head == (uint32_t) -1) - { - return false; - } // if - - for (uint32_t i = graph.nodes[head].edges; i != (uint32_t) -1; i = graph.edges[i].next) - { - if (graph.edges[i].tail == tail) - { - return true; - } // if - } // for - return false; -*/ -} // is_tail - - static Graph build_graph(VA_Allocator const allocator, size_t const len_ref, size_t const len_obs, @@ -137,7 +111,7 @@ build_graph(VA_Allocator const allocator, { if (heads[i].row + heads[i].length < sink.row + sink.length && heads[i].col + heads[i].length < sink.col + sink.length) { - printf("MAKE EDGE (%u %u %u) -> (%u %u %u)\n", heads[i].row, heads[i].col, heads[i].length, sink.row, sink.col, sink.length); + //printf("MAKE EDGE (%u %u %u) -> (%u %u %u)\n", heads[i].row, heads[i].col, heads[i].length, sink.row, sink.col, sink.length); VA_Variant const variant = {heads[i].row + heads[i].length, sink.row + sink.length - 1, heads[i].col + heads[i].length - shift, sink.col + sink.length - 1 - shift}; max_sink = MAX(max_sink, sink.row + sink.length - 1); @@ -153,21 +127,11 @@ build_graph(VA_Allocator const allocator, sink.incoming = len_lcs - 1; va_array_insert(allocator, lcs_nodes[len_lcs - 1], sink, here); - printf("INSERT (%u %u %u) here: %zu\n", sink.row, sink.col, sink.length, here); + //printf("INSERT (%u %u %u) here: %zu\n", sink.row, sink.col, sink.length, here); } // if for (size_t i = len_lcs - 1; i >= 1; --i) { - for (size_t j = 0; j < len_lcs; ++j) - { - printf("%zu: ", j); - for (size_t k = 0; k < va_array_length(lcs_nodes[j]); ++k) - { - printf("(%u %u %u) ", lcs_nodes[j][k].row, lcs_nodes[j][k].col, lcs_nodes[j][k].length); - } // for - printf("\n"); - } // for - for (size_t j = 0; j < va_array_length(lcs_nodes[i]); ++j) { if (lcs_nodes[i][j].idx == (uint32_t) -1) @@ -184,12 +148,7 @@ build_graph(VA_Allocator const allocator, { max_sink = MAX(max_sink, tail.row + tail.length - 1); - printf("MAKE EDGE (%u %u %u) -> (%u %u %u)\n", heads[k].row, heads[k].col, heads[k].length, tail.row, tail.col, tail.length); - - if (is_tail(graph, heads[k].idx, tail.idx)) - { - continue; - } // if + //printf("MAKE EDGE (%u %u %u) -> (%u %u %u)\n", heads[k].row, heads[k].col, heads[k].length, tail.row, tail.col, tail.length); VA_Variant const variant = {heads[k].row + heads[k].length, tail.row + tail.length - 1, heads[k].col + heads[k].length - shift, tail.col + tail.length - 1 - shift}; @@ -229,24 +188,13 @@ build_graph(VA_Allocator const allocator, } // if va_array_insert(allocator, lcs_nodes[i - 1], lcs_nodes[i][j], here); - printf("INSERT (%u %u %u) here: %zu\n", lcs_nodes[i][j].row, lcs_nodes[i][j].col, lcs_nodes[i][j].length, here); + //printf("INSERT (%u %u %u) here: %zu\n", lcs_nodes[i][j].row, lcs_nodes[i][j].col, lcs_nodes[i][j].length, here); } // if } // for lcs_nodes[i] = va_array_destroy(allocator, lcs_nodes[i]); } // for - for (size_t j = 0; j < len_lcs; ++j) - { - printf("%zu: ", j); - for (size_t k = 0; k < va_array_length(lcs_nodes[j]); ++k) - { - printf("(%u %u %u) ", lcs_nodes[j][k].row, lcs_nodes[j][k].col, lcs_nodes[j][k].length); - } // for - printf("\n"); - } // for - - VA_LCS_Node source = lcs_nodes[0][0]; size_t start = 0; @@ -271,12 +219,7 @@ build_graph(VA_Allocator const allocator, { max_sink = MAX(max_sink, lcs_nodes[0][i].row + lcs_nodes[0][i].length - 1); - printf("MAKE EDGE (%u %u %u) -> (%u %u %u)\n", source.row, source.col, source.length, lcs_nodes[0][i].row, lcs_nodes[0][i].col, lcs_nodes[0][i].length); - - if (is_tail(graph, source.idx, lcs_nodes[0][i].idx)) - { - continue; - } // if + //printf("MAKE EDGE (%u %u %u) -> (%u %u %u)\n", source.row, source.col, source.length, lcs_nodes[0][i].row, lcs_nodes[0][i].col, lcs_nodes[0][i].length); VA_Variant const variant = {source.row, lcs_nodes[0][i].row + lcs_nodes[0][i].length - 1, source.col - shift, lcs_nodes[0][i].col + lcs_nodes[0][i].length - 1 - shift}; graph.nodes[source.idx].edges = add_edge(allocator, &graph, lcs_nodes[0][i].idx, graph.nodes[source.idx].edges, variant); @@ -780,6 +723,49 @@ to_json(Graph const graph, size_t const len_obs, char const observed[static len_ } // to_json +static void +edges(uint32_t const head_row, uint32_t const head_col, uint32_t const head_length, + uint32_t const tail_row, uint32_t const tail_col, uint32_t const tail_length, + bool const is_source, bool const is_sink, + size_t const len_obs, char const observed[static len_obs]) +{ + printf( + "(%u, %u, %u) -> (%u, %u, %u)\n", + head_row, head_col, head_length, + tail_row, tail_col, tail_length + ); + + ptrdiff_t const row = (ptrdiff_t) head_row - is_source; + ptrdiff_t const col = (ptrdiff_t) head_col - is_source; + uint32_t const length = head_length + is_source; + + //printf("%zd, %zd, %u\n", row, col, length); + + ptrdiff_t const offset = MIN((ptrdiff_t) tail_row - row, (ptrdiff_t) tail_col - col) - 1; + uint32_t const head_start = offset > 0 ? MIN(offset, length - 1) : 0; + uint32_t const tail_start = offset < 0 ? MIN(-offset, tail_length - 1) : 0; + + //printf(" %zd: (%u, %u)\n", offset, head_start, tail_start); + + for (uint32_t j = 0; j < MIN(length - head_start, tail_length - tail_start + is_sink); ++j) + { + VA_Variant const variant = + { + row + head_start + j + 1, + tail_row + tail_start + j, + col + head_start + j + 1, + tail_col + tail_start + j + }; + + printf(" (%u, %u) -> (%u, %u) :: " VAR_FMT "\n", + head_row + head_start + j, head_col + head_start + j, + tail_row + tail_start + j, tail_col + tail_start + j, + print_variant(variant, observed) + ); + } // for +} // edges + + int main(int argc, char* argv[static argc + 1]) { @@ -845,51 +831,52 @@ main(int argc, char* argv[static argc + 1]) for (uint32_t head = 0; head < va_array_length(graph.nodes); ++head) { + uint32_t* tails = va_array_init(va_std_allocator, 10, sizeof(*tails)); for (uint32_t i = graph.nodes[head].edges; i != (uint32_t) -1; i = graph.edges[i].next) { uint32_t const tail = graph.edges[i].tail; - printf( - "(%u, %u, %u) -> (%u, %u, %u)\n", - graph.nodes[head].row, graph.nodes[head].col, graph.nodes[head].length, - graph.nodes[tail].row, graph.nodes[tail].col, graph.nodes[tail].length - ); - bool const is_source = graph.source == head; - bool const is_sink = graph.nodes[tail].edges == (uint32_t) -1; - ptrdiff_t const row = (ptrdiff_t) graph.nodes[head].row - is_source; - ptrdiff_t const col = (ptrdiff_t) graph.nodes[head].col - is_source; - uint32_t const length = graph.nodes[head].length + is_source; - - //printf("%zd, %zd, %u\n", row, col, length); - - ptrdiff_t const offset = MIN( - (ptrdiff_t) graph.nodes[tail].row - row, - (ptrdiff_t) graph.nodes[tail].col - col - ) - 1; - uint32_t const head_start = offset > 0 ? MIN(offset, length - 1) : 0; - uint32_t const tail_start = offset < 0 ? MIN(-offset, graph.nodes[tail].length - 1) : 0; - - //printf(" %zd: (%u, %u): %u\n", offset, head_start, tail_start); - - for (uint32_t j = 0; j < MIN(length - head_start, graph.nodes[tail].length - tail_start + is_sink); ++j) + bool found = false; + for (uint32_t j = 0; j < va_array_length(tails); ++j) { - VA_Variant const variant = + if (tail == tails[j]) { - row + head_start + j + 1, - graph.nodes[tail].row + tail_start + j, - col + head_start + j + 1, - graph.nodes[tail].col + tail_start + j - }; - - printf(" (%u, %u) -> (%u, %u) :: " VAR_FMT "\n", - graph.nodes[head].row + head_start + j, graph.nodes[head].col + head_start + j, - graph.nodes[tail].row + tail_start + j, graph.nodes[tail].col + tail_start + j, - print_variant(variant, observed) - ); + found = true; + break; + } // if } // for + if (found) + { + continue; + } // if + + va_array_append(va_std_allocator, tails, tail); + + edges( + graph.nodes[head].row, graph.nodes[head].col, graph.nodes[head].length, + graph.nodes[tail].row, graph.nodes[tail].col, graph.nodes[tail].length, + graph.source == head, graph.nodes[tail].edges == (uint32_t) -1, + len_obs, observed + ); } // for + tails = va_array_destroy(va_std_allocator, tails); } // for + /* + edges(1, 5, 5, 6, 6, 5, false, true, len_obs, observed); + edges(7, 8, 1, 6, 6, 4, false, false, len_obs, observed); + edges(4, 7, 1, 6, 6, 3, false, false, len_obs, observed); + edges(5, 0, 1, 6, 6, 1, false, false, len_obs, observed); + edges(1, 4, 1, 6, 6, 1, false, false, len_obs, observed); + edges(1, 3, 1, 6, 6, 1, false, false, len_obs, observed); + edges(1, 2, 1, 6, 6, 1, false, false, len_obs, observed); + edges(1, 1, 1, 6, 6, 1, false, false, len_obs, observed); + edges(7, 8, 1, 1, 5, 5, false, false, len_obs, observed); + edges(4, 7, 1, 1, 5, 4, false, false, len_obs, observed); + edges(5, 0, 1, 1, 5, 2, false, false, len_obs, observed); + edges(1, 4, 1, 1, 5, 2, false, false, len_obs, observed); + */ + destroy(va_std_allocator, &graph); return EXIT_SUCCESS; From 211cac6deee60d4311d640f7712d8c28fdadf90f Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 5 Nov 2024 10:30:00 +0100 Subject: [PATCH 129/704] Reconstructing edge labels --- src/main.c | 229 ++++++++++++++++++++++++++++++++++------------------- 1 file changed, 147 insertions(+), 82 deletions(-) diff --git a/src/main.c b/src/main.c index e18e8a4..ef9e0ae 100644 --- a/src/main.c +++ b/src/main.c @@ -2,7 +2,7 @@ #include // NULL, ptrdiff_t, size_t #include // uint32_t #include // stderr, fprintf, printf -#include // EXIT_* +#include // EXIT_*, atoi, rand, srand #include // strlen, strncmp #include "../include/alloc.h" // VA_Allocator @@ -723,31 +723,40 @@ to_json(Graph const graph, size_t const len_obs, char const observed[static len_ } // to_json -static void +static size_t edges(uint32_t const head_row, uint32_t const head_col, uint32_t const head_length, uint32_t const tail_row, uint32_t const tail_col, uint32_t const tail_length, - bool const is_source, bool const is_sink, - size_t const len_obs, char const observed[static len_obs]) + bool const is_source, + size_t const len_obs, char const observed[static len_obs], + VA_Variant const edge) { +/* printf( - "(%u, %u, %u) -> (%u, %u, %u)\n", + "(%u, %u, %u) -> (%u, %u, %u) source: %d\n", head_row, head_col, head_length, - tail_row, tail_col, tail_length + tail_row, tail_col, tail_length, + is_source ); + printf(VAR_FMT "\n", print_variant(edge, observed)); + printf("%u %u %u %u\n", edge.start, edge.end, edge.obs_start, edge.obs_end); +*/ ptrdiff_t const row = (ptrdiff_t) head_row - is_source; ptrdiff_t const col = (ptrdiff_t) head_col - is_source; uint32_t const length = head_length + is_source; - //printf("%zd, %zd, %u\n", row, col, length); +// printf("%zd, %zd, %u\n", row, col, length); ptrdiff_t const offset = MIN((ptrdiff_t) tail_row - row, (ptrdiff_t) tail_col - col) - 1; uint32_t const head_start = offset > 0 ? MIN(offset, length - 1) : 0; uint32_t const tail_start = offset < 0 ? MIN(-offset, tail_length - 1) : 0; - //printf(" %zd: (%u, %u)\n", offset, head_start, tail_start); + uint32_t const count = MIN(length - head_start, tail_length - tail_start); - for (uint32_t j = 0; j < MIN(length - head_start, tail_length - tail_start + is_sink); ++j) +// printf(" %zd: (%u, %u) :: %u\n", offset, head_start, tail_start, count); + + bool found = false; + for (uint32_t j = 0; j < count; ++j) { VA_Variant const variant = { @@ -757,78 +766,73 @@ edges(uint32_t const head_row, uint32_t const head_col, uint32_t const head_leng tail_col + tail_start + j }; - printf(" (%u, %u) -> (%u, %u) :: " VAR_FMT "\n", + if (edge.start == variant.start && edge.end == variant.end && + edge.obs_start == variant.obs_start && edge.obs_end == variant.obs_end) + { + found = true; + } // if +/* + printf(" (%u, %u) -> (%u, %u) :: " VAR_FMT "\n%u %u %u %u\n", head_row + head_start + j, head_col + head_start + j, tail_row + tail_start + j, tail_col + tail_start + j, - print_variant(variant, observed) + print_variant(variant, observed), + variant.start, variant.end, variant.obs_start, variant.obs_end ); +*/ } // for + + if (!found) + { + return -1; + } // if + return count; } // edges -int -main(int argc, char* argv[static argc + 1]) +static size_t +random_sequence(size_t const min, size_t const max, char sequence[static max]) { -/* - (void) argv; - char const* const restrict reference = "ATTCTATCTTCTGTCTACATAAGATGTCATACTAGAGGGCATATCTGCAATGTATACATATTATCTTTTCCAGCATGCATTCAGTTGTGTTGGAATAATTTATGTACACCTTTATAAACGCTGAGCCTCACAAGAGCCATGTGCCACGTATTGTTTTCTTACTACTTTTTGGGATACCTGGCACGTAATAGACACTCATTGAAAGTTTCCTAATGAATGAAGTACAAAGATAAAACAAGTTATAGACTGATTCTTTTGAGCTGTCAAGGTTGTAAATAGACTTTTGCTCAATCAATTCAAATGGTGGCAGGTAGTGGGGGTAGAGGGATTGGTATGAAAAACATAAGCTTTCAGAACTCCTGTGTTTATTTTTAGAATGTCAACTGCTTGAGTGTTTTTAACTCTGTGGTATCTGAACTATCTTCTCTAACTGCAGGTTGGGCTCAGATCTGTGATAGAACAGTTTCCTGGGAAGCTTGACTTTGTCCTTGTGGATGGGGGCTGTGTCCTAAGCCATGGCCACAAGCAGTTGATGTGCTTGGCTAGATCTGTTCTCAGTAAGGCGAAGATCTTGCTGCTTGATGAACCCAGTGCTCATTTGGATCCAGTGTGAGTTTCAGATGTTCTGTTACTTAATAGCACAGTGGGAACAGAATCATTATGCCTGCTTCATGGTGACACATATTTCTATTAGGCTGTCATGTCTGCGTGTGGGGGTCTCCCCCAAGATATGAAATAATTGCCCAGTGGAAATGAGCATAAATGCATATTTCCTTGCTAAGAGTCTTGTGTTTTCTTCCGAAGATAGTTTTTAGTTTCATACAAACTCTTCCCCCTTGTCAACACATGATGAAGCTTTTAAATACATGGGCCTAATCTGATCCTTATGATTTGCCTTTGTATCCCATTTATACCATAAGCATGTTTATAGCCCCAAATAAAGAAGTACTGGTGATTCTACATAATGAAAAATGTACTCATTTATTAAAGTTTCTTTGAAATATTTGTCCTGTTTATTTATGGATACTTAGAGTCTACCCCATGGTTGAAAAGCTGATTGTGGCTAACGCTATATCAACATTATGTGAAAAGAACTTAAAGAAATAAGTAATTTAAAGAGATAATAGAACAATAGACATATTATCAAGGTAAATACAGATCATTACTGTTCTGTGATATTATGTGTGGTATTTTCTTTCTTTTCTAGAACATACCAAATAATTAGAAGAACTCTAAAACAAGCATTTGCTGATTGCACAGTAATTCTCTGTGAACACAGGATAGAAGCAATGCTGGAATGCCAACAATTTTTGGTGAGTCTTTATAACTTTACTTAAGATCTCATTGCCCTTGTAATTCTTGATAACAATCTCACATGTGATAGTTCCTGCAAATTGCAACAATGTACAAGTTCTTTTCAAAAATATGTATCATACAGCCATCCAGCTTTACTCAAAATAGCTGCACAAGTTTTTCACTTTGATCTGAGCCATGTGGTGAGGTTGAAATATAGTAAATCTAAAATGGCAGCATATTACTAAGTTATGTTTATAAATAGGATATATATACTTTTTGAGCCCTTTATTTGGGGACCAAGTCATACAAAATACTCTACTGTTTAAGATTTTAAAAAAGGTCCCTGTGATTCTTTCAATAACTAAATGTCCCATGGATGTGGTCTGGGACAGGCCTAGTTGTCTTACAGTCTGATTTATGGTATTAATGACAAAGTTGAGAGGCACATTTCATTTTT"; - char const* const restrict observed = "ATTCTATCTTCTGTCTACATAAGATGTCATACTAGAGGGCATATCTGCAATGTATACATATTATCTTTTCCAGCATGCATTCAGTTGTGTTGGAATAATTTATGTACACCTTTATAAACGCTGAGCCTCACAAGAGCCATGTGCCACGTATTGTTTTCTTACTACTTTTTGGGATACCTGGCACGTAATAGACACTCATTGAAAGTTTCCTAATGAATGAAGTACAAAGATAAAACAAGTTATAGACTGATTCTTTTGAGCTGTCAAGGTTGTAAATAGACTTTTGCTCAATCAATTCAAATGGTGGCAGGTAGTGGGGGTAGAGGGATTGGTATGAAAAACATAAGCTTTCAGAACTCCTGTGTTTATTTTTAGAATGTCAACTGCTTGAGTGTTTTTAACTCTGTGGTATCTGAACTATCTTCTCTAACTGCAGGTGAGTCTTTATAACTTTACTTAAGATCTCATTGCCCTTGTAATTCTTGATAACAATCTCACATGTGATAGTTCCTGCAAATTGCAACAATGTACAAGTTCTTTTCAAAAATATGTATCATACAGCCATCCAGCTTTACTCAAAATAGCTGCACAAGTTTTTCACTTTGATCTGAGCCATGTGGTGAGGTTGAAATATAGTAAATCTAAAATGGCAGCATATTACTAAGTTATGTTTATAAATAGGATATATATACTTTTTGAGCCCTTTATTTGGGGACCAAGTCATACAAAATACTCTACTGTTTAAGATTTTAAAAAAGGTCCCTGTGATTCTTTCAATAACTAAATGTCCCATGGATGTGGTCTGGGACAGGCCTAGTTGTCTTACAGTCTGATTTATGGTATTAATGACAAAGTTGAGAGGCACATTTCATTTTT"; -*/ + size_t const len = rand() % (max - min) + min; - if (argc < 3) - { - fprintf(stderr, "usage: %s reference observed\n", argv[0]); - return EXIT_FAILURE; - } // if - char const* const restrict reference = argv[1]; - char const* const restrict observed = argv[2]; - bool lambda = false; - if (argc == 4 && strncmp(argv[3], "true", 4) == 0) + for (size_t i = 0; i < len; ++i) { - lambda = true; - } // if + sequence[i] = "ACGT"[rand() % 4]; + } // for - size_t const len_ref = strlen(reference); - size_t const len_obs = strlen(observed); + return len; +} // random_sequence + +static int +check(size_t const len_ref, char const reference[static len_ref], + size_t const len_obs, char const observed[static len_obs], + bool const debug) +{ VA_LCS_Node** lcs_nodes = NULL; size_t const len_lcs = va_edit(va_std_allocator, len_ref, reference, len_obs, observed, &lcs_nodes); - /* - fprintf(stderr, "%zu\n", len_lcs); - for (size_t i = 0; i < len_lcs; ++i) + + if (debug) { - fprintf(stderr, "%zu: ", i); - for (size_t j = 0; j < va_array_length(lcs_nodes[i]); ++j) + fprintf(stderr, "%zu\n", len_lcs); + for (size_t i = 0; i < len_lcs; ++i) { - fprintf(stderr, "(%u, %u, %u) ", lcs_nodes[i][j].row, lcs_nodes[i][j].col, lcs_nodes[i][j].length); + fprintf(stderr, "%zu: ", i); + for (size_t j = 0; j < va_array_length(lcs_nodes[i]); ++j) + { + fprintf(stderr, "(%u, %u, %u) ", lcs_nodes[i][j].row, lcs_nodes[i][j].col, lcs_nodes[i][j].length); + } // for + fprintf(stderr, "\n"); } // for - fprintf(stderr, "\n"); - } // for - */ + } // if Graph graph = build_graph(va_std_allocator, len_ref, len_obs, len_lcs, lcs_nodes, 0); -/* - printf("nodes (%zu)\n #\t(row, col, len)\tedges\tlambda\n", va_array_length(graph.nodes)); - for (size_t i = 0; i < va_array_length(graph.nodes); ++i) - { - printf("%c%2zu:\t(%u, %u, %u)\t%5d\t%6d\n", i == graph.source ? '*' : ' ', i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, (signed) graph.nodes[i].edges, (signed) graph.nodes[i].lambda); - } // for - printf("edges (%zu)\n #\ttail\t\"start:end/seq\"\tnext\n", va_array_length(graph.edges)); - for (size_t i = 0; i < va_array_length(graph.edges); ++i) + if (debug) { - printf("%3zu:\t%4u\t \"%u:%u/%.*s\"\t%4d\n", i, graph.edges[i].tail, graph.edges[i].variant.start, graph.edges[i].variant.end, (int) graph.edges[i].variant.obs_end - graph.edges[i].variant.obs_start, observed + graph.edges[i].variant.obs_start, (signed) graph.edges[i].next); - } // for -*/ - - to_dot(graph, len_obs, observed); - - //local_supremal(va_std_allocator, graph, len_obs, observed); - - //canonical(va_std_allocator, graph, len_obs, observed); - - //to_json(graph, len_obs, observed, lambda); + to_dot(graph, len_obs, observed); + } // if + size_t count = 0; for (uint32_t head = 0; head < va_array_length(graph.nodes); ++head) { uint32_t* tails = va_array_init(va_std_allocator, 10, sizeof(*tails)); @@ -845,39 +849,100 @@ main(int argc, char* argv[static argc + 1]) break; } // if } // for - if (found) - { - continue; - } // if va_array_append(va_std_allocator, tails, tail); - edges( + size_t const n = edges( graph.nodes[head].row, graph.nodes[head].col, graph.nodes[head].length, - graph.nodes[tail].row, graph.nodes[tail].col, graph.nodes[tail].length, - graph.source == head, graph.nodes[tail].edges == (uint32_t) -1, - len_obs, observed - ); + graph.nodes[tail].row, graph.nodes[tail].col, graph.nodes[tail].length + (graph.nodes[tail].edges == (uint32_t) -1), + graph.source == head, + len_obs, observed, + graph.edges[i].variant + ); + if (n == (size_t) -1) + { + printf("EDGE NOT FOUND: " VAR_FMT "\n", print_variant(graph.edges[i].variant, observed)); + return EXIT_FAILURE; + } // if + if (!found) + { + count += n; + } // if } // for tails = va_array_destroy(va_std_allocator, tails); } // for - /* - edges(1, 5, 5, 6, 6, 5, false, true, len_obs, observed); - edges(7, 8, 1, 6, 6, 4, false, false, len_obs, observed); - edges(4, 7, 1, 6, 6, 3, false, false, len_obs, observed); - edges(5, 0, 1, 6, 6, 1, false, false, len_obs, observed); - edges(1, 4, 1, 6, 6, 1, false, false, len_obs, observed); - edges(1, 3, 1, 6, 6, 1, false, false, len_obs, observed); - edges(1, 2, 1, 6, 6, 1, false, false, len_obs, observed); - edges(1, 1, 1, 6, 6, 1, false, false, len_obs, observed); - edges(7, 8, 1, 1, 5, 5, false, false, len_obs, observed); - edges(4, 7, 1, 1, 5, 4, false, false, len_obs, observed); - edges(5, 0, 1, 1, 5, 2, false, false, len_obs, observed); - edges(1, 4, 1, 1, 5, 2, false, false, len_obs, observed); - */ + if (count != va_array_length(graph.edges)) + { + printf("COUNTS: %zu vs %zu\n", count, va_array_length(graph.edges)); + return EXIT_FAILURE; + } // if destroy(va_std_allocator, &graph); + return EXIT_SUCCESS; +} // check + + +int +main(int argc, char* argv[static argc + 1]) +{ +/* + (void) argv; + char const* const restrict reference = "ATTCTATCTTCTGTCTACATAAGATGTCATACTAGAGGGCATATCTGCAATGTATACATATTATCTTTTCCAGCATGCATTCAGTTGTGTTGGAATAATTTATGTACACCTTTATAAACGCTGAGCCTCACAAGAGCCATGTGCCACGTATTGTTTTCTTACTACTTTTTGGGATACCTGGCACGTAATAGACACTCATTGAAAGTTTCCTAATGAATGAAGTACAAAGATAAAACAAGTTATAGACTGATTCTTTTGAGCTGTCAAGGTTGTAAATAGACTTTTGCTCAATCAATTCAAATGGTGGCAGGTAGTGGGGGTAGAGGGATTGGTATGAAAAACATAAGCTTTCAGAACTCCTGTGTTTATTTTTAGAATGTCAACTGCTTGAGTGTTTTTAACTCTGTGGTATCTGAACTATCTTCTCTAACTGCAGGTTGGGCTCAGATCTGTGATAGAACAGTTTCCTGGGAAGCTTGACTTTGTCCTTGTGGATGGGGGCTGTGTCCTAAGCCATGGCCACAAGCAGTTGATGTGCTTGGCTAGATCTGTTCTCAGTAAGGCGAAGATCTTGCTGCTTGATGAACCCAGTGCTCATTTGGATCCAGTGTGAGTTTCAGATGTTCTGTTACTTAATAGCACAGTGGGAACAGAATCATTATGCCTGCTTCATGGTGACACATATTTCTATTAGGCTGTCATGTCTGCGTGTGGGGGTCTCCCCCAAGATATGAAATAATTGCCCAGTGGAAATGAGCATAAATGCATATTTCCTTGCTAAGAGTCTTGTGTTTTCTTCCGAAGATAGTTTTTAGTTTCATACAAACTCTTCCCCCTTGTCAACACATGATGAAGCTTTTAAATACATGGGCCTAATCTGATCCTTATGATTTGCCTTTGTATCCCATTTATACCATAAGCATGTTTATAGCCCCAAATAAAGAAGTACTGGTGATTCTACATAATGAAAAATGTACTCATTTATTAAAGTTTCTTTGAAATATTTGTCCTGTTTATTTATGGATACTTAGAGTCTACCCCATGGTTGAAAAGCTGATTGTGGCTAACGCTATATCAACATTATGTGAAAAGAACTTAAAGAAATAAGTAATTTAAAGAGATAATAGAACAATAGACATATTATCAAGGTAAATACAGATCATTACTGTTCTGTGATATTATGTGTGGTATTTTCTTTCTTTTCTAGAACATACCAAATAATTAGAAGAACTCTAAAACAAGCATTTGCTGATTGCACAGTAATTCTCTGTGAACACAGGATAGAAGCAATGCTGGAATGCCAACAATTTTTGGTGAGTCTTTATAACTTTACTTAAGATCTCATTGCCCTTGTAATTCTTGATAACAATCTCACATGTGATAGTTCCTGCAAATTGCAACAATGTACAAGTTCTTTTCAAAAATATGTATCATACAGCCATCCAGCTTTACTCAAAATAGCTGCACAAGTTTTTCACTTTGATCTGAGCCATGTGGTGAGGTTGAAATATAGTAAATCTAAAATGGCAGCATATTACTAAGTTATGTTTATAAATAGGATATATATACTTTTTGAGCCCTTTATTTGGGGACCAAGTCATACAAAATACTCTACTGTTTAAGATTTTAAAAAAGGTCCCTGTGATTCTTTCAATAACTAAATGTCCCATGGATGTGGTCTGGGACAGGCCTAGTTGTCTTACAGTCTGATTTATGGTATTAATGACAAAGTTGAGAGGCACATTTCATTTTT"; + char const* const restrict observed = "ATTCTATCTTCTGTCTACATAAGATGTCATACTAGAGGGCATATCTGCAATGTATACATATTATCTTTTCCAGCATGCATTCAGTTGTGTTGGAATAATTTATGTACACCTTTATAAACGCTGAGCCTCACAAGAGCCATGTGCCACGTATTGTTTTCTTACTACTTTTTGGGATACCTGGCACGTAATAGACACTCATTGAAAGTTTCCTAATGAATGAAGTACAAAGATAAAACAAGTTATAGACTGATTCTTTTGAGCTGTCAAGGTTGTAAATAGACTTTTGCTCAATCAATTCAAATGGTGGCAGGTAGTGGGGGTAGAGGGATTGGTATGAAAAACATAAGCTTTCAGAACTCCTGTGTTTATTTTTAGAATGTCAACTGCTTGAGTGTTTTTAACTCTGTGGTATCTGAACTATCTTCTCTAACTGCAGGTGAGTCTTTATAACTTTACTTAAGATCTCATTGCCCTTGTAATTCTTGATAACAATCTCACATGTGATAGTTCCTGCAAATTGCAACAATGTACAAGTTCTTTTCAAAAATATGTATCATACAGCCATCCAGCTTTACTCAAAATAGCTGCACAAGTTTTTCACTTTGATCTGAGCCATGTGGTGAGGTTGAAATATAGTAAATCTAAAATGGCAGCATATTACTAAGTTATGTTTATAAATAGGATATATATACTTTTTGAGCCCTTTATTTGGGGACCAAGTCATACAAAATACTCTACTGTTTAAGATTTTAAAAAAGGTCCCTGTGATTCTTTCAATAACTAAATGTCCCATGGATGTGGTCTGGGACAGGCCTAGTTGTCTTACAGTCTGATTTATGGTATTAATGACAAAGTTGAGAGGCACATTTCATTTTT"; +*/ + + if (argc == 2) + { + srand(atoi(argv[1])); + size_t count = 0; + while (true) + { + char reference[4096]; + char observed[4096]; + size_t const len_ref = random_sequence(0, 40, reference); + size_t const len_obs = random_sequence(0, 40, observed); + + printf("%zu: %.*s %.*s\n", count, (int) len_ref, reference, (int) len_obs, observed); + if (check(len_ref, reference, len_obs, observed, false) == EXIT_FAILURE) + { + return EXIT_FAILURE; + } // if + count += 1; + } // while + } // if + else if (argc == 3) + { + char const* const restrict reference = argv[1]; + char const* const restrict observed = argv[2]; + size_t const len_ref = strlen(reference); + size_t const len_obs = strlen(observed); + check(len_ref, reference, len_obs, observed, true); + } // if + else + { + fprintf(stderr, "usage: %s\n", argv[0]); + return EXIT_FAILURE; + } // else + +/* + printf("nodes (%zu)\n #\t(row, col, len)\tedges\tlambda\n", va_array_length(graph.nodes)); + for (size_t i = 0; i < va_array_length(graph.nodes); ++i) + { + printf("%c%2zu:\t(%u, %u, %u)\t%5d\t%6d\n", i == graph.source ? '*' : ' ', i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, (signed) graph.nodes[i].edges, (signed) graph.nodes[i].lambda); + } // for + printf("edges (%zu)\n #\ttail\t\"start:end/seq\"\tnext\n", va_array_length(graph.edges)); + for (size_t i = 0; i < va_array_length(graph.edges); ++i) + { + printf("%3zu:\t%4u\t \"%u:%u/%.*s\"\t%4d\n", i, graph.edges[i].tail, graph.edges[i].variant.start, graph.edges[i].variant.end, (int) graph.edges[i].variant.obs_end - graph.edges[i].variant.obs_start, observed + graph.edges[i].variant.obs_start, (signed) graph.edges[i].next); + } // for +*/ + + //local_supremal(va_std_allocator, graph, len_obs, observed); + + //canonical(va_std_allocator, graph, len_obs, observed); + + //to_json(graph, len_obs, observed, lambda); return EXIT_SUCCESS; } // main From e686ac3d0c9ff72fa95e09ea46f56b15a207a20a Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 12 Nov 2024 16:53:46 +0100 Subject: [PATCH 130/704] Start on build graph again --- src/main.c | 176 ++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 147 insertions(+), 29 deletions(-) diff --git a/src/main.c b/src/main.c index ef9e0ae..c897976 100644 --- a/src/main.c +++ b/src/main.c @@ -1,6 +1,6 @@ #include // bool, false, true -#include // NULL, ptrdiff_t, size_t -#include // uint32_t +#include // NULL, size_t +#include // intmax_t, uint32_t #include // stderr, fprintf, printf #include // EXIT_*, atoi, rand, srand #include // strlen, strncmp @@ -19,6 +19,20 @@ #define VAR_FMT "%u:%u/%.*s" +static size_t +random_sequence(size_t const min, size_t const max, char sequence[static max]) +{ + size_t const len = rand() % (max - min) + min; + + for (size_t i = 0; i < len; ++i) + { + sequence[i] = "ACGT"[rand() % 4]; + } // for + + return len; +} // random_sequence + + typedef struct { uint32_t tail; @@ -697,7 +711,7 @@ lambda_edges(Graph const graph, size_t const len_obs, char const observed[static printf("\n ],\n"); } // lambda_edges - +/* static void to_json(Graph const graph, size_t const len_obs, char const observed[static len_obs], bool const lambda) { @@ -721,6 +735,7 @@ to_json(Graph const graph, size_t const len_obs, char const observed[static len_ printf("\n ]\n"); printf("}"); } // to_json +*/ static size_t @@ -730,22 +745,20 @@ edges(uint32_t const head_row, uint32_t const head_col, uint32_t const head_leng size_t const len_obs, char const observed[static len_obs], VA_Variant const edge) { -/* printf( "(%u, %u, %u) -> (%u, %u, %u) source: %d\n", head_row, head_col, head_length, tail_row, tail_col, tail_length, is_source ); - printf(VAR_FMT "\n", print_variant(edge, observed)); + //printf(VAR_FMT "\n", print_variant(edge, observed)); printf("%u %u %u %u\n", edge.start, edge.end, edge.obs_start, edge.obs_end); -*/ ptrdiff_t const row = (ptrdiff_t) head_row - is_source; ptrdiff_t const col = (ptrdiff_t) head_col - is_source; uint32_t const length = head_length + is_source; -// printf("%zd, %zd, %u\n", row, col, length); + printf("%zd, %zd, %u\n", row, col, length); ptrdiff_t const offset = MIN((ptrdiff_t) tail_row - row, (ptrdiff_t) tail_col - col) - 1; uint32_t const head_start = offset > 0 ? MIN(offset, length - 1) : 0; @@ -753,7 +766,13 @@ edges(uint32_t const head_row, uint32_t const head_col, uint32_t const head_leng uint32_t const count = MIN(length - head_start, tail_length - tail_start); -// printf(" %zd: (%u, %u) :: %u\n", offset, head_start, tail_start, count); + printf(" %zd: (%u, %u) :: %u\n", offset, head_start, tail_start, count); + + if (offset < 0 && tail_length <= -offset) + { + printf(" X\n"); + return 0; + } // if bool found = false; for (uint32_t j = 0; j < count; ++j) @@ -771,14 +790,13 @@ edges(uint32_t const head_row, uint32_t const head_col, uint32_t const head_leng { found = true; } // if -/* - printf(" (%u, %u) -> (%u, %u) :: " VAR_FMT "\n%u %u %u %u\n", + + printf(" (%u, %u) -> (%u, %u) :: " VAR_FMT "\n", //"%u %u %u %u\n", head_row + head_start + j, head_col + head_start + j, tail_row + tail_start + j, tail_col + tail_start + j, - print_variant(variant, observed), - variant.start, variant.end, variant.obs_start, variant.obs_end + print_variant(variant, observed) //, + //variant.start, variant.end, variant.obs_start, variant.obs_end ); -*/ } // for if (!found) @@ -789,20 +807,6 @@ edges(uint32_t const head_row, uint32_t const head_col, uint32_t const head_leng } // edges -static size_t -random_sequence(size_t const min, size_t const max, char sequence[static max]) -{ - size_t const len = rand() % (max - min) + min; - - for (size_t i = 0; i < len; ++i) - { - sequence[i] = "ACGT"[rand() % 4]; - } // for - - return len; -} // random_sequence - - static int check(size_t const len_ref, char const reference[static len_ref], size_t const len_obs, char const observed[static len_obs], @@ -874,7 +878,7 @@ check(size_t const len_ref, char const reference[static len_ref], if (count != va_array_length(graph.edges)) { - printf("COUNTS: %zu vs %zu\n", count, va_array_length(graph.edges)); + printf("COUNTS: %zu vs %zu1:5/, o\n", count, va_array_length(graph.edges)); return EXIT_FAILURE; } // if @@ -883,6 +887,104 @@ check(size_t const len_ref, char const reference[static len_ref], } // check +static void +edges2(VA_LCS_Node const head, VA_LCS_Node const tail, bool const is_source, + size_t const len_obs, char const observed[static len_obs]) +{ + printf("%u %u %u -> %u %u %u %s\n", head.row, head.col, head.length, tail.row, tail.col, tail.length, is_source ? "SOURCE" : ""); + + intmax_t const row = (intmax_t) head.row - is_source; + intmax_t const col = (intmax_t) head.col - is_source; + uint32_t const length = head.length + is_source; + + intmax_t const offset = MIN((intmax_t) tail.row - row, (intmax_t) tail.col - col) - 1; + + uint32_t const head_offset = offset > 0 ? MIN(length, offset + 1) : 1; + uint32_t const tail_offset = offset < 0 ? MIN(tail.length, -offset) : 0; + + //printf(" %ld: (%u, %u)\n", offset, head_offset, tail_offset); + + if (head_offset > length || (tail.length > 0 && tail_offset >= tail.length)) + { + printf(" NO EDGE\n"); + return; + } // if + + uint32_t const count = MIN(length - head_offset, tail.length - tail_offset - 1) + 1; + + VA_Variant const variant = {row + head_offset, tail.row + tail_offset, col + head_offset, tail.col + tail_offset}; + + printf(" " VAR_FMT " x %u\n", print_variant(variant, observed), count); +} // edges2 + + +static void +build(size_t const len_ref, char const reference[static len_ref], + size_t const len_obs, char const observed[static len_obs], + size_t const shift) +{ + VA_LCS_Node** lcs_nodes = NULL; + size_t const len_lcs = va_edit(va_std_allocator, len_ref, reference, len_obs, observed, &lcs_nodes); + + if (len_lcs == 0 || lcs_nodes == NULL) + { + fprintf(stderr, "Trivial graph\n"); + return; + } // if + + VA_LCS_Node const last = lcs_nodes[len_lcs - 1][va_array_length(lcs_nodes[len_lcs - 1]) - 1]; + if (last.row + last.length != len_ref + shift || last.col + last.length != len_obs + shift) + { + va_array_append(va_std_allocator, lcs_nodes[len_lcs - 1], ((VA_LCS_Node) {.row = len_ref + shift, .col = len_obs + shift, .length = 0})); + } // if + + fprintf(stderr, "%zu\n", len_lcs); + for (size_t i = 0; i < len_lcs; ++i) + { + fprintf(stderr, "%zu: ", i); + for (size_t j = 0; j < va_array_length(lcs_nodes[i]); ++j) + { + fprintf(stderr, "(%u, %u, %u) ", lcs_nodes[i][j].row, lcs_nodes[i][j].col, lcs_nodes[i][j].length); + } // for + fprintf(stderr, "\n"); + } // for + + bool is_sink = true; + for (size_t t_i = 0; t_i < len_lcs; ++t_i) + { + size_t const t_len = va_array_length(lcs_nodes[len_lcs - t_i - 1]); + for (size_t t_j = 0; t_j < t_len; ++t_j) + { + VA_LCS_Node const tail = lcs_nodes[len_lcs - t_i - 1][t_len - t_j - 1]; + bool const is_source = tail.row == shift && tail.col == shift; + printf("%s", is_sink ? "SINK\n" : ""); + //printf("%u %u %u\n", tail.row, tail.col, tail.length); + + for (size_t h_i = 0; h_i < MIN(len_lcs - t_i, tail.length + 1); ++h_i) + { + size_t const h_len = h_i == 0 ? t_len - t_j - 1: va_array_length(lcs_nodes[len_lcs - t_i - h_i - 1]); + //printf(" level: %zu with %zu nodes\n", len_lcs - t_i - h_i - 1, h_len); + for (size_t h_j = 0; h_j < h_len; ++h_j) + { + VA_LCS_Node const head = lcs_nodes[len_lcs - t_i - h_i - 1][h_j]; + //printf(" %u %u %u\n", head.row, head.col, head.length); + if (is_source) + { + edges2(tail, head, true, len_obs, observed); + } // if + else + { + edges2(head, tail, head.row == shift && head.col == shift, len_obs, observed); + } // else + } // for + is_sink = false; + } // for + + } // for + } // for + +} // build + int main(int argc, char* argv[static argc + 1]) { @@ -917,7 +1019,22 @@ main(int argc, char* argv[static argc + 1]) char const* const restrict observed = argv[2]; size_t const len_ref = strlen(reference); size_t const len_obs = strlen(observed); - check(len_ref, reference, len_obs, observed, true); + //check(len_ref, reference, len_obs, observed, true); + + build(len_ref, reference, len_obs, observed, 0); + +/* + edges2((VA_LCS_Node) {.row = 0, .col = 0, .length = 4}, (VA_LCS_Node) {.row = 5, .col = 2, .length = 1}, true, len_obs, observed); + edges2((VA_LCS_Node) {.row = 0, .col = 0, .length = 4}, (VA_LCS_Node) {.row = 2, .col = 1, .length = 1}, true, len_obs, observed); + edges2((VA_LCS_Node) {.row = 0, .col = 0, .length = 4}, (VA_LCS_Node) {.row = 4, .col = 0, .length = 5}, true, len_obs, observed); + edges2((VA_LCS_Node) {.row = 4, .col = 0, .length = 5}, (VA_LCS_Node) {.row = 10, .col = 10, .length = 0}, false, len_obs, observed); + edges2((VA_LCS_Node) {.row = 5, .col = 2, .length = 1}, (VA_LCS_Node) {.row = 4, .col = 0, .length = 5}, false, len_obs, observed); + edges2((VA_LCS_Node) {.row = 0, .col = 0, .length = 4}, (VA_LCS_Node) {.row = 4, .col = 9, .length = 1}, true, len_obs, observed); + edges2((VA_LCS_Node) {.row = 0, .col = 0, .length = 4}, (VA_LCS_Node) {.row = 8, .col = 8, .length = 1}, true, len_obs, observed); + edges2((VA_LCS_Node) {.row = 2, .col = 1, .length = 1}, (VA_LCS_Node) {.row = 8, .col = 5, .length = 1}, false, len_obs, observed); + edges2((VA_LCS_Node) {.row = 8, .col = 5, .length = 1}, (VA_LCS_Node) {.row = 2, .col = 1, .length = 1}, false, len_obs, observed); + edges2((VA_LCS_Node) {.row = 2, .col = 1, .length = 1}, (VA_LCS_Node) {.row = 5, .col = 2, .length = 1}, false, len_obs, observed); +*/ } // if else { @@ -928,6 +1045,7 @@ main(int argc, char* argv[static argc + 1]) /* printf("nodes (%zu)\n #\t(row, col, len)\tedges\tlambda\n", va_array_length(graph.nodes)); for (size_t i = 0; i < va_array_length(graph.nodes); ++i) + { printf("%c%2zu:\t(%u, %u, %u)\t%5d\t%6d\n", i == graph.source ? '*' : ' ', i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, (signed) graph.nodes[i].edges, (signed) graph.nodes[i].lambda); } // for From de1f3f31f4da355a163e322e459de8f8ed5697f4 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 14 Nov 2024 12:46:20 +0100 Subject: [PATCH 131/704] WIP building graph --- src/main.c | 101 +++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 74 insertions(+), 27 deletions(-) diff --git a/src/main.c b/src/main.c index c897976..99fc691 100644 --- a/src/main.c +++ b/src/main.c @@ -888,33 +888,35 @@ check(size_t const len_ref, char const reference[static len_ref], static void -edges2(VA_LCS_Node const head, VA_LCS_Node const tail, bool const is_source, +edges2(VA_LCS_Node const head, VA_LCS_Node const tail, + bool const is_source, bool const is_sink, size_t const len_obs, char const observed[static len_obs]) { - printf("%u %u %u -> %u %u %u %s\n", head.row, head.col, head.length, tail.row, tail.col, tail.length, is_source ? "SOURCE" : ""); + //printf("%u %u %u -> %u %u %u %s %s\n", head.row, head.col, head.length, tail.row, tail.col, tail.length, is_source ? "SOURCE" : "", is_sink ? "SINK" : ""); intmax_t const row = (intmax_t) head.row - is_source; intmax_t const col = (intmax_t) head.col - is_source; - uint32_t const length = head.length + is_source; + uint32_t const head_length = head.length + is_source; + uint32_t const tail_length = tail.length + is_sink; intmax_t const offset = MIN((intmax_t) tail.row - row, (intmax_t) tail.col - col) - 1; - uint32_t const head_offset = offset > 0 ? MIN(length, offset + 1) : 1; - uint32_t const tail_offset = offset < 0 ? MIN(tail.length, -offset) : 0; + uint32_t const head_offset = offset > 0 ? MIN(head_length, offset + 1) : 1; + uint32_t const tail_offset = offset < 0 ? MIN(tail_length, -offset) : 0; //printf(" %ld: (%u, %u)\n", offset, head_offset, tail_offset); - if (head_offset > length || (tail.length > 0 && tail_offset >= tail.length)) + if (head_offset > head_length || (tail_length > 0 && tail_offset >= tail_length)) { - printf(" NO EDGE\n"); + printf("NO EDGE\n"); return; } // if - uint32_t const count = MIN(length - head_offset, tail.length - tail_offset - 1) + 1; + uint32_t const count = MIN(head_length - head_offset, tail_length - tail_offset - 1) + 1; VA_Variant const variant = {row + head_offset, tail.row + tail_offset, col + head_offset, tail.col + tail_offset}; - printf(" " VAR_FMT " x %u\n", print_variant(variant, observed), count); + printf(VAR_FMT " x %u\n", print_variant(variant, observed), count); } // edges2 @@ -949,6 +951,9 @@ build(size_t const len_ref, char const reference[static len_ref], fprintf(stderr, "\n"); } // for + + VA_LCS_Node source = {.row = shift, .col = shift, .length = 0}; + bool found_source = false; bool is_sink = true; for (size_t t_i = 0; t_i < len_lcs; ++t_i) { @@ -957,8 +962,12 @@ build(size_t const len_ref, char const reference[static len_ref], { VA_LCS_Node const tail = lcs_nodes[len_lcs - t_i - 1][t_len - t_j - 1]; bool const is_source = tail.row == shift && tail.col == shift; - printf("%s", is_sink ? "SINK\n" : ""); - //printf("%u %u %u\n", tail.row, tail.col, tail.length); + if (is_source) + { + source = tail; + found_source = true; + } // if + printf("%u %u %u\n", tail.row, tail.col, tail.length); for (size_t h_i = 0; h_i < MIN(len_lcs - t_i, tail.length + 1); ++h_i) { @@ -967,24 +976,41 @@ build(size_t const len_ref, char const reference[static len_ref], for (size_t h_j = 0; h_j < h_len; ++h_j) { VA_LCS_Node const head = lcs_nodes[len_lcs - t_i - h_i - 1][h_j]; - //printf(" %u %u %u\n", head.row, head.col, head.length); - if (is_source) + + printf(" %u %u %u: ", head.row, head.col, head.length); + + if (head.row + head.length > tail.row + tail.length - h_i || + head.col + head.length > tail.col + tail.length - h_i) { - edges2(tail, head, true, len_obs, observed); + if (tail.row + tail.length - h_i > head.row + head.length || + tail.col + tail.length - h_i > head.col + head.length) + { + printf("--\n"); + } // if + else + { + //printf(" CONVERSE\n"); + edges2(tail, head, is_source, false, len_obs, observed); + } // else } // if else { - edges2(head, tail, head.row == shift && head.col == shift, len_obs, observed); + edges2(head, tail, head.row == shift && head.col == shift, is_sink, len_obs, observed); } // else + } // for is_sink = false; } // for - + if (!found_source && tail.length >= len_lcs - t_i) + { + printf(" %u %u %u: ", source.row, source.col, source.length); + edges2(source, tail, true, is_sink, len_obs, observed); + } // if } // for } // for - } // build + int main(int argc, char* argv[static argc + 1]) { @@ -1024,17 +1050,38 @@ main(int argc, char* argv[static argc + 1]) build(len_ref, reference, len_obs, observed, 0); /* - edges2((VA_LCS_Node) {.row = 0, .col = 0, .length = 4}, (VA_LCS_Node) {.row = 5, .col = 2, .length = 1}, true, len_obs, observed); - edges2((VA_LCS_Node) {.row = 0, .col = 0, .length = 4}, (VA_LCS_Node) {.row = 2, .col = 1, .length = 1}, true, len_obs, observed); - edges2((VA_LCS_Node) {.row = 0, .col = 0, .length = 4}, (VA_LCS_Node) {.row = 4, .col = 0, .length = 5}, true, len_obs, observed); - edges2((VA_LCS_Node) {.row = 4, .col = 0, .length = 5}, (VA_LCS_Node) {.row = 10, .col = 10, .length = 0}, false, len_obs, observed); - edges2((VA_LCS_Node) {.row = 5, .col = 2, .length = 1}, (VA_LCS_Node) {.row = 4, .col = 0, .length = 5}, false, len_obs, observed); - edges2((VA_LCS_Node) {.row = 0, .col = 0, .length = 4}, (VA_LCS_Node) {.row = 4, .col = 9, .length = 1}, true, len_obs, observed); - edges2((VA_LCS_Node) {.row = 0, .col = 0, .length = 4}, (VA_LCS_Node) {.row = 8, .col = 8, .length = 1}, true, len_obs, observed); - edges2((VA_LCS_Node) {.row = 2, .col = 1, .length = 1}, (VA_LCS_Node) {.row = 8, .col = 5, .length = 1}, false, len_obs, observed); - edges2((VA_LCS_Node) {.row = 8, .col = 5, .length = 1}, (VA_LCS_Node) {.row = 2, .col = 1, .length = 1}, false, len_obs, observed); - edges2((VA_LCS_Node) {.row = 2, .col = 1, .length = 1}, (VA_LCS_Node) {.row = 5, .col = 2, .length = 1}, false, len_obs, observed); + edges2((VA_LCS_Node) {.row = 1, .col = 5, .length = 5}, (VA_LCS_Node) {.row = 6, .col = 6, .length = 4}, false, true, len_obs, observed); + edges2((VA_LCS_Node) {.row = 7, .col = 8, .length = 1}, (VA_LCS_Node) {.row = 6, .col = 6, .length = 4}, false, true, len_obs, observed); + edges2((VA_LCS_Node) {.row = 4, .col = 7, .length = 1}, (VA_LCS_Node) {.row = 6, .col = 6, .length = 4}, false, true, len_obs, observed); + edges2((VA_LCS_Node) {.row = 1, .col = 1, .length = 1}, (VA_LCS_Node) {.row = 6, .col = 6, .length = 4}, false, true, len_obs, observed); + edges2((VA_LCS_Node) {.row = 1, .col = 2, .length = 1}, (VA_LCS_Node) {.row = 6, .col = 6, .length = 4}, false, true, len_obs, observed); + edges2((VA_LCS_Node) {.row = 1, .col = 3, .length = 1}, (VA_LCS_Node) {.row = 6, .col = 6, .length = 4}, false, true, len_obs, observed); + edges2((VA_LCS_Node) {.row = 1, .col = 4, .length = 1}, (VA_LCS_Node) {.row = 6, .col = 6, .length = 4}, false, true, len_obs, observed); + edges2((VA_LCS_Node) {.row = 5, .col = 0, .length = 1}, (VA_LCS_Node) {.row = 6, .col = 6, .length = 4}, false, true, len_obs, observed); + + edges2((VA_LCS_Node) {.row = 1, .col = 5, .length = 5}, (VA_LCS_Node) {.row = 7, .col = 8, .length = 1}, false, false, len_obs, observed); + edges2((VA_LCS_Node) {.row = 1, .col = 5, .length = 5}, (VA_LCS_Node) {.row = 4, .col = 7, .length = 1}, false, false, len_obs, observed); + edges2((VA_LCS_Node) {.row = 1, .col = 1, .length = 1}, (VA_LCS_Node) {.row = 1, .col = 5, .length = 5}, false, false, len_obs, observed); + edges2((VA_LCS_Node) {.row = 1, .col = 2, .length = 1}, (VA_LCS_Node) {.row = 1, .col = 5, .length = 5}, false, false, len_obs, observed); + edges2((VA_LCS_Node) {.row = 1, .col = 3, .length = 1}, (VA_LCS_Node) {.row = 1, .col = 5, .length = 5}, false, false, len_obs, observed); + edges2((VA_LCS_Node) {.row = 1, .col = 4, .length = 1}, (VA_LCS_Node) {.row = 1, .col = 5, .length = 5}, false, false, len_obs, observed); + edges2((VA_LCS_Node) {.row = 5, .col = 0, .length = 1}, (VA_LCS_Node) {.row = 1, .col = 5, .length = 5}, false, false, len_obs, observed); + edges2((VA_LCS_Node) {.row = 0, .col = 0, .length = 0}, (VA_LCS_Node) {.row = 1, .col = 5, .length = 5}, true, false, len_obs, observed); + + edges2((VA_LCS_Node) {.row = 4, .col = 7, .length = 1}, (VA_LCS_Node) {.row = 7, .col = 8, .length = 1}, false, false, len_obs, observed); + + edges2((VA_LCS_Node) {.row = 1, .col = 1, .length = 1}, (VA_LCS_Node) {.row = 5, .col = 0, .length = 1}, false, false, len_obs, observed); + edges2((VA_LCS_Node) {.row = 1, .col = 2, .length = 1}, (VA_LCS_Node) {.row = 5, .col = 0, .length = 1}, false, false, len_obs, observed); + edges2((VA_LCS_Node) {.row = 1, .col = 3, .length = 1}, (VA_LCS_Node) {.row = 5, .col = 0, .length = 1}, false, false, len_obs, observed); + edges2((VA_LCS_Node) {.row = 1, .col = 4, .length = 1}, (VA_LCS_Node) {.row = 5, .col = 0, .length = 1}, false, false, len_obs, observed); + edges2((VA_LCS_Node) {.row = 0, .col = 0, .length = 0}, (VA_LCS_Node) {.row = 5, .col = 0, .length = 1}, true, false, len_obs, observed); + + edges2((VA_LCS_Node) {.row = 1, .col = 1, .length = 1}, (VA_LCS_Node) {.row = 1, .col = 4, .length = 1}, false, false, len_obs, observed); + edges2((VA_LCS_Node) {.row = 1, .col = 2, .length = 1}, (VA_LCS_Node) {.row = 1, .col = 4, .length = 1}, false, false, len_obs, observed); + edges2((VA_LCS_Node) {.row = 1, .col = 3, .length = 1}, (VA_LCS_Node) {.row = 1, .col = 4, .length = 1}, false, false, len_obs, observed); + edges2((VA_LCS_Node) {.row = 0, .col = 0, .length = 0}, (VA_LCS_Node) {.row = 1, .col = 4, .length = 1}, true, false, len_obs, observed); */ + } // if else { From 43e1df47cd60e28858476873fa3aadc3c83c9be5 Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 20 Nov 2024 16:34:02 +0100 Subject: [PATCH 132/704] Snapshot before build --- src/main.c | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/src/main.c b/src/main.c index 99fc691..a8e297e 100644 --- a/src/main.c +++ b/src/main.c @@ -887,7 +887,7 @@ check(size_t const len_ref, char const reference[static len_ref], } // check -static void +static bool edges2(VA_LCS_Node const head, VA_LCS_Node const tail, bool const is_source, bool const is_sink, size_t const len_obs, char const observed[static len_obs]) @@ -909,7 +909,7 @@ edges2(VA_LCS_Node const head, VA_LCS_Node const tail, if (head_offset > head_length || (tail_length > 0 && tail_offset >= tail_length)) { printf("NO EDGE\n"); - return; + return false; } // if uint32_t const count = MIN(head_length - head_offset, tail_length - tail_offset - 1) + 1; @@ -917,9 +917,26 @@ edges2(VA_LCS_Node const head, VA_LCS_Node const tail, VA_Variant const variant = {row + head_offset, tail.row + tail_offset, col + head_offset, tail.col + tail_offset}; printf(VAR_FMT " x %u\n", print_variant(variant, observed), count); + return true; } // edges2 +typedef struct +{ + uint32_t row; + uint32_t col; + uint32_t length; + uint32_t edges; +} Node2; + + +typedef struct +{ + uint32_t tail; + uint32_t next; +} Edge2; + + static void build(size_t const len_ref, char const reference[static len_ref], size_t const len_obs, char const observed[static len_obs], @@ -951,6 +968,8 @@ build(size_t const len_ref, char const reference[static len_ref], fprintf(stderr, "\n"); } // for + Node2* nodes = NULL; + Edge2* edges = NULL; VA_LCS_Node source = {.row = shift, .col = shift, .length = 0}; bool found_source = false; @@ -989,7 +1008,7 @@ build(size_t const len_ref, char const reference[static len_ref], } // if else { - //printf(" CONVERSE\n"); + printf("CONVERSE "); edges2(tail, head, is_source, false, len_obs, observed); } // else } // if @@ -1007,7 +1026,10 @@ build(size_t const len_ref, char const reference[static len_ref], edges2(source, tail, true, is_sink, len_obs, observed); } // if } // for + lcs_nodes[len_lcs - t_i - 1] = va_array_destroy(va_std_allocator, lcs_nodes[len_lcs - t_i - 1]); } // for + + lcs_nodes = va_std_allocator.alloc(va_std_allocator.context, lcs_nodes, len_lcs, 0); } // build @@ -1045,7 +1067,7 @@ main(int argc, char* argv[static argc + 1]) char const* const restrict observed = argv[2]; size_t const len_ref = strlen(reference); size_t const len_obs = strlen(observed); - //check(len_ref, reference, len_obs, observed, true); + check(len_ref, reference, len_obs, observed, true); build(len_ref, reference, len_obs, observed, 0); From 350b28708a814784b21cfc5e05775d53f32288a8 Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 12 Mar 2025 09:29:44 +0100 Subject: [PATCH 133/704] Modern compiler --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 29f2573..09fa1b2 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ TEST_COVS = $(TESTS:.c=.c.gcov) TARGET = a.out -CC = gcc-11 +CC = gcc CFLAGS = -std=c99 -march=native -Wall -Wextra -Wpedantic -fanalyzer MEMCHECK = valgrind -q --leak-check=full --error-exitcode=1 @@ -53,7 +53,7 @@ $(TARGET): $(OBJECTS) $(MEMCHECK) ./$< %.c.gcov: %.gcda - gcov-11 $< + gcov $< mv *.gcov $(TEST_DIR) From 00f718289a0f480128f18d229327243e7cf96d2c Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Mon, 17 Mar 2025 16:53:47 +0100 Subject: [PATCH 134/704] WIP WIP. --- src/main.c | 86 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 51 insertions(+), 35 deletions(-) diff --git a/src/main.c b/src/main.c index a8e297e..79b16bd 100644 --- a/src/main.c +++ b/src/main.c @@ -921,15 +921,6 @@ edges2(VA_LCS_Node const head, VA_LCS_Node const tail, } // edges2 -typedef struct -{ - uint32_t row; - uint32_t col; - uint32_t length; - uint32_t edges; -} Node2; - - typedef struct { uint32_t tail; @@ -951,79 +942,104 @@ build(size_t const len_ref, char const reference[static len_ref], return; } // if - VA_LCS_Node const last = lcs_nodes[len_lcs - 1][va_array_length(lcs_nodes[len_lcs - 1]) - 1]; - if (last.row + last.length != len_ref + shift || last.col + last.length != len_obs + shift) + VA_LCS_Node* last = &lcs_nodes[len_lcs - 1][va_array_length(lcs_nodes[len_lcs - 1]) - 1]; + if (last->row + last->length != len_ref + shift || last->col + last->length != len_obs + shift) { va_array_append(va_std_allocator, lcs_nodes[len_lcs - 1], ((VA_LCS_Node) {.row = len_ref + shift, .col = len_obs + shift, .length = 0})); } // if + Node* nodes = NULL; + Edge2* edges = NULL; + + last = &lcs_nodes[len_lcs - 1][va_array_length(lcs_nodes[len_lcs - 1]) - 1]; + va_array_append(va_std_allocator, nodes, ((Node) {last->row, last->col, last->length, -1, -1})); + last->idx = va_array_length(nodes) - 1; + fprintf(stderr, "%zu\n", len_lcs); for (size_t i = 0; i < len_lcs; ++i) { fprintf(stderr, "%zu: ", i); for (size_t j = 0; j < va_array_length(lcs_nodes[i]); ++j) { - fprintf(stderr, "(%u, %u, %u) ", lcs_nodes[i][j].row, lcs_nodes[i][j].col, lcs_nodes[i][j].length); + fprintf(stderr, "(%u, %u, %u, %d) ", lcs_nodes[i][j].row, lcs_nodes[i][j].col, lcs_nodes[i][j].length, lcs_nodes[i][j].idx); } // for fprintf(stderr, "\n"); } // for - Node2* nodes = NULL; - Edge2* edges = NULL; - - VA_LCS_Node source = {.row = shift, .col = shift, .length = 0}; - bool found_source = false; + uint32_t source_idx = -1; bool is_sink = true; for (size_t t_i = 0; t_i < len_lcs; ++t_i) { size_t const t_len = va_array_length(lcs_nodes[len_lcs - t_i - 1]); for (size_t t_j = 0; t_j < t_len; ++t_j) { - VA_LCS_Node const tail = lcs_nodes[len_lcs - t_i - 1][t_len - t_j - 1]; - bool const is_source = tail.row == shift && tail.col == shift; - if (is_source) + VA_LCS_Node const* const tail = &lcs_nodes[len_lcs - t_i - 1][t_len - t_j - 1]; + if (tail->idx == (uint32_t) -1) { - source = tail; - found_source = true; + continue; } // if - printf("%u %u %u\n", tail.row, tail.col, tail.length); + bool const is_source = tail->row == shift && tail->col == shift; + printf("%u %u %u\n", tail->row, tail->col, tail->length); - for (size_t h_i = 0; h_i < MIN(len_lcs - t_i, tail.length + 1); ++h_i) + for (size_t h_i = 0; h_i < MIN(len_lcs - t_i, tail->length + 1); ++h_i) { size_t const h_len = h_i == 0 ? t_len - t_j - 1: va_array_length(lcs_nodes[len_lcs - t_i - h_i - 1]); //printf(" level: %zu with %zu nodes\n", len_lcs - t_i - h_i - 1, h_len); for (size_t h_j = 0; h_j < h_len; ++h_j) { - VA_LCS_Node const head = lcs_nodes[len_lcs - t_i - h_i - 1][h_j]; + VA_LCS_Node* head = &lcs_nodes[len_lcs - t_i - h_i - 1][h_j]; - printf(" %u %u %u: ", head.row, head.col, head.length); + printf(" %u %u %u: ", head->row, head->col, head->length); - if (head.row + head.length > tail.row + tail.length - h_i || - head.col + head.length > tail.col + tail.length - h_i) + if (head->row + head->length > tail->row + tail->length - h_i || + head->col + head->length > tail->col + tail->length - h_i) { - if (tail.row + tail.length - h_i > head.row + head.length || - tail.col + tail.length - h_i > head.col + head.length) + if (tail->row + tail->length - h_i > head->row + head->length || + tail->col + tail->length - h_i > head->col + head->length) { printf("--\n"); } // if else { printf("CONVERSE "); - edges2(tail, head, is_source, false, len_obs, observed); + if (edges2(*tail, *head, is_source, false, len_obs, observed)) + { + if (head->idx == (uint32_t) -1) + { + va_array_append(va_std_allocator, nodes, ((Node) {head->row, head->col, head->length, -1, -1})); + head->idx = va_array_length(nodes) - 1; + } // if + va_array_append(va_std_allocator, edges, ((Edge2) {head->idx, nodes[tail->idx].edges})); + nodes[tail->idx].edges = va_array_length(edges) - 1; + } } // else } // if else { - edges2(head, tail, head.row == shift && head.col == shift, is_sink, len_obs, observed); + if (edges2(*head, *tail, head->row == shift && head->col == shift, is_sink, len_obs, observed)) + { + if (head->idx == (uint32_t) -1) + { + va_array_append(va_std_allocator, nodes, ((Node) {head->row, head->col, head->length, -1, -1})); + head->idx = va_array_length(nodes) - 1; + if (head->row == shift && head->col == shift) + { + source_idx = head->idx; + } + } // if + va_array_append(va_std_allocator, edges, ((Edge2) {tail->idx, nodes[head->idx].edges})); + nodes[head->idx].edges = va_array_length(edges) - 1; + } // if } // else } // for is_sink = false; } // for - if (!found_source && tail.length >= len_lcs - t_i) + if (source_idx == (uint32_t) -1 && tail->length >= len_lcs - t_i) { - printf(" %u %u %u: ", source.row, source.col, source.length); - edges2(source, tail, true, is_sink, len_obs, observed); + VA_LCS_Node const source = {.row = 0, .col = 0, .length = 0}; + printf("XXX %u %u %u: ", source.row, source.col, source.length); + edges2(source, *tail, true, is_sink, len_obs, observed); } // if } // for lcs_nodes[len_lcs - t_i - 1] = va_array_destroy(va_std_allocator, lcs_nodes[len_lcs - t_i - 1]); From 9ef03ad929d955321497dca09ab58426c655984c Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 18 Mar 2025 10:18:31 +0100 Subject: [PATCH 135/704] WIP --- src/main.c | 60 ++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 45 insertions(+), 15 deletions(-) diff --git a/src/main.c b/src/main.c index 79b16bd..caec51b 100644 --- a/src/main.c +++ b/src/main.c @@ -19,6 +19,9 @@ #define VAR_FMT "%u:%u/%.*s" +static uint32_t const GVA_NULL = UINT32_MAX; + + static size_t random_sequence(size_t const min, size_t const max, char sequence[static max]) { @@ -966,7 +969,9 @@ build(size_t const len_ref, char const reference[static len_ref], fprintf(stderr, "\n"); } // for - uint32_t source_idx = -1; + + VA_LCS_Node source = {0, 0, 0, -1, -1}; + bool found_source = false; bool is_sink = true; for (size_t t_i = 0; t_i < len_lcs; ++t_i) { @@ -979,6 +984,11 @@ build(size_t const len_ref, char const reference[static len_ref], continue; } // if bool const is_source = tail->row == shift && tail->col == shift; + if (is_source) + { + source = *tail; + found_source = true; + } // if printf("%u %u %u\n", tail->row, tail->col, tail->length); for (size_t h_i = 0; h_i < MIN(len_lcs - t_i, tail->length + 1); ++h_i) @@ -997,18 +1007,13 @@ build(size_t const len_ref, char const reference[static len_ref], if (tail->row + tail->length - h_i > head->row + head->length || tail->col + tail->length - h_i > head->col + head->length) { - printf("--\n"); + printf("--\n"); // FIXME: skip this remainder of this (head) level } // if else { printf("CONVERSE "); - if (edges2(*tail, *head, is_source, false, len_obs, observed)) + if (head->idx != GVA_NULL && edges2(*tail, *head, is_source, false, len_obs, observed)) { - if (head->idx == (uint32_t) -1) - { - va_array_append(va_std_allocator, nodes, ((Node) {head->row, head->col, head->length, -1, -1})); - head->idx = va_array_length(nodes) - 1; - } // if va_array_append(va_std_allocator, edges, ((Edge2) {head->idx, nodes[tail->idx].edges})); nodes[tail->idx].edges = va_array_length(edges) - 1; } @@ -1016,16 +1021,18 @@ build(size_t const len_ref, char const reference[static len_ref], } // if else { + // is this always true? if (edges2(*head, *tail, head->row == shift && head->col == shift, is_sink, len_obs, observed)) { - if (head->idx == (uint32_t) -1) + if (head->idx == GVA_NULL) { va_array_append(va_std_allocator, nodes, ((Node) {head->row, head->col, head->length, -1, -1})); head->idx = va_array_length(nodes) - 1; if (head->row == shift && head->col == shift) { - source_idx = head->idx; - } + source = *head; + found_source = true; + } // if } // if va_array_append(va_std_allocator, edges, ((Edge2) {tail->idx, nodes[head->idx].edges})); nodes[head->idx].edges = va_array_length(edges) - 1; @@ -1035,17 +1042,40 @@ build(size_t const len_ref, char const reference[static len_ref], } // for is_sink = false; } // for - if (source_idx == (uint32_t) -1 && tail->length >= len_lcs - t_i) + if (!found_source && tail->length >= len_lcs - t_i) { - VA_LCS_Node const source = {.row = 0, .col = 0, .length = 0}; - printf("XXX %u %u %u: ", source.row, source.col, source.length); - edges2(source, *tail, true, is_sink, len_obs, observed); + if (source.idx == GVA_NULL) + { + va_array_append(va_std_allocator, nodes, ((Node) {0, 0, 0, -1, -1})); + source.idx = va_array_length(nodes) - 1; + } // if + printf("SOURCE %u %u %u: ", source.row, source.col, source.length); + if (edges2(source, *tail, true, is_sink, len_obs, observed)) + { + va_array_append(va_std_allocator, edges, ((Edge2) {tail->idx, nodes[source.idx].edges})); + nodes[source.idx].edges = va_array_length(edges) - 1; + } // if } // if } // for lcs_nodes[len_lcs - t_i - 1] = va_array_destroy(va_std_allocator, lcs_nodes[len_lcs - t_i - 1]); } // for lcs_nodes = va_std_allocator.alloc(va_std_allocator.context, lcs_nodes, len_lcs, 0); + + + printf("#nodes: %zu\n#edges: %zu\n", va_array_length(nodes), va_array_length(edges)); + printf("source: %u\n", source.idx); + for (size_t i = 0; i < va_array_length(nodes); ++i) + { + printf("%zu: (%u, %u, %u):\n", i, nodes[i].row, nodes[i].col, nodes[i].length); + for (size_t j = nodes[i].edges; j != GVA_NULL; j = edges[j].next) + { + printf(" (%u, %u, %u): ", nodes[edges[j].tail].row, nodes[edges[j].tail].col, nodes[edges[j].tail].length); + edges2(((VA_LCS_Node) {nodes[i].row, nodes[i].col, nodes[i].length}), + ((VA_LCS_Node) {nodes[edges[j].tail].row, nodes[edges[j].tail].col, nodes[edges[j].tail].length}), + nodes[i].row == shift && nodes[i].col == shift, nodes[edges[j].tail].edges == GVA_NULL, len_obs, observed); + } // for + } // for } // build From ca9858a4cec18e82fc1214e94a639c30a4923efa Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Tue, 18 Mar 2025 12:48:25 +0100 Subject: [PATCH 136/704] WIP. --- src/main.c | 57 +++++++++++++++++++++++++++--------------------------- 1 file changed, 28 insertions(+), 29 deletions(-) diff --git a/src/main.c b/src/main.c index caec51b..a975d08 100644 --- a/src/main.c +++ b/src/main.c @@ -895,7 +895,7 @@ edges2(VA_LCS_Node const head, VA_LCS_Node const tail, bool const is_source, bool const is_sink, size_t const len_obs, char const observed[static len_obs]) { - //printf("%u %u %u -> %u %u %u %s %s\n", head.row, head.col, head.length, tail.row, tail.col, tail.length, is_source ? "SOURCE" : "", is_sink ? "SINK" : ""); +// printf("%u %u %u -> %u %u %u %s %s\n", head.row, head.col, head.length, tail.row, tail.col, tail.length, is_source ? "SOURCE" : "", is_sink ? "SINK" : ""); intmax_t const row = (intmax_t) head.row - is_source; intmax_t const col = (intmax_t) head.col - is_source; @@ -945,17 +945,17 @@ build(size_t const len_ref, char const reference[static len_ref], return; } // if + Node* nodes = NULL; + Edge2* edges = NULL; + VA_LCS_Node* last = &lcs_nodes[len_lcs - 1][va_array_length(lcs_nodes[len_lcs - 1]) - 1]; if (last->row + last->length != len_ref + shift || last->col + last->length != len_obs + shift) { - va_array_append(va_std_allocator, lcs_nodes[len_lcs - 1], ((VA_LCS_Node) {.row = len_ref + shift, .col = len_obs + shift, .length = 0})); + va_array_append(va_std_allocator, lcs_nodes[len_lcs - 1], + ((VA_LCS_Node) {.row = len_ref + shift, .col = len_obs + shift, .length = 0})); + last = &lcs_nodes[len_lcs - 1][va_array_length(lcs_nodes[len_lcs - 1]) - 1]; } // if - - Node* nodes = NULL; - Edge2* edges = NULL; - - last = &lcs_nodes[len_lcs - 1][va_array_length(lcs_nodes[len_lcs - 1]) - 1]; - va_array_append(va_std_allocator, nodes, ((Node) {last->row, last->col, last->length, -1, -1})); + va_array_append(va_std_allocator, nodes, ((Node) {last->row, last->col, last->length, GVA_NULL, GVA_NULL})); last->idx = va_array_length(nodes) - 1; fprintf(stderr, "%zu\n", len_lcs); @@ -969,8 +969,7 @@ build(size_t const len_ref, char const reference[static len_ref], fprintf(stderr, "\n"); } // for - - VA_LCS_Node source = {0, 0, 0, -1, -1}; + VA_LCS_Node source = {shift, shift, 0, -1, GVA_NULL}; bool found_source = false; bool is_sink = true; for (size_t t_i = 0; t_i < len_lcs; ++t_i) @@ -979,16 +978,10 @@ build(size_t const len_ref, char const reference[static len_ref], for (size_t t_j = 0; t_j < t_len; ++t_j) { VA_LCS_Node const* const tail = &lcs_nodes[len_lcs - t_i - 1][t_len - t_j - 1]; - if (tail->idx == (uint32_t) -1) + if (tail->idx == GVA_NULL) { continue; } // if - bool const is_source = tail->row == shift && tail->col == shift; - if (is_source) - { - source = *tail; - found_source = true; - } // if printf("%u %u %u\n", tail->row, tail->col, tail->length); for (size_t h_i = 0; h_i < MIN(len_lcs - t_i, tail->length + 1); ++h_i) @@ -1001,18 +994,19 @@ build(size_t const len_ref, char const reference[static len_ref], printf(" %u %u %u: ", head->row, head->col, head->length); - if (head->row + head->length > tail->row + tail->length - h_i || - head->col + head->length > tail->col + tail->length - h_i) + if (head->row + head->length + h_i > tail->row + tail->length || + head->col + head->length + h_i > tail->col + tail->length) { - if (tail->row + tail->length - h_i > head->row + head->length || - tail->col + tail->length - h_i > head->col + head->length) + if (tail->row + tail->length > head->row + head->length + h_i || + tail->col + tail->length > head->col + head->length + h_i) { printf("--\n"); // FIXME: skip this remainder of this (head) level } // if else { printf("CONVERSE "); - if (head->idx != GVA_NULL && edges2(*tail, *head, is_source, false, len_obs, observed)) + if (head->idx != GVA_NULL && edges2(*tail, *head, tail->row == shift && tail->col == shift, + false, len_obs, observed)) { va_array_append(va_std_allocator, edges, ((Edge2) {head->idx, nodes[tail->idx].edges})); nodes[tail->idx].edges = va_array_length(edges) - 1; @@ -1021,12 +1015,11 @@ build(size_t const len_ref, char const reference[static len_ref], } // if else { - // is this always true? if (edges2(*head, *tail, head->row == shift && head->col == shift, is_sink, len_obs, observed)) { if (head->idx == GVA_NULL) { - va_array_append(va_std_allocator, nodes, ((Node) {head->row, head->col, head->length, -1, -1})); + va_array_append(va_std_allocator, nodes, ((Node) {head->row, head->col, head->length, GVA_NULL, GVA_NULL})); head->idx = va_array_length(nodes) - 1; if (head->row == shift && head->col == shift) { @@ -1037,16 +1030,20 @@ build(size_t const len_ref, char const reference[static len_ref], va_array_append(va_std_allocator, edges, ((Edge2) {tail->idx, nodes[head->idx].edges})); nodes[head->idx].edges = va_array_length(edges) - 1; } // if + else + { + // FIXME: skip this remainder of this (head) level + } // else } // else - } // for + } // for h_j is_sink = false; - } // for + } // for h_i if (!found_source && tail->length >= len_lcs - t_i) { if (source.idx == GVA_NULL) { - va_array_append(va_std_allocator, nodes, ((Node) {0, 0, 0, -1, -1})); + va_array_append(va_std_allocator, nodes, ((Node) {source.row, source.col, source.length, GVA_NULL, GVA_NULL})); source.idx = va_array_length(nodes) - 1; } // if printf("SOURCE %u %u %u: ", source.row, source.col, source.length); @@ -1056,10 +1053,12 @@ build(size_t const len_ref, char const reference[static len_ref], nodes[source.idx].edges = va_array_length(edges) - 1; } // if } // if - } // for + } // for t_j + // dealloc lcs pos level lcs_nodes[len_lcs - t_i - 1] = va_array_destroy(va_std_allocator, lcs_nodes[len_lcs - t_i - 1]); - } // for + } // for t_i + // deallocation lcs_nodes = va_std_allocator.alloc(va_std_allocator.context, lcs_nodes, len_lcs, 0); From 99720bda51abab9fb2bb16fcc345650b52bab23b Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Tue, 18 Mar 2025 15:36:33 +0100 Subject: [PATCH 137/704] WIP Split. --- src/main.c | 59 ++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 48 insertions(+), 11 deletions(-) diff --git a/src/main.c b/src/main.c index a975d08..4879e25 100644 --- a/src/main.c +++ b/src/main.c @@ -890,10 +890,10 @@ check(size_t const len_ref, char const reference[static len_ref], } // check -static bool +static uint32_t edges2(VA_LCS_Node const head, VA_LCS_Node const tail, bool const is_source, bool const is_sink, - size_t const len_obs, char const observed[static len_obs]) + size_t const len_obs, char const observed[static len_obs], uint32_t* const start, uint32_t* const end) { // printf("%u %u %u -> %u %u %u %s %s\n", head.row, head.col, head.length, tail.row, tail.col, tail.length, is_source ? "SOURCE" : "", is_sink ? "SINK" : ""); @@ -912,15 +912,17 @@ edges2(VA_LCS_Node const head, VA_LCS_Node const tail, if (head_offset > head_length || (tail_length > 0 && tail_offset >= tail_length)) { printf("NO EDGE\n"); - return false; + return 0; } // if uint32_t const count = MIN(head_length - head_offset, tail_length - tail_offset - 1) + 1; - VA_Variant const variant = {row + head_offset, tail.row + tail_offset, col + head_offset, tail.col + tail_offset}; + *start = row + head_offset; + *end = tail.row + tail_offset; + VA_Variant const variant = {*start, *end, col + head_offset, tail.col + tail_offset}; printf(VAR_FMT " x %u\n", print_variant(variant, observed), count); - return true; + return count; } // edges2 @@ -957,6 +959,7 @@ build(size_t const len_ref, char const reference[static len_ref], } // if va_array_append(va_std_allocator, nodes, ((Node) {last->row, last->col, last->length, GVA_NULL, GVA_NULL})); last->idx = va_array_length(nodes) - 1; + last->incoming = -1; fprintf(stderr, "%zu\n", len_lcs); for (size_t i = 0; i < len_lcs; ++i) @@ -977,13 +980,14 @@ build(size_t const len_ref, char const reference[static len_ref], size_t const t_len = va_array_length(lcs_nodes[len_lcs - t_i - 1]); for (size_t t_j = 0; t_j < t_len; ++t_j) { - VA_LCS_Node const* const tail = &lcs_nodes[len_lcs - t_i - 1][t_len - t_j - 1]; + VA_LCS_Node* const tail = &lcs_nodes[len_lcs - t_i - 1][t_len - t_j - 1]; if (tail->idx == GVA_NULL) { continue; } // if - printf("%u %u %u\n", tail->row, tail->col, tail->length); + printf("%u %u %u %u\n", tail->row, tail->col, tail->length, tail->incoming); + uint32_t split_idx = GVA_NULL; for (size_t h_i = 0; h_i < MIN(len_lcs - t_i, tail->length + 1); ++h_i) { size_t const h_len = h_i == 0 ? t_len - t_j - 1: va_array_length(lcs_nodes[len_lcs - t_i - h_i - 1]); @@ -1005,8 +1009,9 @@ build(size_t const len_ref, char const reference[static len_ref], else { printf("CONVERSE "); + uint32_t unused; if (head->idx != GVA_NULL && edges2(*tail, *head, tail->row == shift && tail->col == shift, - false, len_obs, observed)) + false, len_obs, observed, &unused, &unused)) { va_array_append(va_std_allocator, edges, ((Edge2) {head->idx, nodes[tail->idx].edges})); nodes[tail->idx].edges = va_array_length(edges) - 1; @@ -1015,18 +1020,40 @@ build(size_t const len_ref, char const reference[static len_ref], } // if else { - if (edges2(*head, *tail, head->row == shift && head->col == shift, is_sink, len_obs, observed)) + uint32_t start = -1; + uint32_t end = -1; + uint32_t const count = edges2(*head, *tail, head->row == shift && head->col == shift, is_sink, len_obs, observed, &start, &end); + if (count > 0) { if (head->idx == GVA_NULL) { va_array_append(va_std_allocator, nodes, ((Node) {head->row, head->col, head->length, GVA_NULL, GVA_NULL})); head->idx = va_array_length(nodes) - 1; + head->incoming = start; if (head->row == shift && head->col == shift) { source = *head; found_source = true; } // if } // if + head->incoming = MIN(head->incoming, start); + if (end + count > tail->incoming) + { + printf("SPLIT?! "); + uint32_t const el = tail->incoming - tail->row; + va_array_append(va_std_allocator, nodes, + ((Node) {tail->row, tail->col, el, GVA_NULL, tail->idx})); + split_idx = va_array_length(nodes) - 1; + tail->row += el; + tail->col += el; + tail->length -= el; + tail->incoming += el; + nodes[tail->idx].row = tail->row; + nodes[tail->idx].col = tail->col; + nodes[tail->idx].length = tail->length; + + printf(" %u %u %u %u: \n", el, tail->row, tail->col, tail->length); + } va_array_append(va_std_allocator, edges, ((Edge2) {tail->idx, nodes[head->idx].edges})); nodes[head->idx].edges = va_array_length(edges) - 1; } // if @@ -1039,6 +1066,14 @@ build(size_t const len_ref, char const reference[static len_ref], } // for h_j is_sink = false; } // for h_i + if (split_idx != GVA_NULL) + { + tail->row = nodes[split_idx].row; + tail->col = nodes[split_idx].col; + tail->length = nodes[split_idx].length; + tail->idx = split_idx; + tail->incoming = -1; + } if (!found_source && tail->length >= len_lcs - t_i) { if (source.idx == GVA_NULL) @@ -1047,7 +1082,8 @@ build(size_t const len_ref, char const reference[static len_ref], source.idx = va_array_length(nodes) - 1; } // if printf("SOURCE %u %u %u: ", source.row, source.col, source.length); - if (edges2(source, *tail, true, is_sink, len_obs, observed)) + uint32_t unused; + if (edges2(source, *tail, true, is_sink, len_obs, observed, &unused, &unused)) { va_array_append(va_std_allocator, edges, ((Edge2) {tail->idx, nodes[source.idx].edges})); nodes[source.idx].edges = va_array_length(edges) - 1; @@ -1070,9 +1106,10 @@ build(size_t const len_ref, char const reference[static len_ref], for (size_t j = nodes[i].edges; j != GVA_NULL; j = edges[j].next) { printf(" (%u, %u, %u): ", nodes[edges[j].tail].row, nodes[edges[j].tail].col, nodes[edges[j].tail].length); + uint32_t unused; edges2(((VA_LCS_Node) {nodes[i].row, nodes[i].col, nodes[i].length}), ((VA_LCS_Node) {nodes[edges[j].tail].row, nodes[edges[j].tail].col, nodes[edges[j].tail].length}), - nodes[i].row == shift && nodes[i].col == shift, nodes[edges[j].tail].edges == GVA_NULL, len_obs, observed); + nodes[i].row == shift && nodes[i].col == shift, nodes[edges[j].tail].edges == GVA_NULL, len_obs, observed, &unused, &unused); } // for } // for } // build From 1114c1904f24ae5585b6ba5c1eb243dd54a8ed71 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 18 Mar 2025 16:13:05 +0100 Subject: [PATCH 138/704] Example TATCCGTCCG GAAAAATCCG works --- src/main.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/main.c b/src/main.c index 4879e25..a74cd27 100644 --- a/src/main.c +++ b/src/main.c @@ -967,7 +967,7 @@ build(size_t const len_ref, char const reference[static len_ref], fprintf(stderr, "%zu: ", i); for (size_t j = 0; j < va_array_length(lcs_nodes[i]); ++j) { - fprintf(stderr, "(%u, %u, %u, %d) ", lcs_nodes[i][j].row, lcs_nodes[i][j].col, lcs_nodes[i][j].length, lcs_nodes[i][j].idx); + fprintf(stderr, "(%u, %u, %u) ", lcs_nodes[i][j].row, lcs_nodes[i][j].col, lcs_nodes[i][j].length); } // for fprintf(stderr, "\n"); } // for @@ -1039,7 +1039,7 @@ build(size_t const len_ref, char const reference[static len_ref], head->incoming = MIN(head->incoming, start); if (end + count > tail->incoming) { - printf("SPLIT?! "); + printf("SPLIT "); uint32_t const el = tail->incoming - tail->row; va_array_append(va_std_allocator, nodes, ((Node) {tail->row, tail->col, el, GVA_NULL, tail->idx})); @@ -1065,15 +1065,17 @@ build(size_t const len_ref, char const reference[static len_ref], } // for h_j is_sink = false; + if (split_idx != GVA_NULL) + { + tail->row = nodes[split_idx].row; + tail->col = nodes[split_idx].col; + tail->length = tail->length + nodes[split_idx].length; + tail->idx = split_idx; + tail->incoming = -1; + printf("tail renamed to: %u %u %u %u\n", tail->row, tail->col, tail->length, tail->incoming); + split_idx = GVA_NULL; + } // if } // for h_i - if (split_idx != GVA_NULL) - { - tail->row = nodes[split_idx].row; - tail->col = nodes[split_idx].col; - tail->length = nodes[split_idx].length; - tail->idx = split_idx; - tail->incoming = -1; - } if (!found_source && tail->length >= len_lcs - t_i) { if (source.idx == GVA_NULL) @@ -1107,8 +1109,8 @@ build(size_t const len_ref, char const reference[static len_ref], { printf(" (%u, %u, %u): ", nodes[edges[j].tail].row, nodes[edges[j].tail].col, nodes[edges[j].tail].length); uint32_t unused; - edges2(((VA_LCS_Node) {nodes[i].row, nodes[i].col, nodes[i].length}), - ((VA_LCS_Node) {nodes[edges[j].tail].row, nodes[edges[j].tail].col, nodes[edges[j].tail].length}), + edges2(((VA_LCS_Node) {nodes[i].row, nodes[i].col, nodes[i].length, 0, 0}), + ((VA_LCS_Node) {nodes[edges[j].tail].row, nodes[edges[j].tail].col, nodes[edges[j].tail].length, 0, 0}), nodes[i].row == shift && nodes[i].col == shift, nodes[edges[j].tail].edges == GVA_NULL, len_obs, observed, &unused, &unused); } // for } // for From 427a09c4e5996ec2ba7b5eb409cb8434ffcd1d8a Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 19 Mar 2025 09:40:04 +0100 Subject: [PATCH 139/704] Split? --- src/edit.c | 4 ++-- src/main.c | 39 ++++++++++----------------------------- 2 files changed, 12 insertions(+), 31 deletions(-) diff --git a/src/edit.c b/src/edit.c index e252374..3c5d9cb 100644 --- a/src/edit.c +++ b/src/edit.c @@ -170,7 +170,7 @@ expand(Context const context, { context.lcs_nodes[lcs_pos] = va_array_init(context.allocator, 256, sizeof(*context.lcs_nodes[lcs_pos])); } // if - va_array_append(context.allocator, context.lcs_nodes[lcs_pos], ((VA_LCS_Node) {match_row, match_col, length, 0, -1})); + va_array_append(context.allocator, context.lcs_nodes[lcs_pos], ((VA_LCS_Node) {match_row, match_col, length, -1, -1})); matching = false; } // if row += 1; @@ -203,7 +203,7 @@ expand(Context const context, { context.lcs_nodes[lcs_pos] = va_array_init(context.allocator, 256, sizeof(*context.lcs_nodes[lcs_pos])); } // if - va_array_append(context.allocator, context.lcs_nodes[lcs_pos], ((VA_LCS_Node) {match_row, match_col, length, 0, -1})); + va_array_append(context.allocator, context.lcs_nodes[lcs_pos], ((VA_LCS_Node) {match_row, match_col, length, -1, -1})); } // if return steps; diff --git a/src/main.c b/src/main.c index a74cd27..51b8e50 100644 --- a/src/main.c +++ b/src/main.c @@ -987,7 +987,7 @@ build(size_t const len_ref, char const reference[static len_ref], } // if printf("%u %u %u %u\n", tail->row, tail->col, tail->length, tail->incoming); - uint32_t split_idx = GVA_NULL; + uint32_t split_idx = tail->idx; for (size_t h_i = 0; h_i < MIN(len_lcs - t_i, tail->length + 1); ++h_i) { size_t const h_len = h_i == 0 ? t_len - t_j - 1: va_array_length(lcs_nodes[len_lcs - t_i - h_i - 1]); @@ -1009,9 +1009,8 @@ build(size_t const len_ref, char const reference[static len_ref], else { printf("CONVERSE "); - uint32_t unused; if (head->idx != GVA_NULL && edges2(*tail, *head, tail->row == shift && tail->col == shift, - false, len_obs, observed, &unused, &unused)) + false, len_obs, observed, &(uint32_t) {0}, &(uint32_t) {0})) { va_array_append(va_std_allocator, edges, ((Edge2) {head->idx, nodes[tail->idx].edges})); nodes[tail->idx].edges = va_array_length(edges) - 1; @@ -1029,7 +1028,6 @@ build(size_t const len_ref, char const reference[static len_ref], { va_array_append(va_std_allocator, nodes, ((Node) {head->row, head->col, head->length, GVA_NULL, GVA_NULL})); head->idx = va_array_length(nodes) - 1; - head->incoming = start; if (head->row == shift && head->col == shift) { source = *head; @@ -1039,21 +1037,15 @@ build(size_t const len_ref, char const reference[static len_ref], head->incoming = MIN(head->incoming, start); if (end + count > tail->incoming) { - printf("SPLIT "); - uint32_t const el = tail->incoming - tail->row; va_array_append(va_std_allocator, nodes, - ((Node) {tail->row, tail->col, el, GVA_NULL, tail->idx})); + ((Node) {tail->row, tail->col, tail->incoming - tail->row, GVA_NULL, tail->idx})); split_idx = va_array_length(nodes) - 1; - tail->row += el; - tail->col += el; - tail->length -= el; - tail->incoming += el; nodes[tail->idx].row = tail->row; nodes[tail->idx].col = tail->col; nodes[tail->idx].length = tail->length; - - printf(" %u %u %u %u: \n", el, tail->row, tail->col, tail->length); - } + tail->incoming = end + count; + printf("SPLIT %u %u %u\n", tail->row, tail->col, tail->length); + } // if va_array_append(va_std_allocator, edges, ((Edge2) {tail->idx, nodes[head->idx].edges})); nodes[head->idx].edges = va_array_length(edges) - 1; } // if @@ -1062,19 +1054,9 @@ build(size_t const len_ref, char const reference[static len_ref], // FIXME: skip this remainder of this (head) level } // else } // else - } // for h_j is_sink = false; - if (split_idx != GVA_NULL) - { - tail->row = nodes[split_idx].row; - tail->col = nodes[split_idx].col; - tail->length = tail->length + nodes[split_idx].length; - tail->idx = split_idx; - tail->incoming = -1; - printf("tail renamed to: %u %u %u %u\n", tail->row, tail->col, tail->length, tail->incoming); - split_idx = GVA_NULL; - } // if + tail->idx = split_idx; } // for h_i if (!found_source && tail->length >= len_lcs - t_i) { @@ -1084,8 +1066,8 @@ build(size_t const len_ref, char const reference[static len_ref], source.idx = va_array_length(nodes) - 1; } // if printf("SOURCE %u %u %u: ", source.row, source.col, source.length); - uint32_t unused; - if (edges2(source, *tail, true, is_sink, len_obs, observed, &unused, &unused)) + // is this edges2 check always true? + if (edges2(source, *tail, true, is_sink, len_obs, observed, &(uint32_t) {0}, &(uint32_t) {0})) { va_array_append(va_std_allocator, edges, ((Edge2) {tail->idx, nodes[source.idx].edges})); nodes[source.idx].edges = va_array_length(edges) - 1; @@ -1108,10 +1090,9 @@ build(size_t const len_ref, char const reference[static len_ref], for (size_t j = nodes[i].edges; j != GVA_NULL; j = edges[j].next) { printf(" (%u, %u, %u): ", nodes[edges[j].tail].row, nodes[edges[j].tail].col, nodes[edges[j].tail].length); - uint32_t unused; edges2(((VA_LCS_Node) {nodes[i].row, nodes[i].col, nodes[i].length, 0, 0}), ((VA_LCS_Node) {nodes[edges[j].tail].row, nodes[edges[j].tail].col, nodes[edges[j].tail].length, 0, 0}), - nodes[i].row == shift && nodes[i].col == shift, nodes[edges[j].tail].edges == GVA_NULL, len_obs, observed, &unused, &unused); + nodes[i].row == shift && nodes[i].col == shift, nodes[edges[j].tail].edges == GVA_NULL, len_obs, observed, &(uint32_t) {0}, &(uint32_t) {0}); } // for } // for } // build From 4b549002845e8807210c6b56e77e9b45cf00ca87 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Wed, 19 Mar 2025 12:19:48 +0100 Subject: [PATCH 140/704] Proper relabeling. --- src/main.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/main.c b/src/main.c index 51b8e50..91011cd 100644 --- a/src/main.c +++ b/src/main.c @@ -1037,12 +1037,13 @@ build(size_t const len_ref, char const reference[static len_ref], head->incoming = MIN(head->incoming, start); if (end + count > tail->incoming) { + uint32_t const split_len = tail->incoming - tail->row; va_array_append(va_std_allocator, nodes, - ((Node) {tail->row, tail->col, tail->incoming - tail->row, GVA_NULL, tail->idx})); + ((Node) {tail->row, tail->col, split_len, GVA_NULL, tail->idx})); split_idx = va_array_length(nodes) - 1; - nodes[tail->idx].row = tail->row; - nodes[tail->idx].col = tail->col; - nodes[tail->idx].length = tail->length; + nodes[tail->idx].row += split_len; + nodes[tail->idx].col += split_len; + nodes[tail->idx].length -= split_len; tail->incoming = end + count; printf("SPLIT %u %u %u\n", tail->row, tail->col, tail->length); } // if @@ -1087,6 +1088,10 @@ build(size_t const len_ref, char const reference[static len_ref], for (size_t i = 0; i < va_array_length(nodes); ++i) { printf("%zu: (%u, %u, %u):\n", i, nodes[i].row, nodes[i].col, nodes[i].length); + if (nodes[i].lambda != GVA_NULL) + { + printf(" (%u, %u, %u): lambda\n", nodes[nodes[i].lambda].row, nodes[nodes[i].lambda].col, nodes[nodes[i].lambda].length); + } for (size_t j = nodes[i].edges; j != GVA_NULL; j = edges[j].next) { printf(" (%u, %u, %u): ", nodes[edges[j].tail].row, nodes[edges[j].tail].col, nodes[edges[j].tail].length); From 63c646bb133d02314c5a08da696140331c751379 Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 19 Mar 2025 16:26:17 +0100 Subject: [PATCH 141/704] Pasto --- src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.c b/src/main.c index 91011cd..c9458ac 100644 --- a/src/main.c +++ b/src/main.c @@ -881,7 +881,7 @@ check(size_t const len_ref, char const reference[static len_ref], if (count != va_array_length(graph.edges)) { - printf("COUNTS: %zu vs %zu1:5/, o\n", count, va_array_length(graph.edges)); + printf("COUNTS: %zu vs %zu\n", count, va_array_length(graph.edges)); return EXIT_FAILURE; } // if From 20d31a493c86fc10aeaecad3aff44cab18d82739 Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 19 Mar 2025 16:46:37 +0100 Subject: [PATCH 142/704] Graph2 --- src/main.c | 86 +++++++++++++++++++++++++++++------------------------- 1 file changed, 47 insertions(+), 39 deletions(-) diff --git a/src/main.c b/src/main.c index c9458ac..f77f9a8 100644 --- a/src/main.c +++ b/src/main.c @@ -44,6 +44,13 @@ typedef struct } Edge; +typedef struct +{ + uint32_t tail; + uint32_t next; +} Edge2; + + typedef struct { uint32_t row; @@ -63,6 +70,14 @@ typedef struct } Graph; +typedef struct +{ + Node* nodes; + Edge2* edges; + uint32_t source; +} Graph2; + + static inline size_t add_node(VA_Allocator const allocator, Graph* const graph, size_t const row, size_t const col, size_t const length) { @@ -926,14 +941,7 @@ edges2(VA_LCS_Node const head, VA_LCS_Node const tail, } // edges2 -typedef struct -{ - uint32_t tail; - uint32_t next; -} Edge2; - - -static void +static Graph2 build(size_t const len_ref, char const reference[static len_ref], size_t const len_obs, char const observed[static len_obs], size_t const shift) @@ -941,15 +949,14 @@ build(size_t const len_ref, char const reference[static len_ref], VA_LCS_Node** lcs_nodes = NULL; size_t const len_lcs = va_edit(va_std_allocator, len_ref, reference, len_obs, observed, &lcs_nodes); + Graph2 graph = {NULL, NULL, GVA_NULL}; + if (len_lcs == 0 || lcs_nodes == NULL) { fprintf(stderr, "Trivial graph\n"); - return; + return graph; } // if - Node* nodes = NULL; - Edge2* edges = NULL; - VA_LCS_Node* last = &lcs_nodes[len_lcs - 1][va_array_length(lcs_nodes[len_lcs - 1]) - 1]; if (last->row + last->length != len_ref + shift || last->col + last->length != len_obs + shift) { @@ -957,8 +964,8 @@ build(size_t const len_ref, char const reference[static len_ref], ((VA_LCS_Node) {.row = len_ref + shift, .col = len_obs + shift, .length = 0})); last = &lcs_nodes[len_lcs - 1][va_array_length(lcs_nodes[len_lcs - 1]) - 1]; } // if - va_array_append(va_std_allocator, nodes, ((Node) {last->row, last->col, last->length, GVA_NULL, GVA_NULL})); - last->idx = va_array_length(nodes) - 1; + va_array_append(va_std_allocator, graph.nodes, ((Node) {last->row, last->col, last->length, GVA_NULL, GVA_NULL})); + last->idx = va_array_length(graph.nodes) - 1; last->incoming = -1; fprintf(stderr, "%zu\n", len_lcs); @@ -1012,8 +1019,8 @@ build(size_t const len_ref, char const reference[static len_ref], if (head->idx != GVA_NULL && edges2(*tail, *head, tail->row == shift && tail->col == shift, false, len_obs, observed, &(uint32_t) {0}, &(uint32_t) {0})) { - va_array_append(va_std_allocator, edges, ((Edge2) {head->idx, nodes[tail->idx].edges})); - nodes[tail->idx].edges = va_array_length(edges) - 1; + va_array_append(va_std_allocator, graph.edges, ((Edge2) {head->idx, graph.nodes[tail->idx].edges})); + graph.nodes[tail->idx].edges = va_array_length(graph.edges) - 1; } } // else } // if @@ -1026,8 +1033,8 @@ build(size_t const len_ref, char const reference[static len_ref], { if (head->idx == GVA_NULL) { - va_array_append(va_std_allocator, nodes, ((Node) {head->row, head->col, head->length, GVA_NULL, GVA_NULL})); - head->idx = va_array_length(nodes) - 1; + va_array_append(va_std_allocator, graph.nodes, ((Node) {head->row, head->col, head->length, GVA_NULL, GVA_NULL})); + head->idx = va_array_length(graph.nodes) - 1; if (head->row == shift && head->col == shift) { source = *head; @@ -1038,17 +1045,17 @@ build(size_t const len_ref, char const reference[static len_ref], if (end + count > tail->incoming) { uint32_t const split_len = tail->incoming - tail->row; - va_array_append(va_std_allocator, nodes, + va_array_append(va_std_allocator, graph.nodes, ((Node) {tail->row, tail->col, split_len, GVA_NULL, tail->idx})); - split_idx = va_array_length(nodes) - 1; - nodes[tail->idx].row += split_len; - nodes[tail->idx].col += split_len; - nodes[tail->idx].length -= split_len; + split_idx = va_array_length(graph.nodes) - 1; + graph.nodes[tail->idx].row += split_len; + graph.nodes[tail->idx].col += split_len; + graph.nodes[tail->idx].length -= split_len; tail->incoming = end + count; printf("SPLIT %u %u %u\n", tail->row, tail->col, tail->length); } // if - va_array_append(va_std_allocator, edges, ((Edge2) {tail->idx, nodes[head->idx].edges})); - nodes[head->idx].edges = va_array_length(edges) - 1; + va_array_append(va_std_allocator, graph.edges, ((Edge2) {tail->idx, graph.nodes[head->idx].edges})); + graph.nodes[head->idx].edges = va_array_length(graph.edges) - 1; } // if else { @@ -1063,15 +1070,15 @@ build(size_t const len_ref, char const reference[static len_ref], { if (source.idx == GVA_NULL) { - va_array_append(va_std_allocator, nodes, ((Node) {source.row, source.col, source.length, GVA_NULL, GVA_NULL})); - source.idx = va_array_length(nodes) - 1; + va_array_append(va_std_allocator, graph.nodes, ((Node) {source.row, source.col, source.length, GVA_NULL, GVA_NULL})); + source.idx = va_array_length(graph.nodes) - 1; } // if printf("SOURCE %u %u %u: ", source.row, source.col, source.length); // is this edges2 check always true? if (edges2(source, *tail, true, is_sink, len_obs, observed, &(uint32_t) {0}, &(uint32_t) {0})) { - va_array_append(va_std_allocator, edges, ((Edge2) {tail->idx, nodes[source.idx].edges})); - nodes[source.idx].edges = va_array_length(edges) - 1; + va_array_append(va_std_allocator, graph.edges, ((Edge2) {tail->idx, graph.nodes[source.idx].edges})); + graph.nodes[source.idx].edges = va_array_length(graph.edges) - 1; } // if } // if } // for t_j @@ -1083,23 +1090,24 @@ build(size_t const len_ref, char const reference[static len_ref], lcs_nodes = va_std_allocator.alloc(va_std_allocator.context, lcs_nodes, len_lcs, 0); - printf("#nodes: %zu\n#edges: %zu\n", va_array_length(nodes), va_array_length(edges)); + printf("#nodes: %zu\n#edges: %zu\n", va_array_length(graph.nodes), va_array_length(graph.edges)); printf("source: %u\n", source.idx); - for (size_t i = 0; i < va_array_length(nodes); ++i) + for (size_t i = 0; i < va_array_length(graph.nodes); ++i) { - printf("%zu: (%u, %u, %u):\n", i, nodes[i].row, nodes[i].col, nodes[i].length); - if (nodes[i].lambda != GVA_NULL) + printf("%zu: (%u, %u, %u):\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length); + if (graph.nodes[i].lambda != GVA_NULL) { - printf(" (%u, %u, %u): lambda\n", nodes[nodes[i].lambda].row, nodes[nodes[i].lambda].col, nodes[nodes[i].lambda].length); + printf(" (%u, %u, %u): lambda\n", graph.nodes[graph.nodes[i].lambda].row, graph.nodes[graph.nodes[i].lambda].col, graph.nodes[graph.nodes[i].lambda].length); } - for (size_t j = nodes[i].edges; j != GVA_NULL; j = edges[j].next) + for (size_t j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) { - printf(" (%u, %u, %u): ", nodes[edges[j].tail].row, nodes[edges[j].tail].col, nodes[edges[j].tail].length); - edges2(((VA_LCS_Node) {nodes[i].row, nodes[i].col, nodes[i].length, 0, 0}), - ((VA_LCS_Node) {nodes[edges[j].tail].row, nodes[edges[j].tail].col, nodes[edges[j].tail].length, 0, 0}), - nodes[i].row == shift && nodes[i].col == shift, nodes[edges[j].tail].edges == GVA_NULL, len_obs, observed, &(uint32_t) {0}, &(uint32_t) {0}); + printf(" (%u, %u, %u): ", graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length); + edges2(((VA_LCS_Node) {graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, 0, 0}), + ((VA_LCS_Node) {graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length, 0, 0}), + graph.nodes[i].row == shift && graph.nodes[i].col == shift, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, len_obs, observed, &(uint32_t) {0}, &(uint32_t) {0}); } // for } // for + return graph; } // build From 5e95cf6f6727579df6df602539af575932420475 Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 19 Mar 2025 17:06:29 +0100 Subject: [PATCH 143/704] Work on bfs_traversal2 --- src/main.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 88 insertions(+), 2 deletions(-) diff --git a/src/main.c b/src/main.c index f77f9a8..9093c11 100644 --- a/src/main.c +++ b/src/main.c @@ -941,6 +941,87 @@ edges2(VA_LCS_Node const head, VA_LCS_Node const tail, } // edges2 +static size_t +bfs_traversal2(Graph2 const graph, size_t const len_obs, char const observed[static len_obs]) +{ + struct + { + uint32_t depth; + uint32_t next; + }* table = va_std_allocator.alloc(va_std_allocator.context, NULL, 0, sizeof(*table) * va_array_length(graph.nodes)); + + for (size_t i = 0; i < va_array_length(graph.nodes); ++i) + { + table[i].depth = 0; + table[i].next = GVA_NULL; + } // for + uint32_t head = graph.source; + uint32_t tail = graph.source; + + size_t count = 0; + //printf("digraph{\nrankdir=LR\nedge[fontname=monospace]\nnode[fixedsize=true,fontname=serif,shape=circle,width=1]\nsi[shape=point,width=.1]\n"); + //printf("si->s%u\n", graph.source); + + printf(" \"edges\": [\n"); + while (head != GVA_NULL) + { + //printf("pop %u\n", head); + for (uint32_t i = head; i != GVA_NULL; i = graph.nodes[i].lambda) + { + //printf("s%u[label=\"(%u, %u, %u)\"%s]\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, graph.nodes[i].edges == (uint32_t) -1 ? ",peripheries=2" : ""); + if (i != head) + { + //printf("lambda %u\n", i); + } // if + for (uint32_t j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) + { + if (count > 0) + { + printf(",\n"); + } // if + count += 1; + uint32_t const count2 = edges2(((VA_LCS_Node) {graph.nodes[head].row, graph.nodes[head].col, graph.nodes[head].length, 0, 0}), + ((VA_LCS_Node) {graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length, 0, 0}), + false, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, len_obs, observed, &(uint32_t) {0}, &(uint32_t) {0}); + + if (count2 > 0) + { + printf(" {\"head\": \"s%u\", \"tail\": \"s%u\", \"variant\": \"%u\"}", head, graph.edges[j].tail, count2); + } // if + //printf("s%u->s%u[label=\"%u:%u/%.*s\"]\n", head, graph.edges[j].tail, graph.edges[j].variant.start, graph.edges[j].variant.end, (int) graph.edges[j].variant.obs_end - graph.edges[j].variant.obs_start, observed + graph.edges[j].variant.obs_start); + + if (table[graph.edges[j].tail].depth > 0) + { + //printf("skip %u\n", graph.edges[j].tail); + continue; + } // if + + //printf("push %u\n", graph.edges[j].tail); + table[graph.edges[j].tail].depth = table[i].depth + 1; + table[tail].next = graph.edges[j].tail; + tail = graph.edges[j].tail; + } // for + } // for + head = table[head].next; + + /* + printf(" # \tdepth\tnext\n"); + for (size_t i = 0; i < va_array_length(graph.nodes); ++i) + { + printf("%3zu:\t%5u\t%4d\n", i, table[i].depth, table[i].next); + } // for + printf("head: %d\ntail: %d\n", head, tail); + */ + } // while + + printf("\n ],\n"); + + table = va_std_allocator.alloc(va_std_allocator.context, table, sizeof(*table) * va_array_length(graph.nodes), 0); + + return count; +} // bfs_traversal2 + + static Graph2 build(size_t const len_ref, char const reference[static len_ref], size_t const len_obs, char const observed[static len_obs], @@ -1038,6 +1119,7 @@ build(size_t const len_ref, char const reference[static len_ref], if (head->row == shift && head->col == shift) { source = *head; + graph.source = source.idx; found_source = true; } // if } // if @@ -1072,6 +1154,7 @@ build(size_t const len_ref, char const reference[static len_ref], { va_array_append(va_std_allocator, graph.nodes, ((Node) {source.row, source.col, source.length, GVA_NULL, GVA_NULL})); source.idx = va_array_length(graph.nodes) - 1; + graph.source = source.idx; } // if printf("SOURCE %u %u %u: ", source.row, source.col, source.length); // is this edges2 check always true? @@ -1089,9 +1172,8 @@ build(size_t const len_ref, char const reference[static len_ref], // deallocation lcs_nodes = va_std_allocator.alloc(va_std_allocator.context, lcs_nodes, len_lcs, 0); - printf("#nodes: %zu\n#edges: %zu\n", va_array_length(graph.nodes), va_array_length(graph.edges)); - printf("source: %u\n", source.idx); + printf("source: %u\n", graph.source); for (size_t i = 0; i < va_array_length(graph.nodes); ++i) { printf("%zu: (%u, %u, %u):\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length); @@ -1107,6 +1189,10 @@ build(size_t const len_ref, char const reference[static len_ref], graph.nodes[i].row == shift && graph.nodes[i].col == shift, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, len_obs, observed, &(uint32_t) {0}, &(uint32_t) {0}); } // for } // for + + + bfs_traversal2(graph, len_obs, observed); + return graph; } // build From baf4856908a55f75cdc701ac3bc2bff261736efb Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 19 Mar 2025 19:26:17 +0100 Subject: [PATCH 144/704] Source detection --- src/main.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main.c b/src/main.c index 9093c11..5b5182b 100644 --- a/src/main.c +++ b/src/main.c @@ -982,12 +982,12 @@ bfs_traversal2(Graph2 const graph, size_t const len_obs, char const observed[sta count += 1; uint32_t const count2 = edges2(((VA_LCS_Node) {graph.nodes[head].row, graph.nodes[head].col, graph.nodes[head].length, 0, 0}), ((VA_LCS_Node) {graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length, 0, 0}), - false, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, len_obs, observed, &(uint32_t) {0}, &(uint32_t) {0}); + graph.nodes[head].row == graph.nodes[graph.source].row && graph.nodes[head].col == graph.nodes[graph.source].col, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, len_obs, observed, &(uint32_t) {0}, &(uint32_t) {0}); - if (count2 > 0) + for (uint32_t k = 0; k < count2; ++k) { - printf(" {\"head\": \"s%u\", \"tail\": \"s%u\", \"variant\": \"%u\"}", head, graph.edges[j].tail, count2); - } // if + printf(" {\"head\": \"s%u\", \"tail\": \"s%u\", \"variant\": \"%u\"}\n", head, graph.edges[j].tail, count2); + } // for //printf("s%u->s%u[label=\"%u:%u/%.*s\"]\n", head, graph.edges[j].tail, graph.edges[j].variant.start, graph.edges[j].variant.end, (int) graph.edges[j].variant.obs_end - graph.edges[j].variant.obs_start, observed + graph.edges[j].variant.obs_start); if (table[graph.edges[j].tail].depth > 0) From 48aa3e661cd8868bdf602f336edc883fbbaf052c Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 19 Mar 2025 19:57:07 +0100 Subject: [PATCH 145/704] Edges2 returns variant --- src/main.c | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/src/main.c b/src/main.c index 5b5182b..0381603 100644 --- a/src/main.c +++ b/src/main.c @@ -908,7 +908,7 @@ check(size_t const len_ref, char const reference[static len_ref], static uint32_t edges2(VA_LCS_Node const head, VA_LCS_Node const tail, bool const is_source, bool const is_sink, - size_t const len_obs, char const observed[static len_obs], uint32_t* const start, uint32_t* const end) + size_t const len_obs, char const observed[static len_obs], VA_Variant* const variant) { // printf("%u %u %u -> %u %u %u %s %s\n", head.row, head.col, head.length, tail.row, tail.col, tail.length, is_source ? "SOURCE" : "", is_sink ? "SINK" : ""); @@ -932,11 +932,9 @@ edges2(VA_LCS_Node const head, VA_LCS_Node const tail, uint32_t const count = MIN(head_length - head_offset, tail_length - tail_offset - 1) + 1; - *start = row + head_offset; - *end = tail.row + tail_offset; - VA_Variant const variant = {*start, *end, col + head_offset, tail.col + tail_offset}; + *variant = (VA_Variant) {row + head_offset, tail.row + tail_offset, col + head_offset, tail.col + tail_offset}; - printf(VAR_FMT " x %u\n", print_variant(variant, observed), count); + printf(VAR_FMT " x %u\n", print_variant((*variant), observed), count); return count; } // edges2 @@ -980,9 +978,10 @@ bfs_traversal2(Graph2 const graph, size_t const len_obs, char const observed[sta printf(",\n"); } // if count += 1; + VA_Variant variant; uint32_t const count2 = edges2(((VA_LCS_Node) {graph.nodes[head].row, graph.nodes[head].col, graph.nodes[head].length, 0, 0}), ((VA_LCS_Node) {graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length, 0, 0}), - graph.nodes[head].row == graph.nodes[graph.source].row && graph.nodes[head].col == graph.nodes[graph.source].col, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, len_obs, observed, &(uint32_t) {0}, &(uint32_t) {0}); + graph.nodes[head].row == graph.nodes[graph.source].row && graph.nodes[head].col == graph.nodes[graph.source].col, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, len_obs, observed, &variant); for (uint32_t k = 0; k < count2; ++k) { @@ -1098,7 +1097,7 @@ build(size_t const len_ref, char const reference[static len_ref], { printf("CONVERSE "); if (head->idx != GVA_NULL && edges2(*tail, *head, tail->row == shift && tail->col == shift, - false, len_obs, observed, &(uint32_t) {0}, &(uint32_t) {0})) + false, len_obs, observed, &(VA_Variant) {0, 0, 0, 0})) { va_array_append(va_std_allocator, graph.edges, ((Edge2) {head->idx, graph.nodes[tail->idx].edges})); graph.nodes[tail->idx].edges = va_array_length(graph.edges) - 1; @@ -1107,9 +1106,8 @@ build(size_t const len_ref, char const reference[static len_ref], } // if else { - uint32_t start = -1; - uint32_t end = -1; - uint32_t const count = edges2(*head, *tail, head->row == shift && head->col == shift, is_sink, len_obs, observed, &start, &end); + VA_Variant variant; + uint32_t const count = edges2(*head, *tail, head->row == shift && head->col == shift, is_sink, len_obs, observed, &variant); if (count > 0) { if (head->idx == GVA_NULL) @@ -1123,8 +1121,8 @@ build(size_t const len_ref, char const reference[static len_ref], found_source = true; } // if } // if - head->incoming = MIN(head->incoming, start); - if (end + count > tail->incoming) + head->incoming = MIN(head->incoming, variant.start); + if (variant.end + count > tail->incoming) { uint32_t const split_len = tail->incoming - tail->row; va_array_append(va_std_allocator, graph.nodes, @@ -1133,7 +1131,7 @@ build(size_t const len_ref, char const reference[static len_ref], graph.nodes[tail->idx].row += split_len; graph.nodes[tail->idx].col += split_len; graph.nodes[tail->idx].length -= split_len; - tail->incoming = end + count; + tail->incoming = variant.end + count; printf("SPLIT %u %u %u\n", tail->row, tail->col, tail->length); } // if va_array_append(va_std_allocator, graph.edges, ((Edge2) {tail->idx, graph.nodes[head->idx].edges})); @@ -1158,7 +1156,7 @@ build(size_t const len_ref, char const reference[static len_ref], } // if printf("SOURCE %u %u %u: ", source.row, source.col, source.length); // is this edges2 check always true? - if (edges2(source, *tail, true, is_sink, len_obs, observed, &(uint32_t) {0}, &(uint32_t) {0})) + if (edges2(source, *tail, true, is_sink, len_obs, observed, &(VA_Variant) {0, 0, 0, 0})) { va_array_append(va_std_allocator, graph.edges, ((Edge2) {tail->idx, graph.nodes[source.idx].edges})); graph.nodes[source.idx].edges = va_array_length(graph.edges) - 1; @@ -1186,7 +1184,7 @@ build(size_t const len_ref, char const reference[static len_ref], printf(" (%u, %u, %u): ", graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length); edges2(((VA_LCS_Node) {graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, 0, 0}), ((VA_LCS_Node) {graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length, 0, 0}), - graph.nodes[i].row == shift && graph.nodes[i].col == shift, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, len_obs, observed, &(uint32_t) {0}, &(uint32_t) {0}); + graph.nodes[i].row == shift && graph.nodes[i].col == shift, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, len_obs, observed, &(VA_Variant) {0, 0, 0, 0}); } // for } // for From c288d51aa79f5e9e64ddcf4b8a69763d6631beb2 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 20 Mar 2025 10:32:42 +0100 Subject: [PATCH 146/704] Running length for lambda edges --- src/main.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/main.c b/src/main.c index 0381603..3d31d2f 100644 --- a/src/main.c +++ b/src/main.c @@ -963,12 +963,14 @@ bfs_traversal2(Graph2 const graph, size_t const len_obs, char const observed[sta printf(" \"edges\": [\n"); while (head != GVA_NULL) { + uint32_t len = graph.nodes[head].length; //printf("pop %u\n", head); for (uint32_t i = head; i != GVA_NULL; i = graph.nodes[i].lambda) { //printf("s%u[label=\"(%u, %u, %u)\"%s]\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, graph.nodes[i].edges == (uint32_t) -1 ? ",peripheries=2" : ""); if (i != head) { + len += graph.nodes[i].length; //printf("lambda %u\n", i); } // if for (uint32_t j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) @@ -979,13 +981,17 @@ bfs_traversal2(Graph2 const graph, size_t const len_obs, char const observed[sta } // if count += 1; VA_Variant variant; - uint32_t const count2 = edges2(((VA_LCS_Node) {graph.nodes[head].row, graph.nodes[head].col, graph.nodes[head].length, 0, 0}), + uint32_t const count2 = edges2(((VA_LCS_Node) {graph.nodes[head].row, graph.nodes[head].col, len, 0, 0}), ((VA_LCS_Node) {graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length, 0, 0}), graph.nodes[head].row == graph.nodes[graph.source].row && graph.nodes[head].col == graph.nodes[graph.source].col, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, len_obs, observed, &variant); for (uint32_t k = 0; k < count2; ++k) { - printf(" {\"head\": \"s%u\", \"tail\": \"s%u\", \"variant\": \"%u\"}\n", head, graph.edges[j].tail, count2); + printf(" {\"head\": \"s%u\", \"tail\": \"s%u\", \"variant\": \"" VAR_FMT "\"}%s", head, graph.edges[j].tail, print_variant(variant, observed), k < count2 - 1 ? ",\n" : ""); + variant.start += 1; + variant.end += 1; + variant.obs_start += 1; + variant.obs_end += 1; } // for //printf("s%u->s%u[label=\"%u:%u/%.*s\"]\n", head, graph.edges[j].tail, graph.edges[j].variant.start, graph.edges[j].variant.end, (int) graph.edges[j].variant.obs_end - graph.edges[j].variant.obs_start, observed + graph.edges[j].variant.obs_start); From 0545c0e29e5a8ab96ec85bfd6bfa72cb98f5b751 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 20 Mar 2025 11:03:02 +0100 Subject: [PATCH 147/704] Print dot in traversal2 --- src/main.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/main.c b/src/main.c index 3d31d2f..7af18b9 100644 --- a/src/main.c +++ b/src/main.c @@ -934,7 +934,7 @@ edges2(VA_LCS_Node const head, VA_LCS_Node const tail, *variant = (VA_Variant) {row + head_offset, tail.row + tail_offset, col + head_offset, tail.col + tail_offset}; - printf(VAR_FMT " x %u\n", print_variant((*variant), observed), count); + //printf(VAR_FMT " x %u\n", print_variant((*variant), observed), count); return count; } // edges2 @@ -957,17 +957,17 @@ bfs_traversal2(Graph2 const graph, size_t const len_obs, char const observed[sta uint32_t tail = graph.source; size_t count = 0; - //printf("digraph{\nrankdir=LR\nedge[fontname=monospace]\nnode[fixedsize=true,fontname=serif,shape=circle,width=1]\nsi[shape=point,width=.1]\n"); - //printf("si->s%u\n", graph.source); + printf("digraph{\nrankdir=LR\nedge[fontname=monospace]\nnode[fixedsize=true,fontname=serif,shape=circle,width=1]\nsi[label=\"\",shape=none,width=0]\n"); + printf("si->s%u\n", graph.source); - printf(" \"edges\": [\n"); + //printf(" \"edges\": [\n"); while (head != GVA_NULL) { uint32_t len = graph.nodes[head].length; //printf("pop %u\n", head); for (uint32_t i = head; i != GVA_NULL; i = graph.nodes[i].lambda) { - //printf("s%u[label=\"(%u, %u, %u)\"%s]\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, graph.nodes[i].edges == (uint32_t) -1 ? ",peripheries=2" : ""); + printf("s%u[label=\"(%u, %u, %u)\"%s]\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, graph.nodes[i].edges == GVA_NULL && graph.nodes[i].lambda == GVA_NULL ? ",peripheries=2" : ""); if (i != head) { len += graph.nodes[i].length; @@ -977,7 +977,7 @@ bfs_traversal2(Graph2 const graph, size_t const len_obs, char const observed[sta { if (count > 0) { - printf(",\n"); + //printf(",\n"); } // if count += 1; VA_Variant variant; @@ -987,7 +987,8 @@ bfs_traversal2(Graph2 const graph, size_t const len_obs, char const observed[sta for (uint32_t k = 0; k < count2; ++k) { - printf(" {\"head\": \"s%u\", \"tail\": \"s%u\", \"variant\": \"" VAR_FMT "\"}%s", head, graph.edges[j].tail, print_variant(variant, observed), k < count2 - 1 ? ",\n" : ""); + printf("s%u->s%u[label=\"" VAR_FMT "\"]\n", head, graph.edges[j].tail, print_variant(variant, observed)); + //printf(" {\"head\": \"s%u\", \"tail\": \"s%u\", \"variant\": \"" VAR_FMT "\"}%s", head, graph.edges[j].tail, print_variant(variant, observed), k < count2 - 1 ? ",\n" : ""); variant.start += 1; variant.end += 1; variant.obs_start += 1; @@ -1019,7 +1020,8 @@ bfs_traversal2(Graph2 const graph, size_t const len_obs, char const observed[sta */ } // while - printf("\n ],\n"); + printf("}\n"); + //printf("\n ],\n"); table = va_std_allocator.alloc(va_std_allocator.context, table, sizeof(*table) * va_array_length(graph.nodes), 0); From 90b557f13890697130d9438c068c32600e4c9fb1 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 20 Mar 2025 13:52:35 +0100 Subject: [PATCH 148/704] More debug info --- src/main.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/main.c b/src/main.c index 7af18b9..2e5595b 100644 --- a/src/main.c +++ b/src/main.c @@ -854,6 +854,21 @@ check(size_t const len_ref, char const reference[static len_ref], to_dot(graph, len_obs, observed); } // if + printf("#nodes: %zu\n#edges: %zu\n", va_array_length(graph.nodes), va_array_length(graph.edges)); + printf("source: %u\n", graph.source); + for (size_t i = 0; i < va_array_length(graph.nodes); ++i) + { + printf("%zu: (%u, %u, %u):\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length); + if (graph.nodes[i].lambda != GVA_NULL) + { + printf(" (%u, %u, %u): lambda\n", graph.nodes[graph.nodes[i].lambda].row, graph.nodes[graph.nodes[i].lambda].col, graph.nodes[graph.nodes[i].lambda].length); + } + for (uint32_t j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) + { + printf(" (%u, %u, %u): " VAR_FMT "\n", graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length, print_variant(graph.edges[j].variant, observed)); + } // for + } // for + size_t count = 0; for (uint32_t head = 0; head < va_array_length(graph.nodes); ++head) { @@ -934,7 +949,7 @@ edges2(VA_LCS_Node const head, VA_LCS_Node const tail, *variant = (VA_Variant) {row + head_offset, tail.row + tail_offset, col + head_offset, tail.col + tail_offset}; - //printf(VAR_FMT " x %u\n", print_variant((*variant), observed), count); + printf(VAR_FMT " x %u\n", print_variant((*variant), observed), count); return count; } // edges2 @@ -994,7 +1009,6 @@ bfs_traversal2(Graph2 const graph, size_t const len_obs, char const observed[sta variant.obs_start += 1; variant.obs_end += 1; } // for - //printf("s%u->s%u[label=\"%u:%u/%.*s\"]\n", head, graph.edges[j].tail, graph.edges[j].variant.start, graph.edges[j].variant.end, (int) graph.edges[j].variant.obs_end - graph.edges[j].variant.obs_start, observed + graph.edges[j].variant.obs_start); if (table[graph.edges[j].tail].depth > 0) { @@ -1187,7 +1201,7 @@ build(size_t const len_ref, char const reference[static len_ref], { printf(" (%u, %u, %u): lambda\n", graph.nodes[graph.nodes[i].lambda].row, graph.nodes[graph.nodes[i].lambda].col, graph.nodes[graph.nodes[i].lambda].length); } - for (size_t j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) + for (uint32_t j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) { printf(" (%u, %u, %u): ", graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length); edges2(((VA_LCS_Node) {graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, 0, 0}), From 5acf9c246e9e970d01ffcbd913b209f2971168c6 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 25 Mar 2025 16:39:14 +0100 Subject: [PATCH 149/704] Classify existing edges HEAD/TAIL/BOTH when splitting --- src/main.c | 69 ++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 49 insertions(+), 20 deletions(-) diff --git a/src/main.c b/src/main.c index 2e5595b..af1c273 100644 --- a/src/main.c +++ b/src/main.c @@ -137,18 +137,20 @@ build_graph(VA_Allocator const allocator, uint32_t max_sink = 0; sink.idx = add_node(allocator, &graph, sink.row, sink.col, sink.length - 1); + printf("MAKE NODE %u: (%u, %u, %u)\n", sink.idx, sink.row, sink.col, sink.length - 1); size_t here = 0; VA_LCS_Node* const heads = lcs_nodes[len_lcs - 1]; for (size_t i = 0; i < va_array_length(heads); ++i) { if (heads[i].row + heads[i].length < sink.row + sink.length && heads[i].col + heads[i].length < sink.col + sink.length) { - //printf("MAKE EDGE (%u %u %u) -> (%u %u %u)\n", heads[i].row, heads[i].col, heads[i].length, sink.row, sink.col, sink.length); - VA_Variant const variant = {heads[i].row + heads[i].length, sink.row + sink.length - 1, heads[i].col + heads[i].length - shift, sink.col + sink.length - 1 - shift}; + max_sink = MAX(max_sink, sink.row + sink.length - 1); heads[i].idx = add_node(allocator, &graph, heads[i].row, heads[i].col, heads[i].length); + printf("MAKE NODE %u: (%u, %u, %u)\n", heads[i].idx, heads[i].row, heads[i].col, heads[i].length); graph.nodes[heads[i].idx].edges = add_edge(allocator, &graph, sink.idx, graph.nodes[heads[i].idx].edges, variant); + printf("MAKE EDGE (%u %u %u) -> (%u %u %u): " VAR_FMT "\n", heads[i].row, heads[i].col, heads[i].length, sink.row, sink.col, sink.length, print_variant(variant, "0123456789")); here = i + 1; } // if } // for @@ -158,15 +160,14 @@ build_graph(VA_Allocator const allocator, sink.length -= 1; sink.incoming = len_lcs - 1; va_array_insert(allocator, lcs_nodes[len_lcs - 1], sink, here); - - //printf("INSERT (%u %u %u) here: %zu\n", sink.row, sink.col, sink.length, here); + printf("INSERT (%u %u %u) here: %zu\n", sink.row, sink.col, sink.length, here); } // if for (size_t i = len_lcs - 1; i >= 1; --i) { for (size_t j = 0; j < va_array_length(lcs_nodes[i]); ++j) { - if (lcs_nodes[i][j].idx == (uint32_t) -1) + if (lcs_nodes[i][j].idx == GVA_NULL) { continue; } // if @@ -180,33 +181,36 @@ build_graph(VA_Allocator const allocator, { max_sink = MAX(max_sink, tail.row + tail.length - 1); - //printf("MAKE EDGE (%u %u %u) -> (%u %u %u)\n", heads[k].row, heads[k].col, heads[k].length, tail.row, tail.col, tail.length); - VA_Variant const variant = {heads[k].row + heads[k].length, tail.row + tail.length - 1, heads[k].col + heads[k].length - shift, tail.col + tail.length - 1 - shift}; if (heads[k].incoming == i) { - size_t const split_idx = heads[k].idx; + printf("SPLIT at %zu\n", i); + uint32_t const split_idx = heads[k].idx; heads[k].idx = add_node(allocator, &graph, heads[k].row, heads[k].col, heads[k].length); + printf("MAKE NODE %u: (%u, %u, %u)\n", heads[k].idx, heads[k].row, heads[k].col, heads[k].length); heads[k].incoming = 0; // lambda-edge graph.nodes[heads[k].idx].lambda = split_idx; - graph.nodes[heads[k].idx].edges = add_edge(allocator, &graph, tail.idx, graph.nodes[heads[k].idx].edges, variant); - graph.nodes[split_idx].row += heads[k].length; graph.nodes[split_idx].col += heads[k].length; graph.nodes[split_idx].length -= heads[k].length; + printf("RELABEL NODE %u: (%u, %u, %u)\n", split_idx, graph.nodes[split_idx].row,graph.nodes[split_idx].col, graph.nodes[split_idx].length); } // if else { - if (heads[k].idx == (uint32_t) -1) + if (heads[k].idx == GVA_NULL) { heads[k].idx = add_node(allocator, &graph, heads[k].row, heads[k].col, heads[k].length); + printf("MAKE NODE %u: (%u, %u, %u)\n", heads[k].idx, heads[k].row, heads[k].col, heads[k].length); } // if - graph.nodes[heads[k].idx].edges = add_edge(allocator, &graph, tail.idx, graph.nodes[heads[k].idx].edges, variant); } // else + + graph.nodes[heads[k].idx].edges = add_edge(allocator, &graph, tail.idx, graph.nodes[heads[k].idx].edges, variant); + printf("MAKE EDGE (%u %u %u) -> (%u %u %u): " VAR_FMT "\n", heads[k].row, heads[k].col, heads[k].length, tail.row, tail.col, tail.length, print_variant(variant, "0123456789")); + here = k + 1; } // if } // for @@ -219,9 +223,7 @@ build_graph(VA_Allocator const allocator, lcs_nodes[i][j].incoming = i; } // if va_array_insert(allocator, lcs_nodes[i - 1], lcs_nodes[i][j], here); - - //printf("INSERT (%u %u %u) here: %zu\n", lcs_nodes[i][j].row, lcs_nodes[i][j].col, lcs_nodes[i][j].length, here); - + printf("INSERT (%u %u %u) here: %zu\n", lcs_nodes[i][j].row, lcs_nodes[i][j].col, lcs_nodes[i][j].length, here); } // if } // for lcs_nodes[i] = va_array_destroy(allocator, lcs_nodes[i]); @@ -237,12 +239,13 @@ build_graph(VA_Allocator const allocator, else { source = (VA_LCS_Node) {.row = shift, .col = shift, .length = 0}; - source.idx = add_node(allocator, &graph, shift, shift, 0); + source.idx = add_node(allocator, &graph, source.row, source.col, source.length); + printf("MAKE NODE %u: (%u, %u, %u)\n", source.idx, source.row, source.col, source.length); } // else for (size_t i = start; i < va_array_length(lcs_nodes[0]); ++i) { - if (lcs_nodes[0][i].idx == (uint32_t) -1) + if (lcs_nodes[0][i].idx == GVA_NULL) { continue; } // if @@ -251,10 +254,10 @@ build_graph(VA_Allocator const allocator, { max_sink = MAX(max_sink, lcs_nodes[0][i].row + lcs_nodes[0][i].length - 1); - //printf("MAKE EDGE (%u %u %u) -> (%u %u %u)\n", source.row, source.col, source.length, lcs_nodes[0][i].row, lcs_nodes[0][i].col, lcs_nodes[0][i].length); - VA_Variant const variant = {source.row, lcs_nodes[0][i].row + lcs_nodes[0][i].length - 1, source.col - shift, lcs_nodes[0][i].col + lcs_nodes[0][i].length - 1 - shift}; + graph.nodes[source.idx].edges = add_edge(allocator, &graph, lcs_nodes[0][i].idx, graph.nodes[source.idx].edges, variant); + printf("MAKE EDGE (%u %u %u) -> (%u %u %u): " VAR_FMT "\n", source.row, source.col, source.length, lcs_nodes[0][i].row, lcs_nodes[0][i].col, lcs_nodes[0][i].length, print_variant(variant, "0123456789")); } // if } // for lcs_nodes[0] = va_array_destroy(allocator, lcs_nodes[0]); @@ -1068,8 +1071,10 @@ build(size_t const len_ref, char const reference[static len_ref], } // if va_array_append(va_std_allocator, graph.nodes, ((Node) {last->row, last->col, last->length, GVA_NULL, GVA_NULL})); last->idx = va_array_length(graph.nodes) - 1; + printf("MAKE NODE %u: (%u, %u, %u)\n", last->idx, last->row, last->col, last->length); last->incoming = -1; + /* fprintf(stderr, "%zu\n", len_lcs); for (size_t i = 0; i < len_lcs; ++i) { @@ -1080,6 +1085,7 @@ build(size_t const len_ref, char const reference[static len_ref], } // for fprintf(stderr, "\n"); } // for + */ VA_LCS_Node source = {shift, shift, 0, -1, GVA_NULL}; bool found_source = false; @@ -1123,6 +1129,7 @@ build(size_t const len_ref, char const reference[static len_ref], { va_array_append(va_std_allocator, graph.edges, ((Edge2) {head->idx, graph.nodes[tail->idx].edges})); graph.nodes[tail->idx].edges = va_array_length(graph.edges) - 1; + printf("MAKE EDGE\n"); } } // else } // if @@ -1136,6 +1143,7 @@ build(size_t const len_ref, char const reference[static len_ref], { va_array_append(va_std_allocator, graph.nodes, ((Node) {head->row, head->col, head->length, GVA_NULL, GVA_NULL})); head->idx = va_array_length(graph.nodes) - 1; + printf("MAKE NODE %u: (%u, %u, %u)\n", head->idx, head->row, head->col, head->length); if (head->row == shift && head->col == shift) { source = *head; @@ -1154,10 +1162,29 @@ build(size_t const len_ref, char const reference[static len_ref], graph.nodes[tail->idx].col += split_len; graph.nodes[tail->idx].length -= split_len; tail->incoming = variant.end + count; - printf("SPLIT %u %u %u\n", tail->row, tail->col, tail->length); + printf("SPLIT %u %u %u @ %u\n", tail->row, tail->col, tail->length, variant.end + count - 1); + for (uint32_t i = graph.nodes[tail->idx].edges; i != GVA_NULL; i = graph.edges[i].next) + { + VA_Variant var; + uint32_t const count2 = edges2(*tail, (VA_LCS_Node) {graph.nodes[graph.edges[i].tail].row, graph.nodes[graph.edges[i].tail].col, graph.nodes[graph.edges[i].tail].length, 0, 0}, tail->row == shift && tail->col == shift, graph.nodes[graph.edges[i].tail].edges == GVA_NULL && graph.nodes[graph.edges[i].tail].lambda == GVA_NULL, len_obs, observed, &var); + printf(" -> %u: " VAR_FMT " x %u ::\n", graph.edges[i].tail, print_variant(var, observed), count2); + if (var.start > variant.end + count - 1) + { + printf(" -> TAIL\n"); + } // if + else if (var.end + count2 - 1 < variant.end + count) + { + printf(" -> HEAD\n"); + } // if + else + { + printf(" -> BOTH\n"); + } // else + } // for } // if va_array_append(va_std_allocator, graph.edges, ((Edge2) {tail->idx, graph.nodes[head->idx].edges})); graph.nodes[head->idx].edges = va_array_length(graph.edges) - 1; + printf("MAKE EDGE\n"); } // if else { @@ -1174,6 +1201,7 @@ build(size_t const len_ref, char const reference[static len_ref], { va_array_append(va_std_allocator, graph.nodes, ((Node) {source.row, source.col, source.length, GVA_NULL, GVA_NULL})); source.idx = va_array_length(graph.nodes) - 1; + printf("MAKE NODE %u: (%u, %u, %u)\n", source.idx, source.row, source.col, source.length); graph.source = source.idx; } // if printf("SOURCE %u %u %u: ", source.row, source.col, source.length); @@ -1182,6 +1210,7 @@ build(size_t const len_ref, char const reference[static len_ref], { va_array_append(va_std_allocator, graph.edges, ((Edge2) {tail->idx, graph.nodes[source.idx].edges})); graph.nodes[source.idx].edges = va_array_length(graph.edges) - 1; + printf("MAKE EDGE\n"); } // if } // if } // for t_j From cbc604e6d153ade301835cd87a32a81f72d61eaa Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Wed, 26 Mar 2025 16:44:00 +0100 Subject: [PATCH 150/704] WIP split edges. --- src/main.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/main.c b/src/main.c index af1c273..d6c65eb 100644 --- a/src/main.c +++ b/src/main.c @@ -1051,6 +1051,7 @@ build(size_t const len_ref, char const reference[static len_ref], size_t const len_obs, char const observed[static len_obs], size_t const shift) { + printf("build!\n"); VA_LCS_Node** lcs_nodes = NULL; size_t const len_lcs = va_edit(va_std_allocator, len_ref, reference, len_obs, observed, &lcs_nodes); @@ -1098,9 +1099,10 @@ build(size_t const len_ref, char const reference[static len_ref], VA_LCS_Node* const tail = &lcs_nodes[len_lcs - t_i - 1][t_len - t_j - 1]; if (tail->idx == GVA_NULL) { + // sink unreachable from tail, do not add to graph continue; } // if - printf("%u %u %u %u\n", tail->row, tail->col, tail->length, tail->incoming); + printf("%u %u %u %d\n", tail->row, tail->col, tail->length, tail->incoming); uint32_t split_idx = tail->idx; for (size_t h_i = 0; h_i < MIN(len_lcs - t_i, tail->length + 1); ++h_i) @@ -1119,11 +1121,11 @@ build(size_t const len_ref, char const reference[static len_ref], if (tail->row + tail->length > head->row + head->length + h_i || tail->col + tail->length > head->col + head->length + h_i) { - printf("--\n"); // FIXME: skip this remainder of this (head) level + printf("--\n"); // FIXME: skip the remainder of this (head) level } // if else { - printf("CONVERSE "); + printf("CONVERSE\n"); if (head->idx != GVA_NULL && edges2(*tail, *head, tail->row == shift && tail->col == shift, false, len_obs, observed, &(VA_Variant) {0, 0, 0, 0})) { @@ -1146,6 +1148,7 @@ build(size_t const len_ref, char const reference[static len_ref], printf("MAKE NODE %u: (%u, %u, %u)\n", head->idx, head->row, head->col, head->length); if (head->row == shift && head->col == shift) { + // head is the source source = *head; graph.source = source.idx; found_source = true; @@ -1154,6 +1157,7 @@ build(size_t const len_ref, char const reference[static len_ref], head->incoming = MIN(head->incoming, variant.start); if (variant.end + count > tail->incoming) { + printf("SPLIT %u %u %u @ %u\n", tail->row, tail->col, tail->length, variant.end + count - 1); uint32_t const split_len = tail->incoming - tail->row; va_array_append(va_std_allocator, graph.nodes, ((Node) {tail->row, tail->col, split_len, GVA_NULL, tail->idx})); @@ -1162,9 +1166,17 @@ build(size_t const len_ref, char const reference[static len_ref], graph.nodes[tail->idx].col += split_len; graph.nodes[tail->idx].length -= split_len; tail->incoming = variant.end + count; - printf("SPLIT %u %u %u @ %u\n", tail->row, tail->col, tail->length, variant.end + count - 1); + printf(VAR_FMT "\n", print_variant(variant, observed)); + if (variant.start < variant.end + count - 1) + { + // incoming edge + printf("INCOMING -> BOTH\n"); + va_array_append(va_std_allocator, graph.edges, ((Edge2) {split_idx, graph.nodes[head->idx].edges})); + graph.nodes[head->idx].edges = va_array_length(graph.edges) - 1; + } // if for (uint32_t i = graph.nodes[tail->idx].edges; i != GVA_NULL; i = graph.edges[i].next) { + // outgoing edges VA_Variant var; uint32_t const count2 = edges2(*tail, (VA_LCS_Node) {graph.nodes[graph.edges[i].tail].row, graph.nodes[graph.edges[i].tail].col, graph.nodes[graph.edges[i].tail].length, 0, 0}, tail->row == shift && tail->col == shift, graph.nodes[graph.edges[i].tail].edges == GVA_NULL && graph.nodes[graph.edges[i].tail].lambda == GVA_NULL, len_obs, observed, &var); printf(" -> %u: " VAR_FMT " x %u ::\n", graph.edges[i].tail, print_variant(var, observed), count2); @@ -1188,7 +1200,7 @@ build(size_t const len_ref, char const reference[static len_ref], } // if else { - // FIXME: skip this remainder of this (head) level + // FIXME: skip the remainder of this (head) level } // else } // else } // for h_j @@ -1229,7 +1241,7 @@ build(size_t const len_ref, char const reference[static len_ref], if (graph.nodes[i].lambda != GVA_NULL) { printf(" (%u, %u, %u): lambda\n", graph.nodes[graph.nodes[i].lambda].row, graph.nodes[graph.nodes[i].lambda].col, graph.nodes[graph.nodes[i].lambda].length); - } + } // if for (uint32_t j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) { printf(" (%u, %u, %u): ", graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length); From a1fca750a729bf23e3ed05b3d35a572d82d38310 Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 26 Mar 2025 17:01:29 +0100 Subject: [PATCH 151/704] Splitting for outgoing edges --- src/main.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/main.c b/src/main.c index d6c65eb..33f50c5 100644 --- a/src/main.c +++ b/src/main.c @@ -1174,6 +1174,10 @@ build(size_t const len_ref, char const reference[static len_ref], va_array_append(va_std_allocator, graph.edges, ((Edge2) {split_idx, graph.nodes[head->idx].edges})); graph.nodes[head->idx].edges = va_array_length(graph.edges) - 1; } // if + uint32_t head_head = GVA_NULL; + uint32_t head_tail = GVA_NULL; + uint32_t tail_head = GVA_NULL; + uint32_t tail_tail = GVA_NULL; for (uint32_t i = graph.nodes[tail->idx].edges; i != GVA_NULL; i = graph.edges[i].next) { // outgoing edges @@ -1183,16 +1187,46 @@ build(size_t const len_ref, char const reference[static len_ref], if (var.start > variant.end + count - 1) { printf(" -> TAIL\n"); + if (tail_tail != GVA_NULL) + { + graph.edges[tail_tail].next = i; + } // if + if (tail_head == GVA_NULL) + { + tail_head = i; + } // if + tail_tail = i; } // if else if (var.end + count2 - 1 < variant.end + count) { printf(" -> HEAD\n"); + if (head_tail != GVA_NULL) + { + graph.edges[head_tail].next = i; + } // if + if (head_head == GVA_NULL) + { + head_head = i; + } // if + head_tail = i; } // if else { printf(" -> BOTH\n"); + va_array_append(va_std_allocator, graph.edges, ((Edge2) {tail->idx, head_head})); + head_head = va_array_length(graph.edges) - 1; } // else } // for + if (head_tail != GVA_NULL) + { + graph.edges[head_tail].next = GVA_NULL; + } // if + if (tail_tail != GVA_NULL) + { + graph.edges[tail_tail].next = GVA_NULL; + } // if + graph.nodes[split_idx].edges = head_head; + graph.nodes[tail->idx].edges = tail_head; } // if va_array_append(va_std_allocator, graph.edges, ((Edge2) {tail->idx, graph.nodes[head->idx].edges})); graph.nodes[head->idx].edges = va_array_length(graph.edges) - 1; From c6794f3254a9de592c99970ba14c2aed657f0a7a Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 26 Mar 2025 17:15:15 +0100 Subject: [PATCH 152/704] Fixed something --- src/main.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/main.c b/src/main.c index 33f50c5..544765f 100644 --- a/src/main.c +++ b/src/main.c @@ -1213,7 +1213,16 @@ build(size_t const len_ref, char const reference[static len_ref], else { printf(" -> BOTH\n"); - va_array_append(va_std_allocator, graph.edges, ((Edge2) {tail->idx, head_head})); + if (tail_tail != GVA_NULL) + { + graph.edges[tail_tail].next = i; + } // if + if (tail_head == GVA_NULL) + { + tail_head = i; + } // if + tail_tail = i; + va_array_append(va_std_allocator, graph.edges, ((Edge2) {graph.edges[i].tail, head_head})); head_head = va_array_length(graph.edges) - 1; } // else } // for From 737aa2c93f9b028a562f90f0bcde1566db9abc88 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Wed, 2 Apr 2025 23:08:21 +0200 Subject: [PATCH 153/704] Split files. --- include/extract.h | 0 include/graph.h | 69 +++ src/extract.c | 341 +++++++++++++ src/graph.c | 824 ++++++++++++++++++++++++++++++ src/main.c | 1215 +-------------------------------------------- 5 files changed, 1237 insertions(+), 1212 deletions(-) create mode 100644 include/extract.h create mode 100644 include/graph.h create mode 100644 src/extract.c create mode 100644 src/graph.c diff --git a/include/extract.h b/include/extract.h new file mode 100644 index 0000000..e69de29 diff --git a/include/graph.h b/include/graph.h new file mode 100644 index 0000000..35e57d7 --- /dev/null +++ b/include/graph.h @@ -0,0 +1,69 @@ +#include // uint32_t +#include "../include/edit.h" // VA_LCS_Node +#include "../include/variant.h" // VA_Variant + +typedef struct +{ + uint32_t tail; + uint32_t next; + VA_Variant variant; +} Edge; + + +typedef struct +{ + uint32_t tail; + uint32_t next; +} Edge2; + + +typedef struct +{ + uint32_t row; + uint32_t col; + uint32_t length; + uint32_t edges; + uint32_t lambda; +} Node; + + +typedef struct +{ + Node* nodes; + Edge* edges; + VA_Variant supremal; + uint32_t source; +} Graph; + + +typedef struct +{ + Node* nodes; + Edge2* edges; + uint32_t source; +} Graph2; + + +Graph +build_graph(VA_Allocator const allocator, + size_t const len_ref, size_t const len_obs, + size_t const len_lcs, VA_LCS_Node* lcs_nodes[static len_lcs], + size_t const shift); + +Graph2 +build(size_t const len_ref, char const reference[static len_ref], + size_t const len_obs, char const observed[static len_obs], + size_t const shift); + +void +to_dot(Graph const graph, size_t const len_obs, char const observed[static len_obs]); + +size_t +edges(uint32_t const head_row, uint32_t const head_col, uint32_t const head_length, + uint32_t const tail_row, uint32_t const tail_col, uint32_t const tail_length, + bool const is_source, + size_t const len_obs, char const observed[static len_obs], + VA_Variant const edge); + +void +destroy(VA_Allocator const allocator, Graph* const graph); diff --git a/src/extract.c b/src/extract.c new file mode 100644 index 0000000..e5cc45c --- /dev/null +++ b/src/extract.c @@ -0,0 +1,341 @@ +#include // NULL, size_t +#include // uint32_t +#include // stderr, fprintf, printf + +#include "../include/alloc.h" // VA_Allocator +#include "../include/array.h" // va_array_* +#include "../include/variant.h" // VA_Variant +#include "../include/graph.h" // Edge, Edge2, Graph, Node + +#define MAX(lhs, rhs) (((lhs) > (rhs)) ? (lhs) : (rhs)) +#define MIN(lhs, rhs) (((lhs) < (rhs)) ? (lhs) : (rhs)) + +#define print_variant(variant, observed) variant.start, variant.end, (int) variant.obs_end - variant.obs_start, observed + variant.obs_start +#define VAR_FMT "%u:%u/%.*s" + + +typedef struct +{ + uint32_t post; + uint32_t rank; + uint32_t edge; + uint32_t start; + uint32_t end; + uint32_t next; +} Post_Table; + + +static uint32_t +intersection(uint32_t lhs, uint32_t rhs, size_t const length, Post_Table const visited[static length]) +{ + if (lhs == (uint32_t) -1) + { + return rhs; + } // if + while (lhs != rhs) + { + while (visited[lhs].rank > visited[rhs].rank) + { + lhs = visited[lhs].post; + } // while + while (visited[rhs].rank > visited[lhs].rank) + { + rhs = visited[rhs].post; + } // while + } // while + return lhs; +} // intersection + + +static void +local_supremal(VA_Allocator const allocator, Graph const graph, size_t const len_obs, char const observed[static len_obs]) +{ + uint32_t const length = va_array_length(graph.nodes); + Post_Table* visited = allocator.alloc(allocator.context, NULL, 0, sizeof(*visited) * length); + if (visited == NULL) + { + return; + } // if + + for (uint32_t i = 0; i < length; ++i) + { + visited[i].post = -1; + visited[i].start = 0; + visited[i].end = -1; + visited[i].next = -1; + } // for + + uint32_t rank = 0; + uint32_t head = graph.source; + visited[head].edge = graph.nodes[head].edges; + + while (head != (uint32_t) -1) + { + uint32_t edge = visited[head].edge; + if (edge == (uint32_t) -1) + { + uint32_t const lambda = graph.nodes[head].lambda; + if (lambda != (uint32_t) -1) + { + if (visited[lambda].next == (uint32_t) -1) + { + visited[lambda].edge = graph.nodes[lambda].edges; + visited[lambda].next = head; + head = lambda; + continue; + } // if + visited[head].post = intersection(visited[head].post, lambda, length, visited); + } // if + + visited[head].rank = rank; + rank += 1; + head = visited[head].next; + continue; + } // if + + if (visited[graph.edges[edge].tail].next != (uint32_t) -1) + { + visited[head].post = intersection(visited[head].post, graph.edges[edge].tail, length, visited); + visited[head].edge = graph.edges[edge].next; + } // if + while (edge != (uint32_t) -1) + { + uint32_t const tail = graph.edges[edge].tail; + visited[head].end = MIN(visited[head].end, graph.edges[edge].variant.start); + visited[tail].start = MAX(visited[tail].start, graph.edges[edge].variant.end); + if (visited[tail].next == (uint32_t) -1) + { + visited[tail].edge = graph.nodes[tail].edges; + visited[tail].next = head; + head = tail; + break; + } // if + visited[head].post = intersection(visited[head].post, tail, length, visited); + edge = graph.edges[edge].next; + } // while + } // while + + /* + printf(" # \tpost\trank\tstart\tend\n"); + for (uint32_t i = 0; i < length; ++i) + { + printf("%2u:\t%4d\t%4u\t%5u\t%3d\n", i, visited[i].post, visited[i].rank, visited[i].start, visited[i].end); + } // for + */ + + head = graph.source; + uint32_t shift = 0; + for (uint32_t tail = visited[head].post; tail != (uint32_t) -1; head = tail, tail = visited[head].post) + { + uint32_t const start = visited[head].end; + uint32_t const end = visited[tail].start; + VA_Variant const variant = {start, end, graph.nodes[head].col + start - graph.nodes[head].row - shift, graph.nodes[tail].col + end - graph.nodes[tail].row - shift}; + if (head != graph.source) + { + printf(",\n"); + } // if + printf(" \"" VAR_FMT "\"", print_variant(variant, observed)); + } // for + + visited = allocator.alloc(allocator.context, visited, sizeof(*visited) * length, 0); +} // local_supremal + + +typedef struct +{ + uint32_t lca; + uint32_t rank; + uint32_t depth; + uint32_t start; + uint32_t end; + uint32_t prev; + uint32_t next; +} LCA_Table; + + +static inline uint32_t +lca(uint32_t* const start, uint32_t lhs, uint32_t rhs, size_t const length, LCA_Table const visited[static length]) +{ + uint32_t lhs_start = *start; + uint32_t rhs_start = *start; + while (lhs != rhs) + { + fprintf(stderr, " lca %u (%d), %u (%d)\n", lhs, lhs_start, rhs, rhs_start); + + while (visited[lhs].rank > visited[rhs].rank) + { + fprintf(stderr, " left\n"); + lhs_start = visited[lhs].start; + lhs = visited[lhs].lca; + } // if + while (visited[rhs].rank > visited[lhs].rank) + { + fprintf(stderr, " right\n"); + rhs_start = visited[rhs].start; + rhs = visited[rhs].lca; + } // if + } // while + *start = MIN(lhs_start, rhs_start); + return lhs; +} // lca + + +static void +print_lca_table(size_t const length, LCA_Table const visited[static length], uint32_t const head, uint32_t const tail) +{ + fprintf(stderr, " # \tlca\trank\tdepth\tstart\tend\tprev\tnext\n"); + for (uint32_t i = 0; i < length; ++i) + { + fprintf(stderr, "%2u:\t%3d\t%4d\t%5d\t%5d\t%3d\t%4d\t%4d\n", i, visited[i].lca, visited[i].rank, visited[i].depth, visited[i].start, visited[i].end, visited[i].prev, visited[i].next); + } // for + fprintf(stderr, "head: %d\ntail: %d\n", head, tail); +} // print_lca_table + + +static void +canonical(VA_Allocator const allocator, Graph const graph, size_t const len_obs, char const observed[static len_obs]) +{ + uint32_t const length = va_array_length(graph.nodes); + LCA_Table* visited = allocator.alloc(allocator.context, NULL, 0, sizeof(*visited) * length); + if (visited == NULL) + { + return; + } // if + + for (uint32_t i = 0; i < length; ++i) + { + visited[i].depth = -1; + + visited[i].lca = -1; + visited[i].rank = -1; + visited[i].start = -1; + visited[i].end = -1; + visited[i].prev = -1; + visited[i].next = -1; + + } // for + + uint32_t sink = -1; + visited[graph.source] = (LCA_Table) {-1, 0, 0, -1, -1, -1, -1}; + uint32_t rank = 1; + // main loop over a queue + for (uint32_t head = graph.source, tail = graph.source; head != (uint32_t) -1; head = visited[head].next) + { + fprintf(stderr, "pop %u @ %u\n", head, visited[head].depth); + + if (graph.nodes[head].edges == (uint32_t) -1) + { + fprintf(stderr, " sink\n"); + sink = head; + continue; + } // if + + uint32_t const lambda = graph.nodes[head].lambda; + if (lambda != (uint32_t) -1) + { + if (visited[lambda].depth == (uint32_t) -1) + { + // add lambda in stack order + fprintf(stderr, " push lambda %u @ %u\n", lambda, visited[head].depth); + + visited[visited[head].next].prev = lambda; + visited[lambda] = (LCA_Table) {head, rank, visited[head].depth, -1, -1, head, visited[head].next}; + rank += 1; + visited[head].next = lambda; + } // if + else if (visited[lambda].depth == visited[head].depth) + { + fprintf(stderr, " update lambda %u @ %u\n", lambda, visited[head].depth); + fprintf(stderr, " lca(%u, %u)\n", visited[lambda].lca, head); + visited[lambda].lca = lca(&visited[lambda].start, visited[lambda].lca, head, length, visited); + + // FIXME: what is correct here? + // AGGCCG CGCAGCCTC ignores the common end position + // ACAGGA CAAGGCG + // TAATTGGTAG CTATTCAG needs the common end position + // TTAAG TAACA + + //visited[lambda].end = graph.nodes[head].row; // this simulates the empty variant on a lambda edge + + fprintf(stderr, " = %u (%u:%u)\n", visited[lambda].lca, visited[lambda].start, visited[lambda].end); + } // if + else if (visited[head].next == lambda) + { + fprintf(stderr, " improve lambda in place %u @ %u\n", lambda, visited[head].depth); + visited[lambda] = (LCA_Table) {head, visited[lambda].rank, visited[head].depth, -1, -1, visited[lambda].prev, visited[lambda].next}; + } // if + else + { + fprintf(stderr, " improve lambda %u @ %u\n", lambda, visited[head].depth); + + if (lambda == tail) + { + tail = visited[lambda].prev; + } // if + else + { + visited[visited[lambda].next].prev = visited[lambda].prev; + } // else + visited[visited[head].next].prev = lambda; + visited[visited[lambda].prev].next = visited[lambda].next; + visited[lambda] = (LCA_Table) {head, visited[lambda].rank, visited[head].depth, -1, -1, head, visited[head].next}; + visited[head].next = lambda; + } // else + + //print_lca_table(length, visited, head, tail); + + } // if + + for (uint32_t i = graph.nodes[head].edges; i != (uint32_t) -1; i = graph.edges[i].next) + { + uint32_t const edge_tail = graph.edges[i].tail; + if (visited[edge_tail].depth == (uint32_t) -1) + { + // add regular successors in queue order + fprintf(stderr, " push %u @ %u\n", edge_tail, visited[head].depth + 1); + visited[edge_tail] = (LCA_Table) {head, rank, visited[head].depth + 1, graph.edges[i].variant.start, graph.edges[i].variant.end, tail, -1}; + rank += 1; + visited[tail].next = edge_tail; + tail = edge_tail; + } // if + else if (visited[edge_tail].depth - 1 == visited[head].depth) + { + fprintf(stderr, " update %u @ %u\n", edge_tail, visited[edge_tail].depth); + fprintf(stderr, " lca(%u, %u)\n", visited[edge_tail].lca, head); + visited[edge_tail].start = MIN(visited[edge_tail].start, graph.edges[i].variant.start); + visited[edge_tail].lca = lca(&visited[edge_tail].start, visited[edge_tail].lca, head, length, visited); + visited[edge_tail].end = MAX(visited[edge_tail].end, graph.edges[i].variant.end); + fprintf(stderr, " = %u (%u:%u)\n", visited[edge_tail].lca, visited[edge_tail].start, visited[edge_tail].end); + } // if + else + { + fprintf(stderr, " skip %u @ %u\n", edge_tail, visited[edge_tail].depth); + } // else + + //print_lca_table(length, visited, head, tail); + } // for + } // for + + print_lca_table(length, visited, -1, -1); + + // the canonical variant is given in the reverse order (for now): the Python checker needs to reverse this list + for (uint32_t tail = sink; tail != (uint32_t) -1; tail = visited[tail].lca) + { + uint32_t const head = visited[tail].lca; + if (head != (uint32_t) - 1 && visited[tail].start != (uint32_t) -1) + { + // we need to skip lambda edges: start && end == -1 + uint32_t const start_offset = visited[tail].start - graph.nodes[head].row; + uint32_t const end_offset = visited[tail].end - graph.nodes[tail].row; + VA_Variant const variant = {visited[tail].start, visited[tail].end, graph.nodes[head].col + start_offset, graph.nodes[tail].col + end_offset}; + + if (tail != sink) + { + printf(",\n"); + } // if + printf(" \"" VAR_FMT "\"", print_variant(variant, observed)); + } // if + } // while + + visited = allocator.alloc(allocator.context, visited, sizeof(*visited) * length, 0); +} // canonical \ No newline at end of file diff --git a/src/graph.c b/src/graph.c new file mode 100644 index 0000000..0cab89b --- /dev/null +++ b/src/graph.c @@ -0,0 +1,824 @@ +#include // bool, false, true +#include // NULL, size_t +#include // intmax_t, uint32_t +#include // stderr, fprintf, printf +#include // EXIT_*, atoi, rand, srand +#include // strlen, strncmp + +#include "../include/alloc.h" // VA_Allocator +#include "../include/array.h" // va_array_* +#include "../include/edit.h" // VA_LCS_Node, va_edit +#include "../include/std_alloc.h" // va_std_allocator +#include "../include/variant.h" // VA_Variant +#include "../include/graph.h" // Edge, Edge2, Graph, Node + + +#define MAX(lhs, rhs) (((lhs) > (rhs)) ? (lhs) : (rhs)) +#define MIN(lhs, rhs) (((lhs) < (rhs)) ? (lhs) : (rhs)) + +#define print_variant(variant, observed) variant.start, variant.end, (int) variant.obs_end - variant.obs_start, observed + variant.obs_start +#define VAR_FMT "%u:%u/%.*s" + + +static uint32_t const GVA_NULL = UINT32_MAX; + + +static inline size_t +add_node(VA_Allocator const allocator, Graph* const graph, size_t const row, size_t const col, size_t const length) +{ + va_array_append(allocator, graph->nodes, ((Node) {row, col, length, -1, -1})); + return va_array_length(graph->nodes) - 1; +} // add_node + + +static inline size_t +add_edge(VA_Allocator const allocator, Graph* const graph, size_t const tail, size_t const next, VA_Variant const variant) +{ + va_array_append(allocator, graph->edges, ((Edge) {tail, next, variant})); + return va_array_length(graph->edges) - 1; +} // add_edge + + +inline void +destroy(VA_Allocator const allocator, Graph* const graph) +{ + graph->nodes = va_array_destroy(allocator, graph->nodes); + graph->edges = va_array_destroy(allocator, graph->edges); +} // destroy + + +Graph +build_graph(VA_Allocator const allocator, + size_t const len_ref, size_t const len_obs, + size_t const len_lcs, VA_LCS_Node* lcs_nodes[static len_lcs], + size_t const shift) +{ + Graph graph = {.nodes = NULL, .edges = NULL}; + + if (len_lcs == 0 || lcs_nodes == NULL) + { + graph.source = add_node(allocator, &graph, shift, shift, 0); + if (len_ref == 0 && len_obs == 0) + { + graph.supremal = (VA_Variant) {0, 0, 0, 0}; + return graph; + } // if + uint32_t const sink = add_node(allocator, &graph, len_ref, len_obs, 0); + graph.supremal = (VA_Variant) {shift, shift + len_ref, 0, len_obs}; + graph.nodes[graph.source].edges = add_edge(allocator, &graph, sink, -1, graph.supremal); + return graph; + } // if + + VA_LCS_Node sink = lcs_nodes[len_lcs - 1][va_array_length(lcs_nodes[len_lcs - 1]) - 1]; + if (sink.row + sink.length == len_ref + shift && sink.col + sink.length == len_obs + shift) + { + va_array_header(lcs_nodes[len_lcs - 1])->length -= 1; // del + sink.length += 1; + } // if + else + { + sink = (VA_LCS_Node) {.row = len_ref + shift, .col = len_obs + shift, .length = 1}; + } // else + + uint32_t max_sink = 0; + sink.idx = add_node(allocator, &graph, sink.row, sink.col, sink.length - 1); + printf("MAKE NODE %u: (%u, %u, %u)\n", sink.idx, sink.row, sink.col, sink.length - 1); + size_t here = 0; + VA_LCS_Node* const heads = lcs_nodes[len_lcs - 1]; + for (size_t i = 0; i < va_array_length(heads); ++i) + { + if (heads[i].row + heads[i].length < sink.row + sink.length && heads[i].col + heads[i].length < sink.col + sink.length) + { + VA_Variant const variant = {heads[i].row + heads[i].length, sink.row + sink.length - 1, heads[i].col + heads[i].length - shift, sink.col + sink.length - 1 - shift}; + + max_sink = MAX(max_sink, sink.row + sink.length - 1); + heads[i].idx = add_node(allocator, &graph, heads[i].row, heads[i].col, heads[i].length); + printf("MAKE NODE %u: (%u, %u, %u)\n", heads[i].idx, heads[i].row, heads[i].col, heads[i].length); + graph.nodes[heads[i].idx].edges = add_edge(allocator, &graph, sink.idx, graph.nodes[heads[i].idx].edges, variant); + printf("MAKE EDGE (%u %u %u) -> (%u %u %u): " VAR_FMT "\n", heads[i].row, heads[i].col, heads[i].length, sink.row, sink.col, sink.length, print_variant(variant, "0123456789")); + here = i + 1; + } // if + } // for + + if (sink.length > 1) + { + sink.length -= 1; + sink.incoming = len_lcs - 1; + va_array_insert(allocator, lcs_nodes[len_lcs - 1], sink, here); + printf("INSERT (%u %u %u) here: %zu\n", sink.row, sink.col, sink.length, here); + } // if + + for (size_t i = len_lcs - 1; i >= 1; --i) + { + for (size_t j = 0; j < va_array_length(lcs_nodes[i]); ++j) + { + if (lcs_nodes[i][j].idx == GVA_NULL) + { + continue; + } // if + + here = 0; + VA_LCS_Node const tail = lcs_nodes[i][j]; + VA_LCS_Node* const heads = lcs_nodes[i - 1]; + for (size_t k = 0; k < va_array_length(heads); ++k) + { + if (heads[k].row + heads[k].length < tail.row + tail.length && heads[k].col + heads[k].length < tail.col + tail.length) + { + max_sink = MAX(max_sink, tail.row + tail.length - 1); + + VA_Variant const variant = {heads[k].row + heads[k].length, tail.row + tail.length - 1, heads[k].col + heads[k].length - shift, tail.col + tail.length - 1 - shift}; + + if (heads[k].incoming == i) + { + printf("SPLIT at %zu\n", i); + uint32_t const split_idx = heads[k].idx; + heads[k].idx = add_node(allocator, &graph, heads[k].row, heads[k].col, heads[k].length); + printf("MAKE NODE %u: (%u, %u, %u)\n", heads[k].idx, heads[k].row, heads[k].col, heads[k].length); + heads[k].incoming = 0; + + // lambda-edge + graph.nodes[heads[k].idx].lambda = split_idx; + + graph.nodes[split_idx].row += heads[k].length; + graph.nodes[split_idx].col += heads[k].length; + graph.nodes[split_idx].length -= heads[k].length; + printf("RELABEL NODE %u: (%u, %u, %u)\n", split_idx, graph.nodes[split_idx].row,graph.nodes[split_idx].col, graph.nodes[split_idx].length); + } // if + else + { + if (heads[k].idx == GVA_NULL) + { + heads[k].idx = add_node(allocator, &graph, heads[k].row, heads[k].col, heads[k].length); + printf("MAKE NODE %u: (%u, %u, %u)\n", heads[k].idx, heads[k].row, heads[k].col, heads[k].length); + } // if + } // else + + graph.nodes[heads[k].idx].edges = add_edge(allocator, &graph, tail.idx, graph.nodes[heads[k].idx].edges, variant); + printf("MAKE EDGE (%u %u %u) -> (%u %u %u): " VAR_FMT "\n", heads[k].row, heads[k].col, heads[k].length, tail.row, tail.col, tail.length, print_variant(variant, "0123456789")); + + here = k + 1; + } // if + } // for + + if (lcs_nodes[i][j].length > 1) + { + lcs_nodes[i][j].length -= 1; + if (here > 0) + { + lcs_nodes[i][j].incoming = i; + } // if + va_array_insert(allocator, lcs_nodes[i - 1], lcs_nodes[i][j], here); + printf("INSERT (%u %u %u) here: %zu\n", lcs_nodes[i][j].row, lcs_nodes[i][j].col, lcs_nodes[i][j].length, here); + } // if + } // for + lcs_nodes[i] = va_array_destroy(allocator, lcs_nodes[i]); + } // for + + VA_LCS_Node source = lcs_nodes[0][0]; + + size_t start = 0; + if (source.row == shift && source.col == shift) + { + start = 1; + } // if + else + { + source = (VA_LCS_Node) {.row = shift, .col = shift, .length = 0}; + source.idx = add_node(allocator, &graph, source.row, source.col, source.length); + printf("MAKE NODE %u: (%u, %u, %u)\n", source.idx, source.row, source.col, source.length); + } // else + + for (size_t i = start; i < va_array_length(lcs_nodes[0]); ++i) + { + if (lcs_nodes[0][i].idx == GVA_NULL) + { + continue; + } // if + + if (source.row < lcs_nodes[0][i].row + lcs_nodes[0][i].length && source.col < lcs_nodes[0][i].col + lcs_nodes[0][i].length) + { + max_sink = MAX(max_sink, lcs_nodes[0][i].row + lcs_nodes[0][i].length - 1); + + VA_Variant const variant = {source.row, lcs_nodes[0][i].row + lcs_nodes[0][i].length - 1, source.col - shift, lcs_nodes[0][i].col + lcs_nodes[0][i].length - 1 - shift}; + + graph.nodes[source.idx].edges = add_edge(allocator, &graph, lcs_nodes[0][i].idx, graph.nodes[source.idx].edges, variant); + printf("MAKE EDGE (%u %u %u) -> (%u %u %u): " VAR_FMT "\n", source.row, source.col, source.length, lcs_nodes[0][i].row, lcs_nodes[0][i].col, lcs_nodes[0][i].length, print_variant(variant, "0123456789")); + } // if + } // for + lcs_nodes[0] = va_array_destroy(allocator, lcs_nodes[0]); + lcs_nodes = allocator.alloc(allocator.context, lcs_nodes, len_lcs * sizeof(*lcs_nodes), 0); + + uint32_t min_source = max_sink; + for (uint32_t i = graph.nodes[source.idx].edges; i != (uint32_t) -1; i = graph.edges[i].next) + { + min_source = MIN(min_source, graph.edges[i].variant.start); + } // for + uint32_t const min_offset = min_source - graph.nodes[source.idx].row; + + graph.nodes[source.idx].row += min_offset; + graph.nodes[source.idx].col += min_offset; + graph.nodes[source.idx].length -= min_offset; + graph.nodes[sink.idx].length -= graph.nodes[sink.idx].row + graph.nodes[sink.idx].length - max_sink; + + graph.supremal = (VA_Variant) {min_source, max_sink, graph.nodes[source.idx].col - shift, graph.nodes[sink.idx].col + graph.nodes[sink.idx].length - shift}; + graph.source = source.idx; + + return graph; +} // build_graph + + +void +to_dot(Graph const graph, size_t const len_obs, char const observed[static len_obs]) +{ + fprintf(stderr, "digraph{\nrankdir=LR\nedge[fontname=monospace]\nnode[fixedsize=true,fontname=serif,shape=circle,width=1]\nsi[label=\"\",shape=none,width=0]\nsi->s%u\n", graph.source); + for (uint32_t i = 0; i < va_array_length(graph.nodes); ++i) + { + fprintf(stderr, "s%u[label=\"(%u, %u, %u)\"%s]\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, graph.nodes[i].edges == (uint32_t) -1 ? ",peripheries=2" : ""); + if (graph.nodes[i].lambda != (uint32_t) -1) + { + fprintf(stderr, "s%u->s%u[label=\"λ\",style=\"dashed\"]\n", i, graph.nodes[i].lambda); + } // if + for (uint32_t j = graph.nodes[i].edges; j != (uint32_t) -1; j = graph.edges[j].next) + { + fprintf(stderr, "s%u->s%u[label=\"%u:%u/%.*s\"]\n", i, graph.edges[j].tail, graph.edges[j].variant.start, graph.edges[j].variant.end, (int) graph.edges[j].variant.obs_end - graph.edges[j].variant.obs_start, observed + graph.edges[j].variant.obs_start); + } // for + } // for + fprintf(stderr, "}\n"); +} // to_dot + + +static size_t +bfs_traversal(VA_Allocator const allocator, Graph const graph, size_t const len_obs, char const observed[static len_obs]) +{ + struct + { + uint32_t depth; + uint32_t next; + }* table = allocator.alloc(allocator.context, NULL, 0, sizeof(*table) * va_array_length(graph.nodes)); + + for (size_t i = 0; i < va_array_length(graph.nodes); ++i) + { + table[i].depth = 0; + table[i].next = -1; + } // for + uint32_t head = graph.source; + uint32_t tail = graph.source; + + size_t count = 0; + //printf("digraph{\nrankdir=LR\nedge[fontname=monospace]\nnode[fixedsize=true,fontname=serif,shape=circle,width=1]\nsi[shape=point,width=.1]\n"); + //printf("si->s%u\n", graph.source); + + printf(" \"edges\": [\n"); + while (head != (uint32_t) -1) + { + //printf("pop %u\n", head); + for (uint32_t i = head; i != (uint32_t) -1; i = graph.nodes[i].lambda) + { + //printf("s%u[label=\"(%u, %u, %u)\"%s]\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, graph.nodes[i].edges == (uint32_t) -1 ? ",peripheries=2" : ""); + if (i != head) + { + //printf("lambda %u\n", i); + } // if + for (uint32_t j = graph.nodes[i].edges; j != (uint32_t) -1; j = graph.edges[j].next) + { + if (count > 0) + { + printf(",\n"); + } // if + count += 1; + printf(" {\"head\": \"s%u\", \"tail\": \"s%u\", \"variant\": \"%u:%u/%.*s\"}", head, graph.edges[j].tail, graph.edges[j].variant.start, graph.edges[j].variant.end, (int) graph.edges[j].variant.obs_end - graph.edges[j].variant.obs_start, observed + graph.edges[j].variant.obs_start); + //printf("s%u->s%u[label=\"%u:%u/%.*s\"]\n", head, graph.edges[j].tail, graph.edges[j].variant.start, graph.edges[j].variant.end, (int) graph.edges[j].variant.obs_end - graph.edges[j].variant.obs_start, observed + graph.edges[j].variant.obs_start); + + if (table[graph.edges[j].tail].depth > 0) + { + //printf("skip %u\n", graph.edges[j].tail); + continue; + } // if + + //printf("push %u\n", graph.edges[j].tail); + table[graph.edges[j].tail].depth = table[i].depth + 1; + table[tail].next = graph.edges[j].tail; + tail = graph.edges[j].tail; + } // for + } // for + head = table[head].next; + + /* + printf(" # \tdepth\tnext\n"); + for (size_t i = 0; i < va_array_length(graph.nodes); ++i) + { + printf("%3zu:\t%5u\t%4d\n", i, table[i].depth, table[i].next); + } // for + printf("head: %d\ntail: %d\n", head, tail); + */ + } // while + + printf("\n ],\n"); + + table = allocator.alloc(allocator.context, table, sizeof(*table) * va_array_length(graph.nodes), 0); + + return count; +} // bfs_traversal + + +static void +lambda_edges(Graph const graph, size_t const len_obs, char const observed[static len_obs]) +{ + printf(" \"edges\": [\n"); + size_t count = 0; + for (uint32_t i = 0; i < va_array_length(graph.nodes); ++i) + { + if (graph.nodes[i].lambda != (uint32_t) -1) + { + if (count > 0) + { + printf(",\n"); + } // if + count += 1; + printf(" {\"head\": \"s%u\", \"tail\": \"s%u\", \"variant\": \"lambda\"}", i, graph.nodes[i].lambda); + } // if + for (uint32_t j = graph.nodes[i].edges; j != (uint32_t) -1; j = graph.edges[j].next) + { + if (count > 0) + { + printf(",\n"); + } // if + count += 1; + printf(" {\"head\": \"s%u\", \"tail\": \"s%u\", \"variant\": \"%u:%u/%.*s\"}", i, graph.edges[j].tail, graph.edges[j].variant.start, graph.edges[j].variant.end, (int) graph.edges[j].variant.obs_end - graph.edges[j].variant.obs_start, observed + graph.edges[j].variant.obs_start); + } // for + } // for + printf("\n ],\n"); +} // lambda_edges + +/* +static void +to_json(Graph const graph, size_t const len_obs, char const observed[static len_obs], bool const lambda) +{ + printf("{\n \"source\": \"s%u\",\n \"nodes\": {\n", graph.source); + for (uint32_t i = 0; i < va_array_length(graph.nodes); ++i) + { + printf(" \"s%u\": {\"row\": %u, \"col\": %u, \"length\": %u}%s\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, i < va_array_length(graph.nodes) - 1 ? "," : ""); + } // for + printf(" },\n"); + if (lambda) { + lambda_edges(graph, len_obs, observed); + } else { + bfs_traversal(va_std_allocator, graph, len_obs, observed); + } + printf(" \"supremal\": \"%u:%u/%.*s\",\n", graph.supremal.start, graph.supremal.end, (int) graph.supremal.obs_end - graph.supremal.obs_start, observed + graph.supremal.obs_start); + printf(" \"local_supremal\": [\n"); + local_supremal(va_std_allocator, graph, len_obs, observed); + printf("\n ],\n"); + printf(" \"canonical\": [\n"); + canonical(va_std_allocator, graph, len_obs, observed); + printf("\n ]\n"); + printf("}"); +} // to_json +*/ + + +size_t +edges(uint32_t const head_row, uint32_t const head_col, uint32_t const head_length, + uint32_t const tail_row, uint32_t const tail_col, uint32_t const tail_length, + bool const is_source, + size_t const len_obs, char const observed[static len_obs], + VA_Variant const edge) +{ + printf( + "(%u, %u, %u) -> (%u, %u, %u) source: %d\n", + head_row, head_col, head_length, + tail_row, tail_col, tail_length, + is_source + ); + //printf(VAR_FMT "\n", print_variant(edge, observed)); + printf("%u %u %u %u\n", edge.start, edge.end, edge.obs_start, edge.obs_end); + + ptrdiff_t const row = (ptrdiff_t) head_row - is_source; + ptrdiff_t const col = (ptrdiff_t) head_col - is_source; + uint32_t const length = head_length + is_source; + + printf("%zd, %zd, %u\n", row, col, length); + + ptrdiff_t const offset = MIN((ptrdiff_t) tail_row - row, (ptrdiff_t) tail_col - col) - 1; + uint32_t const head_start = offset > 0 ? MIN(offset, length - 1) : 0; + uint32_t const tail_start = offset < 0 ? MIN(-offset, tail_length - 1) : 0; + + uint32_t const count = MIN(length - head_start, tail_length - tail_start); + + printf(" %zd: (%u, %u) :: %u\n", offset, head_start, tail_start, count); + + if (offset < 0 && tail_length <= -offset) + { + printf(" X\n"); + return 0; + } // if + + bool found = false; + for (uint32_t j = 0; j < count; ++j) + { + VA_Variant const variant = + { + row + head_start + j + 1, + tail_row + tail_start + j, + col + head_start + j + 1, + tail_col + tail_start + j + }; + + if (edge.start == variant.start && edge.end == variant.end && + edge.obs_start == variant.obs_start && edge.obs_end == variant.obs_end) + { + found = true; + } // if + + printf(" (%u, %u) -> (%u, %u) :: " VAR_FMT "\n", //"%u %u %u %u\n", + head_row + head_start + j, head_col + head_start + j, + tail_row + tail_start + j, tail_col + tail_start + j, + print_variant(variant, observed) //, + //variant.start, variant.end, variant.obs_start, variant.obs_end + ); + } // for + + if (!found) + { + return -1; + } // if + return count; +} // edges + + +static uint32_t +edges2(VA_LCS_Node const head, VA_LCS_Node const tail, + bool const is_source, bool const is_sink, + size_t const len_obs, char const observed[static len_obs], VA_Variant* const variant) +{ +// printf("%u %u %u -> %u %u %u %s %s\n", head.row, head.col, head.length, tail.row, tail.col, tail.length, is_source ? "SOURCE" : "", is_sink ? "SINK" : ""); + + intmax_t const row = (intmax_t) head.row - is_source; + intmax_t const col = (intmax_t) head.col - is_source; + uint32_t const head_length = head.length + is_source; + uint32_t const tail_length = tail.length + is_sink; + + intmax_t const offset = MIN((intmax_t) tail.row - row, (intmax_t) tail.col - col) - 1; + + uint32_t const head_offset = offset > 0 ? MIN(head_length, offset + 1) : 1; + uint32_t const tail_offset = offset < 0 ? MIN(tail_length, -offset) : 0; + + //printf(" %ld: (%u, %u)\n", offset, head_offset, tail_offset); + + if (head_offset > head_length || (tail_length > 0 && tail_offset >= tail_length)) + { + printf("NO EDGE\n"); + return 0; + } // if + + uint32_t const count = MIN(head_length - head_offset, tail_length - tail_offset - 1) + 1; + + *variant = (VA_Variant) {row + head_offset, tail.row + tail_offset, col + head_offset, tail.col + tail_offset}; + + printf(VAR_FMT " x %u\n", print_variant((*variant), observed), count); + return count; +} // edges2 + + +static size_t +bfs_traversal2(Graph2 const graph, size_t const len_obs, char const observed[static len_obs]) +{ + struct + { + uint32_t depth; + uint32_t next; + }* table = va_std_allocator.alloc(va_std_allocator.context, NULL, 0, sizeof(*table) * va_array_length(graph.nodes)); + + for (size_t i = 0; i < va_array_length(graph.nodes); ++i) + { + table[i].depth = 0; + table[i].next = GVA_NULL; + } // for + uint32_t head = graph.source; + uint32_t tail = graph.source; + + size_t count = 0; + printf("digraph{\nrankdir=LR\nedge[fontname=monospace]\nnode[fixedsize=true,fontname=serif,shape=circle,width=1]\nsi[label=\"\",shape=none,width=0]\n"); + printf("si->s%u\n", graph.source); + + //printf(" \"edges\": [\n"); + while (head != GVA_NULL) + { + uint32_t len = graph.nodes[head].length; + //printf("pop %u\n", head); + for (uint32_t i = head; i != GVA_NULL; i = graph.nodes[i].lambda) + { + printf("s%u[label=\"(%u, %u, %u)\"%s]\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, graph.nodes[i].edges == GVA_NULL && graph.nodes[i].lambda == GVA_NULL ? ",peripheries=2" : ""); + if (i != head) + { + len += graph.nodes[i].length; + //printf("lambda %u\n", i); + } // if + for (uint32_t j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) + { + if (count > 0) + { + //printf(",\n"); + } // if + count += 1; + VA_Variant variant; + uint32_t const count2 = edges2(((VA_LCS_Node) {graph.nodes[head].row, graph.nodes[head].col, len, 0, 0}), + ((VA_LCS_Node) {graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length, 0, 0}), + graph.nodes[head].row == graph.nodes[graph.source].row && graph.nodes[head].col == graph.nodes[graph.source].col, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, len_obs, observed, &variant); + + for (uint32_t k = 0; k < count2; ++k) + { + printf("s%u->s%u[label=\"" VAR_FMT "\"]\n", head, graph.edges[j].tail, print_variant(variant, observed)); + //printf(" {\"head\": \"s%u\", \"tail\": \"s%u\", \"variant\": \"" VAR_FMT "\"}%s", head, graph.edges[j].tail, print_variant(variant, observed), k < count2 - 1 ? ",\n" : ""); + variant.start += 1; + variant.end += 1; + variant.obs_start += 1; + variant.obs_end += 1; + } // for + + if (table[graph.edges[j].tail].depth > 0) + { + //printf("skip %u\n", graph.edges[j].tail); + continue; + } // if + + //printf("push %u\n", graph.edges[j].tail); + table[graph.edges[j].tail].depth = table[i].depth + 1; + table[tail].next = graph.edges[j].tail; + tail = graph.edges[j].tail; + } // for + } // for + head = table[head].next; + + /* + printf(" # \tdepth\tnext\n"); + for (size_t i = 0; i < va_array_length(graph.nodes); ++i) + { + printf("%3zu:\t%5u\t%4d\n", i, table[i].depth, table[i].next); + } // for + printf("head: %d\ntail: %d\n", head, tail); + */ + } // while + + printf("}\n"); + //printf("\n ],\n"); + + table = va_std_allocator.alloc(va_std_allocator.context, table, sizeof(*table) * va_array_length(graph.nodes), 0); + + return count; +} // bfs_traversal2 + + +Graph2 +build(size_t const len_ref, char const reference[static len_ref], + size_t const len_obs, char const observed[static len_obs], + size_t const shift) +{ + printf("build!\n"); + VA_LCS_Node** lcs_nodes = NULL; + size_t const len_lcs = va_edit(va_std_allocator, len_ref, reference, len_obs, observed, &lcs_nodes); + + Graph2 graph = {NULL, NULL, GVA_NULL}; + + if (len_lcs == 0 || lcs_nodes == NULL) + { + fprintf(stderr, "Trivial graph\n"); + return graph; + } // if + + VA_LCS_Node* last = &lcs_nodes[len_lcs - 1][va_array_length(lcs_nodes[len_lcs - 1]) - 1]; + if (last->row + last->length != len_ref + shift || last->col + last->length != len_obs + shift) + { + va_array_append(va_std_allocator, lcs_nodes[len_lcs - 1], + ((VA_LCS_Node) {.row = len_ref + shift, .col = len_obs + shift, .length = 0})); + last = &lcs_nodes[len_lcs - 1][va_array_length(lcs_nodes[len_lcs - 1]) - 1]; + } // if + va_array_append(va_std_allocator, graph.nodes, ((Node) {last->row, last->col, last->length, GVA_NULL, GVA_NULL})); + last->idx = va_array_length(graph.nodes) - 1; + printf("MAKE NODE %u: (%u, %u, %u)\n", last->idx, last->row, last->col, last->length); + last->incoming = -1; + + /* + fprintf(stderr, "%zu\n", len_lcs); + for (size_t i = 0; i < len_lcs; ++i) + { + fprintf(stderr, "%zu: ", i); + for (size_t j = 0; j < va_array_length(lcs_nodes[i]); ++j) + { + fprintf(stderr, "(%u, %u, %u) ", lcs_nodes[i][j].row, lcs_nodes[i][j].col, lcs_nodes[i][j].length); + } // for + fprintf(stderr, "\n"); + } // for + */ + + VA_LCS_Node source = {shift, shift, 0, -1, GVA_NULL}; + bool found_source = false; + bool is_sink = true; + for (size_t t_i = 0; t_i < len_lcs; ++t_i) + { + size_t const t_len = va_array_length(lcs_nodes[len_lcs - t_i - 1]); + for (size_t t_j = 0; t_j < t_len; ++t_j) + { + VA_LCS_Node* const tail = &lcs_nodes[len_lcs - t_i - 1][t_len - t_j - 1]; + if (tail->idx == GVA_NULL) + { + // sink unreachable from tail, do not add to graph + continue; + } // if + printf("%u %u %u %d\n", tail->row, tail->col, tail->length, tail->incoming); + + uint32_t split_idx = tail->idx; + for (size_t h_i = 0; h_i < MIN(len_lcs - t_i, tail->length + 1); ++h_i) + { + size_t const h_len = h_i == 0 ? t_len - t_j - 1: va_array_length(lcs_nodes[len_lcs - t_i - h_i - 1]); + //printf(" level: %zu with %zu nodes\n", len_lcs - t_i - h_i - 1, h_len); + for (size_t h_j = 0; h_j < h_len; ++h_j) + { + VA_LCS_Node* head = &lcs_nodes[len_lcs - t_i - h_i - 1][h_j]; + + printf(" %u %u %u: ", head->row, head->col, head->length); + + if (head->row + head->length + h_i > tail->row + tail->length || + head->col + head->length + h_i > tail->col + tail->length) + { + if (tail->row + tail->length > head->row + head->length + h_i || + tail->col + tail->length > head->col + head->length + h_i) + { + printf("--\n"); // FIXME: skip the remainder of this (head) level + } // if + else + { + printf("CONVERSE\n"); + if (head->idx != GVA_NULL && edges2(*tail, *head, tail->row == shift && tail->col == shift, + false, len_obs, observed, &(VA_Variant) {0, 0, 0, 0})) + { + va_array_append(va_std_allocator, graph.edges, ((Edge2) {head->idx, graph.nodes[tail->idx].edges})); + graph.nodes[tail->idx].edges = va_array_length(graph.edges) - 1; + printf("MAKE EDGE\n"); + } + } // else + } // if + else + { + VA_Variant variant; + uint32_t const count = edges2(*head, *tail, head->row == shift && head->col == shift, is_sink, len_obs, observed, &variant); + if (count > 0) + { + if (head->idx == GVA_NULL) + { + va_array_append(va_std_allocator, graph.nodes, ((Node) {head->row, head->col, head->length, GVA_NULL, GVA_NULL})); + head->idx = va_array_length(graph.nodes) - 1; + printf("MAKE NODE %u: (%u, %u, %u)\n", head->idx, head->row, head->col, head->length); + if (head->row == shift && head->col == shift) + { + // head is the source + source = *head; + graph.source = source.idx; + found_source = true; + } // if + } // if + head->incoming = MIN(head->incoming, variant.start); + if (variant.end + count > tail->incoming) + { + printf("SPLIT %u %u %u @ %u\n", tail->row, tail->col, tail->length, variant.end + count - 1); + uint32_t const split_len = tail->incoming - tail->row; + va_array_append(va_std_allocator, graph.nodes, + ((Node) {tail->row, tail->col, split_len, GVA_NULL, tail->idx})); + split_idx = va_array_length(graph.nodes) - 1; + graph.nodes[tail->idx].row += split_len; + graph.nodes[tail->idx].col += split_len; + graph.nodes[tail->idx].length -= split_len; + tail->incoming = variant.end + count; + printf(VAR_FMT "\n", print_variant(variant, observed)); + if (variant.start < variant.end + count - 1) + { + // incoming edge + printf("INCOMING -> BOTH\n"); + va_array_append(va_std_allocator, graph.edges, ((Edge2) {split_idx, graph.nodes[head->idx].edges})); + graph.nodes[head->idx].edges = va_array_length(graph.edges) - 1; + } // if + uint32_t head_head = GVA_NULL; + uint32_t head_tail = GVA_NULL; + uint32_t tail_head = GVA_NULL; + uint32_t tail_tail = GVA_NULL; + for (uint32_t i = graph.nodes[tail->idx].edges; i != GVA_NULL; i = graph.edges[i].next) + { + // outgoing edges + VA_Variant var; + uint32_t const count2 = edges2(*tail, (VA_LCS_Node) {graph.nodes[graph.edges[i].tail].row, graph.nodes[graph.edges[i].tail].col, graph.nodes[graph.edges[i].tail].length, 0, 0}, tail->row == shift && tail->col == shift, graph.nodes[graph.edges[i].tail].edges == GVA_NULL && graph.nodes[graph.edges[i].tail].lambda == GVA_NULL, len_obs, observed, &var); + printf(" -> %u: " VAR_FMT " x %u ::\n", graph.edges[i].tail, print_variant(var, observed), count2); + if (var.start > variant.end + count - 1) + { + printf(" -> TAIL\n"); + if (tail_tail != GVA_NULL) + { + graph.edges[tail_tail].next = i; + } // if + if (tail_head == GVA_NULL) + { + tail_head = i; + } // if + tail_tail = i; + } // if + else if (var.end + count2 - 1 < variant.end + count) + { + printf(" -> HEAD\n"); + if (head_tail != GVA_NULL) + { + graph.edges[head_tail].next = i; + } // if + if (head_head == GVA_NULL) + { + head_head = i; + } // if + head_tail = i; + } // if + else + { + printf(" -> BOTH\n"); + if (tail_tail != GVA_NULL) + { + graph.edges[tail_tail].next = i; + } // if + if (tail_head == GVA_NULL) + { + tail_head = i; + } // if + tail_tail = i; + va_array_append(va_std_allocator, graph.edges, ((Edge2) {graph.edges[i].tail, head_head})); + head_head = va_array_length(graph.edges) - 1; + } // else + } // for + if (head_tail != GVA_NULL) + { + graph.edges[head_tail].next = GVA_NULL; + } // if + if (tail_tail != GVA_NULL) + { + graph.edges[tail_tail].next = GVA_NULL; + } // if + graph.nodes[split_idx].edges = head_head; + graph.nodes[tail->idx].edges = tail_head; + } // if + va_array_append(va_std_allocator, graph.edges, ((Edge2) {tail->idx, graph.nodes[head->idx].edges})); + graph.nodes[head->idx].edges = va_array_length(graph.edges) - 1; + printf("MAKE EDGE\n"); + } // if + else + { + // FIXME: skip the remainder of this (head) level + } // else + } // else + } // for h_j + is_sink = false; + tail->idx = split_idx; + } // for h_i + if (!found_source && tail->length >= len_lcs - t_i) + { + if (source.idx == GVA_NULL) + { + va_array_append(va_std_allocator, graph.nodes, ((Node) {source.row, source.col, source.length, GVA_NULL, GVA_NULL})); + source.idx = va_array_length(graph.nodes) - 1; + printf("MAKE NODE %u: (%u, %u, %u)\n", source.idx, source.row, source.col, source.length); + graph.source = source.idx; + } // if + printf("SOURCE %u %u %u: ", source.row, source.col, source.length); + // is this edges2 check always true? + if (edges2(source, *tail, true, is_sink, len_obs, observed, &(VA_Variant) {0, 0, 0, 0})) + { + va_array_append(va_std_allocator, graph.edges, ((Edge2) {tail->idx, graph.nodes[source.idx].edges})); + graph.nodes[source.idx].edges = va_array_length(graph.edges) - 1; + printf("MAKE EDGE\n"); + } // if + } // if + } // for t_j + // dealloc lcs pos level + lcs_nodes[len_lcs - t_i - 1] = va_array_destroy(va_std_allocator, lcs_nodes[len_lcs - t_i - 1]); + } // for t_i + + // deallocation + lcs_nodes = va_std_allocator.alloc(va_std_allocator.context, lcs_nodes, len_lcs, 0); + + printf("#nodes: %zu\n#edges: %zu\n", va_array_length(graph.nodes), va_array_length(graph.edges)); + printf("source: %u\n", graph.source); + for (size_t i = 0; i < va_array_length(graph.nodes); ++i) + { + printf("%zu: (%u, %u, %u):\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length); + if (graph.nodes[i].lambda != GVA_NULL) + { + printf(" (%u, %u, %u): lambda\n", graph.nodes[graph.nodes[i].lambda].row, graph.nodes[graph.nodes[i].lambda].col, graph.nodes[graph.nodes[i].lambda].length); + } // if + for (uint32_t j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) + { + printf(" (%u, %u, %u): ", graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length); + edges2(((VA_LCS_Node) {graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, 0, 0}), + ((VA_LCS_Node) {graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length, 0, 0}), + graph.nodes[i].row == shift && graph.nodes[i].col == shift, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, len_obs, observed, &(VA_Variant) {0, 0, 0, 0}); + } // for + } // for + + + bfs_traversal2(graph, len_obs, observed); + + return graph; +} // build \ No newline at end of file diff --git a/src/main.c b/src/main.c index 544765f..f6520ed 100644 --- a/src/main.c +++ b/src/main.c @@ -1,24 +1,18 @@ #include // bool, false, true #include // NULL, size_t -#include // intmax_t, uint32_t +#include // uint32_t #include // stderr, fprintf, printf #include // EXIT_*, atoi, rand, srand -#include // strlen, strncmp - -#include "../include/alloc.h" // VA_Allocator +#include // strlen #include "../include/array.h" // va_array_* #include "../include/edit.h" // va_edit +#include "../include/graph.h" // Graph, to_dot #include "../include/std_alloc.h" // va_std_allocator -#include "../include/variant.h" // VA_Variant - -#define MAX(lhs, rhs) (((lhs) > (rhs)) ? (lhs) : (rhs)) -#define MIN(lhs, rhs) (((lhs) < (rhs)) ? (lhs) : (rhs)) #define print_variant(variant, observed) variant.start, variant.end, (int) variant.obs_end - variant.obs_start, observed + variant.obs_start #define VAR_FMT "%u:%u/%.*s" - static uint32_t const GVA_NULL = UINT32_MAX; @@ -36,798 +30,6 @@ random_sequence(size_t const min, size_t const max, char sequence[static max]) } // random_sequence -typedef struct -{ - uint32_t tail; - uint32_t next; - VA_Variant variant; -} Edge; - - -typedef struct -{ - uint32_t tail; - uint32_t next; -} Edge2; - - -typedef struct -{ - uint32_t row; - uint32_t col; - uint32_t length; - uint32_t edges; - uint32_t lambda; -} Node; - - -typedef struct -{ - Node* nodes; - Edge* edges; - VA_Variant supremal; - uint32_t source; -} Graph; - - -typedef struct -{ - Node* nodes; - Edge2* edges; - uint32_t source; -} Graph2; - - -static inline size_t -add_node(VA_Allocator const allocator, Graph* const graph, size_t const row, size_t const col, size_t const length) -{ - va_array_append(allocator, graph->nodes, ((Node) {row, col, length, -1, -1})); - return va_array_length(graph->nodes) - 1; -} // add_node - - -static inline size_t -add_edge(VA_Allocator const allocator, Graph* const graph, size_t const tail, size_t const next, VA_Variant const variant) -{ - va_array_append(allocator, graph->edges, ((Edge) {tail, next, variant})); - return va_array_length(graph->edges) - 1; -} // add_edge - - -static inline void -destroy(VA_Allocator const allocator, Graph* const graph) -{ - graph->nodes = va_array_destroy(allocator, graph->nodes); - graph->edges = va_array_destroy(allocator, graph->edges); -} // destroy - - -static Graph -build_graph(VA_Allocator const allocator, - size_t const len_ref, size_t const len_obs, - size_t const len_lcs, VA_LCS_Node* lcs_nodes[static len_lcs], - size_t const shift) -{ - Graph graph = {.nodes = NULL, .edges = NULL}; - - if (len_lcs == 0 || lcs_nodes == NULL) - { - graph.source = add_node(allocator, &graph, shift, shift, 0); - if (len_ref == 0 && len_obs == 0) - { - graph.supremal = (VA_Variant) {0, 0, 0, 0}; - return graph; - } // if - uint32_t const sink = add_node(allocator, &graph, len_ref, len_obs, 0); - graph.supremal = (VA_Variant) {shift, shift + len_ref, 0, len_obs}; - graph.nodes[graph.source].edges = add_edge(allocator, &graph, sink, -1, graph.supremal); - return graph; - } // if - - VA_LCS_Node sink = lcs_nodes[len_lcs - 1][va_array_length(lcs_nodes[len_lcs - 1]) - 1]; - if (sink.row + sink.length == len_ref + shift && sink.col + sink.length == len_obs + shift) - { - va_array_header(lcs_nodes[len_lcs - 1])->length -= 1; // del - sink.length += 1; - } // if - else - { - sink = (VA_LCS_Node) {.row = len_ref + shift, .col = len_obs + shift, .length = 1}; - } // else - - uint32_t max_sink = 0; - sink.idx = add_node(allocator, &graph, sink.row, sink.col, sink.length - 1); - printf("MAKE NODE %u: (%u, %u, %u)\n", sink.idx, sink.row, sink.col, sink.length - 1); - size_t here = 0; - VA_LCS_Node* const heads = lcs_nodes[len_lcs - 1]; - for (size_t i = 0; i < va_array_length(heads); ++i) - { - if (heads[i].row + heads[i].length < sink.row + sink.length && heads[i].col + heads[i].length < sink.col + sink.length) - { - VA_Variant const variant = {heads[i].row + heads[i].length, sink.row + sink.length - 1, heads[i].col + heads[i].length - shift, sink.col + sink.length - 1 - shift}; - - max_sink = MAX(max_sink, sink.row + sink.length - 1); - heads[i].idx = add_node(allocator, &graph, heads[i].row, heads[i].col, heads[i].length); - printf("MAKE NODE %u: (%u, %u, %u)\n", heads[i].idx, heads[i].row, heads[i].col, heads[i].length); - graph.nodes[heads[i].idx].edges = add_edge(allocator, &graph, sink.idx, graph.nodes[heads[i].idx].edges, variant); - printf("MAKE EDGE (%u %u %u) -> (%u %u %u): " VAR_FMT "\n", heads[i].row, heads[i].col, heads[i].length, sink.row, sink.col, sink.length, print_variant(variant, "0123456789")); - here = i + 1; - } // if - } // for - - if (sink.length > 1) - { - sink.length -= 1; - sink.incoming = len_lcs - 1; - va_array_insert(allocator, lcs_nodes[len_lcs - 1], sink, here); - printf("INSERT (%u %u %u) here: %zu\n", sink.row, sink.col, sink.length, here); - } // if - - for (size_t i = len_lcs - 1; i >= 1; --i) - { - for (size_t j = 0; j < va_array_length(lcs_nodes[i]); ++j) - { - if (lcs_nodes[i][j].idx == GVA_NULL) - { - continue; - } // if - - here = 0; - VA_LCS_Node const tail = lcs_nodes[i][j]; - VA_LCS_Node* const heads = lcs_nodes[i - 1]; - for (size_t k = 0; k < va_array_length(heads); ++k) - { - if (heads[k].row + heads[k].length < tail.row + tail.length && heads[k].col + heads[k].length < tail.col + tail.length) - { - max_sink = MAX(max_sink, tail.row + tail.length - 1); - - VA_Variant const variant = {heads[k].row + heads[k].length, tail.row + tail.length - 1, heads[k].col + heads[k].length - shift, tail.col + tail.length - 1 - shift}; - - if (heads[k].incoming == i) - { - printf("SPLIT at %zu\n", i); - uint32_t const split_idx = heads[k].idx; - heads[k].idx = add_node(allocator, &graph, heads[k].row, heads[k].col, heads[k].length); - printf("MAKE NODE %u: (%u, %u, %u)\n", heads[k].idx, heads[k].row, heads[k].col, heads[k].length); - heads[k].incoming = 0; - - // lambda-edge - graph.nodes[heads[k].idx].lambda = split_idx; - - graph.nodes[split_idx].row += heads[k].length; - graph.nodes[split_idx].col += heads[k].length; - graph.nodes[split_idx].length -= heads[k].length; - printf("RELABEL NODE %u: (%u, %u, %u)\n", split_idx, graph.nodes[split_idx].row,graph.nodes[split_idx].col, graph.nodes[split_idx].length); - } // if - else - { - if (heads[k].idx == GVA_NULL) - { - heads[k].idx = add_node(allocator, &graph, heads[k].row, heads[k].col, heads[k].length); - printf("MAKE NODE %u: (%u, %u, %u)\n", heads[k].idx, heads[k].row, heads[k].col, heads[k].length); - } // if - } // else - - graph.nodes[heads[k].idx].edges = add_edge(allocator, &graph, tail.idx, graph.nodes[heads[k].idx].edges, variant); - printf("MAKE EDGE (%u %u %u) -> (%u %u %u): " VAR_FMT "\n", heads[k].row, heads[k].col, heads[k].length, tail.row, tail.col, tail.length, print_variant(variant, "0123456789")); - - here = k + 1; - } // if - } // for - - if (lcs_nodes[i][j].length > 1) - { - lcs_nodes[i][j].length -= 1; - if (here > 0) - { - lcs_nodes[i][j].incoming = i; - } // if - va_array_insert(allocator, lcs_nodes[i - 1], lcs_nodes[i][j], here); - printf("INSERT (%u %u %u) here: %zu\n", lcs_nodes[i][j].row, lcs_nodes[i][j].col, lcs_nodes[i][j].length, here); - } // if - } // for - lcs_nodes[i] = va_array_destroy(allocator, lcs_nodes[i]); - } // for - - VA_LCS_Node source = lcs_nodes[0][0]; - - size_t start = 0; - if (source.row == shift && source.col == shift) - { - start = 1; - } // if - else - { - source = (VA_LCS_Node) {.row = shift, .col = shift, .length = 0}; - source.idx = add_node(allocator, &graph, source.row, source.col, source.length); - printf("MAKE NODE %u: (%u, %u, %u)\n", source.idx, source.row, source.col, source.length); - } // else - - for (size_t i = start; i < va_array_length(lcs_nodes[0]); ++i) - { - if (lcs_nodes[0][i].idx == GVA_NULL) - { - continue; - } // if - - if (source.row < lcs_nodes[0][i].row + lcs_nodes[0][i].length && source.col < lcs_nodes[0][i].col + lcs_nodes[0][i].length) - { - max_sink = MAX(max_sink, lcs_nodes[0][i].row + lcs_nodes[0][i].length - 1); - - VA_Variant const variant = {source.row, lcs_nodes[0][i].row + lcs_nodes[0][i].length - 1, source.col - shift, lcs_nodes[0][i].col + lcs_nodes[0][i].length - 1 - shift}; - - graph.nodes[source.idx].edges = add_edge(allocator, &graph, lcs_nodes[0][i].idx, graph.nodes[source.idx].edges, variant); - printf("MAKE EDGE (%u %u %u) -> (%u %u %u): " VAR_FMT "\n", source.row, source.col, source.length, lcs_nodes[0][i].row, lcs_nodes[0][i].col, lcs_nodes[0][i].length, print_variant(variant, "0123456789")); - } // if - } // for - lcs_nodes[0] = va_array_destroy(allocator, lcs_nodes[0]); - lcs_nodes = allocator.alloc(allocator.context, lcs_nodes, len_lcs * sizeof(*lcs_nodes), 0); - - uint32_t min_source = max_sink; - for (uint32_t i = graph.nodes[source.idx].edges; i != (uint32_t) -1; i = graph.edges[i].next) - { - min_source = MIN(min_source, graph.edges[i].variant.start); - } // for - uint32_t const min_offset = min_source - graph.nodes[source.idx].row; - - graph.nodes[source.idx].row += min_offset; - graph.nodes[source.idx].col += min_offset; - graph.nodes[source.idx].length -= min_offset; - graph.nodes[sink.idx].length -= graph.nodes[sink.idx].row + graph.nodes[sink.idx].length - max_sink; - - graph.supremal = (VA_Variant) {min_source, max_sink, graph.nodes[source.idx].col - shift, graph.nodes[sink.idx].col + graph.nodes[sink.idx].length - shift}; - graph.source = source.idx; - - return graph; -} // build_graph - - -static void -to_dot(Graph const graph, size_t const len_obs, char const observed[static len_obs]) -{ - fprintf(stderr, "digraph{\nrankdir=LR\nedge[fontname=monospace]\nnode[fixedsize=true,fontname=serif,shape=circle,width=1]\nsi[label=\"\",shape=none,width=0]\nsi->s%u\n", graph.source); - for (uint32_t i = 0; i < va_array_length(graph.nodes); ++i) - { - fprintf(stderr, "s%u[label=\"(%u, %u, %u)\"%s]\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, graph.nodes[i].edges == (uint32_t) -1 ? ",peripheries=2" : ""); - if (graph.nodes[i].lambda != (uint32_t) -1) - { - fprintf(stderr, "s%u->s%u[label=\"λ\",style=\"dashed\"]\n", i, graph.nodes[i].lambda); - } // if - for (uint32_t j = graph.nodes[i].edges; j != (uint32_t) -1; j = graph.edges[j].next) - { - fprintf(stderr, "s%u->s%u[label=\"%u:%u/%.*s\"]\n", i, graph.edges[j].tail, graph.edges[j].variant.start, graph.edges[j].variant.end, (int) graph.edges[j].variant.obs_end - graph.edges[j].variant.obs_start, observed + graph.edges[j].variant.obs_start); - } // for - } // for - fprintf(stderr, "}\n"); -} // to_dot - - -typedef struct -{ - uint32_t post; - uint32_t rank; - uint32_t edge; - uint32_t start; - uint32_t end; - uint32_t next; -} Post_Table; - - -static uint32_t -intersection(uint32_t lhs, uint32_t rhs, size_t const length, Post_Table const visited[static length]) -{ - if (lhs == (uint32_t) -1) - { - return rhs; - } // if - while (lhs != rhs) - { - while (visited[lhs].rank > visited[rhs].rank) - { - lhs = visited[lhs].post; - } // while - while (visited[rhs].rank > visited[lhs].rank) - { - rhs = visited[rhs].post; - } // while - } // while - return lhs; -} // intersection - - -static void -local_supremal(VA_Allocator const allocator, Graph const graph, size_t const len_obs, char const observed[static len_obs]) -{ - uint32_t const length = va_array_length(graph.nodes); - Post_Table* visited = allocator.alloc(allocator.context, NULL, 0, sizeof(*visited) * length); - if (visited == NULL) - { - return; - } // if - - for (uint32_t i = 0; i < length; ++i) - { - visited[i].post = -1; - visited[i].start = 0; - visited[i].end = -1; - visited[i].next = -1; - } // for - - uint32_t rank = 0; - uint32_t head = graph.source; - visited[head].edge = graph.nodes[head].edges; - - while (head != (uint32_t) -1) - { - uint32_t edge = visited[head].edge; - if (edge == (uint32_t) -1) - { - uint32_t const lambda = graph.nodes[head].lambda; - if (lambda != (uint32_t) -1) - { - if (visited[lambda].next == (uint32_t) -1) - { - visited[lambda].edge = graph.nodes[lambda].edges; - visited[lambda].next = head; - head = lambda; - continue; - } // if - visited[head].post = intersection(visited[head].post, lambda, length, visited); - } // if - - visited[head].rank = rank; - rank += 1; - head = visited[head].next; - continue; - } // if - - if (visited[graph.edges[edge].tail].next != (uint32_t) -1) - { - visited[head].post = intersection(visited[head].post, graph.edges[edge].tail, length, visited); - visited[head].edge = graph.edges[edge].next; - } // if - while (edge != (uint32_t) -1) - { - uint32_t const tail = graph.edges[edge].tail; - visited[head].end = MIN(visited[head].end, graph.edges[edge].variant.start); - visited[tail].start = MAX(visited[tail].start, graph.edges[edge].variant.end); - if (visited[tail].next == (uint32_t) -1) - { - visited[tail].edge = graph.nodes[tail].edges; - visited[tail].next = head; - head = tail; - break; - } // if - visited[head].post = intersection(visited[head].post, tail, length, visited); - edge = graph.edges[edge].next; - } // while - } // while - - /* - printf(" # \tpost\trank\tstart\tend\n"); - for (uint32_t i = 0; i < length; ++i) - { - printf("%2u:\t%4d\t%4u\t%5u\t%3d\n", i, visited[i].post, visited[i].rank, visited[i].start, visited[i].end); - } // for - */ - - head = graph.source; - uint32_t shift = 0; - for (uint32_t tail = visited[head].post; tail != (uint32_t) -1; head = tail, tail = visited[head].post) - { - uint32_t const start = visited[head].end; - uint32_t const end = visited[tail].start; - VA_Variant const variant = {start, end, graph.nodes[head].col + start - graph.nodes[head].row - shift, graph.nodes[tail].col + end - graph.nodes[tail].row - shift}; - if (head != graph.source) - { - printf(",\n"); - } // if - printf(" \"" VAR_FMT "\"", print_variant(variant, observed)); - } // for - - visited = allocator.alloc(allocator.context, visited, sizeof(*visited) * length, 0); -} // local_supremal - - -typedef struct -{ - uint32_t lca; - uint32_t rank; - uint32_t depth; - uint32_t start; - uint32_t end; - uint32_t prev; - uint32_t next; -} LCA_Table; - - -static inline uint32_t -lca(uint32_t* const start, uint32_t lhs, uint32_t rhs, size_t const length, LCA_Table const visited[static length]) -{ - uint32_t lhs_start = *start; - uint32_t rhs_start = *start; - while (lhs != rhs) - { - fprintf(stderr, " lca %u (%d), %u (%d)\n", lhs, lhs_start, rhs, rhs_start); - - while (visited[lhs].rank > visited[rhs].rank) - { - fprintf(stderr, " left\n"); - lhs_start = visited[lhs].start; - lhs = visited[lhs].lca; - } // if - while (visited[rhs].rank > visited[lhs].rank) - { - fprintf(stderr, " right\n"); - rhs_start = visited[rhs].start; - rhs = visited[rhs].lca; - } // if - } // while - *start = MIN(lhs_start, rhs_start); - return lhs; -} // lca - - -static void -print_lca_table(size_t const length, LCA_Table const visited[static length], uint32_t const head, uint32_t const tail) -{ - fprintf(stderr, " # \tlca\trank\tdepth\tstart\tend\tprev\tnext\n"); - for (uint32_t i = 0; i < length; ++i) - { - fprintf(stderr, "%2u:\t%3d\t%4d\t%5d\t%5d\t%3d\t%4d\t%4d\n", i, visited[i].lca, visited[i].rank, visited[i].depth, visited[i].start, visited[i].end, visited[i].prev, visited[i].next); - } // for - fprintf(stderr, "head: %d\ntail: %d\n", head, tail); -} // print_lca_table - - -static void -canonical(VA_Allocator const allocator, Graph const graph, size_t const len_obs, char const observed[static len_obs]) -{ - uint32_t const length = va_array_length(graph.nodes); - LCA_Table* visited = allocator.alloc(allocator.context, NULL, 0, sizeof(*visited) * length); - if (visited == NULL) - { - return; - } // if - - for (uint32_t i = 0; i < length; ++i) - { - visited[i].depth = -1; - - visited[i].lca = -1; - visited[i].rank = -1; - visited[i].start = -1; - visited[i].end = -1; - visited[i].prev = -1; - visited[i].next = -1; - - } // for - - uint32_t sink = -1; - visited[graph.source] = (LCA_Table) {-1, 0, 0, -1, -1, -1, -1}; - uint32_t rank = 1; - // main loop over a queue - for (uint32_t head = graph.source, tail = graph.source; head != (uint32_t) -1; head = visited[head].next) - { - fprintf(stderr, "pop %u @ %u\n", head, visited[head].depth); - - if (graph.nodes[head].edges == (uint32_t) -1) - { - fprintf(stderr, " sink\n"); - sink = head; - continue; - } // if - - uint32_t const lambda = graph.nodes[head].lambda; - if (lambda != (uint32_t) -1) - { - if (visited[lambda].depth == (uint32_t) -1) - { - // add lambda in stack order - fprintf(stderr, " push lambda %u @ %u\n", lambda, visited[head].depth); - - visited[visited[head].next].prev = lambda; - visited[lambda] = (LCA_Table) {head, rank, visited[head].depth, -1, -1, head, visited[head].next}; - rank += 1; - visited[head].next = lambda; - } // if - else if (visited[lambda].depth == visited[head].depth) - { - fprintf(stderr, " update lambda %u @ %u\n", lambda, visited[head].depth); - fprintf(stderr, " lca(%u, %u)\n", visited[lambda].lca, head); - visited[lambda].lca = lca(&visited[lambda].start, visited[lambda].lca, head, length, visited); - - // FIXME: what is correct here? - // AGGCCG CGCAGCCTC ignores the common end position - // ACAGGA CAAGGCG - // TAATTGGTAG CTATTCAG needs the common end position - // TTAAG TAACA - - //visited[lambda].end = graph.nodes[head].row; // this simulates the empty variant on a lambda edge - - fprintf(stderr, " = %u (%u:%u)\n", visited[lambda].lca, visited[lambda].start, visited[lambda].end); - } // if - else if (visited[head].next == lambda) - { - fprintf(stderr, " improve lambda in place %u @ %u\n", lambda, visited[head].depth); - visited[lambda] = (LCA_Table) {head, visited[lambda].rank, visited[head].depth, -1, -1, visited[lambda].prev, visited[lambda].next}; - } // if - else - { - fprintf(stderr, " improve lambda %u @ %u\n", lambda, visited[head].depth); - - if (lambda == tail) - { - tail = visited[lambda].prev; - } // if - else - { - visited[visited[lambda].next].prev = visited[lambda].prev; - } // else - visited[visited[head].next].prev = lambda; - visited[visited[lambda].prev].next = visited[lambda].next; - visited[lambda] = (LCA_Table) {head, visited[lambda].rank, visited[head].depth, -1, -1, head, visited[head].next}; - visited[head].next = lambda; - } // else - - //print_lca_table(length, visited, head, tail); - - } // if - - for (uint32_t i = graph.nodes[head].edges; i != (uint32_t) -1; i = graph.edges[i].next) - { - uint32_t const edge_tail = graph.edges[i].tail; - if (visited[edge_tail].depth == (uint32_t) -1) - { - // add regular successors in queue order - fprintf(stderr, " push %u @ %u\n", edge_tail, visited[head].depth + 1); - visited[edge_tail] = (LCA_Table) {head, rank, visited[head].depth + 1, graph.edges[i].variant.start, graph.edges[i].variant.end, tail, -1}; - rank += 1; - visited[tail].next = edge_tail; - tail = edge_tail; - } // if - else if (visited[edge_tail].depth - 1 == visited[head].depth) - { - fprintf(stderr, " update %u @ %u\n", edge_tail, visited[edge_tail].depth); - fprintf(stderr, " lca(%u, %u)\n", visited[edge_tail].lca, head); - visited[edge_tail].start = MIN(visited[edge_tail].start, graph.edges[i].variant.start); - visited[edge_tail].lca = lca(&visited[edge_tail].start, visited[edge_tail].lca, head, length, visited); - visited[edge_tail].end = MAX(visited[edge_tail].end, graph.edges[i].variant.end); - fprintf(stderr, " = %u (%u:%u)\n", visited[edge_tail].lca, visited[edge_tail].start, visited[edge_tail].end); - } // if - else - { - fprintf(stderr, " skip %u @ %u\n", edge_tail, visited[edge_tail].depth); - } // else - - //print_lca_table(length, visited, head, tail); - } // for - } // for - - print_lca_table(length, visited, -1, -1); - - // the canonical variant is given in the reverse order (for now): the Python checker needs to reverse this list - for (uint32_t tail = sink; tail != (uint32_t) -1; tail = visited[tail].lca) - { - uint32_t const head = visited[tail].lca; - if (head != (uint32_t) - 1 && visited[tail].start != (uint32_t) -1) - { - // we need to skip lambda edges: start && end == -1 - uint32_t const start_offset = visited[tail].start - graph.nodes[head].row; - uint32_t const end_offset = visited[tail].end - graph.nodes[tail].row; - VA_Variant const variant = {visited[tail].start, visited[tail].end, graph.nodes[head].col + start_offset, graph.nodes[tail].col + end_offset}; - - if (tail != sink) - { - printf(",\n"); - } // if - printf(" \"" VAR_FMT "\"", print_variant(variant, observed)); - } // if - } // while - - visited = allocator.alloc(allocator.context, visited, sizeof(*visited) * length, 0); -} // canonical - - -static size_t -bfs_traversal(VA_Allocator const allocator, Graph const graph, size_t const len_obs, char const observed[static len_obs]) -{ - struct - { - uint32_t depth; - uint32_t next; - }* table = allocator.alloc(allocator.context, NULL, 0, sizeof(*table) * va_array_length(graph.nodes)); - - for (size_t i = 0; i < va_array_length(graph.nodes); ++i) - { - table[i].depth = 0; - table[i].next = -1; - } // for - uint32_t head = graph.source; - uint32_t tail = graph.source; - - size_t count = 0; - //printf("digraph{\nrankdir=LR\nedge[fontname=monospace]\nnode[fixedsize=true,fontname=serif,shape=circle,width=1]\nsi[shape=point,width=.1]\n"); - //printf("si->s%u\n", graph.source); - - printf(" \"edges\": [\n"); - while (head != (uint32_t) -1) - { - //printf("pop %u\n", head); - for (uint32_t i = head; i != (uint32_t) -1; i = graph.nodes[i].lambda) - { - //printf("s%u[label=\"(%u, %u, %u)\"%s]\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, graph.nodes[i].edges == (uint32_t) -1 ? ",peripheries=2" : ""); - if (i != head) - { - //printf("lambda %u\n", i); - } // if - for (uint32_t j = graph.nodes[i].edges; j != (uint32_t) -1; j = graph.edges[j].next) - { - if (count > 0) - { - printf(",\n"); - } // if - count += 1; - printf(" {\"head\": \"s%u\", \"tail\": \"s%u\", \"variant\": \"%u:%u/%.*s\"}", head, graph.edges[j].tail, graph.edges[j].variant.start, graph.edges[j].variant.end, (int) graph.edges[j].variant.obs_end - graph.edges[j].variant.obs_start, observed + graph.edges[j].variant.obs_start); - //printf("s%u->s%u[label=\"%u:%u/%.*s\"]\n", head, graph.edges[j].tail, graph.edges[j].variant.start, graph.edges[j].variant.end, (int) graph.edges[j].variant.obs_end - graph.edges[j].variant.obs_start, observed + graph.edges[j].variant.obs_start); - - if (table[graph.edges[j].tail].depth > 0) - { - //printf("skip %u\n", graph.edges[j].tail); - continue; - } // if - - //printf("push %u\n", graph.edges[j].tail); - table[graph.edges[j].tail].depth = table[i].depth + 1; - table[tail].next = graph.edges[j].tail; - tail = graph.edges[j].tail; - } // for - } // for - head = table[head].next; - - /* - printf(" # \tdepth\tnext\n"); - for (size_t i = 0; i < va_array_length(graph.nodes); ++i) - { - printf("%3zu:\t%5u\t%4d\n", i, table[i].depth, table[i].next); - } // for - printf("head: %d\ntail: %d\n", head, tail); - */ - } // while - - printf("\n ],\n"); - - table = allocator.alloc(allocator.context, table, sizeof(*table) * va_array_length(graph.nodes), 0); - - return count; -} // bfs_traversal - - -static void -lambda_edges(Graph const graph, size_t const len_obs, char const observed[static len_obs]) -{ - printf(" \"edges\": [\n"); - size_t count = 0; - for (uint32_t i = 0; i < va_array_length(graph.nodes); ++i) - { - if (graph.nodes[i].lambda != (uint32_t) -1) - { - if (count > 0) - { - printf(",\n"); - } // if - count += 1; - printf(" {\"head\": \"s%u\", \"tail\": \"s%u\", \"variant\": \"lambda\"}", i, graph.nodes[i].lambda); - } // if - for (uint32_t j = graph.nodes[i].edges; j != (uint32_t) -1; j = graph.edges[j].next) - { - if (count > 0) - { - printf(",\n"); - } // if - count += 1; - printf(" {\"head\": \"s%u\", \"tail\": \"s%u\", \"variant\": \"%u:%u/%.*s\"}", i, graph.edges[j].tail, graph.edges[j].variant.start, graph.edges[j].variant.end, (int) graph.edges[j].variant.obs_end - graph.edges[j].variant.obs_start, observed + graph.edges[j].variant.obs_start); - } // for - } // for - printf("\n ],\n"); -} // lambda_edges - -/* -static void -to_json(Graph const graph, size_t const len_obs, char const observed[static len_obs], bool const lambda) -{ - printf("{\n \"source\": \"s%u\",\n \"nodes\": {\n", graph.source); - for (uint32_t i = 0; i < va_array_length(graph.nodes); ++i) - { - printf(" \"s%u\": {\"row\": %u, \"col\": %u, \"length\": %u}%s\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, i < va_array_length(graph.nodes) - 1 ? "," : ""); - } // for - printf(" },\n"); - if (lambda) { - lambda_edges(graph, len_obs, observed); - } else { - bfs_traversal(va_std_allocator, graph, len_obs, observed); - } - printf(" \"supremal\": \"%u:%u/%.*s\",\n", graph.supremal.start, graph.supremal.end, (int) graph.supremal.obs_end - graph.supremal.obs_start, observed + graph.supremal.obs_start); - printf(" \"local_supremal\": [\n"); - local_supremal(va_std_allocator, graph, len_obs, observed); - printf("\n ],\n"); - printf(" \"canonical\": [\n"); - canonical(va_std_allocator, graph, len_obs, observed); - printf("\n ]\n"); - printf("}"); -} // to_json -*/ - - -static size_t -edges(uint32_t const head_row, uint32_t const head_col, uint32_t const head_length, - uint32_t const tail_row, uint32_t const tail_col, uint32_t const tail_length, - bool const is_source, - size_t const len_obs, char const observed[static len_obs], - VA_Variant const edge) -{ - printf( - "(%u, %u, %u) -> (%u, %u, %u) source: %d\n", - head_row, head_col, head_length, - tail_row, tail_col, tail_length, - is_source - ); - //printf(VAR_FMT "\n", print_variant(edge, observed)); - printf("%u %u %u %u\n", edge.start, edge.end, edge.obs_start, edge.obs_end); - - ptrdiff_t const row = (ptrdiff_t) head_row - is_source; - ptrdiff_t const col = (ptrdiff_t) head_col - is_source; - uint32_t const length = head_length + is_source; - - printf("%zd, %zd, %u\n", row, col, length); - - ptrdiff_t const offset = MIN((ptrdiff_t) tail_row - row, (ptrdiff_t) tail_col - col) - 1; - uint32_t const head_start = offset > 0 ? MIN(offset, length - 1) : 0; - uint32_t const tail_start = offset < 0 ? MIN(-offset, tail_length - 1) : 0; - - uint32_t const count = MIN(length - head_start, tail_length - tail_start); - - printf(" %zd: (%u, %u) :: %u\n", offset, head_start, tail_start, count); - - if (offset < 0 && tail_length <= -offset) - { - printf(" X\n"); - return 0; - } // if - - bool found = false; - for (uint32_t j = 0; j < count; ++j) - { - VA_Variant const variant = - { - row + head_start + j + 1, - tail_row + tail_start + j, - col + head_start + j + 1, - tail_col + tail_start + j - }; - - if (edge.start == variant.start && edge.end == variant.end && - edge.obs_start == variant.obs_start && edge.obs_end == variant.obs_end) - { - found = true; - } // if - - printf(" (%u, %u) -> (%u, %u) :: " VAR_FMT "\n", //"%u %u %u %u\n", - head_row + head_start + j, head_col + head_start + j, - tail_row + tail_start + j, tail_col + tail_start + j, - print_variant(variant, observed) //, - //variant.start, variant.end, variant.obs_start, variant.obs_end - ); - } // for - - if (!found) - { - return -1; - } // if - return count; -} // edges - - static int check(size_t const len_ref, char const reference[static len_ref], size_t const len_obs, char const observed[static len_obs], @@ -923,384 +125,6 @@ check(size_t const len_ref, char const reference[static len_ref], } // check -static uint32_t -edges2(VA_LCS_Node const head, VA_LCS_Node const tail, - bool const is_source, bool const is_sink, - size_t const len_obs, char const observed[static len_obs], VA_Variant* const variant) -{ -// printf("%u %u %u -> %u %u %u %s %s\n", head.row, head.col, head.length, tail.row, tail.col, tail.length, is_source ? "SOURCE" : "", is_sink ? "SINK" : ""); - - intmax_t const row = (intmax_t) head.row - is_source; - intmax_t const col = (intmax_t) head.col - is_source; - uint32_t const head_length = head.length + is_source; - uint32_t const tail_length = tail.length + is_sink; - - intmax_t const offset = MIN((intmax_t) tail.row - row, (intmax_t) tail.col - col) - 1; - - uint32_t const head_offset = offset > 0 ? MIN(head_length, offset + 1) : 1; - uint32_t const tail_offset = offset < 0 ? MIN(tail_length, -offset) : 0; - - //printf(" %ld: (%u, %u)\n", offset, head_offset, tail_offset); - - if (head_offset > head_length || (tail_length > 0 && tail_offset >= tail_length)) - { - printf("NO EDGE\n"); - return 0; - } // if - - uint32_t const count = MIN(head_length - head_offset, tail_length - tail_offset - 1) + 1; - - *variant = (VA_Variant) {row + head_offset, tail.row + tail_offset, col + head_offset, tail.col + tail_offset}; - - printf(VAR_FMT " x %u\n", print_variant((*variant), observed), count); - return count; -} // edges2 - - -static size_t -bfs_traversal2(Graph2 const graph, size_t const len_obs, char const observed[static len_obs]) -{ - struct - { - uint32_t depth; - uint32_t next; - }* table = va_std_allocator.alloc(va_std_allocator.context, NULL, 0, sizeof(*table) * va_array_length(graph.nodes)); - - for (size_t i = 0; i < va_array_length(graph.nodes); ++i) - { - table[i].depth = 0; - table[i].next = GVA_NULL; - } // for - uint32_t head = graph.source; - uint32_t tail = graph.source; - - size_t count = 0; - printf("digraph{\nrankdir=LR\nedge[fontname=monospace]\nnode[fixedsize=true,fontname=serif,shape=circle,width=1]\nsi[label=\"\",shape=none,width=0]\n"); - printf("si->s%u\n", graph.source); - - //printf(" \"edges\": [\n"); - while (head != GVA_NULL) - { - uint32_t len = graph.nodes[head].length; - //printf("pop %u\n", head); - for (uint32_t i = head; i != GVA_NULL; i = graph.nodes[i].lambda) - { - printf("s%u[label=\"(%u, %u, %u)\"%s]\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, graph.nodes[i].edges == GVA_NULL && graph.nodes[i].lambda == GVA_NULL ? ",peripheries=2" : ""); - if (i != head) - { - len += graph.nodes[i].length; - //printf("lambda %u\n", i); - } // if - for (uint32_t j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) - { - if (count > 0) - { - //printf(",\n"); - } // if - count += 1; - VA_Variant variant; - uint32_t const count2 = edges2(((VA_LCS_Node) {graph.nodes[head].row, graph.nodes[head].col, len, 0, 0}), - ((VA_LCS_Node) {graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length, 0, 0}), - graph.nodes[head].row == graph.nodes[graph.source].row && graph.nodes[head].col == graph.nodes[graph.source].col, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, len_obs, observed, &variant); - - for (uint32_t k = 0; k < count2; ++k) - { - printf("s%u->s%u[label=\"" VAR_FMT "\"]\n", head, graph.edges[j].tail, print_variant(variant, observed)); - //printf(" {\"head\": \"s%u\", \"tail\": \"s%u\", \"variant\": \"" VAR_FMT "\"}%s", head, graph.edges[j].tail, print_variant(variant, observed), k < count2 - 1 ? ",\n" : ""); - variant.start += 1; - variant.end += 1; - variant.obs_start += 1; - variant.obs_end += 1; - } // for - - if (table[graph.edges[j].tail].depth > 0) - { - //printf("skip %u\n", graph.edges[j].tail); - continue; - } // if - - //printf("push %u\n", graph.edges[j].tail); - table[graph.edges[j].tail].depth = table[i].depth + 1; - table[tail].next = graph.edges[j].tail; - tail = graph.edges[j].tail; - } // for - } // for - head = table[head].next; - - /* - printf(" # \tdepth\tnext\n"); - for (size_t i = 0; i < va_array_length(graph.nodes); ++i) - { - printf("%3zu:\t%5u\t%4d\n", i, table[i].depth, table[i].next); - } // for - printf("head: %d\ntail: %d\n", head, tail); - */ - } // while - - printf("}\n"); - //printf("\n ],\n"); - - table = va_std_allocator.alloc(va_std_allocator.context, table, sizeof(*table) * va_array_length(graph.nodes), 0); - - return count; -} // bfs_traversal2 - - -static Graph2 -build(size_t const len_ref, char const reference[static len_ref], - size_t const len_obs, char const observed[static len_obs], - size_t const shift) -{ - printf("build!\n"); - VA_LCS_Node** lcs_nodes = NULL; - size_t const len_lcs = va_edit(va_std_allocator, len_ref, reference, len_obs, observed, &lcs_nodes); - - Graph2 graph = {NULL, NULL, GVA_NULL}; - - if (len_lcs == 0 || lcs_nodes == NULL) - { - fprintf(stderr, "Trivial graph\n"); - return graph; - } // if - - VA_LCS_Node* last = &lcs_nodes[len_lcs - 1][va_array_length(lcs_nodes[len_lcs - 1]) - 1]; - if (last->row + last->length != len_ref + shift || last->col + last->length != len_obs + shift) - { - va_array_append(va_std_allocator, lcs_nodes[len_lcs - 1], - ((VA_LCS_Node) {.row = len_ref + shift, .col = len_obs + shift, .length = 0})); - last = &lcs_nodes[len_lcs - 1][va_array_length(lcs_nodes[len_lcs - 1]) - 1]; - } // if - va_array_append(va_std_allocator, graph.nodes, ((Node) {last->row, last->col, last->length, GVA_NULL, GVA_NULL})); - last->idx = va_array_length(graph.nodes) - 1; - printf("MAKE NODE %u: (%u, %u, %u)\n", last->idx, last->row, last->col, last->length); - last->incoming = -1; - - /* - fprintf(stderr, "%zu\n", len_lcs); - for (size_t i = 0; i < len_lcs; ++i) - { - fprintf(stderr, "%zu: ", i); - for (size_t j = 0; j < va_array_length(lcs_nodes[i]); ++j) - { - fprintf(stderr, "(%u, %u, %u) ", lcs_nodes[i][j].row, lcs_nodes[i][j].col, lcs_nodes[i][j].length); - } // for - fprintf(stderr, "\n"); - } // for - */ - - VA_LCS_Node source = {shift, shift, 0, -1, GVA_NULL}; - bool found_source = false; - bool is_sink = true; - for (size_t t_i = 0; t_i < len_lcs; ++t_i) - { - size_t const t_len = va_array_length(lcs_nodes[len_lcs - t_i - 1]); - for (size_t t_j = 0; t_j < t_len; ++t_j) - { - VA_LCS_Node* const tail = &lcs_nodes[len_lcs - t_i - 1][t_len - t_j - 1]; - if (tail->idx == GVA_NULL) - { - // sink unreachable from tail, do not add to graph - continue; - } // if - printf("%u %u %u %d\n", tail->row, tail->col, tail->length, tail->incoming); - - uint32_t split_idx = tail->idx; - for (size_t h_i = 0; h_i < MIN(len_lcs - t_i, tail->length + 1); ++h_i) - { - size_t const h_len = h_i == 0 ? t_len - t_j - 1: va_array_length(lcs_nodes[len_lcs - t_i - h_i - 1]); - //printf(" level: %zu with %zu nodes\n", len_lcs - t_i - h_i - 1, h_len); - for (size_t h_j = 0; h_j < h_len; ++h_j) - { - VA_LCS_Node* head = &lcs_nodes[len_lcs - t_i - h_i - 1][h_j]; - - printf(" %u %u %u: ", head->row, head->col, head->length); - - if (head->row + head->length + h_i > tail->row + tail->length || - head->col + head->length + h_i > tail->col + tail->length) - { - if (tail->row + tail->length > head->row + head->length + h_i || - tail->col + tail->length > head->col + head->length + h_i) - { - printf("--\n"); // FIXME: skip the remainder of this (head) level - } // if - else - { - printf("CONVERSE\n"); - if (head->idx != GVA_NULL && edges2(*tail, *head, tail->row == shift && tail->col == shift, - false, len_obs, observed, &(VA_Variant) {0, 0, 0, 0})) - { - va_array_append(va_std_allocator, graph.edges, ((Edge2) {head->idx, graph.nodes[tail->idx].edges})); - graph.nodes[tail->idx].edges = va_array_length(graph.edges) - 1; - printf("MAKE EDGE\n"); - } - } // else - } // if - else - { - VA_Variant variant; - uint32_t const count = edges2(*head, *tail, head->row == shift && head->col == shift, is_sink, len_obs, observed, &variant); - if (count > 0) - { - if (head->idx == GVA_NULL) - { - va_array_append(va_std_allocator, graph.nodes, ((Node) {head->row, head->col, head->length, GVA_NULL, GVA_NULL})); - head->idx = va_array_length(graph.nodes) - 1; - printf("MAKE NODE %u: (%u, %u, %u)\n", head->idx, head->row, head->col, head->length); - if (head->row == shift && head->col == shift) - { - // head is the source - source = *head; - graph.source = source.idx; - found_source = true; - } // if - } // if - head->incoming = MIN(head->incoming, variant.start); - if (variant.end + count > tail->incoming) - { - printf("SPLIT %u %u %u @ %u\n", tail->row, tail->col, tail->length, variant.end + count - 1); - uint32_t const split_len = tail->incoming - tail->row; - va_array_append(va_std_allocator, graph.nodes, - ((Node) {tail->row, tail->col, split_len, GVA_NULL, tail->idx})); - split_idx = va_array_length(graph.nodes) - 1; - graph.nodes[tail->idx].row += split_len; - graph.nodes[tail->idx].col += split_len; - graph.nodes[tail->idx].length -= split_len; - tail->incoming = variant.end + count; - printf(VAR_FMT "\n", print_variant(variant, observed)); - if (variant.start < variant.end + count - 1) - { - // incoming edge - printf("INCOMING -> BOTH\n"); - va_array_append(va_std_allocator, graph.edges, ((Edge2) {split_idx, graph.nodes[head->idx].edges})); - graph.nodes[head->idx].edges = va_array_length(graph.edges) - 1; - } // if - uint32_t head_head = GVA_NULL; - uint32_t head_tail = GVA_NULL; - uint32_t tail_head = GVA_NULL; - uint32_t tail_tail = GVA_NULL; - for (uint32_t i = graph.nodes[tail->idx].edges; i != GVA_NULL; i = graph.edges[i].next) - { - // outgoing edges - VA_Variant var; - uint32_t const count2 = edges2(*tail, (VA_LCS_Node) {graph.nodes[graph.edges[i].tail].row, graph.nodes[graph.edges[i].tail].col, graph.nodes[graph.edges[i].tail].length, 0, 0}, tail->row == shift && tail->col == shift, graph.nodes[graph.edges[i].tail].edges == GVA_NULL && graph.nodes[graph.edges[i].tail].lambda == GVA_NULL, len_obs, observed, &var); - printf(" -> %u: " VAR_FMT " x %u ::\n", graph.edges[i].tail, print_variant(var, observed), count2); - if (var.start > variant.end + count - 1) - { - printf(" -> TAIL\n"); - if (tail_tail != GVA_NULL) - { - graph.edges[tail_tail].next = i; - } // if - if (tail_head == GVA_NULL) - { - tail_head = i; - } // if - tail_tail = i; - } // if - else if (var.end + count2 - 1 < variant.end + count) - { - printf(" -> HEAD\n"); - if (head_tail != GVA_NULL) - { - graph.edges[head_tail].next = i; - } // if - if (head_head == GVA_NULL) - { - head_head = i; - } // if - head_tail = i; - } // if - else - { - printf(" -> BOTH\n"); - if (tail_tail != GVA_NULL) - { - graph.edges[tail_tail].next = i; - } // if - if (tail_head == GVA_NULL) - { - tail_head = i; - } // if - tail_tail = i; - va_array_append(va_std_allocator, graph.edges, ((Edge2) {graph.edges[i].tail, head_head})); - head_head = va_array_length(graph.edges) - 1; - } // else - } // for - if (head_tail != GVA_NULL) - { - graph.edges[head_tail].next = GVA_NULL; - } // if - if (tail_tail != GVA_NULL) - { - graph.edges[tail_tail].next = GVA_NULL; - } // if - graph.nodes[split_idx].edges = head_head; - graph.nodes[tail->idx].edges = tail_head; - } // if - va_array_append(va_std_allocator, graph.edges, ((Edge2) {tail->idx, graph.nodes[head->idx].edges})); - graph.nodes[head->idx].edges = va_array_length(graph.edges) - 1; - printf("MAKE EDGE\n"); - } // if - else - { - // FIXME: skip the remainder of this (head) level - } // else - } // else - } // for h_j - is_sink = false; - tail->idx = split_idx; - } // for h_i - if (!found_source && tail->length >= len_lcs - t_i) - { - if (source.idx == GVA_NULL) - { - va_array_append(va_std_allocator, graph.nodes, ((Node) {source.row, source.col, source.length, GVA_NULL, GVA_NULL})); - source.idx = va_array_length(graph.nodes) - 1; - printf("MAKE NODE %u: (%u, %u, %u)\n", source.idx, source.row, source.col, source.length); - graph.source = source.idx; - } // if - printf("SOURCE %u %u %u: ", source.row, source.col, source.length); - // is this edges2 check always true? - if (edges2(source, *tail, true, is_sink, len_obs, observed, &(VA_Variant) {0, 0, 0, 0})) - { - va_array_append(va_std_allocator, graph.edges, ((Edge2) {tail->idx, graph.nodes[source.idx].edges})); - graph.nodes[source.idx].edges = va_array_length(graph.edges) - 1; - printf("MAKE EDGE\n"); - } // if - } // if - } // for t_j - // dealloc lcs pos level - lcs_nodes[len_lcs - t_i - 1] = va_array_destroy(va_std_allocator, lcs_nodes[len_lcs - t_i - 1]); - } // for t_i - - // deallocation - lcs_nodes = va_std_allocator.alloc(va_std_allocator.context, lcs_nodes, len_lcs, 0); - - printf("#nodes: %zu\n#edges: %zu\n", va_array_length(graph.nodes), va_array_length(graph.edges)); - printf("source: %u\n", graph.source); - for (size_t i = 0; i < va_array_length(graph.nodes); ++i) - { - printf("%zu: (%u, %u, %u):\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length); - if (graph.nodes[i].lambda != GVA_NULL) - { - printf(" (%u, %u, %u): lambda\n", graph.nodes[graph.nodes[i].lambda].row, graph.nodes[graph.nodes[i].lambda].col, graph.nodes[graph.nodes[i].lambda].length); - } // if - for (uint32_t j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) - { - printf(" (%u, %u, %u): ", graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length); - edges2(((VA_LCS_Node) {graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, 0, 0}), - ((VA_LCS_Node) {graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length, 0, 0}), - graph.nodes[i].row == shift && graph.nodes[i].col == shift, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, len_obs, observed, &(VA_Variant) {0, 0, 0, 0}); - } // for - } // for - - - bfs_traversal2(graph, len_obs, observed); - - return graph; -} // build - - int main(int argc, char* argv[static argc + 1]) { @@ -1339,39 +163,6 @@ main(int argc, char* argv[static argc + 1]) build(len_ref, reference, len_obs, observed, 0); -/* - edges2((VA_LCS_Node) {.row = 1, .col = 5, .length = 5}, (VA_LCS_Node) {.row = 6, .col = 6, .length = 4}, false, true, len_obs, observed); - edges2((VA_LCS_Node) {.row = 7, .col = 8, .length = 1}, (VA_LCS_Node) {.row = 6, .col = 6, .length = 4}, false, true, len_obs, observed); - edges2((VA_LCS_Node) {.row = 4, .col = 7, .length = 1}, (VA_LCS_Node) {.row = 6, .col = 6, .length = 4}, false, true, len_obs, observed); - edges2((VA_LCS_Node) {.row = 1, .col = 1, .length = 1}, (VA_LCS_Node) {.row = 6, .col = 6, .length = 4}, false, true, len_obs, observed); - edges2((VA_LCS_Node) {.row = 1, .col = 2, .length = 1}, (VA_LCS_Node) {.row = 6, .col = 6, .length = 4}, false, true, len_obs, observed); - edges2((VA_LCS_Node) {.row = 1, .col = 3, .length = 1}, (VA_LCS_Node) {.row = 6, .col = 6, .length = 4}, false, true, len_obs, observed); - edges2((VA_LCS_Node) {.row = 1, .col = 4, .length = 1}, (VA_LCS_Node) {.row = 6, .col = 6, .length = 4}, false, true, len_obs, observed); - edges2((VA_LCS_Node) {.row = 5, .col = 0, .length = 1}, (VA_LCS_Node) {.row = 6, .col = 6, .length = 4}, false, true, len_obs, observed); - - edges2((VA_LCS_Node) {.row = 1, .col = 5, .length = 5}, (VA_LCS_Node) {.row = 7, .col = 8, .length = 1}, false, false, len_obs, observed); - edges2((VA_LCS_Node) {.row = 1, .col = 5, .length = 5}, (VA_LCS_Node) {.row = 4, .col = 7, .length = 1}, false, false, len_obs, observed); - edges2((VA_LCS_Node) {.row = 1, .col = 1, .length = 1}, (VA_LCS_Node) {.row = 1, .col = 5, .length = 5}, false, false, len_obs, observed); - edges2((VA_LCS_Node) {.row = 1, .col = 2, .length = 1}, (VA_LCS_Node) {.row = 1, .col = 5, .length = 5}, false, false, len_obs, observed); - edges2((VA_LCS_Node) {.row = 1, .col = 3, .length = 1}, (VA_LCS_Node) {.row = 1, .col = 5, .length = 5}, false, false, len_obs, observed); - edges2((VA_LCS_Node) {.row = 1, .col = 4, .length = 1}, (VA_LCS_Node) {.row = 1, .col = 5, .length = 5}, false, false, len_obs, observed); - edges2((VA_LCS_Node) {.row = 5, .col = 0, .length = 1}, (VA_LCS_Node) {.row = 1, .col = 5, .length = 5}, false, false, len_obs, observed); - edges2((VA_LCS_Node) {.row = 0, .col = 0, .length = 0}, (VA_LCS_Node) {.row = 1, .col = 5, .length = 5}, true, false, len_obs, observed); - - edges2((VA_LCS_Node) {.row = 4, .col = 7, .length = 1}, (VA_LCS_Node) {.row = 7, .col = 8, .length = 1}, false, false, len_obs, observed); - - edges2((VA_LCS_Node) {.row = 1, .col = 1, .length = 1}, (VA_LCS_Node) {.row = 5, .col = 0, .length = 1}, false, false, len_obs, observed); - edges2((VA_LCS_Node) {.row = 1, .col = 2, .length = 1}, (VA_LCS_Node) {.row = 5, .col = 0, .length = 1}, false, false, len_obs, observed); - edges2((VA_LCS_Node) {.row = 1, .col = 3, .length = 1}, (VA_LCS_Node) {.row = 5, .col = 0, .length = 1}, false, false, len_obs, observed); - edges2((VA_LCS_Node) {.row = 1, .col = 4, .length = 1}, (VA_LCS_Node) {.row = 5, .col = 0, .length = 1}, false, false, len_obs, observed); - edges2((VA_LCS_Node) {.row = 0, .col = 0, .length = 0}, (VA_LCS_Node) {.row = 5, .col = 0, .length = 1}, true, false, len_obs, observed); - - edges2((VA_LCS_Node) {.row = 1, .col = 1, .length = 1}, (VA_LCS_Node) {.row = 1, .col = 4, .length = 1}, false, false, len_obs, observed); - edges2((VA_LCS_Node) {.row = 1, .col = 2, .length = 1}, (VA_LCS_Node) {.row = 1, .col = 4, .length = 1}, false, false, len_obs, observed); - edges2((VA_LCS_Node) {.row = 1, .col = 3, .length = 1}, (VA_LCS_Node) {.row = 1, .col = 4, .length = 1}, false, false, len_obs, observed); - edges2((VA_LCS_Node) {.row = 0, .col = 0, .length = 0}, (VA_LCS_Node) {.row = 1, .col = 4, .length = 1}, true, false, len_obs, observed); -*/ - } // if else { From e83fa54d4da2184af409edb98568a5db17cc8f84 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Wed, 2 Apr 2025 23:14:22 +0200 Subject: [PATCH 154/704] TODO silence static analyzer or is there a real fix? --- src/graph.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/graph.c b/src/graph.c index 0cab89b..c0050a4 100644 --- a/src/graph.c +++ b/src/graph.c @@ -491,8 +491,11 @@ bfs_traversal2(Graph2 const graph, size_t const len_obs, char const observed[sta for (size_t i = 0; i < va_array_length(graph.nodes); ++i) { - table[i].depth = 0; - table[i].next = GVA_NULL; + // if (NULL != table) // silence static analyzer + { + table[i].depth = 0; + table[i].next = GVA_NULL; + } } // for uint32_t head = graph.source; uint32_t tail = graph.source; From 0e3b68183f5e0fc177c9089844f346a5f76c84a0 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Thu, 3 Apr 2025 08:34:06 +0200 Subject: [PATCH 155/704] Split graph into graph and graph2. --- include/graph.h | 22 +-- include/graph2.h | 34 ++++ src/graph.c | 383 +------------------------------------------- src/graph2.c | 403 +++++++++++++++++++++++++++++++++++++++++++++++ src/main.c | 1 + 5 files changed, 441 insertions(+), 402 deletions(-) create mode 100644 include/graph2.h create mode 100644 src/graph2.c diff --git a/include/graph.h b/include/graph.h index 35e57d7..deb5059 100644 --- a/include/graph.h +++ b/include/graph.h @@ -10,13 +10,6 @@ typedef struct } Edge; -typedef struct -{ - uint32_t tail; - uint32_t next; -} Edge2; - - typedef struct { uint32_t row; @@ -26,7 +19,6 @@ typedef struct uint32_t lambda; } Node; - typedef struct { Node* nodes; @@ -36,28 +28,17 @@ typedef struct } Graph; -typedef struct -{ - Node* nodes; - Edge2* edges; - uint32_t source; -} Graph2; - - Graph build_graph(VA_Allocator const allocator, size_t const len_ref, size_t const len_obs, size_t const len_lcs, VA_LCS_Node* lcs_nodes[static len_lcs], size_t const shift); -Graph2 -build(size_t const len_ref, char const reference[static len_ref], - size_t const len_obs, char const observed[static len_obs], - size_t const shift); void to_dot(Graph const graph, size_t const len_obs, char const observed[static len_obs]); + size_t edges(uint32_t const head_row, uint32_t const head_col, uint32_t const head_length, uint32_t const tail_row, uint32_t const tail_col, uint32_t const tail_length, @@ -65,5 +46,6 @@ edges(uint32_t const head_row, uint32_t const head_col, uint32_t const head_leng size_t const len_obs, char const observed[static len_obs], VA_Variant const edge); + void destroy(VA_Allocator const allocator, Graph* const graph); diff --git a/include/graph2.h b/include/graph2.h new file mode 100644 index 0000000..0b97995 --- /dev/null +++ b/include/graph2.h @@ -0,0 +1,34 @@ +#include // uint32_t +#include "../include/edit.h" // VA_LCS_Node +#include "../include/variant.h" // VA_Variant + + +typedef struct +{ + uint32_t tail; + uint32_t next; +} Edge2; + + +typedef struct +{ + uint32_t row; + uint32_t col; + uint32_t length; + uint32_t edges; + uint32_t lambda; +} Node2; + + +typedef struct +{ + Node2* nodes; + Edge2* edges; + uint32_t source; +} Graph2; + + +Graph2 +build(size_t const len_ref, char const reference[static len_ref], + size_t const len_obs, char const observed[static len_obs], + size_t const shift); diff --git a/src/graph.c b/src/graph.c index c0050a4..4d2a2b4 100644 --- a/src/graph.c +++ b/src/graph.c @@ -10,7 +10,7 @@ #include "../include/edit.h" // VA_LCS_Node, va_edit #include "../include/std_alloc.h" // va_std_allocator #include "../include/variant.h" // VA_Variant -#include "../include/graph.h" // Edge, Edge2, Graph, Node +#include "../include/graph.h" // Edge, Graph, Node #define MAX(lhs, rhs) (((lhs) > (rhs)) ? (lhs) : (rhs)) @@ -444,384 +444,3 @@ edges(uint32_t const head_row, uint32_t const head_col, uint32_t const head_leng } // if return count; } // edges - - -static uint32_t -edges2(VA_LCS_Node const head, VA_LCS_Node const tail, - bool const is_source, bool const is_sink, - size_t const len_obs, char const observed[static len_obs], VA_Variant* const variant) -{ -// printf("%u %u %u -> %u %u %u %s %s\n", head.row, head.col, head.length, tail.row, tail.col, tail.length, is_source ? "SOURCE" : "", is_sink ? "SINK" : ""); - - intmax_t const row = (intmax_t) head.row - is_source; - intmax_t const col = (intmax_t) head.col - is_source; - uint32_t const head_length = head.length + is_source; - uint32_t const tail_length = tail.length + is_sink; - - intmax_t const offset = MIN((intmax_t) tail.row - row, (intmax_t) tail.col - col) - 1; - - uint32_t const head_offset = offset > 0 ? MIN(head_length, offset + 1) : 1; - uint32_t const tail_offset = offset < 0 ? MIN(tail_length, -offset) : 0; - - //printf(" %ld: (%u, %u)\n", offset, head_offset, tail_offset); - - if (head_offset > head_length || (tail_length > 0 && tail_offset >= tail_length)) - { - printf("NO EDGE\n"); - return 0; - } // if - - uint32_t const count = MIN(head_length - head_offset, tail_length - tail_offset - 1) + 1; - - *variant = (VA_Variant) {row + head_offset, tail.row + tail_offset, col + head_offset, tail.col + tail_offset}; - - printf(VAR_FMT " x %u\n", print_variant((*variant), observed), count); - return count; -} // edges2 - - -static size_t -bfs_traversal2(Graph2 const graph, size_t const len_obs, char const observed[static len_obs]) -{ - struct - { - uint32_t depth; - uint32_t next; - }* table = va_std_allocator.alloc(va_std_allocator.context, NULL, 0, sizeof(*table) * va_array_length(graph.nodes)); - - for (size_t i = 0; i < va_array_length(graph.nodes); ++i) - { - // if (NULL != table) // silence static analyzer - { - table[i].depth = 0; - table[i].next = GVA_NULL; - } - } // for - uint32_t head = graph.source; - uint32_t tail = graph.source; - - size_t count = 0; - printf("digraph{\nrankdir=LR\nedge[fontname=monospace]\nnode[fixedsize=true,fontname=serif,shape=circle,width=1]\nsi[label=\"\",shape=none,width=0]\n"); - printf("si->s%u\n", graph.source); - - //printf(" \"edges\": [\n"); - while (head != GVA_NULL) - { - uint32_t len = graph.nodes[head].length; - //printf("pop %u\n", head); - for (uint32_t i = head; i != GVA_NULL; i = graph.nodes[i].lambda) - { - printf("s%u[label=\"(%u, %u, %u)\"%s]\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, graph.nodes[i].edges == GVA_NULL && graph.nodes[i].lambda == GVA_NULL ? ",peripheries=2" : ""); - if (i != head) - { - len += graph.nodes[i].length; - //printf("lambda %u\n", i); - } // if - for (uint32_t j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) - { - if (count > 0) - { - //printf(",\n"); - } // if - count += 1; - VA_Variant variant; - uint32_t const count2 = edges2(((VA_LCS_Node) {graph.nodes[head].row, graph.nodes[head].col, len, 0, 0}), - ((VA_LCS_Node) {graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length, 0, 0}), - graph.nodes[head].row == graph.nodes[graph.source].row && graph.nodes[head].col == graph.nodes[graph.source].col, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, len_obs, observed, &variant); - - for (uint32_t k = 0; k < count2; ++k) - { - printf("s%u->s%u[label=\"" VAR_FMT "\"]\n", head, graph.edges[j].tail, print_variant(variant, observed)); - //printf(" {\"head\": \"s%u\", \"tail\": \"s%u\", \"variant\": \"" VAR_FMT "\"}%s", head, graph.edges[j].tail, print_variant(variant, observed), k < count2 - 1 ? ",\n" : ""); - variant.start += 1; - variant.end += 1; - variant.obs_start += 1; - variant.obs_end += 1; - } // for - - if (table[graph.edges[j].tail].depth > 0) - { - //printf("skip %u\n", graph.edges[j].tail); - continue; - } // if - - //printf("push %u\n", graph.edges[j].tail); - table[graph.edges[j].tail].depth = table[i].depth + 1; - table[tail].next = graph.edges[j].tail; - tail = graph.edges[j].tail; - } // for - } // for - head = table[head].next; - - /* - printf(" # \tdepth\tnext\n"); - for (size_t i = 0; i < va_array_length(graph.nodes); ++i) - { - printf("%3zu:\t%5u\t%4d\n", i, table[i].depth, table[i].next); - } // for - printf("head: %d\ntail: %d\n", head, tail); - */ - } // while - - printf("}\n"); - //printf("\n ],\n"); - - table = va_std_allocator.alloc(va_std_allocator.context, table, sizeof(*table) * va_array_length(graph.nodes), 0); - - return count; -} // bfs_traversal2 - - -Graph2 -build(size_t const len_ref, char const reference[static len_ref], - size_t const len_obs, char const observed[static len_obs], - size_t const shift) -{ - printf("build!\n"); - VA_LCS_Node** lcs_nodes = NULL; - size_t const len_lcs = va_edit(va_std_allocator, len_ref, reference, len_obs, observed, &lcs_nodes); - - Graph2 graph = {NULL, NULL, GVA_NULL}; - - if (len_lcs == 0 || lcs_nodes == NULL) - { - fprintf(stderr, "Trivial graph\n"); - return graph; - } // if - - VA_LCS_Node* last = &lcs_nodes[len_lcs - 1][va_array_length(lcs_nodes[len_lcs - 1]) - 1]; - if (last->row + last->length != len_ref + shift || last->col + last->length != len_obs + shift) - { - va_array_append(va_std_allocator, lcs_nodes[len_lcs - 1], - ((VA_LCS_Node) {.row = len_ref + shift, .col = len_obs + shift, .length = 0})); - last = &lcs_nodes[len_lcs - 1][va_array_length(lcs_nodes[len_lcs - 1]) - 1]; - } // if - va_array_append(va_std_allocator, graph.nodes, ((Node) {last->row, last->col, last->length, GVA_NULL, GVA_NULL})); - last->idx = va_array_length(graph.nodes) - 1; - printf("MAKE NODE %u: (%u, %u, %u)\n", last->idx, last->row, last->col, last->length); - last->incoming = -1; - - /* - fprintf(stderr, "%zu\n", len_lcs); - for (size_t i = 0; i < len_lcs; ++i) - { - fprintf(stderr, "%zu: ", i); - for (size_t j = 0; j < va_array_length(lcs_nodes[i]); ++j) - { - fprintf(stderr, "(%u, %u, %u) ", lcs_nodes[i][j].row, lcs_nodes[i][j].col, lcs_nodes[i][j].length); - } // for - fprintf(stderr, "\n"); - } // for - */ - - VA_LCS_Node source = {shift, shift, 0, -1, GVA_NULL}; - bool found_source = false; - bool is_sink = true; - for (size_t t_i = 0; t_i < len_lcs; ++t_i) - { - size_t const t_len = va_array_length(lcs_nodes[len_lcs - t_i - 1]); - for (size_t t_j = 0; t_j < t_len; ++t_j) - { - VA_LCS_Node* const tail = &lcs_nodes[len_lcs - t_i - 1][t_len - t_j - 1]; - if (tail->idx == GVA_NULL) - { - // sink unreachable from tail, do not add to graph - continue; - } // if - printf("%u %u %u %d\n", tail->row, tail->col, tail->length, tail->incoming); - - uint32_t split_idx = tail->idx; - for (size_t h_i = 0; h_i < MIN(len_lcs - t_i, tail->length + 1); ++h_i) - { - size_t const h_len = h_i == 0 ? t_len - t_j - 1: va_array_length(lcs_nodes[len_lcs - t_i - h_i - 1]); - //printf(" level: %zu with %zu nodes\n", len_lcs - t_i - h_i - 1, h_len); - for (size_t h_j = 0; h_j < h_len; ++h_j) - { - VA_LCS_Node* head = &lcs_nodes[len_lcs - t_i - h_i - 1][h_j]; - - printf(" %u %u %u: ", head->row, head->col, head->length); - - if (head->row + head->length + h_i > tail->row + tail->length || - head->col + head->length + h_i > tail->col + tail->length) - { - if (tail->row + tail->length > head->row + head->length + h_i || - tail->col + tail->length > head->col + head->length + h_i) - { - printf("--\n"); // FIXME: skip the remainder of this (head) level - } // if - else - { - printf("CONVERSE\n"); - if (head->idx != GVA_NULL && edges2(*tail, *head, tail->row == shift && tail->col == shift, - false, len_obs, observed, &(VA_Variant) {0, 0, 0, 0})) - { - va_array_append(va_std_allocator, graph.edges, ((Edge2) {head->idx, graph.nodes[tail->idx].edges})); - graph.nodes[tail->idx].edges = va_array_length(graph.edges) - 1; - printf("MAKE EDGE\n"); - } - } // else - } // if - else - { - VA_Variant variant; - uint32_t const count = edges2(*head, *tail, head->row == shift && head->col == shift, is_sink, len_obs, observed, &variant); - if (count > 0) - { - if (head->idx == GVA_NULL) - { - va_array_append(va_std_allocator, graph.nodes, ((Node) {head->row, head->col, head->length, GVA_NULL, GVA_NULL})); - head->idx = va_array_length(graph.nodes) - 1; - printf("MAKE NODE %u: (%u, %u, %u)\n", head->idx, head->row, head->col, head->length); - if (head->row == shift && head->col == shift) - { - // head is the source - source = *head; - graph.source = source.idx; - found_source = true; - } // if - } // if - head->incoming = MIN(head->incoming, variant.start); - if (variant.end + count > tail->incoming) - { - printf("SPLIT %u %u %u @ %u\n", tail->row, tail->col, tail->length, variant.end + count - 1); - uint32_t const split_len = tail->incoming - tail->row; - va_array_append(va_std_allocator, graph.nodes, - ((Node) {tail->row, tail->col, split_len, GVA_NULL, tail->idx})); - split_idx = va_array_length(graph.nodes) - 1; - graph.nodes[tail->idx].row += split_len; - graph.nodes[tail->idx].col += split_len; - graph.nodes[tail->idx].length -= split_len; - tail->incoming = variant.end + count; - printf(VAR_FMT "\n", print_variant(variant, observed)); - if (variant.start < variant.end + count - 1) - { - // incoming edge - printf("INCOMING -> BOTH\n"); - va_array_append(va_std_allocator, graph.edges, ((Edge2) {split_idx, graph.nodes[head->idx].edges})); - graph.nodes[head->idx].edges = va_array_length(graph.edges) - 1; - } // if - uint32_t head_head = GVA_NULL; - uint32_t head_tail = GVA_NULL; - uint32_t tail_head = GVA_NULL; - uint32_t tail_tail = GVA_NULL; - for (uint32_t i = graph.nodes[tail->idx].edges; i != GVA_NULL; i = graph.edges[i].next) - { - // outgoing edges - VA_Variant var; - uint32_t const count2 = edges2(*tail, (VA_LCS_Node) {graph.nodes[graph.edges[i].tail].row, graph.nodes[graph.edges[i].tail].col, graph.nodes[graph.edges[i].tail].length, 0, 0}, tail->row == shift && tail->col == shift, graph.nodes[graph.edges[i].tail].edges == GVA_NULL && graph.nodes[graph.edges[i].tail].lambda == GVA_NULL, len_obs, observed, &var); - printf(" -> %u: " VAR_FMT " x %u ::\n", graph.edges[i].tail, print_variant(var, observed), count2); - if (var.start > variant.end + count - 1) - { - printf(" -> TAIL\n"); - if (tail_tail != GVA_NULL) - { - graph.edges[tail_tail].next = i; - } // if - if (tail_head == GVA_NULL) - { - tail_head = i; - } // if - tail_tail = i; - } // if - else if (var.end + count2 - 1 < variant.end + count) - { - printf(" -> HEAD\n"); - if (head_tail != GVA_NULL) - { - graph.edges[head_tail].next = i; - } // if - if (head_head == GVA_NULL) - { - head_head = i; - } // if - head_tail = i; - } // if - else - { - printf(" -> BOTH\n"); - if (tail_tail != GVA_NULL) - { - graph.edges[tail_tail].next = i; - } // if - if (tail_head == GVA_NULL) - { - tail_head = i; - } // if - tail_tail = i; - va_array_append(va_std_allocator, graph.edges, ((Edge2) {graph.edges[i].tail, head_head})); - head_head = va_array_length(graph.edges) - 1; - } // else - } // for - if (head_tail != GVA_NULL) - { - graph.edges[head_tail].next = GVA_NULL; - } // if - if (tail_tail != GVA_NULL) - { - graph.edges[tail_tail].next = GVA_NULL; - } // if - graph.nodes[split_idx].edges = head_head; - graph.nodes[tail->idx].edges = tail_head; - } // if - va_array_append(va_std_allocator, graph.edges, ((Edge2) {tail->idx, graph.nodes[head->idx].edges})); - graph.nodes[head->idx].edges = va_array_length(graph.edges) - 1; - printf("MAKE EDGE\n"); - } // if - else - { - // FIXME: skip the remainder of this (head) level - } // else - } // else - } // for h_j - is_sink = false; - tail->idx = split_idx; - } // for h_i - if (!found_source && tail->length >= len_lcs - t_i) - { - if (source.idx == GVA_NULL) - { - va_array_append(va_std_allocator, graph.nodes, ((Node) {source.row, source.col, source.length, GVA_NULL, GVA_NULL})); - source.idx = va_array_length(graph.nodes) - 1; - printf("MAKE NODE %u: (%u, %u, %u)\n", source.idx, source.row, source.col, source.length); - graph.source = source.idx; - } // if - printf("SOURCE %u %u %u: ", source.row, source.col, source.length); - // is this edges2 check always true? - if (edges2(source, *tail, true, is_sink, len_obs, observed, &(VA_Variant) {0, 0, 0, 0})) - { - va_array_append(va_std_allocator, graph.edges, ((Edge2) {tail->idx, graph.nodes[source.idx].edges})); - graph.nodes[source.idx].edges = va_array_length(graph.edges) - 1; - printf("MAKE EDGE\n"); - } // if - } // if - } // for t_j - // dealloc lcs pos level - lcs_nodes[len_lcs - t_i - 1] = va_array_destroy(va_std_allocator, lcs_nodes[len_lcs - t_i - 1]); - } // for t_i - - // deallocation - lcs_nodes = va_std_allocator.alloc(va_std_allocator.context, lcs_nodes, len_lcs, 0); - - printf("#nodes: %zu\n#edges: %zu\n", va_array_length(graph.nodes), va_array_length(graph.edges)); - printf("source: %u\n", graph.source); - for (size_t i = 0; i < va_array_length(graph.nodes); ++i) - { - printf("%zu: (%u, %u, %u):\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length); - if (graph.nodes[i].lambda != GVA_NULL) - { - printf(" (%u, %u, %u): lambda\n", graph.nodes[graph.nodes[i].lambda].row, graph.nodes[graph.nodes[i].lambda].col, graph.nodes[graph.nodes[i].lambda].length); - } // if - for (uint32_t j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) - { - printf(" (%u, %u, %u): ", graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length); - edges2(((VA_LCS_Node) {graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, 0, 0}), - ((VA_LCS_Node) {graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length, 0, 0}), - graph.nodes[i].row == shift && graph.nodes[i].col == shift, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, len_obs, observed, &(VA_Variant) {0, 0, 0, 0}); - } // for - } // for - - - bfs_traversal2(graph, len_obs, observed); - - return graph; -} // build \ No newline at end of file diff --git a/src/graph2.c b/src/graph2.c new file mode 100644 index 0000000..47fe7e3 --- /dev/null +++ b/src/graph2.c @@ -0,0 +1,403 @@ +#include // bool, false, true +#include // NULL, size_t +#include // intmax_t, uint32_t +#include // stderr, fprintf, printf + +#include "../include/alloc.h" // VA_Allocator +#include "../include/array.h" // va_array_* +#include "../include/edit.h" // VA_LCS_Node, va_edit +#include "../include/std_alloc.h" // va_std_allocator +#include "../include/variant.h" // VA_Variant +#include "../include/graph2.h" // Edge2, Graph2, Node2 + + +#define MAX(lhs, rhs) (((lhs) > (rhs)) ? (lhs) : (rhs)) +#define MIN(lhs, rhs) (((lhs) < (rhs)) ? (lhs) : (rhs)) + +#define print_variant(variant, observed) variant.start, variant.end, (int) variant.obs_end - variant.obs_start, observed + variant.obs_start +#define VAR_FMT "%u:%u/%.*s" + + +static uint32_t const GVA_NULL = UINT32_MAX; + + + +static uint32_t +edges2(VA_LCS_Node const head, VA_LCS_Node const tail, + bool const is_source, bool const is_sink, + size_t const len_obs, char const observed[static len_obs], VA_Variant* const variant) +{ +// printf("%u %u %u -> %u %u %u %s %s\n", head.row, head.col, head.length, tail.row, tail.col, tail.length, is_source ? "SOURCE" : "", is_sink ? "SINK" : ""); + + intmax_t const row = (intmax_t) head.row - is_source; + intmax_t const col = (intmax_t) head.col - is_source; + uint32_t const head_length = head.length + is_source; + uint32_t const tail_length = tail.length + is_sink; + + intmax_t const offset = MIN((intmax_t) tail.row - row, (intmax_t) tail.col - col) - 1; + + uint32_t const head_offset = offset > 0 ? MIN(head_length, offset + 1) : 1; + uint32_t const tail_offset = offset < 0 ? MIN(tail_length, -offset) : 0; + + //printf(" %ld: (%u, %u)\n", offset, head_offset, tail_offset); + + if (head_offset > head_length || (tail_length > 0 && tail_offset >= tail_length)) + { + printf("NO EDGE\n"); + return 0; + } // if + + uint32_t const count = MIN(head_length - head_offset, tail_length - tail_offset - 1) + 1; + + *variant = (VA_Variant) {row + head_offset, tail.row + tail_offset, col + head_offset, tail.col + tail_offset}; + + printf(VAR_FMT " x %u\n", print_variant((*variant), observed), count); + return count; +} // edges2 + + +static size_t +bfs_traversal2(Graph2 const graph, size_t const len_obs, char const observed[static len_obs]) +{ + struct + { + uint32_t depth; + uint32_t next; + }* table = va_std_allocator.alloc(va_std_allocator.context, NULL, 0, sizeof(*table) * va_array_length(graph.nodes)); + + for (size_t i = 0; i < va_array_length(graph.nodes); ++i) + { + // if (NULL != table) // silence static analyzer + { + table[i].depth = 0; + table[i].next = GVA_NULL; + } + } // for + uint32_t head = graph.source; + uint32_t tail = graph.source; + + size_t count = 0; + printf("digraph{\nrankdir=LR\nedge[fontname=monospace]\nnode[fixedsize=true,fontname=serif,shape=circle,width=1]\nsi[label=\"\",shape=none,width=0]\n"); + printf("si->s%u\n", graph.source); + + //printf(" \"edges\": [\n"); + while (head != GVA_NULL) + { + uint32_t len = graph.nodes[head].length; + //printf("pop %u\n", head); + for (uint32_t i = head; i != GVA_NULL; i = graph.nodes[i].lambda) + { + printf("s%u[label=\"(%u, %u, %u)\"%s]\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, graph.nodes[i].edges == GVA_NULL && graph.nodes[i].lambda == GVA_NULL ? ",peripheries=2" : ""); + if (i != head) + { + len += graph.nodes[i].length; + //printf("lambda %u\n", i); + } // if + for (uint32_t j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) + { + if (count > 0) + { + //printf(",\n"); + } // if + count += 1; + VA_Variant variant; + uint32_t const count2 = edges2(((VA_LCS_Node) {graph.nodes[head].row, graph.nodes[head].col, len, 0, 0}), + ((VA_LCS_Node) {graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length, 0, 0}), + graph.nodes[head].row == graph.nodes[graph.source].row && graph.nodes[head].col == graph.nodes[graph.source].col, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, len_obs, observed, &variant); + + for (uint32_t k = 0; k < count2; ++k) + { + printf("s%u->s%u[label=\"" VAR_FMT "\"]\n", head, graph.edges[j].tail, print_variant(variant, observed)); + //printf(" {\"head\": \"s%u\", \"tail\": \"s%u\", \"variant\": \"" VAR_FMT "\"}%s", head, graph.edges[j].tail, print_variant(variant, observed), k < count2 - 1 ? ",\n" : ""); + variant.start += 1; + variant.end += 1; + variant.obs_start += 1; + variant.obs_end += 1; + } // for + + if (table[graph.edges[j].tail].depth > 0) + { + //printf("skip %u\n", graph.edges[j].tail); + continue; + } // if + + //printf("push %u\n", graph.edges[j].tail); + table[graph.edges[j].tail].depth = table[i].depth + 1; + table[tail].next = graph.edges[j].tail; + tail = graph.edges[j].tail; + } // for + } // for + head = table[head].next; + + /* + printf(" # \tdepth\tnext\n"); + for (size_t i = 0; i < va_array_length(graph.nodes); ++i) + { + printf("%3zu:\t%5u\t%4d\n", i, table[i].depth, table[i].next); + } // for + printf("head: %d\ntail: %d\n", head, tail); + */ + } // while + + printf("}\n"); + //printf("\n ],\n"); + + table = va_std_allocator.alloc(va_std_allocator.context, table, sizeof(*table) * va_array_length(graph.nodes), 0); + + return count; +} // bfs_traversal2 + + +Graph2 +build(size_t const len_ref, char const reference[static len_ref], + size_t const len_obs, char const observed[static len_obs], + size_t const shift) +{ + printf("build!\n"); + VA_LCS_Node** lcs_nodes = NULL; + size_t const len_lcs = va_edit(va_std_allocator, len_ref, reference, len_obs, observed, &lcs_nodes); + + Graph2 graph = {NULL, NULL, GVA_NULL}; + + if (len_lcs == 0 || lcs_nodes == NULL) + { + fprintf(stderr, "Trivial graph\n"); + return graph; + } // if + + VA_LCS_Node* last = &lcs_nodes[len_lcs - 1][va_array_length(lcs_nodes[len_lcs - 1]) - 1]; + if (last->row + last->length != len_ref + shift || last->col + last->length != len_obs + shift) + { + va_array_append(va_std_allocator, lcs_nodes[len_lcs - 1], + ((VA_LCS_Node) {.row = len_ref + shift, .col = len_obs + shift, .length = 0})); + last = &lcs_nodes[len_lcs - 1][va_array_length(lcs_nodes[len_lcs - 1]) - 1]; + } // if + va_array_append(va_std_allocator, graph.nodes, ((Node2) {last->row, last->col, last->length, GVA_NULL, GVA_NULL})); + last->idx = va_array_length(graph.nodes) - 1; + printf("MAKE NODE %u: (%u, %u, %u)\n", last->idx, last->row, last->col, last->length); + last->incoming = -1; + + /* + fprintf(stderr, "%zu\n", len_lcs); + for (size_t i = 0; i < len_lcs; ++i) + { + fprintf(stderr, "%zu: ", i); + for (size_t j = 0; j < va_array_length(lcs_nodes[i]); ++j) + { + fprintf(stderr, "(%u, %u, %u) ", lcs_nodes[i][j].row, lcs_nodes[i][j].col, lcs_nodes[i][j].length); + } // for + fprintf(stderr, "\n"); + } // for + */ + + VA_LCS_Node source = {shift, shift, 0, -1, GVA_NULL}; + bool found_source = false; + bool is_sink = true; + for (size_t t_i = 0; t_i < len_lcs; ++t_i) + { + size_t const t_len = va_array_length(lcs_nodes[len_lcs - t_i - 1]); + for (size_t t_j = 0; t_j < t_len; ++t_j) + { + VA_LCS_Node* const tail = &lcs_nodes[len_lcs - t_i - 1][t_len - t_j - 1]; + if (tail->idx == GVA_NULL) + { + // sink unreachable from tail, do not add to graph + continue; + } // if + printf("%u %u %u %d\n", tail->row, tail->col, tail->length, tail->incoming); + + uint32_t split_idx = tail->idx; + for (size_t h_i = 0; h_i < MIN(len_lcs - t_i, tail->length + 1); ++h_i) + { + size_t const h_len = h_i == 0 ? t_len - t_j - 1: va_array_length(lcs_nodes[len_lcs - t_i - h_i - 1]); + //printf(" level: %zu with %zu nodes\n", len_lcs - t_i - h_i - 1, h_len); + for (size_t h_j = 0; h_j < h_len; ++h_j) + { + VA_LCS_Node* head = &lcs_nodes[len_lcs - t_i - h_i - 1][h_j]; + + printf(" %u %u %u: ", head->row, head->col, head->length); + + if (head->row + head->length + h_i > tail->row + tail->length || + head->col + head->length + h_i > tail->col + tail->length) + { + if (tail->row + tail->length > head->row + head->length + h_i || + tail->col + tail->length > head->col + head->length + h_i) + { + printf("--\n"); // FIXME: skip the remainder of this (head) level + } // if + else + { + printf("CONVERSE\n"); + if (head->idx != GVA_NULL && edges2(*tail, *head, tail->row == shift && tail->col == shift, + false, len_obs, observed, &(VA_Variant) {0, 0, 0, 0})) + { + va_array_append(va_std_allocator, graph.edges, ((Edge2) {head->idx, graph.nodes[tail->idx].edges})); + graph.nodes[tail->idx].edges = va_array_length(graph.edges) - 1; + printf("MAKE EDGE\n"); + } + } // else + } // if + else + { + VA_Variant variant; + uint32_t const count = edges2(*head, *tail, head->row == shift && head->col == shift, is_sink, len_obs, observed, &variant); + if (count > 0) + { + if (head->idx == GVA_NULL) + { + va_array_append(va_std_allocator, graph.nodes, ((Node2) {head->row, head->col, head->length, GVA_NULL, GVA_NULL})); + head->idx = va_array_length(graph.nodes) - 1; + printf("MAKE NODE %u: (%u, %u, %u)\n", head->idx, head->row, head->col, head->length); + if (head->row == shift && head->col == shift) + { + // head is the source + source = *head; + graph.source = source.idx; + found_source = true; + } // if + } // if + head->incoming = MIN(head->incoming, variant.start); + if (variant.end + count > tail->incoming) + { + printf("SPLIT %u %u %u @ %u\n", tail->row, tail->col, tail->length, variant.end + count - 1); + uint32_t const split_len = tail->incoming - tail->row; + va_array_append(va_std_allocator, graph.nodes, + ((Node2) {tail->row, tail->col, split_len, GVA_NULL, tail->idx})); + split_idx = va_array_length(graph.nodes) - 1; + graph.nodes[tail->idx].row += split_len; + graph.nodes[tail->idx].col += split_len; + graph.nodes[tail->idx].length -= split_len; + tail->incoming = variant.end + count; + printf(VAR_FMT "\n", print_variant(variant, observed)); + if (variant.start < variant.end + count - 1) + { + // incoming edge + printf("INCOMING -> BOTH\n"); + va_array_append(va_std_allocator, graph.edges, ((Edge2) {split_idx, graph.nodes[head->idx].edges})); + graph.nodes[head->idx].edges = va_array_length(graph.edges) - 1; + } // if + uint32_t head_head = GVA_NULL; + uint32_t head_tail = GVA_NULL; + uint32_t tail_head = GVA_NULL; + uint32_t tail_tail = GVA_NULL; + for (uint32_t i = graph.nodes[tail->idx].edges; i != GVA_NULL; i = graph.edges[i].next) + { + // outgoing edges + VA_Variant var; + uint32_t const count2 = edges2(*tail, (VA_LCS_Node) {graph.nodes[graph.edges[i].tail].row, graph.nodes[graph.edges[i].tail].col, graph.nodes[graph.edges[i].tail].length, 0, 0}, tail->row == shift && tail->col == shift, graph.nodes[graph.edges[i].tail].edges == GVA_NULL && graph.nodes[graph.edges[i].tail].lambda == GVA_NULL, len_obs, observed, &var); + printf(" -> %u: " VAR_FMT " x %u ::\n", graph.edges[i].tail, print_variant(var, observed), count2); + if (var.start > variant.end + count - 1) + { + printf(" -> TAIL\n"); + if (tail_tail != GVA_NULL) + { + graph.edges[tail_tail].next = i; + } // if + if (tail_head == GVA_NULL) + { + tail_head = i; + } // if + tail_tail = i; + } // if + else if (var.end + count2 - 1 < variant.end + count) + { + printf(" -> HEAD\n"); + if (head_tail != GVA_NULL) + { + graph.edges[head_tail].next = i; + } // if + if (head_head == GVA_NULL) + { + head_head = i; + } // if + head_tail = i; + } // if + else + { + printf(" -> BOTH\n"); + if (tail_tail != GVA_NULL) + { + graph.edges[tail_tail].next = i; + } // if + if (tail_head == GVA_NULL) + { + tail_head = i; + } // if + tail_tail = i; + va_array_append(va_std_allocator, graph.edges, ((Edge2) {graph.edges[i].tail, head_head})); + head_head = va_array_length(graph.edges) - 1; + } // else + } // for + if (head_tail != GVA_NULL) + { + graph.edges[head_tail].next = GVA_NULL; + } // if + if (tail_tail != GVA_NULL) + { + graph.edges[tail_tail].next = GVA_NULL; + } // if + graph.nodes[split_idx].edges = head_head; + graph.nodes[tail->idx].edges = tail_head; + } // if + va_array_append(va_std_allocator, graph.edges, ((Edge2) {tail->idx, graph.nodes[head->idx].edges})); + graph.nodes[head->idx].edges = va_array_length(graph.edges) - 1; + printf("MAKE EDGE\n"); + } // if + else + { + // FIXME: skip the remainder of this (head) level + } // else + } // else + } // for h_j + is_sink = false; + tail->idx = split_idx; + } // for h_i + if (!found_source && tail->length >= len_lcs - t_i) + { + if (source.idx == GVA_NULL) + { + va_array_append(va_std_allocator, graph.nodes, ((Node2) {source.row, source.col, source.length, GVA_NULL, GVA_NULL})); + source.idx = va_array_length(graph.nodes) - 1; + printf("MAKE NODE %u: (%u, %u, %u)\n", source.idx, source.row, source.col, source.length); + graph.source = source.idx; + } // if + printf("SOURCE %u %u %u: ", source.row, source.col, source.length); + // is this edges2 check always true? + if (edges2(source, *tail, true, is_sink, len_obs, observed, &(VA_Variant) {0, 0, 0, 0})) + { + va_array_append(va_std_allocator, graph.edges, ((Edge2) {tail->idx, graph.nodes[source.idx].edges})); + graph.nodes[source.idx].edges = va_array_length(graph.edges) - 1; + printf("MAKE EDGE\n"); + } // if + } // if + } // for t_j + // dealloc lcs pos level + lcs_nodes[len_lcs - t_i - 1] = va_array_destroy(va_std_allocator, lcs_nodes[len_lcs - t_i - 1]); + } // for t_i + + // deallocation + lcs_nodes = va_std_allocator.alloc(va_std_allocator.context, lcs_nodes, len_lcs, 0); + + printf("#nodes: %zu\n#edges: %zu\n", va_array_length(graph.nodes), va_array_length(graph.edges)); + printf("source: %u\n", graph.source); + for (size_t i = 0; i < va_array_length(graph.nodes); ++i) + { + printf("%zu: (%u, %u, %u):\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length); + if (graph.nodes[i].lambda != GVA_NULL) + { + printf(" (%u, %u, %u): lambda\n", graph.nodes[graph.nodes[i].lambda].row, graph.nodes[graph.nodes[i].lambda].col, graph.nodes[graph.nodes[i].lambda].length); + } // if + for (uint32_t j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) + { + printf(" (%u, %u, %u): ", graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length); + edges2(((VA_LCS_Node) {graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, 0, 0}), + ((VA_LCS_Node) {graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length, 0, 0}), + graph.nodes[i].row == shift && graph.nodes[i].col == shift, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, len_obs, observed, &(VA_Variant) {0, 0, 0, 0}); + } // for + } // for + + + bfs_traversal2(graph, len_obs, observed); + + return graph; +} // build \ No newline at end of file diff --git a/src/main.c b/src/main.c index f6520ed..217c7ef 100644 --- a/src/main.c +++ b/src/main.c @@ -7,6 +7,7 @@ #include "../include/array.h" // va_array_* #include "../include/edit.h" // va_edit #include "../include/graph.h" // Graph, to_dot +#include "../include/graph2.h" // build #include "../include/std_alloc.h" // va_std_allocator From 33d621398696c38f2e79f427c58e8b78e6656e66 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Thu, 3 Apr 2025 10:17:59 +0200 Subject: [PATCH 156/704] Undo. --- src/graph2.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/graph2.c b/src/graph2.c index 47fe7e3..7685e2b 100644 --- a/src/graph2.c +++ b/src/graph2.c @@ -67,11 +67,8 @@ bfs_traversal2(Graph2 const graph, size_t const len_obs, char const observed[sta for (size_t i = 0; i < va_array_length(graph.nodes); ++i) { - // if (NULL != table) // silence static analyzer - { - table[i].depth = 0; - table[i].next = GVA_NULL; - } + table[i].depth = 0; + table[i].next = GVA_NULL; } // for uint32_t head = graph.source; uint32_t tail = graph.source; From ed9dd0fd8e81ce0cd251581e5ea439de4fb73fb1 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Tue, 8 Apr 2025 11:46:06 +0200 Subject: [PATCH 157/704] Debug infra. --- include/extract.h | 9 +++++++ include/graph.h | 6 ++++- src/extract.c | 64 ++++++++++++++++++++++++++++++----------------- src/graph.c | 54 +++++++++++++++++++++++++-------------- src/main.c | 15 ++++++++--- test.py | 14 +++++++---- 6 files changed, 111 insertions(+), 51 deletions(-) diff --git a/include/extract.h b/include/extract.h index e69de29..c233ddd 100644 --- a/include/extract.h +++ b/include/extract.h @@ -0,0 +1,9 @@ +#include "../include/alloc.h" // VA_Allocator +#include "../include/graph.h" // Graph + + +void +local_supremal(VA_Allocator const allocator, Graph const graph, size_t const len_obs, char const observed[static len_obs], bool const debug); + +void +canonical(VA_Allocator const allocator, Graph const graph, size_t const len_obs, char const observed[static len_obs], bool const debug); diff --git a/include/graph.h b/include/graph.h index deb5059..47dd17d 100644 --- a/include/graph.h +++ b/include/graph.h @@ -32,13 +32,17 @@ Graph build_graph(VA_Allocator const allocator, size_t const len_ref, size_t const len_obs, size_t const len_lcs, VA_LCS_Node* lcs_nodes[static len_lcs], - size_t const shift); + size_t const shift, bool const debug); void to_dot(Graph const graph, size_t const len_obs, char const observed[static len_obs]); +void +to_json(Graph const graph, size_t const len_obs, char const observed[static len_obs], bool const lambda); + + size_t edges(uint32_t const head_row, uint32_t const head_col, uint32_t const head_length, uint32_t const tail_row, uint32_t const tail_col, uint32_t const tail_length, diff --git a/src/extract.c b/src/extract.c index e5cc45c..69b5bba 100644 --- a/src/extract.c +++ b/src/extract.c @@ -47,7 +47,7 @@ intersection(uint32_t lhs, uint32_t rhs, size_t const length, Post_Table const v } // intersection -static void +void local_supremal(VA_Allocator const allocator, Graph const graph, size_t const len_obs, char const observed[static len_obs]) { uint32_t const length = va_array_length(graph.nodes); @@ -154,23 +154,26 @@ typedef struct static inline uint32_t -lca(uint32_t* const start, uint32_t lhs, uint32_t rhs, size_t const length, LCA_Table const visited[static length]) +lca(uint32_t* const start, uint32_t lhs, uint32_t rhs, size_t const length, LCA_Table const visited[static length], bool const debug) { uint32_t lhs_start = *start; uint32_t rhs_start = *start; while (lhs != rhs) { - fprintf(stderr, " lca %u (%d), %u (%d)\n", lhs, lhs_start, rhs, rhs_start); + if (debug) + fprintf(stderr, " lca %u (%d), %u (%d)\n", lhs, lhs_start, rhs, rhs_start); while (visited[lhs].rank > visited[rhs].rank) { - fprintf(stderr, " left\n"); + if (debug) + fprintf(stderr, " left\n"); lhs_start = visited[lhs].start; lhs = visited[lhs].lca; } // if while (visited[rhs].rank > visited[lhs].rank) { - fprintf(stderr, " right\n"); + if (debug) + fprintf(stderr, " right\n"); rhs_start = visited[rhs].start; rhs = visited[rhs].lca; } // if @@ -192,8 +195,8 @@ print_lca_table(size_t const length, LCA_Table const visited[static length], uin } // print_lca_table -static void -canonical(VA_Allocator const allocator, Graph const graph, size_t const len_obs, char const observed[static len_obs]) +void +canonical(VA_Allocator const allocator, Graph const graph, size_t const len_obs, char const observed[static len_obs], bool const debug) { uint32_t const length = va_array_length(graph.nodes); LCA_Table* visited = allocator.alloc(allocator.context, NULL, 0, sizeof(*visited) * length); @@ -221,11 +224,13 @@ canonical(VA_Allocator const allocator, Graph const graph, size_t const len_obs, // main loop over a queue for (uint32_t head = graph.source, tail = graph.source; head != (uint32_t) -1; head = visited[head].next) { - fprintf(stderr, "pop %u @ %u\n", head, visited[head].depth); + if (debug) + fprintf(stderr, "pop %u @ %u\n", head, visited[head].depth); if (graph.nodes[head].edges == (uint32_t) -1) { - fprintf(stderr, " sink\n"); + if (debug) + fprintf(stderr, " sink\n"); sink = head; continue; } // if @@ -236,7 +241,8 @@ canonical(VA_Allocator const allocator, Graph const graph, size_t const len_obs, if (visited[lambda].depth == (uint32_t) -1) { // add lambda in stack order - fprintf(stderr, " push lambda %u @ %u\n", lambda, visited[head].depth); + if (debug) + fprintf(stderr, " push lambda %u @ %u\n", lambda, visited[head].depth); visited[visited[head].next].prev = lambda; visited[lambda] = (LCA_Table) {head, rank, visited[head].depth, -1, -1, head, visited[head].next}; @@ -245,9 +251,11 @@ canonical(VA_Allocator const allocator, Graph const graph, size_t const len_obs, } // if else if (visited[lambda].depth == visited[head].depth) { - fprintf(stderr, " update lambda %u @ %u\n", lambda, visited[head].depth); - fprintf(stderr, " lca(%u, %u)\n", visited[lambda].lca, head); - visited[lambda].lca = lca(&visited[lambda].start, visited[lambda].lca, head, length, visited); + if (debug) { + fprintf(stderr, " update lambda %u @ %u\n", lambda, visited[head].depth); + fprintf(stderr, " lca(%u, %u)\n", visited[lambda].lca, head); + } + visited[lambda].lca = lca(&visited[lambda].start, visited[lambda].lca, head, length, visited, false); // FIXME: what is correct here? // AGGCCG CGCAGCCTC ignores the common end position @@ -257,16 +265,19 @@ canonical(VA_Allocator const allocator, Graph const graph, size_t const len_obs, //visited[lambda].end = graph.nodes[head].row; // this simulates the empty variant on a lambda edge - fprintf(stderr, " = %u (%u:%u)\n", visited[lambda].lca, visited[lambda].start, visited[lambda].end); + if (debug) + fprintf(stderr, " = %u (%u:%u)\n", visited[lambda].lca, visited[lambda].start, visited[lambda].end); } // if else if (visited[head].next == lambda) { - fprintf(stderr, " improve lambda in place %u @ %u\n", lambda, visited[head].depth); + if (debug) + fprintf(stderr, " improve lambda in place %u @ %u\n", lambda, visited[head].depth); visited[lambda] = (LCA_Table) {head, visited[lambda].rank, visited[head].depth, -1, -1, visited[lambda].prev, visited[lambda].next}; } // if else { - fprintf(stderr, " improve lambda %u @ %u\n", lambda, visited[head].depth); + if (debug) + fprintf(stderr, " improve lambda %u @ %u\n", lambda, visited[head].depth); if (lambda == tail) { @@ -292,7 +303,8 @@ canonical(VA_Allocator const allocator, Graph const graph, size_t const len_obs, if (visited[edge_tail].depth == (uint32_t) -1) { // add regular successors in queue order - fprintf(stderr, " push %u @ %u\n", edge_tail, visited[head].depth + 1); + if (debug) + fprintf(stderr, " push %u @ %u\n", edge_tail, visited[head].depth + 1); visited[edge_tail] = (LCA_Table) {head, rank, visited[head].depth + 1, graph.edges[i].variant.start, graph.edges[i].variant.end, tail, -1}; rank += 1; visited[tail].next = edge_tail; @@ -300,23 +312,29 @@ canonical(VA_Allocator const allocator, Graph const graph, size_t const len_obs, } // if else if (visited[edge_tail].depth - 1 == visited[head].depth) { - fprintf(stderr, " update %u @ %u\n", edge_tail, visited[edge_tail].depth); - fprintf(stderr, " lca(%u, %u)\n", visited[edge_tail].lca, head); + if (debug) + { + fprintf(stderr, " update %u @ %u\n", edge_tail, visited[edge_tail].depth); + fprintf(stderr, " lca(%u, %u)\n", visited[edge_tail].lca, head); + } visited[edge_tail].start = MIN(visited[edge_tail].start, graph.edges[i].variant.start); - visited[edge_tail].lca = lca(&visited[edge_tail].start, visited[edge_tail].lca, head, length, visited); + visited[edge_tail].lca = lca(&visited[edge_tail].start, visited[edge_tail].lca, head, length, visited, false); visited[edge_tail].end = MAX(visited[edge_tail].end, graph.edges[i].variant.end); - fprintf(stderr, " = %u (%u:%u)\n", visited[edge_tail].lca, visited[edge_tail].start, visited[edge_tail].end); + if (debug) + fprintf(stderr, " = %u (%u:%u)\n", visited[edge_tail].lca, visited[edge_tail].start, visited[edge_tail].end); } // if else { - fprintf(stderr, " skip %u @ %u\n", edge_tail, visited[edge_tail].depth); + if (debug) + fprintf(stderr, " skip %u @ %u\n", edge_tail, visited[edge_tail].depth); } // else //print_lca_table(length, visited, head, tail); } // for } // for - print_lca_table(length, visited, -1, -1); + if (debug) + print_lca_table(length, visited, -1, -1); // the canonical variant is given in the reverse order (for now): the Python checker needs to reverse this list for (uint32_t tail = sink; tail != (uint32_t) -1; tail = visited[tail].lca) diff --git a/src/graph.c b/src/graph.c index 4d2a2b4..ce6b014 100644 --- a/src/graph.c +++ b/src/graph.c @@ -8,9 +8,10 @@ #include "../include/alloc.h" // VA_Allocator #include "../include/array.h" // va_array_* #include "../include/edit.h" // VA_LCS_Node, va_edit +#include "../include/extract.h" // canonical, local_supremal #include "../include/std_alloc.h" // va_std_allocator #include "../include/variant.h" // VA_Variant -#include "../include/graph.h" // Edge, Graph, Node +// #include "../include/graph.h" // Edge, Graph, Node #define MAX(lhs, rhs) (((lhs) > (rhs)) ? (lhs) : (rhs)) @@ -51,7 +52,7 @@ Graph build_graph(VA_Allocator const allocator, size_t const len_ref, size_t const len_obs, size_t const len_lcs, VA_LCS_Node* lcs_nodes[static len_lcs], - size_t const shift) + size_t const shift, bool const debug) { Graph graph = {.nodes = NULL, .edges = NULL}; @@ -82,7 +83,8 @@ build_graph(VA_Allocator const allocator, uint32_t max_sink = 0; sink.idx = add_node(allocator, &graph, sink.row, sink.col, sink.length - 1); - printf("MAKE NODE %u: (%u, %u, %u)\n", sink.idx, sink.row, sink.col, sink.length - 1); + if (debug) + printf("MAKE NODE %u: (%u, %u, %u)\n", sink.idx, sink.row, sink.col, sink.length - 1); size_t here = 0; VA_LCS_Node* const heads = lcs_nodes[len_lcs - 1]; for (size_t i = 0; i < va_array_length(heads); ++i) @@ -93,9 +95,11 @@ build_graph(VA_Allocator const allocator, max_sink = MAX(max_sink, sink.row + sink.length - 1); heads[i].idx = add_node(allocator, &graph, heads[i].row, heads[i].col, heads[i].length); - printf("MAKE NODE %u: (%u, %u, %u)\n", heads[i].idx, heads[i].row, heads[i].col, heads[i].length); + if (debug) + printf("MAKE NODE %u: (%u, %u, %u)\n", heads[i].idx, heads[i].row, heads[i].col, heads[i].length); graph.nodes[heads[i].idx].edges = add_edge(allocator, &graph, sink.idx, graph.nodes[heads[i].idx].edges, variant); - printf("MAKE EDGE (%u %u %u) -> (%u %u %u): " VAR_FMT "\n", heads[i].row, heads[i].col, heads[i].length, sink.row, sink.col, sink.length, print_variant(variant, "0123456789")); + if (debug) + printf("MAKE EDGE (%u %u %u) -> (%u %u %u): " VAR_FMT "\n", heads[i].row, heads[i].col, heads[i].length, sink.row, sink.col, sink.length, print_variant(variant, "0123456789")); here = i + 1; } // if } // for @@ -105,7 +109,8 @@ build_graph(VA_Allocator const allocator, sink.length -= 1; sink.incoming = len_lcs - 1; va_array_insert(allocator, lcs_nodes[len_lcs - 1], sink, here); - printf("INSERT (%u %u %u) here: %zu\n", sink.row, sink.col, sink.length, here); + if (debug) + printf("INSERT (%u %u %u) here: %zu\n", sink.row, sink.col, sink.length, here); } // if for (size_t i = len_lcs - 1; i >= 1; --i) @@ -130,10 +135,12 @@ build_graph(VA_Allocator const allocator, if (heads[k].incoming == i) { - printf("SPLIT at %zu\n", i); + if (debug) + printf("SPLIT at %zu\n", i); uint32_t const split_idx = heads[k].idx; heads[k].idx = add_node(allocator, &graph, heads[k].row, heads[k].col, heads[k].length); - printf("MAKE NODE %u: (%u, %u, %u)\n", heads[k].idx, heads[k].row, heads[k].col, heads[k].length); + if (debug) + printf("MAKE NODE %u: (%u, %u, %u)\n", heads[k].idx, heads[k].row, heads[k].col, heads[k].length); heads[k].incoming = 0; // lambda-edge @@ -142,19 +149,22 @@ build_graph(VA_Allocator const allocator, graph.nodes[split_idx].row += heads[k].length; graph.nodes[split_idx].col += heads[k].length; graph.nodes[split_idx].length -= heads[k].length; - printf("RELABEL NODE %u: (%u, %u, %u)\n", split_idx, graph.nodes[split_idx].row,graph.nodes[split_idx].col, graph.nodes[split_idx].length); + if (debug) + printf("RELABEL NODE %u: (%u, %u, %u)\n", split_idx, graph.nodes[split_idx].row,graph.nodes[split_idx].col, graph.nodes[split_idx].length); } // if else { if (heads[k].idx == GVA_NULL) { heads[k].idx = add_node(allocator, &graph, heads[k].row, heads[k].col, heads[k].length); - printf("MAKE NODE %u: (%u, %u, %u)\n", heads[k].idx, heads[k].row, heads[k].col, heads[k].length); + if (debug) + printf("MAKE NODE %u: (%u, %u, %u)\n", heads[k].idx, heads[k].row, heads[k].col, heads[k].length); } // if } // else graph.nodes[heads[k].idx].edges = add_edge(allocator, &graph, tail.idx, graph.nodes[heads[k].idx].edges, variant); - printf("MAKE EDGE (%u %u %u) -> (%u %u %u): " VAR_FMT "\n", heads[k].row, heads[k].col, heads[k].length, tail.row, tail.col, tail.length, print_variant(variant, "0123456789")); + if (debug) + printf("MAKE EDGE (%u %u %u) -> (%u %u %u): " VAR_FMT "\n", heads[k].row, heads[k].col, heads[k].length, tail.row, tail.col, tail.length, print_variant(variant, "0123456789")); here = k + 1; } // if @@ -168,7 +178,8 @@ build_graph(VA_Allocator const allocator, lcs_nodes[i][j].incoming = i; } // if va_array_insert(allocator, lcs_nodes[i - 1], lcs_nodes[i][j], here); - printf("INSERT (%u %u %u) here: %zu\n", lcs_nodes[i][j].row, lcs_nodes[i][j].col, lcs_nodes[i][j].length, here); + if (debug) + printf("INSERT (%u %u %u) here: %zu\n", lcs_nodes[i][j].row, lcs_nodes[i][j].col, lcs_nodes[i][j].length, here); } // if } // for lcs_nodes[i] = va_array_destroy(allocator, lcs_nodes[i]); @@ -185,7 +196,8 @@ build_graph(VA_Allocator const allocator, { source = (VA_LCS_Node) {.row = shift, .col = shift, .length = 0}; source.idx = add_node(allocator, &graph, source.row, source.col, source.length); - printf("MAKE NODE %u: (%u, %u, %u)\n", source.idx, source.row, source.col, source.length); + if (debug) + printf("MAKE NODE %u: (%u, %u, %u)\n", source.idx, source.row, source.col, source.length); } // else for (size_t i = start; i < va_array_length(lcs_nodes[0]); ++i) @@ -202,7 +214,8 @@ build_graph(VA_Allocator const allocator, VA_Variant const variant = {source.row, lcs_nodes[0][i].row + lcs_nodes[0][i].length - 1, source.col - shift, lcs_nodes[0][i].col + lcs_nodes[0][i].length - 1 - shift}; graph.nodes[source.idx].edges = add_edge(allocator, &graph, lcs_nodes[0][i].idx, graph.nodes[source.idx].edges, variant); - printf("MAKE EDGE (%u %u %u) -> (%u %u %u): " VAR_FMT "\n", source.row, source.col, source.length, lcs_nodes[0][i].row, lcs_nodes[0][i].col, lcs_nodes[0][i].length, print_variant(variant, "0123456789")); + if (debug) + printf("MAKE EDGE (%u %u %u) -> (%u %u %u): " VAR_FMT "\n", source.row, source.col, source.length, lcs_nodes[0][i].row, lcs_nodes[0][i].col, lcs_nodes[0][i].length, print_variant(variant, "0123456789")); } // if } // for lcs_nodes[0] = va_array_destroy(allocator, lcs_nodes[0]); @@ -256,6 +269,11 @@ bfs_traversal(VA_Allocator const allocator, Graph const graph, size_t const len_ uint32_t next; }* table = allocator.alloc(allocator.context, NULL, 0, sizeof(*table) * va_array_length(graph.nodes)); + if (table == NULL) + { + return -1; + } + for (size_t i = 0; i < va_array_length(graph.nodes); ++i) { table[i].depth = 0; @@ -350,8 +368,7 @@ lambda_edges(Graph const graph, size_t const len_obs, char const observed[static printf("\n ],\n"); } // lambda_edges -/* -static void +void to_json(Graph const graph, size_t const len_obs, char const observed[static len_obs], bool const lambda) { printf("{\n \"source\": \"s%u\",\n \"nodes\": {\n", graph.source); @@ -367,14 +384,13 @@ to_json(Graph const graph, size_t const len_obs, char const observed[static len_ } printf(" \"supremal\": \"%u:%u/%.*s\",\n", graph.supremal.start, graph.supremal.end, (int) graph.supremal.obs_end - graph.supremal.obs_start, observed + graph.supremal.obs_start); printf(" \"local_supremal\": [\n"); - local_supremal(va_std_allocator, graph, len_obs, observed); + local_supremal(va_std_allocator, graph, len_obs, observed, false); printf("\n ],\n"); printf(" \"canonical\": [\n"); - canonical(va_std_allocator, graph, len_obs, observed); + canonical(va_std_allocator, graph, len_obs, observed, false); printf("\n ]\n"); printf("}"); } // to_json -*/ size_t diff --git a/src/main.c b/src/main.c index 217c7ef..6024c60 100644 --- a/src/main.c +++ b/src/main.c @@ -53,7 +53,7 @@ check(size_t const len_ref, char const reference[static len_ref], } // for } // if - Graph graph = build_graph(va_std_allocator, len_ref, len_obs, len_lcs, lcs_nodes, 0); + Graph graph = build_graph(va_std_allocator, len_ref, len_obs, len_lcs, lcs_nodes, 0, false); if (debug) { @@ -160,9 +160,18 @@ main(int argc, char* argv[static argc + 1]) char const* const restrict observed = argv[2]; size_t const len_ref = strlen(reference); size_t const len_obs = strlen(observed); - check(len_ref, reference, len_obs, observed, true); + // check(len_ref, reference, len_obs, observed, true); + // build(len_ref, reference, len_obs, observed, 0); - build(len_ref, reference, len_obs, observed, 0); + VA_LCS_Node** lcs_nodes = NULL; + size_t const len_lcs = va_edit(va_std_allocator, len_ref, reference, len_obs, observed, &lcs_nodes); + + Graph graph = build_graph(va_std_allocator, len_ref, len_obs, len_lcs, lcs_nodes, 0, false); + + // to_dot(graph, len_obs, observed); + to_json(graph, len_obs, observed, false); + + destroy(va_std_allocator, &graph); } // if else diff --git a/test.py b/test.py index d65cdf6..45c0042 100644 --- a/test.py +++ b/test.py @@ -105,7 +105,7 @@ def check(reference, observed, debug=False, timeout=2): for cnode in cgraph["nodes"].values(): try: - cnode["node"] = next(node for node in nodes if node == LCSgraph.Node(cnode["row"], cnode["col"], cnode["length"])) + cnode["node"] = next(node for node in nodes if node.row == cnode["row"] and node.col == cnode["col"]) except StopIteration: raise ValueError(f'{cnode} not in graph nodes') from None @@ -125,6 +125,10 @@ def check(reference, observed, debug=False, timeout=2): if debug: print(list(reversed(cgraph["canonical"])), canonical(graph)) + + print() + print(cgraph["canonical"]) + print(canonical(graph)) assert len(cgraph["canonical"]) == len(canonical(graph)), f'canonical length' for lhs, rhs in zip(reversed(cgraph["canonical"]), canonical(graph)): @@ -133,7 +137,7 @@ def check(reference, observed, debug=False, timeout=2): def main(): if len(sys.argv) == 3: - return check(sys.argv[1], sys.argv[2], debug=True) + return check(sys.argv[1], sys.argv[2], debug=False) signal.signal(signal.SIGINT, handler) @@ -145,15 +149,15 @@ def main(): #if random.random() > 0.5: # prefix = random_sequence(1000) # suffix = random_sequence(1000) - reference = prefix + random_sequence(30) + suffix - observed = prefix + random_sequence(30) + suffix + reference = prefix + random_sequence(130) + suffix + observed = prefix + random_sequence(100) + suffix if n % 1_000 == 0: print(n) try: check(reference, observed) - nx_extract(reference, observed) + # nx_extract(reference, observed) n += 1 except KeyboardInterrupt: break From b272346afafab7f09988ccef5800d6a0f5c404f4 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Tue, 8 Apr 2025 11:51:37 +0200 Subject: [PATCH 158/704] WIP. --- src/main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main.c b/src/main.c index 6024c60..28b48d1 100644 --- a/src/main.c +++ b/src/main.c @@ -160,8 +160,8 @@ main(int argc, char* argv[static argc + 1]) char const* const restrict observed = argv[2]; size_t const len_ref = strlen(reference); size_t const len_obs = strlen(observed); - // check(len_ref, reference, len_obs, observed, true); - // build(len_ref, reference, len_obs, observed, 0); + check(len_ref, reference, len_obs, observed, true); + build(len_ref, reference, len_obs, observed, 0); VA_LCS_Node** lcs_nodes = NULL; size_t const len_lcs = va_edit(va_std_allocator, len_ref, reference, len_obs, observed, &lcs_nodes); @@ -169,7 +169,7 @@ main(int argc, char* argv[static argc + 1]) Graph graph = build_graph(va_std_allocator, len_ref, len_obs, len_lcs, lcs_nodes, 0, false); // to_dot(graph, len_obs, observed); - to_json(graph, len_obs, observed, false); + // to_json(graph, len_obs, observed, false); destroy(va_std_allocator, &graph); From ee8e15e677bb3ced19ee8b79ce944f091b125417 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 8 Apr 2025 14:03:41 +0200 Subject: [PATCH 159/704] WIP incoming for converse edges --- src/graph2.c | 8 +++++--- src/main.c | 6 +++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/graph2.c b/src/graph2.c index 7685e2b..0542758 100644 --- a/src/graph2.c +++ b/src/graph2.c @@ -225,13 +225,15 @@ build(size_t const len_ref, char const reference[static len_ref], else { printf("CONVERSE\n"); + VA_Variant variant; if (head->idx != GVA_NULL && edges2(*tail, *head, tail->row == shift && tail->col == shift, - false, len_obs, observed, &(VA_Variant) {0, 0, 0, 0})) + false, len_obs, observed, &variant)) { va_array_append(va_std_allocator, graph.edges, ((Edge2) {head->idx, graph.nodes[tail->idx].edges})); graph.nodes[tail->idx].edges = va_array_length(graph.edges) - 1; printf("MAKE EDGE\n"); - } + } // if + tail->incoming = MIN(tail->incoming, variant.start); } // else } // if else @@ -397,4 +399,4 @@ build(size_t const len_ref, char const reference[static len_ref], bfs_traversal2(graph, len_obs, observed); return graph; -} // build \ No newline at end of file +} // build diff --git a/src/main.c b/src/main.c index 6024c60..28b48d1 100644 --- a/src/main.c +++ b/src/main.c @@ -160,8 +160,8 @@ main(int argc, char* argv[static argc + 1]) char const* const restrict observed = argv[2]; size_t const len_ref = strlen(reference); size_t const len_obs = strlen(observed); - // check(len_ref, reference, len_obs, observed, true); - // build(len_ref, reference, len_obs, observed, 0); + check(len_ref, reference, len_obs, observed, true); + build(len_ref, reference, len_obs, observed, 0); VA_LCS_Node** lcs_nodes = NULL; size_t const len_lcs = va_edit(va_std_allocator, len_ref, reference, len_obs, observed, &lcs_nodes); @@ -169,7 +169,7 @@ main(int argc, char* argv[static argc + 1]) Graph graph = build_graph(va_std_allocator, len_ref, len_obs, len_lcs, lcs_nodes, 0, false); // to_dot(graph, len_obs, observed); - to_json(graph, len_obs, observed, false); + // to_json(graph, len_obs, observed, false); destroy(va_std_allocator, &graph); From fdd6d2890e21cb2578617a0957b025e3d16aae3d Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 8 Apr 2025 16:44:47 +0200 Subject: [PATCH 160/704] WIP: before multi-split --- include/graph2.h | 4 ++ src/graph.c | 1 + src/graph2.c | 120 +++++++++++++++++++++++++++++++---------------- src/main.c | 6 ++- 4 files changed, 88 insertions(+), 43 deletions(-) diff --git a/include/graph2.h b/include/graph2.h index 0b97995..ee20cf0 100644 --- a/include/graph2.h +++ b/include/graph2.h @@ -32,3 +32,7 @@ Graph2 build(size_t const len_ref, char const reference[static len_ref], size_t const len_obs, char const observed[static len_obs], size_t const shift); + + +void +to_json2(Graph2 const graph, size_t const len_obs, char const observed[static len_obs]); diff --git a/src/graph.c b/src/graph.c index ce6b014..320ee02 100644 --- a/src/graph.c +++ b/src/graph.c @@ -368,6 +368,7 @@ lambda_edges(Graph const graph, size_t const len_obs, char const observed[static printf("\n ],\n"); } // lambda_edges + void to_json(Graph const graph, size_t const len_obs, char const observed[static len_obs], bool const lambda) { diff --git a/src/graph2.c b/src/graph2.c index 0542758..e8e4c9f 100644 --- a/src/graph2.c +++ b/src/graph2.c @@ -43,7 +43,7 @@ edges2(VA_LCS_Node const head, VA_LCS_Node const tail, if (head_offset > head_length || (tail_length > 0 && tail_offset >= tail_length)) { - printf("NO EDGE\n"); + fprintf(stderr, "NO EDGE\n"); return 0; } // if @@ -51,7 +51,7 @@ edges2(VA_LCS_Node const head, VA_LCS_Node const tail, *variant = (VA_Variant) {row + head_offset, tail.row + tail_offset, col + head_offset, tail.col + tail_offset}; - printf(VAR_FMT " x %u\n", print_variant((*variant), observed), count); + fprintf(stderr, VAR_FMT " x %u\n", print_variant((*variant), observed), count); return count; } // edges2 @@ -65,6 +65,11 @@ bfs_traversal2(Graph2 const graph, size_t const len_obs, char const observed[sta uint32_t next; }* table = va_std_allocator.alloc(va_std_allocator.context, NULL, 0, sizeof(*table) * va_array_length(graph.nodes)); + if (table == NULL) + { + return -1; + } // if + for (size_t i = 0; i < va_array_length(graph.nodes); ++i) { table[i].depth = 0; @@ -74,17 +79,19 @@ bfs_traversal2(Graph2 const graph, size_t const len_obs, char const observed[sta uint32_t tail = graph.source; size_t count = 0; - printf("digraph{\nrankdir=LR\nedge[fontname=monospace]\nnode[fixedsize=true,fontname=serif,shape=circle,width=1]\nsi[label=\"\",shape=none,width=0]\n"); - printf("si->s%u\n", graph.source); + fprintf(stderr, "digraph{\nrankdir=LR\nedge[fontname=monospace]\nnode[fixedsize=true,fontname=serif,shape=circle,width=1]\nsi[label=\"\",shape=none,width=0]\n"); + fprintf(stderr, "si->s%u\n", graph.source); - //printf(" \"edges\": [\n"); + bool first = true; + + printf(" \"edges\": [\n"); while (head != GVA_NULL) { uint32_t len = graph.nodes[head].length; //printf("pop %u\n", head); for (uint32_t i = head; i != GVA_NULL; i = graph.nodes[i].lambda) { - printf("s%u[label=\"(%u, %u, %u)\"%s]\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, graph.nodes[i].edges == GVA_NULL && graph.nodes[i].lambda == GVA_NULL ? ",peripheries=2" : ""); + fprintf(stderr, "s%u[label=\"(%u, %u, %u)\"%s]\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, graph.nodes[i].edges == GVA_NULL && graph.nodes[i].lambda == GVA_NULL ? ",peripheries=2" : ""); if (i != head) { len += graph.nodes[i].length; @@ -98,14 +105,19 @@ bfs_traversal2(Graph2 const graph, size_t const len_obs, char const observed[sta } // if count += 1; VA_Variant variant; - uint32_t const count2 = edges2(((VA_LCS_Node) {graph.nodes[head].row, graph.nodes[head].col, len, 0, 0}), + uint32_t const count2 = edges2(((VA_LCS_Node) {graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, 0, 0}), ((VA_LCS_Node) {graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length, 0, 0}), graph.nodes[head].row == graph.nodes[graph.source].row && graph.nodes[head].col == graph.nodes[graph.source].col, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, len_obs, observed, &variant); for (uint32_t k = 0; k < count2; ++k) { - printf("s%u->s%u[label=\"" VAR_FMT "\"]\n", head, graph.edges[j].tail, print_variant(variant, observed)); - //printf(" {\"head\": \"s%u\", \"tail\": \"s%u\", \"variant\": \"" VAR_FMT "\"}%s", head, graph.edges[j].tail, print_variant(variant, observed), k < count2 - 1 ? ",\n" : ""); + if (!first) + { + printf(",\n"); + } // if + first = false; + fprintf(stderr, "s%u->s%u[label=\"" VAR_FMT "\"]\n", head, graph.edges[j].tail, print_variant(variant, observed)); + printf(" {\"head\": \"s%u\", \"tail\": \"s%u\", \"variant\": \"" VAR_FMT "\"}", head, graph.edges[j].tail, print_variant(variant, observed)); variant.start += 1; variant.end += 1; variant.obs_start += 1; @@ -136,8 +148,8 @@ bfs_traversal2(Graph2 const graph, size_t const len_obs, char const observed[sta */ } // while - printf("}\n"); - //printf("\n ],\n"); + fprintf(stderr, "}\n"); + printf("\n ]\n"); table = va_std_allocator.alloc(va_std_allocator.context, table, sizeof(*table) * va_array_length(graph.nodes), 0); @@ -150,7 +162,7 @@ build(size_t const len_ref, char const reference[static len_ref], size_t const len_obs, char const observed[static len_obs], size_t const shift) { - printf("build!\n"); + //printf("build!\n"); VA_LCS_Node** lcs_nodes = NULL; size_t const len_lcs = va_edit(va_std_allocator, len_ref, reference, len_obs, observed, &lcs_nodes); @@ -158,7 +170,20 @@ build(size_t const len_ref, char const reference[static len_ref], if (len_lcs == 0 || lcs_nodes == NULL) { - fprintf(stderr, "Trivial graph\n"); + va_array_append(va_std_allocator, graph.nodes, ((Node2) {shift, shift, 0, GVA_NULL, GVA_NULL})); + graph.source = va_array_length(graph.nodes) - 1; + + if (len_ref == 0 && len_obs == 0) + { + //graph.supremal = (VA_Variant) {0, 0, 0, 0}; + return graph; + } // if + va_array_append(va_std_allocator, graph.nodes, ((Node2) {len_ref, len_obs, 0, GVA_NULL, GVA_NULL})); + uint32_t const sink = va_array_length(graph.nodes) - 1; + //graph.supremal = (VA_Variant) {shift, shift + len_ref, 0, len_obs}; + + va_array_append(va_std_allocator, graph.edges, ((Edge2) {sink, graph.nodes[graph.source].edges})); + graph.nodes[graph.source].edges = va_array_length(graph.edges) - 1; return graph; } // if @@ -171,7 +196,7 @@ build(size_t const len_ref, char const reference[static len_ref], } // if va_array_append(va_std_allocator, graph.nodes, ((Node2) {last->row, last->col, last->length, GVA_NULL, GVA_NULL})); last->idx = va_array_length(graph.nodes) - 1; - printf("MAKE NODE %u: (%u, %u, %u)\n", last->idx, last->row, last->col, last->length); + fprintf(stderr, "MAKE NODE %u: (%u, %u, %u)\n", last->idx, last->row, last->col, last->length); last->incoming = -1; /* @@ -188,7 +213,7 @@ build(size_t const len_ref, char const reference[static len_ref], */ VA_LCS_Node source = {shift, shift, 0, -1, GVA_NULL}; - bool found_source = false; + bool found_source = last->row == shift && last->col == shift; bool is_sink = true; for (size_t t_i = 0; t_i < len_lcs; ++t_i) { @@ -201,7 +226,7 @@ build(size_t const len_ref, char const reference[static len_ref], // sink unreachable from tail, do not add to graph continue; } // if - printf("%u %u %u %d\n", tail->row, tail->col, tail->length, tail->incoming); + fprintf(stderr, "%u %u %u %d\n", tail->row, tail->col, tail->length, tail->incoming); uint32_t split_idx = tail->idx; for (size_t h_i = 0; h_i < MIN(len_lcs - t_i, tail->length + 1); ++h_i) @@ -212,7 +237,7 @@ build(size_t const len_ref, char const reference[static len_ref], { VA_LCS_Node* head = &lcs_nodes[len_lcs - t_i - h_i - 1][h_j]; - printf(" %u %u %u: ", head->row, head->col, head->length); + fprintf(stderr, " %u %u %u: ", head->row, head->col, head->length); if (head->row + head->length + h_i > tail->row + tail->length || head->col + head->length + h_i > tail->col + tail->length) @@ -220,20 +245,20 @@ build(size_t const len_ref, char const reference[static len_ref], if (tail->row + tail->length > head->row + head->length + h_i || tail->col + tail->length > head->col + head->length + h_i) { - printf("--\n"); // FIXME: skip the remainder of this (head) level + fprintf(stderr, "--\n"); // FIXME: skip the remainder of this (head) level } // if else { - printf("CONVERSE\n"); + fprintf(stderr, "CONVERSE\n"); VA_Variant variant; if (head->idx != GVA_NULL && edges2(*tail, *head, tail->row == shift && tail->col == shift, false, len_obs, observed, &variant)) { va_array_append(va_std_allocator, graph.edges, ((Edge2) {head->idx, graph.nodes[tail->idx].edges})); graph.nodes[tail->idx].edges = va_array_length(graph.edges) - 1; - printf("MAKE EDGE\n"); + fprintf(stderr, "MAKE EDGE\n"); + tail->incoming = MIN(tail->incoming, variant.start); } // if - tail->incoming = MIN(tail->incoming, variant.start); } // else } // if else @@ -246,7 +271,7 @@ build(size_t const len_ref, char const reference[static len_ref], { va_array_append(va_std_allocator, graph.nodes, ((Node2) {head->row, head->col, head->length, GVA_NULL, GVA_NULL})); head->idx = va_array_length(graph.nodes) - 1; - printf("MAKE NODE %u: (%u, %u, %u)\n", head->idx, head->row, head->col, head->length); + fprintf(stderr, "MAKE NODE %u: (%u, %u, %u)\n", head->idx, head->row, head->col, head->length); if (head->row == shift && head->col == shift) { // head is the source @@ -258,7 +283,7 @@ build(size_t const len_ref, char const reference[static len_ref], head->incoming = MIN(head->incoming, variant.start); if (variant.end + count > tail->incoming) { - printf("SPLIT %u %u %u @ %u\n", tail->row, tail->col, tail->length, variant.end + count - 1); + fprintf(stderr, "SPLIT %u %u %u @ %u\n", tail->row, tail->col, tail->length, tail->incoming); uint32_t const split_len = tail->incoming - tail->row; va_array_append(va_std_allocator, graph.nodes, ((Node2) {tail->row, tail->col, split_len, GVA_NULL, tail->idx})); @@ -267,11 +292,11 @@ build(size_t const len_ref, char const reference[static len_ref], graph.nodes[tail->idx].col += split_len; graph.nodes[tail->idx].length -= split_len; tail->incoming = variant.end + count; - printf(VAR_FMT "\n", print_variant(variant, observed)); - if (variant.start < variant.end + count - 1) + fprintf(stderr, VAR_FMT "\n", print_variant(variant, observed)); + if (count > 1) { // incoming edge - printf("INCOMING -> BOTH\n"); + fprintf(stderr, "INCOMING -> BOTH\n"); va_array_append(va_std_allocator, graph.edges, ((Edge2) {split_idx, graph.nodes[head->idx].edges})); graph.nodes[head->idx].edges = va_array_length(graph.edges) - 1; } // if @@ -284,10 +309,10 @@ build(size_t const len_ref, char const reference[static len_ref], // outgoing edges VA_Variant var; uint32_t const count2 = edges2(*tail, (VA_LCS_Node) {graph.nodes[graph.edges[i].tail].row, graph.nodes[graph.edges[i].tail].col, graph.nodes[graph.edges[i].tail].length, 0, 0}, tail->row == shift && tail->col == shift, graph.nodes[graph.edges[i].tail].edges == GVA_NULL && graph.nodes[graph.edges[i].tail].lambda == GVA_NULL, len_obs, observed, &var); - printf(" -> %u: " VAR_FMT " x %u ::\n", graph.edges[i].tail, print_variant(var, observed), count2); + fprintf(stderr, " -> %u: " VAR_FMT " x %u ::\n", graph.edges[i].tail, print_variant(var, observed), count2); if (var.start > variant.end + count - 1) { - printf(" -> TAIL\n"); + fprintf(stderr, " -> TAIL\n"); if (tail_tail != GVA_NULL) { graph.edges[tail_tail].next = i; @@ -300,7 +325,7 @@ build(size_t const len_ref, char const reference[static len_ref], } // if else if (var.end + count2 - 1 < variant.end + count) { - printf(" -> HEAD\n"); + fprintf(stderr, " -> HEAD\n"); if (head_tail != GVA_NULL) { graph.edges[head_tail].next = i; @@ -313,7 +338,7 @@ build(size_t const len_ref, char const reference[static len_ref], } // if else { - printf(" -> BOTH\n"); + fprintf(stderr, " -> BOTH\n"); if (tail_tail != GVA_NULL) { graph.edges[tail_tail].next = i; @@ -340,7 +365,7 @@ build(size_t const len_ref, char const reference[static len_ref], } // if va_array_append(va_std_allocator, graph.edges, ((Edge2) {tail->idx, graph.nodes[head->idx].edges})); graph.nodes[head->idx].edges = va_array_length(graph.edges) - 1; - printf("MAKE EDGE\n"); + fprintf(stderr, "MAKE EDGE\n"); } // if else { @@ -357,16 +382,16 @@ build(size_t const len_ref, char const reference[static len_ref], { va_array_append(va_std_allocator, graph.nodes, ((Node2) {source.row, source.col, source.length, GVA_NULL, GVA_NULL})); source.idx = va_array_length(graph.nodes) - 1; - printf("MAKE NODE %u: (%u, %u, %u)\n", source.idx, source.row, source.col, source.length); + fprintf(stderr, "MAKE NODE %u: (%u, %u, %u)\n", source.idx, source.row, source.col, source.length); graph.source = source.idx; } // if - printf("SOURCE %u %u %u: ", source.row, source.col, source.length); + fprintf(stderr, "SOURCE %u %u %u: ", source.row, source.col, source.length); // is this edges2 check always true? if (edges2(source, *tail, true, is_sink, len_obs, observed, &(VA_Variant) {0, 0, 0, 0})) { va_array_append(va_std_allocator, graph.edges, ((Edge2) {tail->idx, graph.nodes[source.idx].edges})); graph.nodes[source.idx].edges = va_array_length(graph.edges) - 1; - printf("MAKE EDGE\n"); + fprintf(stderr, "MAKE EDGE\n"); } // if } // if } // for t_j @@ -377,26 +402,39 @@ build(size_t const len_ref, char const reference[static len_ref], // deallocation lcs_nodes = va_std_allocator.alloc(va_std_allocator.context, lcs_nodes, len_lcs, 0); - printf("#nodes: %zu\n#edges: %zu\n", va_array_length(graph.nodes), va_array_length(graph.edges)); - printf("source: %u\n", graph.source); + fprintf(stderr, "#nodes: %zu\n#edges: %zu\n", va_array_length(graph.nodes), va_array_length(graph.edges)); + fprintf(stderr, "source: %u\n", graph.source); for (size_t i = 0; i < va_array_length(graph.nodes); ++i) { - printf("%zu: (%u, %u, %u):\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length); + fprintf(stderr, "%zu: (%u, %u, %u):\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length); if (graph.nodes[i].lambda != GVA_NULL) { - printf(" (%u, %u, %u): lambda\n", graph.nodes[graph.nodes[i].lambda].row, graph.nodes[graph.nodes[i].lambda].col, graph.nodes[graph.nodes[i].lambda].length); + fprintf(stderr, " (%u, %u, %u): lambda\n", graph.nodes[graph.nodes[i].lambda].row, graph.nodes[graph.nodes[i].lambda].col, graph.nodes[graph.nodes[i].lambda].length); } // if for (uint32_t j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) { - printf(" (%u, %u, %u): ", graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length); + fprintf(stderr, " (%u, %u, %u): ", graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length); edges2(((VA_LCS_Node) {graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, 0, 0}), ((VA_LCS_Node) {graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length, 0, 0}), graph.nodes[i].row == shift && graph.nodes[i].col == shift, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, len_obs, observed, &(VA_Variant) {0, 0, 0, 0}); } // for } // for - - bfs_traversal2(graph, len_obs, observed); + //bfs_traversal2(graph, len_obs, observed); return graph; } // build + + +void +to_json2(Graph2 const graph, size_t const len_obs, char const observed[static len_obs]) +{ + printf("{\n \"source\": \"s%u\",\n \"nodes\": {\n", graph.source); + for (uint32_t i = 0; i < va_array_length(graph.nodes); ++i) + { + printf(" \"s%u\": {\"row\": %u, \"col\": %u, \"length\": %u}%s\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, i < va_array_length(graph.nodes) - 1 ? "," : ""); + } // for + printf(" },\n"); + bfs_traversal2(graph, len_obs, observed); + printf("}"); +} // to_json2 diff --git a/src/main.c b/src/main.c index 28b48d1..e760d0f 100644 --- a/src/main.c +++ b/src/main.c @@ -160,8 +160,10 @@ main(int argc, char* argv[static argc + 1]) char const* const restrict observed = argv[2]; size_t const len_ref = strlen(reference); size_t const len_obs = strlen(observed); - check(len_ref, reference, len_obs, observed, true); - build(len_ref, reference, len_obs, observed, 0); + //check(len_ref, reference, len_obs, observed, true); + Graph2 graph2 = build(len_ref, reference, len_obs, observed, 0); + + to_json2(graph2, len_obs, observed); VA_LCS_Node** lcs_nodes = NULL; size_t const len_lcs = va_edit(va_std_allocator, len_ref, reference, len_obs, observed, &lcs_nodes); From cbbbe61634110d8ef9552c4c6f8c25800ece6c8d Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 8 Apr 2025 17:17:36 +0200 Subject: [PATCH 161/704] WIP multi-split --- src/graph2.c | 106 +++++++++++++-------------------------------------- 1 file changed, 27 insertions(+), 79 deletions(-) diff --git a/src/graph2.c b/src/graph2.c index e8e4c9f..66cd31e 100644 --- a/src/graph2.c +++ b/src/graph2.c @@ -157,6 +157,32 @@ bfs_traversal2(Graph2 const graph, size_t const len_obs, char const observed[sta } // bfs_traversal2 +static inline VA_Variant +shift_variant(VA_Variant const variant, uint32_t const shift) +{ + return (VA_Variant) {variant.start + shift, variant.end + shift, variant.obs_start + shift, variant.obs_end + shift}; +} // shift_variant + + +static void +split(Graph2 graph, VA_LCS_Node const* const head, uint32_t const count, VA_Variant const incoming, size_t const len_obs, char const observed[static len_obs]) +{ + fprintf(stderr, "SPLIT %u %u %u @ %u\n", head->row, head->col, head->length, head->incoming); + fprintf(stderr, "incoming: " VAR_FMT " x %u\n", print_variant(incoming, observed), count); + for (uint32_t i = 0; i < count; ++i) + { + uint32_t const offset = count - 1 - i; + fprintf(stderr, " " VAR_FMT "\n", print_variant(shift_variant(incoming, offset), observed)); + for (uint32_t j = graph.nodes[head->idx].edges; j != GVA_NULL; j = graph.edges[j].next) + { + Node2 const tail = graph.nodes[graph.edges[j].tail]; + VA_Variant outgoing; + uint32_t const count2 = edges2(*head, (VA_LCS_Node) {tail.row, tail.col, tail.length, 0, 0}, head->row == 0 && head->col == 0, tail.edges == GVA_NULL, len_obs, observed, &outgoing); + } // for + } // for +} // split + + Graph2 build(size_t const len_ref, char const reference[static len_ref], size_t const len_obs, char const observed[static len_obs], @@ -283,85 +309,7 @@ build(size_t const len_ref, char const reference[static len_ref], head->incoming = MIN(head->incoming, variant.start); if (variant.end + count > tail->incoming) { - fprintf(stderr, "SPLIT %u %u %u @ %u\n", tail->row, tail->col, tail->length, tail->incoming); - uint32_t const split_len = tail->incoming - tail->row; - va_array_append(va_std_allocator, graph.nodes, - ((Node2) {tail->row, tail->col, split_len, GVA_NULL, tail->idx})); - split_idx = va_array_length(graph.nodes) - 1; - graph.nodes[tail->idx].row += split_len; - graph.nodes[tail->idx].col += split_len; - graph.nodes[tail->idx].length -= split_len; - tail->incoming = variant.end + count; - fprintf(stderr, VAR_FMT "\n", print_variant(variant, observed)); - if (count > 1) - { - // incoming edge - fprintf(stderr, "INCOMING -> BOTH\n"); - va_array_append(va_std_allocator, graph.edges, ((Edge2) {split_idx, graph.nodes[head->idx].edges})); - graph.nodes[head->idx].edges = va_array_length(graph.edges) - 1; - } // if - uint32_t head_head = GVA_NULL; - uint32_t head_tail = GVA_NULL; - uint32_t tail_head = GVA_NULL; - uint32_t tail_tail = GVA_NULL; - for (uint32_t i = graph.nodes[tail->idx].edges; i != GVA_NULL; i = graph.edges[i].next) - { - // outgoing edges - VA_Variant var; - uint32_t const count2 = edges2(*tail, (VA_LCS_Node) {graph.nodes[graph.edges[i].tail].row, graph.nodes[graph.edges[i].tail].col, graph.nodes[graph.edges[i].tail].length, 0, 0}, tail->row == shift && tail->col == shift, graph.nodes[graph.edges[i].tail].edges == GVA_NULL && graph.nodes[graph.edges[i].tail].lambda == GVA_NULL, len_obs, observed, &var); - fprintf(stderr, " -> %u: " VAR_FMT " x %u ::\n", graph.edges[i].tail, print_variant(var, observed), count2); - if (var.start > variant.end + count - 1) - { - fprintf(stderr, " -> TAIL\n"); - if (tail_tail != GVA_NULL) - { - graph.edges[tail_tail].next = i; - } // if - if (tail_head == GVA_NULL) - { - tail_head = i; - } // if - tail_tail = i; - } // if - else if (var.end + count2 - 1 < variant.end + count) - { - fprintf(stderr, " -> HEAD\n"); - if (head_tail != GVA_NULL) - { - graph.edges[head_tail].next = i; - } // if - if (head_head == GVA_NULL) - { - head_head = i; - } // if - head_tail = i; - } // if - else - { - fprintf(stderr, " -> BOTH\n"); - if (tail_tail != GVA_NULL) - { - graph.edges[tail_tail].next = i; - } // if - if (tail_head == GVA_NULL) - { - tail_head = i; - } // if - tail_tail = i; - va_array_append(va_std_allocator, graph.edges, ((Edge2) {graph.edges[i].tail, head_head})); - head_head = va_array_length(graph.edges) - 1; - } // else - } // for - if (head_tail != GVA_NULL) - { - graph.edges[head_tail].next = GVA_NULL; - } // if - if (tail_tail != GVA_NULL) - { - graph.edges[tail_tail].next = GVA_NULL; - } // if - graph.nodes[split_idx].edges = head_head; - graph.nodes[tail->idx].edges = tail_head; + split(graph, tail, count, variant, len_obs, observed); } // if va_array_append(va_std_allocator, graph.edges, ((Edge2) {tail->idx, graph.nodes[head->idx].edges})); graph.nodes[head->idx].edges = va_array_length(graph.edges) - 1; From bc4a959b7d7a2d64a51a18c44764c8d9a7c8ca45 Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 9 Apr 2025 11:49:36 +0200 Subject: [PATCH 162/704] Some more QoL --- src/graph2.c | 45 +++++++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/src/graph2.c b/src/graph2.c index 66cd31e..34bc5e5 100644 --- a/src/graph2.c +++ b/src/graph2.c @@ -21,11 +21,10 @@ static uint32_t const GVA_NULL = UINT32_MAX; - static uint32_t edges2(VA_LCS_Node const head, VA_LCS_Node const tail, bool const is_source, bool const is_sink, - size_t const len_obs, char const observed[static len_obs], VA_Variant* const variant) + VA_Variant* const variant) { // printf("%u %u %u -> %u %u %u %s %s\n", head.row, head.col, head.length, tail.row, tail.col, tail.length, is_source ? "SOURCE" : "", is_sink ? "SINK" : ""); @@ -43,7 +42,7 @@ edges2(VA_LCS_Node const head, VA_LCS_Node const tail, if (head_offset > head_length || (tail_length > 0 && tail_offset >= tail_length)) { - fprintf(stderr, "NO EDGE\n"); + //fprintf(stderr, "NO EDGE\n"); return 0; } // if @@ -51,7 +50,7 @@ edges2(VA_LCS_Node const head, VA_LCS_Node const tail, *variant = (VA_Variant) {row + head_offset, tail.row + tail_offset, col + head_offset, tail.col + tail_offset}; - fprintf(stderr, VAR_FMT " x %u\n", print_variant((*variant), observed), count); + //fprintf(stderr, VAR_FMT " x %u\n", print_variant((*variant), observed), count); return count; } // edges2 @@ -107,7 +106,7 @@ bfs_traversal2(Graph2 const graph, size_t const len_obs, char const observed[sta VA_Variant variant; uint32_t const count2 = edges2(((VA_LCS_Node) {graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, 0, 0}), ((VA_LCS_Node) {graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length, 0, 0}), - graph.nodes[head].row == graph.nodes[graph.source].row && graph.nodes[head].col == graph.nodes[graph.source].col, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, len_obs, observed, &variant); + graph.nodes[head].row == graph.nodes[graph.source].row && graph.nodes[head].col == graph.nodes[graph.source].col, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, &variant); for (uint32_t k = 0; k < count2; ++k) { @@ -167,7 +166,7 @@ shift_variant(VA_Variant const variant, uint32_t const shift) static void split(Graph2 graph, VA_LCS_Node const* const head, uint32_t const count, VA_Variant const incoming, size_t const len_obs, char const observed[static len_obs]) { - fprintf(stderr, "SPLIT %u %u %u @ %u\n", head->row, head->col, head->length, head->incoming); + fprintf(stderr, "\n\nSPLIT %u %u %u @ %u\n", head->row, head->col, head->length, head->incoming); fprintf(stderr, "incoming: " VAR_FMT " x %u\n", print_variant(incoming, observed), count); for (uint32_t i = 0; i < count; ++i) { @@ -177,9 +176,11 @@ split(Graph2 graph, VA_LCS_Node const* const head, uint32_t const count, VA_Vari { Node2 const tail = graph.nodes[graph.edges[j].tail]; VA_Variant outgoing; - uint32_t const count2 = edges2(*head, (VA_LCS_Node) {tail.row, tail.col, tail.length, 0, 0}, head->row == 0 && head->col == 0, tail.edges == GVA_NULL, len_obs, observed, &outgoing); + uint32_t const count2 = edges2(*head, (VA_LCS_Node) {tail.row, tail.col, tail.length, 0, 0}, head->row == 0 && head->col == 0, tail.edges == GVA_NULL, &outgoing); + fprintf(stderr, VAR_FMT " x %u\n", print_variant(outgoing, observed), count2); } // for } // for + fprintf(stderr, "\n\n"); } // split @@ -225,7 +226,6 @@ build(size_t const len_ref, char const reference[static len_ref], fprintf(stderr, "MAKE NODE %u: (%u, %u, %u)\n", last->idx, last->row, last->col, last->length); last->incoming = -1; - /* fprintf(stderr, "%zu\n", len_lcs); for (size_t i = 0; i < len_lcs; ++i) { @@ -236,7 +236,6 @@ build(size_t const len_ref, char const reference[static len_ref], } // for fprintf(stderr, "\n"); } // for - */ VA_LCS_Node source = {shift, shift, 0, -1, GVA_NULL}; bool found_source = last->row == shift && last->col == shift; @@ -271,28 +270,34 @@ build(size_t const len_ref, char const reference[static len_ref], if (tail->row + tail->length > head->row + head->length + h_i || tail->col + tail->length > head->col + head->length + h_i) { - fprintf(stderr, "--\n"); // FIXME: skip the remainder of this (head) level + fprintf(stderr, "no edge\n"); } // if else { fprintf(stderr, "CONVERSE\n"); VA_Variant variant; - if (head->idx != GVA_NULL && edges2(*tail, *head, tail->row == shift && tail->col == shift, - false, len_obs, observed, &variant)) + uint32_t const count = edges2(*tail, *head, tail->row == shift && tail->col == shift, false, &variant); + if (head->idx != GVA_NULL && count > 0) { + fprintf(stderr, VAR_FMT " x %u\n", print_variant(variant, observed), count); va_array_append(va_std_allocator, graph.edges, ((Edge2) {head->idx, graph.nodes[tail->idx].edges})); graph.nodes[tail->idx].edges = va_array_length(graph.edges) - 1; fprintf(stderr, "MAKE EDGE\n"); tail->incoming = MIN(tail->incoming, variant.start); } // if + else + { + fprintf(stderr, "no edge\n"); + } // else } // else } // if else { VA_Variant variant; - uint32_t const count = edges2(*head, *tail, head->row == shift && head->col == shift, is_sink, len_obs, observed, &variant); + uint32_t const count = edges2(*head, *tail, head->row == shift && head->col == shift, is_sink, &variant); if (count > 0) { + fprintf(stderr, VAR_FMT " x %u\n", print_variant(variant, observed), count); if (head->idx == GVA_NULL) { va_array_append(va_std_allocator, graph.nodes, ((Node2) {head->row, head->col, head->length, GVA_NULL, GVA_NULL})); @@ -317,7 +322,7 @@ build(size_t const len_ref, char const reference[static len_ref], } // if else { - // FIXME: skip the remainder of this (head) level + fprintf(stderr, "no edge\n"); } // else } // else } // for h_j @@ -335,7 +340,7 @@ build(size_t const len_ref, char const reference[static len_ref], } // if fprintf(stderr, "SOURCE %u %u %u: ", source.row, source.col, source.length); // is this edges2 check always true? - if (edges2(source, *tail, true, is_sink, len_obs, observed, &(VA_Variant) {0, 0, 0, 0})) + if (edges2(source, *tail, true, is_sink, &(VA_Variant) {0, 0, 0, 0})) { va_array_append(va_std_allocator, graph.edges, ((Edge2) {tail->idx, graph.nodes[source.idx].edges})); graph.nodes[source.idx].edges = va_array_length(graph.edges) - 1; @@ -362,14 +367,14 @@ build(size_t const len_ref, char const reference[static len_ref], for (uint32_t j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) { fprintf(stderr, " (%u, %u, %u): ", graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length); - edges2(((VA_LCS_Node) {graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, 0, 0}), - ((VA_LCS_Node) {graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length, 0, 0}), - graph.nodes[i].row == shift && graph.nodes[i].col == shift, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, len_obs, observed, &(VA_Variant) {0, 0, 0, 0}); + VA_Variant variant; + uint32_t const count = edges2(((VA_LCS_Node) {graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, 0, 0}), + ((VA_LCS_Node) {graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length, 0, 0}), + graph.nodes[i].row == shift && graph.nodes[i].col == shift, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, &variant); + fprintf(stderr, VAR_FMT " x %u\n", print_variant(variant, observed), count); } // for } // for - //bfs_traversal2(graph, len_obs, observed); - return graph; } // build From 62905d3231a9fc98a2d7d99af5cc52dc7579d8f9 Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 11 Apr 2025 11:05:35 +0200 Subject: [PATCH 163/704] WIP multi-split --- src/graph2.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 78 insertions(+), 6 deletions(-) diff --git a/src/graph2.c b/src/graph2.c index 34bc5e5..508008b 100644 --- a/src/graph2.c +++ b/src/graph2.c @@ -163,22 +163,94 @@ shift_variant(VA_Variant const variant, uint32_t const shift) } // shift_variant +/* +./a.out TATCCGTCCG GAAAAATCCG +./a.out GCCTGCCTAT GCCTAAAAAG +./a.out TGCCTTA TAGCAGCCC +*/ + + static void -split(Graph2 graph, VA_LCS_Node const* const head, uint32_t const count, VA_Variant const incoming, size_t const len_obs, char const observed[static len_obs]) +split(Graph2 graph, VA_LCS_Node* head, uint32_t const in_count, VA_Variant const incoming, size_t const len_obs, char const observed[static len_obs]) { fprintf(stderr, "\n\nSPLIT %u %u %u @ %u\n", head->row, head->col, head->length, head->incoming); - fprintf(stderr, "incoming: " VAR_FMT " x %u\n", print_variant(incoming, observed), count); - for (uint32_t i = 0; i < count; ++i) + fprintf(stderr, "incoming: " VAR_FMT " x %u\n", print_variant(incoming, observed), in_count); + for (uint32_t i = 0; i < in_count; ++i) { - uint32_t const offset = count - 1 - i; + uint32_t const offset = in_count - 1 - i; fprintf(stderr, " " VAR_FMT "\n", print_variant(shift_variant(incoming, offset), observed)); + uint32_t head_head = GVA_NULL; + uint32_t head_tail = GVA_NULL; + uint32_t tail_head = GVA_NULL; + uint32_t tail_tail = GVA_NULL; for (uint32_t j = graph.nodes[head->idx].edges; j != GVA_NULL; j = graph.edges[j].next) { Node2 const tail = graph.nodes[graph.edges[j].tail]; VA_Variant outgoing; - uint32_t const count2 = edges2(*head, (VA_LCS_Node) {tail.row, tail.col, tail.length, 0, 0}, head->row == 0 && head->col == 0, tail.edges == GVA_NULL, &outgoing); - fprintf(stderr, VAR_FMT " x %u\n", print_variant(outgoing, observed), count2); + // FIXME: 0 -> shift 2x FIXME: lambda == GVA_NULL + uint32_t const out_count = edges2(*head, (VA_LCS_Node) {tail.row, tail.col, tail.length, 0, 0}, head->row == 0 && head->col == 0, tail.edges == GVA_NULL, &outgoing); + fprintf(stderr, VAR_FMT " x %u: ", print_variant(outgoing, observed), out_count); + if (outgoing.start > incoming.end + offset) + { + fprintf(stderr, " tail\n"); + if (tail_tail != GVA_NULL) + { + graph.edges[tail_tail].next = j; + } // if + if (tail_head == GVA_NULL) + { + tail_head = j; + } // if + tail_tail = j; + } // if + else + { + fprintf(stderr, " split @ %u\n", incoming.end + offset); + graph.nodes[head->idx].row += offset + 1; + graph.nodes[head->idx].col += offset + 1; + graph.nodes[head->idx].length -= offset + 1; + fprintf(stderr, " tail (%u, %u, %u)\n", graph.nodes[head->idx].row, graph.nodes[head->idx].col, graph.nodes[head->idx].length); + if (outgoing.end + out_count - 1 > incoming.end + offset) + { + fprintf(stderr, " keep both outgoing\n"); + if (tail_tail != GVA_NULL) + { + graph.edges[tail_tail].next = j; + } // if + if (tail_head == GVA_NULL) + { + tail_head = j; + } // if + tail_tail = j; + va_array_append(va_std_allocator, graph.edges, ((Edge2) {graph.edges[j].tail, head_head})); + head_head = va_array_length(graph.edges) - 1; + } // if + else + { + if (head_tail != GVA_NULL) + { + graph.edges[head_tail].next = j; + } // if + if (head_head == GVA_NULL) + { + head_head = j; + } // if + head_tail = j; + } // else + } // else } // for + if (head_tail != GVA_NULL) + { + graph.edges[head_tail].next = GVA_NULL; + } // if + if (tail_tail != GVA_NULL) + { + graph.edges[tail_tail].next = GVA_NULL; + } // if + graph.nodes[head->idx].edges = tail_head; + head->length -= offset; + va_array_append(va_std_allocator, graph.nodes, ((Node2) {head->row, head->col, head->length - offset, head_head, head->idx})); + head->idx = va_array_length(graph.nodes); } // for fprintf(stderr, "\n\n"); } // split From 2e3e6cb91cd1ba83556887529097ee7fc9a49c84 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Mon, 14 Apr 2025 13:33:55 +0200 Subject: [PATCH 164/704] WIP split. --- src/graph2.c | 89 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 54 insertions(+), 35 deletions(-) diff --git a/src/graph2.c b/src/graph2.c index 508008b..4c24686 100644 --- a/src/graph2.c +++ b/src/graph2.c @@ -155,6 +155,31 @@ bfs_traversal2(Graph2 const graph, size_t const len_obs, char const observed[sta return count; } // bfs_traversal2 +static void +print_graph(Graph2 const graph, size_t const len_obs, char const observed[static len_obs], uint32_t const shift) { + fprintf(stderr, "#nodes: %zu\n#edges: %zu\n", va_array_length(graph.nodes), va_array_length(graph.edges)); + fprintf(stderr, "source: %u\n", graph.source); + for (size_t i = 0; i < va_array_length(graph.nodes); ++i) { + fprintf(stderr, "%zu: (%u, %u, %u):\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length); + if (graph.nodes[i].lambda != GVA_NULL) { + fprintf(stderr, " (%u, %u, %u): lambda\n", graph.nodes[graph.nodes[i].lambda].row, + graph.nodes[graph.nodes[i].lambda].col, graph.nodes[graph.nodes[i].lambda].length); + } // if + for (uint32_t j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) { + fprintf(stderr, " (%u, %u, %u): ", graph.nodes[graph.edges[j].tail].row, + graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length); + VA_Variant variant; + uint32_t const count = edges2( + ((VA_LCS_Node) {graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, 0, 0}), + ((VA_LCS_Node) {graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, + graph.nodes[graph.edges[j].tail].length, 0, 0}), + graph.nodes[i].row == shift && graph.nodes[i].col == shift, + graph.nodes[graph.edges[j].tail].edges == GVA_NULL, &variant); + fprintf(stderr, VAR_FMT " x %u\n", print_variant(variant, observed), count); + } // for + } // for +} + static inline VA_Variant shift_variant(VA_Variant const variant, uint32_t const shift) @@ -171,24 +196,26 @@ shift_variant(VA_Variant const variant, uint32_t const shift) static void -split(Graph2 graph, VA_LCS_Node* head, uint32_t const in_count, VA_Variant const incoming, size_t const len_obs, char const observed[static len_obs]) +split(Graph2 graph, VA_LCS_Node* node, uint32_t const head_idx, uint32_t const in_count, VA_Variant const incoming, size_t const len_obs, char const observed[static len_obs]) { - fprintf(stderr, "\n\nSPLIT %u %u %u @ %u\n", head->row, head->col, head->length, head->incoming); + fprintf(stderr, "\n\nSPLIT %u %u %u @ %u\n", node->row, node->col, node->length, node->incoming); fprintf(stderr, "incoming: " VAR_FMT " x %u\n", print_variant(incoming, observed), in_count); + print_graph(graph, len_obs, observed, 0); for (uint32_t i = 0; i < in_count; ++i) { + fprintf(stderr, "X %u %u %u %u\n", node->row, node->col, node->length, node->idx); uint32_t const offset = in_count - 1 - i; fprintf(stderr, " " VAR_FMT "\n", print_variant(shift_variant(incoming, offset), observed)); uint32_t head_head = GVA_NULL; uint32_t head_tail = GVA_NULL; uint32_t tail_head = GVA_NULL; uint32_t tail_tail = GVA_NULL; - for (uint32_t j = graph.nodes[head->idx].edges; j != GVA_NULL; j = graph.edges[j].next) + for (uint32_t j = graph.nodes[node->idx].edges; j != GVA_NULL; j = graph.edges[j].next) { Node2 const tail = graph.nodes[graph.edges[j].tail]; VA_Variant outgoing; // FIXME: 0 -> shift 2x FIXME: lambda == GVA_NULL - uint32_t const out_count = edges2(*head, (VA_LCS_Node) {tail.row, tail.col, tail.length, 0, 0}, head->row == 0 && head->col == 0, tail.edges == GVA_NULL, &outgoing); + uint32_t const out_count = edges2(*node, (VA_LCS_Node) {tail.row, tail.col, tail.length, 0, 0}, node->row == 0 && node->col == 0, tail.edges == GVA_NULL, &outgoing); fprintf(stderr, VAR_FMT " x %u: ", print_variant(outgoing, observed), out_count); if (outgoing.start > incoming.end + offset) { @@ -206,10 +233,13 @@ split(Graph2 graph, VA_LCS_Node* head, uint32_t const in_count, VA_Variant const else { fprintf(stderr, " split @ %u\n", incoming.end + offset); - graph.nodes[head->idx].row += offset + 1; - graph.nodes[head->idx].col += offset + 1; - graph.nodes[head->idx].length -= offset + 1; - fprintf(stderr, " tail (%u, %u, %u)\n", graph.nodes[head->idx].row, graph.nodes[head->idx].col, graph.nodes[head->idx].length); + graph.nodes[node->idx].row += offset + 1; + graph.nodes[node->idx].col += offset + 1; + graph.nodes[node->idx].length -= offset + 1; + fprintf(stderr, " tail (%u, %u, %u)\n", graph.nodes[node->idx].row, graph.nodes[node->idx].col, graph.nodes[node->idx].length); + + va_array_append(va_std_allocator, graph.edges, ((Edge2) {node->idx, graph.nodes[head_idx].edges})); + graph.nodes[head_idx].edges = va_array_length(graph.edges) - 1; if (outgoing.end + out_count - 1 > incoming.end + offset) { fprintf(stderr, " keep both outgoing\n"); @@ -247,12 +277,15 @@ split(Graph2 graph, VA_LCS_Node* head, uint32_t const in_count, VA_Variant const { graph.edges[tail_tail].next = GVA_NULL; } // if - graph.nodes[head->idx].edges = tail_head; - head->length -= offset; - va_array_append(va_std_allocator, graph.nodes, ((Node2) {head->row, head->col, head->length - offset, head_head, head->idx})); - head->idx = va_array_length(graph.nodes); + graph.nodes[node->idx].edges = tail_head; + node->length -= graph.nodes[node->idx].length; + va_array_append(va_std_allocator, graph.nodes, ((Node2) {node->row, node->col, node->length, head_head, node->idx})); + node->idx = va_array_length(graph.nodes) - 1; + fprintf(stderr, "After split\n"); + print_graph(graph, len_obs, observed, 0); } // for fprintf(stderr, "\n\n"); + node->length = 3; } // split @@ -386,11 +419,15 @@ build(size_t const len_ref, char const reference[static len_ref], head->incoming = MIN(head->incoming, variant.start); if (variant.end + count > tail->incoming) { - split(graph, tail, count, variant, len_obs, observed); + split(graph, tail, head->idx, count, variant, len_obs, observed); + fprintf(stderr, "%u %u %u %u\n", tail->row, tail->col, tail->length, tail->idx); } // if - va_array_append(va_std_allocator, graph.edges, ((Edge2) {tail->idx, graph.nodes[head->idx].edges})); - graph.nodes[head->idx].edges = va_array_length(graph.edges) - 1; - fprintf(stderr, "MAKE EDGE\n"); + else + { + va_array_append(va_std_allocator, graph.edges, ((Edge2) {tail->idx, graph.nodes[head->idx].edges})); + graph.nodes[head->idx].edges = va_array_length(graph.edges) - 1; + fprintf(stderr, "MAKE EDGE\n"); + } } // if else { @@ -427,25 +464,7 @@ build(size_t const len_ref, char const reference[static len_ref], // deallocation lcs_nodes = va_std_allocator.alloc(va_std_allocator.context, lcs_nodes, len_lcs, 0); - fprintf(stderr, "#nodes: %zu\n#edges: %zu\n", va_array_length(graph.nodes), va_array_length(graph.edges)); - fprintf(stderr, "source: %u\n", graph.source); - for (size_t i = 0; i < va_array_length(graph.nodes); ++i) - { - fprintf(stderr, "%zu: (%u, %u, %u):\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length); - if (graph.nodes[i].lambda != GVA_NULL) - { - fprintf(stderr, " (%u, %u, %u): lambda\n", graph.nodes[graph.nodes[i].lambda].row, graph.nodes[graph.nodes[i].lambda].col, graph.nodes[graph.nodes[i].lambda].length); - } // if - for (uint32_t j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) - { - fprintf(stderr, " (%u, %u, %u): ", graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length); - VA_Variant variant; - uint32_t const count = edges2(((VA_LCS_Node) {graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, 0, 0}), - ((VA_LCS_Node) {graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length, 0, 0}), - graph.nodes[i].row == shift && graph.nodes[i].col == shift, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, &variant); - fprintf(stderr, VAR_FMT " x %u\n", print_variant(variant, observed), count); - } // for - } // for + print_graph(graph, len_obs, observed, shift); return graph; } // build From 2802b296ad70c351cf3e133174578b6a253536e9 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Mon, 14 Apr 2025 13:41:34 +0200 Subject: [PATCH 165/704] Dont copy graph. --- src/graph2.c | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/src/graph2.c b/src/graph2.c index 4c24686..223a5cc 100644 --- a/src/graph2.c +++ b/src/graph2.c @@ -196,11 +196,11 @@ shift_variant(VA_Variant const variant, uint32_t const shift) static void -split(Graph2 graph, VA_LCS_Node* node, uint32_t const head_idx, uint32_t const in_count, VA_Variant const incoming, size_t const len_obs, char const observed[static len_obs]) +split(Graph2* const graph, VA_LCS_Node* node, uint32_t const head_idx, uint32_t const in_count, VA_Variant const incoming, size_t const len_obs, char const observed[static len_obs]) { fprintf(stderr, "\n\nSPLIT %u %u %u @ %u\n", node->row, node->col, node->length, node->incoming); fprintf(stderr, "incoming: " VAR_FMT " x %u\n", print_variant(incoming, observed), in_count); - print_graph(graph, len_obs, observed, 0); + print_graph(*graph, len_obs, observed, 0); for (uint32_t i = 0; i < in_count; ++i) { fprintf(stderr, "X %u %u %u %u\n", node->row, node->col, node->length, node->idx); @@ -210,9 +210,9 @@ split(Graph2 graph, VA_LCS_Node* node, uint32_t const head_idx, uint32_t const i uint32_t head_tail = GVA_NULL; uint32_t tail_head = GVA_NULL; uint32_t tail_tail = GVA_NULL; - for (uint32_t j = graph.nodes[node->idx].edges; j != GVA_NULL; j = graph.edges[j].next) + for (uint32_t j = graph->nodes[node->idx].edges; j != GVA_NULL; j = graph->edges[j].next) { - Node2 const tail = graph.nodes[graph.edges[j].tail]; + Node2 const tail = graph->nodes[graph->edges[j].tail]; VA_Variant outgoing; // FIXME: 0 -> shift 2x FIXME: lambda == GVA_NULL uint32_t const out_count = edges2(*node, (VA_LCS_Node) {tail.row, tail.col, tail.length, 0, 0}, node->row == 0 && node->col == 0, tail.edges == GVA_NULL, &outgoing); @@ -222,7 +222,7 @@ split(Graph2 graph, VA_LCS_Node* node, uint32_t const head_idx, uint32_t const i fprintf(stderr, " tail\n"); if (tail_tail != GVA_NULL) { - graph.edges[tail_tail].next = j; + graph->edges[tail_tail].next = j; } // if if (tail_head == GVA_NULL) { @@ -233,33 +233,33 @@ split(Graph2 graph, VA_LCS_Node* node, uint32_t const head_idx, uint32_t const i else { fprintf(stderr, " split @ %u\n", incoming.end + offset); - graph.nodes[node->idx].row += offset + 1; - graph.nodes[node->idx].col += offset + 1; - graph.nodes[node->idx].length -= offset + 1; - fprintf(stderr, " tail (%u, %u, %u)\n", graph.nodes[node->idx].row, graph.nodes[node->idx].col, graph.nodes[node->idx].length); + graph->nodes[node->idx].row += offset + 1; + graph->nodes[node->idx].col += offset + 1; + graph->nodes[node->idx].length -= offset + 1; + fprintf(stderr, " tail (%u, %u, %u)\n", graph->nodes[node->idx].row, graph->nodes[node->idx].col, graph->nodes[node->idx].length); - va_array_append(va_std_allocator, graph.edges, ((Edge2) {node->idx, graph.nodes[head_idx].edges})); - graph.nodes[head_idx].edges = va_array_length(graph.edges) - 1; + va_array_append(va_std_allocator, graph->edges, ((Edge2) {node->idx, graph->nodes[head_idx].edges})); + graph->nodes[head_idx].edges = va_array_length(graph->edges) - 1; if (outgoing.end + out_count - 1 > incoming.end + offset) { fprintf(stderr, " keep both outgoing\n"); if (tail_tail != GVA_NULL) { - graph.edges[tail_tail].next = j; + graph->edges[tail_tail].next = j; } // if if (tail_head == GVA_NULL) { tail_head = j; } // if tail_tail = j; - va_array_append(va_std_allocator, graph.edges, ((Edge2) {graph.edges[j].tail, head_head})); - head_head = va_array_length(graph.edges) - 1; + va_array_append(va_std_allocator, graph->edges, ((Edge2) {graph->edges[j].tail, head_head})); + head_head = va_array_length(graph->edges) - 1; } // if else { if (head_tail != GVA_NULL) { - graph.edges[head_tail].next = j; + graph->edges[head_tail].next = j; } // if if (head_head == GVA_NULL) { @@ -271,18 +271,18 @@ split(Graph2 graph, VA_LCS_Node* node, uint32_t const head_idx, uint32_t const i } // for if (head_tail != GVA_NULL) { - graph.edges[head_tail].next = GVA_NULL; + graph->edges[head_tail].next = GVA_NULL; } // if if (tail_tail != GVA_NULL) { - graph.edges[tail_tail].next = GVA_NULL; + graph->edges[tail_tail].next = GVA_NULL; } // if - graph.nodes[node->idx].edges = tail_head; - node->length -= graph.nodes[node->idx].length; - va_array_append(va_std_allocator, graph.nodes, ((Node2) {node->row, node->col, node->length, head_head, node->idx})); - node->idx = va_array_length(graph.nodes) - 1; + graph->nodes[node->idx].edges = tail_head; + node->length -= graph->nodes[node->idx].length; + va_array_append(va_std_allocator, graph->nodes, ((Node2) {node->row, node->col, node->length, head_head, node->idx})); + node->idx = va_array_length(graph->nodes) - 1; fprintf(stderr, "After split\n"); - print_graph(graph, len_obs, observed, 0); + print_graph(*graph, len_obs, observed, 0); } // for fprintf(stderr, "\n\n"); node->length = 3; @@ -419,7 +419,7 @@ build(size_t const len_ref, char const reference[static len_ref], head->incoming = MIN(head->incoming, variant.start); if (variant.end + count > tail->incoming) { - split(graph, tail, head->idx, count, variant, len_obs, observed); + split(&graph, tail, head->idx, count, variant, len_obs, observed); fprintf(stderr, "%u %u %u %u\n", tail->row, tail->col, tail->length, tail->idx); } // if else From ecf45dc2e2d761f13a6bad70ee9d509858b0280f Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 14 Apr 2025 15:14:24 +0200 Subject: [PATCH 166/704] WIP: multi-split --- src/graph2.c | 55 +++++++++++++++++++++++++++++++++++++++++++--------- src/main.c | 4 ++++ 2 files changed, 50 insertions(+), 9 deletions(-) diff --git a/src/graph2.c b/src/graph2.c index 223a5cc..8eab0a0 100644 --- a/src/graph2.c +++ b/src/graph2.c @@ -201,6 +201,7 @@ split(Graph2* const graph, VA_LCS_Node* node, uint32_t const head_idx, uint32_t fprintf(stderr, "\n\nSPLIT %u %u %u @ %u\n", node->row, node->col, node->length, node->incoming); fprintf(stderr, "incoming: " VAR_FMT " x %u\n", print_variant(incoming, observed), in_count); print_graph(*graph, len_obs, observed, 0); + uint32_t const length = node->length; for (uint32_t i = 0; i < in_count; ++i) { fprintf(stderr, "X %u %u %u %u\n", node->row, node->col, node->length, node->idx); @@ -210,6 +211,7 @@ split(Graph2* const graph, VA_LCS_Node* node, uint32_t const head_idx, uint32_t uint32_t head_tail = GVA_NULL; uint32_t tail_head = GVA_NULL; uint32_t tail_tail = GVA_NULL; + bool split = false; for (uint32_t j = graph->nodes[node->idx].edges; j != GVA_NULL; j = graph->edges[j].next) { Node2 const tail = graph->nodes[graph->edges[j].tail]; @@ -230,12 +232,32 @@ split(Graph2* const graph, VA_LCS_Node* node, uint32_t const head_idx, uint32_t } // if tail_tail = j; } // if + else if (split) + { + fprintf(stderr, " head\n"); + if (head_tail != GVA_NULL) + { + graph->edges[head_tail].next = j; + } // if + if (head_head == GVA_NULL) + { + head_head = j; + } // if + head_tail = j; + } // if else { + split = true; fprintf(stderr, " split @ %u\n", incoming.end + offset); - graph->nodes[node->idx].row += offset + 1; - graph->nodes[node->idx].col += offset + 1; - graph->nodes[node->idx].length -= offset + 1; + + uint32_t const tail_len = (node->row + node->length - 1) - (incoming.end + offset) + 1; + + fprintf(stderr, " %u\n", tail_len); + + graph->nodes[node->idx].row += graph->nodes[node->idx].length - tail_len; + graph->nodes[node->idx].col += graph->nodes[node->idx].length - tail_len; + graph->nodes[node->idx].length = tail_len; + fprintf(stderr, " tail (%u, %u, %u)\n", graph->nodes[node->idx].row, graph->nodes[node->idx].col, graph->nodes[node->idx].length); va_array_append(va_std_allocator, graph->edges, ((Edge2) {node->idx, graph->nodes[head_idx].edges})); @@ -269,6 +291,13 @@ split(Graph2* const graph, VA_LCS_Node* node, uint32_t const head_idx, uint32_t } // else } // else } // for + if (!split) + { + fprintf(stderr, "STOPPEN\n"); + va_array_append(va_std_allocator, graph->edges, ((Edge2) {node->idx, graph->nodes[head_idx].edges})); + graph->nodes[head_idx].edges = va_array_length(graph->edges) - 1; + break; + } // if if (head_tail != GVA_NULL) { graph->edges[head_tail].next = GVA_NULL; @@ -285,7 +314,7 @@ split(Graph2* const graph, VA_LCS_Node* node, uint32_t const head_idx, uint32_t print_graph(*graph, len_obs, observed, 0); } // for fprintf(stderr, "\n\n"); - node->length = 3; + node->length = length; } // split @@ -358,7 +387,6 @@ build(size_t const len_ref, char const reference[static len_ref], } // if fprintf(stderr, "%u %u %u %d\n", tail->row, tail->col, tail->length, tail->incoming); - uint32_t split_idx = tail->idx; for (size_t h_i = 0; h_i < MIN(len_lcs - t_i, tail->length + 1); ++h_i) { size_t const h_len = h_i == 0 ? t_len - t_j - 1: va_array_length(lcs_nodes[len_lcs - t_i - h_i - 1]); @@ -419,14 +447,24 @@ build(size_t const len_ref, char const reference[static len_ref], head->incoming = MIN(head->incoming, variant.start); if (variant.end + count > tail->incoming) { - split(&graph, tail, head->idx, count, variant, len_obs, observed); - fprintf(stderr, "%u %u %u %u\n", tail->row, tail->col, tail->length, tail->idx); + // volg eerst de lambda takken + if (graph.nodes[tail->idx].lambda != GVA_NULL) + { + va_array_append(va_std_allocator, graph.edges, ((Edge2) {graph.nodes[tail->idx].lambda, graph.nodes[head->idx].edges})); + graph.nodes[head->idx].edges = va_array_length(graph.edges) - 1; + fprintf(stderr, "MAKE EDGE: %u\n", graph.nodes[tail->idx].lambda); + } // if + else + { + split(&graph, tail, head->idx, count, variant, len_obs, observed); + fprintf(stderr, "%u %u %u %u\n", tail->row, tail->col, tail->length, tail->idx); + } // else } // if else { va_array_append(va_std_allocator, graph.edges, ((Edge2) {tail->idx, graph.nodes[head->idx].edges})); graph.nodes[head->idx].edges = va_array_length(graph.edges) - 1; - fprintf(stderr, "MAKE EDGE\n"); + fprintf(stderr, "MAKE EDGE: %u\n", tail->idx); } } // if else @@ -436,7 +474,6 @@ build(size_t const len_ref, char const reference[static len_ref], } // else } // for h_j is_sink = false; - tail->idx = split_idx; } // for h_i if (!found_source && tail->length >= len_lcs - t_i) { diff --git a/src/main.c b/src/main.c index e760d0f..61cfe00 100644 --- a/src/main.c +++ b/src/main.c @@ -173,6 +173,10 @@ main(int argc, char* argv[static argc + 1]) // to_dot(graph, len_obs, observed); // to_json(graph, len_obs, observed, false); + // destroy graph2 + va_array_destroy(va_std_allocator, graph2.nodes); + va_array_destroy(va_std_allocator, graph2.edges); + destroy(va_std_allocator, &graph); } // if From cc8604f3c97a98d45652f87ea58676246e81bdff Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Mon, 14 Apr 2025 16:12:04 +0200 Subject: [PATCH 167/704] Satisfy valgrind. --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 09fa1b2..6f13e6e 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,7 @@ MEMCHECK = valgrind -q --leak-check=full --error-exitcode=1 .PHONY: check clean debug release -debug: CFLAGS+=-O0 -g -DDEBUG +debug: CFLAGS+=-O0 -g -DDEBUG -mno-avx512f release: CFLAGS+=-O3 @@ -30,7 +30,7 @@ debug release: $(TARGET) check: CFLAGS+=-O0 -g -DDEBUG -ftest-coverage -fprofile-arcs -dumpbase '' \ - -fkeep-inline-functions -fkeep-static-functions + -fkeep-inline-functions -fkeep-static-functions -mno-avx512f check: $(TEST_BINS) $(TESTS_GCNOS) $(TEST_GCDAS) $(TEST_COVS) From 6777d60408ed289cd073bbb6f6b604f6a34f60f4 Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 14 Apr 2025 17:36:15 +0200 Subject: [PATCH 168/704] WIP: length and lambda --- src/graph2.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/graph2.c b/src/graph2.c index 8eab0a0..9ff9203 100644 --- a/src/graph2.c +++ b/src/graph2.c @@ -192,6 +192,9 @@ shift_variant(VA_Variant const variant, uint32_t const shift) ./a.out TATCCGTCCG GAAAAATCCG ./a.out GCCTGCCTAT GCCTAAAAAG ./a.out TGCCTTA TAGCAGCCC + +lengte aanpassen en zomaar eerste lambda volgen +./a.out CCC CACCCACA */ @@ -206,6 +209,7 @@ split(Graph2* const graph, VA_LCS_Node* node, uint32_t const head_idx, uint32_t { fprintf(stderr, "X %u %u %u %u\n", node->row, node->col, node->length, node->idx); uint32_t const offset = in_count - 1 - i; + fprintf(stderr, "OFFSET: %u\n", offset); fprintf(stderr, " " VAR_FMT "\n", print_variant(shift_variant(incoming, offset), observed)); uint32_t head_head = GVA_NULL; uint32_t head_tail = GVA_NULL; @@ -232,6 +236,7 @@ split(Graph2* const graph, VA_LCS_Node* node, uint32_t const head_idx, uint32_t } // if tail_tail = j; } // if + // dit is toeval else if (split) { fprintf(stderr, " head\n"); @@ -262,7 +267,8 @@ split(Graph2* const graph, VA_LCS_Node* node, uint32_t const head_idx, uint32_t va_array_append(va_std_allocator, graph->edges, ((Edge2) {node->idx, graph->nodes[head_idx].edges})); graph->nodes[head_idx].edges = va_array_length(graph->edges) - 1; - if (outgoing.end + out_count - 1 > incoming.end + offset) + // dit is toeval + if (out_count > 1) { fprintf(stderr, " keep both outgoing\n"); if (tail_tail != GVA_NULL) @@ -279,6 +285,7 @@ split(Graph2* const graph, VA_LCS_Node* node, uint32_t const head_idx, uint32_t } // if else { + fprintf(stderr, " head\n"); if (head_tail != GVA_NULL) { graph->edges[head_tail].next = j; @@ -314,6 +321,7 @@ split(Graph2* const graph, VA_LCS_Node* node, uint32_t const head_idx, uint32_t print_graph(*graph, len_obs, observed, 0); } // for fprintf(stderr, "\n\n"); + // dit is toeval node->length = length; } // split @@ -417,6 +425,7 @@ build(size_t const len_ref, char const reference[static len_ref], graph.nodes[tail->idx].edges = va_array_length(graph.edges) - 1; fprintf(stderr, "MAKE EDGE\n"); tail->incoming = MIN(tail->incoming, variant.start); + fprintf(stderr, "new incoming (%u, %u, %u): %u\n", tail->row, tail->col, tail->length, tail->incoming); } // if else { @@ -447,7 +456,9 @@ build(size_t const len_ref, char const reference[static len_ref], head->incoming = MIN(head->incoming, variant.start); if (variant.end + count > tail->incoming) { + // dit is toeval // volg eerst de lambda takken + /* if (graph.nodes[tail->idx].lambda != GVA_NULL) { va_array_append(va_std_allocator, graph.edges, ((Edge2) {graph.nodes[tail->idx].lambda, graph.nodes[head->idx].edges})); @@ -455,6 +466,7 @@ build(size_t const len_ref, char const reference[static len_ref], fprintf(stderr, "MAKE EDGE: %u\n", graph.nodes[tail->idx].lambda); } // if else + */ { split(&graph, tail, head->idx, count, variant, len_obs, observed); fprintf(stderr, "%u %u %u %u\n", tail->row, tail->col, tail->length, tail->idx); From 55a6728e358131eb1313fb6e6ed0f2d5ee448178 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Tue, 15 Apr 2025 11:08:07 +0200 Subject: [PATCH 169/704] WIP split. --- src/graph2.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/graph2.c b/src/graph2.c index 9ff9203..55fd521 100644 --- a/src/graph2.c +++ b/src/graph2.c @@ -198,7 +198,7 @@ lengte aanpassen en zomaar eerste lambda volgen */ -static void +static uint32_t split(Graph2* const graph, VA_LCS_Node* node, uint32_t const head_idx, uint32_t const in_count, VA_Variant const incoming, size_t const len_obs, char const observed[static len_obs]) { fprintf(stderr, "\n\nSPLIT %u %u %u @ %u\n", node->row, node->col, node->length, node->incoming); @@ -321,8 +321,8 @@ split(Graph2* const graph, VA_LCS_Node* node, uint32_t const head_idx, uint32_t print_graph(*graph, len_obs, observed, 0); } // for fprintf(stderr, "\n\n"); - // dit is toeval - node->length = length; + fprintf(stderr, "split return %u\n", length - node->length); + return length - node->length; } // split @@ -395,7 +395,9 @@ build(size_t const len_ref, char const reference[static len_ref], } // if fprintf(stderr, "%u %u %u %d\n", tail->row, tail->col, tail->length, tail->incoming); - for (size_t h_i = 0; h_i < MIN(len_lcs - t_i, tail->length + 1); ++h_i) + size_t const tmp_len = MIN(len_lcs - t_i, tail->length + 1); + uint32_t split_len = 0; + for (size_t h_i = 0; h_i < tmp_len; ++h_i) { size_t const h_len = h_i == 0 ? t_len - t_j - 1: va_array_length(lcs_nodes[len_lcs - t_i - h_i - 1]); //printf(" level: %zu with %zu nodes\n", len_lcs - t_i - h_i - 1, h_len); @@ -405,13 +407,13 @@ build(size_t const len_ref, char const reference[static len_ref], fprintf(stderr, " %u %u %u: ", head->row, head->col, head->length); - if (head->row + head->length + h_i > tail->row + tail->length || - head->col + head->length + h_i > tail->col + tail->length) + if (head->row + head->length + h_i > tail->row + tail->length + split_len || + head->col + head->length + h_i > tail->col + tail->length + split_len) { - if (tail->row + tail->length > head->row + head->length + h_i || - tail->col + tail->length > head->col + head->length + h_i) + if (tail->row + tail->length + split_len > head->row + head->length + h_i || + tail->col + tail->length + split_len > head->col + head->length + h_i) { - fprintf(stderr, "no edge\n"); + fprintf(stderr, "no edge X\n"); } // if else { @@ -454,6 +456,7 @@ build(size_t const len_ref, char const reference[static len_ref], } // if } // if head->incoming = MIN(head->incoming, variant.start); + fprintf(stderr, "YO! %u %u (%u,%u,%u) %u\n", variant.end, count, tail->row, tail->col, tail->length, tail->incoming); if (variant.end + count > tail->incoming) { // dit is toeval @@ -468,7 +471,7 @@ build(size_t const len_ref, char const reference[static len_ref], else */ { - split(&graph, tail, head->idx, count, variant, len_obs, observed); + split_len = split(&graph, tail, head->idx, count, variant, len_obs, observed); fprintf(stderr, "%u %u %u %u\n", tail->row, tail->col, tail->length, tail->idx); } // else } // if @@ -487,7 +490,7 @@ build(size_t const len_ref, char const reference[static len_ref], } // for h_j is_sink = false; } // for h_i - if (!found_source && tail->length >= len_lcs - t_i) + if (!found_source && tail->length + split_len >= len_lcs - t_i) { if (source.idx == GVA_NULL) { From 831ea1e10147eca8d328d8d2d632913e16a6251c Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 15 Apr 2025 17:46:21 +0200 Subject: [PATCH 170/704] WIP regressions --- include/edit.h | 2 + regres.sh | 14 +++++ src/edit.c | 4 +- src/graph2.c | 138 +++++++++++++++++++++++++++++++------------------ test.py | 32 ++++++------ 5 files changed, 123 insertions(+), 67 deletions(-) create mode 100755 regres.sh diff --git a/include/edit.h b/include/edit.h index e7c09eb..1750ab5 100644 --- a/include/edit.h +++ b/include/edit.h @@ -19,6 +19,8 @@ typedef struct uint32_t length; uint32_t incoming; uint32_t idx; + uint32_t split_len; + uint32_t orig_len; } VA_LCS_Node; diff --git a/regres.sh b/regres.sh new file mode 100755 index 0000000..575e314 --- /dev/null +++ b/regres.sh @@ -0,0 +1,14 @@ +set -o errexit + +python test.py TATCCGTCCG GAAAAATCCG +python test.py GCCTGCCTAT GCCTAAAAAG +python test.py TGCCTTA TAGCAGCCC +python test.py CCC CACCCACA +python test.py TTGGGAA CCGAATA +python test.py GACAT ACACTCCCAT +python test.py GAG AGGATAAGT +python test.py CACGCTCGT ACACT +python test.py GTTTA TCTTTCTGC +python test.py TCAACAAAGG CAA +python test.py CTTATAAT CCTACCG + diff --git a/src/edit.c b/src/edit.c index 3c5d9cb..bb7cb00 100644 --- a/src/edit.c +++ b/src/edit.c @@ -170,7 +170,7 @@ expand(Context const context, { context.lcs_nodes[lcs_pos] = va_array_init(context.allocator, 256, sizeof(*context.lcs_nodes[lcs_pos])); } // if - va_array_append(context.allocator, context.lcs_nodes[lcs_pos], ((VA_LCS_Node) {match_row, match_col, length, -1, -1})); + va_array_append(context.allocator, context.lcs_nodes[lcs_pos], ((VA_LCS_Node) {match_row, match_col, length, -1, -1, 0, length})); matching = false; } // if row += 1; @@ -203,7 +203,7 @@ expand(Context const context, { context.lcs_nodes[lcs_pos] = va_array_init(context.allocator, 256, sizeof(*context.lcs_nodes[lcs_pos])); } // if - va_array_append(context.allocator, context.lcs_nodes[lcs_pos], ((VA_LCS_Node) {match_row, match_col, length, -1, -1})); + va_array_append(context.allocator, context.lcs_nodes[lcs_pos], ((VA_LCS_Node) {match_row, match_col, length, -1, -1, 0, length})); } // if return steps; diff --git a/src/graph2.c b/src/graph2.c index 55fd521..516819b 100644 --- a/src/graph2.c +++ b/src/graph2.c @@ -104,8 +104,8 @@ bfs_traversal2(Graph2 const graph, size_t const len_obs, char const observed[sta } // if count += 1; VA_Variant variant; - uint32_t const count2 = edges2(((VA_LCS_Node) {graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, 0, 0}), - ((VA_LCS_Node) {graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length, 0, 0}), + uint32_t const count2 = edges2(((VA_LCS_Node) {graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, 0, 0, 0, 0}), + ((VA_LCS_Node) {graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length, 0, 0, 0, 0}), graph.nodes[head].row == graph.nodes[graph.source].row && graph.nodes[head].col == graph.nodes[graph.source].col, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, &variant); for (uint32_t k = 0; k < count2; ++k) @@ -159,6 +159,10 @@ static void print_graph(Graph2 const graph, size_t const len_obs, char const observed[static len_obs], uint32_t const shift) { fprintf(stderr, "#nodes: %zu\n#edges: %zu\n", va_array_length(graph.nodes), va_array_length(graph.edges)); fprintf(stderr, "source: %u\n", graph.source); + if (graph.nodes == NULL) + { + return; + } // if for (size_t i = 0; i < va_array_length(graph.nodes); ++i) { fprintf(stderr, "%zu: (%u, %u, %u):\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length); if (graph.nodes[i].lambda != GVA_NULL) { @@ -170,15 +174,15 @@ print_graph(Graph2 const graph, size_t const len_obs, char const observed[static graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length); VA_Variant variant; uint32_t const count = edges2( - ((VA_LCS_Node) {graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, 0, 0}), + ((VA_LCS_Node) {graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, 0, 0, 0, 0}), ((VA_LCS_Node) {graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, - graph.nodes[graph.edges[j].tail].length, 0, 0}), + graph.nodes[graph.edges[j].tail].length, 0, 0, 0, 0}), graph.nodes[i].row == shift && graph.nodes[i].col == shift, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, &variant); fprintf(stderr, VAR_FMT " x %u\n", print_variant(variant, observed), count); } // for } // for -} +} // print_graph static inline VA_Variant @@ -188,17 +192,7 @@ shift_variant(VA_Variant const variant, uint32_t const shift) } // shift_variant -/* -./a.out TATCCGTCCG GAAAAATCCG -./a.out GCCTGCCTAT GCCTAAAAAG -./a.out TGCCTTA TAGCAGCCC - -lengte aanpassen en zomaar eerste lambda volgen -./a.out CCC CACCCACA -*/ - - -static uint32_t +static void split(Graph2* const graph, VA_LCS_Node* node, uint32_t const head_idx, uint32_t const in_count, VA_Variant const incoming, size_t const len_obs, char const observed[static len_obs]) { fprintf(stderr, "\n\nSPLIT %u %u %u @ %u\n", node->row, node->col, node->length, node->incoming); @@ -220,8 +214,8 @@ split(Graph2* const graph, VA_LCS_Node* node, uint32_t const head_idx, uint32_t { Node2 const tail = graph->nodes[graph->edges[j].tail]; VA_Variant outgoing; - // FIXME: 0 -> shift 2x FIXME: lambda == GVA_NULL - uint32_t const out_count = edges2(*node, (VA_LCS_Node) {tail.row, tail.col, tail.length, 0, 0}, node->row == 0 && node->col == 0, tail.edges == GVA_NULL, &outgoing); + // FIXME: 0 -> shift 2x FIXME: lambda == GVA_NULL + uint32_t const out_count = edges2(*node, (VA_LCS_Node) {tail.row, tail.col, tail.length, 0, 0, 0, 0}, node->row == 0 && node->col == 0, tail.edges == GVA_NULL, &outgoing); fprintf(stderr, VAR_FMT " x %u: ", print_variant(outgoing, observed), out_count); if (outgoing.start > incoming.end + offset) { @@ -239,16 +233,35 @@ split(Graph2* const graph, VA_LCS_Node* node, uint32_t const head_idx, uint32_t // dit is toeval else if (split) { - fprintf(stderr, " head\n"); - if (head_tail != GVA_NULL) + // dit is toeval + if (out_count > 1) { - graph->edges[head_tail].next = j; + fprintf(stderr, " keep both outgoing TOEVAL\n"); + if (tail_tail != GVA_NULL) + { + graph->edges[tail_tail].next = j; + } // if + if (tail_head == GVA_NULL) + { + tail_head = j; + } // if + tail_tail = j; + va_array_append(va_std_allocator, graph->edges, ((Edge2) {graph->edges[j].tail, head_head})); + head_head = va_array_length(graph->edges) - 1; } // if - if (head_head == GVA_NULL) + else { - head_head = j; - } // if - head_tail = j; + fprintf(stderr, " head TOEVAL\n"); + if (head_tail != GVA_NULL) + { + graph->edges[head_tail].next = j; + } // if + if (head_head == GVA_NULL) + { + head_head = j; + } // if + head_tail = j; + } // else } // if else { @@ -268,7 +281,7 @@ split(Graph2* const graph, VA_LCS_Node* node, uint32_t const head_idx, uint32_t va_array_append(va_std_allocator, graph->edges, ((Edge2) {node->idx, graph->nodes[head_idx].edges})); graph->nodes[head_idx].edges = va_array_length(graph->edges) - 1; // dit is toeval - if (out_count > 1) + if (incoming.end + offset < outgoing.start + out_count - 1) { fprintf(stderr, " keep both outgoing\n"); if (tail_tail != GVA_NULL) @@ -322,7 +335,7 @@ split(Graph2* const graph, VA_LCS_Node* node, uint32_t const head_idx, uint32_t } // for fprintf(stderr, "\n\n"); fprintf(stderr, "split return %u\n", length - node->length); - return length - node->length; + node->split_len += length - node->length; } // split @@ -379,7 +392,7 @@ build(size_t const len_ref, char const reference[static len_ref], fprintf(stderr, "\n"); } // for - VA_LCS_Node source = {shift, shift, 0, -1, GVA_NULL}; + VA_LCS_Node source = {shift, shift, 0, -1, GVA_NULL, 0, 0}; bool found_source = last->row == shift && last->col == shift; bool is_sink = true; for (size_t t_i = 0; t_i < len_lcs; ++t_i) @@ -396,7 +409,6 @@ build(size_t const len_ref, char const reference[static len_ref], fprintf(stderr, "%u %u %u %d\n", tail->row, tail->col, tail->length, tail->incoming); size_t const tmp_len = MIN(len_lcs - t_i, tail->length + 1); - uint32_t split_len = 0; for (size_t h_i = 0; h_i < tmp_len; ++h_i) { size_t const h_len = h_i == 0 ? t_len - t_j - 1: va_array_length(lcs_nodes[len_lcs - t_i - h_i - 1]); @@ -407,11 +419,11 @@ build(size_t const len_ref, char const reference[static len_ref], fprintf(stderr, " %u %u %u: ", head->row, head->col, head->length); - if (head->row + head->length + h_i > tail->row + tail->length + split_len || - head->col + head->length + h_i > tail->col + tail->length + split_len) + if (head->row + head->length + h_i > tail->row + tail->length + tail->split_len || + head->col + head->length + h_i > tail->col + tail->length + tail->split_len) { - if (tail->row + tail->length + split_len > head->row + head->length + h_i || - tail->col + tail->length + split_len > head->col + head->length + h_i) + if (tail->row + tail->length + tail->split_len > head->row + head->length + h_i || + tail->col + tail->length + tail->split_len > head->col + head->length + h_i) { fprintf(stderr, "no edge X\n"); } // if @@ -420,7 +432,13 @@ build(size_t const len_ref, char const reference[static len_ref], fprintf(stderr, "CONVERSE\n"); VA_Variant variant; uint32_t const count = edges2(*tail, *head, tail->row == shift && tail->col == shift, false, &variant); - if (head->idx != GVA_NULL && count > 0) + fprintf(stderr, " check (%u, %u, %u)\n", head->row, head->col, head->length); + if (variant.end + count > head->incoming) + { + fprintf(stderr, "SPLIT HEAD\n"); + split(&graph, head, tail->idx, count, variant, len_obs, observed); + } // if + else if (head->idx != GVA_NULL && count > 0) // strange? { fprintf(stderr, VAR_FMT " x %u\n", print_variant(variant, observed), count); va_array_append(va_std_allocator, graph.edges, ((Edge2) {head->idx, graph.nodes[tail->idx].edges})); @@ -459,21 +477,8 @@ build(size_t const len_ref, char const reference[static len_ref], fprintf(stderr, "YO! %u %u (%u,%u,%u) %u\n", variant.end, count, tail->row, tail->col, tail->length, tail->incoming); if (variant.end + count > tail->incoming) { - // dit is toeval - // volg eerst de lambda takken - /* - if (graph.nodes[tail->idx].lambda != GVA_NULL) - { - va_array_append(va_std_allocator, graph.edges, ((Edge2) {graph.nodes[tail->idx].lambda, graph.nodes[head->idx].edges})); - graph.nodes[head->idx].edges = va_array_length(graph.edges) - 1; - fprintf(stderr, "MAKE EDGE: %u\n", graph.nodes[tail->idx].lambda); - } // if - else - */ - { - split_len = split(&graph, tail, head->idx, count, variant, len_obs, observed); - fprintf(stderr, "%u %u %u %u\n", tail->row, tail->col, tail->length, tail->idx); - } // else + split(&graph, tail, head->idx, count, variant, len_obs, observed); + fprintf(stderr, "%u %u %u %u\n", tail->row, tail->col, tail->length, tail->idx); } // if else { @@ -482,6 +487,39 @@ build(size_t const len_ref, char const reference[static len_ref], fprintf(stderr, "MAKE EDGE: %u\n", tail->idx); } } // if + else if (tail->split_len > 0) + { + uint32_t const nog_count = edges2(*head, (VA_LCS_Node) {tail->row, tail->col, tail->orig_len, 0, 0, 0, 0}, head->row == shift && head->col == shift, is_sink, &variant); + if (nog_count > 0) + { + for (uint32_t xxx = tail->idx; xxx != GVA_NULL; xxx = graph.nodes[xxx].lambda) + { + uint32_t const nog_nog_count = edges2(*head, (VA_LCS_Node) {graph.nodes[xxx].row, graph.nodes[xxx].col, graph.nodes[xxx].length, 0, 0, 0, 0}, head->row == shift && head->col == shift, false, &variant); + if (nog_nog_count > 0) + { + if (head->idx == GVA_NULL) + { + va_array_append(va_std_allocator, graph.nodes, ((Node2) {head->row, head->col, head->length, GVA_NULL, GVA_NULL})); + head->idx = va_array_length(graph.nodes) - 1; + fprintf(stderr, "MAKE NODE %u: (%u, %u, %u)\n", head->idx, head->row, head->col, head->length); + if (head->row == shift && head->col == shift) + { + // head is the source + source = *head; + graph.source = source.idx; + found_source = true; + } // if + } // if + fprintf(stderr, "check with lambda\n"); + va_array_append(va_std_allocator, graph.edges, ((Edge2) {xxx, graph.nodes[head->idx].edges})); + graph.nodes[head->idx].edges = va_array_length(graph.edges) - 1; + fprintf(stderr, "MAKE EDGE to lambda: %u\n", xxx); + + break; + } // if + } // for + } // if + } // if else { fprintf(stderr, "no edge\n"); @@ -490,7 +528,7 @@ build(size_t const len_ref, char const reference[static len_ref], } // for h_j is_sink = false; } // for h_i - if (!found_source && tail->length + split_len >= len_lcs - t_i) + if (!found_source && tail->length + tail->split_len >= len_lcs - t_i) { if (source.idx == GVA_NULL) { diff --git a/test.py b/test.py index 45c0042..aecf6a5 100644 --- a/test.py +++ b/test.py @@ -80,7 +80,8 @@ def str2var(desc): def check(reference, observed, debug=False, timeout=2): - graph = LCSgraph.from_sequence(reference, observed) + #graph = LCSgraph.from_sequence(reference, observed) + graph = LCSgraph(reference, observed) valgrind = [] if debug: print("\n".join(to_dot(reference, graph, labels=False, hgvs=False))) @@ -95,7 +96,7 @@ def check(reference, observed, debug=False, timeout=2): print(f'\"{stdout}\"') raise exc - assert str(graph.supremal) == cgraph["supremal"], f'supremals differ: {cgraph["supremal"]} vs {graph.supremal}' + #assert str(graph.supremal) == cgraph["supremal"], f'supremals differ: {cgraph["supremal"]} vs {graph.supremal}' nodes = list(graph.nodes()) edges = list(graph.bfs_traversal()) @@ -117,26 +118,27 @@ def check(reference, observed, debug=False, timeout=2): except StopIteration: raise ValueError(f'{cedge} not in edges of {head}') from None - assert len(cgraph["local_supremal"]) == len(local_supremal(reference, graph)), f'local supremal length' + #assert len(cgraph["local_supremal"]) == len(local_supremal(reference, graph)), f'local supremal length' - for lhs, rhs in zip(cgraph["local_supremal"], local_supremal(reference, graph)): - assert lhs == str(rhs), f'local supremal elements differ: {lhs} vs {rhs}' + #for lhs, rhs in zip(cgraph["local_supremal"], local_supremal(reference, graph)): + # assert lhs == str(rhs), f'local supremal elements differ: {lhs} vs {rhs}' - if debug: - print(list(reversed(cgraph["canonical"])), canonical(graph)) + #if debug: + # print(list(reversed(cgraph["canonical"])), canonical(graph)) - print() - print(cgraph["canonical"]) - print(canonical(graph)) - assert len(cgraph["canonical"]) == len(canonical(graph)), f'canonical length' + #print() + #print(cgraph["canonical"]) + #print(canonical(graph)) + #assert len(cgraph["canonical"]) == len(canonical(graph)), f'canonical length' - for lhs, rhs in zip(reversed(cgraph["canonical"]), canonical(graph)): - assert lhs == str(rhs), f'canonical elements differ: {lhs} vs {rhs}' + #for lhs, rhs in zip(reversed(cgraph["canonical"]), canonical(graph)): + # assert lhs == str(rhs), f'canonical elements differ: {lhs} vs {rhs}' def main(): if len(sys.argv) == 3: + print(sys.argv[1], sys.argv[2]) return check(sys.argv[1], sys.argv[2], debug=False) signal.signal(signal.SIGINT, handler) @@ -149,8 +151,8 @@ def main(): #if random.random() > 0.5: # prefix = random_sequence(1000) # suffix = random_sequence(1000) - reference = prefix + random_sequence(130) + suffix - observed = prefix + random_sequence(100) + suffix + reference = prefix + random_sequence(10) + suffix + observed = prefix + random_sequence(10) + suffix if n % 1_000 == 0: print(n) From 34cc499a1bcd519ba1851477f87698ffe7153f9b Mon Sep 17 00:00:00 2001 From: jkvis Date: Sun, 20 Apr 2025 13:45:56 +0200 Subject: [PATCH 171/704] Removed extra fields in VA_LCS_Node --- include/edit.h | 2 -- src/edit.c | 4 ++-- src/main.c | 1 + 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/include/edit.h b/include/edit.h index 1750ab5..e7c09eb 100644 --- a/include/edit.h +++ b/include/edit.h @@ -19,8 +19,6 @@ typedef struct uint32_t length; uint32_t incoming; uint32_t idx; - uint32_t split_len; - uint32_t orig_len; } VA_LCS_Node; diff --git a/src/edit.c b/src/edit.c index bb7cb00..3c5d9cb 100644 --- a/src/edit.c +++ b/src/edit.c @@ -170,7 +170,7 @@ expand(Context const context, { context.lcs_nodes[lcs_pos] = va_array_init(context.allocator, 256, sizeof(*context.lcs_nodes[lcs_pos])); } // if - va_array_append(context.allocator, context.lcs_nodes[lcs_pos], ((VA_LCS_Node) {match_row, match_col, length, -1, -1, 0, length})); + va_array_append(context.allocator, context.lcs_nodes[lcs_pos], ((VA_LCS_Node) {match_row, match_col, length, -1, -1})); matching = false; } // if row += 1; @@ -203,7 +203,7 @@ expand(Context const context, { context.lcs_nodes[lcs_pos] = va_array_init(context.allocator, 256, sizeof(*context.lcs_nodes[lcs_pos])); } // if - va_array_append(context.allocator, context.lcs_nodes[lcs_pos], ((VA_LCS_Node) {match_row, match_col, length, -1, -1, 0, length})); + va_array_append(context.allocator, context.lcs_nodes[lcs_pos], ((VA_LCS_Node) {match_row, match_col, length, -1, -1})); } // if return steps; diff --git a/src/main.c b/src/main.c index 61cfe00..ef4651a 100644 --- a/src/main.c +++ b/src/main.c @@ -14,6 +14,7 @@ #define print_variant(variant, observed) variant.start, variant.end, (int) variant.obs_end - variant.obs_start, observed + variant.obs_start #define VAR_FMT "%u:%u/%.*s" + static uint32_t const GVA_NULL = UINT32_MAX; From 1d4fec08b17dd78df316289b1760736d1a207351 Mon Sep 17 00:00:00 2001 From: jkvis Date: Sun, 20 Apr 2025 13:47:18 +0200 Subject: [PATCH 172/704] Basic graph build without splitting --- src/graph2.c | 388 +++++++++++---------------------------------------- 1 file changed, 80 insertions(+), 308 deletions(-) diff --git a/src/graph2.c b/src/graph2.c index 516819b..3ac778a 100644 --- a/src/graph2.c +++ b/src/graph2.c @@ -104,8 +104,8 @@ bfs_traversal2(Graph2 const graph, size_t const len_obs, char const observed[sta } // if count += 1; VA_Variant variant; - uint32_t const count2 = edges2(((VA_LCS_Node) {graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, 0, 0, 0, 0}), - ((VA_LCS_Node) {graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length, 0, 0, 0, 0}), + uint32_t const count2 = edges2(((VA_LCS_Node) {graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, 0, 0}), + ((VA_LCS_Node) {graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length, 0, 0}), graph.nodes[head].row == graph.nodes[graph.source].row && graph.nodes[head].col == graph.nodes[graph.source].col, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, &variant); for (uint32_t k = 0; k < count2; ++k) @@ -174,9 +174,9 @@ print_graph(Graph2 const graph, size_t const len_obs, char const observed[static graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length); VA_Variant variant; uint32_t const count = edges2( - ((VA_LCS_Node) {graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, 0, 0, 0, 0}), + ((VA_LCS_Node) {graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, 0, 0}), ((VA_LCS_Node) {graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, - graph.nodes[graph.edges[j].tail].length, 0, 0, 0, 0}), + graph.nodes[graph.edges[j].tail].length, 0, 0}), graph.nodes[i].row == shift && graph.nodes[i].col == shift, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, &variant); fprintf(stderr, VAR_FMT " x %u\n", print_variant(variant, observed), count); @@ -185,373 +185,145 @@ print_graph(Graph2 const graph, size_t const len_obs, char const observed[static } // print_graph -static inline VA_Variant -shift_variant(VA_Variant const variant, uint32_t const shift) -{ - return (VA_Variant) {variant.start + shift, variant.end + shift, variant.obs_start + shift, variant.obs_end + shift}; -} // shift_variant - - -static void -split(Graph2* const graph, VA_LCS_Node* node, uint32_t const head_idx, uint32_t const in_count, VA_Variant const incoming, size_t const len_obs, char const observed[static len_obs]) -{ - fprintf(stderr, "\n\nSPLIT %u %u %u @ %u\n", node->row, node->col, node->length, node->incoming); - fprintf(stderr, "incoming: " VAR_FMT " x %u\n", print_variant(incoming, observed), in_count); - print_graph(*graph, len_obs, observed, 0); - uint32_t const length = node->length; - for (uint32_t i = 0; i < in_count; ++i) - { - fprintf(stderr, "X %u %u %u %u\n", node->row, node->col, node->length, node->idx); - uint32_t const offset = in_count - 1 - i; - fprintf(stderr, "OFFSET: %u\n", offset); - fprintf(stderr, " " VAR_FMT "\n", print_variant(shift_variant(incoming, offset), observed)); - uint32_t head_head = GVA_NULL; - uint32_t head_tail = GVA_NULL; - uint32_t tail_head = GVA_NULL; - uint32_t tail_tail = GVA_NULL; - bool split = false; - for (uint32_t j = graph->nodes[node->idx].edges; j != GVA_NULL; j = graph->edges[j].next) - { - Node2 const tail = graph->nodes[graph->edges[j].tail]; - VA_Variant outgoing; - // FIXME: 0 -> shift 2x FIXME: lambda == GVA_NULL - uint32_t const out_count = edges2(*node, (VA_LCS_Node) {tail.row, tail.col, tail.length, 0, 0, 0, 0}, node->row == 0 && node->col == 0, tail.edges == GVA_NULL, &outgoing); - fprintf(stderr, VAR_FMT " x %u: ", print_variant(outgoing, observed), out_count); - if (outgoing.start > incoming.end + offset) - { - fprintf(stderr, " tail\n"); - if (tail_tail != GVA_NULL) - { - graph->edges[tail_tail].next = j; - } // if - if (tail_head == GVA_NULL) - { - tail_head = j; - } // if - tail_tail = j; - } // if - // dit is toeval - else if (split) - { - // dit is toeval - if (out_count > 1) - { - fprintf(stderr, " keep both outgoing TOEVAL\n"); - if (tail_tail != GVA_NULL) - { - graph->edges[tail_tail].next = j; - } // if - if (tail_head == GVA_NULL) - { - tail_head = j; - } // if - tail_tail = j; - va_array_append(va_std_allocator, graph->edges, ((Edge2) {graph->edges[j].tail, head_head})); - head_head = va_array_length(graph->edges) - 1; - } // if - else - { - fprintf(stderr, " head TOEVAL\n"); - if (head_tail != GVA_NULL) - { - graph->edges[head_tail].next = j; - } // if - if (head_head == GVA_NULL) - { - head_head = j; - } // if - head_tail = j; - } // else - } // if - else - { - split = true; - fprintf(stderr, " split @ %u\n", incoming.end + offset); - - uint32_t const tail_len = (node->row + node->length - 1) - (incoming.end + offset) + 1; - - fprintf(stderr, " %u\n", tail_len); - - graph->nodes[node->idx].row += graph->nodes[node->idx].length - tail_len; - graph->nodes[node->idx].col += graph->nodes[node->idx].length - tail_len; - graph->nodes[node->idx].length = tail_len; - - fprintf(stderr, " tail (%u, %u, %u)\n", graph->nodes[node->idx].row, graph->nodes[node->idx].col, graph->nodes[node->idx].length); - - va_array_append(va_std_allocator, graph->edges, ((Edge2) {node->idx, graph->nodes[head_idx].edges})); - graph->nodes[head_idx].edges = va_array_length(graph->edges) - 1; - // dit is toeval - if (incoming.end + offset < outgoing.start + out_count - 1) - { - fprintf(stderr, " keep both outgoing\n"); - if (tail_tail != GVA_NULL) - { - graph->edges[tail_tail].next = j; - } // if - if (tail_head == GVA_NULL) - { - tail_head = j; - } // if - tail_tail = j; - va_array_append(va_std_allocator, graph->edges, ((Edge2) {graph->edges[j].tail, head_head})); - head_head = va_array_length(graph->edges) - 1; - } // if - else - { - fprintf(stderr, " head\n"); - if (head_tail != GVA_NULL) - { - graph->edges[head_tail].next = j; - } // if - if (head_head == GVA_NULL) - { - head_head = j; - } // if - head_tail = j; - } // else - } // else - } // for - if (!split) - { - fprintf(stderr, "STOPPEN\n"); - va_array_append(va_std_allocator, graph->edges, ((Edge2) {node->idx, graph->nodes[head_idx].edges})); - graph->nodes[head_idx].edges = va_array_length(graph->edges) - 1; - break; - } // if - if (head_tail != GVA_NULL) - { - graph->edges[head_tail].next = GVA_NULL; - } // if - if (tail_tail != GVA_NULL) - { - graph->edges[tail_tail].next = GVA_NULL; - } // if - graph->nodes[node->idx].edges = tail_head; - node->length -= graph->nodes[node->idx].length; - va_array_append(va_std_allocator, graph->nodes, ((Node2) {node->row, node->col, node->length, head_head, node->idx})); - node->idx = va_array_length(graph->nodes) - 1; - fprintf(stderr, "After split\n"); - print_graph(*graph, len_obs, observed, 0); - } // for - fprintf(stderr, "\n\n"); - fprintf(stderr, "split return %u\n", length - node->length); - node->split_len += length - node->length; -} // split - - Graph2 build(size_t const len_ref, char const reference[static len_ref], size_t const len_obs, char const observed[static len_obs], size_t const shift) { - //printf("build!\n"); VA_LCS_Node** lcs_nodes = NULL; size_t const len_lcs = va_edit(va_std_allocator, len_ref, reference, len_obs, observed, &lcs_nodes); + fprintf(stderr, "%zu\n", len_lcs); + for (size_t i = 0; i < len_lcs; ++i) + { + fprintf(stderr, "%zu: ", i); + for (size_t j = 0; j < va_array_length(lcs_nodes[i]); ++j) + { + fprintf(stderr, "(%u, %u, %u) ", lcs_nodes[i][j].row, lcs_nodes[i][j].col, lcs_nodes[i][j].length); + } // for + fprintf(stderr, "\n"); + } // for + Graph2 graph = {NULL, NULL, GVA_NULL}; if (len_lcs == 0 || lcs_nodes == NULL) { - va_array_append(va_std_allocator, graph.nodes, ((Node2) {shift, shift, 0, GVA_NULL, GVA_NULL})); - graph.source = va_array_length(graph.nodes) - 1; - + va_array_append(va_std_allocator, graph.nodes, ((Node2) {len_ref, len_obs, 0, GVA_NULL, GVA_NULL})); + uint32_t const sink = va_array_length(graph.nodes) - 1; if (len_ref == 0 && len_obs == 0) { - //graph.supremal = (VA_Variant) {0, 0, 0, 0}; + graph.source = sink; return graph; } // if - va_array_append(va_std_allocator, graph.nodes, ((Node2) {len_ref, len_obs, 0, GVA_NULL, GVA_NULL})); - uint32_t const sink = va_array_length(graph.nodes) - 1; - //graph.supremal = (VA_Variant) {shift, shift + len_ref, 0, len_obs}; - va_array_append(va_std_allocator, graph.edges, ((Edge2) {sink, graph.nodes[graph.source].edges})); - graph.nodes[graph.source].edges = va_array_length(graph.edges) - 1; + va_array_append(va_std_allocator, graph.edges, ((Edge2) {sink, GVA_NULL})); + va_array_append(va_std_allocator, graph.nodes, ((Node2) {shift, shift, 0, va_array_length(graph.edges) - 1, GVA_NULL})); + graph.source = va_array_length(graph.nodes) - 1; return graph; } // if - VA_LCS_Node* last = &lcs_nodes[len_lcs - 1][va_array_length(lcs_nodes[len_lcs - 1]) - 1]; + VA_LCS_Node* const last = &lcs_nodes[len_lcs - 1][va_array_length(lcs_nodes[len_lcs - 1]) - 1]; if (last->row + last->length != len_ref + shift || last->col + last->length != len_obs + shift) { - va_array_append(va_std_allocator, lcs_nodes[len_lcs - 1], - ((VA_LCS_Node) {.row = len_ref + shift, .col = len_obs + shift, .length = 0})); - last = &lcs_nodes[len_lcs - 1][va_array_length(lcs_nodes[len_lcs - 1]) - 1]; - } // if - va_array_append(va_std_allocator, graph.nodes, ((Node2) {last->row, last->col, last->length, GVA_NULL, GVA_NULL})); - last->idx = va_array_length(graph.nodes) - 1; - fprintf(stderr, "MAKE NODE %u: (%u, %u, %u)\n", last->idx, last->row, last->col, last->length); - last->incoming = -1; - - fprintf(stderr, "%zu\n", len_lcs); - for (size_t i = 0; i < len_lcs; ++i) - { - fprintf(stderr, "%zu: ", i); - for (size_t j = 0; j < va_array_length(lcs_nodes[i]); ++j) + VA_LCS_Node const sink = {len_ref, len_obs, 0, -1, GVA_NULL}; + va_array_append(va_std_allocator, graph.nodes, ((Node2) {sink.row, sink.col, sink.length, GVA_NULL, GVA_NULL})); + uint32_t const sink_idx = va_array_length(graph.nodes) - 1; + size_t const h_len = va_array_length(lcs_nodes[len_lcs - 1]); + for (size_t i = 0; i < h_len; ++i) { - fprintf(stderr, "(%u, %u, %u) ", lcs_nodes[i][j].row, lcs_nodes[i][j].col, lcs_nodes[i][j].length); + VA_LCS_Node* const head = &lcs_nodes[len_lcs - 1][h_len - i - 1]; + + va_array_append(va_std_allocator, graph.edges, ((Edge2) {sink_idx, GVA_NULL})); + va_array_append(va_std_allocator, graph.nodes, ((Node2) {head->row, head->col, head->length, va_array_length(graph.edges) - 1, GVA_NULL})); + head->idx = va_array_length(graph.nodes) - 1; + + VA_Variant variant; + uint32_t const count = edges2(*head, sink, head->row == shift && head->col == shift, true, &variant); + fprintf(stderr, "SINK (%u, %u, %u) -> (%u, %u, %u) " VAR_FMT " x %u\n", head->row, head->col, head->length, sink.row, sink.col, sink.length, print_variant(variant, observed), count); } // for - fprintf(stderr, "\n"); - } // for + } // if + else + { + va_array_append(va_std_allocator, graph.nodes, ((Node2) {last->row, last->col, last->length, GVA_NULL, GVA_NULL})); + last->idx = va_array_length(graph.nodes) - 1; + } // else - VA_LCS_Node source = {shift, shift, 0, -1, GVA_NULL, 0, 0}; - bool found_source = last->row == shift && last->col == shift; - bool is_sink = true; + VA_LCS_Node source = {shift, shift, 0, -1, GVA_NULL}; + bool found_source = false; for (size_t t_i = 0; t_i < len_lcs; ++t_i) { size_t const t_len = va_array_length(lcs_nodes[len_lcs - t_i - 1]); for (size_t t_j = 0; t_j < t_len; ++t_j) { - VA_LCS_Node* const tail = &lcs_nodes[len_lcs - t_i - 1][t_len - t_j - 1]; + VA_LCS_Node const* const tail = &lcs_nodes[len_lcs - t_i - 1][t_len - t_j - 1]; if (tail->idx == GVA_NULL) { - // sink unreachable from tail, do not add to graph continue; } // if - fprintf(stderr, "%u %u %u %d\n", tail->row, tail->col, tail->length, tail->incoming); - size_t const tmp_len = MIN(len_lcs - t_i, tail->length + 1); - for (size_t h_i = 0; h_i < tmp_len; ++h_i) + if (tail->row == shift && tail->col == shift) + { + graph.source = tail->idx; + } // if + + bool const is_sink = tail->row + tail->length == len_ref + shift && tail->col + tail->length == len_obs + shift; + size_t const len = MIN(len_lcs - t_i, tail->length + 1); + for (size_t h_i = 0; h_i < len; ++h_i) { size_t const h_len = h_i == 0 ? t_len - t_j - 1: va_array_length(lcs_nodes[len_lcs - t_i - h_i - 1]); - //printf(" level: %zu with %zu nodes\n", len_lcs - t_i - h_i - 1, h_len); for (size_t h_j = 0; h_j < h_len; ++h_j) { - VA_LCS_Node* head = &lcs_nodes[len_lcs - t_i - h_i - 1][h_j]; - - fprintf(stderr, " %u %u %u: ", head->row, head->col, head->length); + VA_LCS_Node* const head = &lcs_nodes[len_lcs - t_i - h_i - 1][h_len - h_j - 1]; + if (head->row == shift && head->col == shift) + { + found_source = true; + } // if - if (head->row + head->length + h_i > tail->row + tail->length + tail->split_len || - head->col + head->length + h_i > tail->col + tail->length + tail->split_len) + VA_Variant variant; + uint32_t const count = edges2(*head, *tail, head->row == shift && head->col == shift, is_sink, &variant); + if (count > 0) { - if (tail->row + tail->length + tail->split_len > head->row + head->length + h_i || - tail->col + tail->length + tail->split_len > head->col + head->length + h_i) + if (head->idx == GVA_NULL) { - fprintf(stderr, "no edge X\n"); + va_array_append(va_std_allocator, graph.nodes, ((Node2) {head->row, head->col, head->length, GVA_NULL, GVA_NULL})); + head->idx = va_array_length(graph.nodes) - 1; } // if - else - { - fprintf(stderr, "CONVERSE\n"); - VA_Variant variant; - uint32_t const count = edges2(*tail, *head, tail->row == shift && tail->col == shift, false, &variant); - fprintf(stderr, " check (%u, %u, %u)\n", head->row, head->col, head->length); - if (variant.end + count > head->incoming) - { - fprintf(stderr, "SPLIT HEAD\n"); - split(&graph, head, tail->idx, count, variant, len_obs, observed); - } // if - else if (head->idx != GVA_NULL && count > 0) // strange? - { - fprintf(stderr, VAR_FMT " x %u\n", print_variant(variant, observed), count); - va_array_append(va_std_allocator, graph.edges, ((Edge2) {head->idx, graph.nodes[tail->idx].edges})); - graph.nodes[tail->idx].edges = va_array_length(graph.edges) - 1; - fprintf(stderr, "MAKE EDGE\n"); - tail->incoming = MIN(tail->incoming, variant.start); - fprintf(stderr, "new incoming (%u, %u, %u): %u\n", tail->row, tail->col, tail->length, tail->incoming); - } // if - else - { - fprintf(stderr, "no edge\n"); - } // else - } // else + va_array_append(va_std_allocator, graph.edges, ((Edge2) {tail->idx, graph.nodes[head->idx].edges})); + graph.nodes[head->idx].edges = va_array_length(graph.edges) - 1; + + fprintf(stderr, "(%u, %u, %u) -> (%u, %u, %u) " VAR_FMT " x %u\n", head->row, head->col, head->length, tail->row, tail->col, tail->length, print_variant(variant, observed), count); } // if else { - VA_Variant variant; - uint32_t const count = edges2(*head, *tail, head->row == shift && head->col == shift, is_sink, &variant); + uint32_t const count = edges2(*tail, *head, false, false, &variant); if (count > 0) { - fprintf(stderr, VAR_FMT " x %u\n", print_variant(variant, observed), count); - if (head->idx == GVA_NULL) - { - va_array_append(va_std_allocator, graph.nodes, ((Node2) {head->row, head->col, head->length, GVA_NULL, GVA_NULL})); - head->idx = va_array_length(graph.nodes) - 1; - fprintf(stderr, "MAKE NODE %u: (%u, %u, %u)\n", head->idx, head->row, head->col, head->length); - if (head->row == shift && head->col == shift) - { - // head is the source - source = *head; - graph.source = source.idx; - found_source = true; - } // if - } // if - head->incoming = MIN(head->incoming, variant.start); - fprintf(stderr, "YO! %u %u (%u,%u,%u) %u\n", variant.end, count, tail->row, tail->col, tail->length, tail->incoming); - if (variant.end + count > tail->incoming) - { - split(&graph, tail, head->idx, count, variant, len_obs, observed); - fprintf(stderr, "%u %u %u %u\n", tail->row, tail->col, tail->length, tail->idx); - } // if - else - { - va_array_append(va_std_allocator, graph.edges, ((Edge2) {tail->idx, graph.nodes[head->idx].edges})); - graph.nodes[head->idx].edges = va_array_length(graph.edges) - 1; - fprintf(stderr, "MAKE EDGE: %u\n", tail->idx); - } - } // if - else if (tail->split_len > 0) - { - uint32_t const nog_count = edges2(*head, (VA_LCS_Node) {tail->row, tail->col, tail->orig_len, 0, 0, 0, 0}, head->row == shift && head->col == shift, is_sink, &variant); - if (nog_count > 0) - { - for (uint32_t xxx = tail->idx; xxx != GVA_NULL; xxx = graph.nodes[xxx].lambda) - { - uint32_t const nog_nog_count = edges2(*head, (VA_LCS_Node) {graph.nodes[xxx].row, graph.nodes[xxx].col, graph.nodes[xxx].length, 0, 0, 0, 0}, head->row == shift && head->col == shift, false, &variant); - if (nog_nog_count > 0) - { - if (head->idx == GVA_NULL) - { - va_array_append(va_std_allocator, graph.nodes, ((Node2) {head->row, head->col, head->length, GVA_NULL, GVA_NULL})); - head->idx = va_array_length(graph.nodes) - 1; - fprintf(stderr, "MAKE NODE %u: (%u, %u, %u)\n", head->idx, head->row, head->col, head->length); - if (head->row == shift && head->col == shift) - { - // head is the source - source = *head; - graph.source = source.idx; - found_source = true; - } // if - } // if - fprintf(stderr, "check with lambda\n"); - va_array_append(va_std_allocator, graph.edges, ((Edge2) {xxx, graph.nodes[head->idx].edges})); - graph.nodes[head->idx].edges = va_array_length(graph.edges) - 1; - fprintf(stderr, "MAKE EDGE to lambda: %u\n", xxx); - - break; - } // if - } // for - } // if + va_array_append(va_std_allocator, graph.edges, ((Edge2) {head->idx, graph.nodes[tail->idx].edges})); + graph.nodes[tail->idx].edges = va_array_length(graph.edges) - 1; + + fprintf(stderr, "CONVERSE (%u, %u, %u) -> (%u, %u, %u) " VAR_FMT " x %u\n", tail->row, tail->col, tail->length, head->row, head->col, head->length, print_variant(variant, observed), count); } // if - else - { - fprintf(stderr, "no edge\n"); - } // else } // else } // for h_j - is_sink = false; } // for h_i - if (!found_source && tail->length + tail->split_len >= len_lcs - t_i) + if (!found_source && tail->length + 1 > len_lcs - t_i) { if (source.idx == GVA_NULL) { va_array_append(va_std_allocator, graph.nodes, ((Node2) {source.row, source.col, source.length, GVA_NULL, GVA_NULL})); source.idx = va_array_length(graph.nodes) - 1; - fprintf(stderr, "MAKE NODE %u: (%u, %u, %u)\n", source.idx, source.row, source.col, source.length); graph.source = source.idx; } // if - fprintf(stderr, "SOURCE %u %u %u: ", source.row, source.col, source.length); - // is this edges2 check always true? - if (edges2(source, *tail, true, is_sink, &(VA_Variant) {0, 0, 0, 0})) - { - va_array_append(va_std_allocator, graph.edges, ((Edge2) {tail->idx, graph.nodes[source.idx].edges})); - graph.nodes[source.idx].edges = va_array_length(graph.edges) - 1; - fprintf(stderr, "MAKE EDGE\n"); - } // if + va_array_append(va_std_allocator, graph.edges, ((Edge2) {tail->idx, graph.nodes[source.idx].edges})); + graph.nodes[source.idx].edges = va_array_length(graph.edges) - 1; + + VA_Variant variant; + uint32_t const count = edges2(source, *tail, true, is_sink, &variant); + fprintf(stderr, "SOURCE (%u, %u, %u) -> (%u, %u, %u) " VAR_FMT " x %u\n", source.row, source.col, source.length, tail->row, tail->col, tail->length, print_variant(variant, observed), count); } // if } // for t_j - // dealloc lcs pos level lcs_nodes[len_lcs - t_i - 1] = va_array_destroy(va_std_allocator, lcs_nodes[len_lcs - t_i - 1]); } // for t_i - - // deallocation lcs_nodes = va_std_allocator.alloc(va_std_allocator.context, lcs_nodes, len_lcs, 0); print_graph(graph, len_obs, observed, shift); From 907ba25c5f2485128d6b2d16944934f47ad0caea Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 21 Apr 2025 11:20:25 +0200 Subject: [PATCH 173/704] Tests for C --- c_regres.sh | 13 +++++++++++++ regres.sh | 1 - 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100755 c_regres.sh diff --git a/c_regres.sh b/c_regres.sh new file mode 100755 index 0000000..163d8df --- /dev/null +++ b/c_regres.sh @@ -0,0 +1,13 @@ +set -o errexit + +valgrind --error-exitcode=1 ./a.out TATCCGTCCG GAAAAATCCG +valgrind --error-exitcode=1 ./a.out GCCTGCCTAT GCCTAAAAAG +valgrind --error-exitcode=1 ./a.out TGCCTTA TAGCAGCCC +valgrind --error-exitcode=1 ./a.out CCC CACCCACA +valgrind --error-exitcode=1 ./a.out TTGGGAA CCGAATA +valgrind --error-exitcode=1 ./a.out GACAT ACACTCCCAT +valgrind --error-exitcode=1 ./a.out GAG AGGATAAGT +valgrind --error-exitcode=1 ./a.out CACGCTCGT ACACT +valgrind --error-exitcode=1 ./a.out GTTTA TCTTTCTGC +valgrind --error-exitcode=1 ./a.out TCAACAAAGG CAA +valgrind --error-exitcode=1 ./a.out CTTATAAT CCTACCG diff --git a/regres.sh b/regres.sh index 575e314..57bd810 100755 --- a/regres.sh +++ b/regres.sh @@ -11,4 +11,3 @@ python test.py CACGCTCGT ACACT python test.py GTTTA TCTTTCTGC python test.py TCAACAAAGG CAA python test.py CTTATAAT CCTACCG - From 07a0cdaf95e952dbb2538c8f2f68e58e952137aa Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 21 Apr 2025 11:21:10 +0200 Subject: [PATCH 174/704] Also show 'old' C implementation --- src/main.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/main.c b/src/main.c index ef4651a..ad6daa5 100644 --- a/src/main.c +++ b/src/main.c @@ -127,6 +127,29 @@ check(size_t const len_ref, char const reference[static len_ref], } // check +static void +print_graph(Graph const graph, size_t const len_obs, char const observed[static len_obs]) { + fprintf(stderr, "#nodes: %zu\n#edges: %zu\n", va_array_length(graph.nodes), va_array_length(graph.edges)); + fprintf(stderr, "source: %u\n", graph.source); + if (graph.nodes == NULL) + { + return; + } // if + for (size_t i = 0; i < va_array_length(graph.nodes); ++i) { + fprintf(stderr, "%zu: (%u, %u, %u):\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length); + if (graph.nodes[i].lambda != GVA_NULL) { + fprintf(stderr, " (%u, %u, %u): lambda\n", graph.nodes[graph.nodes[i].lambda].row, + graph.nodes[graph.nodes[i].lambda].col, graph.nodes[graph.nodes[i].lambda].length); + } // if + for (uint32_t j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) { + fprintf(stderr, " (%u, %u, %u): ", graph.nodes[graph.edges[j].tail].row, + graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length); + fprintf(stderr, VAR_FMT "\n", print_variant(graph.edges[j].variant, observed)); + } // for + } // for +} // print_graph + + int main(int argc, char* argv[static argc + 1]) { @@ -164,13 +187,14 @@ main(int argc, char* argv[static argc + 1]) //check(len_ref, reference, len_obs, observed, true); Graph2 graph2 = build(len_ref, reference, len_obs, observed, 0); - to_json2(graph2, len_obs, observed); + //to_json2(graph2, len_obs, observed); VA_LCS_Node** lcs_nodes = NULL; size_t const len_lcs = va_edit(va_std_allocator, len_ref, reference, len_obs, observed, &lcs_nodes); Graph graph = build_graph(va_std_allocator, len_ref, len_obs, len_lcs, lcs_nodes, 0, false); + print_graph(graph, len_obs, observed); // to_dot(graph, len_obs, observed); // to_json(graph, len_obs, observed, false); From c741208736aae487733d68a6e732f2d411bde3e9 Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 21 Apr 2025 11:22:17 +0200 Subject: [PATCH 175/704] Correct no split graph --- src/graph2.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/src/graph2.c b/src/graph2.c index 3ac778a..37833d0 100644 --- a/src/graph2.c +++ b/src/graph2.c @@ -155,6 +155,7 @@ bfs_traversal2(Graph2 const graph, size_t const len_obs, char const observed[sta return count; } // bfs_traversal2 + static void print_graph(Graph2 const graph, size_t const len_obs, char const observed[static len_obs], uint32_t const shift) { fprintf(stderr, "#nodes: %zu\n#edges: %zu\n", va_array_length(graph.nodes), va_array_length(graph.edges)); @@ -279,22 +280,27 @@ build(size_t const len_ref, char const reference[static len_ref], found_source = true; } // if - VA_Variant variant; - uint32_t const count = edges2(*head, *tail, head->row == shift && head->col == shift, is_sink, &variant); - if (count > 0) + if (head->row + head->length + h_i <= tail->row + tail->length && + head->col + head->length + h_i <= tail->col + tail->length) { - if (head->idx == GVA_NULL) + VA_Variant variant; + uint32_t const count = edges2(*head, *tail, head->row == shift && head->col == shift, is_sink, &variant); + if (count > 0) { - va_array_append(va_std_allocator, graph.nodes, ((Node2) {head->row, head->col, head->length, GVA_NULL, GVA_NULL})); - head->idx = va_array_length(graph.nodes) - 1; + if (head->idx == GVA_NULL) + { + va_array_append(va_std_allocator, graph.nodes, ((Node2) {head->row, head->col, head->length, GVA_NULL, GVA_NULL})); + head->idx = va_array_length(graph.nodes) - 1; + } // if + va_array_append(va_std_allocator, graph.edges, ((Edge2) {tail->idx, graph.nodes[head->idx].edges})); + graph.nodes[head->idx].edges = va_array_length(graph.edges) - 1; + + fprintf(stderr, "(%u, %u, %u) -> (%u, %u, %u) " VAR_FMT " x %u\n", head->row, head->col, head->length, tail->row, tail->col, tail->length, print_variant(variant, observed), count); } // if - va_array_append(va_std_allocator, graph.edges, ((Edge2) {tail->idx, graph.nodes[head->idx].edges})); - graph.nodes[head->idx].edges = va_array_length(graph.edges) - 1; - - fprintf(stderr, "(%u, %u, %u) -> (%u, %u, %u) " VAR_FMT " x %u\n", head->row, head->col, head->length, tail->row, tail->col, tail->length, print_variant(variant, observed), count); } // if - else + else if (head->idx != GVA_NULL) { + VA_Variant variant; uint32_t const count = edges2(*tail, *head, false, false, &variant); if (count > 0) { @@ -303,7 +309,8 @@ build(size_t const len_ref, char const reference[static len_ref], fprintf(stderr, "CONVERSE (%u, %u, %u) -> (%u, %u, %u) " VAR_FMT " x %u\n", tail->row, tail->col, tail->length, head->row, head->col, head->length, print_variant(variant, observed), count); } // if - } // else + } // if + } // for h_j } // for h_i if (!found_source && tail->length + 1 > len_lcs - t_i) From b78e8b6b459f70a964399b00250788ccac3d55bc Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 21 Apr 2025 12:53:33 +0200 Subject: [PATCH 176/704] Split detection + source node shortening --- src/graph2.c | 39 ++++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/src/graph2.c b/src/graph2.c index 37833d0..d048dca 100644 --- a/src/graph2.c +++ b/src/graph2.c @@ -157,7 +157,7 @@ bfs_traversal2(Graph2 const graph, size_t const len_obs, char const observed[sta static void -print_graph(Graph2 const graph, size_t const len_obs, char const observed[static len_obs], uint32_t const shift) { +print_graph(Graph2 const graph, size_t const len_obs, char const observed[static len_obs]) { fprintf(stderr, "#nodes: %zu\n#edges: %zu\n", va_array_length(graph.nodes), va_array_length(graph.edges)); fprintf(stderr, "source: %u\n", graph.source); if (graph.nodes == NULL) @@ -178,8 +178,9 @@ print_graph(Graph2 const graph, size_t const len_obs, char const observed[static ((VA_LCS_Node) {graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, 0, 0}), ((VA_LCS_Node) {graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length, 0, 0}), - graph.nodes[i].row == shift && graph.nodes[i].col == shift, - graph.nodes[graph.edges[j].tail].edges == GVA_NULL, &variant); + i == graph.source, + graph.nodes[graph.edges[j].tail].edges == GVA_NULL && graph.nodes[graph.edges[j].tail].edges == GVA_NULL, + &variant); fprintf(stderr, VAR_FMT " x %u\n", print_variant(variant, observed), count); } // for } // for @@ -237,6 +238,7 @@ build(size_t const len_ref, char const reference[static len_ref], va_array_append(va_std_allocator, graph.edges, ((Edge2) {sink_idx, GVA_NULL})); va_array_append(va_std_allocator, graph.nodes, ((Node2) {head->row, head->col, head->length, va_array_length(graph.edges) - 1, GVA_NULL})); head->idx = va_array_length(graph.nodes) - 1; + head->incoming = head->row + head->length; VA_Variant variant; uint32_t const count = edges2(*head, sink, head->row == shift && head->col == shift, true, &variant); @@ -256,7 +258,7 @@ build(size_t const len_ref, char const reference[static len_ref], size_t const t_len = va_array_length(lcs_nodes[len_lcs - t_i - 1]); for (size_t t_j = 0; t_j < t_len; ++t_j) { - VA_LCS_Node const* const tail = &lcs_nodes[len_lcs - t_i - 1][t_len - t_j - 1]; + VA_LCS_Node* const tail = &lcs_nodes[len_lcs - t_i - 1][t_len - t_j - 1]; if (tail->idx == GVA_NULL) { continue; @@ -264,7 +266,8 @@ build(size_t const len_ref, char const reference[static len_ref], if (tail->row == shift && tail->col == shift) { - graph.source = tail->idx; + source.idx = tail->idx; + source.incoming = tail->incoming; } // if bool const is_sink = tail->row + tail->length == len_ref + shift && tail->col + tail->length == len_obs + shift; @@ -287,6 +290,12 @@ build(size_t const len_ref, char const reference[static len_ref], uint32_t const count = edges2(*head, *tail, head->row == shift && head->col == shift, is_sink, &variant); if (count > 0) { + + if (variant.end + count > tail->incoming) + { + fprintf(stderr, "SPLIT (%u, %u, %u) first outgoing edge at %u\n", tail->row, tail->col, tail->length, tail->incoming); + } // if + if (head->idx == GVA_NULL) { va_array_append(va_std_allocator, graph.nodes, ((Node2) {head->row, head->col, head->length, GVA_NULL, GVA_NULL})); @@ -294,6 +303,7 @@ build(size_t const len_ref, char const reference[static len_ref], } // if va_array_append(va_std_allocator, graph.edges, ((Edge2) {tail->idx, graph.nodes[head->idx].edges})); graph.nodes[head->idx].edges = va_array_length(graph.edges) - 1; + head->incoming = MIN(head->incoming, variant.start); fprintf(stderr, "(%u, %u, %u) -> (%u, %u, %u) " VAR_FMT " x %u\n", head->row, head->col, head->length, tail->row, tail->col, tail->length, print_variant(variant, observed), count); } // if @@ -304,8 +314,15 @@ build(size_t const len_ref, char const reference[static len_ref], uint32_t const count = edges2(*tail, *head, false, false, &variant); if (count > 0) { + + if (variant.end + count > head->incoming) + { + fprintf(stderr, "SPLIT (%u, %u, %u) first outgoing edge at %u\n", head->row, head->col, head->length, head->incoming); + } // if + va_array_append(va_std_allocator, graph.edges, ((Edge2) {head->idx, graph.nodes[tail->idx].edges})); graph.nodes[tail->idx].edges = va_array_length(graph.edges) - 1; + tail->incoming = MIN(tail->incoming, variant.start); fprintf(stderr, "CONVERSE (%u, %u, %u) -> (%u, %u, %u) " VAR_FMT " x %u\n", tail->row, tail->col, tail->length, head->row, head->col, head->length, print_variant(variant, observed), count); } // if @@ -313,7 +330,7 @@ build(size_t const len_ref, char const reference[static len_ref], } // for h_j } // for h_i - if (!found_source && tail->length + 1 > len_lcs - t_i) + if (!found_source && tail->length >= len_lcs - t_i) { if (source.idx == GVA_NULL) { @@ -323,6 +340,7 @@ build(size_t const len_ref, char const reference[static len_ref], } // if va_array_append(va_std_allocator, graph.edges, ((Edge2) {tail->idx, graph.nodes[source.idx].edges})); graph.nodes[source.idx].edges = va_array_length(graph.edges) - 1; + source.incoming = MIN(source.incoming, source.row + source.length); VA_Variant variant; uint32_t const count = edges2(source, *tail, true, is_sink, &variant); @@ -333,7 +351,14 @@ build(size_t const len_ref, char const reference[static len_ref], } // for t_i lcs_nodes = va_std_allocator.alloc(va_std_allocator.context, lcs_nodes, len_lcs, 0); - print_graph(graph, len_obs, observed, shift); + fprintf(stderr, "SOURCE first outgoing edge at %u\n", source.incoming); + graph.nodes[source.idx].row += source.incoming; + graph.nodes[source.idx].col += source.incoming; + graph.nodes[source.idx].length -= source.incoming; + + graph.source = source.idx; + + print_graph(graph, len_obs, observed); return graph; } // build From 43adef6ab4370f48e01435eed4def9bb6bea1321 Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 21 Apr 2025 13:44:00 +0200 Subject: [PATCH 177/704] Correct split points (in reverse) --- src/graph2.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/graph2.c b/src/graph2.c index d048dca..f948250 100644 --- a/src/graph2.c +++ b/src/graph2.c @@ -187,6 +187,20 @@ print_graph(Graph2 const graph, size_t const len_obs, char const observed[static } // print_graph +static void +split(VA_LCS_Node* const node, uint32_t const in_count, VA_Variant const incoming, Graph2* const graph) +{ + fprintf(stderr, "\n\n***SPLIT (%u, %u, %u) because of first outgoing edge at %u\n", node->row, node->col, node->length, node->incoming); + + for (uint32_t i = 0; i < incoming.end + in_count - node->incoming; ++i) + { + fprintf(stderr, "%u\n", incoming.end + in_count - i - 1); + } // for + node->incoming = -1; + fprintf(stderr, "***\n\n\n"); +} // split + + Graph2 build(size_t const len_ref, char const reference[static len_ref], size_t const len_obs, char const observed[static len_obs], @@ -293,7 +307,7 @@ build(size_t const len_ref, char const reference[static len_ref], if (variant.end + count > tail->incoming) { - fprintf(stderr, "SPLIT (%u, %u, %u) first outgoing edge at %u\n", tail->row, tail->col, tail->length, tail->incoming); + split(tail, count, variant, &graph); } // if if (head->idx == GVA_NULL) @@ -317,7 +331,7 @@ build(size_t const len_ref, char const reference[static len_ref], if (variant.end + count > head->incoming) { - fprintf(stderr, "SPLIT (%u, %u, %u) first outgoing edge at %u\n", head->row, head->col, head->length, head->incoming); + split(head, count, variant, &graph); } // if va_array_append(va_std_allocator, graph.edges, ((Edge2) {head->idx, graph.nodes[tail->idx].edges})); From 89d9a0f07e8be67040183a9432c72c7005886af4 Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 21 Apr 2025 14:25:58 +0200 Subject: [PATCH 178/704] WIP: splitting --- src/graph2.c | 30 +++++++++++++++++++----------- src/main.c | 6 ++---- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/src/graph2.c b/src/graph2.c index f948250..a771d7e 100644 --- a/src/graph2.c +++ b/src/graph2.c @@ -167,13 +167,11 @@ print_graph(Graph2 const graph, size_t const len_obs, char const observed[static for (size_t i = 0; i < va_array_length(graph.nodes); ++i) { fprintf(stderr, "%zu: (%u, %u, %u):\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length); if (graph.nodes[i].lambda != GVA_NULL) { - fprintf(stderr, " (%u, %u, %u): lambda\n", graph.nodes[graph.nodes[i].lambda].row, - graph.nodes[graph.nodes[i].lambda].col, graph.nodes[graph.nodes[i].lambda].length); + fprintf(stderr, " (%u, %u, %u): lambda\n", graph.nodes[graph.nodes[i].lambda].row, graph.nodes[graph.nodes[i].lambda].col, graph.nodes[graph.nodes[i].lambda].length); } // if for (uint32_t j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) { - fprintf(stderr, " (%u, %u, %u): ", graph.nodes[graph.edges[j].tail].row, - graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length); - VA_Variant variant; + fprintf(stderr, " %u: (%u, %u, %u): ", graph.edges[j].tail, graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length); + VA_Variant variant = {0, 0, 0, 0}; uint32_t const count = edges2( ((VA_LCS_Node) {graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, 0, 0}), ((VA_LCS_Node) {graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, @@ -194,7 +192,17 @@ split(VA_LCS_Node* const node, uint32_t const in_count, VA_Variant const incomin for (uint32_t i = 0; i < incoming.end + in_count - node->incoming; ++i) { - fprintf(stderr, "%u\n", incoming.end + in_count - i - 1); + uint32_t const pos = incoming.end + in_count - i - 1; + + graph->nodes[node->idx].row += (pos - node->row); + graph->nodes[node->idx].col += (pos - node->row); + graph->nodes[node->idx].length -= (pos - node->row); + + va_array_append(va_std_allocator, graph->nodes, ((Node2) {node->row, node->col, pos - node->row, GVA_NULL, node->idx})); + node->idx = va_array_length(graph->nodes) - 1; + + fprintf(stderr, "(%u, %u, %u) l> (%u, %u, %u)\n", graph->nodes[node->idx].row, graph->nodes[node->idx].col, graph->nodes[node->idx].length, + graph->nodes[graph->nodes[node->idx].lambda].row, graph->nodes[graph->nodes[node->idx].lambda].col, graph->nodes[graph->nodes[node->idx].lambda].length); } // for node->incoming = -1; fprintf(stderr, "***\n\n\n"); @@ -304,17 +312,17 @@ build(size_t const len_ref, char const reference[static len_ref], uint32_t const count = edges2(*head, *tail, head->row == shift && head->col == shift, is_sink, &variant); if (count > 0) { + if (head->idx == GVA_NULL) + { + va_array_append(va_std_allocator, graph.nodes, ((Node2) {head->row, head->col, head->length, GVA_NULL, GVA_NULL})); + head->idx = va_array_length(graph.nodes) - 1; + } // if if (variant.end + count > tail->incoming) { split(tail, count, variant, &graph); } // if - if (head->idx == GVA_NULL) - { - va_array_append(va_std_allocator, graph.nodes, ((Node2) {head->row, head->col, head->length, GVA_NULL, GVA_NULL})); - head->idx = va_array_length(graph.nodes) - 1; - } // if va_array_append(va_std_allocator, graph.edges, ((Edge2) {tail->idx, graph.nodes[head->idx].edges})); graph.nodes[head->idx].edges = va_array_length(graph.edges) - 1; head->incoming = MIN(head->incoming, variant.start); diff --git a/src/main.c b/src/main.c index ad6daa5..cdee1d4 100644 --- a/src/main.c +++ b/src/main.c @@ -138,12 +138,10 @@ print_graph(Graph const graph, size_t const len_obs, char const observed[static for (size_t i = 0; i < va_array_length(graph.nodes); ++i) { fprintf(stderr, "%zu: (%u, %u, %u):\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length); if (graph.nodes[i].lambda != GVA_NULL) { - fprintf(stderr, " (%u, %u, %u): lambda\n", graph.nodes[graph.nodes[i].lambda].row, - graph.nodes[graph.nodes[i].lambda].col, graph.nodes[graph.nodes[i].lambda].length); + fprintf(stderr, " (%u, %u, %u): lambda\n", graph.nodes[graph.nodes[i].lambda].row, graph.nodes[graph.nodes[i].lambda].col, graph.nodes[graph.nodes[i].lambda].length); } // if for (uint32_t j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) { - fprintf(stderr, " (%u, %u, %u): ", graph.nodes[graph.edges[j].tail].row, - graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length); + fprintf(stderr, " %u: (%u, %u, %u): ", graph.edges[j].tail, graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length); fprintf(stderr, VAR_FMT "\n", print_variant(graph.edges[j].variant, observed)); } // for } // for From 612a6508490ae4fb78721ec82b0a6a623efdcc83 Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 21 Apr 2025 18:02:19 +0200 Subject: [PATCH 179/704] WIP: outgoing edge classification while splitting --- src/graph2.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 97 insertions(+), 7 deletions(-) diff --git a/src/graph2.c b/src/graph2.c index a771d7e..67f1813 100644 --- a/src/graph2.c +++ b/src/graph2.c @@ -186,7 +186,7 @@ print_graph(Graph2 const graph, size_t const len_obs, char const observed[static static void -split(VA_LCS_Node* const node, uint32_t const in_count, VA_Variant const incoming, Graph2* const graph) +split(VA_LCS_Node* const node, VA_LCS_Node* const head, uint32_t const in_count, VA_Variant const incoming, Graph2* const graph) { fprintf(stderr, "\n\n***SPLIT (%u, %u, %u) because of first outgoing edge at %u\n", node->row, node->col, node->length, node->incoming); @@ -194,17 +194,101 @@ split(VA_LCS_Node* const node, uint32_t const in_count, VA_Variant const incomin { uint32_t const pos = incoming.end + in_count - i - 1; + uint32_t head_head = GVA_NULL; + /* + uint32_t head_tail = GVA_NULL; + uint32_t tail_head = GVA_NULL; + uint32_t tail_tail = GVA_NULL; + */ + for (uint32_t j = graph->nodes[node->idx].edges; j != GVA_NULL; j = graph->edges[j].next) + { + Node2 const* const tail = &graph->nodes[graph->edges[j].tail]; + VA_Variant outgoing; + uint32_t const out_count = edges2(*node, (VA_LCS_Node) {tail->row, tail->col, tail->length, -1, GVA_NULL}, false, tail->edges == GVA_NULL && tail->lambda == GVA_NULL, &outgoing); + fprintf(stderr, " %u: (%u, %u, %u): x %u ", graph->edges[j].tail, tail->row, tail->col, tail->length, out_count); + + if (outgoing.start > pos) + { + /* + if (tail_tail != GVA_NULL) + { + graph->edges[tail_tail].next = j; + } // if + if (tail_head == GVA_NULL) + { + tail_head = j; + } // if + tail_tail = j; + */ + + fprintf(stderr, "tail\n"); + } // if + else if (outgoing.end + out_count - 1 <= pos) + { + /* + if (head_tail != GVA_NULL) + { + graph->edges[head_tail].next = j; + } // if + if (head_head == GVA_NULL) + { + head_head = j; + } // if + head_tail = j; + */ + + fprintf(stderr, "head\n"); + } // if + else + { + /* + if (tail_tail != GVA_NULL) + { + graph->edges[tail_tail].next = j; + } // if + if (tail_head == GVA_NULL) + { + tail_head = j; + } // if + tail_tail = j; + + va_array_append(va_std_allocator, graph->edges, ((Edge2) {graph->edges[j].tail, head_head})); + head_head = va_array_length(graph->edges) - 1; + */ + fprintf(stderr, "both\n"); + } // else + } // for + /* + if (head_tail != GVA_NULL) + { + graph->edges[head_tail].next = GVA_NULL; + } // if + if (tail_tail != GVA_NULL) + { + graph->edges[tail_tail].next = GVA_NULL; + } // if + graph->nodes[node->idx].edges = tail_head; + */ + graph->nodes[node->idx].row += (pos - node->row); graph->nodes[node->idx].col += (pos - node->row); graph->nodes[node->idx].length -= (pos - node->row); - va_array_append(va_std_allocator, graph->nodes, ((Node2) {node->row, node->col, pos - node->row, GVA_NULL, node->idx})); + /* + va_array_append(va_std_allocator, graph->edges, ((Edge2) {node->idx, graph->nodes[head->idx].edges})); + graph->nodes[head->idx].edges = va_array_length(graph->edges) - 1; + head->incoming = MIN(head->incoming, node->incoming + i); // TODO: check + */ + + va_array_append(va_std_allocator, graph->nodes, ((Node2) {node->row, node->col, pos - node->row, head_head, node->idx})); node->idx = va_array_length(graph->nodes) - 1; - fprintf(stderr, "(%u, %u, %u) l> (%u, %u, %u)\n", graph->nodes[node->idx].row, graph->nodes[node->idx].col, graph->nodes[node->idx].length, - graph->nodes[graph->nodes[node->idx].lambda].row, graph->nodes[graph->nodes[node->idx].lambda].col, graph->nodes[graph->nodes[node->idx].lambda].length); + Node2 const* const lambda = &graph->nodes[graph->nodes[node->idx].lambda]; + fprintf(stderr, "(%u, %u, %u) l> (%u, %u, %u) @ %u\n", graph->nodes[node->idx].row, graph->nodes[node->idx].col, graph->nodes[node->idx].length, + lambda->row, lambda->col, lambda->length, pos); } // for node->incoming = -1; + fprintf(stderr, "***\n\n\n"); } // split @@ -320,9 +404,11 @@ build(size_t const len_ref, char const reference[static len_ref], if (variant.end + count > tail->incoming) { - split(tail, count, variant, &graph); + split(tail, head, count, variant, &graph); + //continue; } // if + // TODO: add to lambda chain va_array_append(va_std_allocator, graph.edges, ((Edge2) {tail->idx, graph.nodes[head->idx].edges})); graph.nodes[head->idx].edges = va_array_length(graph.edges) - 1; head->incoming = MIN(head->incoming, variant.start); @@ -339,12 +425,17 @@ build(size_t const len_ref, char const reference[static len_ref], if (variant.end + count > head->incoming) { - split(head, count, variant, &graph); + split(head, tail, count, variant, &graph); + //continue; } // if va_array_append(va_std_allocator, graph.edges, ((Edge2) {head->idx, graph.nodes[tail->idx].edges})); graph.nodes[tail->idx].edges = va_array_length(graph.edges) - 1; tail->incoming = MIN(tail->incoming, variant.start); + if (source.idx == tail->idx) + { + source.incoming = tail->incoming; + } // if fprintf(stderr, "CONVERSE (%u, %u, %u) -> (%u, %u, %u) " VAR_FMT " x %u\n", tail->row, tail->col, tail->length, head->row, head->col, head->length, print_variant(variant, observed), count); } // if @@ -358,7 +449,6 @@ build(size_t const len_ref, char const reference[static len_ref], { va_array_append(va_std_allocator, graph.nodes, ((Node2) {source.row, source.col, source.length, GVA_NULL, GVA_NULL})); source.idx = va_array_length(graph.nodes) - 1; - graph.source = source.idx; } // if va_array_append(va_std_allocator, graph.edges, ((Edge2) {tail->idx, graph.nodes[source.idx].edges})); graph.nodes[source.idx].edges = va_array_length(graph.edges) - 1; From 35b846170f496e46209fc483ea36e5aed4626f3a Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 22 Apr 2025 11:41:21 +0200 Subject: [PATCH 180/704] WIP: Test set passing except for one --- src/graph2.c | 65 +++++++++++++++++++++++++++------------------------- 1 file changed, 34 insertions(+), 31 deletions(-) diff --git a/src/graph2.c b/src/graph2.c index 67f1813..4d70605 100644 --- a/src/graph2.c +++ b/src/graph2.c @@ -171,7 +171,7 @@ print_graph(Graph2 const graph, size_t const len_obs, char const observed[static } // if for (uint32_t j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) { fprintf(stderr, " %u: (%u, %u, %u): ", graph.edges[j].tail, graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length); - VA_Variant variant = {0, 0, 0, 0}; + VA_Variant variant; uint32_t const count = edges2( ((VA_LCS_Node) {graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, 0, 0}), ((VA_LCS_Node) {graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, @@ -190,16 +190,15 @@ split(VA_LCS_Node* const node, VA_LCS_Node* const head, uint32_t const in_count, { fprintf(stderr, "\n\n***SPLIT (%u, %u, %u) because of first outgoing edge at %u\n", node->row, node->col, node->length, node->incoming); + uint32_t pos = 0; for (uint32_t i = 0; i < incoming.end + in_count - node->incoming; ++i) { - uint32_t const pos = incoming.end + in_count - i - 1; + pos = incoming.end + in_count - i - 1; uint32_t head_head = GVA_NULL; - /* uint32_t head_tail = GVA_NULL; uint32_t tail_head = GVA_NULL; uint32_t tail_tail = GVA_NULL; - */ for (uint32_t j = graph->nodes[node->idx].edges; j != GVA_NULL; j = graph->edges[j].next) { Node2 const* const tail = &graph->nodes[graph->edges[j].tail]; @@ -209,7 +208,6 @@ split(VA_LCS_Node* const node, VA_LCS_Node* const head, uint32_t const in_count, if (outgoing.start > pos) { - /* if (tail_tail != GVA_NULL) { graph->edges[tail_tail].next = j; @@ -219,13 +217,11 @@ split(VA_LCS_Node* const node, VA_LCS_Node* const head, uint32_t const in_count, tail_head = j; } // if tail_tail = j; - */ fprintf(stderr, "tail\n"); } // if - else if (outgoing.end + out_count - 1 <= pos) + else if (outgoing.start + out_count - 1 <= pos) { - /* if (head_tail != GVA_NULL) { graph->edges[head_tail].next = j; @@ -235,13 +231,11 @@ split(VA_LCS_Node* const node, VA_LCS_Node* const head, uint32_t const in_count, head_head = j; } // if head_tail = j; - */ fprintf(stderr, "head\n"); } // if else { - /* if (tail_tail != GVA_NULL) { graph->edges[tail_tail].next = j; @@ -251,14 +245,12 @@ split(VA_LCS_Node* const node, VA_LCS_Node* const head, uint32_t const in_count, tail_head = j; } // if tail_tail = j; - va_array_append(va_std_allocator, graph->edges, ((Edge2) {graph->edges[j].tail, head_head})); head_head = va_array_length(graph->edges) - 1; - */ + fprintf(stderr, "both\n"); } // else } // for - /* if (head_tail != GVA_NULL) { graph->edges[head_tail].next = GVA_NULL; @@ -268,17 +260,13 @@ split(VA_LCS_Node* const node, VA_LCS_Node* const head, uint32_t const in_count, graph->edges[tail_tail].next = GVA_NULL; } // if graph->nodes[node->idx].edges = tail_head; - */ graph->nodes[node->idx].row += (pos - node->row); graph->nodes[node->idx].col += (pos - node->row); graph->nodes[node->idx].length -= (pos - node->row); - /* va_array_append(va_std_allocator, graph->edges, ((Edge2) {node->idx, graph->nodes[head->idx].edges})); graph->nodes[head->idx].edges = va_array_length(graph->edges) - 1; - head->incoming = MIN(head->incoming, node->incoming + i); // TODO: check - */ va_array_append(va_std_allocator, graph->nodes, ((Node2) {node->row, node->col, pos - node->row, head_head, node->idx})); node->idx = va_array_length(graph->nodes) - 1; @@ -287,7 +275,14 @@ split(VA_LCS_Node* const node, VA_LCS_Node* const head, uint32_t const in_count, fprintf(stderr, "(%u, %u, %u) l> (%u, %u, %u) @ %u\n", graph->nodes[node->idx].row, graph->nodes[node->idx].col, graph->nodes[node->idx].length, lambda->row, lambda->col, lambda->length, pos); } // for - node->incoming = -1; + + if (incoming.end < pos) + { + va_array_append(va_std_allocator, graph->edges, ((Edge2) {node->idx, graph->nodes[head->idx].edges})); + graph->nodes[head->idx].edges = va_array_length(graph->edges) - 1; + } // if + node->incoming = -1; // FIXME: real value? + head->incoming = incoming.start; fprintf(stderr, "***\n\n\n"); } // split @@ -405,13 +400,19 @@ build(size_t const len_ref, char const reference[static len_ref], if (variant.end + count > tail->incoming) { split(tail, head, count, variant, &graph); - //continue; } // if + else + { + uint32_t lambda = tail->idx; + while (graph.nodes[lambda].lambda != GVA_NULL && variant.end >= graph.nodes[lambda].row + graph.nodes[lambda].length) + { + lambda = graph.nodes[lambda].lambda; + } // if - // TODO: add to lambda chain - va_array_append(va_std_allocator, graph.edges, ((Edge2) {tail->idx, graph.nodes[head->idx].edges})); - graph.nodes[head->idx].edges = va_array_length(graph.edges) - 1; - head->incoming = MIN(head->incoming, variant.start); + va_array_append(va_std_allocator, graph.edges, ((Edge2) {lambda, graph.nodes[head->idx].edges})); + graph.nodes[head->idx].edges = va_array_length(graph.edges) - 1; + head->incoming = MIN(head->incoming, variant.start); + } // else fprintf(stderr, "(%u, %u, %u) -> (%u, %u, %u) " VAR_FMT " x %u\n", head->row, head->col, head->length, tail->row, tail->col, tail->length, print_variant(variant, observed), count); } // if @@ -426,16 +427,18 @@ build(size_t const len_ref, char const reference[static len_ref], if (variant.end + count > head->incoming) { split(head, tail, count, variant, &graph); - //continue; } // if - - va_array_append(va_std_allocator, graph.edges, ((Edge2) {head->idx, graph.nodes[tail->idx].edges})); - graph.nodes[tail->idx].edges = va_array_length(graph.edges) - 1; - tail->incoming = MIN(tail->incoming, variant.start); - if (source.idx == tail->idx) + else { - source.incoming = tail->incoming; - } // if + // FIXME: add to lambda chain? + va_array_append(va_std_allocator, graph.edges, ((Edge2) {head->idx, graph.nodes[tail->idx].edges})); + graph.nodes[tail->idx].edges = va_array_length(graph.edges) - 1; + tail->incoming = MIN(tail->incoming, variant.start); + if (source.idx == tail->idx) + { + source.incoming = tail->incoming; + } // if + } // else fprintf(stderr, "CONVERSE (%u, %u, %u) -> (%u, %u, %u) " VAR_FMT " x %u\n", tail->row, tail->col, tail->length, head->row, head->col, head->length, print_variant(variant, observed), count); } // if From fb14f79dbaf06ce048000639e6481359769dd3d6 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 22 Apr 2025 13:39:37 +0200 Subject: [PATCH 181/704] WIP: Manually checked the test set --- src/graph2.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/src/graph2.c b/src/graph2.c index 4d70605..f38acbd 100644 --- a/src/graph2.c +++ b/src/graph2.c @@ -188,7 +188,7 @@ print_graph(Graph2 const graph, size_t const len_obs, char const observed[static static void split(VA_LCS_Node* const node, VA_LCS_Node* const head, uint32_t const in_count, VA_Variant const incoming, Graph2* const graph) { - fprintf(stderr, "\n\n***SPLIT (%u, %u, %u) because of first outgoing edge at %u\n", node->row, node->col, node->length, node->incoming); + fprintf(stderr, "\n***SPLIT (%u, %u, %u) because of first outgoing edge at %u\n", node->row, node->col, node->length, node->incoming); uint32_t pos = 0; for (uint32_t i = 0; i < incoming.end + in_count - node->incoming; ++i) @@ -206,6 +206,7 @@ split(VA_LCS_Node* const node, VA_LCS_Node* const head, uint32_t const in_count, uint32_t const out_count = edges2(*node, (VA_LCS_Node) {tail->row, tail->col, tail->length, -1, GVA_NULL}, false, tail->edges == GVA_NULL && tail->lambda == GVA_NULL, &outgoing); fprintf(stderr, " %u: (%u, %u, %u): x %u ", graph->edges[j].tail, tail->row, tail->col, tail->length, out_count); + // TODO: can we avoid reordering the tail list? if (outgoing.start > pos) { if (tail_tail != GVA_NULL) @@ -284,10 +285,11 @@ split(VA_LCS_Node* const node, VA_LCS_Node* const head, uint32_t const in_count, node->incoming = -1; // FIXME: real value? head->incoming = incoming.start; - fprintf(stderr, "***\n\n\n"); + fprintf(stderr, "***\n\n"); } // split +// FIXME: incoming means the first *outgoing* edge Graph2 build(size_t const len_ref, char const reference[static len_ref], size_t const len_obs, char const observed[static len_obs], @@ -404,13 +406,22 @@ build(size_t const len_ref, char const reference[static len_ref], else { uint32_t lambda = tail->idx; - while (graph.nodes[lambda].lambda != GVA_NULL && variant.end >= graph.nodes[lambda].row + graph.nodes[lambda].length) + for (uint32_t i = 0; i < count; ++i) { - lambda = graph.nodes[lambda].lambda; - } // if - - va_array_append(va_std_allocator, graph.edges, ((Edge2) {lambda, graph.nodes[head->idx].edges})); - graph.nodes[head->idx].edges = va_array_length(graph.edges) - 1; + while (graph.nodes[lambda].lambda != GVA_NULL && + variant.end + i >= graph.nodes[lambda].row + graph.nodes[lambda].length) + { + lambda = graph.nodes[lambda].lambda; + } // if + + va_array_append(va_std_allocator, graph.edges, ((Edge2) {lambda, graph.nodes[head->idx].edges})); + graph.nodes[head->idx].edges = va_array_length(graph.edges) - 1; + + if (graph.nodes[lambda].lambda == GVA_NULL) + { + break; + } // if + } // for head->incoming = MIN(head->incoming, variant.start); } // else From 7b691523fd53868ec80fca18baef0ecb0abc8179 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 22 Apr 2025 17:07:04 +0200 Subject: [PATCH 182/704] WIP: more testing --- c_regres.sh | 3 +++ regres.sh | 3 +++ src/graph2.c | 28 ++++++++++++++++------------ src/main.c | 2 +- test.py | 2 +- 5 files changed, 24 insertions(+), 14 deletions(-) diff --git a/c_regres.sh b/c_regres.sh index 163d8df..47b1145 100755 --- a/c_regres.sh +++ b/c_regres.sh @@ -11,3 +11,6 @@ valgrind --error-exitcode=1 ./a.out CACGCTCGT ACACT valgrind --error-exitcode=1 ./a.out GTTTA TCTTTCTGC valgrind --error-exitcode=1 ./a.out TCAACAAAGG CAA valgrind --error-exitcode=1 ./a.out CTTATAAT CCTACCG +valgrind --error-exitcode=1 ./a.out GG GGTCA +valgrind --error-exitcode=1 ./a.out "" AAT +valgrind --error-exitcode=1 ./a.out AGTGG TGGGGTAGT diff --git a/regres.sh b/regres.sh index 57bd810..b3095d2 100755 --- a/regres.sh +++ b/regres.sh @@ -11,3 +11,6 @@ python test.py CACGCTCGT ACACT python test.py GTTTA TCTTTCTGC python test.py TCAACAAAGG CAA python test.py CTTATAAT CCTACCG +python test.py GG GGTCA +python test.py "" AAT +python test.py AGTGG TGGGGTAGT diff --git a/src/graph2.c b/src/graph2.c index f38acbd..49d0741 100644 --- a/src/graph2.c +++ b/src/graph2.c @@ -298,17 +298,6 @@ build(size_t const len_ref, char const reference[static len_ref], VA_LCS_Node** lcs_nodes = NULL; size_t const len_lcs = va_edit(va_std_allocator, len_ref, reference, len_obs, observed, &lcs_nodes); - fprintf(stderr, "%zu\n", len_lcs); - for (size_t i = 0; i < len_lcs; ++i) - { - fprintf(stderr, "%zu: ", i); - for (size_t j = 0; j < va_array_length(lcs_nodes[i]); ++j) - { - fprintf(stderr, "(%u, %u, %u) ", lcs_nodes[i][j].row, lcs_nodes[i][j].col, lcs_nodes[i][j].length); - } // for - fprintf(stderr, "\n"); - } // for - Graph2 graph = {NULL, NULL, GVA_NULL}; if (len_lcs == 0 || lcs_nodes == NULL) @@ -327,6 +316,18 @@ build(size_t const len_ref, char const reference[static len_ref], return graph; } // if + fprintf(stderr, "%zu\n", len_lcs); + for (size_t i = 0; i < len_lcs; ++i) + { + fprintf(stderr, "%zu: ", i); + for (size_t j = 0; j < va_array_length(lcs_nodes[i]); ++j) + { + fprintf(stderr, "(%u, %u, %u) ", lcs_nodes[i][j].row, lcs_nodes[i][j].col, lcs_nodes[i][j].length); + } // for + fprintf(stderr, "\n"); + } // for + + bool found_source = false; VA_LCS_Node* const last = &lcs_nodes[len_lcs - 1][va_array_length(lcs_nodes[len_lcs - 1]) - 1]; if (last->row + last->length != len_ref + shift || last->col + last->length != len_obs + shift) { @@ -337,6 +338,10 @@ build(size_t const len_ref, char const reference[static len_ref], for (size_t i = 0; i < h_len; ++i) { VA_LCS_Node* const head = &lcs_nodes[len_lcs - 1][h_len - i - 1]; + if (head->row == shift && head->col == shift) + { + found_source = true; + } // if va_array_append(va_std_allocator, graph.edges, ((Edge2) {sink_idx, GVA_NULL})); va_array_append(va_std_allocator, graph.nodes, ((Node2) {head->row, head->col, head->length, va_array_length(graph.edges) - 1, GVA_NULL})); @@ -355,7 +360,6 @@ build(size_t const len_ref, char const reference[static len_ref], } // else VA_LCS_Node source = {shift, shift, 0, -1, GVA_NULL}; - bool found_source = false; for (size_t t_i = 0; t_i < len_lcs; ++t_i) { size_t const t_len = va_array_length(lcs_nodes[len_lcs - t_i - 1]); diff --git a/src/main.c b/src/main.c index cdee1d4..bb73765 100644 --- a/src/main.c +++ b/src/main.c @@ -185,7 +185,7 @@ main(int argc, char* argv[static argc + 1]) //check(len_ref, reference, len_obs, observed, true); Graph2 graph2 = build(len_ref, reference, len_obs, observed, 0); - //to_json2(graph2, len_obs, observed); + to_json2(graph2, len_obs, observed); VA_LCS_Node** lcs_nodes = NULL; size_t const len_lcs = va_edit(va_std_allocator, len_ref, reference, len_obs, observed, &lcs_nodes); diff --git a/test.py b/test.py index aecf6a5..2361dba 100644 --- a/test.py +++ b/test.py @@ -5,7 +5,7 @@ import sys from itertools import chain -import networkx as nx +#import networkx as nx from algebra import LCSgraph from algebra.extractor import local_supremal From bcc6b0511358fb4e013790c3565c355b6889cb6c Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 23 Apr 2025 09:16:57 +0200 Subject: [PATCH 183/704] WIP: snapshot --- c_regres.sh | 16 ---------------- regres.sh | 7 +++++++ src/graph2.c | 19 +++++++++++++++---- 3 files changed, 22 insertions(+), 20 deletions(-) delete mode 100755 c_regres.sh diff --git a/c_regres.sh b/c_regres.sh deleted file mode 100755 index 47b1145..0000000 --- a/c_regres.sh +++ /dev/null @@ -1,16 +0,0 @@ -set -o errexit - -valgrind --error-exitcode=1 ./a.out TATCCGTCCG GAAAAATCCG -valgrind --error-exitcode=1 ./a.out GCCTGCCTAT GCCTAAAAAG -valgrind --error-exitcode=1 ./a.out TGCCTTA TAGCAGCCC -valgrind --error-exitcode=1 ./a.out CCC CACCCACA -valgrind --error-exitcode=1 ./a.out TTGGGAA CCGAATA -valgrind --error-exitcode=1 ./a.out GACAT ACACTCCCAT -valgrind --error-exitcode=1 ./a.out GAG AGGATAAGT -valgrind --error-exitcode=1 ./a.out CACGCTCGT ACACT -valgrind --error-exitcode=1 ./a.out GTTTA TCTTTCTGC -valgrind --error-exitcode=1 ./a.out TCAACAAAGG CAA -valgrind --error-exitcode=1 ./a.out CTTATAAT CCTACCG -valgrind --error-exitcode=1 ./a.out GG GGTCA -valgrind --error-exitcode=1 ./a.out "" AAT -valgrind --error-exitcode=1 ./a.out AGTGG TGGGGTAGT diff --git a/regres.sh b/regres.sh index b3095d2..96e548b 100755 --- a/regres.sh +++ b/regres.sh @@ -13,4 +13,11 @@ python test.py TCAACAAAGG CAA python test.py CTTATAAT CCTACCG python test.py GG GGTCA python test.py "" AAT +python test.py CGATGT TGTGA python test.py AGTGG TGGGGTAGT +python test.py CGAG CGAG +python test.py GGCGAA GGACCA +python test.py CTCCTCGGA ACCTCGTCTG +python test.py TTTCCAG TTGTTCA +python test.py TTAATTAGTT GACGTTAATT +#python test.py CGGGGGC CCGGCCG diff --git a/src/graph2.c b/src/graph2.c index 49d0741..9ede0d0 100644 --- a/src/graph2.c +++ b/src/graph2.c @@ -327,6 +327,7 @@ build(size_t const len_ref, char const reference[static len_ref], fprintf(stderr, "\n"); } // for + VA_LCS_Node source = {shift, shift, 0, -1, GVA_NULL}; bool found_source = false; VA_LCS_Node* const last = &lcs_nodes[len_lcs - 1][va_array_length(lcs_nodes[len_lcs - 1]) - 1]; if (last->row + last->length != len_ref + shift || last->col + last->length != len_obs + shift) @@ -357,9 +358,16 @@ build(size_t const len_ref, char const reference[static len_ref], { va_array_append(va_std_allocator, graph.nodes, ((Node2) {last->row, last->col, last->length, GVA_NULL, GVA_NULL})); last->idx = va_array_length(graph.nodes) - 1; + + if (last->row == shift && last->col == shift) + { + found_source = true; + source.idx = last->idx; + last->incoming = 0; + source.incoming = 0; + } // if } // else - VA_LCS_Node source = {shift, shift, 0, -1, GVA_NULL}; for (size_t t_i = 0; t_i < len_lcs; ++t_i) { size_t const t_len = va_array_length(lcs_nodes[len_lcs - t_i - 1]); @@ -412,6 +420,7 @@ build(size_t const len_ref, char const reference[static len_ref], uint32_t lambda = tail->idx; for (uint32_t i = 0; i < count; ++i) { + fprintf(stderr, "LAMBDA\n"); while (graph.nodes[lambda].lambda != GVA_NULL && variant.end + i >= graph.nodes[lambda].row + graph.nodes[lambda].length) { @@ -421,7 +430,7 @@ build(size_t const len_ref, char const reference[static len_ref], va_array_append(va_std_allocator, graph.edges, ((Edge2) {lambda, graph.nodes[head->idx].edges})); graph.nodes[head->idx].edges = va_array_length(graph.edges) - 1; - if (graph.nodes[lambda].lambda == GVA_NULL) + if (graph.nodes[lambda].lambda == GVA_NULL || variant.end + count <= graph.nodes[lambda].row + graph.nodes[lambda].length) { break; } // if @@ -432,10 +441,12 @@ build(size_t const len_ref, char const reference[static len_ref], fprintf(stderr, "(%u, %u, %u) -> (%u, %u, %u) " VAR_FMT " x %u\n", head->row, head->col, head->length, tail->row, tail->col, tail->length, print_variant(variant, observed), count); } // if } // if - else if (head->idx != GVA_NULL) + else if (/*head->idx != GVA_NULL &&*/ + tail->row + tail->length <= head->row + head->length + h_i && + tail->col + tail->length <= head->col + head->length + h_i) { VA_Variant variant; - uint32_t const count = edges2(*tail, *head, false, false, &variant); + uint32_t const count = edges2(*tail, *head, tail->row == shift && tail->col == shift, false, &variant); if (count > 0) { From 9bf57823ba18bd19afeaf57d35dee8e8b930d054 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 24 Apr 2025 14:41:14 +0200 Subject: [PATCH 184/704] WIP: Appending nodes for converse edges --- src/graph2.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/graph2.c b/src/graph2.c index 9ede0d0..7e0d73d 100644 --- a/src/graph2.c +++ b/src/graph2.c @@ -398,6 +398,8 @@ build(size_t const len_ref, char const reference[static len_ref], found_source = true; } // if + fprintf(stderr, "(%u, %u, %u) -> (%u, %u, %u)\n", head->row, head->col, head->length, tail->row, tail->col, tail->length); + if (head->row + head->length + h_i <= tail->row + tail->length && head->col + head->length + h_i <= tail->col + tail->length) { @@ -441,14 +443,20 @@ build(size_t const len_ref, char const reference[static len_ref], fprintf(stderr, "(%u, %u, %u) -> (%u, %u, %u) " VAR_FMT " x %u\n", head->row, head->col, head->length, tail->row, tail->col, tail->length, print_variant(variant, observed), count); } // if } // if - else if (/*head->idx != GVA_NULL &&*/ - tail->row + tail->length <= head->row + head->length + h_i && + else if (tail->row + tail->length <= head->row + head->length + h_i && tail->col + tail->length <= head->col + head->length + h_i) { VA_Variant variant; uint32_t const count = edges2(*tail, *head, tail->row == shift && tail->col == shift, false, &variant); if (count > 0) { + if (head->idx == GVA_NULL) + { + fprintf(stderr, "CONVERSE We don't know yet\n"); + fprintf(stderr, "Append (%u, %u, %zu) at level: %zu\n", tail->row, tail->col, tail->length - h_i - 1, h_i - 2); + h_i = len; + break; + } // if if (variant.end + count > head->incoming) { From 36afa4cc7b960b4ff239553ef53ae6b23f79c79e Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 24 Apr 2025 21:19:57 +0200 Subject: [PATCH 185/704] WIP: replacing lcs nodes --- regres.sh | 2 +- src/graph2.c | 20 +++++++++++++------- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/regres.sh b/regres.sh index 96e548b..0d23c13 100755 --- a/regres.sh +++ b/regres.sh @@ -20,4 +20,4 @@ python test.py GGCGAA GGACCA python test.py CTCCTCGGA ACCTCGTCTG python test.py TTTCCAG TTGTTCA python test.py TTAATTAGTT GACGTTAATT -#python test.py CGGGGGC CCGGCCG +python test.py CGGGGGC CCGGCCG diff --git a/src/graph2.c b/src/graph2.c index 7e0d73d..5478fb4 100644 --- a/src/graph2.c +++ b/src/graph2.c @@ -387,6 +387,7 @@ build(size_t const len_ref, char const reference[static len_ref], bool const is_sink = tail->row + tail->length == len_ref + shift && tail->col + tail->length == len_obs + shift; size_t const len = MIN(len_lcs - t_i, tail->length + 1); + bool replaced = false; for (size_t h_i = 0; h_i < len; ++h_i) { size_t const h_len = h_i == 0 ? t_len - t_j - 1: va_array_length(lcs_nodes[len_lcs - t_i - h_i - 1]); @@ -398,7 +399,7 @@ build(size_t const len_ref, char const reference[static len_ref], found_source = true; } // if - fprintf(stderr, "(%u, %u, %u) -> (%u, %u, %u)\n", head->row, head->col, head->length, tail->row, tail->col, tail->length); + fprintf(stderr, "(%u, %u, %u) vs (%u, %u, %u)\n", head->row, head->col, head->length, tail->row, tail->col, tail->length); if (head->row + head->length + h_i <= tail->row + tail->length && head->col + head->length + h_i <= tail->col + tail->length) @@ -422,7 +423,6 @@ build(size_t const len_ref, char const reference[static len_ref], uint32_t lambda = tail->idx; for (uint32_t i = 0; i < count; ++i) { - fprintf(stderr, "LAMBDA\n"); while (graph.nodes[lambda].lambda != GVA_NULL && variant.end + i >= graph.nodes[lambda].row + graph.nodes[lambda].length) { @@ -452,10 +452,16 @@ build(size_t const len_ref, char const reference[static len_ref], { if (head->idx == GVA_NULL) { - fprintf(stderr, "CONVERSE We don't know yet\n"); - fprintf(stderr, "Append (%u, %u, %zu) at level: %zu\n", tail->row, tail->col, tail->length - h_i - 1, h_i - 2); - h_i = len; - break; + fprintf(stderr, "CONVERSE We don't know yet %zu %zu\n", len_lcs - t_i - 1, h_i); + if (len_lcs - t_i - 2 > h_i) + { + fprintf(stderr, "Append (%u, %u, %zu) %u %u at level: %zu\n", tail->row, tail->col, tail->length - h_i - 1, tail->incoming, tail->idx, len_lcs - t_i - h_i - 2); + va_array_append(va_std_allocator, lcs_nodes[len_lcs - t_i - h_i - 2], ((VA_LCS_Node) {tail->row, tail->col, tail->length - h_i - 1, tail->incoming, tail->idx})); + h_i = len; + replaced = true; + break; + } // if + continue; } // if if (variant.end + count > head->incoming) @@ -480,7 +486,7 @@ build(size_t const len_ref, char const reference[static len_ref], } // for h_j } // for h_i - if (!found_source && tail->length >= len_lcs - t_i) + if (!replaced && !found_source && tail->length >= len_lcs - t_i) { if (source.idx == GVA_NULL) { From 5a52ee43a9a302806656b9e9b8a83f89ae6e9895 Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 25 Apr 2025 08:44:32 +0200 Subject: [PATCH 186/704] WIP: replacing lcs nodes --- regres.sh | 1 + src/graph2.c | 17 +++++++++++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/regres.sh b/regres.sh index 0d23c13..2666ac6 100755 --- a/regres.sh +++ b/regres.sh @@ -21,3 +21,4 @@ python test.py CTCCTCGGA ACCTCGTCTG python test.py TTTCCAG TTGTTCA python test.py TTAATTAGTT GACGTTAATT python test.py CGGGGGC CCGGCCG +python test.py CTATATAAAC CTCGTAA diff --git a/src/graph2.c b/src/graph2.c index 5478fb4..2f78afa 100644 --- a/src/graph2.c +++ b/src/graph2.c @@ -423,15 +423,23 @@ build(size_t const len_ref, char const reference[static len_ref], uint32_t lambda = tail->idx; for (uint32_t i = 0; i < count; ++i) { + fprintf(stderr, "LAMBDA: %u\n", lambda); + fprintf(stderr, " variant: %u\n", variant.end + i); + bool is_lambda = false; while (graph.nodes[lambda].lambda != GVA_NULL && variant.end + i >= graph.nodes[lambda].row + graph.nodes[lambda].length) { lambda = graph.nodes[lambda].lambda; + is_lambda = true; } // if - va_array_append(va_std_allocator, graph.edges, ((Edge2) {lambda, graph.nodes[head->idx].edges})); - graph.nodes[head->idx].edges = va_array_length(graph.edges) - 1; + if (i == 0 || is_lambda) + { + va_array_append(va_std_allocator, graph.edges, ((Edge2) {lambda, graph.nodes[head->idx].edges})); + graph.nodes[head->idx].edges = va_array_length(graph.edges) - 1; + } // if + fprintf(stderr, " next: %u\n", graph.nodes[lambda].lambda); if (graph.nodes[lambda].lambda == GVA_NULL || variant.end + count <= graph.nodes[lambda].row + graph.nodes[lambda].length) { break; @@ -452,10 +460,11 @@ build(size_t const len_ref, char const reference[static len_ref], { if (head->idx == GVA_NULL) { - fprintf(stderr, "CONVERSE We don't know yet %zu %zu\n", len_lcs - t_i - 1, h_i); + fprintf(stderr, "(%u, %u, %u) not in the graph yet\n", head->row, head->col, head->length); + // FIXME: why is this special? if (len_lcs - t_i - 2 > h_i) { - fprintf(stderr, "Append (%u, %u, %zu) %u %u at level: %zu\n", tail->row, tail->col, tail->length - h_i - 1, tail->incoming, tail->idx, len_lcs - t_i - h_i - 2); + fprintf(stderr, "Append (%u, %u, %zu) at level: %zu\n", tail->row, tail->col, tail->length - h_i - 1, len_lcs - t_i - h_i - 2); va_array_append(va_std_allocator, lcs_nodes[len_lcs - t_i - h_i - 2], ((VA_LCS_Node) {tail->row, tail->col, tail->length - h_i - 1, tail->incoming, tail->idx})); h_i = len; replaced = true; From b253414d4c375a7244ea265aae07487125027171 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 29 Apr 2025 17:47:52 +0200 Subject: [PATCH 187/704] WIP: appending lcs nodes --- regres.sh | 3 ++- src/graph2.c | 36 +++++++++++++++++++++++------------- 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/regres.sh b/regres.sh index 2666ac6..8855079 100755 --- a/regres.sh +++ b/regres.sh @@ -19,6 +19,7 @@ python test.py CGAG CGAG python test.py GGCGAA GGACCA python test.py CTCCTCGGA ACCTCGTCTG python test.py TTTCCAG TTGTTCA -python test.py TTAATTAGTT GACGTTAATT python test.py CGGGGGC CCGGCCG python test.py CTATATAAAC CTCGTAA +python test.py TTAATTAGTT GACGTTAATT +python test.py TAAG TAAGACCGC diff --git a/src/graph2.c b/src/graph2.c index 2f78afa..70e719e 100644 --- a/src/graph2.c +++ b/src/graph2.c @@ -368,6 +368,12 @@ build(size_t const len_ref, char const reference[static len_ref], } // if } // else + size_t* x = va_array_init(va_std_allocator, len_lcs, sizeof(*x)); + for (size_t i = 0; i < len_lcs; ++i) + { + x[i] = va_array_length(lcs_nodes[i]); + } // for + for (size_t t_i = 0; t_i < len_lcs; ++t_i) { size_t const t_len = va_array_length(lcs_nodes[len_lcs - t_i - 1]); @@ -387,10 +393,11 @@ build(size_t const len_ref, char const reference[static len_ref], bool const is_sink = tail->row + tail->length == len_ref + shift && tail->col + tail->length == len_obs + shift; size_t const len = MIN(len_lcs - t_i, tail->length + 1); - bool replaced = false; - for (size_t h_i = 0; h_i < len; ++h_i) + bool converse_stop = false; + size_t append_level = 0; + for (size_t h_i = 0; !converse_stop && h_i < len; ++h_i) { - size_t const h_len = h_i == 0 ? t_len - t_j - 1: va_array_length(lcs_nodes[len_lcs - t_i - h_i - 1]); + size_t const h_len = MIN(h_i == 0 ? t_len - t_j - 1: va_array_length(lcs_nodes[len_lcs - t_i - h_i - 1]), x[len_lcs - t_i - h_i - 1]); for (size_t h_j = 0; h_j < h_len; ++h_j) { VA_LCS_Node* const head = &lcs_nodes[len_lcs - t_i - h_i - 1][h_len - h_j - 1]; @@ -462,18 +469,14 @@ build(size_t const len_ref, char const reference[static len_ref], { fprintf(stderr, "(%u, %u, %u) not in the graph yet\n", head->row, head->col, head->length); // FIXME: why is this special? - if (len_lcs - t_i - 2 > h_i) + if (h_i > 0) { - fprintf(stderr, "Append (%u, %u, %zu) at level: %zu\n", tail->row, tail->col, tail->length - h_i - 1, len_lcs - t_i - h_i - 2); - va_array_append(va_std_allocator, lcs_nodes[len_lcs - t_i - h_i - 2], ((VA_LCS_Node) {tail->row, tail->col, tail->length - h_i - 1, tail->incoming, tail->idx})); - h_i = len; - replaced = true; - break; + fprintf(stderr, "Marking to stop\n"); + append_level = h_i; + converse_stop = true; } // if - continue; } // if - - if (variant.end + count > head->incoming) + else if (variant.end + count > head->incoming) { split(head, tail, count, variant, &graph); } // if @@ -495,7 +498,12 @@ build(size_t const len_ref, char const reference[static len_ref], } // for h_j } // for h_i - if (!replaced && !found_source && tail->length >= len_lcs - t_i) + if (converse_stop) + { + fprintf(stderr, "Append (%u, %u, %zu) at level: %zu\n", tail->row, tail->col, tail->length - append_level, len_lcs - t_i - append_level - 1); + va_array_append(va_std_allocator, lcs_nodes[len_lcs - t_i - append_level - 1], ((VA_LCS_Node) {tail->row, tail->col, tail->length - append_level, tail->incoming, tail->idx})); + } // if + else if (!found_source && tail->length >= len_lcs - t_i) { if (source.idx == GVA_NULL) { @@ -515,6 +523,8 @@ build(size_t const len_ref, char const reference[static len_ref], } // for t_i lcs_nodes = va_std_allocator.alloc(va_std_allocator.context, lcs_nodes, len_lcs, 0); + x = va_array_destroy(va_std_allocator, x); + fprintf(stderr, "SOURCE first outgoing edge at %u\n", source.incoming); graph.nodes[source.idx].row += source.incoming; graph.nodes[source.idx].col += source.incoming; From 659b0ee442d00018dd3b61996d503b5142f65a0e Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Wed, 30 Apr 2025 12:16:55 +0200 Subject: [PATCH 188/704] Variable for tests. --- regres.sh | 52 +++++++++++++++++++++++++++++----------------------- 1 file changed, 29 insertions(+), 23 deletions(-) diff --git a/regres.sh b/regres.sh index 8855079..2e6a11c 100755 --- a/regres.sh +++ b/regres.sh @@ -1,25 +1,31 @@ set -o errexit -python test.py TATCCGTCCG GAAAAATCCG -python test.py GCCTGCCTAT GCCTAAAAAG -python test.py TGCCTTA TAGCAGCCC -python test.py CCC CACCCACA -python test.py TTGGGAA CCGAATA -python test.py GACAT ACACTCCCAT -python test.py GAG AGGATAAGT -python test.py CACGCTCGT ACACT -python test.py GTTTA TCTTTCTGC -python test.py TCAACAAAGG CAA -python test.py CTTATAAT CCTACCG -python test.py GG GGTCA -python test.py "" AAT -python test.py CGATGT TGTGA -python test.py AGTGG TGGGGTAGT -python test.py CGAG CGAG -python test.py GGCGAA GGACCA -python test.py CTCCTCGGA ACCTCGTCTG -python test.py TTTCCAG TTGTTCA -python test.py CGGGGGC CCGGCCG -python test.py CTATATAAAC CTCGTAA -python test.py TTAATTAGTT GACGTTAATT -python test.py TAAG TAAGACCGC +TESTS=( +TATCCGTCCG GAAAAATCCG +GCCTGCCTAT GCCTAAAAAG +TGCCTTA TAGCAGCCC +CCC CACCCACA +TTGGGAA CCGAATA +GACAT ACACTCCCAT +GAG AGGATAAGT +CACGCTCGT ACACT +GTTTA TCTTTCTGC +TCAACAAAGG CAA +CTTATAAT CCTACCG +GG GGTCA +"" AAT +CGATGT TGTGA +AGTGG TGGGGTAGT +CGAG CGAG +GGCGAA GGACCA +CTCCTCGGA ACCTCGTCTG +TTTCCAG TTGTTCA +CGGGGGC CCGGCCG +CTATATAAAC CTCGTAA +TTAATTAGTT GACGTTAATT +TAAG TAAGACCGC +) + +for ((i=0; i<${#TESTS[@]}; i+=2)); do + python test.py \"${TESTS[i]}\" \"${TESTS[i+1]}\" +done From 5fb15570509213bb856100732efa9b20e02c5d01 Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 14 May 2025 15:57:18 +0200 Subject: [PATCH 189/704] WIP: moving nodes --- include/edit.h | 1 + regres.sh | 5 +++-- src/edit.c | 4 ++-- src/graph2.c | 49 +++++++++++++++++++++++++------------------------ 4 files changed, 31 insertions(+), 28 deletions(-) diff --git a/include/edit.h b/include/edit.h index e7c09eb..393a9cd 100644 --- a/include/edit.h +++ b/include/edit.h @@ -19,6 +19,7 @@ typedef struct uint32_t length; uint32_t incoming; uint32_t idx; + uint32_t x; } VA_LCS_Node; diff --git a/regres.sh b/regres.sh index 2e6a11c..d365402 100755 --- a/regres.sh +++ b/regres.sh @@ -13,7 +13,7 @@ GTTTA TCTTTCTGC TCAACAAAGG CAA CTTATAAT CCTACCG GG GGTCA -"" AAT +#"" AAT CGATGT TGTGA AGTGG TGGGGTAGT CGAG CGAG @@ -24,8 +24,9 @@ CGGGGGC CCGGCCG CTATATAAAC CTCGTAA TTAATTAGTT GACGTTAATT TAAG TAAGACCGC +GGCGA GGTTTTA ) for ((i=0; i<${#TESTS[@]}; i+=2)); do - python test.py \"${TESTS[i]}\" \"${TESTS[i+1]}\" + python test.py ${TESTS[i]} ${TESTS[i+1]} done diff --git a/src/edit.c b/src/edit.c index 3c5d9cb..3ace6ac 100644 --- a/src/edit.c +++ b/src/edit.c @@ -170,7 +170,7 @@ expand(Context const context, { context.lcs_nodes[lcs_pos] = va_array_init(context.allocator, 256, sizeof(*context.lcs_nodes[lcs_pos])); } // if - va_array_append(context.allocator, context.lcs_nodes[lcs_pos], ((VA_LCS_Node) {match_row, match_col, length, -1, -1})); + va_array_append(context.allocator, context.lcs_nodes[lcs_pos], ((VA_LCS_Node) {match_row, match_col, length, -1, -1, length})); matching = false; } // if row += 1; @@ -203,7 +203,7 @@ expand(Context const context, { context.lcs_nodes[lcs_pos] = va_array_init(context.allocator, 256, sizeof(*context.lcs_nodes[lcs_pos])); } // if - va_array_append(context.allocator, context.lcs_nodes[lcs_pos], ((VA_LCS_Node) {match_row, match_col, length, -1, -1})); + va_array_append(context.allocator, context.lcs_nodes[lcs_pos], ((VA_LCS_Node) {match_row, match_col, length, -1, -1, length})); } // if return steps; diff --git a/src/graph2.c b/src/graph2.c index 70e719e..2d37233 100644 --- a/src/graph2.c +++ b/src/graph2.c @@ -104,8 +104,8 @@ bfs_traversal2(Graph2 const graph, size_t const len_obs, char const observed[sta } // if count += 1; VA_Variant variant; - uint32_t const count2 = edges2(((VA_LCS_Node) {graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, 0, 0}), - ((VA_LCS_Node) {graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length, 0, 0}), + uint32_t const count2 = edges2(((VA_LCS_Node) {graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, 0, 0, 0}), + ((VA_LCS_Node) {graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length, 0, 0, 0}), graph.nodes[head].row == graph.nodes[graph.source].row && graph.nodes[head].col == graph.nodes[graph.source].col, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, &variant); for (uint32_t k = 0; k < count2; ++k) @@ -173,9 +173,9 @@ print_graph(Graph2 const graph, size_t const len_obs, char const observed[static fprintf(stderr, " %u: (%u, %u, %u): ", graph.edges[j].tail, graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length); VA_Variant variant; uint32_t const count = edges2( - ((VA_LCS_Node) {graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, 0, 0}), + ((VA_LCS_Node) {graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, 0, 0, 0}), ((VA_LCS_Node) {graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, - graph.nodes[graph.edges[j].tail].length, 0, 0}), + graph.nodes[graph.edges[j].tail].length, 0, 0, 0}), i == graph.source, graph.nodes[graph.edges[j].tail].edges == GVA_NULL && graph.nodes[graph.edges[j].tail].edges == GVA_NULL, &variant); @@ -203,7 +203,7 @@ split(VA_LCS_Node* const node, VA_LCS_Node* const head, uint32_t const in_count, { Node2 const* const tail = &graph->nodes[graph->edges[j].tail]; VA_Variant outgoing; - uint32_t const out_count = edges2(*node, (VA_LCS_Node) {tail->row, tail->col, tail->length, -1, GVA_NULL}, false, tail->edges == GVA_NULL && tail->lambda == GVA_NULL, &outgoing); + uint32_t const out_count = edges2(*node, (VA_LCS_Node) {tail->row, tail->col, tail->length, -1, GVA_NULL, 0}, false, tail->edges == GVA_NULL && tail->lambda == GVA_NULL, &outgoing); fprintf(stderr, " %u: (%u, %u, %u): x %u ", graph->edges[j].tail, tail->row, tail->col, tail->length, out_count); // TODO: can we avoid reordering the tail list? @@ -327,12 +327,12 @@ build(size_t const len_ref, char const reference[static len_ref], fprintf(stderr, "\n"); } // for - VA_LCS_Node source = {shift, shift, 0, -1, GVA_NULL}; + VA_LCS_Node source = {shift, shift, 0, -1, GVA_NULL, 0}; bool found_source = false; VA_LCS_Node* const last = &lcs_nodes[len_lcs - 1][va_array_length(lcs_nodes[len_lcs - 1]) - 1]; if (last->row + last->length != len_ref + shift || last->col + last->length != len_obs + shift) { - VA_LCS_Node const sink = {len_ref, len_obs, 0, -1, GVA_NULL}; + VA_LCS_Node const sink = {len_ref, len_obs, 0, -1, GVA_NULL, 0}; va_array_append(va_std_allocator, graph.nodes, ((Node2) {sink.row, sink.col, sink.length, GVA_NULL, GVA_NULL})); uint32_t const sink_idx = va_array_length(graph.nodes) - 1; size_t const h_len = va_array_length(lcs_nodes[len_lcs - 1]); @@ -392,12 +392,12 @@ build(size_t const len_ref, char const reference[static len_ref], } // if bool const is_sink = tail->row + tail->length == len_ref + shift && tail->col + tail->length == len_obs + shift; - size_t const len = MIN(len_lcs - t_i, tail->length + 1); - bool converse_stop = false; - size_t append_level = 0; - for (size_t h_i = 0; !converse_stop && h_i < len; ++h_i) + size_t const len = MIN(len_lcs - t_i, tail->x + 1); + for (size_t h_i = 0; h_i < len; ++h_i) { - size_t const h_len = MIN(h_i == 0 ? t_len - t_j - 1: va_array_length(lcs_nodes[len_lcs - t_i - h_i - 1]), x[len_lcs - t_i - h_i - 1]); + size_t const h_len = h_i == 0 && t_len - t_j <= x[len_lcs - t_i - h_i - 1] ? + t_len - t_j - 1 : + x[len_lcs - t_i - h_i - 1]; for (size_t h_j = 0; h_j < h_len; ++h_j) { VA_LCS_Node* const head = &lcs_nodes[len_lcs - t_i - h_i - 1][h_len - h_j - 1]; @@ -408,8 +408,8 @@ build(size_t const len_ref, char const reference[static len_ref], fprintf(stderr, "(%u, %u, %u) vs (%u, %u, %u)\n", head->row, head->col, head->length, tail->row, tail->col, tail->length); - if (head->row + head->length + h_i <= tail->row + tail->length && - head->col + head->length + h_i <= tail->col + tail->length) + if (head->row + head->x + h_i <= tail->row + tail->x && + head->col + head->x + h_i <= tail->col + tail->x) { VA_Variant variant; uint32_t const count = edges2(*head, *tail, head->row == shift && head->col == shift, is_sink, &variant); @@ -458,8 +458,9 @@ build(size_t const len_ref, char const reference[static len_ref], fprintf(stderr, "(%u, %u, %u) -> (%u, %u, %u) " VAR_FMT " x %u\n", head->row, head->col, head->length, tail->row, tail->col, tail->length, print_variant(variant, observed), count); } // if } // if - else if (tail->row + tail->length <= head->row + head->length + h_i && - tail->col + tail->length <= head->col + head->length + h_i) + // CONVERSE EDGE + else if (tail->row + tail->x <= head->row + head->x + h_i && + tail->col + tail->x <= head->col + head->x + h_i) { VA_Variant variant; uint32_t const count = edges2(*tail, *head, tail->row == shift && tail->col == shift, false, &variant); @@ -472,10 +473,12 @@ build(size_t const len_ref, char const reference[static len_ref], if (h_i > 0) { fprintf(stderr, "Marking to stop\n"); - append_level = h_i; - converse_stop = true; + va_array_append(va_std_allocator, lcs_nodes[len_lcs - t_i - h_i - 1], ((VA_LCS_Node) {tail->row, tail->col, tail->length, tail->incoming, tail->idx, tail->x - h_i})); + fprintf(stderr, "Append (%u, %u, %u) at level: %zu\n", tail->row, tail->col, tail->length, len_lcs - t_i - h_i - 1); + goto hier; } // if } // if + // TODO: reorder cases else if (variant.end + count > head->incoming) { split(head, tail, count, variant, &graph); @@ -498,12 +501,7 @@ build(size_t const len_ref, char const reference[static len_ref], } // for h_j } // for h_i - if (converse_stop) - { - fprintf(stderr, "Append (%u, %u, %zu) at level: %zu\n", tail->row, tail->col, tail->length - append_level, len_lcs - t_i - append_level - 1); - va_array_append(va_std_allocator, lcs_nodes[len_lcs - t_i - append_level - 1], ((VA_LCS_Node) {tail->row, tail->col, tail->length - append_level, tail->incoming, tail->idx})); - } // if - else if (!found_source && tail->length >= len_lcs - t_i) + if (!found_source && tail->x >= len_lcs - t_i) { if (source.idx == GVA_NULL) { @@ -518,6 +516,9 @@ build(size_t const len_ref, char const reference[static len_ref], uint32_t const count = edges2(source, *tail, true, is_sink, &variant); fprintf(stderr, "SOURCE (%u, %u, %u) -> (%u, %u, %u) " VAR_FMT " x %u\n", source.row, source.col, source.length, tail->row, tail->col, tail->length, print_variant(variant, observed), count); } // if + +hier:; + } // for t_j lcs_nodes[len_lcs - t_i - 1] = va_array_destroy(va_std_allocator, lcs_nodes[len_lcs - t_i - 1]); } // for t_i From 70a35a549c56580c4d53e88b404e5f83e7217eee Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 19 May 2025 16:52:53 +0200 Subject: [PATCH 190/704] WIP: new graph build idea --- include/edit.h | 21 +++++ src/edit.c | 5 ++ src/edit2.c | 202 +++++++++++++++++++++++++++++++++++++++++ src/graph2.c | 239 ++++++++++++------------------------------------- 4 files changed, 283 insertions(+), 184 deletions(-) create mode 100644 src/edit2.c diff --git a/include/edit.h b/include/edit.h index 393a9cd..58fe559 100644 --- a/include/edit.h +++ b/include/edit.h @@ -23,6 +23,17 @@ typedef struct } VA_LCS_Node; +typedef struct +{ + uint32_t row; + uint32_t col; + uint32_t length; + uint32_t lcs_pos; + uint32_t prev; + uint32_t idx; +} VA_LCS_Node2; + + size_t va_edit_distance_only(VA_Allocator const allocator, size_t const len_ref, @@ -40,6 +51,16 @@ va_edit(VA_Allocator const allocator, VA_LCS_Node*** restrict lcs_nodes); +size_t +va_edit2(VA_Allocator const allocator, + size_t const len_ref, + char const reference[static restrict len_ref], + size_t const len_obs, + char const observed[static restrict len_obs], + VA_LCS_Node2** restrict lcs_nodes, + uint32_t** restrict lcs_index); + + #ifdef __cplusplus } // extern "C" #endif diff --git a/src/edit.c b/src/edit.c index 3ace6ac..a585ba3 100644 --- a/src/edit.c +++ b/src/edit.c @@ -7,6 +7,9 @@ #include "../include/edit.h" // VA_LCS_Node, va_edit* +#include + + static inline size_t wu_snake(size_t const m, char const a[static restrict m], @@ -171,6 +174,7 @@ expand(Context const context, context.lcs_nodes[lcs_pos] = va_array_init(context.allocator, 256, sizeof(*context.lcs_nodes[lcs_pos])); } // if va_array_append(context.allocator, context.lcs_nodes[lcs_pos], ((VA_LCS_Node) {match_row, match_col, length, -1, -1, length})); + fprintf(stderr, "(%zu, %zu, %zu)\n", match_row, match_col, length); matching = false; } // if row += 1; @@ -204,6 +208,7 @@ expand(Context const context, context.lcs_nodes[lcs_pos] = va_array_init(context.allocator, 256, sizeof(*context.lcs_nodes[lcs_pos])); } // if va_array_append(context.allocator, context.lcs_nodes[lcs_pos], ((VA_LCS_Node) {match_row, match_col, length, -1, -1, length})); + fprintf(stderr, "(%zu, %zu, %zu)\n", match_row, match_col, length); } // if return steps; diff --git a/src/edit2.c b/src/edit2.c new file mode 100644 index 0000000..1463485 --- /dev/null +++ b/src/edit2.c @@ -0,0 +1,202 @@ +#include // imaxabs +#include // bool, false, true +#include // NULL, ptrdiff_t, size_t + +#include "../include/alloc.h" // VA_Allocator +#include "../include/array.h" // va_array_* +#include "../include/edit.h" + + +static inline size_t +umax(size_t const a, size_t const b) +{ + return a > b ? a : b; +} // umax + + +static inline size_t +umin(size_t const a, size_t const b) +{ + return a < b ? a : b; +} // umin + + +typedef struct +{ + VA_Allocator const allocator; + size_t const len_ref; + char const* const restrict reference; + size_t const len_obs; + char const* const restrict observed; + size_t* const restrict diagonals; + uint32_t* const restrict lcs_index; +} Context; + + +static size_t +expand(Context const context, + ptrdiff_t const idx, + size_t const p, + size_t* const len_lcs, + VA_LCS_Node2** lcs_nodes) +{ + ptrdiff_t const delta = context.len_obs - context.len_ref; + size_t const offset = context.len_ref + 1; + + size_t row; + size_t col; + size_t end; + if (idx > 0) + { + row = context.diagonals[offset + idx]; + col = row + idx; + end = umax(context.diagonals[offset + idx - 1] - 1, context.diagonals[offset + idx + 1]); + } // if + else if (idx < 0) + { + col = context.diagonals[offset + idx]; + row = col - idx; + end = umax(context.diagonals[offset + idx - 1], context.diagonals[offset + idx + 1] - 1); + } // if + else + { + row = context.diagonals[offset + idx]; + col = row + idx; + end = umax(context.diagonals[offset + idx - 1], context.diagonals[offset + idx + 1]); + } // else + + size_t steps = end + 1; + + bool matching = false; + size_t match_row = 0; + size_t match_col = 0; + + for (size_t i = context.diagonals[offset + idx]; i < end; ++i) + { + if (context.reference[row] == context.observed[col]) + { + if (!matching) + { + match_row = row; + match_col = col; + matching = true; + } // if + } // if + else if (matching) + { + ptrdiff_t const d_row = context.len_ref - row; + ptrdiff_t const d_col = context.len_obs - col; + size_t const lcs_pos = (row + col - imaxabs(delta) - 2 * p + imaxabs(d_row - d_col)) / 2 - 1; + if (lcs_pos + 1 > *len_lcs) + { + *len_lcs = lcs_pos + 1; + } // if + size_t const length = row - match_row; + va_array_append(context.allocator, *lcs_nodes, ((VA_LCS_Node2) {match_row, match_col, length, lcs_pos, context.lcs_index[lcs_pos], -1})); + context.lcs_index[lcs_pos] = va_array_length(*lcs_nodes) - 1; + matching = false; + } // if + row += 1; + col += 1; + } // for + + if (!matching) + { + match_row = row; + match_col = col; + } // if + while (row < context.len_ref && col < context.len_obs && context.reference[row] == context.observed[col]) + { + matching = true; + row += 1; + col += 1; + steps += 1; + } // while + if (matching) + { + ptrdiff_t const d_row = context.len_ref - row; + ptrdiff_t const d_col = context.len_obs - col; + size_t const lcs_pos = (row + col - imaxabs(delta) - 2 * p + imaxabs(d_row - d_col)) / 2 - 1; + if (lcs_pos + 1 > *len_lcs) + { + *len_lcs = lcs_pos + 1; + } // if + size_t const length = row - match_row; + va_array_append(context.allocator, *lcs_nodes, ((VA_LCS_Node2) {match_row, match_col, length, lcs_pos, context.lcs_index[lcs_pos], -1})); + context.lcs_index[lcs_pos] = va_array_length(*lcs_nodes) - 1; + } // if + + return steps; +} // expand + + +size_t +va_edit2(VA_Allocator const allocator, + size_t const len_ref, + char const reference[static restrict len_ref], + size_t const len_obs, + char const observed[static restrict len_obs], + VA_LCS_Node2** restrict lcs_nodes, + uint32_t** restrict lcs_index) +{ + ptrdiff_t const delta = len_obs - len_ref; + size_t const offset = len_ref + 1; + size_t const size = len_ref + len_obs + 3; + + Context const context = + { + allocator, + len_ref, + reference, + len_obs, + observed, + .diagonals = allocator.alloc(allocator.context, NULL, 0, size * sizeof(*context.diagonals)), + .lcs_index = allocator.alloc(allocator.context, NULL, 0, umin(len_ref, len_obs) * sizeof(*context.lcs_index)), + }; + if (context.diagonals == NULL || context.lcs_index == NULL) + { + allocator.alloc(allocator.context, context.diagonals, size * sizeof(*context.diagonals), 0); + allocator.alloc(allocator.context, context.lcs_index, umin(len_ref, len_obs) * sizeof(*context.lcs_index), 0); + return -1; + } // if + + for (size_t i = 0; i < size; ++i) + { + context.diagonals[i] = 0; + } // for + + for (size_t i = 0; i < umin(len_ref, len_obs); ++i) + { + context.lcs_index[i] = -1; + } // for + + *lcs_nodes = NULL; + + size_t const lower = delta > 0 ? 0 : delta; + size_t const upper = delta > 0 ? delta : 0; + + size_t const len = umax(len_ref, len_obs) - imaxabs(delta); + size_t p = 0; + size_t max_lcs_pos = 0; + while (context.diagonals[offset + delta] <= len) + { + for (ptrdiff_t idx = lower - p; idx < delta; ++idx) + { + context.diagonals[offset + idx] = expand(context, idx, p, &max_lcs_pos, lcs_nodes); + } // for + for (ptrdiff_t idx = upper + p; idx > delta; --idx) + { + context.diagonals[offset + idx] = expand(context, idx, p, &max_lcs_pos, lcs_nodes); + } // for + context.diagonals[offset + delta] = expand(context, delta, p, &max_lcs_pos, lcs_nodes); + + p += 1; + } // while + + allocator.alloc(allocator.context, context.diagonals, size * sizeof(*context.diagonals), 0); + + // transfer ownership + *lcs_index = allocator.alloc(allocator.context, context.lcs_index, umin(len_ref, len_obs) * sizeof(*context.lcs_index), max_lcs_pos * sizeof(*context.lcs_index)); + + return max_lcs_pos; +} // va_edit2 diff --git a/src/graph2.c b/src/graph2.c index 2d37233..9eb7198 100644 --- a/src/graph2.c +++ b/src/graph2.c @@ -295,8 +295,9 @@ build(size_t const len_ref, char const reference[static len_ref], size_t const len_obs, char const observed[static len_obs], size_t const shift) { - VA_LCS_Node** lcs_nodes = NULL; - size_t const len_lcs = va_edit(va_std_allocator, len_ref, reference, len_obs, observed, &lcs_nodes); + VA_LCS_Node2* lcs_nodes = NULL; + uint32_t* lcs_index = NULL; + size_t const len_lcs = va_edit2(va_std_allocator, len_ref, reference, len_obs, observed, &lcs_nodes, &lcs_index); Graph2 graph = {NULL, NULL, GVA_NULL}; @@ -316,222 +317,92 @@ build(size_t const len_ref, char const reference[static len_ref], return graph; } // if - fprintf(stderr, "%zu\n", len_lcs); + for (size_t i = 0; i < va_array_length(lcs_nodes); ++i) + { + fprintf(stderr, "%zu: (%u, %u, %u), %d\n", i, lcs_nodes[i].row, lcs_nodes[i].col, lcs_nodes[i].length, lcs_nodes[i].prev); + } // for + for (size_t i = 0; i < len_lcs; ++i) { - fprintf(stderr, "%zu: ", i); - for (size_t j = 0; j < va_array_length(lcs_nodes[i]); ++j) - { - fprintf(stderr, "(%u, %u, %u) ", lcs_nodes[i][j].row, lcs_nodes[i][j].col, lcs_nodes[i][j].length); - } // for - fprintf(stderr, "\n"); + fprintf(stderr, "%zu: %d\n", i, lcs_index[i]); } // for - VA_LCS_Node source = {shift, shift, 0, -1, GVA_NULL, 0}; - bool found_source = false; - VA_LCS_Node* const last = &lcs_nodes[len_lcs - 1][va_array_length(lcs_nodes[len_lcs - 1]) - 1]; + VA_LCS_Node2* const last = &lcs_nodes[lcs_index[len_lcs - 1]]; if (last->row + last->length != len_ref + shift || last->col + last->length != len_obs + shift) { - VA_LCS_Node const sink = {len_ref, len_obs, 0, -1, GVA_NULL, 0}; + fprintf(stderr, "Nieuwe sink\n"); + VA_LCS_Node2 const sink = {len_ref, len_obs, 0, len_lcs, GVA_NULL, GVA_NULL}; va_array_append(va_std_allocator, graph.nodes, ((Node2) {sink.row, sink.col, sink.length, GVA_NULL, GVA_NULL})); uint32_t const sink_idx = va_array_length(graph.nodes) - 1; - size_t const h_len = va_array_length(lcs_nodes[len_lcs - 1]); - for (size_t i = 0; i < h_len; ++i) + for (uint32_t idx = lcs_index[len_lcs - 1]; idx != GVA_NULL; idx = lcs_nodes[idx].prev) { - VA_LCS_Node* const head = &lcs_nodes[len_lcs - 1][h_len - i - 1]; - if (head->row == shift && head->col == shift) - { - found_source = true; - } // if - + VA_LCS_Node2* const head = &lcs_nodes[idx]; va_array_append(va_std_allocator, graph.edges, ((Edge2) {sink_idx, GVA_NULL})); va_array_append(va_std_allocator, graph.nodes, ((Node2) {head->row, head->col, head->length, va_array_length(graph.edges) - 1, GVA_NULL})); head->idx = va_array_length(graph.nodes) - 1; - head->incoming = head->row + head->length; - - VA_Variant variant; - uint32_t const count = edges2(*head, sink, head->row == shift && head->col == shift, true, &variant); - fprintf(stderr, "SINK (%u, %u, %u) -> (%u, %u, %u) " VAR_FMT " x %u\n", head->row, head->col, head->length, sink.row, sink.col, sink.length, print_variant(variant, observed), count); } // for } // if else { + fprintf(stderr, "Oude sink\n"); va_array_append(va_std_allocator, graph.nodes, ((Node2) {last->row, last->col, last->length, GVA_NULL, GVA_NULL})); last->idx = va_array_length(graph.nodes) - 1; - - if (last->row == shift && last->col == shift) - { - found_source = true; - source.idx = last->idx; - last->incoming = 0; - source.incoming = 0; - } // if } // else - size_t* x = va_array_init(va_std_allocator, len_lcs, sizeof(*x)); - for (size_t i = 0; i < len_lcs; ++i) - { - x[i] = va_array_length(lcs_nodes[i]); - } // for - - for (size_t t_i = 0; t_i < len_lcs; ++t_i) + size_t const t_len = va_array_length(lcs_nodes); + for (size_t i = 0; i < t_len; ++i) { - size_t const t_len = va_array_length(lcs_nodes[len_lcs - t_i - 1]); - for (size_t t_j = 0; t_j < t_len; ++t_j) + VA_LCS_Node2* const tail = &lcs_nodes[t_len - i - 1]; + fprintf(stderr, "(%u, %u, %u) @ %u\n", tail->row, tail->col, tail->length, tail->lcs_pos); + if (tail->idx == GVA_NULL) { - VA_LCS_Node* const tail = &lcs_nodes[len_lcs - t_i - 1][t_len - t_j - 1]; - if (tail->idx == GVA_NULL) - { - continue; - } // if - - if (tail->row == shift && tail->col == shift) - { - source.idx = tail->idx; - source.incoming = tail->incoming; - } // if + fprintf(stderr, " Not in graph\n"); + tail->lcs_pos = GVA_NULL; + continue; + } // if - bool const is_sink = tail->row + tail->length == len_ref + shift && tail->col + tail->length == len_obs + shift; - size_t const len = MIN(len_lcs - t_i, tail->x + 1); - for (size_t h_i = 0; h_i < len; ++h_i) + bool const is_sink = tail->row + tail->length == len_ref + shift && tail->col + tail->length == len_obs + shift; + uint32_t const h_len = MIN(tail->length, tail->lcs_pos); + for (uint32_t j = 0; j <= h_len; ++j) + { + for (uint32_t k = j == 0 ? tail->prev : lcs_index[tail->lcs_pos - j]; k != GVA_NULL; k = lcs_nodes[k].prev) { - size_t const h_len = h_i == 0 && t_len - t_j <= x[len_lcs - t_i - h_i - 1] ? - t_len - t_j - 1 : - x[len_lcs - t_i - h_i - 1]; - for (size_t h_j = 0; h_j < h_len; ++h_j) + VA_LCS_Node2* const head = &lcs_nodes[k]; + if (head->lcs_pos == GVA_NULL) { - VA_LCS_Node* const head = &lcs_nodes[len_lcs - t_i - h_i - 1][h_len - h_j - 1]; - if (head->row == shift && head->col == shift) - { - found_source = true; - } // if - - fprintf(stderr, "(%u, %u, %u) vs (%u, %u, %u)\n", head->row, head->col, head->length, tail->row, tail->col, tail->length); + continue; + } // if - if (head->row + head->x + h_i <= tail->row + tail->x && - head->col + head->x + h_i <= tail->col + tail->x) - { - VA_Variant variant; - uint32_t const count = edges2(*head, *tail, head->row == shift && head->col == shift, is_sink, &variant); - if (count > 0) - { - if (head->idx == GVA_NULL) - { - va_array_append(va_std_allocator, graph.nodes, ((Node2) {head->row, head->col, head->length, GVA_NULL, GVA_NULL})); - head->idx = va_array_length(graph.nodes) - 1; - } // if - - if (variant.end + count > tail->incoming) - { - split(tail, head, count, variant, &graph); - } // if - else - { - uint32_t lambda = tail->idx; - for (uint32_t i = 0; i < count; ++i) - { - fprintf(stderr, "LAMBDA: %u\n", lambda); - fprintf(stderr, " variant: %u\n", variant.end + i); - bool is_lambda = false; - while (graph.nodes[lambda].lambda != GVA_NULL && - variant.end + i >= graph.nodes[lambda].row + graph.nodes[lambda].length) - { - lambda = graph.nodes[lambda].lambda; - is_lambda = true; - } // if - - if (i == 0 || is_lambda) - { - va_array_append(va_std_allocator, graph.edges, ((Edge2) {lambda, graph.nodes[head->idx].edges})); - graph.nodes[head->idx].edges = va_array_length(graph.edges) - 1; - } // if - - fprintf(stderr, " next: %u\n", graph.nodes[lambda].lambda); - if (graph.nodes[lambda].lambda == GVA_NULL || variant.end + count <= graph.nodes[lambda].row + graph.nodes[lambda].length) - { - break; - } // if - } // for - head->incoming = MIN(head->incoming, variant.start); - } // else - - fprintf(stderr, "(%u, %u, %u) -> (%u, %u, %u) " VAR_FMT " x %u\n", head->row, head->col, head->length, tail->row, tail->col, tail->length, print_variant(variant, observed), count); - } // if - } // if - // CONVERSE EDGE - else if (tail->row + tail->x <= head->row + head->x + h_i && - tail->col + tail->x <= head->col + head->x + h_i) + fprintf(stderr, " (%u, %u, %u)\n", head->row, head->col, head->length); + if (head->row + head->length + j <= tail->row + tail->length && + head->col + head->length + j <= tail->col + tail->length) + { + VA_Variant variant; + uint32_t const count = edges2((VA_LCS_Node) {head->row, head->col, head->length}, (VA_LCS_Node) {tail->row, tail->col, tail->length}, head->row == shift && head->col == shift, is_sink, &variant); + if (count > 0) { - VA_Variant variant; - uint32_t const count = edges2(*tail, *head, tail->row == shift && tail->col == shift, false, &variant); - if (count > 0) + fprintf(stderr, " BINGO!\n"); + if (head->idx == GVA_NULL) { - if (head->idx == GVA_NULL) - { - fprintf(stderr, "(%u, %u, %u) not in the graph yet\n", head->row, head->col, head->length); - // FIXME: why is this special? - if (h_i > 0) - { - fprintf(stderr, "Marking to stop\n"); - va_array_append(va_std_allocator, lcs_nodes[len_lcs - t_i - h_i - 1], ((VA_LCS_Node) {tail->row, tail->col, tail->length, tail->incoming, tail->idx, tail->x - h_i})); - fprintf(stderr, "Append (%u, %u, %u) at level: %zu\n", tail->row, tail->col, tail->length, len_lcs - t_i - h_i - 1); - goto hier; - } // if - } // if - // TODO: reorder cases - else if (variant.end + count > head->incoming) - { - split(head, tail, count, variant, &graph); - } // if - else - { - // FIXME: add to lambda chain? - va_array_append(va_std_allocator, graph.edges, ((Edge2) {head->idx, graph.nodes[tail->idx].edges})); - graph.nodes[tail->idx].edges = va_array_length(graph.edges) - 1; - tail->incoming = MIN(tail->incoming, variant.start); - if (source.idx == tail->idx) - { - source.incoming = tail->incoming; - } // if - } // else - - fprintf(stderr, "CONVERSE (%u, %u, %u) -> (%u, %u, %u) " VAR_FMT " x %u\n", tail->row, tail->col, tail->length, head->row, head->col, head->length, print_variant(variant, observed), count); + va_array_append(va_std_allocator, graph.nodes, ((Node2) {head->row, head->col, head->length, GVA_NULL, GVA_NULL})); + head->idx = va_array_length(graph.nodes) - 1; } // if + va_array_append(va_std_allocator, graph.edges, ((Edge2) {tail->idx, graph.nodes[head->idx].edges})); + graph.nodes[head->idx].edges = va_array_length(graph.edges); } // if - - } // for h_j - } // for h_i - if (!found_source && tail->x >= len_lcs - t_i) - { - if (source.idx == GVA_NULL) - { - va_array_append(va_std_allocator, graph.nodes, ((Node2) {source.row, source.col, source.length, GVA_NULL, GVA_NULL})); - source.idx = va_array_length(graph.nodes) - 1; } // if - va_array_append(va_std_allocator, graph.edges, ((Edge2) {tail->idx, graph.nodes[source.idx].edges})); - graph.nodes[source.idx].edges = va_array_length(graph.edges) - 1; - source.incoming = MIN(source.incoming, source.row + source.length); - - VA_Variant variant; - uint32_t const count = edges2(source, *tail, true, is_sink, &variant); - fprintf(stderr, "SOURCE (%u, %u, %u) -> (%u, %u, %u) " VAR_FMT " x %u\n", source.row, source.col, source.length, tail->row, tail->col, tail->length, print_variant(variant, observed), count); - } // if - -hier:; - - } // for t_j - lcs_nodes[len_lcs - t_i - 1] = va_array_destroy(va_std_allocator, lcs_nodes[len_lcs - t_i - 1]); - } // for t_i - lcs_nodes = va_std_allocator.alloc(va_std_allocator.context, lcs_nodes, len_lcs, 0); + } // for + } // for - x = va_array_destroy(va_std_allocator, x); + if (tail->length > tail->lcs_pos) + { + fprintf(stderr, " SOURCE\n"); + } // if + } // for - fprintf(stderr, "SOURCE first outgoing edge at %u\n", source.incoming); - graph.nodes[source.idx].row += source.incoming; - graph.nodes[source.idx].col += source.incoming; - graph.nodes[source.idx].length -= source.incoming; - graph.source = source.idx; + lcs_nodes = va_array_destroy(va_std_allocator, lcs_nodes); + va_std_allocator.alloc(va_std_allocator.context, lcs_index, len_lcs * sizeof(*lcs_index), 0); print_graph(graph, len_obs, observed); From 315b7d6bc72fce10b9d47b2be66e9bf4adc081a0 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 20 May 2025 17:14:07 +0200 Subject: [PATCH 191/704] WIP: new approach --- include/edit.h | 1 + src/edit.c | 5 -- src/edit2.c | 4 +- src/graph2.c | 152 ++++++++++++++++++++++++++++++++++--------------- 4 files changed, 109 insertions(+), 53 deletions(-) diff --git a/include/edit.h b/include/edit.h index 58fe559..98ec8a8 100644 --- a/include/edit.h +++ b/include/edit.h @@ -31,6 +31,7 @@ typedef struct uint32_t lcs_pos; uint32_t prev; uint32_t idx; + uint32_t outgoing; } VA_LCS_Node2; diff --git a/src/edit.c b/src/edit.c index a585ba3..3ace6ac 100644 --- a/src/edit.c +++ b/src/edit.c @@ -7,9 +7,6 @@ #include "../include/edit.h" // VA_LCS_Node, va_edit* -#include - - static inline size_t wu_snake(size_t const m, char const a[static restrict m], @@ -174,7 +171,6 @@ expand(Context const context, context.lcs_nodes[lcs_pos] = va_array_init(context.allocator, 256, sizeof(*context.lcs_nodes[lcs_pos])); } // if va_array_append(context.allocator, context.lcs_nodes[lcs_pos], ((VA_LCS_Node) {match_row, match_col, length, -1, -1, length})); - fprintf(stderr, "(%zu, %zu, %zu)\n", match_row, match_col, length); matching = false; } // if row += 1; @@ -208,7 +204,6 @@ expand(Context const context, context.lcs_nodes[lcs_pos] = va_array_init(context.allocator, 256, sizeof(*context.lcs_nodes[lcs_pos])); } // if va_array_append(context.allocator, context.lcs_nodes[lcs_pos], ((VA_LCS_Node) {match_row, match_col, length, -1, -1, length})); - fprintf(stderr, "(%zu, %zu, %zu)\n", match_row, match_col, length); } // if return steps; diff --git a/src/edit2.c b/src/edit2.c index 1463485..538d2f8 100644 --- a/src/edit2.c +++ b/src/edit2.c @@ -92,7 +92,7 @@ expand(Context const context, *len_lcs = lcs_pos + 1; } // if size_t const length = row - match_row; - va_array_append(context.allocator, *lcs_nodes, ((VA_LCS_Node2) {match_row, match_col, length, lcs_pos, context.lcs_index[lcs_pos], -1})); + va_array_append(context.allocator, *lcs_nodes, ((VA_LCS_Node2) {match_row, match_col, length, lcs_pos, context.lcs_index[lcs_pos], -1, -1})); context.lcs_index[lcs_pos] = va_array_length(*lcs_nodes) - 1; matching = false; } // if @@ -122,7 +122,7 @@ expand(Context const context, *len_lcs = lcs_pos + 1; } // if size_t const length = row - match_row; - va_array_append(context.allocator, *lcs_nodes, ((VA_LCS_Node2) {match_row, match_col, length, lcs_pos, context.lcs_index[lcs_pos], -1})); + va_array_append(context.allocator, *lcs_nodes, ((VA_LCS_Node2) {match_row, match_col, length, lcs_pos, context.lcs_index[lcs_pos], -1, -1})); context.lcs_index[lcs_pos] = va_array_length(*lcs_nodes) - 1; } // if diff --git a/src/graph2.c b/src/graph2.c index 9eb7198..713d6a2 100644 --- a/src/graph2.c +++ b/src/graph2.c @@ -186,12 +186,12 @@ print_graph(Graph2 const graph, size_t const len_obs, char const observed[static static void -split(VA_LCS_Node* const node, VA_LCS_Node* const head, uint32_t const in_count, VA_Variant const incoming, Graph2* const graph) +split(VA_LCS_Node2* const node, VA_LCS_Node2* const head, uint32_t const in_count, VA_Variant const incoming, Graph2* const graph) { - fprintf(stderr, "\n***SPLIT (%u, %u, %u) because of first outgoing edge at %u\n", node->row, node->col, node->length, node->incoming); + fprintf(stderr, "\n***SPLIT (%u, %u, %u) because of first outgoing edge at %u\n", node->row, node->col, node->length, node->outgoing); uint32_t pos = 0; - for (uint32_t i = 0; i < incoming.end + in_count - node->incoming; ++i) + for (uint32_t i = 0; i < incoming.end + in_count - node->outgoing; ++i) { pos = incoming.end + in_count - i - 1; @@ -203,7 +203,9 @@ split(VA_LCS_Node* const node, VA_LCS_Node* const head, uint32_t const in_count, { Node2 const* const tail = &graph->nodes[graph->edges[j].tail]; VA_Variant outgoing; - uint32_t const out_count = edges2(*node, (VA_LCS_Node) {tail->row, tail->col, tail->length, -1, GVA_NULL, 0}, false, tail->edges == GVA_NULL && tail->lambda == GVA_NULL, &outgoing); + uint32_t const out_count = edges2( + (VA_LCS_Node) {node->row, node->col, node->length, -1, GVA_NULL, 0}, + (VA_LCS_Node) {tail->row, tail->col, tail->length, -1, GVA_NULL, 0}, false, tail->edges == GVA_NULL && tail->lambda == GVA_NULL, &outgoing); fprintf(stderr, " %u: (%u, %u, %u): x %u ", graph->edges[j].tail, tail->row, tail->col, tail->length, out_count); // TODO: can we avoid reordering the tail list? @@ -260,17 +262,16 @@ split(VA_LCS_Node* const node, VA_LCS_Node* const head, uint32_t const in_count, { graph->edges[tail_tail].next = GVA_NULL; } // if - graph->nodes[node->idx].edges = tail_head; + graph->nodes[node->idx].edges = head_head; + uint32_t const length = pos - node->row; - graph->nodes[node->idx].row += (pos - node->row); - graph->nodes[node->idx].col += (pos - node->row); - graph->nodes[node->idx].length -= (pos - node->row); + va_array_append(va_std_allocator, graph->nodes, ((Node2) {node->row + length, node->col + length, graph->nodes[node->idx].length - length, tail_head, graph->nodes[node->idx].lambda})); + graph->nodes[node->idx].lambda = va_array_length(graph->nodes) - 1; - va_array_append(va_std_allocator, graph->edges, ((Edge2) {node->idx, graph->nodes[head->idx].edges})); - graph->nodes[head->idx].edges = va_array_length(graph->edges) - 1; + graph->nodes[node->idx].length = length; - va_array_append(va_std_allocator, graph->nodes, ((Node2) {node->row, node->col, pos - node->row, head_head, node->idx})); - node->idx = va_array_length(graph->nodes) - 1; + va_array_append(va_std_allocator, graph->edges, ((Edge2) {graph->nodes[node->idx].lambda, graph->nodes[head->idx].edges})); + graph->nodes[head->idx].edges = va_array_length(graph->edges) - 1; Node2 const* const lambda = &graph->nodes[graph->nodes[node->idx].lambda]; fprintf(stderr, "(%u, %u, %u) l> (%u, %u, %u) @ %u\n", graph->nodes[node->idx].row, graph->nodes[node->idx].col, graph->nodes[node->idx].length, @@ -282,14 +283,40 @@ split(VA_LCS_Node* const node, VA_LCS_Node* const head, uint32_t const in_count, va_array_append(va_std_allocator, graph->edges, ((Edge2) {node->idx, graph->nodes[head->idx].edges})); graph->nodes[head->idx].edges = va_array_length(graph->edges) - 1; } // if - node->incoming = -1; // FIXME: real value? - head->incoming = incoming.start; + node->outgoing = -1; // FIXME: real value? + head->outgoing = incoming.start; fprintf(stderr, "***\n\n"); } // split -// FIXME: incoming means the first *outgoing* edge +static uint32_t +edges3(VA_LCS_Node2 const* const head, VA_LCS_Node2 const* const tail, bool const is_source, bool const is_sink, VA_Variant* const variant) +{ + uint32_t const h_min = head->lcs_pos - (head->length - 1); + uint32_t const t_min = tail->lcs_pos - (tail->length - 1); + + uint32_t const start = MAX(h_min + 1 - is_source, t_min); + uint32_t const end = MIN(head->lcs_pos + 1, tail->lcs_pos + is_sink); + + if (start > end) + { + return 0; + } // if + + uint32_t const h_offset = (head->length - 1) - (head->lcs_pos - start); + uint32_t const t_offset = (tail->length - 1) - (tail->lcs_pos - start); + + if (head->row + h_offset > tail->row + t_offset || head->col + h_offset > tail->col + t_offset) + { + return 0; + } // if + + *variant = (VA_Variant) {head->row + h_offset, tail->row + t_offset, head->col + h_offset, tail->col + t_offset}; + return end - start + 1; +} // edges3 + + Graph2 build(size_t const len_ref, char const reference[static len_ref], size_t const len_obs, char const observed[static len_obs], @@ -327,11 +354,12 @@ build(size_t const len_ref, char const reference[static len_ref], fprintf(stderr, "%zu: %d\n", i, lcs_index[i]); } // for + VA_LCS_Node2 source = {shift, shift, 0, 0, GVA_NULL, GVA_NULL, -1}; + bool found_source = false; VA_LCS_Node2* const last = &lcs_nodes[lcs_index[len_lcs - 1]]; if (last->row + last->length != len_ref + shift || last->col + last->length != len_obs + shift) { - fprintf(stderr, "Nieuwe sink\n"); - VA_LCS_Node2 const sink = {len_ref, len_obs, 0, len_lcs, GVA_NULL, GVA_NULL}; + VA_LCS_Node2 const sink = {len_ref, len_obs, 0, len_lcs, GVA_NULL, GVA_NULL, -1}; va_array_append(va_std_allocator, graph.nodes, ((Node2) {sink.row, sink.col, sink.length, GVA_NULL, GVA_NULL})); uint32_t const sink_idx = va_array_length(graph.nodes) - 1; for (uint32_t idx = lcs_index[len_lcs - 1]; idx != GVA_NULL; idx = lcs_nodes[idx].prev) @@ -344,63 +372,95 @@ build(size_t const len_ref, char const reference[static len_ref], } // if else { - fprintf(stderr, "Oude sink\n"); va_array_append(va_std_allocator, graph.nodes, ((Node2) {last->row, last->col, last->length, GVA_NULL, GVA_NULL})); last->idx = va_array_length(graph.nodes) - 1; + if (last->row == shift && last->col == shift) + { + found_source = true; + source.idx = last->idx; + } // if } // else size_t const t_len = va_array_length(lcs_nodes); for (size_t i = 0; i < t_len; ++i) { VA_LCS_Node2* const tail = &lcs_nodes[t_len - i - 1]; - fprintf(stderr, "(%u, %u, %u) @ %u\n", tail->row, tail->col, tail->length, tail->lcs_pos); if (tail->idx == GVA_NULL) { - fprintf(stderr, " Not in graph\n"); - tail->lcs_pos = GVA_NULL; continue; } // if bool const is_sink = tail->row + tail->length == len_ref + shift && tail->col + tail->length == len_obs + shift; - uint32_t const h_len = MIN(tail->length, tail->lcs_pos); - for (uint32_t j = 0; j <= h_len; ++j) + for (size_t j = i + 1; j < t_len; ++j) { - for (uint32_t k = j == 0 ? tail->prev : lcs_index[tail->lcs_pos - j]; k != GVA_NULL; k = lcs_nodes[k].prev) + VA_LCS_Node2* const head = &lcs_nodes[t_len - j - 1]; + //fprintf(stderr, "(%u, %u, %u) @ %u vs (%u, %u, %u) @ %u\n", head->row, head->col, head->length, head->lcs_pos, tail->row, tail->col, tail->length, tail->lcs_pos); + + bool const is_source = head->row == shift && head->col == shift; + VA_Variant variant; + uint32_t const count = edges3(head, tail, is_source, is_sink, &variant); + if (count > 0) { - VA_LCS_Node2* const head = &lcs_nodes[k]; - if (head->lcs_pos == GVA_NULL) + if (head->idx == GVA_NULL) { - continue; + va_array_append(va_std_allocator, graph.nodes, ((Node2) {head->row, head->col, head->length, GVA_NULL, GVA_NULL})); + head->idx = va_array_length(graph.nodes) - 1; + if (is_source) + { + graph.source = head->idx; + } // if } // if - fprintf(stderr, " (%u, %u, %u)\n", head->row, head->col, head->length); - if (head->row + head->length + j <= tail->row + tail->length && - head->col + head->length + j <= tail->col + tail->length) + if (variant.end + count > tail->outgoing) + { + split(tail, head, count, variant, &graph); + } // if + else { - VA_Variant variant; - uint32_t const count = edges2((VA_LCS_Node) {head->row, head->col, head->length}, (VA_LCS_Node) {tail->row, tail->col, tail->length}, head->row == shift && head->col == shift, is_sink, &variant); - if (count > 0) + uint32_t lambda = tail->idx; + for (uint32_t i = 0; i < count; ++i) { - fprintf(stderr, " BINGO!\n"); - if (head->idx == GVA_NULL) + fprintf(stderr, "LAMBDA: %u\n", lambda); + fprintf(stderr, " variant: %u\n", variant.end + i); + bool is_lambda = false; + while (graph.nodes[lambda].lambda != GVA_NULL && + variant.end + i >= graph.nodes[lambda].row + graph.nodes[lambda].length) { - va_array_append(va_std_allocator, graph.nodes, ((Node2) {head->row, head->col, head->length, GVA_NULL, GVA_NULL})); - head->idx = va_array_length(graph.nodes) - 1; + lambda = graph.nodes[lambda].lambda; + is_lambda = true; } // if - va_array_append(va_std_allocator, graph.edges, ((Edge2) {tail->idx, graph.nodes[head->idx].edges})); - graph.nodes[head->idx].edges = va_array_length(graph.edges); - } // if - } // if - } // for - } // for - if (tail->length > tail->lcs_pos) + if (i == 0 || is_lambda) + { + va_array_append(va_std_allocator, graph.edges, ((Edge2) {lambda, graph.nodes[head->idx].edges})); + graph.nodes[head->idx].edges = va_array_length(graph.edges) - 1; + } // if + + fprintf(stderr, " next: %u\n", graph.nodes[lambda].lambda); + if (graph.nodes[lambda].lambda == GVA_NULL || variant.end + count <= graph.nodes[lambda].row + graph.nodes[lambda].length) + { + break; + } // if + } // for + head->outgoing = MIN(head->outgoing, variant.start); + } // else + + fprintf(stderr, "(%u, %u, %u) -> (%u, %u, %u) " VAR_FMT " x %u\n", head->row, head->col, head->length, tail->row, tail->col, tail->length, print_variant(variant, observed), count); + } // if + } // for + if (!found_source && tail->length > tail->lcs_pos) { - fprintf(stderr, " SOURCE\n"); + if (source.idx == GVA_NULL) + { + va_array_append(va_std_allocator, graph.nodes, ((Node2) {source.row, source.col, source.length, GVA_NULL, GVA_NULL})); + source.idx = va_array_length(graph.nodes) - 1; + graph.source = source.idx; + } // if + va_array_append(va_std_allocator, graph.edges, ((Edge2) {tail->idx, graph.nodes[source.idx].edges})); + graph.nodes[source.idx].edges = va_array_length(graph.edges) - 1; } // if } // for - lcs_nodes = va_array_destroy(va_std_allocator, lcs_nodes); va_std_allocator.alloc(va_std_allocator.context, lcs_index, len_lcs * sizeof(*lcs_index), 0); From a2a9c18242bc56b8920f0f6119c36754c1dfe375 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 20 May 2025 18:46:48 +0200 Subject: [PATCH 192/704] Fix: found source --- src/graph2.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/graph2.c b/src/graph2.c index 713d6a2..ff71da0 100644 --- a/src/graph2.c +++ b/src/graph2.c @@ -407,6 +407,7 @@ build(size_t const len_ref, char const reference[static len_ref], head->idx = va_array_length(graph.nodes) - 1; if (is_source) { + found_source = true; graph.source = head->idx; } // if } // if @@ -436,7 +437,7 @@ build(size_t const len_ref, char const reference[static len_ref], graph.nodes[head->idx].edges = va_array_length(graph.edges) - 1; } // if - fprintf(stderr, " next: %u\n", graph.nodes[lambda].lambda); + fprintf(stderr, " next: %d\n", graph.nodes[lambda].lambda); if (graph.nodes[lambda].lambda == GVA_NULL || variant.end + count <= graph.nodes[lambda].row + graph.nodes[lambda].length) { break; From d62082a744400a4b647370ac965480bd46a3c339 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 20 May 2025 19:40:25 +0200 Subject: [PATCH 193/704] Clean up --- src/graph2.c | 123 ++++++++++++++++++++++++++------------------------- 1 file changed, 63 insertions(+), 60 deletions(-) diff --git a/src/graph2.c b/src/graph2.c index ff71da0..a44ec0c 100644 --- a/src/graph2.c +++ b/src/graph2.c @@ -185,8 +185,10 @@ print_graph(Graph2 const graph, size_t const len_obs, char const observed[static } // print_graph -static void -split(VA_LCS_Node2* const node, VA_LCS_Node2* const head, uint32_t const in_count, VA_Variant const incoming, Graph2* const graph) +static inline void +split(VA_LCS_Node2 const* const node, VA_LCS_Node2 const* const head, + uint32_t const in_count, VA_Variant const incoming, + Graph2* const graph) { fprintf(stderr, "\n***SPLIT (%u, %u, %u) because of first outgoing edge at %u\n", node->row, node->col, node->length, node->outgoing); @@ -283,15 +285,47 @@ split(VA_LCS_Node2* const node, VA_LCS_Node2* const head, uint32_t const in_coun va_array_append(va_std_allocator, graph->edges, ((Edge2) {node->idx, graph->nodes[head->idx].edges})); graph->nodes[head->idx].edges = va_array_length(graph->edges) - 1; } // if - node->outgoing = -1; // FIXME: real value? - head->outgoing = incoming.start; - fprintf(stderr, "***\n\n"); } // split -static uint32_t -edges3(VA_LCS_Node2 const* const head, VA_LCS_Node2 const* const tail, bool const is_source, bool const is_sink, VA_Variant* const variant) +static inline void +distribute(VA_LCS_Node2 const* const tail, VA_LCS_Node2 const* const head, + uint32_t const count, VA_Variant const variant, + Graph2* const graph) +{ + uint32_t lambda = tail->idx; + for (uint32_t i = 0; i < count; ++i) + { + fprintf(stderr, "LAMBDA: %u\n", lambda); + fprintf(stderr, " variant: %u\n", variant.end + i); + bool is_lambda = false; + while (graph->nodes[lambda].lambda != GVA_NULL && + variant.end + i >= graph->nodes[lambda].row + graph->nodes[lambda].length) + { + lambda = graph->nodes[lambda].lambda; + is_lambda = true; + } // while + + if (is_lambda || i == 0) + { + va_array_append(va_std_allocator, graph->edges, ((Edge2) {lambda, graph->nodes[head->idx].edges})); + graph->nodes[head->idx].edges = va_array_length(graph->edges) - 1; + } // if + + fprintf(stderr, " next: %d\n", graph->nodes[lambda].lambda); + if (graph->nodes[lambda].lambda == GVA_NULL || variant.end + count <= graph->nodes[lambda].row + graph->nodes[lambda].length) + { + break; + } // if + } // for +} // distribute + + +static inline uint32_t +edges3(VA_LCS_Node2 const* const head, VA_LCS_Node2 const* const tail, + bool const is_source, bool const is_sink, + VA_Variant* const variant) { uint32_t const h_min = head->lcs_pos - (head->length - 1); uint32_t const t_min = tail->lcs_pos - (tail->length - 1); @@ -344,20 +378,20 @@ build(size_t const len_ref, char const reference[static len_ref], return graph; } // if - for (size_t i = 0; i < va_array_length(lcs_nodes); ++i) - { - fprintf(stderr, "%zu: (%u, %u, %u), %d\n", i, lcs_nodes[i].row, lcs_nodes[i].col, lcs_nodes[i].length, lcs_nodes[i].prev); - } // for - - for (size_t i = 0; i < len_lcs; ++i) - { - fprintf(stderr, "%zu: %d\n", i, lcs_index[i]); - } // for - VA_LCS_Node2 source = {shift, shift, 0, 0, GVA_NULL, GVA_NULL, -1}; bool found_source = false; VA_LCS_Node2* const last = &lcs_nodes[lcs_index[len_lcs - 1]]; - if (last->row + last->length != len_ref + shift || last->col + last->length != len_obs + shift) + if (last->row + last->length == len_ref + shift && last->col + last->length == len_obs + shift) + { + va_array_append(va_std_allocator, graph.nodes, ((Node2) {last->row, last->col, last->length, GVA_NULL, GVA_NULL})); + last->idx = va_array_length(graph.nodes) - 1; + if (last->row == shift && last->col == shift) + { + found_source = true; + source.idx = last->idx; + } // if + } // if + else { VA_LCS_Node2 const sink = {len_ref, len_obs, 0, len_lcs, GVA_NULL, GVA_NULL, -1}; va_array_append(va_std_allocator, graph.nodes, ((Node2) {sink.row, sink.col, sink.length, GVA_NULL, GVA_NULL})); @@ -368,17 +402,8 @@ build(size_t const len_ref, char const reference[static len_ref], va_array_append(va_std_allocator, graph.edges, ((Edge2) {sink_idx, GVA_NULL})); va_array_append(va_std_allocator, graph.nodes, ((Node2) {head->row, head->col, head->length, va_array_length(graph.edges) - 1, GVA_NULL})); head->idx = va_array_length(graph.nodes) - 1; + fprintf(stderr, "SINK edge from %u\n", head->idx); } // for - } // if - else - { - va_array_append(va_std_allocator, graph.nodes, ((Node2) {last->row, last->col, last->length, GVA_NULL, GVA_NULL})); - last->idx = va_array_length(graph.nodes) - 1; - if (last->row == shift && last->col == shift) - { - found_source = true; - source.idx = last->idx; - } // if } // else size_t const t_len = va_array_length(lcs_nodes); @@ -394,9 +419,8 @@ build(size_t const len_ref, char const reference[static len_ref], for (size_t j = i + 1; j < t_len; ++j) { VA_LCS_Node2* const head = &lcs_nodes[t_len - j - 1]; - //fprintf(stderr, "(%u, %u, %u) @ %u vs (%u, %u, %u) @ %u\n", head->row, head->col, head->length, head->lcs_pos, tail->row, tail->col, tail->length, tail->lcs_pos); - bool const is_source = head->row == shift && head->col == shift; + VA_Variant variant; uint32_t const count = edges3(head, tail, is_source, is_sink, &variant); if (count > 0) @@ -412,41 +436,19 @@ build(size_t const len_ref, char const reference[static len_ref], } // if } // if - if (variant.end + count > tail->outgoing) + fprintf(stderr, "(%u, %u, %u) -> (%u, %u, %u) " VAR_FMT " x %u\n", head->row, head->col, head->length, tail->row, tail->col, tail->length, print_variant(variant, observed), count); + + if (variant.end + count <= tail->outgoing) { - split(tail, head, count, variant, &graph); + distribute(tail, head, count, variant, &graph); + head->outgoing = MIN(head->outgoing, variant.start); } // if else { - uint32_t lambda = tail->idx; - for (uint32_t i = 0; i < count; ++i) - { - fprintf(stderr, "LAMBDA: %u\n", lambda); - fprintf(stderr, " variant: %u\n", variant.end + i); - bool is_lambda = false; - while (graph.nodes[lambda].lambda != GVA_NULL && - variant.end + i >= graph.nodes[lambda].row + graph.nodes[lambda].length) - { - lambda = graph.nodes[lambda].lambda; - is_lambda = true; - } // if - - if (i == 0 || is_lambda) - { - va_array_append(va_std_allocator, graph.edges, ((Edge2) {lambda, graph.nodes[head->idx].edges})); - graph.nodes[head->idx].edges = va_array_length(graph.edges) - 1; - } // if - - fprintf(stderr, " next: %d\n", graph.nodes[lambda].lambda); - if (graph.nodes[lambda].lambda == GVA_NULL || variant.end + count <= graph.nodes[lambda].row + graph.nodes[lambda].length) - { - break; - } // if - } // for - head->outgoing = MIN(head->outgoing, variant.start); + split(tail, head, count, variant, &graph); + tail->outgoing = -1; // FIXME: real value? + head->outgoing = variant.start; } // else - - fprintf(stderr, "(%u, %u, %u) -> (%u, %u, %u) " VAR_FMT " x %u\n", head->row, head->col, head->length, tail->row, tail->col, tail->length, print_variant(variant, observed), count); } // if } // for if (!found_source && tail->length > tail->lcs_pos) @@ -459,6 +461,7 @@ build(size_t const len_ref, char const reference[static len_ref], } // if va_array_append(va_std_allocator, graph.edges, ((Edge2) {tail->idx, graph.nodes[source.idx].edges})); graph.nodes[source.idx].edges = va_array_length(graph.edges) - 1; + fprintf(stderr, "SOURCE edge to %u\n", tail->idx); } // if } // for From 6d71af05b4a0e6d53d0f71ca833963a601bc55e9 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Wed, 21 May 2025 08:12:01 +0200 Subject: [PATCH 194/704] Transplant regression tests. --- regres.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/regres.sh b/regres.sh index d365402..1814c09 100755 --- a/regres.sh +++ b/regres.sh @@ -25,6 +25,8 @@ CTATATAAAC CTCGTAA TTAATTAGTT GACGTTAATT TAAG TAAGACCGC GGCGA GGTTTTA +GGCTGC GCTCCAA +CTGGGGAG CCACCTGGGC ) for ((i=0; i<${#TESTS[@]}; i+=2)); do From a61b9d17e841ec5cac19e5c496cc483ae77372c7 Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 21 May 2025 15:58:20 +0200 Subject: [PATCH 195/704] WIP: splitting --- src/graph2.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/graph2.c b/src/graph2.c index a44ec0c..d807e85 100644 --- a/src/graph2.c +++ b/src/graph2.c @@ -192,6 +192,8 @@ split(VA_LCS_Node2 const* const node, VA_LCS_Node2 const* const head, { fprintf(stderr, "\n***SPLIT (%u, %u, %u) because of first outgoing edge at %u\n", node->row, node->col, node->length, node->outgoing); + fprintf(stderr, "%u\n", incoming.end + in_count - node->outgoing); + uint32_t pos = 0; for (uint32_t i = 0; i < incoming.end + in_count - node->outgoing; ++i) { @@ -393,7 +395,7 @@ build(size_t const len_ref, char const reference[static len_ref], } // if else { - VA_LCS_Node2 const sink = {len_ref, len_obs, 0, len_lcs, GVA_NULL, GVA_NULL, -1}; + VA_LCS_Node2 const sink = {len_ref, len_obs, 0, len_lcs - 1, GVA_NULL, GVA_NULL, -1}; va_array_append(va_std_allocator, graph.nodes, ((Node2) {sink.row, sink.col, sink.length, GVA_NULL, GVA_NULL})); uint32_t const sink_idx = va_array_length(graph.nodes) - 1; for (uint32_t idx = lcs_index[len_lcs - 1]; idx != GVA_NULL; idx = lcs_nodes[idx].prev) @@ -402,7 +404,10 @@ build(size_t const len_ref, char const reference[static len_ref], va_array_append(va_std_allocator, graph.edges, ((Edge2) {sink_idx, GVA_NULL})); va_array_append(va_std_allocator, graph.nodes, ((Node2) {head->row, head->col, head->length, va_array_length(graph.edges) - 1, GVA_NULL})); head->idx = va_array_length(graph.nodes) - 1; - fprintf(stderr, "SINK edge from %u\n", head->idx); + + VA_Variant variant; + uint32_t const count = edges3(head, &sink, head->row == shift && head->col == shift, true, &variant); + fprintf(stderr, "(%u, %u, %u) -> (%u, %u, %u) " VAR_FMT " x %u\n", head->row, head->col, head->length, sink.row, sink.col, sink.length, print_variant(variant, observed), count); } // for } // else @@ -461,7 +466,10 @@ build(size_t const len_ref, char const reference[static len_ref], } // if va_array_append(va_std_allocator, graph.edges, ((Edge2) {tail->idx, graph.nodes[source.idx].edges})); graph.nodes[source.idx].edges = va_array_length(graph.edges) - 1; - fprintf(stderr, "SOURCE edge to %u\n", tail->idx); + + VA_Variant variant; + uint32_t const count = edges3(&source, tail, true, is_sink, &variant); + fprintf(stderr, "(%u, %u, %u) -> (%u, %u, %u) " VAR_FMT " x %u\n", source.row, source.col, source.length, tail->row, tail->col, tail->length, print_variant(variant, observed), count); } // if } // for From 36d0ee999661a6722c1b60e6e5845005ea03c35a Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Wed, 21 May 2025 16:55:12 +0200 Subject: [PATCH 196/704] Determine split points. --- src/graph2.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/graph2.c b/src/graph2.c index d807e85..764c9b3 100644 --- a/src/graph2.c +++ b/src/graph2.c @@ -194,11 +194,10 @@ split(VA_LCS_Node2 const* const node, VA_LCS_Node2 const* const head, fprintf(stderr, "%u\n", incoming.end + in_count - node->outgoing); + fprintf(stderr, "fsp: %u lsp: %u\n", incoming.end + in_count - 1, MAX(incoming.end, node->outgoing)); uint32_t pos = 0; - for (uint32_t i = 0; i < incoming.end + in_count - node->outgoing; ++i) + for (pos = incoming.end + in_count - 1; pos >= MAX(incoming.end, node->outgoing); --pos) { - pos = incoming.end + in_count - i - 1; - uint32_t head_head = GVA_NULL; uint32_t head_tail = GVA_NULL; uint32_t tail_head = GVA_NULL; @@ -282,7 +281,7 @@ split(VA_LCS_Node2 const* const node, VA_LCS_Node2 const* const head, lambda->row, lambda->col, lambda->length, pos); } // for - if (incoming.end < pos) + if (incoming.end <= pos) { va_array_append(va_std_allocator, graph->edges, ((Edge2) {node->idx, graph->nodes[head->idx].edges})); graph->nodes[head->idx].edges = va_array_length(graph->edges) - 1; @@ -419,6 +418,7 @@ build(size_t const len_ref, char const reference[static len_ref], { continue; } // if + uint32_t split_point = -1; bool const is_sink = tail->row + tail->length == len_ref + shift && tail->col + tail->length == len_obs + shift; for (size_t j = i + 1; j < t_len; ++j) @@ -443,17 +443,16 @@ build(size_t const len_ref, char const reference[static len_ref], fprintf(stderr, "(%u, %u, %u) -> (%u, %u, %u) " VAR_FMT " x %u\n", head->row, head->col, head->length, tail->row, tail->col, tail->length, print_variant(variant, observed), count); - if (variant.end + count <= tail->outgoing) + if (variant.end + count <= tail->outgoing || split_point == tail->outgoing) { distribute(tail, head, count, variant, &graph); - head->outgoing = MIN(head->outgoing, variant.start); } // if else { split(tail, head, count, variant, &graph); - tail->outgoing = -1; // FIXME: real value? - head->outgoing = variant.start; + split_point = MAX(variant.end, tail->outgoing); } // else + head->outgoing = MIN(head->outgoing, variant.start); } // if } // for if (!found_source && tail->length > tail->lcs_pos) From 92ca899d7f18bfcc00f800deb35e1bd5d626c135 Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 21 May 2025 22:20:20 +0200 Subject: [PATCH 197/704] Split split --- src/graph2.c | 31 ++++++++++--------------------- 1 file changed, 10 insertions(+), 21 deletions(-) diff --git a/src/graph2.c b/src/graph2.c index 764c9b3..3c6330f 100644 --- a/src/graph2.c +++ b/src/graph2.c @@ -186,14 +186,12 @@ print_graph(Graph2 const graph, size_t const len_obs, char const observed[static static inline void -split(VA_LCS_Node2 const* const node, VA_LCS_Node2 const* const head, +split(VA_LCS_Node2 const* const node, uint32_t const in_count, VA_Variant const incoming, Graph2* const graph) { fprintf(stderr, "\n***SPLIT (%u, %u, %u) because of first outgoing edge at %u\n", node->row, node->col, node->length, node->outgoing); - fprintf(stderr, "%u\n", incoming.end + in_count - node->outgoing); - fprintf(stderr, "fsp: %u lsp: %u\n", incoming.end + in_count - 1, MAX(incoming.end, node->outgoing)); uint32_t pos = 0; for (pos = incoming.end + in_count - 1; pos >= MAX(incoming.end, node->outgoing); --pos) @@ -270,22 +268,14 @@ split(VA_LCS_Node2 const* const node, VA_LCS_Node2 const* const head, va_array_append(va_std_allocator, graph->nodes, ((Node2) {node->row + length, node->col + length, graph->nodes[node->idx].length - length, tail_head, graph->nodes[node->idx].lambda})); graph->nodes[node->idx].lambda = va_array_length(graph->nodes) - 1; - graph->nodes[node->idx].length = length; - va_array_append(va_std_allocator, graph->edges, ((Edge2) {graph->nodes[node->idx].lambda, graph->nodes[head->idx].edges})); - graph->nodes[head->idx].edges = va_array_length(graph->edges) - 1; - Node2 const* const lambda = &graph->nodes[graph->nodes[node->idx].lambda]; - fprintf(stderr, "(%u, %u, %u) l> (%u, %u, %u) @ %u\n", graph->nodes[node->idx].row, graph->nodes[node->idx].col, graph->nodes[node->idx].length, - lambda->row, lambda->col, lambda->length, pos); + fprintf(stderr, "(%u, %u, %u) l> (%u, %u, %u) @ %u\n", + graph->nodes[node->idx].row, graph->nodes[node->idx].col, graph->nodes[node->idx].length, + lambda->row, lambda->col, lambda->length, pos); } // for - if (incoming.end <= pos) - { - va_array_append(va_std_allocator, graph->edges, ((Edge2) {node->idx, graph->nodes[head->idx].edges})); - graph->nodes[head->idx].edges = va_array_length(graph->edges) - 1; - } // if fprintf(stderr, "***\n\n"); } // split @@ -379,7 +369,7 @@ build(size_t const len_ref, char const reference[static len_ref], return graph; } // if - VA_LCS_Node2 source = {shift, shift, 0, 0, GVA_NULL, GVA_NULL, -1}; + VA_LCS_Node2 source = {shift, shift, 0, -1, GVA_NULL, GVA_NULL, -1}; bool found_source = false; VA_LCS_Node2* const last = &lcs_nodes[lcs_index[len_lcs - 1]]; if (last->row + last->length == len_ref + shift && last->col + last->length == len_obs + shift) @@ -443,15 +433,14 @@ build(size_t const len_ref, char const reference[static len_ref], fprintf(stderr, "(%u, %u, %u) -> (%u, %u, %u) " VAR_FMT " x %u\n", head->row, head->col, head->length, tail->row, tail->col, tail->length, print_variant(variant, observed), count); - if (variant.end + count <= tail->outgoing || split_point == tail->outgoing) - { - distribute(tail, head, count, variant, &graph); - } // if - else + if (variant.end + count > tail->outgoing && split_point != tail->outgoing) { - split(tail, head, count, variant, &graph); + fprintf(stderr, "split_point: %u\n", split_point); + split(tail, count, variant, &graph); split_point = MAX(variant.end, tail->outgoing); + fprintf(stderr, "split_point: %u\n", split_point); } // else + distribute(tail, head, count, variant, &graph); head->outgoing = MIN(head->outgoing, variant.start); } // if } // for From d51e00f1d1e854c52de51a2aeb583d3e87741c41 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 22 May 2025 10:34:21 +0200 Subject: [PATCH 198/704] WIP: snapshot --- regres.sh | 1 + src/graph2.c | 46 +++++++++++++++++++++++++++++++++++----------- 2 files changed, 36 insertions(+), 11 deletions(-) diff --git a/regres.sh b/regres.sh index 1814c09..86b7d4f 100755 --- a/regres.sh +++ b/regres.sh @@ -27,6 +27,7 @@ TAAG TAAGACCGC GGCGA GGTTTTA GGCTGC GCTCCAA CTGGGGAG CCACCTGGGC +CATTTCACGA TCGCCC ) for ((i=0; i<${#TESTS[@]}; i+=2)); do diff --git a/src/graph2.c b/src/graph2.c index 3c6330f..1e35ac9 100644 --- a/src/graph2.c +++ b/src/graph2.c @@ -188,18 +188,20 @@ print_graph(Graph2 const graph, size_t const len_obs, char const observed[static static inline void split(VA_LCS_Node2 const* const node, uint32_t const in_count, VA_Variant const incoming, + uint32_t const split_point, Graph2* const graph) { fprintf(stderr, "\n***SPLIT (%u, %u, %u) because of first outgoing edge at %u\n", node->row, node->col, node->length, node->outgoing); fprintf(stderr, "fsp: %u lsp: %u\n", incoming.end + in_count - 1, MAX(incoming.end, node->outgoing)); uint32_t pos = 0; - for (pos = incoming.end + in_count - 1; pos >= MAX(incoming.end, node->outgoing); --pos) + for (pos = MIN(split_point - 1, incoming.end + in_count - 1); pos >= MAX(incoming.end, node->outgoing); --pos) { uint32_t head_head = GVA_NULL; uint32_t head_tail = GVA_NULL; uint32_t tail_head = GVA_NULL; uint32_t tail_tail = GVA_NULL; + // FIXME: only once after creating all the nodes for (uint32_t j = graph->nodes[node->idx].edges; j != GVA_NULL; j = graph->edges[j].next) { Node2 const* const tail = &graph->nodes[graph->edges[j].tail]; @@ -209,7 +211,7 @@ split(VA_LCS_Node2 const* const node, (VA_LCS_Node) {tail->row, tail->col, tail->length, -1, GVA_NULL, 0}, false, tail->edges == GVA_NULL && tail->lambda == GVA_NULL, &outgoing); fprintf(stderr, " %u: (%u, %u, %u): x %u ", graph->edges[j].tail, tail->row, tail->col, tail->length, out_count); - // TODO: can we avoid reordering the tail list? + // TODO: can we avoid reordering the tail list? Yes? XOR-linked? if (outgoing.start > pos) { if (tail_tail != GVA_NULL) @@ -393,6 +395,13 @@ build(size_t const len_ref, char const reference[static len_ref], va_array_append(va_std_allocator, graph.edges, ((Edge2) {sink_idx, GVA_NULL})); va_array_append(va_std_allocator, graph.nodes, ((Node2) {head->row, head->col, head->length, va_array_length(graph.edges) - 1, GVA_NULL})); head->idx = va_array_length(graph.nodes) - 1; + head->outgoing = head->row + head->length; + if (head->row == shift && head->col == shift) + { + found_source = true; + source.idx = head->idx; + source.outgoing = head->outgoing; + } // if VA_Variant variant; uint32_t const count = edges3(head, &sink, head->row == shift && head->col == shift, true, &variant); @@ -424,33 +433,34 @@ build(size_t const len_ref, char const reference[static len_ref], { va_array_append(va_std_allocator, graph.nodes, ((Node2) {head->row, head->col, head->length, GVA_NULL, GVA_NULL})); head->idx = va_array_length(graph.nodes) - 1; - if (is_source) - { - found_source = true; - graph.source = head->idx; - } // if } // if fprintf(stderr, "(%u, %u, %u) -> (%u, %u, %u) " VAR_FMT " x %u\n", head->row, head->col, head->length, tail->row, tail->col, tail->length, print_variant(variant, observed), count); if (variant.end + count > tail->outgoing && split_point != tail->outgoing) { - fprintf(stderr, "split_point: %u\n", split_point); - split(tail, count, variant, &graph); + split(tail, count, variant, split_point, &graph); split_point = MAX(variant.end, tail->outgoing); - fprintf(stderr, "split_point: %u\n", split_point); } // else distribute(tail, head, count, variant, &graph); + head->outgoing = MIN(head->outgoing, variant.start); + if (is_source) + { + found_source = true; + source.idx = head->idx; + source.outgoing = head->outgoing; + } // if } // if } // for + if (!found_source && tail->length > tail->lcs_pos) { if (source.idx == GVA_NULL) { va_array_append(va_std_allocator, graph.nodes, ((Node2) {source.row, source.col, source.length, GVA_NULL, GVA_NULL})); source.idx = va_array_length(graph.nodes) - 1; - graph.source = source.idx; + source.outgoing = 0; } // if va_array_append(va_std_allocator, graph.edges, ((Edge2) {tail->idx, graph.nodes[source.idx].edges})); graph.nodes[source.idx].edges = va_array_length(graph.edges) - 1; @@ -464,6 +474,20 @@ build(size_t const len_ref, char const reference[static len_ref], lcs_nodes = va_array_destroy(va_std_allocator, lcs_nodes); va_std_allocator.alloc(va_std_allocator.context, lcs_index, len_lcs * sizeof(*lcs_index), 0); + fprintf(stderr, "SOURCE first outgoing edge at %d\n", source.outgoing); + if (source.outgoing != (uint32_t) -1) + { + graph.nodes[source.idx].row += source.outgoing; + graph.nodes[source.idx].col += source.outgoing; + graph.nodes[source.idx].length -= source.outgoing; + } // if + else + { + graph.nodes[source.idx].length = 0; + } // else + + graph.source = source.idx; + print_graph(graph, len_obs, observed); return graph; From eeebc8a86aa3ee9d5a19d4459cce230af1a280e6 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 22 May 2025 11:27:32 +0200 Subject: [PATCH 199/704] FIX: head_tail for both --- src/graph2.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/graph2.c b/src/graph2.c index 1e35ac9..5aeebc5 100644 --- a/src/graph2.c +++ b/src/graph2.c @@ -253,6 +253,10 @@ split(VA_LCS_Node2 const* const node, tail_tail = j; va_array_append(va_std_allocator, graph->edges, ((Edge2) {graph->edges[j].tail, head_head})); head_head = va_array_length(graph->edges) - 1; + if (head_tail == GVA_NULL) + { + head_tail = head_head; + } // if fprintf(stderr, "both\n"); } // else From 724a848dff6d8542286d7457b9894e01f1249c5a Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 22 May 2025 11:57:04 +0200 Subject: [PATCH 200/704] WIP: split too late --- regres.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/regres.sh b/regres.sh index 86b7d4f..8c486be 100755 --- a/regres.sh +++ b/regres.sh @@ -13,7 +13,7 @@ GTTTA TCTTTCTGC TCAACAAAGG CAA CTTATAAT CCTACCG GG GGTCA -#"" AAT +"" AAT CGATGT TGTGA AGTGG TGGGGTAGT CGAG CGAG @@ -28,8 +28,9 @@ GGCGA GGTTTTA GGCTGC GCTCCAA CTGGGGAG CCACCTGGGC CATTTCACGA TCGCCC +GCC CGACGAGCCC ) for ((i=0; i<${#TESTS[@]}; i+=2)); do - python test.py ${TESTS[i]} ${TESTS[i+1]} + python test.py "${TESTS[i]}" "${TESTS[i+1]}" done From c2f523b2b371df573f9529fa0213b97ebea22aa9 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 22 May 2025 12:46:04 +0200 Subject: [PATCH 201/704] WIP: -1 indent --- src/graph2.c | 48 ++++++++++++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 20 deletions(-) diff --git a/src/graph2.c b/src/graph2.c index 5aeebc5..b1f5181 100644 --- a/src/graph2.c +++ b/src/graph2.c @@ -375,6 +375,12 @@ build(size_t const len_ref, char const reference[static len_ref], return graph; } // if + + for (size_t i = 0; i < va_array_length(lcs_nodes); ++i) + { + fprintf(stderr, "(%u, %u, %u) @ %u\n", lcs_nodes[i].row, lcs_nodes[i].col, lcs_nodes[i].length, lcs_nodes[i].lcs_pos); + } // for + VA_LCS_Node2 source = {shift, shift, 0, -1, GVA_NULL, GVA_NULL, -1}; bool found_source = false; VA_LCS_Node2* const last = &lcs_nodes[lcs_index[len_lcs - 1]]; @@ -431,30 +437,32 @@ build(size_t const len_ref, char const reference[static len_ref], VA_Variant variant; uint32_t const count = edges3(head, tail, is_source, is_sink, &variant); - if (count > 0) + if (count == 0) { - if (head->idx == GVA_NULL) - { - va_array_append(va_std_allocator, graph.nodes, ((Node2) {head->row, head->col, head->length, GVA_NULL, GVA_NULL})); - head->idx = va_array_length(graph.nodes) - 1; - } // if + continue; + } // if - fprintf(stderr, "(%u, %u, %u) -> (%u, %u, %u) " VAR_FMT " x %u\n", head->row, head->col, head->length, tail->row, tail->col, tail->length, print_variant(variant, observed), count); + if (head->idx == GVA_NULL) + { + va_array_append(va_std_allocator, graph.nodes, ((Node2) {head->row, head->col, head->length, GVA_NULL, GVA_NULL})); + head->idx = va_array_length(graph.nodes) - 1; + } // if - if (variant.end + count > tail->outgoing && split_point != tail->outgoing) - { - split(tail, count, variant, split_point, &graph); - split_point = MAX(variant.end, tail->outgoing); - } // else - distribute(tail, head, count, variant, &graph); + fprintf(stderr, "(%u, %u, %u) -> (%u, %u, %u) " VAR_FMT " x %u\n", head->row, head->col, head->length, tail->row, tail->col, tail->length, print_variant(variant, observed), count); - head->outgoing = MIN(head->outgoing, variant.start); - if (is_source) - { - found_source = true; - source.idx = head->idx; - source.outgoing = head->outgoing; - } // if + if (variant.end + count > tail->outgoing && split_point != tail->outgoing) + { + split(tail, count, variant, split_point, &graph); + split_point = MAX(variant.end, tail->outgoing); + } // if + distribute(tail, head, count, variant, &graph); + + head->outgoing = MIN(head->outgoing, variant.start); + if (is_source) + { + found_source = true; + source.idx = head->idx; + source.outgoing = head->outgoing; } // if } // for From 3cf125bdd392a0a8ecc3cf9c03b73f290028a38e Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 23 May 2025 22:27:13 +0200 Subject: [PATCH 202/704] Snapshot not working --- include/edit.h | 10 +++----- include/graph2.h | 4 +-- src/edit2.c | 67 ++++++++++++++++++++++++++++++------------------ src/graph2.c | 36 ++++++++++++++------------ 4 files changed, 66 insertions(+), 51 deletions(-) diff --git a/include/edit.h b/include/edit.h index 98ec8a8..b5787da 100644 --- a/include/edit.h +++ b/include/edit.h @@ -52,14 +52,10 @@ va_edit(VA_Allocator const allocator, VA_LCS_Node*** restrict lcs_nodes); -size_t +VA_LCS_Node2* va_edit2(VA_Allocator const allocator, - size_t const len_ref, - char const reference[static restrict len_ref], - size_t const len_obs, - char const observed[static restrict len_obs], - VA_LCS_Node2** restrict lcs_nodes, - uint32_t** restrict lcs_index); + size_t const len_ref, char const reference[static restrict len_ref], + size_t const len_obs, char const observed[static restrict len_obs]); #ifdef __cplusplus diff --git a/include/graph2.h b/include/graph2.h index ee20cf0..7649183 100644 --- a/include/graph2.h +++ b/include/graph2.h @@ -29,8 +29,8 @@ typedef struct Graph2 -build(size_t const len_ref, char const reference[static len_ref], - size_t const len_obs, char const observed[static len_obs], +build(size_t const len_ref, char const reference[static restrict len_ref], + size_t const len_obs, char const observed[static restrict len_obs], size_t const shift); diff --git a/src/edit2.c b/src/edit2.c index 538d2f8..567a7a0 100644 --- a/src/edit2.c +++ b/src/edit2.c @@ -29,7 +29,8 @@ typedef struct size_t const len_obs; char const* const restrict observed; size_t* const restrict diagonals; - uint32_t* const restrict lcs_index; + uint32_t* const restrict head; + uint32_t* const restrict tail; } Context; @@ -92,8 +93,12 @@ expand(Context const context, *len_lcs = lcs_pos + 1; } // if size_t const length = row - match_row; - va_array_append(context.allocator, *lcs_nodes, ((VA_LCS_Node2) {match_row, match_col, length, lcs_pos, context.lcs_index[lcs_pos], -1, -1})); - context.lcs_index[lcs_pos] = va_array_length(*lcs_nodes) - 1; + va_array_append(context.allocator, *lcs_nodes, ((VA_LCS_Node2) {match_row, match_col, length, lcs_pos, context.tail[lcs_pos], -1, -1})); + context.tail[lcs_pos] = va_array_length(*lcs_nodes) - 1; + if (context.head[lcs_pos] == (uint32_t) -1) + { + context.head[lcs_pos] = context.tail[lcs_pos]; + } // if matching = false; } // if row += 1; @@ -122,22 +127,22 @@ expand(Context const context, *len_lcs = lcs_pos + 1; } // if size_t const length = row - match_row; - va_array_append(context.allocator, *lcs_nodes, ((VA_LCS_Node2) {match_row, match_col, length, lcs_pos, context.lcs_index[lcs_pos], -1, -1})); - context.lcs_index[lcs_pos] = va_array_length(*lcs_nodes) - 1; + va_array_append(context.allocator, *lcs_nodes, ((VA_LCS_Node2) {match_row, match_col, length, lcs_pos, context.tail[lcs_pos], -1, -1})); + context.tail[lcs_pos] = va_array_length(*lcs_nodes) - 1; + if (context.head[lcs_pos] == (uint32_t) -1) + { + context.head[lcs_pos] = context.tail[lcs_pos]; + } // if } // if return steps; } // expand -size_t +VA_LCS_Node2* va_edit2(VA_Allocator const allocator, - size_t const len_ref, - char const reference[static restrict len_ref], - size_t const len_obs, - char const observed[static restrict len_obs], - VA_LCS_Node2** restrict lcs_nodes, - uint32_t** restrict lcs_index) + size_t const len_ref, char const reference[static restrict len_ref], + size_t const len_obs, char const observed[static restrict len_obs]) { ptrdiff_t const delta = len_obs - len_ref; size_t const offset = len_ref + 1; @@ -151,13 +156,15 @@ va_edit2(VA_Allocator const allocator, len_obs, observed, .diagonals = allocator.alloc(allocator.context, NULL, 0, size * sizeof(*context.diagonals)), - .lcs_index = allocator.alloc(allocator.context, NULL, 0, umin(len_ref, len_obs) * sizeof(*context.lcs_index)), + .head = allocator.alloc(allocator.context, NULL, 0, umin(len_ref, len_obs) * sizeof(*context.head)), + .tail = allocator.alloc(allocator.context, NULL, 0, umin(len_ref, len_obs) * sizeof(*context.tail)), }; - if (context.diagonals == NULL || context.lcs_index == NULL) + if (context.diagonals == NULL || context.head == NULL || context.tail == NULL) { allocator.alloc(allocator.context, context.diagonals, size * sizeof(*context.diagonals), 0); - allocator.alloc(allocator.context, context.lcs_index, umin(len_ref, len_obs) * sizeof(*context.lcs_index), 0); - return -1; + allocator.alloc(allocator.context, context.head, umin(len_ref, len_obs) * sizeof(*context.head), 0); + allocator.alloc(allocator.context, context.tail, umin(len_ref, len_obs) * sizeof(*context.tail), 0); + return NULL; } // if for (size_t i = 0; i < size; ++i) @@ -167,10 +174,11 @@ va_edit2(VA_Allocator const allocator, for (size_t i = 0; i < umin(len_ref, len_obs); ++i) { - context.lcs_index[i] = -1; + context.head[i] = -1; + context.tail[i] = -1; } // for - *lcs_nodes = NULL; + VA_LCS_Node2* lcs_nodes = NULL; size_t const lower = delta > 0 ? 0 : delta; size_t const upper = delta > 0 ? delta : 0; @@ -182,21 +190,30 @@ va_edit2(VA_Allocator const allocator, { for (ptrdiff_t idx = lower - p; idx < delta; ++idx) { - context.diagonals[offset + idx] = expand(context, idx, p, &max_lcs_pos, lcs_nodes); + context.diagonals[offset + idx] = expand(context, idx, p, &max_lcs_pos, &lcs_nodes); } // for for (ptrdiff_t idx = upper + p; idx > delta; --idx) { - context.diagonals[offset + idx] = expand(context, idx, p, &max_lcs_pos, lcs_nodes); + context.diagonals[offset + idx] = expand(context, idx, p, &max_lcs_pos, &lcs_nodes); } // for - context.diagonals[offset + delta] = expand(context, delta, p, &max_lcs_pos, lcs_nodes); + context.diagonals[offset + delta] = expand(context, delta, p, &max_lcs_pos, &lcs_nodes); p += 1; } // while - allocator.alloc(allocator.context, context.diagonals, size * sizeof(*context.diagonals), 0); + uint32_t prev = 0; + for (size_t i = 1; i < max_lcs_pos; ++i) + { + if (context.head[i] != (uint32_t) -1) + { + lcs_nodes[context.head[i]].prev = context.tail[prev]; + prev = i; + } // if + } // for - // transfer ownership - *lcs_index = allocator.alloc(allocator.context, context.lcs_index, umin(len_ref, len_obs) * sizeof(*context.lcs_index), max_lcs_pos * sizeof(*context.lcs_index)); + allocator.alloc(allocator.context, context.diagonals, size * sizeof(*context.diagonals), 0); + allocator.alloc(allocator.context, context.head, size * sizeof(*context.head), 0); + allocator.alloc(allocator.context, context.tail, size * sizeof(*context.tail), 0); - return max_lcs_pos; + return lcs_nodes; } // va_edit2 diff --git a/src/graph2.c b/src/graph2.c index b1f5181..258f7bd 100644 --- a/src/graph2.c +++ b/src/graph2.c @@ -349,17 +349,15 @@ edges3(VA_LCS_Node2 const* const head, VA_LCS_Node2 const* const tail, Graph2 -build(size_t const len_ref, char const reference[static len_ref], - size_t const len_obs, char const observed[static len_obs], +build(size_t const len_ref, char const reference[static restrict len_ref], + size_t const len_obs, char const observed[static restrict len_obs], size_t const shift) { - VA_LCS_Node2* lcs_nodes = NULL; - uint32_t* lcs_index = NULL; - size_t const len_lcs = va_edit2(va_std_allocator, len_ref, reference, len_obs, observed, &lcs_nodes, &lcs_index); + VA_LCS_Node2* lcs_nodes = va_edit2(va_std_allocator, len_ref, reference, len_obs, observed); Graph2 graph = {NULL, NULL, GVA_NULL}; - if (len_lcs == 0 || lcs_nodes == NULL) + if (lcs_nodes == NULL) { va_array_append(va_std_allocator, graph.nodes, ((Node2) {len_ref, len_obs, 0, GVA_NULL, GVA_NULL})); uint32_t const sink = va_array_length(graph.nodes) - 1; @@ -375,15 +373,16 @@ build(size_t const len_ref, char const reference[static len_ref], return graph; } // if - for (size_t i = 0; i < va_array_length(lcs_nodes); ++i) { - fprintf(stderr, "(%u, %u, %u) @ %u\n", lcs_nodes[i].row, lcs_nodes[i].col, lcs_nodes[i].length, lcs_nodes[i].lcs_pos); + fprintf(stderr, "%zu: (%u, %u, %u) %u %2d\n", i, lcs_nodes[i].row, lcs_nodes[i].col, lcs_nodes[i].length, lcs_nodes[i].lcs_pos, lcs_nodes[i].prev); } // for VA_LCS_Node2 source = {shift, shift, 0, -1, GVA_NULL, GVA_NULL, -1}; bool found_source = false; - VA_LCS_Node2* const last = &lcs_nodes[lcs_index[len_lcs - 1]]; + size_t const len = va_array_length(lcs_nodes); + VA_LCS_Node2* const last = &lcs_nodes[len - 1]; + size_t const len_lcs = last->lcs_pos + 1; if (last->row + last->length == len_ref + shift && last->col + last->length == len_obs + shift) { va_array_append(va_std_allocator, graph.nodes, ((Node2) {last->row, last->col, last->length, GVA_NULL, GVA_NULL})); @@ -399,9 +398,10 @@ build(size_t const len_ref, char const reference[static len_ref], VA_LCS_Node2 const sink = {len_ref, len_obs, 0, len_lcs - 1, GVA_NULL, GVA_NULL, -1}; va_array_append(va_std_allocator, graph.nodes, ((Node2) {sink.row, sink.col, sink.length, GVA_NULL, GVA_NULL})); uint32_t const sink_idx = va_array_length(graph.nodes) - 1; - for (uint32_t idx = lcs_index[len_lcs - 1]; idx != GVA_NULL; idx = lcs_nodes[idx].prev) + + for (uint32_t j = len; j != GVA_NULL && lcs_nodes[j].lcs_pos >= len_lcs; j = lcs_nodes[j].prev) { - VA_LCS_Node2* const head = &lcs_nodes[idx]; + VA_LCS_Node2* const head = &lcs_nodes[j]; va_array_append(va_std_allocator, graph.edges, ((Edge2) {sink_idx, GVA_NULL})); va_array_append(va_std_allocator, graph.nodes, ((Node2) {head->row, head->col, head->length, va_array_length(graph.edges) - 1, GVA_NULL})); head->idx = va_array_length(graph.nodes) - 1; @@ -419,22 +419,25 @@ build(size_t const len_ref, char const reference[static len_ref], } // for } // else - size_t const t_len = va_array_length(lcs_nodes); - for (size_t i = 0; i < t_len; ++i) + for (size_t i = 0; i < len; ++i) { - VA_LCS_Node2* const tail = &lcs_nodes[t_len - i - 1]; + VA_LCS_Node2 const* const tail = &lcs_nodes[len - i - 1]; if (tail->idx == GVA_NULL) { continue; } // if + uint32_t split_point = -1; bool const is_sink = tail->row + tail->length == len_ref + shift && tail->col + tail->length == len_obs + shift; - for (size_t j = i + 1; j < t_len; ++j) + uint32_t const low = tail->length > tail->lcs_pos ? 0 : tail->lcs_pos - tail->length; + for (uint32_t j = tail->prev; j != GVA_NULL && lcs_nodes[j].lcs_pos >= low; j = lcs_nodes[j].prev) { - VA_LCS_Node2* const head = &lcs_nodes[t_len - j - 1]; + VA_LCS_Node2* const head = &lcs_nodes[j]; bool const is_source = head->row == shift && head->col == shift; + fprintf(stderr, "(%u, %u, %u) vs (%u, %u, %u)\n", head->row, head->col, head->length, tail->row, tail->col, tail->length); + VA_Variant variant; uint32_t const count = edges3(head, tail, is_source, is_sink, &variant); if (count == 0) @@ -484,7 +487,6 @@ build(size_t const len_ref, char const reference[static len_ref], } // for lcs_nodes = va_array_destroy(va_std_allocator, lcs_nodes); - va_std_allocator.alloc(va_std_allocator.context, lcs_index, len_lcs * sizeof(*lcs_index), 0); fprintf(stderr, "SOURCE first outgoing edge at %d\n", source.outgoing); if (source.outgoing != (uint32_t) -1) From 0009e478f481d31321e87f0719304d9d516a0b9b Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 27 May 2025 16:09:02 +0200 Subject: [PATCH 203/704] WIP: working? --- include/edit.h | 3 ++- src/edit2.c | 30 +++++++++++++---------- src/graph2.c | 65 ++++++++++++++++++++++++++++++++++---------------- test.py | 4 ++-- 4 files changed, 65 insertions(+), 37 deletions(-) diff --git a/include/edit.h b/include/edit.h index b5787da..1a4a5fc 100644 --- a/include/edit.h +++ b/include/edit.h @@ -29,7 +29,8 @@ typedef struct uint32_t col; uint32_t length; uint32_t lcs_pos; - uint32_t prev; + uint32_t next; + uint32_t head; uint32_t idx; uint32_t outgoing; } VA_LCS_Node2; diff --git a/src/edit2.c b/src/edit2.c index 567a7a0..5cc6967 100644 --- a/src/edit2.c +++ b/src/edit2.c @@ -39,6 +39,7 @@ expand(Context const context, ptrdiff_t const idx, size_t const p, size_t* const len_lcs, + uint32_t* const prev, VA_LCS_Node2** lcs_nodes) { ptrdiff_t const delta = context.len_obs - context.len_ref; @@ -88,13 +89,14 @@ expand(Context const context, ptrdiff_t const d_row = context.len_ref - row; ptrdiff_t const d_col = context.len_obs - col; size_t const lcs_pos = (row + col - imaxabs(delta) - 2 * p + imaxabs(d_row - d_col)) / 2 - 1; - if (lcs_pos + 1 > *len_lcs) + size_t const length = row - match_row; + va_array_append(context.allocator, *lcs_nodes, ((VA_LCS_Node2) {match_row, match_col, length, lcs_pos, context.tail[lcs_pos], *prev, -1, -1})); + context.tail[lcs_pos] = va_array_length(*lcs_nodes) - 1; + if (lcs_pos + 1 >= *len_lcs) { *len_lcs = lcs_pos + 1; + *prev = context.tail[lcs_pos]; } // if - size_t const length = row - match_row; - va_array_append(context.allocator, *lcs_nodes, ((VA_LCS_Node2) {match_row, match_col, length, lcs_pos, context.tail[lcs_pos], -1, -1})); - context.tail[lcs_pos] = va_array_length(*lcs_nodes) - 1; if (context.head[lcs_pos] == (uint32_t) -1) { context.head[lcs_pos] = context.tail[lcs_pos]; @@ -122,13 +124,14 @@ expand(Context const context, ptrdiff_t const d_row = context.len_ref - row; ptrdiff_t const d_col = context.len_obs - col; size_t const lcs_pos = (row + col - imaxabs(delta) - 2 * p + imaxabs(d_row - d_col)) / 2 - 1; - if (lcs_pos + 1 > *len_lcs) + size_t const length = row - match_row; + va_array_append(context.allocator, *lcs_nodes, ((VA_LCS_Node2) {match_row, match_col, length, lcs_pos, context.tail[lcs_pos], *prev, -1, -1})); + context.tail[lcs_pos] = va_array_length(*lcs_nodes) - 1; + if (lcs_pos + 1 >= *len_lcs) { *len_lcs = lcs_pos + 1; + *prev = context.tail[lcs_pos]; } // if - size_t const length = row - match_row; - va_array_append(context.allocator, *lcs_nodes, ((VA_LCS_Node2) {match_row, match_col, length, lcs_pos, context.tail[lcs_pos], -1, -1})); - context.tail[lcs_pos] = va_array_length(*lcs_nodes) - 1; if (context.head[lcs_pos] == (uint32_t) -1) { context.head[lcs_pos] = context.tail[lcs_pos]; @@ -178,6 +181,7 @@ va_edit2(VA_Allocator const allocator, context.tail[i] = -1; } // for + uint32_t prev = -1; VA_LCS_Node2* lcs_nodes = NULL; size_t const lower = delta > 0 ? 0 : delta; @@ -190,23 +194,23 @@ va_edit2(VA_Allocator const allocator, { for (ptrdiff_t idx = lower - p; idx < delta; ++idx) { - context.diagonals[offset + idx] = expand(context, idx, p, &max_lcs_pos, &lcs_nodes); + context.diagonals[offset + idx] = expand(context, idx, p, &max_lcs_pos, &prev, &lcs_nodes); } // for for (ptrdiff_t idx = upper + p; idx > delta; --idx) { - context.diagonals[offset + idx] = expand(context, idx, p, &max_lcs_pos, &lcs_nodes); + context.diagonals[offset + idx] = expand(context, idx, p, &max_lcs_pos, &prev, &lcs_nodes); } // for - context.diagonals[offset + delta] = expand(context, delta, p, &max_lcs_pos, &lcs_nodes); + context.diagonals[offset + delta] = expand(context, delta, p, &max_lcs_pos, &prev, &lcs_nodes); p += 1; } // while - uint32_t prev = 0; + prev = 0; for (size_t i = 1; i < max_lcs_pos; ++i) { if (context.head[i] != (uint32_t) -1) { - lcs_nodes[context.head[i]].prev = context.tail[prev]; + lcs_nodes[context.head[i]].next = context.tail[prev]; prev = i; } // if } // for diff --git a/src/graph2.c b/src/graph2.c index 258f7bd..081f024 100644 --- a/src/graph2.c +++ b/src/graph2.c @@ -193,7 +193,7 @@ split(VA_LCS_Node2 const* const node, { fprintf(stderr, "\n***SPLIT (%u, %u, %u) because of first outgoing edge at %u\n", node->row, node->col, node->length, node->outgoing); - fprintf(stderr, "fsp: %u lsp: %u\n", incoming.end + in_count - 1, MAX(incoming.end, node->outgoing)); + fprintf(stderr, "fsp: %u lsp: %u\n", MIN(split_point - 1, incoming.end + in_count - 1), MAX(incoming.end, node->outgoing)); uint32_t pos = 0; for (pos = MIN(split_point - 1, incoming.end + in_count - 1); pos >= MAX(incoming.end, node->outgoing); --pos) { @@ -375,14 +375,13 @@ build(size_t const len_ref, char const reference[static restrict len_ref], for (size_t i = 0; i < va_array_length(lcs_nodes); ++i) { - fprintf(stderr, "%zu: (%u, %u, %u) %u %2d\n", i, lcs_nodes[i].row, lcs_nodes[i].col, lcs_nodes[i].length, lcs_nodes[i].lcs_pos, lcs_nodes[i].prev); + fprintf(stderr, "%2zu: (%u, %u, %u) %u %2d %2d\n", i, lcs_nodes[i].row, lcs_nodes[i].col, lcs_nodes[i].length, lcs_nodes[i].lcs_pos, lcs_nodes[i].next, lcs_nodes[i].head); } // for - VA_LCS_Node2 source = {shift, shift, 0, -1, GVA_NULL, GVA_NULL, -1}; + VA_LCS_Node2 source = {shift, shift, 0, -1, GVA_NULL, GVA_NULL, GVA_NULL, -1}; bool found_source = false; size_t const len = va_array_length(lcs_nodes); VA_LCS_Node2* const last = &lcs_nodes[len - 1]; - size_t const len_lcs = last->lcs_pos + 1; if (last->row + last->length == len_ref + shift && last->col + last->length == len_obs + shift) { va_array_append(va_std_allocator, graph.nodes, ((Node2) {last->row, last->col, last->length, GVA_NULL, GVA_NULL})); @@ -395,11 +394,24 @@ build(size_t const len_ref, char const reference[static restrict len_ref], } // if else { - VA_LCS_Node2 const sink = {len_ref, len_obs, 0, len_lcs - 1, GVA_NULL, GVA_NULL, -1}; + VA_LCS_Node2 const sink = {len_ref, len_obs, 0, lcs_nodes[len - 1].lcs_pos, GVA_NULL, GVA_NULL, GVA_NULL, -1}; va_array_append(va_std_allocator, graph.nodes, ((Node2) {sink.row, sink.col, sink.length, GVA_NULL, GVA_NULL})); uint32_t const sink_idx = va_array_length(graph.nodes) - 1; - for (uint32_t j = len; j != GVA_NULL && lcs_nodes[j].lcs_pos >= len_lcs; j = lcs_nodes[j].prev) + uint32_t max_lcs_pos; + uint32_t j; + if (lcs_nodes[len - 1].head == GVA_NULL || lcs_nodes[len - 1].lcs_pos >= lcs_nodes[lcs_nodes[len - 1].head].lcs_pos) + { + j = len - 1; + max_lcs_pos = lcs_nodes[len - 1].lcs_pos; + } // if + else + { + j = lcs_nodes[len - 1].head; + max_lcs_pos = lcs_nodes[lcs_nodes[len - 1].head].lcs_pos; + } // else + + for (; j != GVA_NULL && lcs_nodes[j].lcs_pos == max_lcs_pos; j = lcs_nodes[j].next) { VA_LCS_Node2* const head = &lcs_nodes[j]; va_array_append(va_std_allocator, graph.edges, ((Edge2) {sink_idx, GVA_NULL})); @@ -418,26 +430,34 @@ build(size_t const len_ref, char const reference[static restrict len_ref], fprintf(stderr, "(%u, %u, %u) -> (%u, %u, %u) " VAR_FMT " x %u\n", head->row, head->col, head->length, sink.row, sink.col, sink.length, print_variant(variant, observed), count); } // for } // else + fprintf(stderr, "\n"); for (size_t i = 0; i < len; ++i) { - VA_LCS_Node2 const* const tail = &lcs_nodes[len - i - 1]; + VA_LCS_Node2 const* const restrict tail = &lcs_nodes[len - i - 1]; if (tail->idx == GVA_NULL) { continue; } // if + bool const is_sink = tail->row + tail->length == len_ref + shift && tail->col + tail->length == len_obs + shift; uint32_t split_point = -1; - bool const is_sink = tail->row + tail->length == len_ref + shift && tail->col + tail->length == len_obs + shift; - uint32_t const low = tail->length > tail->lcs_pos ? 0 : tail->lcs_pos - tail->length; - for (uint32_t j = tail->prev; j != GVA_NULL && lcs_nodes[j].lcs_pos >= low; j = lcs_nodes[j].prev) + uint32_t const lcs_low = tail->length > tail->lcs_pos ? 0 : tail->lcs_pos - tail->length; + fprintf(stderr, "(%u, %u, %u) @ %u low: %u\n", tail->row, tail->col, tail->length, tail->lcs_pos, lcs_low); + + for (uint32_t j = tail->head; j != GVA_NULL && lcs_nodes[j].lcs_pos >= lcs_low; j = lcs_nodes[j].next) { + if (j >= len - i - 1) + { + fprintf(stderr, " skip %u\n", j); + continue; + } // if + + fprintf(stderr, " %u: (%u, %u, %u) @ %u\n", j, lcs_nodes[j].row, lcs_nodes[j].col, lcs_nodes[j].length, lcs_nodes[j].lcs_pos); VA_LCS_Node2* const head = &lcs_nodes[j]; bool const is_source = head->row == shift && head->col == shift; - fprintf(stderr, "(%u, %u, %u) vs (%u, %u, %u)\n", head->row, head->col, head->length, tail->row, tail->col, tail->length); - VA_Variant variant; uint32_t const count = edges3(head, tail, is_source, is_sink, &variant); if (count == 0) @@ -449,6 +469,11 @@ build(size_t const len_ref, char const reference[static restrict len_ref], { va_array_append(va_std_allocator, graph.nodes, ((Node2) {head->row, head->col, head->length, GVA_NULL, GVA_NULL})); head->idx = va_array_length(graph.nodes) - 1; + if (is_source) + { + found_source = true; + source.idx = head->idx; + } // if } // if fprintf(stderr, "(%u, %u, %u) -> (%u, %u, %u) " VAR_FMT " x %u\n", head->row, head->col, head->length, tail->row, tail->col, tail->length, print_variant(variant, observed), count); @@ -456,17 +481,14 @@ build(size_t const len_ref, char const reference[static restrict len_ref], if (variant.end + count > tail->outgoing && split_point != tail->outgoing) { split(tail, count, variant, split_point, &graph); - split_point = MAX(variant.end, tail->outgoing); + split_point = MIN(split_point, MAX(variant.end, tail->outgoing)); } // if distribute(tail, head, count, variant, &graph); - head->outgoing = MIN(head->outgoing, variant.start); - if (is_source) - { - found_source = true; - source.idx = head->idx; - source.outgoing = head->outgoing; - } // if + + + + source.outgoing = MIN(source.outgoing, variant.start); } // for if (!found_source && tail->length > tail->lcs_pos) @@ -484,6 +506,8 @@ build(size_t const len_ref, char const reference[static restrict len_ref], uint32_t const count = edges3(&source, tail, true, is_sink, &variant); fprintf(stderr, "(%u, %u, %u) -> (%u, %u, %u) " VAR_FMT " x %u\n", source.row, source.col, source.length, tail->row, tail->col, tail->length, print_variant(variant, observed), count); } // if + fprintf(stderr, "\n"); + } // for lcs_nodes = va_array_destroy(va_std_allocator, lcs_nodes); @@ -501,7 +525,6 @@ build(size_t const len_ref, char const reference[static restrict len_ref], } // else graph.source = source.idx; - print_graph(graph, len_obs, observed); return graph; diff --git a/test.py b/test.py index 2361dba..5161d13 100644 --- a/test.py +++ b/test.py @@ -151,8 +151,8 @@ def main(): #if random.random() > 0.5: # prefix = random_sequence(1000) # suffix = random_sequence(1000) - reference = prefix + random_sequence(10) + suffix - observed = prefix + random_sequence(10) + suffix + reference = prefix + random_sequence(42) + suffix + observed = prefix + random_sequence(42) + suffix if n % 1_000 == 0: print(n) From 54c3097ca23015d2f86b3c86f8eea8b18fa40af0 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 27 May 2025 16:10:36 +0200 Subject: [PATCH 204/704] One more test --- regres.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/regres.sh b/regres.sh index 8c486be..1f2dea7 100755 --- a/regres.sh +++ b/regres.sh @@ -29,6 +29,7 @@ GGCTGC GCTCCAA CTGGGGAG CCACCTGGGC CATTTCACGA TCGCCC GCC CGACGAGCCC +AGAGAAAAA AAAA ) for ((i=0; i<${#TESTS[@]}; i+=2)); do From 692843bf1835b8b3722a279a6ad17d397e093e86 Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 28 May 2025 14:54:10 +0200 Subject: [PATCH 205/704] Working? snapshot --- include/edit.h | 5 +-- src/edit2.c | 31 +++++++++++------ src/graph2.c | 94 ++++++++++++++++++++++++++------------------------ test.py | 8 ++--- 4 files changed, 75 insertions(+), 63 deletions(-) diff --git a/include/edit.h b/include/edit.h index 1a4a5fc..81864a7 100644 --- a/include/edit.h +++ b/include/edit.h @@ -30,7 +30,7 @@ typedef struct uint32_t length; uint32_t lcs_pos; uint32_t next; - uint32_t head; + uint32_t inext; uint32_t idx; uint32_t outgoing; } VA_LCS_Node2; @@ -56,7 +56,8 @@ va_edit(VA_Allocator const allocator, VA_LCS_Node2* va_edit2(VA_Allocator const allocator, size_t const len_ref, char const reference[static restrict len_ref], - size_t const len_obs, char const observed[static restrict len_obs]); + size_t const len_obs, char const observed[static restrict len_obs], + uint32_t* const restrict head); #ifdef __cplusplus diff --git a/src/edit2.c b/src/edit2.c index 5cc6967..a3a5a99 100644 --- a/src/edit2.c +++ b/src/edit2.c @@ -39,7 +39,7 @@ expand(Context const context, ptrdiff_t const idx, size_t const p, size_t* const len_lcs, - uint32_t* const prev, + uint32_t* head, VA_LCS_Node2** lcs_nodes) { ptrdiff_t const delta = context.len_obs - context.len_ref; @@ -90,12 +90,12 @@ expand(Context const context, ptrdiff_t const d_col = context.len_obs - col; size_t const lcs_pos = (row + col - imaxabs(delta) - 2 * p + imaxabs(d_row - d_col)) / 2 - 1; size_t const length = row - match_row; - va_array_append(context.allocator, *lcs_nodes, ((VA_LCS_Node2) {match_row, match_col, length, lcs_pos, context.tail[lcs_pos], *prev, -1, -1})); + va_array_append(context.allocator, *lcs_nodes, ((VA_LCS_Node2) {match_row, match_col, length, lcs_pos, context.tail[lcs_pos], -1, -1, -1})); context.tail[lcs_pos] = va_array_length(*lcs_nodes) - 1; if (lcs_pos + 1 >= *len_lcs) { *len_lcs = lcs_pos + 1; - *prev = context.tail[lcs_pos]; + *head = context.tail[lcs_pos]; } // if if (context.head[lcs_pos] == (uint32_t) -1) { @@ -125,12 +125,12 @@ expand(Context const context, ptrdiff_t const d_col = context.len_obs - col; size_t const lcs_pos = (row + col - imaxabs(delta) - 2 * p + imaxabs(d_row - d_col)) / 2 - 1; size_t const length = row - match_row; - va_array_append(context.allocator, *lcs_nodes, ((VA_LCS_Node2) {match_row, match_col, length, lcs_pos, context.tail[lcs_pos], *prev, -1, -1})); + va_array_append(context.allocator, *lcs_nodes, ((VA_LCS_Node2) {match_row, match_col, length, lcs_pos, context.tail[lcs_pos], -1, -1, -1})); context.tail[lcs_pos] = va_array_length(*lcs_nodes) - 1; if (lcs_pos + 1 >= *len_lcs) { *len_lcs = lcs_pos + 1; - *prev = context.tail[lcs_pos]; + *head = context.tail[lcs_pos]; } // if if (context.head[lcs_pos] == (uint32_t) -1) { @@ -145,7 +145,8 @@ expand(Context const context, VA_LCS_Node2* va_edit2(VA_Allocator const allocator, size_t const len_ref, char const reference[static restrict len_ref], - size_t const len_obs, char const observed[static restrict len_obs]) + size_t const len_obs, char const observed[static restrict len_obs], + uint32_t* const restrict head) { ptrdiff_t const delta = len_obs - len_ref; size_t const offset = len_ref + 1; @@ -181,7 +182,7 @@ va_edit2(VA_Allocator const allocator, context.tail[i] = -1; } // for - uint32_t prev = -1; + *head = -1; VA_LCS_Node2* lcs_nodes = NULL; size_t const lower = delta > 0 ? 0 : delta; @@ -194,18 +195,18 @@ va_edit2(VA_Allocator const allocator, { for (ptrdiff_t idx = lower - p; idx < delta; ++idx) { - context.diagonals[offset + idx] = expand(context, idx, p, &max_lcs_pos, &prev, &lcs_nodes); + context.diagonals[offset + idx] = expand(context, idx, p, &max_lcs_pos, head, &lcs_nodes); } // for for (ptrdiff_t idx = upper + p; idx > delta; --idx) { - context.diagonals[offset + idx] = expand(context, idx, p, &max_lcs_pos, &prev, &lcs_nodes); + context.diagonals[offset + idx] = expand(context, idx, p, &max_lcs_pos, head, &lcs_nodes); } // for - context.diagonals[offset + delta] = expand(context, delta, p, &max_lcs_pos, &prev, &lcs_nodes); + context.diagonals[offset + delta] = expand(context, delta, p, &max_lcs_pos, head, &lcs_nodes); p += 1; } // while - prev = 0; + uint32_t prev = 0; for (size_t i = 1; i < max_lcs_pos; ++i) { if (context.head[i] != (uint32_t) -1) @@ -215,6 +216,14 @@ va_edit2(VA_Allocator const allocator, } // if } // for + for (uint32_t i = 0; i < va_array_length(lcs_nodes); ++i) + { + if (lcs_nodes[i].next != (uint32_t) -1) + { + lcs_nodes[lcs_nodes[i].next].inext = i; + } // if + } // for + allocator.alloc(allocator.context, context.diagonals, size * sizeof(*context.diagonals), 0); allocator.alloc(allocator.context, context.head, size * sizeof(*context.head), 0); allocator.alloc(allocator.context, context.tail, size * sizeof(*context.tail), 0); diff --git a/src/graph2.c b/src/graph2.c index 081f024..0c23ed5 100644 --- a/src/graph2.c +++ b/src/graph2.c @@ -191,9 +191,10 @@ split(VA_LCS_Node2 const* const node, uint32_t const split_point, Graph2* const graph) { +/* fprintf(stderr, "\n***SPLIT (%u, %u, %u) because of first outgoing edge at %u\n", node->row, node->col, node->length, node->outgoing); - fprintf(stderr, "fsp: %u lsp: %u\n", MIN(split_point - 1, incoming.end + in_count - 1), MAX(incoming.end, node->outgoing)); +*/ uint32_t pos = 0; for (pos = MIN(split_point - 1, incoming.end + in_count - 1); pos >= MAX(incoming.end, node->outgoing); --pos) { @@ -209,7 +210,7 @@ split(VA_LCS_Node2 const* const node, uint32_t const out_count = edges2( (VA_LCS_Node) {node->row, node->col, node->length, -1, GVA_NULL, 0}, (VA_LCS_Node) {tail->row, tail->col, tail->length, -1, GVA_NULL, 0}, false, tail->edges == GVA_NULL && tail->lambda == GVA_NULL, &outgoing); - fprintf(stderr, " %u: (%u, %u, %u): x %u ", graph->edges[j].tail, tail->row, tail->col, tail->length, out_count); + //fprintf(stderr, " %u: (%u, %u, %u): x %u ", graph->edges[j].tail, tail->row, tail->col, tail->length, out_count); // TODO: can we avoid reordering the tail list? Yes? XOR-linked? if (outgoing.start > pos) @@ -224,7 +225,7 @@ split(VA_LCS_Node2 const* const node, } // if tail_tail = j; - fprintf(stderr, "tail\n"); + //fprintf(stderr, "tail\n"); } // if else if (outgoing.start + out_count - 1 <= pos) { @@ -238,7 +239,7 @@ split(VA_LCS_Node2 const* const node, } // if head_tail = j; - fprintf(stderr, "head\n"); + //fprintf(stderr, "head\n"); } // if else { @@ -258,7 +259,7 @@ split(VA_LCS_Node2 const* const node, head_tail = head_head; } // if - fprintf(stderr, "both\n"); + //fprintf(stderr, "both\n"); } // else } // for if (head_tail != GVA_NULL) @@ -276,13 +277,15 @@ split(VA_LCS_Node2 const* const node, graph->nodes[node->idx].lambda = va_array_length(graph->nodes) - 1; graph->nodes[node->idx].length = length; + /* Node2 const* const lambda = &graph->nodes[graph->nodes[node->idx].lambda]; fprintf(stderr, "(%u, %u, %u) l> (%u, %u, %u) @ %u\n", graph->nodes[node->idx].row, graph->nodes[node->idx].col, graph->nodes[node->idx].length, lambda->row, lambda->col, lambda->length, pos); + */ } // for - fprintf(stderr, "***\n\n"); + //fprintf(stderr, "***\n\n"); } // split @@ -294,8 +297,8 @@ distribute(VA_LCS_Node2 const* const tail, VA_LCS_Node2 const* const head, uint32_t lambda = tail->idx; for (uint32_t i = 0; i < count; ++i) { - fprintf(stderr, "LAMBDA: %u\n", lambda); - fprintf(stderr, " variant: %u\n", variant.end + i); + //fprintf(stderr, "LAMBDA: %u\n", lambda); + //fprintf(stderr, " variant: %u\n", variant.end + i); bool is_lambda = false; while (graph->nodes[lambda].lambda != GVA_NULL && variant.end + i >= graph->nodes[lambda].row + graph->nodes[lambda].length) @@ -310,7 +313,7 @@ distribute(VA_LCS_Node2 const* const tail, VA_LCS_Node2 const* const head, graph->nodes[head->idx].edges = va_array_length(graph->edges) - 1; } // if - fprintf(stderr, " next: %d\n", graph->nodes[lambda].lambda); + //fprintf(stderr, " next: %d\n", graph->nodes[lambda].lambda); if (graph->nodes[lambda].lambda == GVA_NULL || variant.end + count <= graph->nodes[lambda].row + graph->nodes[lambda].length) { break; @@ -353,7 +356,8 @@ build(size_t const len_ref, char const reference[static restrict len_ref], size_t const len_obs, char const observed[static restrict len_obs], size_t const shift) { - VA_LCS_Node2* lcs_nodes = va_edit2(va_std_allocator, len_ref, reference, len_obs, observed); + uint32_t last_idx = -1; + VA_LCS_Node2* lcs_nodes = va_edit2(va_std_allocator, len_ref, reference, len_obs, observed, &last_idx); Graph2 graph = {NULL, NULL, GVA_NULL}; @@ -373,15 +377,17 @@ build(size_t const len_ref, char const reference[static restrict len_ref], return graph; } // if +/* for (size_t i = 0; i < va_array_length(lcs_nodes); ++i) { - fprintf(stderr, "%2zu: (%u, %u, %u) %u %2d %2d\n", i, lcs_nodes[i].row, lcs_nodes[i].col, lcs_nodes[i].length, lcs_nodes[i].lcs_pos, lcs_nodes[i].next, lcs_nodes[i].head); + fprintf(stderr, "%2zu: (%u, %u, %u) %u %2d %2d\n", i, lcs_nodes[i].row, lcs_nodes[i].col, lcs_nodes[i].length, lcs_nodes[i].lcs_pos, lcs_nodes[i].next, lcs_nodes[i].inext); } // for - + fprintf(stderr, "%u\n", last_idx); +*/ VA_LCS_Node2 source = {shift, shift, 0, -1, GVA_NULL, GVA_NULL, GVA_NULL, -1}; bool found_source = false; size_t const len = va_array_length(lcs_nodes); - VA_LCS_Node2* const last = &lcs_nodes[len - 1]; + VA_LCS_Node2* const last = &lcs_nodes[last_idx]; if (last->row + last->length == len_ref + shift && last->col + last->length == len_obs + shift) { va_array_append(va_std_allocator, graph.nodes, ((Node2) {last->row, last->col, last->length, GVA_NULL, GVA_NULL})); @@ -394,24 +400,10 @@ build(size_t const len_ref, char const reference[static restrict len_ref], } // if else { - VA_LCS_Node2 const sink = {len_ref, len_obs, 0, lcs_nodes[len - 1].lcs_pos, GVA_NULL, GVA_NULL, GVA_NULL, -1}; + VA_LCS_Node2 const sink = {len_ref, len_obs, 0, lcs_nodes[last_idx].lcs_pos, GVA_NULL, GVA_NULL, GVA_NULL, -1}; va_array_append(va_std_allocator, graph.nodes, ((Node2) {sink.row, sink.col, sink.length, GVA_NULL, GVA_NULL})); uint32_t const sink_idx = va_array_length(graph.nodes) - 1; - - uint32_t max_lcs_pos; - uint32_t j; - if (lcs_nodes[len - 1].head == GVA_NULL || lcs_nodes[len - 1].lcs_pos >= lcs_nodes[lcs_nodes[len - 1].head].lcs_pos) - { - j = len - 1; - max_lcs_pos = lcs_nodes[len - 1].lcs_pos; - } // if - else - { - j = lcs_nodes[len - 1].head; - max_lcs_pos = lcs_nodes[lcs_nodes[len - 1].head].lcs_pos; - } // else - - for (; j != GVA_NULL && lcs_nodes[j].lcs_pos == max_lcs_pos; j = lcs_nodes[j].next) + for (uint32_t j = last_idx; j != GVA_NULL && lcs_nodes[j].lcs_pos == lcs_nodes[last_idx].lcs_pos; j = lcs_nodes[j].next) { VA_LCS_Node2* const head = &lcs_nodes[j]; va_array_append(va_std_allocator, graph.edges, ((Edge2) {sink_idx, GVA_NULL})); @@ -425,16 +417,33 @@ build(size_t const len_ref, char const reference[static restrict len_ref], source.outgoing = head->outgoing; } // if +/* VA_Variant variant; uint32_t const count = edges3(head, &sink, head->row == shift && head->col == shift, true, &variant); fprintf(stderr, "(%u, %u, %u) -> (%u, %u, %u) " VAR_FMT " x %u\n", head->row, head->col, head->length, sink.row, sink.col, sink.length, print_variant(variant, observed), count); +*/ } // for } // else - fprintf(stderr, "\n"); +// fprintf(stderr, "\n"); for (size_t i = 0; i < len; ++i) { VA_LCS_Node2 const* const restrict tail = &lcs_nodes[len - i - 1]; + uint32_t const idx = len - i - 1; + + if (lcs_nodes[idx].inext != GVA_NULL) + { + lcs_nodes[lcs_nodes[idx].inext].next = lcs_nodes[idx].next; + } // if + else + { + last_idx = lcs_nodes[idx].next; + } // else + if (lcs_nodes[idx].next != GVA_NULL) + { + lcs_nodes[lcs_nodes[idx].next].inext = lcs_nodes[idx].inext; + } // if + if (tail->idx == GVA_NULL) { continue; @@ -444,17 +453,11 @@ build(size_t const len_ref, char const reference[static restrict len_ref], uint32_t split_point = -1; uint32_t const lcs_low = tail->length > tail->lcs_pos ? 0 : tail->lcs_pos - tail->length; - fprintf(stderr, "(%u, %u, %u) @ %u low: %u\n", tail->row, tail->col, tail->length, tail->lcs_pos, lcs_low); + //fprintf(stderr, "(%u, %u, %u) @ %u low: %u\n", tail->row, tail->col, tail->length, tail->lcs_pos, lcs_low); - for (uint32_t j = tail->head; j != GVA_NULL && lcs_nodes[j].lcs_pos >= lcs_low; j = lcs_nodes[j].next) + for (uint32_t j = last_idx; j != GVA_NULL && lcs_nodes[j].lcs_pos >= lcs_low; j = lcs_nodes[j].next) { - if (j >= len - i - 1) - { - fprintf(stderr, " skip %u\n", j); - continue; - } // if - - fprintf(stderr, " %u: (%u, %u, %u) @ %u\n", j, lcs_nodes[j].row, lcs_nodes[j].col, lcs_nodes[j].length, lcs_nodes[j].lcs_pos); + //fprintf(stderr, " %u: (%u, %u, %u) @ %u\n", j, lcs_nodes[j].row, lcs_nodes[j].col, lcs_nodes[j].length, lcs_nodes[j].lcs_pos); VA_LCS_Node2* const head = &lcs_nodes[j]; bool const is_source = head->row == shift && head->col == shift; @@ -476,7 +479,7 @@ build(size_t const len_ref, char const reference[static restrict len_ref], } // if } // if - fprintf(stderr, "(%u, %u, %u) -> (%u, %u, %u) " VAR_FMT " x %u\n", head->row, head->col, head->length, tail->row, tail->col, tail->length, print_variant(variant, observed), count); + //fprintf(stderr, "(%u, %u, %u) -> (%u, %u, %u) " VAR_FMT " x %u\n", head->row, head->col, head->length, tail->row, tail->col, tail->length, print_variant(variant, observed), count); if (variant.end + count > tail->outgoing && split_point != tail->outgoing) { @@ -485,9 +488,6 @@ build(size_t const len_ref, char const reference[static restrict len_ref], } // if distribute(tail, head, count, variant, &graph); head->outgoing = MIN(head->outgoing, variant.start); - - - source.outgoing = MIN(source.outgoing, variant.start); } // for @@ -502,17 +502,19 @@ build(size_t const len_ref, char const reference[static restrict len_ref], va_array_append(va_std_allocator, graph.edges, ((Edge2) {tail->idx, graph.nodes[source.idx].edges})); graph.nodes[source.idx].edges = va_array_length(graph.edges) - 1; +/* VA_Variant variant; uint32_t const count = edges3(&source, tail, true, is_sink, &variant); fprintf(stderr, "(%u, %u, %u) -> (%u, %u, %u) " VAR_FMT " x %u\n", source.row, source.col, source.length, tail->row, tail->col, tail->length, print_variant(variant, observed), count); +*/ } // if - fprintf(stderr, "\n"); + //fprintf(stderr, "\n"); } // for lcs_nodes = va_array_destroy(va_std_allocator, lcs_nodes); - fprintf(stderr, "SOURCE first outgoing edge at %d\n", source.outgoing); + //fprintf(stderr, "SOURCE first outgoing edge at %d\n", source.outgoing); if (source.outgoing != (uint32_t) -1) { graph.nodes[source.idx].row += source.outgoing; @@ -525,7 +527,7 @@ build(size_t const len_ref, char const reference[static restrict len_ref], } // else graph.source = source.idx; - print_graph(graph, len_obs, observed); + //print_graph(graph, len_obs, observed); return graph; } // build diff --git a/test.py b/test.py index 5161d13..41c04ab 100644 --- a/test.py +++ b/test.py @@ -79,7 +79,7 @@ def str2var(desc): assert lhs == str(rhs), f'canonical elements differ: {lhs} vs {rhs}' -def check(reference, observed, debug=False, timeout=2): +def check(reference, observed, debug=False, timeout=None): #graph = LCSgraph.from_sequence(reference, observed) graph = LCSgraph(reference, observed) valgrind = [] @@ -88,7 +88,7 @@ def check(reference, observed, debug=False, timeout=2): print(canonical(graph)) valgrind = ["valgrind", "--leak-check=full", "--error-exitcode=1"] - stdout = subprocess.run([*valgrind, "./a.out", reference, observed], check=True, stdout=subprocess.PIPE, timeout=timeout).stdout.decode("utf-8") + stdout = subprocess.run([*valgrind, "./a.out", reference, observed], check=True, stderr=subprocess.DEVNULL, stdout=subprocess.PIPE, timeout=timeout).stdout.decode("utf-8") try: cgraph = json.loads(stdout) @@ -151,8 +151,8 @@ def main(): #if random.random() > 0.5: # prefix = random_sequence(1000) # suffix = random_sequence(1000) - reference = prefix + random_sequence(42) + suffix - observed = prefix + random_sequence(42) + suffix + reference = prefix + random_sequence(142) + suffix + observed = prefix + random_sequence(142) + suffix if n % 1_000 == 0: print(n) From a77e3cfad89b9a8abb843bd2b6f99899533bf3e0 Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 28 May 2025 17:07:02 +0200 Subject: [PATCH 206/704] Benchmarking --- include/graph.h | 3 +++ include/graph2.h | 3 +++ src/graph.c | 35 +++++++++++++++++++++++++---------- src/graph2.c | 10 ++++++++++ src/main.c | 15 +++++++++++++-- 5 files changed, 54 insertions(+), 12 deletions(-) diff --git a/include/graph.h b/include/graph.h index 47dd17d..00601f2 100644 --- a/include/graph.h +++ b/include/graph.h @@ -2,6 +2,9 @@ #include "../include/edit.h" // VA_LCS_Node #include "../include/variant.h" // VA_Variant +extern size_t eq_count; + + typedef struct { uint32_t tail; diff --git a/include/graph2.h b/include/graph2.h index 7649183..b4f923c 100644 --- a/include/graph2.h +++ b/include/graph2.h @@ -3,6 +3,9 @@ #include "../include/variant.h" // VA_Variant +extern size_t eq_count; + + typedef struct { uint32_t tail; diff --git a/src/graph.c b/src/graph.c index 320ee02..0360f1f 100644 --- a/src/graph.c +++ b/src/graph.c @@ -127,7 +127,10 @@ build_graph(VA_Allocator const allocator, VA_LCS_Node* const heads = lcs_nodes[i - 1]; for (size_t k = 0; k < va_array_length(heads); ++k) { - if (heads[k].row + heads[k].length < tail.row + tail.length && heads[k].col + heads[k].length < tail.col + tail.length) + eq_count += 1; + + if (heads[k].row + heads[k].length < tail.row + tail.length && + heads[k].col + heads[k].length < tail.col + tail.length) { max_sink = MAX(max_sink, tail.row + tail.length - 1); @@ -152,19 +155,31 @@ build_graph(VA_Allocator const allocator, if (debug) printf("RELABEL NODE %u: (%u, %u, %u)\n", split_idx, graph.nodes[split_idx].row,graph.nodes[split_idx].col, graph.nodes[split_idx].length); } // if - else + else if (heads[k].idx == GVA_NULL) + { + heads[k].idx = add_node(allocator, &graph, heads[k].row, heads[k].col, heads[k].length); + if (debug) + printf("MAKE NODE %u: (%u, %u, %u)\n", heads[k].idx, heads[k].row, heads[k].col, heads[k].length); + } // if + + /* + bool found = false; + for (size_t e = graph.nodes[heads[k].idx].edges; e != GVA_NULL; e = graph.edges[e].next) { - if (heads[k].idx == GVA_NULL) + if (graph.edges[e].tail == tail.idx) { - heads[k].idx = add_node(allocator, &graph, heads[k].row, heads[k].col, heads[k].length); - if (debug) - printf("MAKE NODE %u: (%u, %u, %u)\n", heads[k].idx, heads[k].row, heads[k].col, heads[k].length); + found = true; + break; } // if - } // else + } // for + if (!found) + */ - graph.nodes[heads[k].idx].edges = add_edge(allocator, &graph, tail.idx, graph.nodes[heads[k].idx].edges, variant); - if (debug) - printf("MAKE EDGE (%u %u %u) -> (%u %u %u): " VAR_FMT "\n", heads[k].row, heads[k].col, heads[k].length, tail.row, tail.col, tail.length, print_variant(variant, "0123456789")); + { + graph.nodes[heads[k].idx].edges = add_edge(allocator, &graph, tail.idx, graph.nodes[heads[k].idx].edges, variant); + if (debug) + printf("MAKE EDGE (%u %u %u) -> (%u %u %u): " VAR_FMT "\n", heads[k].row, heads[k].col, heads[k].length, tail.row, tail.col, tail.length, print_variant(variant, "0123456789")); + } // if here = k + 1; } // if diff --git a/src/graph2.c b/src/graph2.c index 0c23ed5..442b869 100644 --- a/src/graph2.c +++ b/src/graph2.c @@ -18,6 +18,9 @@ #define VAR_FMT "%u:%u/%.*s" +size_t eq_count; + + static uint32_t const GVA_NULL = UINT32_MAX; @@ -444,6 +447,8 @@ build(size_t const len_ref, char const reference[static restrict len_ref], lcs_nodes[lcs_nodes[idx].next].inext = lcs_nodes[idx].inext; } // if + eq_count += 1; + if (tail->idx == GVA_NULL) { continue; @@ -489,6 +494,11 @@ build(size_t const len_ref, char const reference[static restrict len_ref], distribute(tail, head, count, variant, &graph); head->outgoing = MIN(head->outgoing, variant.start); source.outgoing = MIN(source.outgoing, variant.start); + +/* + va_array_append(va_std_allocator, graph.edges, ((Edge2) {tail->idx, graph.nodes[head->idx].edges})); + graph.nodes[head->idx].edges = va_array_length(graph.edges); +*/ } // for if (!found_source && tail->length > tail->lcs_pos) diff --git a/src/main.c b/src/main.c index bb73765..da26e9b 100644 --- a/src/main.c +++ b/src/main.c @@ -151,11 +151,22 @@ print_graph(Graph const graph, size_t const len_obs, char const observed[static int main(int argc, char* argv[static argc + 1]) { -/* + (void) argv; char const* const restrict reference = "ATTCTATCTTCTGTCTACATAAGATGTCATACTAGAGGGCATATCTGCAATGTATACATATTATCTTTTCCAGCATGCATTCAGTTGTGTTGGAATAATTTATGTACACCTTTATAAACGCTGAGCCTCACAAGAGCCATGTGCCACGTATTGTTTTCTTACTACTTTTTGGGATACCTGGCACGTAATAGACACTCATTGAAAGTTTCCTAATGAATGAAGTACAAAGATAAAACAAGTTATAGACTGATTCTTTTGAGCTGTCAAGGTTGTAAATAGACTTTTGCTCAATCAATTCAAATGGTGGCAGGTAGTGGGGGTAGAGGGATTGGTATGAAAAACATAAGCTTTCAGAACTCCTGTGTTTATTTTTAGAATGTCAACTGCTTGAGTGTTTTTAACTCTGTGGTATCTGAACTATCTTCTCTAACTGCAGGTTGGGCTCAGATCTGTGATAGAACAGTTTCCTGGGAAGCTTGACTTTGTCCTTGTGGATGGGGGCTGTGTCCTAAGCCATGGCCACAAGCAGTTGATGTGCTTGGCTAGATCTGTTCTCAGTAAGGCGAAGATCTTGCTGCTTGATGAACCCAGTGCTCATTTGGATCCAGTGTGAGTTTCAGATGTTCTGTTACTTAATAGCACAGTGGGAACAGAATCATTATGCCTGCTTCATGGTGACACATATTTCTATTAGGCTGTCATGTCTGCGTGTGGGGGTCTCCCCCAAGATATGAAATAATTGCCCAGTGGAAATGAGCATAAATGCATATTTCCTTGCTAAGAGTCTTGTGTTTTCTTCCGAAGATAGTTTTTAGTTTCATACAAACTCTTCCCCCTTGTCAACACATGATGAAGCTTTTAAATACATGGGCCTAATCTGATCCTTATGATTTGCCTTTGTATCCCATTTATACCATAAGCATGTTTATAGCCCCAAATAAAGAAGTACTGGTGATTCTACATAATGAAAAATGTACTCATTTATTAAAGTTTCTTTGAAATATTTGTCCTGTTTATTTATGGATACTTAGAGTCTACCCCATGGTTGAAAAGCTGATTGTGGCTAACGCTATATCAACATTATGTGAAAAGAACTTAAAGAAATAAGTAATTTAAAGAGATAATAGAACAATAGACATATTATCAAGGTAAATACAGATCATTACTGTTCTGTGATATTATGTGTGGTATTTTCTTTCTTTTCTAGAACATACCAAATAATTAGAAGAACTCTAAAACAAGCATTTGCTGATTGCACAGTAATTCTCTGTGAACACAGGATAGAAGCAATGCTGGAATGCCAACAATTTTTGGTGAGTCTTTATAACTTTACTTAAGATCTCATTGCCCTTGTAATTCTTGATAACAATCTCACATGTGATAGTTCCTGCAAATTGCAACAATGTACAAGTTCTTTTCAAAAATATGTATCATACAGCCATCCAGCTTTACTCAAAATAGCTGCACAAGTTTTTCACTTTGATCTGAGCCATGTGGTGAGGTTGAAATATAGTAAATCTAAAATGGCAGCATATTACTAAGTTATGTTTATAAATAGGATATATATACTTTTTGAGCCCTTTATTTGGGGACCAAGTCATACAAAATACTCTACTGTTTAAGATTTTAAAAAAGGTCCCTGTGATTCTTTCAATAACTAAATGTCCCATGGATGTGGTCTGGGACAGGCCTAGTTGTCTTACAGTCTGATTTATGGTATTAATGACAAAGTTGAGAGGCACATTTCATTTTT"; char const* const restrict observed = "ATTCTATCTTCTGTCTACATAAGATGTCATACTAGAGGGCATATCTGCAATGTATACATATTATCTTTTCCAGCATGCATTCAGTTGTGTTGGAATAATTTATGTACACCTTTATAAACGCTGAGCCTCACAAGAGCCATGTGCCACGTATTGTTTTCTTACTACTTTTTGGGATACCTGGCACGTAATAGACACTCATTGAAAGTTTCCTAATGAATGAAGTACAAAGATAAAACAAGTTATAGACTGATTCTTTTGAGCTGTCAAGGTTGTAAATAGACTTTTGCTCAATCAATTCAAATGGTGGCAGGTAGTGGGGGTAGAGGGATTGGTATGAAAAACATAAGCTTTCAGAACTCCTGTGTTTATTTTTAGAATGTCAACTGCTTGAGTGTTTTTAACTCTGTGGTATCTGAACTATCTTCTCTAACTGCAGGTGAGTCTTTATAACTTTACTTAAGATCTCATTGCCCTTGTAATTCTTGATAACAATCTCACATGTGATAGTTCCTGCAAATTGCAACAATGTACAAGTTCTTTTCAAAAATATGTATCATACAGCCATCCAGCTTTACTCAAAATAGCTGCACAAGTTTTTCACTTTGATCTGAGCCATGTGGTGAGGTTGAAATATAGTAAATCTAAAATGGCAGCATATTACTAAGTTATGTTTATAAATAGGATATATATACTTTTTGAGCCCTTTATTTGGGGACCAAGTCATACAAAATACTCTACTGTTTAAGATTTTAAAAAAGGTCCCTGTGATTCTTTCAATAACTAAATGTCCCATGGATGTGGTCTGGGACAGGCCTAGTTGTCTTACAGTCTGATTTATGGTATTAATGACAAAGTTGAGAGGCACATTTCATTTTT"; -*/ + size_t const len_ref = strlen(reference); + size_t const len_obs = strlen(observed); + eq_count = 0; + //Graph2 graph = build(len_ref, reference, len_obs, observed, 0); + //VA_LCS_Node2* lcs_nodes = va_edit2(va_std_allocator, len_ref, reference, len_obs, observed, &(uint32_t) {0}); + VA_LCS_Node** lcs_nodes = NULL; + size_t const len_lcs = va_edit(va_std_allocator, len_ref, reference, len_obs, observed, &lcs_nodes); + Graph graph = build_graph(va_std_allocator, len_ref, len_obs, len_lcs, lcs_nodes, 0, false); + printf("nodes: %zu\nedges: %zu\n", va_array_length(graph.nodes), va_array_length(graph.edges)); + printf("%zu\n", eq_count); + return 0; + if (argc == 2) { From ab61df2bff49eb1c8fd4d6530816f9a8b3f34284 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 29 May 2025 09:14:05 +0200 Subject: [PATCH 207/704] WIP: compare old vs new --- include/edit.h | 1 - src/edit.c | 4 ++-- src/graph.c | 8 ++++++++ src/graph2.c | 34 ++++++++++++++++++---------------- src/main.c | 23 +++++++++++++++++++---- 5 files changed, 47 insertions(+), 23 deletions(-) diff --git a/include/edit.h b/include/edit.h index 81864a7..dc96446 100644 --- a/include/edit.h +++ b/include/edit.h @@ -19,7 +19,6 @@ typedef struct uint32_t length; uint32_t incoming; uint32_t idx; - uint32_t x; } VA_LCS_Node; diff --git a/src/edit.c b/src/edit.c index 3ace6ac..3c5d9cb 100644 --- a/src/edit.c +++ b/src/edit.c @@ -170,7 +170,7 @@ expand(Context const context, { context.lcs_nodes[lcs_pos] = va_array_init(context.allocator, 256, sizeof(*context.lcs_nodes[lcs_pos])); } // if - va_array_append(context.allocator, context.lcs_nodes[lcs_pos], ((VA_LCS_Node) {match_row, match_col, length, -1, -1, length})); + va_array_append(context.allocator, context.lcs_nodes[lcs_pos], ((VA_LCS_Node) {match_row, match_col, length, -1, -1})); matching = false; } // if row += 1; @@ -203,7 +203,7 @@ expand(Context const context, { context.lcs_nodes[lcs_pos] = va_array_init(context.allocator, 256, sizeof(*context.lcs_nodes[lcs_pos])); } // if - va_array_append(context.allocator, context.lcs_nodes[lcs_pos], ((VA_LCS_Node) {match_row, match_col, length, -1, -1, length})); + va_array_append(context.allocator, context.lcs_nodes[lcs_pos], ((VA_LCS_Node) {match_row, match_col, length, -1, -1})); } // if return steps; diff --git a/src/graph.c b/src/graph.c index 0360f1f..45996bb 100644 --- a/src/graph.c +++ b/src/graph.c @@ -89,6 +89,9 @@ build_graph(VA_Allocator const allocator, VA_LCS_Node* const heads = lcs_nodes[len_lcs - 1]; for (size_t i = 0; i < va_array_length(heads); ++i) { + eq_count += 1; + fprintf(stderr, "(%u, %u, %u) vs (%u, %u, %u)\n", heads[i].row, heads[i].col, heads[i].length, sink.row, sink.col, sink.length); + if (heads[i].row + heads[i].length < sink.row + sink.length && heads[i].col + heads[i].length < sink.col + sink.length) { VA_Variant const variant = {heads[i].row + heads[i].length, sink.row + sink.length - 1, heads[i].col + heads[i].length - shift, sink.col + sink.length - 1 - shift}; @@ -100,6 +103,7 @@ build_graph(VA_Allocator const allocator, graph.nodes[heads[i].idx].edges = add_edge(allocator, &graph, sink.idx, graph.nodes[heads[i].idx].edges, variant); if (debug) printf("MAKE EDGE (%u %u %u) -> (%u %u %u): " VAR_FMT "\n", heads[i].row, heads[i].col, heads[i].length, sink.row, sink.col, sink.length, print_variant(variant, "0123456789")); + here = i + 1; } // if } // for @@ -128,6 +132,7 @@ build_graph(VA_Allocator const allocator, for (size_t k = 0; k < va_array_length(heads); ++k) { eq_count += 1; + fprintf(stderr, "(%u, %u, %u) vs (%u, %u, %u)\n", heads[k].row, heads[k].col, heads[k].length, tail.row, tail.col, tail.length); if (heads[k].row + heads[k].length < tail.row + tail.length && heads[k].col + heads[k].length < tail.col + tail.length) @@ -222,6 +227,9 @@ build_graph(VA_Allocator const allocator, continue; } // if + eq_count += 1; + fprintf(stderr, "(%u, %u, %u) vs (%u, %u, %u)\n", source.row, source.col, source.length, lcs_nodes[0][i].row, lcs_nodes[0][i].col, lcs_nodes[0][i].length); + if (source.row < lcs_nodes[0][i].row + lcs_nodes[0][i].length && source.col < lcs_nodes[0][i].col + lcs_nodes[0][i].length) { max_sink = MAX(max_sink, lcs_nodes[0][i].row + lcs_nodes[0][i].length - 1); diff --git a/src/graph2.c b/src/graph2.c index 442b869..e0c89f0 100644 --- a/src/graph2.c +++ b/src/graph2.c @@ -107,8 +107,8 @@ bfs_traversal2(Graph2 const graph, size_t const len_obs, char const observed[sta } // if count += 1; VA_Variant variant; - uint32_t const count2 = edges2(((VA_LCS_Node) {graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, 0, 0, 0}), - ((VA_LCS_Node) {graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length, 0, 0, 0}), + uint32_t const count2 = edges2(((VA_LCS_Node) {graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, 0, 0}), + ((VA_LCS_Node) {graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length, 0, 0}), graph.nodes[head].row == graph.nodes[graph.source].row && graph.nodes[head].col == graph.nodes[graph.source].col, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, &variant); for (uint32_t k = 0; k < count2; ++k) @@ -176,9 +176,9 @@ print_graph(Graph2 const graph, size_t const len_obs, char const observed[static fprintf(stderr, " %u: (%u, %u, %u): ", graph.edges[j].tail, graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length); VA_Variant variant; uint32_t const count = edges2( - ((VA_LCS_Node) {graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, 0, 0, 0}), + ((VA_LCS_Node) {graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, 0, 0}), ((VA_LCS_Node) {graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, - graph.nodes[graph.edges[j].tail].length, 0, 0, 0}), + graph.nodes[graph.edges[j].tail].length, 0, 0}), i == graph.source, graph.nodes[graph.edges[j].tail].edges == GVA_NULL && graph.nodes[graph.edges[j].tail].edges == GVA_NULL, &variant); @@ -211,8 +211,8 @@ split(VA_LCS_Node2 const* const node, Node2 const* const tail = &graph->nodes[graph->edges[j].tail]; VA_Variant outgoing; uint32_t const out_count = edges2( - (VA_LCS_Node) {node->row, node->col, node->length, -1, GVA_NULL, 0}, - (VA_LCS_Node) {tail->row, tail->col, tail->length, -1, GVA_NULL, 0}, false, tail->edges == GVA_NULL && tail->lambda == GVA_NULL, &outgoing); + (VA_LCS_Node) {node->row, node->col, node->length, -1, GVA_NULL}, + (VA_LCS_Node) {tail->row, tail->col, tail->length, -1, GVA_NULL}, false, tail->edges == GVA_NULL && tail->lambda == GVA_NULL, &outgoing); //fprintf(stderr, " %u: (%u, %u, %u): x %u ", graph->edges[j].tail, tail->row, tail->col, tail->length, out_count); // TODO: can we avoid reordering the tail list? Yes? XOR-linked? @@ -380,13 +380,12 @@ build(size_t const len_ref, char const reference[static restrict len_ref], return graph; } // if -/* for (size_t i = 0; i < va_array_length(lcs_nodes); ++i) { fprintf(stderr, "%2zu: (%u, %u, %u) %u %2d %2d\n", i, lcs_nodes[i].row, lcs_nodes[i].col, lcs_nodes[i].length, lcs_nodes[i].lcs_pos, lcs_nodes[i].next, lcs_nodes[i].inext); } // for - fprintf(stderr, "%u\n", last_idx); -*/ + fprintf(stderr, "last: %u\n", last_idx); + VA_LCS_Node2 source = {shift, shift, 0, -1, GVA_NULL, GVA_NULL, GVA_NULL, -1}; bool found_source = false; size_t const len = va_array_length(lcs_nodes); @@ -420,6 +419,9 @@ build(size_t const len_ref, char const reference[static restrict len_ref], source.outgoing = head->outgoing; } // if + eq_count += 1; + fprintf(stderr, "(%u, %u, %u) vs (%u, %u, %u)\n", head->row, head->col, head->length, sink.row, sink.col, sink.length); + /* VA_Variant variant; uint32_t const count = edges3(head, &sink, head->row == shift && head->col == shift, true, &variant); @@ -447,8 +449,6 @@ build(size_t const len_ref, char const reference[static restrict len_ref], lcs_nodes[lcs_nodes[idx].next].inext = lcs_nodes[idx].inext; } // if - eq_count += 1; - if (tail->idx == GVA_NULL) { continue; @@ -458,14 +458,15 @@ build(size_t const len_ref, char const reference[static restrict len_ref], uint32_t split_point = -1; uint32_t const lcs_low = tail->length > tail->lcs_pos ? 0 : tail->lcs_pos - tail->length; - //fprintf(stderr, "(%u, %u, %u) @ %u low: %u\n", tail->row, tail->col, tail->length, tail->lcs_pos, lcs_low); for (uint32_t j = last_idx; j != GVA_NULL && lcs_nodes[j].lcs_pos >= lcs_low; j = lcs_nodes[j].next) { - //fprintf(stderr, " %u: (%u, %u, %u) @ %u\n", j, lcs_nodes[j].row, lcs_nodes[j].col, lcs_nodes[j].length, lcs_nodes[j].lcs_pos); VA_LCS_Node2* const head = &lcs_nodes[j]; bool const is_source = head->row == shift && head->col == shift; + eq_count += 1; + fprintf(stderr, "(%u, %u, %u) vs (%u, %u, %u)\n", head->row, head->col, head->length, tail->row, tail->col, tail->length); + VA_Variant variant; uint32_t const count = edges3(head, tail, is_source, is_sink, &variant); if (count == 0) @@ -495,7 +496,7 @@ build(size_t const len_ref, char const reference[static restrict len_ref], head->outgoing = MIN(head->outgoing, variant.start); source.outgoing = MIN(source.outgoing, variant.start); -/* +/* NO SPLIT NODES va_array_append(va_std_allocator, graph.edges, ((Edge2) {tail->idx, graph.nodes[head->idx].edges})); graph.nodes[head->idx].edges = va_array_length(graph.edges); */ @@ -503,6 +504,9 @@ build(size_t const len_ref, char const reference[static restrict len_ref], if (!found_source && tail->length > tail->lcs_pos) { + eq_count += 1; + fprintf(stderr, "(%u, %u, %u) vs (%u, %u, %u)\n", source.row, source.col, source.length, tail->row, tail->col, tail->length); + if (source.idx == GVA_NULL) { va_array_append(va_std_allocator, graph.nodes, ((Node2) {source.row, source.col, source.length, GVA_NULL, GVA_NULL})); @@ -518,8 +522,6 @@ build(size_t const len_ref, char const reference[static restrict len_ref], fprintf(stderr, "(%u, %u, %u) -> (%u, %u, %u) " VAR_FMT " x %u\n", source.row, source.col, source.length, tail->row, tail->col, tail->length, print_variant(variant, observed), count); */ } // if - //fprintf(stderr, "\n"); - } // for lcs_nodes = va_array_destroy(va_std_allocator, lcs_nodes); diff --git a/src/main.c b/src/main.c index da26e9b..d8953f8 100644 --- a/src/main.c +++ b/src/main.c @@ -151,7 +151,7 @@ print_graph(Graph const graph, size_t const len_obs, char const observed[static int main(int argc, char* argv[static argc + 1]) { - +/* (void) argv; char const* const restrict reference = "ATTCTATCTTCTGTCTACATAAGATGTCATACTAGAGGGCATATCTGCAATGTATACATATTATCTTTTCCAGCATGCATTCAGTTGTGTTGGAATAATTTATGTACACCTTTATAAACGCTGAGCCTCACAAGAGCCATGTGCCACGTATTGTTTTCTTACTACTTTTTGGGATACCTGGCACGTAATAGACACTCATTGAAAGTTTCCTAATGAATGAAGTACAAAGATAAAACAAGTTATAGACTGATTCTTTTGAGCTGTCAAGGTTGTAAATAGACTTTTGCTCAATCAATTCAAATGGTGGCAGGTAGTGGGGGTAGAGGGATTGGTATGAAAAACATAAGCTTTCAGAACTCCTGTGTTTATTTTTAGAATGTCAACTGCTTGAGTGTTTTTAACTCTGTGGTATCTGAACTATCTTCTCTAACTGCAGGTTGGGCTCAGATCTGTGATAGAACAGTTTCCTGGGAAGCTTGACTTTGTCCTTGTGGATGGGGGCTGTGTCCTAAGCCATGGCCACAAGCAGTTGATGTGCTTGGCTAGATCTGTTCTCAGTAAGGCGAAGATCTTGCTGCTTGATGAACCCAGTGCTCATTTGGATCCAGTGTGAGTTTCAGATGTTCTGTTACTTAATAGCACAGTGGGAACAGAATCATTATGCCTGCTTCATGGTGACACATATTTCTATTAGGCTGTCATGTCTGCGTGTGGGGGTCTCCCCCAAGATATGAAATAATTGCCCAGTGGAAATGAGCATAAATGCATATTTCCTTGCTAAGAGTCTTGTGTTTTCTTCCGAAGATAGTTTTTAGTTTCATACAAACTCTTCCCCCTTGTCAACACATGATGAAGCTTTTAAATACATGGGCCTAATCTGATCCTTATGATTTGCCTTTGTATCCCATTTATACCATAAGCATGTTTATAGCCCCAAATAAAGAAGTACTGGTGATTCTACATAATGAAAAATGTACTCATTTATTAAAGTTTCTTTGAAATATTTGTCCTGTTTATTTATGGATACTTAGAGTCTACCCCATGGTTGAAAAGCTGATTGTGGCTAACGCTATATCAACATTATGTGAAAAGAACTTAAAGAAATAAGTAATTTAAAGAGATAATAGAACAATAGACATATTATCAAGGTAAATACAGATCATTACTGTTCTGTGATATTATGTGTGGTATTTTCTTTCTTTTCTAGAACATACCAAATAATTAGAAGAACTCTAAAACAAGCATTTGCTGATTGCACAGTAATTCTCTGTGAACACAGGATAGAAGCAATGCTGGAATGCCAACAATTTTTGGTGAGTCTTTATAACTTTACTTAAGATCTCATTGCCCTTGTAATTCTTGATAACAATCTCACATGTGATAGTTCCTGCAAATTGCAACAATGTACAAGTTCTTTTCAAAAATATGTATCATACAGCCATCCAGCTTTACTCAAAATAGCTGCACAAGTTTTTCACTTTGATCTGAGCCATGTGGTGAGGTTGAAATATAGTAAATCTAAAATGGCAGCATATTACTAAGTTATGTTTATAAATAGGATATATATACTTTTTGAGCCCTTTATTTGGGGACCAAGTCATACAAAATACTCTACTGTTTAAGATTTTAAAAAAGGTCCCTGTGATTCTTTCAATAACTAAATGTCCCATGGATGTGGTCTGGGACAGGCCTAGTTGTCTTACAGTCTGATTTATGGTATTAATGACAAAGTTGAGAGGCACATTTCATTTTT"; char const* const restrict observed = "ATTCTATCTTCTGTCTACATAAGATGTCATACTAGAGGGCATATCTGCAATGTATACATATTATCTTTTCCAGCATGCATTCAGTTGTGTTGGAATAATTTATGTACACCTTTATAAACGCTGAGCCTCACAAGAGCCATGTGCCACGTATTGTTTTCTTACTACTTTTTGGGATACCTGGCACGTAATAGACACTCATTGAAAGTTTCCTAATGAATGAAGTACAAAGATAAAACAAGTTATAGACTGATTCTTTTGAGCTGTCAAGGTTGTAAATAGACTTTTGCTCAATCAATTCAAATGGTGGCAGGTAGTGGGGGTAGAGGGATTGGTATGAAAAACATAAGCTTTCAGAACTCCTGTGTTTATTTTTAGAATGTCAACTGCTTGAGTGTTTTTAACTCTGTGGTATCTGAACTATCTTCTCTAACTGCAGGTGAGTCTTTATAACTTTACTTAAGATCTCATTGCCCTTGTAATTCTTGATAACAATCTCACATGTGATAGTTCCTGCAAATTGCAACAATGTACAAGTTCTTTTCAAAAATATGTATCATACAGCCATCCAGCTTTACTCAAAATAGCTGCACAAGTTTTTCACTTTGATCTGAGCCATGTGGTGAGGTTGAAATATAGTAAATCTAAAATGGCAGCATATTACTAAGTTATGTTTATAAATAGGATATATATACTTTTTGAGCCCTTTATTTGGGGACCAAGTCATACAAAATACTCTACTGTTTAAGATTTTAAAAAAGGTCCCTGTGATTCTTTCAATAACTAAATGTCCCATGGATGTGGTCTGGGACAGGCCTAGTTGTCTTACAGTCTGATTTATGGTATTAATGACAAAGTTGAGAGGCACATTTCATTTTT"; @@ -166,7 +166,7 @@ main(int argc, char* argv[static argc + 1]) printf("nodes: %zu\nedges: %zu\n", va_array_length(graph.nodes), va_array_length(graph.edges)); printf("%zu\n", eq_count); return 0; - +*/ if (argc == 2) { @@ -193,17 +193,32 @@ main(int argc, char* argv[static argc + 1]) char const* const restrict observed = argv[2]; size_t const len_ref = strlen(reference); size_t const len_obs = strlen(observed); + eq_count = 0; //check(len_ref, reference, len_obs, observed, true); Graph2 graph2 = build(len_ref, reference, len_obs, observed, 0); - to_json2(graph2, len_obs, observed); + fprintf(stderr, "count: %zu\n", eq_count); + + //to_json2(graph2, len_obs, observed); VA_LCS_Node** lcs_nodes = NULL; size_t const len_lcs = va_edit(va_std_allocator, len_ref, reference, len_obs, observed, &lcs_nodes); + for (size_t i = 0; i < len_lcs; ++i) + { + fprintf(stderr, "%zu: ", i); + for (size_t j = 0; j < va_array_length(lcs_nodes[i]); ++j) + { + fprintf(stderr, "(%u, %u, %u) ", lcs_nodes[i][j].row, lcs_nodes[i][j].col, lcs_nodes[i][j].length); + } // for + fprintf(stderr, "\n"); + } // for + + eq_count = 0; Graph graph = build_graph(va_std_allocator, len_ref, len_obs, len_lcs, lcs_nodes, 0, false); + fprintf(stderr, "count: %zu\n", eq_count); - print_graph(graph, len_obs, observed); + //print_graph(graph, len_obs, observed); // to_dot(graph, len_obs, observed); // to_json(graph, len_obs, observed, false); From f333db00b96c62ad08ec29aefe93c0e5ab712d68 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 29 May 2025 11:28:18 +0200 Subject: [PATCH 208/704] WIP: more on compare --- include/edit.h | 12 ++++++-- src/edit2.c | 79 +++++++++++++++++++++++--------------------------- src/graph2.c | 47 ++++++++++++++++++------------ 3 files changed, 76 insertions(+), 62 deletions(-) diff --git a/include/edit.h b/include/edit.h index dc96446..2e554e2 100644 --- a/include/edit.h +++ b/include/edit.h @@ -35,6 +35,13 @@ typedef struct } VA_LCS_Node2; +typedef struct +{ + uint32_t head; + uint32_t tail; +} VA_LCS_List; + + size_t va_edit_distance_only(VA_Allocator const allocator, size_t const len_ref, @@ -52,11 +59,12 @@ va_edit(VA_Allocator const allocator, VA_LCS_Node*** restrict lcs_nodes); -VA_LCS_Node2* +size_t va_edit2(VA_Allocator const allocator, size_t const len_ref, char const reference[static restrict len_ref], size_t const len_obs, char const observed[static restrict len_obs], - uint32_t* const restrict head); + VA_LCS_List** restrict lcs_index, + VA_LCS_Node2** restrict lcs_nodes); #ifdef __cplusplus diff --git a/src/edit2.c b/src/edit2.c index a3a5a99..185e830 100644 --- a/src/edit2.c +++ b/src/edit2.c @@ -29,8 +29,6 @@ typedef struct size_t const len_obs; char const* const restrict observed; size_t* const restrict diagonals; - uint32_t* const restrict head; - uint32_t* const restrict tail; } Context; @@ -39,7 +37,7 @@ expand(Context const context, ptrdiff_t const idx, size_t const p, size_t* const len_lcs, - uint32_t* head, + VA_LCS_List lcs_index[static restrict 1], VA_LCS_Node2** lcs_nodes) { ptrdiff_t const delta = context.len_obs - context.len_ref; @@ -90,16 +88,15 @@ expand(Context const context, ptrdiff_t const d_col = context.len_obs - col; size_t const lcs_pos = (row + col - imaxabs(delta) - 2 * p + imaxabs(d_row - d_col)) / 2 - 1; size_t const length = row - match_row; - va_array_append(context.allocator, *lcs_nodes, ((VA_LCS_Node2) {match_row, match_col, length, lcs_pos, context.tail[lcs_pos], -1, -1, -1})); - context.tail[lcs_pos] = va_array_length(*lcs_nodes) - 1; - if (lcs_pos + 1 >= *len_lcs) + va_array_append(context.allocator, *lcs_nodes, ((VA_LCS_Node2) {match_row, match_col, length, lcs_pos, lcs_index[lcs_pos].tail, -1, -1, -1})); + lcs_index[lcs_pos].tail = va_array_length(*lcs_nodes) - 1; + if (lcs_pos + 1 > *len_lcs) { *len_lcs = lcs_pos + 1; - *head = context.tail[lcs_pos]; } // if - if (context.head[lcs_pos] == (uint32_t) -1) + if (lcs_index[lcs_pos].head == (uint32_t) -1) { - context.head[lcs_pos] = context.tail[lcs_pos]; + lcs_index[lcs_pos].head = lcs_index[lcs_pos].tail; } // if matching = false; } // if @@ -125,16 +122,15 @@ expand(Context const context, ptrdiff_t const d_col = context.len_obs - col; size_t const lcs_pos = (row + col - imaxabs(delta) - 2 * p + imaxabs(d_row - d_col)) / 2 - 1; size_t const length = row - match_row; - va_array_append(context.allocator, *lcs_nodes, ((VA_LCS_Node2) {match_row, match_col, length, lcs_pos, context.tail[lcs_pos], -1, -1, -1})); - context.tail[lcs_pos] = va_array_length(*lcs_nodes) - 1; - if (lcs_pos + 1 >= *len_lcs) + va_array_append(context.allocator, *lcs_nodes, ((VA_LCS_Node2) {match_row, match_col, length, lcs_pos, lcs_index[lcs_pos].tail, -1, -1, -1})); + lcs_index[lcs_pos].tail = va_array_length(*lcs_nodes) - 1; + if (lcs_pos + 1 > *len_lcs) { *len_lcs = lcs_pos + 1; - *head = context.tail[lcs_pos]; } // if - if (context.head[lcs_pos] == (uint32_t) -1) + if (lcs_index[lcs_pos].head == (uint32_t) -1) { - context.head[lcs_pos] = context.tail[lcs_pos]; + lcs_index[lcs_pos].head = lcs_index[lcs_pos].tail; } // if } // if @@ -142,11 +138,12 @@ expand(Context const context, } // expand -VA_LCS_Node2* +size_t va_edit2(VA_Allocator const allocator, size_t const len_ref, char const reference[static restrict len_ref], size_t const len_obs, char const observed[static restrict len_obs], - uint32_t* const restrict head) + VA_LCS_List** restrict lcs_index, + VA_LCS_Node2** restrict lcs_nodes) { ptrdiff_t const delta = len_obs - len_ref; size_t const offset = len_ref + 1; @@ -160,15 +157,17 @@ va_edit2(VA_Allocator const allocator, len_obs, observed, .diagonals = allocator.alloc(allocator.context, NULL, 0, size * sizeof(*context.diagonals)), - .head = allocator.alloc(allocator.context, NULL, 0, umin(len_ref, len_obs) * sizeof(*context.head)), - .tail = allocator.alloc(allocator.context, NULL, 0, umin(len_ref, len_obs) * sizeof(*context.tail)), }; - if (context.diagonals == NULL || context.head == NULL || context.tail == NULL) + if (context.diagonals == NULL) { - allocator.alloc(allocator.context, context.diagonals, size * sizeof(*context.diagonals), 0); - allocator.alloc(allocator.context, context.head, umin(len_ref, len_obs) * sizeof(*context.head), 0); - allocator.alloc(allocator.context, context.tail, umin(len_ref, len_obs) * sizeof(*context.tail), 0); - return NULL; + return -1; + } // if + + *lcs_index = allocator.alloc(allocator.context, NULL, 0, umin(len_ref, len_obs) * sizeof(**lcs_index)); + if (*lcs_index == NULL) + { + allocator.alloc(allocator.context, NULL, 0, size * sizeof(*context.diagonals)); + return -1; } // if for (size_t i = 0; i < size; ++i) @@ -178,55 +177,51 @@ va_edit2(VA_Allocator const allocator, for (size_t i = 0; i < umin(len_ref, len_obs); ++i) { - context.head[i] = -1; - context.tail[i] = -1; + (*lcs_index)[i].head = -1; + (*lcs_index)[i].tail = -1; } // for - *head = -1; - VA_LCS_Node2* lcs_nodes = NULL; - size_t const lower = delta > 0 ? 0 : delta; size_t const upper = delta > 0 ? delta : 0; size_t const len = umax(len_ref, len_obs) - imaxabs(delta); size_t p = 0; - size_t max_lcs_pos = 0; + size_t len_lcs = 0; while (context.diagonals[offset + delta] <= len) { for (ptrdiff_t idx = lower - p; idx < delta; ++idx) { - context.diagonals[offset + idx] = expand(context, idx, p, &max_lcs_pos, head, &lcs_nodes); + context.diagonals[offset + idx] = expand(context, idx, p, &len_lcs, *lcs_index, lcs_nodes); } // for for (ptrdiff_t idx = upper + p; idx > delta; --idx) { - context.diagonals[offset + idx] = expand(context, idx, p, &max_lcs_pos, head, &lcs_nodes); + context.diagonals[offset + idx] = expand(context, idx, p, &len_lcs, *lcs_index, lcs_nodes); } // for - context.diagonals[offset + delta] = expand(context, delta, p, &max_lcs_pos, head, &lcs_nodes); + context.diagonals[offset + delta] = expand(context, delta, p, &len_lcs, *lcs_index, lcs_nodes); p += 1; } // while uint32_t prev = 0; - for (size_t i = 1; i < max_lcs_pos; ++i) + for (size_t i = 1; i < len_lcs; ++i) { - if (context.head[i] != (uint32_t) -1) + if ((*lcs_index)[i].head != (uint32_t) -1) { - lcs_nodes[context.head[i]].next = context.tail[prev]; + (*lcs_nodes)[(*lcs_index)[i].head].next = (*lcs_index)[prev].tail; prev = i; } // if } // for - for (uint32_t i = 0; i < va_array_length(lcs_nodes); ++i) + for (uint32_t i = 0; i < va_array_length(*lcs_nodes); ++i) { - if (lcs_nodes[i].next != (uint32_t) -1) + if ((*lcs_nodes)[i].next != (uint32_t) -1) { - lcs_nodes[lcs_nodes[i].next].inext = i; + (*lcs_nodes)[(*lcs_nodes)[i].next].inext = i; } // if } // for allocator.alloc(allocator.context, context.diagonals, size * sizeof(*context.diagonals), 0); - allocator.alloc(allocator.context, context.head, size * sizeof(*context.head), 0); - allocator.alloc(allocator.context, context.tail, size * sizeof(*context.tail), 0); + *lcs_index = allocator.alloc(allocator.context, *lcs_index, umin(len_ref, len_obs) * sizeof(**lcs_index), len_lcs * sizeof(**lcs_index)); - return lcs_nodes; + return len_lcs; } // va_edit2 diff --git a/src/graph2.c b/src/graph2.c index e0c89f0..0cffd3e 100644 --- a/src/graph2.c +++ b/src/graph2.c @@ -359,8 +359,9 @@ build(size_t const len_ref, char const reference[static restrict len_ref], size_t const len_obs, char const observed[static restrict len_obs], size_t const shift) { - uint32_t last_idx = -1; - VA_LCS_Node2* lcs_nodes = va_edit2(va_std_allocator, len_ref, reference, len_obs, observed, &last_idx); + VA_LCS_List* lcs_index = NULL; + VA_LCS_Node2* lcs_nodes = NULL; + size_t const len_lcs = va_edit2(va_std_allocator, len_ref, reference, len_obs, observed, &lcs_index, &lcs_nodes); Graph2 graph = {NULL, NULL, GVA_NULL}; @@ -384,7 +385,21 @@ build(size_t const len_ref, char const reference[static restrict len_ref], { fprintf(stderr, "%2zu: (%u, %u, %u) %u %2d %2d\n", i, lcs_nodes[i].row, lcs_nodes[i].col, lcs_nodes[i].length, lcs_nodes[i].lcs_pos, lcs_nodes[i].next, lcs_nodes[i].inext); } // for - fprintf(stderr, "last: %u\n", last_idx); + for (size_t i = 0; i < len_lcs; ++i) + { + fprintf(stderr, "%zu: ", i); + for (uint32_t j = lcs_index[i].tail; j != GVA_NULL; j = lcs_nodes[j].next) + { + fprintf(stderr, "(%u, %u, %u) ", lcs_nodes[j].row, lcs_nodes[j].col, lcs_nodes[j].length); + if (j == lcs_index[i].head) + { + break; + } // if + } // for + fprintf(stderr, "\n"); + } // for + + uint32_t last_idx = lcs_index[len_lcs - 1].tail; VA_LCS_Node2 source = {shift, shift, 0, -1, GVA_NULL, GVA_NULL, GVA_NULL, -1}; bool found_source = false; @@ -422,14 +437,11 @@ build(size_t const len_ref, char const reference[static restrict len_ref], eq_count += 1; fprintf(stderr, "(%u, %u, %u) vs (%u, %u, %u)\n", head->row, head->col, head->length, sink.row, sink.col, sink.length); -/* - VA_Variant variant; - uint32_t const count = edges3(head, &sink, head->row == shift && head->col == shift, true, &variant); - fprintf(stderr, "(%u, %u, %u) -> (%u, %u, %u) " VAR_FMT " x %u\n", head->row, head->col, head->length, sink.row, sink.col, sink.length, print_variant(variant, observed), count); -*/ + //VA_Variant variant; + //uint32_t const count = edges3(head, &sink, head->row == shift && head->col == shift, true, &variant); + //fprintf(stderr, "(%u, %u, %u) -> (%u, %u, %u) " VAR_FMT " x %u\n", head->row, head->col, head->length, sink.row, sink.col, sink.length, print_variant(variant, observed), count); } // for } // else -// fprintf(stderr, "\n"); for (size_t i = 0; i < len; ++i) { @@ -496,10 +508,10 @@ build(size_t const len_ref, char const reference[static restrict len_ref], head->outgoing = MIN(head->outgoing, variant.start); source.outgoing = MIN(source.outgoing, variant.start); -/* NO SPLIT NODES - va_array_append(va_std_allocator, graph.edges, ((Edge2) {tail->idx, graph.nodes[head->idx].edges})); - graph.nodes[head->idx].edges = va_array_length(graph.edges); -*/ +// NO SPLIT NODES +// va_array_append(va_std_allocator, graph.edges, ((Edge2) {tail->idx, graph.nodes[head->idx].edges})); +// graph.nodes[head->idx].edges = va_array_length(graph.edges); + } // for if (!found_source && tail->length > tail->lcs_pos) @@ -516,15 +528,14 @@ build(size_t const len_ref, char const reference[static restrict len_ref], va_array_append(va_std_allocator, graph.edges, ((Edge2) {tail->idx, graph.nodes[source.idx].edges})); graph.nodes[source.idx].edges = va_array_length(graph.edges) - 1; -/* - VA_Variant variant; - uint32_t const count = edges3(&source, tail, true, is_sink, &variant); - fprintf(stderr, "(%u, %u, %u) -> (%u, %u, %u) " VAR_FMT " x %u\n", source.row, source.col, source.length, tail->row, tail->col, tail->length, print_variant(variant, observed), count); -*/ + //VA_Variant variant; + //uint32_t const count = edges3(&source, tail, true, is_sink, &variant); + //fprintf(stderr, "(%u, %u, %u) -> (%u, %u, %u) " VAR_FMT " x %u\n", source.row, source.col, source.length, tail->row, tail->col, tail->length, print_variant(variant, observed), count); } // if } // for lcs_nodes = va_array_destroy(va_std_allocator, lcs_nodes); + va_std_allocator.alloc(va_std_allocator.context, lcs_index, len_lcs * sizeof(*lcs_index), 0); //fprintf(stderr, "SOURCE first outgoing edge at %d\n", source.outgoing); if (source.outgoing != (uint32_t) -1) From e0e878ded25399ddb5763a95094d6faf64b476c0 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 29 May 2025 18:04:51 +0200 Subject: [PATCH 209/704] Fix zero length strings --- regres.sh | 3 ++- src/edit.c | 6 ++++++ src/edit2.c | 7 +++++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/regres.sh b/regres.sh index 1f2dea7..ca93436 100755 --- a/regres.sh +++ b/regres.sh @@ -33,5 +33,6 @@ AGAGAAAAA AAAA ) for ((i=0; i<${#TESTS[@]}; i+=2)); do - python test.py "${TESTS[i]}" "${TESTS[i+1]}" + #python test.py "${TESTS[i]}" "${TESTS[i+1]}" + valgrind ./a.out "${TESTS[i]}" "${TESTS[i+1]}" done diff --git a/src/edit.c b/src/edit.c index 3c5d9cb..e977d4d 100644 --- a/src/edit.c +++ b/src/edit.c @@ -222,6 +222,12 @@ va_edit(VA_Allocator const allocator, size_t const offset = len_ref + 1; size_t const size = len_ref + len_obs + 3; + *lcs_nodes = NULL; + if (len_ref == 0 || len_obs == 0) + { + return 0; + } // if + Context const context = { allocator, diff --git a/src/edit2.c b/src/edit2.c index 185e830..72d1f07 100644 --- a/src/edit2.c +++ b/src/edit2.c @@ -149,6 +149,13 @@ va_edit2(VA_Allocator const allocator, size_t const offset = len_ref + 1; size_t const size = len_ref + len_obs + 3; + *lcs_index = NULL; + *lcs_nodes = NULL; + if (len_ref == 0 || len_obs == 0) + { + return 0; + } // if + Context const context = { allocator, From 4c8d419733c709eca9a9ac14bc9e3564164bcade Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 3 Jun 2025 17:05:19 +0200 Subject: [PATCH 210/704] WIP: build3 --- include/edit.h | 35 +++++++- include/graph.h | 7 ++ regres.sh | 4 +- src/edit3.c | 217 ++++++++++++++++++++++++++++++++++++++++++++++++ src/graph.c | 198 ++++++++++++++++++++++++++++++++++++++----- src/graph2.c | 28 +++++-- src/main.c | 26 ++++-- 7 files changed, 473 insertions(+), 42 deletions(-) create mode 100644 src/edit3.c diff --git a/include/edit.h b/include/edit.h index 2e554e2..952951a 100644 --- a/include/edit.h +++ b/include/edit.h @@ -12,6 +12,13 @@ extern "C" #include "alloc.h" // VA_Allocator +typedef struct +{ + uint32_t head; + uint32_t tail; +} VA_LCS_List; + + typedef struct { uint32_t row; @@ -37,9 +44,31 @@ typedef struct typedef struct { - uint32_t head; - uint32_t tail; -} VA_LCS_List; + uint32_t row; + uint32_t col; + uint32_t length; + uint32_t incoming; + uint32_t idx; + uint32_t next; +} VA_LCS_Node3; + + +typedef struct +{ + size_t length; + struct + { + uint32_t head; + uint32_t tail; + }* index; + VA_LCS_Node3* nodes; +} VA_LCS; + + +VA_LCS +va_edit3(VA_Allocator const allocator, + size_t const len_ref, char const reference[static restrict len_ref], + size_t const len_obs, char const observed[static restrict len_obs]); size_t diff --git a/include/graph.h b/include/graph.h index 00601f2..20d8c88 100644 --- a/include/graph.h +++ b/include/graph.h @@ -31,6 +31,13 @@ typedef struct } Graph; +Graph +build3(VA_Allocator const allocator, + size_t const len_ref, char const reference[static restrict len_ref], + size_t const len_obs, char const observed[static restrict len_obs], + size_t const shift); + + Graph build_graph(VA_Allocator const allocator, size_t const len_ref, size_t const len_obs, diff --git a/regres.sh b/regres.sh index ca93436..4d5f0bb 100755 --- a/regres.sh +++ b/regres.sh @@ -33,6 +33,6 @@ AGAGAAAAA AAAA ) for ((i=0; i<${#TESTS[@]}; i+=2)); do - #python test.py "${TESTS[i]}" "${TESTS[i+1]}" - valgrind ./a.out "${TESTS[i]}" "${TESTS[i+1]}" + python test.py "${TESTS[i]}" "${TESTS[i+1]}" + #./a.out "${TESTS[i]}" "${TESTS[i+1]}" > /dev/null done diff --git a/src/edit3.c b/src/edit3.c new file mode 100644 index 0000000..b63ca28 --- /dev/null +++ b/src/edit3.c @@ -0,0 +1,217 @@ +#include // imaxabs +#include // bool, false, true +#include // NULL, ptrdiff_t, size_t + + +#include "../include/alloc.h" // VA_Allocator +#include "../include/array.h" // va_array_* +#include "../include/edit.h" + + +typedef struct +{ + VA_Allocator const allocator; + size_t const len_ref; + char const* const restrict reference; + size_t const len_obs; + char const* const restrict observed; + size_t* const restrict diagonals; +} Context; + + +static inline size_t +umax(size_t const a, size_t const b) +{ + return a > b ? a : b; +} // umax + + +static inline size_t +umin(size_t const a, size_t const b) +{ + return a < b ? a : b; +} // umin + + +static size_t +expand(Context const context, + ptrdiff_t const idx, + size_t const p, + VA_LCS* const lcs) +{ + ptrdiff_t const delta = context.len_obs - context.len_ref; + size_t const offset = context.len_ref + 1; + + size_t row; + size_t col; + size_t end; + if (idx > 0) + { + row = context.diagonals[offset + idx]; + col = row + idx; + end = umax(context.diagonals[offset + idx - 1] - 1, context.diagonals[offset + idx + 1]); + } // if + else if (idx < 0) + { + col = context.diagonals[offset + idx]; + row = col - idx; + end = umax(context.diagonals[offset + idx - 1], context.diagonals[offset + idx + 1] - 1); + } // if + else + { + row = context.diagonals[offset + idx]; + col = row + idx; + end = umax(context.diagonals[offset + idx - 1], context.diagonals[offset + idx + 1]); + } // else + + size_t steps = end + 1; + + bool matching = false; + size_t match_row = 0; + size_t match_col = 0; + + for (size_t i = context.diagonals[offset + idx]; i < end; ++i) + { + if (context.reference[row] == context.observed[col]) + { + if (!matching) + { + match_row = row; + match_col = col; + matching = true; + } // if + } // if + else if (matching) + { + ptrdiff_t const d_row = context.len_ref - row; + ptrdiff_t const d_col = context.len_obs - col; + size_t const lcs_pos = (row + col - imaxabs(delta) - 2 * p + imaxabs(d_row - d_col)) / 2 - 1; + size_t const length = row - match_row; + va_array_append(context.allocator, lcs->nodes, ((VA_LCS_Node3) {match_row, match_col, length, -1, -1, -1})); + if (lcs->index[lcs_pos].head != (uint32_t) -1) + { + lcs->nodes[lcs->index[lcs_pos].tail].next = va_array_length(lcs->nodes) - 1; + } // if + else + { + lcs->index[lcs_pos].head = va_array_length(lcs->nodes) - 1; + } // else + lcs->index[lcs_pos].tail = va_array_length(lcs->nodes) - 1; + + if (lcs_pos + 1 > lcs->length) + { + lcs->length = lcs_pos + 1; + } // if + matching = false; + } // if + row += 1; + col += 1; + } // for + + if (!matching) + { + match_row = row; + match_col = col; + } // if + while (row < context.len_ref && col < context.len_obs && context.reference[row] == context.observed[col]) + { + matching = true; + row += 1; + col += 1; + steps += 1; + } // while + if (matching) + { + ptrdiff_t const d_row = context.len_ref - row; + ptrdiff_t const d_col = context.len_obs - col; + size_t const lcs_pos = (row + col - imaxabs(delta) - 2 * p + imaxabs(d_row - d_col)) / 2 - 1; + size_t const length = row - match_row; + va_array_append(context.allocator, lcs->nodes, ((VA_LCS_Node3) {match_row, match_col, length, -1, -1, -1})); + if (lcs->index[lcs_pos].head != (uint32_t) -1) + { + lcs->nodes[lcs->index[lcs_pos].tail].next = va_array_length(lcs->nodes) - 1; + } // if + else + { + lcs->index[lcs_pos].head = va_array_length(lcs->nodes) - 1; + } // else + lcs->index[lcs_pos].tail = va_array_length(lcs->nodes) - 1; + + if (lcs_pos + 1 > lcs->length) + { + lcs->length = lcs_pos + 1; + } // if + } // if + + return steps; +} // expand + + +VA_LCS +va_edit3(VA_Allocator const allocator, + size_t const len_ref, char const reference[static restrict len_ref], + size_t const len_obs, char const observed[static restrict len_obs]) +{ + ptrdiff_t const delta = len_obs - len_ref; + size_t const offset = len_ref + 1; + size_t const size = len_ref + len_obs + 3; + + VA_LCS lcs = {0, NULL, NULL}; + + Context const context = + { + allocator, + len_ref, + reference, + len_obs, + observed, + .diagonals = allocator.alloc(allocator.context, NULL, 0, size * sizeof(*context.diagonals)), + }; + if (context.diagonals == NULL) + { + return lcs; + } // if + + lcs.index = allocator.alloc(allocator.context, NULL, 0, umin(len_ref, len_obs) * sizeof(*lcs.index)); + if (lcs.index == NULL) + { + allocator.alloc(allocator.context, NULL, 0, size * sizeof(*context.diagonals)); + return lcs; + } // if + + for (size_t i = 0; i < size; ++i) + { + context.diagonals[i] = 0; + } // for + + for (size_t i = 0; i < umin(len_ref, len_obs); ++i) + { + lcs.index[i].head = -1; + lcs.index[i].tail = -1; + } // for + + size_t const lower = delta > 0 ? 0 : delta; + size_t const upper = delta > 0 ? delta : 0; + + size_t const len = umax(len_ref, len_obs) - imaxabs(delta); + size_t p = 0; + while (context.diagonals[offset + delta] <= len) + { + for (ptrdiff_t idx = lower - p; idx < delta; ++idx) + { + context.diagonals[offset + idx] = expand(context, idx, p, &lcs); + } // for + for (ptrdiff_t idx = upper + p; idx > delta; --idx) + { + context.diagonals[offset + idx] = expand(context, idx, p, &lcs); + } // for + context.diagonals[offset + delta] = expand(context, delta, p, &lcs); + + p += 1; + } // while + + allocator.alloc(allocator.context, context.diagonals, size * sizeof(*context.diagonals), 0); + lcs.index = allocator.alloc(allocator.context, lcs.index, umin(len_ref, len_obs) * sizeof(*lcs.index), lcs.length * sizeof(*lcs.index)); + + return lcs; +} // va_edit3 diff --git a/src/graph.c b/src/graph.c index 45996bb..024c570 100644 --- a/src/graph.c +++ b/src/graph.c @@ -131,6 +131,13 @@ build_graph(VA_Allocator const allocator, VA_LCS_Node* const heads = lcs_nodes[i - 1]; for (size_t k = 0; k < va_array_length(heads); ++k) { + /* + if (heads[k].idx != GVA_NULL && graph.nodes[heads[k].idx].length != heads[k].length && + tail.length != graph.nodes[tail.idx].length) + { + continue; + } // if + */ eq_count += 1; fprintf(stderr, "(%u, %u, %u) vs (%u, %u, %u)\n", heads[k].row, heads[k].col, heads[k].length, tail.row, tail.col, tail.length); @@ -144,7 +151,7 @@ build_graph(VA_Allocator const allocator, if (heads[k].incoming == i) { if (debug) - printf("SPLIT at %zu\n", i); + fprintf(stderr, "SPLIT at %zu\n", i); uint32_t const split_idx = heads[k].idx; heads[k].idx = add_node(allocator, &graph, heads[k].row, heads[k].col, heads[k].length); if (debug) @@ -167,24 +174,9 @@ build_graph(VA_Allocator const allocator, printf("MAKE NODE %u: (%u, %u, %u)\n", heads[k].idx, heads[k].row, heads[k].col, heads[k].length); } // if - /* - bool found = false; - for (size_t e = graph.nodes[heads[k].idx].edges; e != GVA_NULL; e = graph.edges[e].next) - { - if (graph.edges[e].tail == tail.idx) - { - found = true; - break; - } // if - } // for - if (!found) - */ - - { - graph.nodes[heads[k].idx].edges = add_edge(allocator, &graph, tail.idx, graph.nodes[heads[k].idx].edges, variant); - if (debug) - printf("MAKE EDGE (%u %u %u) -> (%u %u %u): " VAR_FMT "\n", heads[k].row, heads[k].col, heads[k].length, tail.row, tail.col, tail.length, print_variant(variant, "0123456789")); - } // if + graph.nodes[heads[k].idx].edges = add_edge(allocator, &graph, tail.idx, graph.nodes[heads[k].idx].edges, variant); + if (debug) + printf("MAKE EDGE (%u %u %u) -> (%u %u %u): " VAR_FMT "\n", heads[k].row, heads[k].col, heads[k].length, tail.row, tail.col, tail.length, print_variant(variant, "0123456789")); here = k + 1; } // if @@ -263,6 +255,174 @@ build_graph(VA_Allocator const allocator, } // build_graph +Graph +build3(VA_Allocator const allocator, + size_t const len_ref, char const reference[static restrict len_ref], + size_t const len_obs, char const observed[static restrict len_obs], + size_t const shift) +{ + VA_LCS lcs = va_edit3(allocator, len_ref, reference, len_obs, observed); + + Graph graph = {.nodes = NULL, .edges = NULL}; + + if (lcs.length == 0 || lcs.nodes == NULL) + { + graph.source = add_node(allocator, &graph, shift, shift, 0); + if (len_ref == 0 && len_obs == 0) + { + graph.supremal = (VA_Variant) {0, 0, 0, 0}; + return graph; + } // if + uint32_t const sink = add_node(allocator, &graph, len_ref, len_obs, 0); + graph.supremal = (VA_Variant) {shift, shift + len_ref, 0, len_obs}; + graph.nodes[graph.source].edges = add_edge(allocator, &graph, sink, -1, graph.supremal); + return graph; + } // if + + VA_LCS_Node3* sink = &lcs.nodes[lcs.index[lcs.length - 1].tail]; + if (sink->row + sink->length != len_ref + shift || sink->col + sink->length != len_obs + shift) + { + sink = &(VA_LCS_Node3) {.row = len_ref + shift, .col = len_obs + shift, .length = 0}; + } // if + sink->idx = add_node(allocator, &graph, sink->row, sink->col, sink->length); + + for (uint32_t i = lcs.index[lcs.length - 1].head; i != lcs.index[lcs.length - 1].tail; i = lcs.nodes[i].next) + { + eq_count += 1; + fprintf(stderr, "(%u, %u, %u) vs (%u, %u, %u)\n", lcs.nodes[i].row, lcs.nodes[i].col, lcs.nodes[i].length, sink->row, sink->col, sink->length); + + VA_Variant const variant = {lcs.nodes[i].row + lcs.nodes[i].length, sink->row + sink->length, lcs.nodes[i].col + lcs.nodes[i].length - shift, sink->col + sink->length - shift}; + + lcs.nodes[i].idx = add_node(allocator, &graph, lcs.nodes[i].row, lcs.nodes[i].col, lcs.nodes[i].length); + graph.nodes[lcs.nodes[i].idx].edges = add_edge(allocator, &graph, sink->idx, graph.nodes[lcs.nodes[i].idx].edges, variant); + } // for + + for (size_t i = lcs.length - 1; i >= 1; --i) + { + fprintf(stderr, "level %zu\n", i); + for (uint32_t j = 0; j < lcs.length; ++j) + { + fprintf(stderr, "%2u: %2d %2d\n", j, lcs.index[j].head, lcs.index[j].tail); + } // for + for (size_t j = 0; j < va_array_length(lcs.nodes); ++j) + { + fprintf(stderr, "%2zu: (%u, %u, %u) %2d\n", j, lcs.nodes[j].row, lcs.nodes[j].col, lcs.nodes[j].length, lcs.nodes[j].next); + } // for + + uint32_t next = -1; + for (uint32_t j = lcs.index[i].head; j != GVA_NULL; j = next) + { + next = lcs.nodes[j].next; + if (lcs.nodes[j].idx == GVA_NULL) + { + continue; + } // if + + uint32_t here = -1; + for (uint32_t k = lcs.index[i - 1].head; k != GVA_NULL; k = lcs.nodes[k].next) + { + if (k > j) + { + fprintf(stderr, "(%u, %u, %u) skip because topo order\n", lcs.nodes[k].row, lcs.nodes[k].col, lcs.nodes[k].length); + continue; + } // if + + eq_count += 1; + fprintf(stderr, "(%u, %u, %u) vs (%u, %u, %u)\n", lcs.nodes[k].row, lcs.nodes[k].col, lcs.nodes[k].length, lcs.nodes[j].row, lcs.nodes[j].col, lcs.nodes[j].length); + + if (lcs.nodes[k].row + lcs.nodes[k].length < lcs.nodes[j].row + lcs.nodes[j].length && + lcs.nodes[k].col + lcs.nodes[k].length < lcs.nodes[j].col + lcs.nodes[j].length) + { + VA_Variant const variant = {lcs.nodes[k].row + lcs.nodes[k].length, lcs.nodes[j].row + lcs.nodes[j].length - 1, lcs.nodes[k].col + lcs.nodes[k].length - shift, lcs.nodes[j].col + lcs.nodes[j].length - 1 - shift}; + + if (lcs.nodes[k].incoming == i) + { + fprintf(stderr, "SPLIT at %zu\n", i); + uint32_t const split_idx = lcs.nodes[k].idx; + lcs.nodes[k].idx = add_node(allocator, &graph, lcs.nodes[k].row, lcs.nodes[k].col, lcs.nodes[k].length); + lcs.nodes[k].incoming = 0; + + // lambda-edge + graph.nodes[lcs.nodes[k].idx].lambda = split_idx; + + graph.nodes[split_idx].row += lcs.nodes[k].length; + graph.nodes[split_idx].col += lcs.nodes[k].length; + graph.nodes[split_idx].length -= lcs.nodes[k].length; + fprintf(stderr, "RELABEL NODE %u: (%u, %u, %u)\n", split_idx, graph.nodes[split_idx].row, graph.nodes[split_idx].col, graph.nodes[split_idx].length); + } // if + else if (lcs.nodes[k].idx == GVA_NULL) + { + lcs.nodes[k].idx = add_node(allocator, &graph, lcs.nodes[k].row, lcs.nodes[k].col, lcs.nodes[k].length); + } // if + + graph.nodes[lcs.nodes[k].idx].edges = add_edge(allocator, &graph, lcs.nodes[j].idx, graph.nodes[lcs.nodes[k].idx].edges, variant); + + here = k; + } // if + } // for + + if (lcs.nodes[j].length > 1) + { + lcs.nodes[j].length -= 1; + if (here != GVA_NULL) + { + lcs.nodes[j].incoming = i; + lcs.nodes[j].next = lcs.nodes[here].next; + lcs.nodes[here].next = j; + } // if + else + { + lcs.nodes[j].next = lcs.index[i - 1].head; + lcs.index[i - 1].head = j; + } // else + fprintf(stderr, "INSERT (%u %u %u) here: %2d\n", lcs.nodes[j].row, lcs.nodes[j].col, lcs.nodes[j].length, here); + } // if + } // for + } // for + + size_t head = lcs.index[0].head; + VA_LCS_Node3* source = &lcs.nodes[head]; + if (source->row == shift && source->col == shift) + { + head = source->next; + } // if + else + { + source = &(VA_LCS_Node3) {.row = shift, .col = shift, .length = 0}; + source->idx = add_node(allocator, &graph, source->row, source->col, source->length); + } // else + + uint32_t min_source = -1; + for (uint32_t i = head; i != GVA_NULL; i = lcs.nodes[i].next) + { + if (lcs.nodes[i].idx == GVA_NULL) + { + continue; + } // if + + eq_count += 1; + fprintf(stderr, "(%u, %u, %u) vs (%u, %u, %u)\n", source->row, source->col, source->length, lcs.nodes[i].row, lcs.nodes[i].col, lcs.nodes[i].length); + + VA_Variant const variant = {source->row, lcs.nodes[i].row + lcs.nodes[i].length - 1, source->col - shift, lcs.nodes[i].col + lcs.nodes[i].length - 1 - shift}; + + min_source = MIN(min_source, variant.start); + + graph.nodes[source->idx].edges = add_edge(allocator, &graph, lcs.nodes[i].idx, graph.nodes[source->idx].edges, variant); + } // for + uint32_t const min_offset = min_source - graph.nodes[source->idx].row; + + graph.nodes[source->idx].row += min_offset; + graph.nodes[source->idx].col += min_offset; + graph.nodes[source->idx].length -= min_offset; + + graph.source = source->idx; + + va_std_allocator.alloc(va_std_allocator.context, lcs.index, lcs.length * sizeof(*lcs.index), 0); + va_array_destroy(va_std_allocator, lcs.nodes); + return graph; +} // build3 + + void to_dot(Graph const graph, size_t const len_obs, char const observed[static len_obs]) { diff --git a/src/graph2.c b/src/graph2.c index 0cffd3e..a3ce87a 100644 --- a/src/graph2.c +++ b/src/graph2.c @@ -107,8 +107,8 @@ bfs_traversal2(Graph2 const graph, size_t const len_obs, char const observed[sta } // if count += 1; VA_Variant variant; - uint32_t const count2 = edges2(((VA_LCS_Node) {graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, 0, 0}), - ((VA_LCS_Node) {graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length, 0, 0}), + uint32_t const count2 = edges2(((VA_LCS_Node) {.row = graph.nodes[i].row, .col =graph.nodes[i].col, .length = graph.nodes[i].length}), + ((VA_LCS_Node) {.row = graph.nodes[graph.edges[j].tail].row, .col = graph.nodes[graph.edges[j].tail].col, .length = graph.nodes[graph.edges[j].tail].length}), graph.nodes[head].row == graph.nodes[graph.source].row && graph.nodes[head].col == graph.nodes[graph.source].col, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, &variant); for (uint32_t k = 0; k < count2; ++k) @@ -176,9 +176,8 @@ print_graph(Graph2 const graph, size_t const len_obs, char const observed[static fprintf(stderr, " %u: (%u, %u, %u): ", graph.edges[j].tail, graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length); VA_Variant variant; uint32_t const count = edges2( - ((VA_LCS_Node) {graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, 0, 0}), - ((VA_LCS_Node) {graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, - graph.nodes[graph.edges[j].tail].length, 0, 0}), + ((VA_LCS_Node) {.row = graph.nodes[i].row, .col = graph.nodes[i].col, .length = graph.nodes[i].length}), + ((VA_LCS_Node) {.row = graph.nodes[graph.edges[j].tail].row, .col = graph.nodes[graph.edges[j].tail].col, .length = graph.nodes[graph.edges[j].tail].length}), i == graph.source, graph.nodes[graph.edges[j].tail].edges == GVA_NULL && graph.nodes[graph.edges[j].tail].edges == GVA_NULL, &variant); @@ -211,8 +210,9 @@ split(VA_LCS_Node2 const* const node, Node2 const* const tail = &graph->nodes[graph->edges[j].tail]; VA_Variant outgoing; uint32_t const out_count = edges2( - (VA_LCS_Node) {node->row, node->col, node->length, -1, GVA_NULL}, - (VA_LCS_Node) {tail->row, tail->col, tail->length, -1, GVA_NULL}, false, tail->edges == GVA_NULL && tail->lambda == GVA_NULL, &outgoing); + (VA_LCS_Node) {.row = node->row, .col = node->col, .length = node->length}, + (VA_LCS_Node) {.row = tail->row, .col = tail->col, .length = tail->length}, + false, tail->edges == GVA_NULL && tail->lambda == GVA_NULL, &outgoing); //fprintf(stderr, " %u: (%u, %u, %u): x %u ", graph->edges[j].tail, tail->row, tail->col, tail->length, out_count); // TODO: can we avoid reordering the tail list? Yes? XOR-linked? @@ -385,6 +385,9 @@ build(size_t const len_ref, char const reference[static restrict len_ref], { fprintf(stderr, "%2zu: (%u, %u, %u) %u %2d %2d\n", i, lcs_nodes[i].row, lcs_nodes[i].col, lcs_nodes[i].length, lcs_nodes[i].lcs_pos, lcs_nodes[i].next, lcs_nodes[i].inext); } // for + fprintf(stderr, "\n"); + + /* for (size_t i = 0; i < len_lcs; ++i) { fprintf(stderr, "%zu: ", i); @@ -398,6 +401,7 @@ build(size_t const len_ref, char const reference[static restrict len_ref], } // for fprintf(stderr, "\n"); } // for + */ uint32_t last_idx = lcs_index[len_lcs - 1].tail; @@ -445,8 +449,8 @@ build(size_t const len_ref, char const reference[static restrict len_ref], for (size_t i = 0; i < len; ++i) { - VA_LCS_Node2 const* const restrict tail = &lcs_nodes[len - i - 1]; uint32_t const idx = len - i - 1; + VA_LCS_Node2 const* const restrict tail = &lcs_nodes[idx]; if (lcs_nodes[idx].inext != GVA_NULL) { @@ -471,7 +475,13 @@ build(size_t const len_ref, char const reference[static restrict len_ref], uint32_t const lcs_low = tail->length > tail->lcs_pos ? 0 : tail->lcs_pos - tail->length; - for (uint32_t j = last_idx; j != GVA_NULL && lcs_nodes[j].lcs_pos >= lcs_low; j = lcs_nodes[j].next) + uint32_t j = last_idx; + //fprintf(stderr, "%d\n", last_idx); + if (tail->length == 1 && lcs_index[tail->lcs_pos].head < last_idx) + { + //j = lcs_nodes[lcs_index[tail->lcs_pos].head].next; + } + for (; j != GVA_NULL && lcs_nodes[j].lcs_pos >= lcs_low; j = lcs_nodes[j].next) { VA_LCS_Node2* const head = &lcs_nodes[j]; bool const is_source = head->row == shift && head->col == shift; diff --git a/src/main.c b/src/main.c index d8953f8..56139f9 100644 --- a/src/main.c +++ b/src/main.c @@ -158,7 +158,7 @@ main(int argc, char* argv[static argc + 1]) size_t const len_ref = strlen(reference); size_t const len_obs = strlen(observed); eq_count = 0; - //Graph2 graph = build(len_ref, reference, len_obs, observed, 0); + Graph2 graph = build(len_ref, reference, len_obs, observed, 0); //VA_LCS_Node2* lcs_nodes = va_edit2(va_std_allocator, len_ref, reference, len_obs, observed, &(uint32_t) {0}); VA_LCS_Node** lcs_nodes = NULL; size_t const len_lcs = va_edit(va_std_allocator, len_ref, reference, len_obs, observed, &lcs_nodes); @@ -193,30 +193,38 @@ main(int argc, char* argv[static argc + 1]) char const* const restrict observed = argv[2]; size_t const len_ref = strlen(reference); size_t const len_obs = strlen(observed); - eq_count = 0; - //check(len_ref, reference, len_obs, observed, true); - Graph2 graph2 = build(len_ref, reference, len_obs, observed, 0); - fprintf(stderr, "count: %zu\n", eq_count); + Graph graph = build3(va_std_allocator, len_ref, reference, len_obs, observed, 0); + print_graph(graph, len_obs, observed); + to_json(graph, len_obs, observed, false); - //to_json2(graph2, len_obs, observed); + destroy(va_std_allocator, &graph); +/* VA_LCS_Node** lcs_nodes = NULL; size_t const len_lcs = va_edit(va_std_allocator, len_ref, reference, len_obs, observed, &lcs_nodes); for (size_t i = 0; i < len_lcs; ++i) { - fprintf(stderr, "%zu: ", i); + fprintf(stderr, "%2zu: ", i); for (size_t j = 0; j < va_array_length(lcs_nodes[i]); ++j) { fprintf(stderr, "(%u, %u, %u) ", lcs_nodes[i][j].row, lcs_nodes[i][j].col, lcs_nodes[i][j].length); } // for fprintf(stderr, "\n"); } // for + fprintf(stderr, "\n"); + + eq_count = 0; + //check(len_ref, reference, len_obs, observed, true); + Graph2 graph2 = build(len_ref, reference, len_obs, observed, 0); + fprintf(stderr, "new count: %zu\n", eq_count); + + //to_json2(graph2, len_obs, observed); eq_count = 0; Graph graph = build_graph(va_std_allocator, len_ref, len_obs, len_lcs, lcs_nodes, 0, false); - fprintf(stderr, "count: %zu\n", eq_count); + fprintf(stderr, "old count: %zu\n\n", eq_count); //print_graph(graph, len_obs, observed); // to_dot(graph, len_obs, observed); @@ -227,7 +235,7 @@ main(int argc, char* argv[static argc + 1]) va_array_destroy(va_std_allocator, graph2.edges); destroy(va_std_allocator, &graph); - + */ } // if else { From d5ea9e1f3fcc37d0f1bb6c5a3bbe86247af2030b Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 3 Jun 2025 17:44:03 +0200 Subject: [PATCH 211/704] WIP: fixed sink edges --- src/graph.c | 6 ++++-- src/main.c | 19 +++++++++---------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/graph.c b/src/graph.c index 024c570..b5d3cda 100644 --- a/src/graph.c +++ b/src/graph.c @@ -279,14 +279,16 @@ build3(VA_Allocator const allocator, return graph; } // if - VA_LCS_Node3* sink = &lcs.nodes[lcs.index[lcs.length - 1].tail]; + uint32_t tail = lcs.index[lcs.length - 1].tail; + VA_LCS_Node3* sink = &lcs.nodes[tail]; if (sink->row + sink->length != len_ref + shift || sink->col + sink->length != len_obs + shift) { sink = &(VA_LCS_Node3) {.row = len_ref + shift, .col = len_obs + shift, .length = 0}; + tail = GVA_NULL; } // if sink->idx = add_node(allocator, &graph, sink->row, sink->col, sink->length); - for (uint32_t i = lcs.index[lcs.length - 1].head; i != lcs.index[lcs.length - 1].tail; i = lcs.nodes[i].next) + for (uint32_t i = lcs.index[lcs.length - 1].head; i != tail; i = lcs.nodes[i].next) { eq_count += 1; fprintf(stderr, "(%u, %u, %u) vs (%u, %u, %u)\n", lcs.nodes[i].row, lcs.nodes[i].col, lcs.nodes[i].length, sink->row, sink->col, sink->length); diff --git a/src/main.c b/src/main.c index 56139f9..755cc79 100644 --- a/src/main.c +++ b/src/main.c @@ -195,11 +195,10 @@ main(int argc, char* argv[static argc + 1]) size_t const len_obs = strlen(observed); Graph graph = build3(va_std_allocator, len_ref, reference, len_obs, observed, 0); - print_graph(graph, len_obs, observed); + //print_graph(graph, len_obs, observed); to_json(graph, len_obs, observed, false); destroy(va_std_allocator, &graph); - /* VA_LCS_Node** lcs_nodes = NULL; size_t const len_lcs = va_edit(va_std_allocator, len_ref, reference, len_obs, observed, &lcs_nodes); @@ -214,27 +213,27 @@ main(int argc, char* argv[static argc + 1]) fprintf(stderr, "\n"); } // for fprintf(stderr, "\n"); - +/* eq_count = 0; //check(len_ref, reference, len_obs, observed, true); Graph2 graph2 = build(len_ref, reference, len_obs, observed, 0); fprintf(stderr, "new count: %zu\n", eq_count); - +*/ //to_json2(graph2, len_obs, observed); - +/* eq_count = 0; - Graph graph = build_graph(va_std_allocator, len_ref, len_obs, len_lcs, lcs_nodes, 0, false); + Graph graph_old = build_graph(va_std_allocator, len_ref, len_obs, len_lcs, lcs_nodes, 0, false); fprintf(stderr, "old count: %zu\n\n", eq_count); - //print_graph(graph, len_obs, observed); + print_graph(graph_old, len_obs, observed); // to_dot(graph, len_obs, observed); // to_json(graph, len_obs, observed, false); // destroy graph2 - va_array_destroy(va_std_allocator, graph2.nodes); - va_array_destroy(va_std_allocator, graph2.edges); + //va_array_destroy(va_std_allocator, graph2.nodes); + //va_array_destroy(va_std_allocator, graph2.edges); - destroy(va_std_allocator, &graph); + destroy(va_std_allocator, &graph_old); */ } // if else From c15267b6ed16a2b97cbf8107587fd3de258bce7e Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 3 Jun 2025 21:41:56 +0200 Subject: [PATCH 212/704] WIP: build3 tests ok --- src/graph.c | 93 +++++++++++++++++++++++++++++++++++------------------ src/main.c | 4 +-- test.py | 2 +- 3 files changed, 64 insertions(+), 35 deletions(-) diff --git a/src/graph.c b/src/graph.c index b5d3cda..3b31bca 100644 --- a/src/graph.c +++ b/src/graph.c @@ -265,6 +265,20 @@ build3(VA_Allocator const allocator, Graph graph = {.nodes = NULL, .edges = NULL}; + if (lcs.nodes == NULL) + { + uint32_t const sink_idx = add_node(allocator, &graph, len_ref, len_obs, 0); + if (len_ref == 0 && len_obs == 0) + { + graph.source = sink_idx; + return graph; + } // if + + graph.source = add_node(allocator, &graph, shift, shift, 0); + graph.nodes[graph.source].edges = add_edge(allocator, &graph, sink_idx, GVA_NULL, (VA_Variant) {shift, shift + len_ref, 0, len_obs}); + return graph; + } // if + if (lcs.length == 0 || lcs.nodes == NULL) { graph.source = add_node(allocator, &graph, shift, shift, 0); @@ -280,23 +294,28 @@ build3(VA_Allocator const allocator, } // if uint32_t tail = lcs.index[lcs.length - 1].tail; - VA_LCS_Node3* sink = &lcs.nodes[tail]; - if (sink->row + sink->length != len_ref + shift || sink->col + sink->length != len_obs + shift) + VA_LCS_Node3 sink = lcs.nodes[tail]; + if (sink.row + sink.length == len_ref + shift && sink.col + sink.length == len_obs + shift) { - sink = &(VA_LCS_Node3) {.row = len_ref + shift, .col = len_obs + shift, .length = 0}; - tail = GVA_NULL; + lcs.nodes[tail].idx = add_node(allocator, &graph, sink.row, sink.col, sink.length); + sink.idx = lcs.nodes[tail].idx; } // if - sink->idx = add_node(allocator, &graph, sink->row, sink->col, sink->length); + else + { + sink = (VA_LCS_Node3) {.row = len_ref + shift, .col = len_obs + shift, .length = 0}; + sink.idx = add_node(allocator, &graph, sink.row, sink.col, sink.length); + tail = GVA_NULL; + } // else for (uint32_t i = lcs.index[lcs.length - 1].head; i != tail; i = lcs.nodes[i].next) { eq_count += 1; - fprintf(stderr, "(%u, %u, %u) vs (%u, %u, %u)\n", lcs.nodes[i].row, lcs.nodes[i].col, lcs.nodes[i].length, sink->row, sink->col, sink->length); + fprintf(stderr, "(%u, %u, %u) vs (%u, %u, %u)\n", lcs.nodes[i].row, lcs.nodes[i].col, lcs.nodes[i].length, sink.row, sink.col, sink.length); - VA_Variant const variant = {lcs.nodes[i].row + lcs.nodes[i].length, sink->row + sink->length, lcs.nodes[i].col + lcs.nodes[i].length - shift, sink->col + sink->length - shift}; + VA_Variant const variant = {lcs.nodes[i].row + lcs.nodes[i].length, sink.row + sink.length, lcs.nodes[i].col + lcs.nodes[i].length - shift, sink.col + sink.length - shift}; lcs.nodes[i].idx = add_node(allocator, &graph, lcs.nodes[i].row, lcs.nodes[i].col, lcs.nodes[i].length); - graph.nodes[lcs.nodes[i].idx].edges = add_edge(allocator, &graph, sink->idx, graph.nodes[lcs.nodes[i].idx].edges, variant); + graph.nodes[lcs.nodes[i].idx].edges = add_edge(allocator, &graph, sink.idx, graph.nodes[lcs.nodes[i].idx].edges, variant); } // for for (size_t i = lcs.length - 1; i >= 1; --i) @@ -383,18 +402,17 @@ build3(VA_Allocator const allocator, } // for size_t head = lcs.index[0].head; - VA_LCS_Node3* source = &lcs.nodes[head]; - if (source->row == shift && source->col == shift) + VA_LCS_Node3 source = lcs.nodes[head]; + if (source.row == shift && source.col == shift) { - head = source->next; + head = source.next; } // if else { - source = &(VA_LCS_Node3) {.row = shift, .col = shift, .length = 0}; - source->idx = add_node(allocator, &graph, source->row, source->col, source->length); + source = (VA_LCS_Node3) {.row = shift, .col = shift, .length = 0}; + source.idx = add_node(allocator, &graph, source.row, source.col, source.length); } // else - uint32_t min_source = -1; for (uint32_t i = head; i != GVA_NULL; i = lcs.nodes[i].next) { if (lcs.nodes[i].idx == GVA_NULL) @@ -403,21 +421,32 @@ build3(VA_Allocator const allocator, } // if eq_count += 1; - fprintf(stderr, "(%u, %u, %u) vs (%u, %u, %u)\n", source->row, source->col, source->length, lcs.nodes[i].row, lcs.nodes[i].col, lcs.nodes[i].length); + fprintf(stderr, "(%u, %u, %u) vs (%u, %u, %u)\n", source.row, source.col, source.length, lcs.nodes[i].row, lcs.nodes[i].col, lcs.nodes[i].length); - VA_Variant const variant = {source->row, lcs.nodes[i].row + lcs.nodes[i].length - 1, source->col - shift, lcs.nodes[i].col + lcs.nodes[i].length - 1 - shift}; + VA_Variant const variant = {source.row, lcs.nodes[i].row + lcs.nodes[i].length - 1, source.col - shift, lcs.nodes[i].col + lcs.nodes[i].length - 1 - shift}; - min_source = MIN(min_source, variant.start); + graph.nodes[source.idx].edges = add_edge(allocator, &graph, lcs.nodes[i].idx, graph.nodes[source.idx].edges, variant); + } // for - graph.nodes[source->idx].edges = add_edge(allocator, &graph, lcs.nodes[i].idx, graph.nodes[source->idx].edges, variant); + uint32_t min_source = GVA_NULL; + for (uint32_t i = graph.nodes[source.idx].edges; i != (uint32_t) -1; i = graph.edges[i].next) + { + min_source = MIN(min_source, graph.edges[i].variant.start); } // for - uint32_t const min_offset = min_source - graph.nodes[source->idx].row; - graph.nodes[source->idx].row += min_offset; - graph.nodes[source->idx].col += min_offset; - graph.nodes[source->idx].length -= min_offset; + if (min_source != GVA_NULL) + { + uint32_t const min_offset = min_source - graph.nodes[source.idx].row; + graph.nodes[source.idx].row += min_offset; + graph.nodes[source.idx].col += min_offset; + graph.nodes[source.idx].length -= min_offset; + } // if + else + { + graph.nodes[source.idx].length = 0; + } // else - graph.source = source->idx; + graph.source = source.idx; va_std_allocator.alloc(va_std_allocator.context, lcs.index, lcs.length * sizeof(*lcs.index), 0); va_array_destroy(va_std_allocator, lcs.nodes); @@ -516,7 +545,7 @@ bfs_traversal(VA_Allocator const allocator, Graph const graph, size_t const len_ */ } // while - printf("\n ],\n"); + printf("\n ]\n"); table = allocator.alloc(allocator.context, table, sizeof(*table) * va_array_length(graph.nodes), 0); @@ -550,7 +579,7 @@ lambda_edges(Graph const graph, size_t const len_obs, char const observed[static printf(" {\"head\": \"s%u\", \"tail\": \"s%u\", \"variant\": \"%u:%u/%.*s\"}", i, graph.edges[j].tail, graph.edges[j].variant.start, graph.edges[j].variant.end, (int) graph.edges[j].variant.obs_end - graph.edges[j].variant.obs_start, observed + graph.edges[j].variant.obs_start); } // for } // for - printf("\n ],\n"); + printf("\n ]\n"); } // lambda_edges @@ -568,13 +597,13 @@ to_json(Graph const graph, size_t const len_obs, char const observed[static len_ } else { bfs_traversal(va_std_allocator, graph, len_obs, observed); } - printf(" \"supremal\": \"%u:%u/%.*s\",\n", graph.supremal.start, graph.supremal.end, (int) graph.supremal.obs_end - graph.supremal.obs_start, observed + graph.supremal.obs_start); - printf(" \"local_supremal\": [\n"); - local_supremal(va_std_allocator, graph, len_obs, observed, false); - printf("\n ],\n"); - printf(" \"canonical\": [\n"); - canonical(va_std_allocator, graph, len_obs, observed, false); - printf("\n ]\n"); + //printf(" \"supremal\": \"%u:%u/%.*s\",\n", graph.supremal.start, graph.supremal.end, (int) graph.supremal.obs_end - graph.supremal.obs_start, observed + graph.supremal.obs_start); + //printf(" \"local_supremal\": [\n"); + //local_supremal(va_std_allocator, graph, len_obs, observed, false); + //printf("\n ],\n"); + //printf(" \"canonical\": [\n"); + //canonical(va_std_allocator, graph, len_obs, observed, false); + //printf("\n ]\n"); printf("}"); } // to_json diff --git a/src/main.c b/src/main.c index 755cc79..976bd4b 100644 --- a/src/main.c +++ b/src/main.c @@ -195,7 +195,7 @@ main(int argc, char* argv[static argc + 1]) size_t const len_obs = strlen(observed); Graph graph = build3(va_std_allocator, len_ref, reference, len_obs, observed, 0); - //print_graph(graph, len_obs, observed); + print_graph(graph, len_obs, observed); to_json(graph, len_obs, observed, false); destroy(va_std_allocator, &graph); @@ -213,7 +213,7 @@ main(int argc, char* argv[static argc + 1]) fprintf(stderr, "\n"); } // for fprintf(stderr, "\n"); -/* + eq_count = 0; //check(len_ref, reference, len_obs, observed, true); Graph2 graph2 = build(len_ref, reference, len_obs, observed, 0); diff --git a/test.py b/test.py index 41c04ab..682544c 100644 --- a/test.py +++ b/test.py @@ -79,7 +79,7 @@ def str2var(desc): assert lhs == str(rhs), f'canonical elements differ: {lhs} vs {rhs}' -def check(reference, observed, debug=False, timeout=None): +def check(reference, observed, debug=False, timeout=2): #graph = LCSgraph.from_sequence(reference, observed) graph = LCSgraph(reference, observed) valgrind = [] From 9092bec454332014157a3b139f0a38502949a1c4 Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 4 Jun 2025 16:23:09 +0200 Subject: [PATCH 213/704] WIP: build3 without duplicate edges --- include/edit.h | 3 +- include/graph.h | 1 + src/edit3.c | 4 +- src/graph.c | 122 ++++++++++++++++++++---------------------------- src/main.c | 11 +++-- 5 files changed, 62 insertions(+), 79 deletions(-) diff --git a/include/edit.h b/include/edit.h index 952951a..838a277 100644 --- a/include/edit.h +++ b/include/edit.h @@ -46,7 +46,8 @@ typedef struct { uint32_t row; uint32_t col; - uint32_t length; + uint32_t length : 31; + uint32_t moved : 1; uint32_t incoming; uint32_t idx; uint32_t next; diff --git a/include/graph.h b/include/graph.h index 20d8c88..7a97af6 100644 --- a/include/graph.h +++ b/include/graph.h @@ -22,6 +22,7 @@ typedef struct uint32_t lambda; } Node; + typedef struct { Node* nodes; diff --git a/src/edit3.c b/src/edit3.c index b63ca28..f460a0f 100644 --- a/src/edit3.c +++ b/src/edit3.c @@ -87,7 +87,7 @@ expand(Context const context, ptrdiff_t const d_col = context.len_obs - col; size_t const lcs_pos = (row + col - imaxabs(delta) - 2 * p + imaxabs(d_row - d_col)) / 2 - 1; size_t const length = row - match_row; - va_array_append(context.allocator, lcs->nodes, ((VA_LCS_Node3) {match_row, match_col, length, -1, -1, -1})); + va_array_append(context.allocator, lcs->nodes, ((VA_LCS_Node3) {match_row, match_col, length, false, -1, -1, -1})); if (lcs->index[lcs_pos].head != (uint32_t) -1) { lcs->nodes[lcs->index[lcs_pos].tail].next = va_array_length(lcs->nodes) - 1; @@ -126,7 +126,7 @@ expand(Context const context, ptrdiff_t const d_col = context.len_obs - col; size_t const lcs_pos = (row + col - imaxabs(delta) - 2 * p + imaxabs(d_row - d_col)) / 2 - 1; size_t const length = row - match_row; - va_array_append(context.allocator, lcs->nodes, ((VA_LCS_Node3) {match_row, match_col, length, -1, -1, -1})); + va_array_append(context.allocator, lcs->nodes, ((VA_LCS_Node3) {match_row, match_col, length, false, -1, -1, -1})); if (lcs->index[lcs_pos].head != (uint32_t) -1) { lcs->nodes[lcs->index[lcs_pos].tail].next = va_array_length(lcs->nodes) - 1; diff --git a/src/graph.c b/src/graph.c index 3b31bca..4247b69 100644 --- a/src/graph.c +++ b/src/graph.c @@ -90,7 +90,7 @@ build_graph(VA_Allocator const allocator, for (size_t i = 0; i < va_array_length(heads); ++i) { eq_count += 1; - fprintf(stderr, "(%u, %u, %u) vs (%u, %u, %u)\n", heads[i].row, heads[i].col, heads[i].length, sink.row, sink.col, sink.length); + //fprintf(stderr, "(%u, %u, %u) vs (%u, %u, %u)\n", heads[i].row, heads[i].col, heads[i].length, sink.row, sink.col, sink.length); if (heads[i].row + heads[i].length < sink.row + sink.length && heads[i].col + heads[i].length < sink.col + sink.length) { @@ -139,7 +139,7 @@ build_graph(VA_Allocator const allocator, } // if */ eq_count += 1; - fprintf(stderr, "(%u, %u, %u) vs (%u, %u, %u)\n", heads[k].row, heads[k].col, heads[k].length, tail.row, tail.col, tail.length); + //fprintf(stderr, "(%u, %u, %u) vs (%u, %u, %u)\n", heads[k].row, heads[k].col, heads[k].length, tail.row, tail.col, tail.length); if (heads[k].row + heads[k].length < tail.row + tail.length && heads[k].col + heads[k].length < tail.col + tail.length) @@ -220,7 +220,7 @@ build_graph(VA_Allocator const allocator, } // if eq_count += 1; - fprintf(stderr, "(%u, %u, %u) vs (%u, %u, %u)\n", source.row, source.col, source.length, lcs_nodes[0][i].row, lcs_nodes[0][i].col, lcs_nodes[0][i].length); + //fprintf(stderr, "(%u, %u, %u) vs (%u, %u, %u)\n", source.row, source.col, source.length, lcs_nodes[0][i].row, lcs_nodes[0][i].col, lcs_nodes[0][i].length); if (source.row < lcs_nodes[0][i].row + lcs_nodes[0][i].length && source.col < lcs_nodes[0][i].col + lcs_nodes[0][i].length) { @@ -237,7 +237,7 @@ build_graph(VA_Allocator const allocator, lcs_nodes = allocator.alloc(allocator.context, lcs_nodes, len_lcs * sizeof(*lcs_nodes), 0); uint32_t min_source = max_sink; - for (uint32_t i = graph.nodes[source.idx].edges; i != (uint32_t) -1; i = graph.edges[i].next) + for (uint32_t i = graph.nodes[source.idx].edges; i != GVA_NULL; i = graph.edges[i].next) { min_source = MIN(min_source, graph.edges[i].variant.start); } // for @@ -261,7 +261,7 @@ build3(VA_Allocator const allocator, size_t const len_obs, char const observed[static restrict len_obs], size_t const shift) { - VA_LCS lcs = va_edit3(allocator, len_ref, reference, len_obs, observed); + VA_LCS const lcs = va_edit3(allocator, len_ref, reference, len_obs, observed); Graph graph = {.nodes = NULL, .edges = NULL}; @@ -279,38 +279,24 @@ build3(VA_Allocator const allocator, return graph; } // if - if (lcs.length == 0 || lcs.nodes == NULL) - { - graph.source = add_node(allocator, &graph, shift, shift, 0); - if (len_ref == 0 && len_obs == 0) - { - graph.supremal = (VA_Variant) {0, 0, 0, 0}; - return graph; - } // if - uint32_t const sink = add_node(allocator, &graph, len_ref, len_obs, 0); - graph.supremal = (VA_Variant) {shift, shift + len_ref, 0, len_obs}; - graph.nodes[graph.source].edges = add_edge(allocator, &graph, sink, -1, graph.supremal); - return graph; - } // if - - uint32_t tail = lcs.index[lcs.length - 1].tail; - VA_LCS_Node3 sink = lcs.nodes[tail]; + uint32_t tail_idx = lcs.index[lcs.length - 1].tail; + VA_LCS_Node3 sink = lcs.nodes[tail_idx]; if (sink.row + sink.length == len_ref + shift && sink.col + sink.length == len_obs + shift) { - lcs.nodes[tail].idx = add_node(allocator, &graph, sink.row, sink.col, sink.length); - sink.idx = lcs.nodes[tail].idx; + lcs.nodes[tail_idx].idx = add_node(allocator, &graph, sink.row, sink.col, sink.length); + lcs.nodes[tail_idx].moved = true; + sink = lcs.nodes[tail_idx]; } // if else { sink = (VA_LCS_Node3) {.row = len_ref + shift, .col = len_obs + shift, .length = 0}; sink.idx = add_node(allocator, &graph, sink.row, sink.col, sink.length); - tail = GVA_NULL; + tail_idx = GVA_NULL; } // else - for (uint32_t i = lcs.index[lcs.length - 1].head; i != tail; i = lcs.nodes[i].next) + for (uint32_t i = lcs.index[lcs.length - 1].head; i != tail_idx; i = lcs.nodes[i].next) { eq_count += 1; - fprintf(stderr, "(%u, %u, %u) vs (%u, %u, %u)\n", lcs.nodes[i].row, lcs.nodes[i].col, lcs.nodes[i].length, sink.row, sink.col, sink.length); VA_Variant const variant = {lcs.nodes[i].row + lcs.nodes[i].length, sink.row + sink.length, lcs.nodes[i].col + lcs.nodes[i].length - shift, sink.col + sink.length - shift}; @@ -320,92 +306,85 @@ build3(VA_Allocator const allocator, for (size_t i = lcs.length - 1; i >= 1; --i) { - fprintf(stderr, "level %zu\n", i); - for (uint32_t j = 0; j < lcs.length; ++j) - { - fprintf(stderr, "%2u: %2d %2d\n", j, lcs.index[j].head, lcs.index[j].tail); - } // for - for (size_t j = 0; j < va_array_length(lcs.nodes); ++j) - { - fprintf(stderr, "%2zu: (%u, %u, %u) %2d\n", j, lcs.nodes[j].row, lcs.nodes[j].col, lcs.nodes[j].length, lcs.nodes[j].next); - } // for - - uint32_t next = -1; + uint32_t next = GVA_NULL; for (uint32_t j = lcs.index[i].head; j != GVA_NULL; j = next) { - next = lcs.nodes[j].next; + VA_LCS_Node3* const tail = &lcs.nodes[j]; + next = tail->next; if (lcs.nodes[j].idx == GVA_NULL) { continue; } // if - uint32_t here = -1; + uint32_t here = GVA_NULL; for (uint32_t k = lcs.index[i - 1].head; k != GVA_NULL; k = lcs.nodes[k].next) { + eq_count += 1; + if (k > j) { - fprintf(stderr, "(%u, %u, %u) skip because topo order\n", lcs.nodes[k].row, lcs.nodes[k].col, lcs.nodes[k].length); continue; } // if - eq_count += 1; - fprintf(stderr, "(%u, %u, %u) vs (%u, %u, %u)\n", lcs.nodes[k].row, lcs.nodes[k].col, lcs.nodes[k].length, lcs.nodes[j].row, lcs.nodes[j].col, lcs.nodes[j].length); + VA_LCS_Node3* const head = &lcs.nodes[k]; - if (lcs.nodes[k].row + lcs.nodes[k].length < lcs.nodes[j].row + lcs.nodes[j].length && - lcs.nodes[k].col + lcs.nodes[k].length < lcs.nodes[j].col + lcs.nodes[j].length) + if (head->row + head->length < tail->row + tail->length && + head->col + head->length < tail->col + tail->length) { - VA_Variant const variant = {lcs.nodes[k].row + lcs.nodes[k].length, lcs.nodes[j].row + lcs.nodes[j].length - 1, lcs.nodes[k].col + lcs.nodes[k].length - shift, lcs.nodes[j].col + lcs.nodes[j].length - 1 - shift}; + VA_Variant const variant = {head->row + head->length, tail->row + tail->length - 1, head->col + head->length - shift, tail->col + tail->length - 1 - shift}; - if (lcs.nodes[k].incoming == i) + if (head->incoming == i) { - fprintf(stderr, "SPLIT at %zu\n", i); - uint32_t const split_idx = lcs.nodes[k].idx; - lcs.nodes[k].idx = add_node(allocator, &graph, lcs.nodes[k].row, lcs.nodes[k].col, lcs.nodes[k].length); - lcs.nodes[k].incoming = 0; + uint32_t const split_idx = head->idx; + head->idx = add_node(allocator, &graph, head->row, head->col, head->length); + head->incoming = 0; - // lambda-edge - graph.nodes[lcs.nodes[k].idx].lambda = split_idx; + graph.nodes[head->idx].lambda = split_idx; + + graph.nodes[split_idx].row += head->length; + graph.nodes[split_idx].col += head->length; + graph.nodes[split_idx].length -= head->length; - graph.nodes[split_idx].row += lcs.nodes[k].length; - graph.nodes[split_idx].col += lcs.nodes[k].length; - graph.nodes[split_idx].length -= lcs.nodes[k].length; - fprintf(stderr, "RELABEL NODE %u: (%u, %u, %u)\n", split_idx, graph.nodes[split_idx].row, graph.nodes[split_idx].col, graph.nodes[split_idx].length); + graph.nodes[head->idx].edges = add_edge(allocator, &graph, tail->idx, graph.nodes[head->idx].edges, variant); } // if - else if (lcs.nodes[k].idx == GVA_NULL) + else if (head->idx == GVA_NULL) { - lcs.nodes[k].idx = add_node(allocator, &graph, lcs.nodes[k].row, lcs.nodes[k].col, lcs.nodes[k].length); + head->idx = add_node(allocator, &graph, head->row, head->col, head->length); + graph.nodes[head->idx].edges = add_edge(allocator, &graph, tail->idx, graph.nodes[head->idx].edges, variant); + } // if + else if (!head->moved || !tail->moved) + { + graph.nodes[head->idx].edges = add_edge(allocator, &graph, tail->idx, graph.nodes[head->idx].edges, variant); } // if - - graph.nodes[lcs.nodes[k].idx].edges = add_edge(allocator, &graph, lcs.nodes[j].idx, graph.nodes[lcs.nodes[k].idx].edges, variant); here = k; } // if } // for - if (lcs.nodes[j].length > 1) + if (tail->length > 1) { - lcs.nodes[j].length -= 1; + tail->length -= 1; + tail->moved = true; if (here != GVA_NULL) { - lcs.nodes[j].incoming = i; - lcs.nodes[j].next = lcs.nodes[here].next; + tail->incoming = i; + tail->next = lcs.nodes[here].next; lcs.nodes[here].next = j; } // if else { - lcs.nodes[j].next = lcs.index[i - 1].head; + tail->next = lcs.index[i - 1].head; lcs.index[i - 1].head = j; } // else - fprintf(stderr, "INSERT (%u %u %u) here: %2d\n", lcs.nodes[j].row, lcs.nodes[j].col, lcs.nodes[j].length, here); } // if } // for } // for - size_t head = lcs.index[0].head; - VA_LCS_Node3 source = lcs.nodes[head]; + size_t head_idx = lcs.index[0].head; + VA_LCS_Node3 source = lcs.nodes[head_idx]; if (source.row == shift && source.col == shift) { - head = source.next; + head_idx = source.next; } // if else { @@ -413,7 +392,7 @@ build3(VA_Allocator const allocator, source.idx = add_node(allocator, &graph, source.row, source.col, source.length); } // else - for (uint32_t i = head; i != GVA_NULL; i = lcs.nodes[i].next) + for (uint32_t i = head_idx; i != GVA_NULL; i = lcs.nodes[i].next) { if (lcs.nodes[i].idx == GVA_NULL) { @@ -421,7 +400,6 @@ build3(VA_Allocator const allocator, } // if eq_count += 1; - fprintf(stderr, "(%u, %u, %u) vs (%u, %u, %u)\n", source.row, source.col, source.length, lcs.nodes[i].row, lcs.nodes[i].col, lcs.nodes[i].length); VA_Variant const variant = {source.row, lcs.nodes[i].row + lcs.nodes[i].length - 1, source.col - shift, lcs.nodes[i].col + lcs.nodes[i].length - 1 - shift}; @@ -429,7 +407,7 @@ build3(VA_Allocator const allocator, } // for uint32_t min_source = GVA_NULL; - for (uint32_t i = graph.nodes[source.idx].edges; i != (uint32_t) -1; i = graph.edges[i].next) + for (uint32_t i = graph.nodes[source.idx].edges; i != GVA_NULL; i = graph.edges[i].next) { min_source = MIN(min_source, graph.edges[i].variant.start); } // for diff --git a/src/main.c b/src/main.c index 976bd4b..553cde7 100644 --- a/src/main.c +++ b/src/main.c @@ -158,13 +158,16 @@ main(int argc, char* argv[static argc + 1]) size_t const len_ref = strlen(reference); size_t const len_obs = strlen(observed); eq_count = 0; - Graph2 graph = build(len_ref, reference, len_obs, observed, 0); + //Graph2 graph = build(len_ref, reference, len_obs, observed, 0); //VA_LCS_Node2* lcs_nodes = va_edit2(va_std_allocator, len_ref, reference, len_obs, observed, &(uint32_t) {0}); - VA_LCS_Node** lcs_nodes = NULL; - size_t const len_lcs = va_edit(va_std_allocator, len_ref, reference, len_obs, observed, &lcs_nodes); - Graph graph = build_graph(va_std_allocator, len_ref, len_obs, len_lcs, lcs_nodes, 0, false); + //VA_LCS_Node** lcs_nodes = NULL; + //size_t const len_lcs = va_edit(va_std_allocator, len_ref, reference, len_obs, observed, &lcs_nodes); + //Graph graph = build_graph(va_std_allocator, len_ref, len_obs, len_lcs, lcs_nodes, 0, false); + Graph graph = build3(va_std_allocator, len_ref, reference, len_obs, observed, 0); + printf("nodes: %zu\nedges: %zu\n", va_array_length(graph.nodes), va_array_length(graph.edges)); printf("%zu\n", eq_count); + destroy(va_std_allocator, &graph); return 0; */ From 0882a1303aeaf1e864d11fd0a67b486d995868fb Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 4 Jun 2025 17:00:59 +0200 Subject: [PATCH 214/704] WIP: build3 results in Graph3 --- include/graph.h | 23 +++++++++++++++- src/graph.c | 73 ++++++++++++++++++++----------------------------- src/graph2.c | 2 +- src/main.c | 41 ++++++++++++++++++++++++--- 4 files changed, 90 insertions(+), 49 deletions(-) diff --git a/include/graph.h b/include/graph.h index 7a97af6..2d60e05 100644 --- a/include/graph.h +++ b/include/graph.h @@ -32,7 +32,28 @@ typedef struct } Graph; -Graph +typedef struct +{ + uint32_t tail; + uint32_t next; +} Edge3; + + +typedef struct +{ + Node* nodes; + Edge3* edges; + uint32_t source; +} Graph3; + + +uint32_t +edges2(VA_LCS_Node const head, VA_LCS_Node const tail, + bool const is_source, bool const is_sink, + VA_Variant* const variant); + + +Graph3 build3(VA_Allocator const allocator, size_t const len_ref, char const reference[static restrict len_ref], size_t const len_obs, char const observed[static restrict len_obs], diff --git a/src/graph.c b/src/graph.c index 4247b69..a2f8d08 100644 --- a/src/graph.c +++ b/src/graph.c @@ -255,7 +255,7 @@ build_graph(VA_Allocator const allocator, } // build_graph -Graph +Graph3 build3(VA_Allocator const allocator, size_t const len_ref, char const reference[static restrict len_ref], size_t const len_obs, char const observed[static restrict len_obs], @@ -263,19 +263,21 @@ build3(VA_Allocator const allocator, { VA_LCS const lcs = va_edit3(allocator, len_ref, reference, len_obs, observed); - Graph graph = {.nodes = NULL, .edges = NULL}; + Graph3 graph = {.nodes = NULL, .edges = NULL}; if (lcs.nodes == NULL) { - uint32_t const sink_idx = add_node(allocator, &graph, len_ref, len_obs, 0); + va_array_append(va_std_allocator, graph.nodes, ((Node) {len_ref, len_obs, 0, GVA_NULL, GVA_NULL})); + uint32_t const sink = va_array_length(graph.nodes) - 1; if (len_ref == 0 && len_obs == 0) { - graph.source = sink_idx; + graph.source = sink; return graph; } // if - graph.source = add_node(allocator, &graph, shift, shift, 0); - graph.nodes[graph.source].edges = add_edge(allocator, &graph, sink_idx, GVA_NULL, (VA_Variant) {shift, shift + len_ref, 0, len_obs}); + va_array_append(va_std_allocator, graph.edges, ((Edge3) {sink, GVA_NULL})); + va_array_append(va_std_allocator, graph.nodes, ((Node) {shift, shift, 0, va_array_length(graph.edges) - 1, GVA_NULL})); + graph.source = va_array_length(graph.nodes) - 1; return graph; } // if @@ -283,14 +285,16 @@ build3(VA_Allocator const allocator, VA_LCS_Node3 sink = lcs.nodes[tail_idx]; if (sink.row + sink.length == len_ref + shift && sink.col + sink.length == len_obs + shift) { - lcs.nodes[tail_idx].idx = add_node(allocator, &graph, sink.row, sink.col, sink.length); + va_array_append(allocator, graph.nodes, ((Node) {sink.row, sink.col, sink.length, GVA_NULL, GVA_NULL})); + lcs.nodes[tail_idx].idx = va_array_length(graph.nodes) - 1; lcs.nodes[tail_idx].moved = true; sink = lcs.nodes[tail_idx]; } // if else { sink = (VA_LCS_Node3) {.row = len_ref + shift, .col = len_obs + shift, .length = 0}; - sink.idx = add_node(allocator, &graph, sink.row, sink.col, sink.length); + va_array_append(allocator, graph.nodes, ((Node) {sink.row, sink.col, sink.length, GVA_NULL, GVA_NULL})); + sink.idx = va_array_length(graph.nodes) - 1; tail_idx = GVA_NULL; } // else @@ -298,10 +302,10 @@ build3(VA_Allocator const allocator, { eq_count += 1; - VA_Variant const variant = {lcs.nodes[i].row + lcs.nodes[i].length, sink.row + sink.length, lcs.nodes[i].col + lcs.nodes[i].length - shift, sink.col + sink.length - shift}; - - lcs.nodes[i].idx = add_node(allocator, &graph, lcs.nodes[i].row, lcs.nodes[i].col, lcs.nodes[i].length); - graph.nodes[lcs.nodes[i].idx].edges = add_edge(allocator, &graph, sink.idx, graph.nodes[lcs.nodes[i].idx].edges, variant); + va_array_append(allocator, graph.nodes, ((Node) {lcs.nodes[i].row, lcs.nodes[i].col, lcs.nodes[i].length, GVA_NULL, GVA_NULL})); + lcs.nodes[i].idx = va_array_length(graph.nodes) - 1; + va_array_append(allocator, graph.edges, ((Edge3) {sink.idx, graph.nodes[lcs.nodes[i].idx].edges})); + graph.nodes[lcs.nodes[i].idx].edges = va_array_length(graph.edges) - 1; } // for for (size_t i = lcs.length - 1; i >= 1; --i) @@ -331,30 +335,31 @@ build3(VA_Allocator const allocator, if (head->row + head->length < tail->row + tail->length && head->col + head->length < tail->col + tail->length) { - VA_Variant const variant = {head->row + head->length, tail->row + tail->length - 1, head->col + head->length - shift, tail->col + tail->length - 1 - shift}; - if (head->incoming == i) { uint32_t const split_idx = head->idx; - head->idx = add_node(allocator, &graph, head->row, head->col, head->length); + va_array_append(allocator, graph.nodes, ((Node) {head->row, head->col, head->length, GVA_NULL, split_idx})); + head->idx = va_array_length(graph.nodes) - 1; head->incoming = 0; - graph.nodes[head->idx].lambda = split_idx; - graph.nodes[split_idx].row += head->length; graph.nodes[split_idx].col += head->length; graph.nodes[split_idx].length -= head->length; - graph.nodes[head->idx].edges = add_edge(allocator, &graph, tail->idx, graph.nodes[head->idx].edges, variant); + va_array_append(allocator, graph.edges, ((Edge3) {tail->idx, graph.nodes[head->idx].edges})); + graph.nodes[head->idx].edges = va_array_length(graph.edges) - 1; } // if else if (head->idx == GVA_NULL) { - head->idx = add_node(allocator, &graph, head->row, head->col, head->length); - graph.nodes[head->idx].edges = add_edge(allocator, &graph, tail->idx, graph.nodes[head->idx].edges, variant); + va_array_append(allocator, graph.nodes, ((Node) {head->row, head->col, head->length, GVA_NULL, GVA_NULL})); + head->idx = va_array_length(graph.nodes) - 1; + va_array_append(allocator, graph.edges, ((Edge3) {tail->idx, graph.nodes[head->idx].edges})); + graph.nodes[head->idx].edges = va_array_length(graph.edges) - 1; } // if else if (!head->moved || !tail->moved) { - graph.nodes[head->idx].edges = add_edge(allocator, &graph, tail->idx, graph.nodes[head->idx].edges, variant); + va_array_append(allocator, graph.edges, ((Edge3) {tail->idx, graph.nodes[head->idx].edges})); + graph.nodes[head->idx].edges = va_array_length(graph.edges) - 1; } // if here = k; @@ -389,7 +394,8 @@ build3(VA_Allocator const allocator, else { source = (VA_LCS_Node3) {.row = shift, .col = shift, .length = 0}; - source.idx = add_node(allocator, &graph, source.row, source.col, source.length); + va_array_append(allocator, graph.nodes, ((Node) {source.row, source.col, source.length, GVA_NULL, GVA_NULL})); + source.idx = va_array_length(graph.nodes) - 1; } // else for (uint32_t i = head_idx; i != GVA_NULL; i = lcs.nodes[i].next) @@ -401,29 +407,10 @@ build3(VA_Allocator const allocator, eq_count += 1; - VA_Variant const variant = {source.row, lcs.nodes[i].row + lcs.nodes[i].length - 1, source.col - shift, lcs.nodes[i].col + lcs.nodes[i].length - 1 - shift}; - - graph.nodes[source.idx].edges = add_edge(allocator, &graph, lcs.nodes[i].idx, graph.nodes[source.idx].edges, variant); + va_array_append(allocator, graph.edges, ((Edge3) {lcs.nodes[i].idx, graph.nodes[source.idx].edges})); + graph.nodes[source.idx].edges = va_array_length(graph.edges) - 1; } // for - uint32_t min_source = GVA_NULL; - for (uint32_t i = graph.nodes[source.idx].edges; i != GVA_NULL; i = graph.edges[i].next) - { - min_source = MIN(min_source, graph.edges[i].variant.start); - } // for - - if (min_source != GVA_NULL) - { - uint32_t const min_offset = min_source - graph.nodes[source.idx].row; - graph.nodes[source.idx].row += min_offset; - graph.nodes[source.idx].col += min_offset; - graph.nodes[source.idx].length -= min_offset; - } // if - else - { - graph.nodes[source.idx].length = 0; - } // else - graph.source = source.idx; va_std_allocator.alloc(va_std_allocator.context, lcs.index, lcs.length * sizeof(*lcs.index), 0); diff --git a/src/graph2.c b/src/graph2.c index a3ce87a..3f31720 100644 --- a/src/graph2.c +++ b/src/graph2.c @@ -24,7 +24,7 @@ size_t eq_count; static uint32_t const GVA_NULL = UINT32_MAX; -static uint32_t +uint32_t edges2(VA_LCS_Node const head, VA_LCS_Node const tail, bool const is_source, bool const is_sink, VA_Variant* const variant) diff --git a/src/main.c b/src/main.c index 553cde7..58a575e 100644 --- a/src/main.c +++ b/src/main.c @@ -148,6 +148,35 @@ print_graph(Graph const graph, size_t const len_obs, char const observed[static } // print_graph +static void +print_graph3(Graph3 const graph, size_t const len_obs, char const observed[static len_obs]) { + fprintf(stderr, "#nodes: %zu\n#edges: %zu\n", va_array_length(graph.nodes), va_array_length(graph.edges)); + fprintf(stderr, "source: %u\n", graph.source); + if (graph.nodes == NULL) + { + return; + } // if + for (size_t i = 0; i < va_array_length(graph.nodes); ++i) { + fprintf(stderr, "%zu: (%u, %u, %u):\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length); + if (graph.nodes[i].lambda != GVA_NULL) { + fprintf(stderr, " (%u, %u, %u): lambda\n", graph.nodes[graph.nodes[i].lambda].row, graph.nodes[graph.nodes[i].lambda].col, graph.nodes[graph.nodes[i].lambda].length); + } // if + for (uint32_t j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) { + fprintf(stderr, " %u: (%u, %u, %u): ", graph.edges[j].tail, graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length); + VA_Variant variant; + uint32_t const count = edges2( + ((VA_LCS_Node) {.row = graph.nodes[i].row, .col = graph.nodes[i].col, .length = graph.nodes[i].length}), + ((VA_LCS_Node) {.row = graph.nodes[graph.edges[j].tail].row, .col = graph.nodes[graph.edges[j].tail].col, .length = graph.nodes[graph.edges[j].tail].length}), + i == graph.source, + graph.nodes[graph.edges[j].tail].edges == GVA_NULL && graph.nodes[graph.edges[j].tail].edges == GVA_NULL, + &variant); + fprintf(stderr, VAR_FMT " x %u\n", print_variant(variant, observed), count); + } // for + } // for +} // print_graph3 + + + int main(int argc, char* argv[static argc + 1]) { @@ -197,11 +226,15 @@ main(int argc, char* argv[static argc + 1]) size_t const len_ref = strlen(reference); size_t const len_obs = strlen(observed); - Graph graph = build3(va_std_allocator, len_ref, reference, len_obs, observed, 0); - print_graph(graph, len_obs, observed); - to_json(graph, len_obs, observed, false); + Graph3 graph = build3(va_std_allocator, len_ref, reference, len_obs, observed, 0); + print_graph3(graph, len_obs, observed); + + va_array_destroy(va_std_allocator, graph.nodes); + va_array_destroy(va_std_allocator, graph.edges); + + //to_json(graph, len_obs, observed, false); - destroy(va_std_allocator, &graph); + //destroy(va_std_allocator, &graph); /* VA_LCS_Node** lcs_nodes = NULL; size_t const len_lcs = va_edit(va_std_allocator, len_ref, reference, len_obs, observed, &lcs_nodes); From ab7856dd6b906d4ade29dcb52aa4e39fe9b2f907 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 5 Jun 2025 16:18:34 +0200 Subject: [PATCH 215/704] Deduplicated graph --- include/graph.h | 4 + src/edit3.c | 4 +- src/graph.c | 241 ++++++++++++++++++++++++++++++++++++++++-------- src/main.c | 13 ++- 4 files changed, 215 insertions(+), 47 deletions(-) diff --git a/include/graph.h b/include/graph.h index 2d60e05..77d2710 100644 --- a/include/graph.h +++ b/include/graph.h @@ -75,6 +75,10 @@ void to_json(Graph const graph, size_t const len_obs, char const observed[static len_obs], bool const lambda); +void +to_json3(Graph3 const graph, size_t const len_obs, char const observed[static len_obs]); + + size_t edges(uint32_t const head_row, uint32_t const head_col, uint32_t const head_length, uint32_t const tail_row, uint32_t const tail_col, uint32_t const tail_length, diff --git a/src/edit3.c b/src/edit3.c index f460a0f..0c88495 100644 --- a/src/edit3.c +++ b/src/edit3.c @@ -87,7 +87,7 @@ expand(Context const context, ptrdiff_t const d_col = context.len_obs - col; size_t const lcs_pos = (row + col - imaxabs(delta) - 2 * p + imaxabs(d_row - d_col)) / 2 - 1; size_t const length = row - match_row; - va_array_append(context.allocator, lcs->nodes, ((VA_LCS_Node3) {match_row, match_col, length, false, -1, -1, -1})); + va_array_append(context.allocator, lcs->nodes, ((VA_LCS_Node3) {match_row, match_col, length, false, 0, -1, -1})); if (lcs->index[lcs_pos].head != (uint32_t) -1) { lcs->nodes[lcs->index[lcs_pos].tail].next = va_array_length(lcs->nodes) - 1; @@ -126,7 +126,7 @@ expand(Context const context, ptrdiff_t const d_col = context.len_obs - col; size_t const lcs_pos = (row + col - imaxabs(delta) - 2 * p + imaxabs(d_row - d_col)) / 2 - 1; size_t const length = row - match_row; - va_array_append(context.allocator, lcs->nodes, ((VA_LCS_Node3) {match_row, match_col, length, false, -1, -1, -1})); + va_array_append(context.allocator, lcs->nodes, ((VA_LCS_Node3) {match_row, match_col, length, false, 0, -1, -1})); if (lcs->index[lcs_pos].head != (uint32_t) -1) { lcs->nodes[lcs->index[lcs_pos].tail].next = va_array_length(lcs->nodes) - 1; diff --git a/src/graph.c b/src/graph.c index a2f8d08..d331e6c 100644 --- a/src/graph.c +++ b/src/graph.c @@ -48,6 +48,40 @@ destroy(VA_Allocator const allocator, Graph* const graph) } // destroy +static uint32_t +edges42(Node const head, Node const tail, + bool const is_source, bool const is_sink, + VA_Variant* const variant) +{ +// printf("%u %u %u -> %u %u %u %s %s\n", head.row, head.col, head.length, tail.row, tail.col, tail.length, is_source ? "SOURCE" : "", is_sink ? "SINK" : ""); + + intmax_t const row = (intmax_t) head.row - is_source; + intmax_t const col = (intmax_t) head.col - is_source; + uint32_t const head_length = head.length + is_source; + uint32_t const tail_length = tail.length + is_sink; + + intmax_t const offset = MIN((intmax_t) tail.row - row, (intmax_t) tail.col - col) - 1; + + uint32_t const head_offset = offset > 0 ? MIN(head_length, offset + 1) : 1; + uint32_t const tail_offset = offset < 0 ? MIN(tail_length, -offset) : 0; + + //printf(" %ld: (%u, %u)\n", offset, head_offset, tail_offset); + + if (head_offset > head_length || (tail_length > 0 && tail_offset >= tail_length)) + { + //fprintf(stderr, "NO EDGE\n"); + return 0; + } // if + + uint32_t const count = MIN(head_length - head_offset, tail_length - tail_offset - 1) + 1; + + *variant = (VA_Variant) {row + head_offset, tail.row + tail_offset, col + head_offset, tail.col + tail_offset}; + + //fprintf(stderr, VAR_FMT " x %u\n", print_variant((*variant), observed), count); + return count; +} // edges42 + + Graph build_graph(VA_Allocator const allocator, size_t const len_ref, size_t const len_obs, @@ -297,7 +331,6 @@ build3(VA_Allocator const allocator, sink.idx = va_array_length(graph.nodes) - 1; tail_idx = GVA_NULL; } // else - for (uint32_t i = lcs.index[lcs.length - 1].head; i != tail_idx; i = lcs.nodes[i].next) { eq_count += 1; @@ -308,7 +341,7 @@ build3(VA_Allocator const allocator, graph.nodes[lcs.nodes[i].idx].edges = va_array_length(graph.edges) - 1; } // for - for (size_t i = lcs.length - 1; i >= 1; --i) + for (uint32_t i = lcs.length - 1; i >= 1; --i) { uint32_t next = GVA_NULL; for (uint32_t j = lcs.index[i].head; j != GVA_NULL; j = next) @@ -323,46 +356,44 @@ build3(VA_Allocator const allocator, uint32_t here = GVA_NULL; for (uint32_t k = lcs.index[i - 1].head; k != GVA_NULL; k = lcs.nodes[k].next) { + VA_LCS_Node3* const head = &lcs.nodes[k]; eq_count += 1; - if (k > j) + if (k > j || + head->row + head->length >= tail->row + tail->length || + head->col + head->length >= tail->col + tail->length) { continue; } // if - VA_LCS_Node3* const head = &lcs.nodes[k]; - - if (head->row + head->length < tail->row + tail->length && - head->col + head->length < tail->col + tail->length) + here = k; + if (head->incoming == i) { - if (head->incoming == i) - { - uint32_t const split_idx = head->idx; - va_array_append(allocator, graph.nodes, ((Node) {head->row, head->col, head->length, GVA_NULL, split_idx})); - head->idx = va_array_length(graph.nodes) - 1; - head->incoming = 0; - - graph.nodes[split_idx].row += head->length; - graph.nodes[split_idx].col += head->length; - graph.nodes[split_idx].length -= head->length; - - va_array_append(allocator, graph.edges, ((Edge3) {tail->idx, graph.nodes[head->idx].edges})); - graph.nodes[head->idx].edges = va_array_length(graph.edges) - 1; - } // if - else if (head->idx == GVA_NULL) - { - va_array_append(allocator, graph.nodes, ((Node) {head->row, head->col, head->length, GVA_NULL, GVA_NULL})); - head->idx = va_array_length(graph.nodes) - 1; - va_array_append(allocator, graph.edges, ((Edge3) {tail->idx, graph.nodes[head->idx].edges})); - graph.nodes[head->idx].edges = va_array_length(graph.edges) - 1; - } // if - else if (!head->moved || !tail->moved) - { - va_array_append(allocator, graph.edges, ((Edge3) {tail->idx, graph.nodes[head->idx].edges})); - graph.nodes[head->idx].edges = va_array_length(graph.edges) - 1; - } // if + uint32_t const split_idx = head->idx; + va_array_append(allocator, graph.nodes, ((Node) {head->row, head->col, head->length, GVA_NULL, split_idx})); + head->idx = va_array_length(graph.nodes) - 1; + head->moved = false; + head->incoming = 0; + + graph.nodes[split_idx].row += head->length; + graph.nodes[split_idx].col += head->length; + graph.nodes[split_idx].length -= head->length; + + va_array_append(allocator, graph.edges, ((Edge3) {tail->idx, graph.nodes[head->idx].edges})); + graph.nodes[head->idx].edges = va_array_length(graph.edges) - 1; + } // if + else if (head->idx == GVA_NULL) + { + va_array_append(allocator, graph.nodes, ((Node) {head->row, head->col, head->length, GVA_NULL, GVA_NULL})); + head->idx = va_array_length(graph.nodes) - 1; - here = k; + va_array_append(allocator, graph.edges, ((Edge3) {tail->idx, graph.nodes[head->idx].edges})); + graph.nodes[head->idx].edges = va_array_length(graph.edges) - 1; + } // if + else if (!head->moved || !tail->moved) + { + va_array_append(allocator, graph.edges, ((Edge3) {tail->idx, graph.nodes[head->idx].edges})); + graph.nodes[head->idx].edges = va_array_length(graph.edges) - 1; } // if } // for @@ -397,19 +428,38 @@ build3(VA_Allocator const allocator, va_array_append(allocator, graph.nodes, ((Node) {source.row, source.col, source.length, GVA_NULL, GVA_NULL})); source.idx = va_array_length(graph.nodes) - 1; } // else - for (uint32_t i = head_idx; i != GVA_NULL; i = lcs.nodes[i].next) { if (lcs.nodes[i].idx == GVA_NULL) { continue; } // if - eq_count += 1; - va_array_append(allocator, graph.edges, ((Edge3) {lcs.nodes[i].idx, graph.nodes[source.idx].edges})); - graph.nodes[source.idx].edges = va_array_length(graph.edges) - 1; + if (source.length == 0 || !lcs.nodes[i].moved) + { + va_array_append(allocator, graph.edges, ((Edge3) {lcs.nodes[i].idx, graph.nodes[source.idx].edges})); + graph.nodes[source.idx].edges = va_array_length(graph.edges) - 1; + } // if + } // for + + uint32_t min_source = -1; + for (uint32_t i = graph.nodes[source.idx].edges; i != GVA_NULL; i = graph.edges[i].next) + { + VA_Variant variant; + edges42(graph.nodes[source.idx], graph.nodes[graph.edges[i].tail], true, false, &variant); + min_source = MIN(min_source, variant.start); } // for + if (min_source != (uint32_t) -1) + { + graph.nodes[source.idx].row += min_source; + graph.nodes[source.idx].col += min_source; + graph.nodes[source.idx].length -= min_source; + } // if + else + { + graph.nodes[source.idx].length = 0; + } // else graph.source = source.idx; @@ -573,6 +623,121 @@ to_json(Graph const graph, size_t const len_obs, char const observed[static len_ } // to_json +static size_t +bfs_traversal3(Graph3 const graph, size_t const len_obs, char const observed[static len_obs]) +{ + struct + { + uint32_t depth; + uint32_t next; + }* table = va_std_allocator.alloc(va_std_allocator.context, NULL, 0, sizeof(*table) * va_array_length(graph.nodes)); + + if (table == NULL) + { + return -1; + } // if + + for (size_t i = 0; i < va_array_length(graph.nodes); ++i) + { + table[i].depth = 0; + table[i].next = GVA_NULL; + } // for + uint32_t head = graph.source; + uint32_t tail = graph.source; + + size_t count = 0; + fprintf(stderr, "digraph{\nrankdir=LR\nedge[fontname=monospace]\nnode[fixedsize=true,fontname=serif,shape=circle,width=1]\nsi[label=\"\",shape=none,width=0]\n"); + fprintf(stderr, "si->s%u\n", graph.source); + + bool first = true; + + printf(" \"edges\": [\n"); + while (head != GVA_NULL) + { + uint32_t len = graph.nodes[head].length; + //printf("pop %u\n", head); + for (uint32_t i = head; i != GVA_NULL; i = graph.nodes[i].lambda) + { + fprintf(stderr, "s%u[label=\"(%u, %u, %u)\"%s]\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, graph.nodes[i].edges == GVA_NULL && graph.nodes[i].lambda == GVA_NULL ? ",peripheries=2" : ""); + if (i != head) + { + len += graph.nodes[i].length; + //printf("lambda %u\n", i); + } // if + for (uint32_t j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) + { + if (count > 0) + { + //printf(",\n"); + } // if + count += 1; + VA_Variant variant; + uint32_t const count2 = edges2(((VA_LCS_Node) {.row = graph.nodes[i].row, .col =graph.nodes[i].col, .length = graph.nodes[i].length}), + ((VA_LCS_Node) {.row = graph.nodes[graph.edges[j].tail].row, .col = graph.nodes[graph.edges[j].tail].col, .length = graph.nodes[graph.edges[j].tail].length}), + graph.nodes[head].row == graph.nodes[graph.source].row && graph.nodes[head].col == graph.nodes[graph.source].col, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, &variant); + + for (uint32_t k = 0; k < count2; ++k) + { + if (!first) + { + printf(",\n"); + } // if + first = false; + fprintf(stderr, "s%u->s%u[label=\"" VAR_FMT "\"]\n", head, graph.edges[j].tail, print_variant(variant, observed)); + printf(" {\"head\": \"s%u\", \"tail\": \"s%u\", \"variant\": \"" VAR_FMT "\"}", head, graph.edges[j].tail, print_variant(variant, observed)); + variant.start += 1; + variant.end += 1; + variant.obs_start += 1; + variant.obs_end += 1; + } // for + + if (table[graph.edges[j].tail].depth > 0) + { + //printf("skip %u\n", graph.edges[j].tail); + continue; + } // if + + //printf("push %u\n", graph.edges[j].tail); + table[graph.edges[j].tail].depth = table[i].depth + 1; + table[tail].next = graph.edges[j].tail; + tail = graph.edges[j].tail; + } // for + } // for + head = table[head].next; + + /* + printf(" # \tdepth\tnext\n"); + for (size_t i = 0; i < va_array_length(graph.nodes); ++i) + { + printf("%3zu:\t%5u\t%4d\n", i, table[i].depth, table[i].next); + } // for + printf("head: %d\ntail: %d\n", head, tail); + */ + } // while + + fprintf(stderr, "}\n"); + printf("\n ]\n"); + + table = va_std_allocator.alloc(va_std_allocator.context, table, sizeof(*table) * va_array_length(graph.nodes), 0); + + return count; +} // bfs_traversal3 + + +void +to_json3(Graph3 const graph, size_t const len_obs, char const observed[static len_obs]) +{ + printf("{\n \"source\": \"s%u\",\n \"nodes\": {\n", graph.source); + for (uint32_t i = 0; i < va_array_length(graph.nodes); ++i) + { + printf(" \"s%u\": {\"row\": %u, \"col\": %u, \"length\": %u}%s\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, i < va_array_length(graph.nodes) - 1 ? "," : ""); + } // for + printf(" },\n"); + bfs_traversal3(graph, len_obs, observed); + printf("}"); +} // to_json3 + + size_t edges(uint32_t const head_row, uint32_t const head_col, uint32_t const head_length, uint32_t const tail_row, uint32_t const tail_col, uint32_t const tail_length, diff --git a/src/main.c b/src/main.c index 58a575e..af81ec8 100644 --- a/src/main.c +++ b/src/main.c @@ -176,7 +176,6 @@ print_graph3(Graph3 const graph, size_t const len_obs, char const observed[stati } // print_graph3 - int main(int argc, char* argv[static argc + 1]) { @@ -192,14 +191,14 @@ main(int argc, char* argv[static argc + 1]) //VA_LCS_Node** lcs_nodes = NULL; //size_t const len_lcs = va_edit(va_std_allocator, len_ref, reference, len_obs, observed, &lcs_nodes); //Graph graph = build_graph(va_std_allocator, len_ref, len_obs, len_lcs, lcs_nodes, 0, false); - Graph graph = build3(va_std_allocator, len_ref, reference, len_obs, observed, 0); + Graph3 graph = build3(va_std_allocator, len_ref, reference, len_obs, observed, 0); printf("nodes: %zu\nedges: %zu\n", va_array_length(graph.nodes), va_array_length(graph.edges)); printf("%zu\n", eq_count); - destroy(va_std_allocator, &graph); + va_array_destroy(va_std_allocator, graph.nodes); + va_array_destroy(va_std_allocator, graph.edges); return 0; */ - if (argc == 2) { srand(atoi(argv[1])); @@ -228,6 +227,7 @@ main(int argc, char* argv[static argc + 1]) Graph3 graph = build3(va_std_allocator, len_ref, reference, len_obs, observed, 0); print_graph3(graph, len_obs, observed); + to_json3(graph, len_obs, observed); va_array_destroy(va_std_allocator, graph.nodes); va_array_destroy(va_std_allocator, graph.edges); @@ -236,9 +236,6 @@ main(int argc, char* argv[static argc + 1]) //destroy(va_std_allocator, &graph); /* - VA_LCS_Node** lcs_nodes = NULL; - size_t const len_lcs = va_edit(va_std_allocator, len_ref, reference, len_obs, observed, &lcs_nodes); - for (size_t i = 0; i < len_lcs; ++i) { fprintf(stderr, "%2zu: ", i); @@ -257,6 +254,8 @@ main(int argc, char* argv[static argc + 1]) */ //to_json2(graph2, len_obs, observed); /* + VA_LCS_Node** lcs_nodes = NULL; + size_t const len_lcs = va_edit(va_std_allocator, len_ref, reference, len_obs, observed, &lcs_nodes); eq_count = 0; Graph graph_old = build_graph(va_std_allocator, len_ref, len_obs, len_lcs, lcs_nodes, 0, false); fprintf(stderr, "old count: %zu\n\n", eq_count); From 2b61901ae3da30779dca92ee0ee4b08d133a32b1 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 5 Jun 2025 23:17:51 +0200 Subject: [PATCH 216/704] Refactored --- LICENSE | 2 +- include/alloc.h | 23 - include/allocator.h | 26 + include/array.h | 59 -- include/edit.h | 104 ---- include/extract.h | 9 - include/graph.h | 91 ---- include/graph2.h | 41 -- include/lcs_graph.h | 72 +++ include/parser.h | 28 - include/static_alloc.h | 81 --- include/std_alloc.h | 33 +- include/types.h | 18 + include/variant.h | 42 -- javascript/.gitignore | 1 - javascript/Makefile | 10 - javascript/http_server.py | 29 - javascript/index.html | 11 - javascript/main.js | 7 - javascript/modules/algebra.js | 10 - javascript/modules/algebra/lcs.js | 9 - javascript/modules/wasm.js | 144 ----- javascript/wasm/wasm.h | 55 -- javascript/wasm/wrapper.c | 15 - python/.gitignore | 4 - python/README.md | 0 python/algebra/__init__.py | 4 - python/algebra/__main__.py | 13 - python/algebra/variants/__init__.py | 5 - python/ext/algebra_ext.c | 68 --- python/ext/lcs_ext.c | 44 -- python/include | 1 - python/setup.cfg | 24 - python/setup.py | 18 - python/src | 1 - python/tests/test_edit.py | 5 - regres.sh | 1 - src/array.c | 97 ++-- src/array.h | 78 +++ src/base.h | 20 + src/edit.c | 233 +++----- src/edit.h | 40 ++ src/edit2.c | 234 -------- src/edit3.c | 217 -------- src/extract.c | 359 ------------- src/graph.c | 807 ---------------------------- src/graph2.c | 580 -------------------- src/lcs_graph.c | 230 ++++++++ src/main.c | 376 +++++-------- src/parser.c | 319 ----------- src/variant.c | 77 --- tests/test_array.c | 123 ----- tests/test_edit.c | 60 --- tests/test_parser.c | 394 -------------- tests/test_variant.c | 113 ---- 55 files changed, 755 insertions(+), 4710 deletions(-) delete mode 100644 include/alloc.h create mode 100644 include/allocator.h delete mode 100644 include/array.h delete mode 100644 include/edit.h delete mode 100644 include/extract.h delete mode 100644 include/graph.h delete mode 100644 include/graph2.h create mode 100644 include/lcs_graph.h delete mode 100644 include/parser.h delete mode 100644 include/static_alloc.h create mode 100644 include/types.h delete mode 100644 include/variant.h delete mode 100644 javascript/.gitignore delete mode 100644 javascript/Makefile delete mode 100644 javascript/http_server.py delete mode 100644 javascript/index.html delete mode 100644 javascript/main.js delete mode 100644 javascript/modules/algebra.js delete mode 100644 javascript/modules/algebra/lcs.js delete mode 100644 javascript/modules/wasm.js delete mode 100644 javascript/wasm/wasm.h delete mode 100644 javascript/wasm/wrapper.c delete mode 100644 python/.gitignore delete mode 100644 python/README.md delete mode 100644 python/algebra/__init__.py delete mode 100644 python/algebra/__main__.py delete mode 100644 python/algebra/variants/__init__.py delete mode 100644 python/ext/algebra_ext.c delete mode 100644 python/ext/lcs_ext.c delete mode 120000 python/include delete mode 100644 python/setup.cfg delete mode 100644 python/setup.py delete mode 120000 python/src delete mode 100644 python/tests/test_edit.py create mode 100644 src/array.h create mode 100644 src/base.h create mode 100644 src/edit.h delete mode 100644 src/edit2.c delete mode 100644 src/edit3.c delete mode 100644 src/extract.c delete mode 100644 src/graph.c delete mode 100644 src/graph2.c create mode 100644 src/lcs_graph.c delete mode 100644 src/parser.c delete mode 100644 src/variant.c delete mode 100644 tests/test_array.c delete mode 100644 tests/test_edit.c delete mode 100644 tests/test_parser.c delete mode 100644 tests/test_variant.c diff --git a/LICENSE b/LICENSE index 9adf916..780503f 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2024 Leiden University Medical Center +Copyright (c) 2025 Leiden University Medical Center Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/include/alloc.h b/include/alloc.h deleted file mode 100644 index 0e9a68c..0000000 --- a/include/alloc.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef ALLOC_H -#define ALLOC_H - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include // size_t - - -typedef struct -{ - void* (*alloc)(void* const restrict context, void* const restrict ptr, size_t const old_size, size_t const size); - void* context; -} VA_Allocator; - - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif diff --git a/include/allocator.h b/include/allocator.h new file mode 100644 index 0000000..21fcf91 --- /dev/null +++ b/include/allocator.h @@ -0,0 +1,26 @@ +#ifndef GVA_ALLOCATOR_H +#define GVA_ALLOCATOR_H + + +#include // size_t + + +// Generic allocator interface. Provides a single `allocate` function +// similar to `realloc` from libc. The following behavior is expected: +// - when `new_size` is zero, the function behaves like `free` and +// returns `NULL`. +// - when `new_size` is not zero, the function behaves like `realloc`. +// Returns `NULL` if the allocation request cannot be fulfilled. +// +// An opaque `context` may be provided and allows for custom allocators +// that can be scoped/threaded/aligned/etc. +// +// See `std_alloc.h` for a simple libc wrapper. +typedef struct +{ + void* (*allocate)(void* const restrict context, void* const restrict ptr, size_t const old_size, size_t const new_size); + void* context; +} GVA_Allocator; + + +#endif // GVA_ALLOCATOR_H diff --git a/include/array.h b/include/array.h deleted file mode 100644 index d098309..0000000 --- a/include/array.h +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef ARRAY_H -#define ARRAY_H - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include // NULL, size_t - -#include "alloc.h" // VA_Allocator - - -typedef struct -{ - size_t capacity; - size_t length; -} VA_Array; - - -void* -va_array_init(VA_Allocator const allocator, size_t const capacity, size_t const item_size); - - -VA_Array* -va_array_header(void* const ptr); - - -size_t -va_array_length(void* const ptr); - - -void* -va_array_grow(VA_Allocator const allocator, void* const restrict ptr, size_t const capacity, size_t const item_size); - - -size_t -va_array_shift(void* const ptr, size_t const index, size_t const item_size); - - -#define va_array_destroy(allocator, ptr) ((ptr) == NULL ? NULL : allocator.alloc(allocator.context, va_array_header(ptr), va_array_header(ptr)->capacity * sizeof(*(ptr)), 0)) - - -#define va_array_insert(allocator, ptr, value, index) do { \ - (ptr) = va_array_grow(allocator, ptr, 1, sizeof(*ptr)); \ - if ((ptr) == NULL) break; \ - (ptr)[va_array_shift(ptr, index, sizeof(*ptr))] = (value); \ - ++va_array_header(ptr)->length; \ -} while (0) - - -#define va_array_append(allocator, ptr, value) va_array_insert(allocator, ptr, value, va_array_length(ptr)) - - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif diff --git a/include/edit.h b/include/edit.h deleted file mode 100644 index 838a277..0000000 --- a/include/edit.h +++ /dev/null @@ -1,104 +0,0 @@ -#ifndef EDIT_H -#define EDIT_H - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include // size_t -#include // uint32_t - -#include "alloc.h" // VA_Allocator - - -typedef struct -{ - uint32_t head; - uint32_t tail; -} VA_LCS_List; - - -typedef struct -{ - uint32_t row; - uint32_t col; - uint32_t length; - uint32_t incoming; - uint32_t idx; -} VA_LCS_Node; - - -typedef struct -{ - uint32_t row; - uint32_t col; - uint32_t length; - uint32_t lcs_pos; - uint32_t next; - uint32_t inext; - uint32_t idx; - uint32_t outgoing; -} VA_LCS_Node2; - - -typedef struct -{ - uint32_t row; - uint32_t col; - uint32_t length : 31; - uint32_t moved : 1; - uint32_t incoming; - uint32_t idx; - uint32_t next; -} VA_LCS_Node3; - - -typedef struct -{ - size_t length; - struct - { - uint32_t head; - uint32_t tail; - }* index; - VA_LCS_Node3* nodes; -} VA_LCS; - - -VA_LCS -va_edit3(VA_Allocator const allocator, - size_t const len_ref, char const reference[static restrict len_ref], - size_t const len_obs, char const observed[static restrict len_obs]); - - -size_t -va_edit_distance_only(VA_Allocator const allocator, - size_t const len_ref, - char const reference[static restrict len_ref], - size_t const len_obs, - char const observed[static restrict len_obs]); - - -size_t -va_edit(VA_Allocator const allocator, - size_t const len_ref, - char const reference[static restrict len_ref], - size_t const len_obs, - char const observed[static restrict len_obs], - VA_LCS_Node*** restrict lcs_nodes); - - -size_t -va_edit2(VA_Allocator const allocator, - size_t const len_ref, char const reference[static restrict len_ref], - size_t const len_obs, char const observed[static restrict len_obs], - VA_LCS_List** restrict lcs_index, - VA_LCS_Node2** restrict lcs_nodes); - - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif diff --git a/include/extract.h b/include/extract.h deleted file mode 100644 index c233ddd..0000000 --- a/include/extract.h +++ /dev/null @@ -1,9 +0,0 @@ -#include "../include/alloc.h" // VA_Allocator -#include "../include/graph.h" // Graph - - -void -local_supremal(VA_Allocator const allocator, Graph const graph, size_t const len_obs, char const observed[static len_obs], bool const debug); - -void -canonical(VA_Allocator const allocator, Graph const graph, size_t const len_obs, char const observed[static len_obs], bool const debug); diff --git a/include/graph.h b/include/graph.h deleted file mode 100644 index 77d2710..0000000 --- a/include/graph.h +++ /dev/null @@ -1,91 +0,0 @@ -#include // uint32_t -#include "../include/edit.h" // VA_LCS_Node -#include "../include/variant.h" // VA_Variant - -extern size_t eq_count; - - -typedef struct -{ - uint32_t tail; - uint32_t next; - VA_Variant variant; -} Edge; - - -typedef struct -{ - uint32_t row; - uint32_t col; - uint32_t length; - uint32_t edges; - uint32_t lambda; -} Node; - - -typedef struct -{ - Node* nodes; - Edge* edges; - VA_Variant supremal; - uint32_t source; -} Graph; - - -typedef struct -{ - uint32_t tail; - uint32_t next; -} Edge3; - - -typedef struct -{ - Node* nodes; - Edge3* edges; - uint32_t source; -} Graph3; - - -uint32_t -edges2(VA_LCS_Node const head, VA_LCS_Node const tail, - bool const is_source, bool const is_sink, - VA_Variant* const variant); - - -Graph3 -build3(VA_Allocator const allocator, - size_t const len_ref, char const reference[static restrict len_ref], - size_t const len_obs, char const observed[static restrict len_obs], - size_t const shift); - - -Graph -build_graph(VA_Allocator const allocator, - size_t const len_ref, size_t const len_obs, - size_t const len_lcs, VA_LCS_Node* lcs_nodes[static len_lcs], - size_t const shift, bool const debug); - - -void -to_dot(Graph const graph, size_t const len_obs, char const observed[static len_obs]); - - -void -to_json(Graph const graph, size_t const len_obs, char const observed[static len_obs], bool const lambda); - - -void -to_json3(Graph3 const graph, size_t const len_obs, char const observed[static len_obs]); - - -size_t -edges(uint32_t const head_row, uint32_t const head_col, uint32_t const head_length, - uint32_t const tail_row, uint32_t const tail_col, uint32_t const tail_length, - bool const is_source, - size_t const len_obs, char const observed[static len_obs], - VA_Variant const edge); - - -void -destroy(VA_Allocator const allocator, Graph* const graph); diff --git a/include/graph2.h b/include/graph2.h deleted file mode 100644 index b4f923c..0000000 --- a/include/graph2.h +++ /dev/null @@ -1,41 +0,0 @@ -#include // uint32_t -#include "../include/edit.h" // VA_LCS_Node -#include "../include/variant.h" // VA_Variant - - -extern size_t eq_count; - - -typedef struct -{ - uint32_t tail; - uint32_t next; -} Edge2; - - -typedef struct -{ - uint32_t row; - uint32_t col; - uint32_t length; - uint32_t edges; - uint32_t lambda; -} Node2; - - -typedef struct -{ - Node2* nodes; - Edge2* edges; - uint32_t source; -} Graph2; - - -Graph2 -build(size_t const len_ref, char const reference[static restrict len_ref], - size_t const len_obs, char const observed[static restrict len_obs], - size_t const shift); - - -void -to_json2(Graph2 const graph, size_t const len_obs, char const observed[static len_obs]); diff --git a/include/lcs_graph.h b/include/lcs_graph.h new file mode 100644 index 0000000..b9eaada --- /dev/null +++ b/include/lcs_graph.h @@ -0,0 +1,72 @@ +#ifndef GVA_LCS_GRAPH_H +#define GVA_LCS_GRAPH_H + + +#include // bool +#include // size_t + +#include "allocator.h" // GVA_Allocator +#include "types.h" // gva_uint + + +// Internal: Each edge tracks its tail as an index to a node (in the +// nodes array in a graph) as well as a possible `next` edge; a +// singly linked list for all edges that belong to a particular node. +typedef struct +{ + gva_uint tail; + gva_uint next; +} GVA_Edge; + + +// Internal: The triple (`row`, `col`, `length`) uniquely defines each +// node in the graph. Its outgoing edges are found in the edges array of +// graph as a singly linked list with `edges` as entry point. +// A possible `lambda` edge is given as an index to another node. +typedef struct +{ + gva_uint row; + gva_uint col; + gva_uint length; + gva_uint edges; + gva_uint lambda; +} GVA_Node; + + +// The LCS graph stores arrays of nodes and edges with `source` as the +// entry point in the `nodes` array. +typedef struct +{ + GVA_Node* nodes; + GVA_Edge* edges; + gva_uint source; +} GVA_LCS_Graph; + + +typedef struct +{ + gva_uint start; + gva_uint end; + gva_uint obs_start; + gva_uint obs_end; +} GVA_Variant; + + +GVA_LCS_Graph +gva_lcs_graph_init(GVA_Allocator const allocator, + size_t const len_ref, char const reference[static restrict len_ref], + size_t const len_obs, char const observed[static restrict len_obs], + size_t const shift); + + +void +gva_lcs_graph_destroy(GVA_Allocator const allocator, GVA_LCS_Graph self); + + +gva_uint +gva_edges(GVA_Node const head, GVA_Node const tail, + bool const is_source, bool const is_sink, + GVA_Variant* const variant); + + +#endif // GVA_LCS_GRAPH_H diff --git a/include/parser.h b/include/parser.h deleted file mode 100644 index 56c7779..0000000 --- a/include/parser.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef PARSER_H -#define PARSER_H - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include // size_t - -#include "variant.h" // VA_Variant - - -size_t -va_parse_hgvs(size_t const len, char const expression[static len], - size_t const len_var, VA_Variant variants[static len_var]); - - -size_t -va_parse_spdi(size_t const len, char const expression[static len], - VA_Variant variants[static 1]); - - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif diff --git a/include/static_alloc.h b/include/static_alloc.h deleted file mode 100644 index 026bd6c..0000000 --- a/include/static_alloc.h +++ /dev/null @@ -1,81 +0,0 @@ -#ifndef STATIC_ALLOC_H -#define STATIC_ALLOC_H - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include // NULL, size_t - - -#define KiB(size) (((size_t) (size)) * 1024ULL) -#define MiB(size) (KiB(size) * 1024ULL) -#define GiB(size) (MiB(size) * 1024ULL) - - -#define VA_STATIC_BUFFER_SIZE MiB(50) - - -typedef struct -{ - size_t _size; - size_t free; - char data[VA_STATIC_BUFFER_SIZE]; -} VA_Static_Buffer; - - -static VA_Static_Buffer va_static_buffer = { ._size = sizeof(va_static_buffer) }; - - -static void* -va_static_alloc(void* const restrict context, void* const restrict ptr, size_t const old_size, size_t const size) -{ - VA_Static_Buffer* const restrict buffer = context; - - if (size == 0) - { - return NULL; - } // if - - if (old_size >= size) - { - return ptr; - } // if - - if (ptr != NULL && old_size > 0) - { - if (sizeof(buffer->data) - buffer->free < old_size) - { - return NULL; // OOM - } // if - char const* const restrict src = ptr; - for (size_t i = 0; i < old_size; ++i) - { - buffer->data[buffer->free + i] = src[i]; - } // for - } // if - - if (sizeof(buffer->data) - buffer->free < size) - { - return NULL; // OOM - } // if - - void* const restrict new_ptr = buffer->data + buffer->free; - buffer->free += size; - return new_ptr; -} // va_static_alloc - - -static VA_Allocator const va_static_allocator = -{ - va_static_alloc, - &va_static_buffer -}; - - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif diff --git a/include/std_alloc.h b/include/std_alloc.h index 4cbdb4c..63524f3 100644 --- a/include/std_alloc.h +++ b/include/std_alloc.h @@ -1,30 +1,29 @@ -#ifndef STD_ALLOC_H -#define STD_ALLOC_H +// NOT FREESTANDING +#ifndef GVA_STD_ALLOC_H +#define GVA_STD_ALLOC_H -#ifdef __cplusplus -extern "C" -{ -#endif -#include // NULL, size_t -#include // free, realloc +#include // NULL, size_t +#include // free, realloc -#include "alloc.h" // VA_Allocator +#include "allocator.h" // GVA_Allocator +// Provides a simple global allocation strategy based on `realloc` from +// libc. static inline void* -va_std_alloc(void* const restrict context, void* const restrict ptr, size_t const old_size, size_t const size) +gva_std_allocate(void* const restrict context, void* const restrict ptr, size_t const old_size, size_t const new_size) { (void) context; (void) old_size; - if (size == 0) + if (new_size == 0) { free(ptr); return NULL; } // if - char* const restrict new_ptr = realloc(ptr, size); + void* const restrict new_ptr = realloc(ptr, new_size); if (new_ptr == NULL) { free(ptr); @@ -32,14 +31,10 @@ va_std_alloc(void* const restrict context, void* const restrict ptr, size_t cons } // if return new_ptr; -} // va_std_alloc - +} // va_std_allocate -static VA_Allocator const va_std_allocator = { .alloc = va_std_alloc }; +static GVA_Allocator const gva_std_allocator = { .allocate = gva_std_allocate }; -#ifdef __cplusplus -} // extern "C" -#endif -#endif +#endif // GVA_STD_ALLOC_H diff --git a/include/types.h b/include/types.h new file mode 100644 index 0000000..643c0cf --- /dev/null +++ b/include/types.h @@ -0,0 +1,18 @@ +#ifndef GVA_TYPES_H +#define GVA_TYPES_H + + +#include // uint32_t, UINT32_MAX + + +// An unsigned integer type to store any position on a reference +// sequence. For human DNA a 32-bit value is enough. +// Smaller integer types reduce storage requirements. +typedef uint32_t gva_uint; + + +// The maximum value for the `gva_uint` type. +static gva_uint const GVA_NULL = UINT32_MAX; + + +#endif // GVA_TYPES_H diff --git a/include/variant.h b/include/variant.h deleted file mode 100644 index 56a37fb..0000000 --- a/include/variant.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef VARIANT_H -#define VARIANT_H - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include // bool -#include // size_t -#include // uint32_t - - -typedef struct -{ - uint32_t start; - uint32_t end; - uint32_t obs_start; - uint32_t obs_end; -} VA_Variant; - - -bool -va_variant_eq(VA_Variant const lhs, VA_Variant const rhs); - - -size_t -va_variant_len(VA_Variant const variant); - - -size_t -va_patch(size_t const len_ref, char const reference[static len_ref], - size_t const len_obs, char const observed[static len_obs], - size_t const len_var, VA_Variant const variants[len_var], - size_t const len, char string[static len]); - - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif diff --git a/javascript/.gitignore b/javascript/.gitignore deleted file mode 100644 index 19e1bce..0000000 --- a/javascript/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.wasm diff --git a/javascript/Makefile b/javascript/Makefile deleted file mode 100644 index 690f790..0000000 --- a/javascript/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -CC = clang-15 - -CFLAGS = -std=c99 -Wall -Wextra -Wpedantic -O3 \ - --target=wasm32 -nostdlib \ - -Wl,--no-entry, -Wl,--allow-undefined, -Wl,--import-memory, \ - -Wl,--export=__heap_base - -algebra.wasm: wasm/wrapper.c wasm/wasm.h Makefile - $(CC) $(CFLAGS) -o $@ ../src/edit.c $< - chmod -X $@ diff --git a/javascript/http_server.py b/javascript/http_server.py deleted file mode 100644 index b101866..0000000 --- a/javascript/http_server.py +++ /dev/null @@ -1,29 +0,0 @@ -from http.server import SimpleHTTPRequestHandler -from socketserver import TCPServer -import sys - - -def main(): - class HttpRequestHandler(SimpleHTTPRequestHandler): - extensions_map = { - "" : "application/octet-stream", - ".html": "text/html", - ".js" : "application/x-javascript", - ".wasm": "application/wasm", - } - - port = 8000 - if len(sys.argv) > 1: - port = int(sys.argv[1]) - - with TCPServer(("localhost", port), HttpRequestHandler) as httpd: - server_ip, server_port = httpd.server_address - print(f"Serving HTTP on {server_ip} port {server_port} (http://{server_ip}:{server_port}/) ...", file=sys.stderr) - try: - httpd.serve_forever() - except KeyboardInterrupt: - print("Keyboard interrupt received, exiting.", file=sys.stderr) - - -if __name__ == "__main__": - main() diff --git a/javascript/index.html b/javascript/index.html deleted file mode 100644 index a0b01e1..0000000 --- a/javascript/index.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - -WASM Algebra sandbox - - - - - diff --git a/javascript/main.js b/javascript/main.js deleted file mode 100644 index e0d457b..0000000 --- a/javascript/main.js +++ /dev/null @@ -1,7 +0,0 @@ -import { algebra } from "./modules/algebra.js"; -import { edit } from "./modules/algebra/lcs.js"; - - -console.log(algebra.hello(5)); -console.log(algebra.lcs.edit(4)); -console.log(edit(4, 2)); diff --git a/javascript/modules/algebra.js b/javascript/modules/algebra.js deleted file mode 100644 index 2e52d33..0000000 --- a/javascript/modules/algebra.js +++ /dev/null @@ -1,10 +0,0 @@ -import { wasmInstance } from "./wasm.js"; -import * as lcs from "./algebra/lcs.js"; - - -export const algebra = await wasmInstance("./algebra.wasm").then(wasm => { - return { - lcs, - hello: (lhs, rhs) => lhs * (rhs ?? 42), - }; -}); diff --git a/javascript/modules/algebra/lcs.js b/javascript/modules/algebra/lcs.js deleted file mode 100644 index 7f584bc..0000000 --- a/javascript/modules/algebra/lcs.js +++ /dev/null @@ -1,9 +0,0 @@ -import { wasmInstance } from "../wasm.js"; - - -export let edit; - - -await wasmInstance("./algebra.wasm").then(wasm => { - edit = (lhs, rhs) => wasm.exports.edit(lhs, rhs ?? 42); -}); diff --git a/javascript/modules/wasm.js b/javascript/modules/wasm.js deleted file mode 100644 index 2306021..0000000 --- a/javascript/modules/wasm.js +++ /dev/null @@ -1,144 +0,0 @@ -export function wasmInstance(path, initial_pages=2) { - const utf8decoder = new TextDecoder(); - let heap_blocks; - - const imports = { env : { - memory: new WebAssembly.Memory({ - initial: initial_pages, - }), - - console_log: function(len, msg) { - if (msg === 0) { - console.log(len); - return; - } // if - console.log(utf8decoder.decode(new Uint8Array(imports.env.memory.buffer, msg, len))); - }, - - free: function(address) { - console.groupCollapsed(`free(0x${address.toString(16)})`); - if (address === null || address === 0) { - console.log("freeing null"); - console.groupEnd(); - return; - } // if - const len = heap_blocks.length; - for (let idx = 0; idx < len; ++idx) { - let heap_block = heap_blocks[idx]; - if (heap_block.address === address) { - console.log(`found heap block ${idx}`); - if (heap_block.free) { - console.warn(`double free at 0x${address.toString(16)}`); - console.groupEnd(); - return; - } // if - heap_block.free = true; - if (idx > 0 && heap_blocks[idx - 1].free) { - console.log(`coalesce with heap block ${idx - 1}`); - heap_blocks[idx - 1].size += heap_block.size; - heap_blocks.splice(idx, 1); - idx -= 1; - heap_block = heap_blocks[idx]; - } // if - if (idx < len - 1 && heap_blocks[idx + 1].free) { - console.log(`coalesce with heap block ${idx + 1}`); - heap_blocks[idx + 1].address = heap_block.address; - heap_blocks[idx + 1].size += heap_block.size; - heap_blocks.splice(idx, 1); - } // if - console.log("heap_blocks:", JSON.parse(JSON.stringify(heap_blocks))); - console.groupEnd(); - return; - } // if - } // for - console.warn(`illegal free at 0x${address.toString(16)}`); - console.groupEnd(); - }, - - malloc: function(size) { - console.groupCollapsed(`malloc(${size})`); - if (size <= 0) { - console.warn("invalid size"); - console.groupEnd(); - return null; - } // if - const word_size = imports.env.word_size; - if (size % word_size > 0) { - size += word_size - size % word_size; - } // if - console.log(`for ${word_size}-byte aligned ${size} bytes`); - const len = heap_blocks.length; - for (let idx = 0; idx < len; ++idx) { - const heap_block = heap_blocks[idx]; - const diff = heap_block.size - size; - if (heap_block.free && diff >= 0) { - console.log(`found suitable heap block ${idx}`); - heap_block.free = false; - const fragment_size = 0; - if (diff > fragment_size) { - console.log(`splitting ${size} bytes from heap block ${idx}`); - heap_block.size = size; - heap_blocks.splice(idx + 1, 0, { - address: heap_block.address + size, - size: diff, - free: true, - }); - } // if - console.log("heap blocks:", JSON.parse(JSON.stringify(heap_blocks))); - console.log(`address: 0x${heap_block.address.toString(16)}`); - console.groupEnd(); - return heap_block.address; - } // if - } // for - const page_size = 1 << 16; - const pages = Math.floor(size / page_size + 1); - console.log(`grow memory with ${pages} 16KiB pages`); - const memory = imports.env.memory; - try { - memory.grow(pages); - } // try - catch(error) { - console.warn("out of memory"); - console.groupEnd(); - return null; - } // catch - const buffer = memory.buffer; - const buffer_size = buffer.byteLength; - memory.words = new Uint32Array(buffer, 0, buffer_size / word_size); - memory.bytes = new Uint8Array(buffer, 0, buffer_size); - console.log(`total memory: ${memory.buffer.byteLength / (1024 * 1024)} MiB`); - const heap_block = heap_blocks[heap_blocks.length - 1]; - heap_blocks.push({ - address: heap_block.address + heap_block.size, - size: pages * page_size, - free: true, - }); - console.log("heap blocks:", JSON.parse(JSON.stringify(heap_blocks))); - console.groupEnd(); - return imports.env.malloc(size); - }, - }}; // imports - - return WebAssembly.instantiateStreaming(fetch(path), imports).then(obj => { - const env = imports.env; - const memory = env.memory; - const buffer = memory.buffer; - const buffer_size = buffer.byteLength; - const exports = obj.instance.exports; - const word_size = env.word_size = exports.__word_size(); - const heap_base = exports.__heap_base; - console.assert(word_size === 4); // For now we assume wasm32 - console.assert(heap_base % word_size === 0); - heap_blocks = [{ - address: heap_base.value, - size: buffer_size - heap_base, - free: true, - }]; - memory.words = new Uint32Array(buffer, 0, buffer_size / word_size); - memory.bytes = new Uint8Array(buffer, 0, buffer_size); - return { - env: env, - exports: exports, - }; - }); -} // wasmInstance diff --git a/javascript/wasm/wasm.h b/javascript/wasm/wasm.h deleted file mode 100644 index ca073ed..0000000 --- a/javascript/wasm/wasm.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef WASM_H -#define WASM_H - - -#include // size_t - - -#define WASM_EXPORT(name) __attribute__((export_name(name))) - - -extern void console_log(size_t, char const*); - -extern void free(void*); -extern void* malloc(size_t); - - -WASM_EXPORT("__word_size") -size_t -__word_size(void) -{ - return sizeof(size_t); -} // __word_size - - -void* -calloc(size_t count, size_t size) -{ - return malloc(count * size); -} // calloc - - -__attribute__((noinline)) -void* -realloc(void* ptr, size_t size) -{ - free(ptr); - return malloc(size); -} // realloc - - -void* -memcpy(void* dest, void const* src, size_t n) -{ - char* bdest = dest; - char const* bsrc = src; - - for (size_t i = 0; i < n; ++i) - { - bdest[i] = bsrc[i]; - } // for - return dest; -} // memcpy - - -#endif diff --git a/javascript/wasm/wrapper.c b/javascript/wasm/wrapper.c deleted file mode 100644 index 6f1c3c5..0000000 --- a/javascript/wasm/wrapper.c +++ /dev/null @@ -1,15 +0,0 @@ -#include // NULL, size_t - -#include "wasm.h" // WASM_EXPORT -#include "../../include/edit.h" // varalg_edit - - -WASM_EXPORT("edit") -size_t -edit(size_t const lhs, size_t const rhs) -{ - console_log(13, "Hello, World!"); - console_log(42, NULL); - - return varalg_edit(lhs, rhs); -} // edit diff --git a/python/.gitignore b/python/.gitignore deleted file mode 100644 index 5b692d3..0000000 --- a/python/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -__pycache__/ -*.egg-info/ -build/ -venv/ diff --git a/python/README.md b/python/README.md deleted file mode 100644 index e69de29..0000000 diff --git a/python/algebra/__init__.py b/python/algebra/__init__.py deleted file mode 100644 index faf5a50..0000000 --- a/python/algebra/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -"""A Boolean Algebra for Genetic Variants.""" - - -#from algebra_ext import Variant diff --git a/python/algebra/__main__.py b/python/algebra/__main__.py deleted file mode 100644 index 58313a2..0000000 --- a/python/algebra/__main__.py +++ /dev/null @@ -1,13 +0,0 @@ -"""Entry point for the Algebra package. - -Provides a command-line interface to interact with sequences and variants -to determine their relations. -""" - - -def main(): - pass - - -if __name__ == "__main__": - main() diff --git a/python/algebra/variants/__init__.py b/python/algebra/variants/__init__.py deleted file mode 100644 index 0dbaa4a..0000000 --- a/python/algebra/variants/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -"""Variant model and parsers.""" - - -from algebra_ext import parse_hgvs, parse_spdi - diff --git a/python/ext/algebra_ext.c b/python/ext/algebra_ext.c deleted file mode 100644 index f696fa2..0000000 --- a/python/ext/algebra_ext.c +++ /dev/null @@ -1,68 +0,0 @@ -#define PY_SSIZE_T_CLEAN -#include // Py* - -#include // NULL, size_t - -#include "../include/parser.h" // va_parse_* -#include "../include/variant.h" // VA_Variant - - -static PyObject* -parse_hgvs(PyObject* const self, PyObject* const args, PyObject* const kwargs) -{ - (void) self; - - char const* expression = NULL; - size_t len = 0; - char const* reference = NULL; - size_t len_ref = 0; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#|z#:parse_hgvs", (char*[3]) {"expression", "reference", NULL}, &expression, &len, &reference, &len_ref)) - { - return NULL; - } // if - - VA_Variant variants[256] = {{0}}; - size_t const count = va_parse_hgvs(len, expression, 256, variants); - - return Py_BuildValue("i", count); -} // parse_hgvs - - -static PyObject* -parse_spdi(PyObject* const self, PyObject* const args, PyObject* const kwargs) -{ - (void) self; - - char const* expression = NULL; - size_t len = 0; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#:parse_spdi", (char*[2]) {"expression", NULL}, &expression, &len)) - { - return NULL; - } // if - - VA_Variant variants[1] = {{0}}; - size_t const count = va_parse_spdi(len, expression, variants); - - return Py_BuildValue("i", count); -} // parse_spdi - - -static struct PyModuleDef const def = -{ - .m_base = PyModuleDef_HEAD_INIT, - .m_name = "algebra_ext", - .m_doc = "Algebra C extension", - .m_size = -1, - .m_methods = (PyMethodDef[]) { - {"parse_hgvs", (PyCFunction) (void(*)(void)) parse_hgvs, METH_VARARGS | METH_KEYWORDS, "Parse HGVS expression"}, - {"parse_spdi", (PyCFunction) (void(*)(void)) parse_spdi, METH_VARARGS | METH_KEYWORDS, "Parse SPDI expression"}, - {NULL, NULL, 0, NULL} // sentinel - }, -}; - - -PyMODINIT_FUNC -PyInit_algebra_ext(void) -{ - return PyModule_Create(&def); -} // PyInit_algebra_ext diff --git a/python/ext/lcs_ext.c b/python/ext/lcs_ext.c deleted file mode 100644 index 8231655..0000000 --- a/python/ext/lcs_ext.c +++ /dev/null @@ -1,44 +0,0 @@ -#define PY_SSIZE_T_CLEAN -#include // Py* - -#include // NULL, size_t - -#include "../include/edit.h" // varalg_edit - - -static PyObject* -edit(PyObject* self, PyObject* args, PyObject* kwargs) -{ - (void) self; - - size_t lhs = 0; - size_t rhs = 40; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|i:edit", (char*[3]) {"lhs", "rhs", NULL}, &lhs, &rhs)) - { - return NULL; - } // if - - return Py_BuildValue("i", varalg_edit(lhs, rhs)); -} // edit - - -static PyModuleDef def = -{ - .m_base = PyModuleDef_HEAD_INIT, - .m_name = "lcs_ext", - .m_doc = "LCS C extension", - .m_size = -1, - .m_methods = (PyMethodDef[]) - { - {"edit", (PyCFunction) (void(*)(void)) edit, METH_VARARGS | METH_KEYWORDS, "Calculate the simple edit distance between two strings."}, - {NULL, NULL, 0, NULL} - }, -}; - - -PyMODINIT_FUNC -PyInit_lcs_ext(void) -{ - - return PyModule_Create(&def); -} // PyInit_lcs_ext diff --git a/python/include b/python/include deleted file mode 120000 index f5030fe..0000000 --- a/python/include +++ /dev/null @@ -1 +0,0 @@ -../include \ No newline at end of file diff --git a/python/setup.cfg b/python/setup.cfg deleted file mode 100644 index b43f4b1..0000000 --- a/python/setup.cfg +++ /dev/null @@ -1,24 +0,0 @@ -[metadata] -name = mutalyzer-algebra -version = 2.0.0 -description = A Boolean Algebra for Genetic Variants -long_description = file: README.md -long_description_content_type = text/markdown -author = Mark A. Santcroos, Jonathan K. Vis -author_email = m.a.santcroos@lumc.nl, j.k.vis@lumc.nl -url = https://github.com/mutalyzer/algebra -keywords = algebra, genomics, graph, string, genetics, extractor, edit-distance, dna, variants, alignment, compare, sequence, lcs, relations, hgvs -license = MIT -classifiers = - Intended Audience :: Science/Research - Intended Audience :: Developers - Operating System :: OS Independent - Programming Language :: Python :: 3 - Topic :: Scientific/Engineering :: Bio-Informatics - -[options] -packages = find: - -[options.entry_points] -console_scripts = - algebra = algebra.__main__:main diff --git a/python/setup.py b/python/setup.py deleted file mode 100644 index 39b1b14..0000000 --- a/python/setup.py +++ /dev/null @@ -1,18 +0,0 @@ -from setuptools import Extension, setup - - -setup( - ext_modules = [ - Extension("algebra_ext", - extra_compile_args=[ - "-Wextra", - "-Wpedantic", - "-std=c11", - ], - sources=[ - "ext/algebra_ext.c", - "src/parser.c", - "src/variant.c", - ]), - ], -) diff --git a/python/src b/python/src deleted file mode 120000 index 5cd551c..0000000 --- a/python/src +++ /dev/null @@ -1 +0,0 @@ -../src \ No newline at end of file diff --git a/python/tests/test_edit.py b/python/tests/test_edit.py deleted file mode 100644 index 8100e1c..0000000 --- a/python/tests/test_edit.py +++ /dev/null @@ -1,5 +0,0 @@ -from algebra.lcs import edit - - -def test_edit(): - assert edit(4, 5) == 9 diff --git a/regres.sh b/regres.sh index 4d5f0bb..1f2dea7 100755 --- a/regres.sh +++ b/regres.sh @@ -34,5 +34,4 @@ AGAGAAAAA AAAA for ((i=0; i<${#TESTS[@]}; i+=2)); do python test.py "${TESTS[i]}" "${TESTS[i+1]}" - #./a.out "${TESTS[i]}" "${TESTS[i+1]}" > /dev/null done diff --git a/src/array.c b/src/array.c index b8164fe..db4dd38 100644 --- a/src/array.c +++ b/src/array.c @@ -1,85 +1,80 @@ #include // NULL, size_t -#include "../include/alloc.h" // VA_Allocator -#include "../include/array.h" // VA_Array, va_array_* +#include "../include/allocator.h" // GVA_Allocator +#include "array.h" // GVA_Array, gva_array_* inline void* -va_array_init(VA_Allocator const allocator, size_t const capacity, size_t const item_size) +array_init(GVA_Allocator const allocator, size_t const capacity, + size_t const item_size) { - return va_array_grow(allocator, NULL, capacity, item_size); -} // va_array_init + Array* const header = allocator.allocate( + allocator.context, + NULL, + 0, + sizeof(*header) + capacity * item_size // OVERFLOW + ); + return header == NULL ? NULL : header + 1; +} // array_init -inline VA_Array* -va_array_header(void* const ptr) +inline size_t +array_length(void* const self) { - return (VA_Array*) (ptr) - 1; -} // va_array_header + return self == NULL ? 0 : array_header(self)->length; +} // array_length -inline size_t -va_array_length(void* const ptr) +inline Array* +array_header(void* const self) { - return ptr == NULL ? 0 : va_array_header(ptr)->length; -} // va_array_length + return (Array*) self - 1; +} // array_header void* -va_array_grow(VA_Allocator const allocator, void* const restrict ptr, size_t const capacity, size_t const item_size) +array_ensure_one(GVA_Allocator const allocator, void* const restrict self, + size_t const item_size) { - if (capacity == 0) + // Initial allocation + if (self == NULL) { - return ptr; - } // if - - if (ptr == NULL) - { - VA_Array* const restrict header = allocator.alloc(allocator.context, NULL, 0, sizeof(*header) + capacity * item_size); // OVERFLOW + Array* const restrict header = allocator.allocate( + allocator.context, + NULL, + 0, + sizeof(*header) + item_size // OVERFLOW + ); if (header == NULL) { return NULL; // OOM } // if - header->capacity = capacity; + header->capacity = 1; header->length = 0; return header + 1; } // if - VA_Array* restrict header = va_array_header(ptr); - if (header->capacity - header->length >= capacity) + // The current capacity is sufficient. + Array* const restrict header = array_header(self); + if (header->capacity > header->length) { - return ptr; + return header + 1; } // if + // A simple geometric growth reallocation scheme. size_t new_capacity = header->capacity * 2; // OVERFLOW - while (new_capacity < capacity) - { - new_capacity *= 2; // OVERFLOW - } // while - header = allocator.alloc(allocator.context, header, sizeof(*header) + header->capacity * item_size, sizeof(*header) * new_capacity * item_size); - if (header == NULL) + Array* const restrict new_header = allocator.allocate( + allocator.context, + header, + sizeof(*header) + header->capacity * item_size, + sizeof(*new_header) + new_capacity * item_size // OVERFLOW + ); + if (new_header == NULL) { return NULL; // OOM } // if - header->capacity = new_capacity; - return header + 1; -} // va_array_grow - - -size_t -va_array_shift(void* const ptr, size_t const index, size_t const item_size) -{ - size_t const length = va_array_length(ptr); - if (index >= length) - { - return length; - } // if - - for (size_t i = 0; i < (length - index) * item_size; ++i) - { - ((char*) ptr)[length * item_size + item_size - 1 - i] = ((char*) ptr)[length * item_size - 1 - i]; - } // for - return index; -} // va_array_shift + new_header->capacity = new_capacity; + return new_header + 1; +} // array_ensure_one diff --git a/src/array.h b/src/array.h new file mode 100644 index 0000000..b674cf9 --- /dev/null +++ b/src/array.h @@ -0,0 +1,78 @@ +#ifndef GVA_ARRAY_H +#define GVA_ARRAY_H + + +#include // NULL, size_t + +#include "../include/allocator.h" // GVA_Allocator + + +// Internal: the metadata of a dynamic array. +// Should not be used directly. +typedef struct +{ + size_t capacity; + size_t length; +} Array; + + +// Creates a new dynamic array allocated with `capacity` number of +// initial elements. +// It is the responsibility of the caller to provide the same allocator +// to any consequent allocation events (including the destruction of the +// array). +// Usage: +// int* a = array_init(gva_std_allocator, 10, sizeof(*a)); +// When `capacity` is zero the result is `NULL`. Any `NULL` value behaves +// as an empty array. +void* +array_init(GVA_Allocator const allocator, size_t const capacity, + size_t const item_size); + + +// Returns the number of elements currently in use by the array. +size_t +array_length(void* const self); + + +// Internal: Returns the metadata of the array. +// `self` must not be `NULL`. +Array* +array_header(void* const self); + + +// Internal: Returns the possibly (re)allocated array with place for +// `capacity` number of additional elements. +void* +array_ensure_one(GVA_Allocator const allocator, void* const restrict self, + size_t const item_size); + + +// Destroys an array. Does not destroy the elements of the array. +// Returns `NULL`. +// Usage: +// a = ARRAY_DESTROY(gva_std_allocator, a); +#define ARRAY_DESTROY(allocator, self) ( \ + (self) == NULL ? NULL : \ + allocator.allocate( \ + allocator.context, \ + array_header(self), \ + array_header(self)->capacity * sizeof(*(self)), \ + 0 \ + ) \ +) + + +// Adds an element at the end of the array. Returns the new length of the +// array. -1 if (re)allocation failed. +// Warning: `self` is evaluated multiple times. +#define ARRAY_APPEND(allocator, self, value) ( \ + (self) = array_ensure_one(allocator, self, sizeof(*(self))), \ + (self) == NULL ? (size_t) -1 : ( \ + (self)[array_header(self)->length] = (value), \ + array_header(self)->length += 1 \ + ) \ +) + + +#endif // GVA_ARRAY_H diff --git a/src/base.h b/src/base.h new file mode 100644 index 0000000..df92b1f --- /dev/null +++ b/src/base.h @@ -0,0 +1,20 @@ +#ifndef GVA_BASE_H +#define GVA_BASE_H + + +#include "../include/types.h" // GVA_NULL, gva_uint + + +// Generic abs function. Evaluates its parameters multiple times. +#define ABS(x) (((x) >= 0) ? (x) : -(x)) + + +// Generic max function. Evaluates its parameters multiple times. +#define MAX(lhs, rhs) (((lhs) > (rhs)) ? (lhs) : (rhs)) + + +// Generic min function. Evaluates its parameters multiple times. +#define MIN(lhs, rhs) (((lhs) < (rhs)) ? (lhs) : (rhs)) + + +#endif // GVA_BASE_H diff --git a/src/edit.c b/src/edit.c index e977d4d..93f7eab 100644 --- a/src/edit.c +++ b/src/edit.c @@ -1,120 +1,32 @@ -#include // imaxabs +#include // intmax_t #include // bool, false, true -#include // NULL, ptrdiff_t, size_t +#include // NULL, size_t -#include "../include/alloc.h" // VA_Allocator -#include "../include/array.h" // va_array_* -#include "../include/edit.h" // VA_LCS_Node, va_edit* - -static inline size_t -wu_snake(size_t const m, - char const a[static restrict m], - size_t const n, - char const b[static restrict n], - ptrdiff_t const k, - ptrdiff_t const lower, - ptrdiff_t const upper) -{ - size_t col = lower > upper ? lower : upper; - size_t row = col - k; - while (row < m && col < n && a[row] == b[col]) - { - row += 1; - col += 1; - } // while - return col; -} // wu_snake - - -static size_t -wu_compare(VA_Allocator const allocator, - size_t const m, - char const a[static restrict m], - size_t const n, - char const b[static restrict n]) -{ - ptrdiff_t const delta = n - m; - size_t const offset = m + 1; - size_t const size = m + n + 3; - ptrdiff_t* const restrict fp = allocator.alloc(allocator.context, NULL, 0, size * sizeof(*fp)); - if (fp == NULL) - { - return -1; - } // if - - for (size_t i = 0; i < size; ++i) - { - fp[i] = -1; - } // for - - size_t p = 0; - while ((size_t) fp[delta + offset] != n) - { - for (ptrdiff_t k = -p; k <= delta - 1; ++k) - { - fp[k + offset] = wu_snake(m, a, n, b, k, fp[k - 1 + offset] + 1, fp[k + 1 + offset]); - } // for - for (ptrdiff_t k = delta + p; k >= delta + 1; --k) - { - fp[k + offset] = wu_snake(m, a, n, b, k, fp[k - 1 + offset] + 1, fp[k + 1 + offset]); - } // for - fp[delta + offset] = wu_snake(m, a, n, b, delta, fp[delta - 1 + offset] + 1, fp[delta + 1 + offset]); - p += 1; - } // while - - allocator.alloc(allocator.context, fp, size * sizeof(*fp), 0); - - return delta + 2 * (p - 1); -} // wu_compare - - -size_t -va_edit_distance_only(VA_Allocator const allocator, - size_t const len_ref, - char const reference[static restrict len_ref], - size_t const len_obs, - char const observed[static restrict len_obs]) -{ - return len_ref > len_obs ? - wu_compare(allocator, len_obs, observed, len_ref, reference) : - wu_compare(allocator, len_ref, reference, len_obs, observed); -} // va_edit_distance_only - - -static inline size_t -umax(size_t const a, size_t const b) -{ - return a > b ? a : b; -} // umax - - -static inline size_t -umin(size_t const a, size_t const b) -{ - return a < b ? a : b; -} // umin +#include "../include/allocator.h" // GVA_Allocator +#include "array.h" // ARRAY_APPEND +#include "base.h" // ABS, MAX, MIN, GVA_NULL +#include "edit.h" // LCS, LCS_Node, edit typedef struct { - VA_Allocator const allocator; + GVA_Allocator const allocator; size_t const len_ref; char const* const restrict reference; size_t const len_obs; char const* const restrict observed; size_t* const restrict diagonals; - VA_LCS_Node** const restrict lcs_nodes; } Context; static size_t expand(Context const context, - ptrdiff_t const idx, - size_t const p, - size_t* const len_lcs) + intmax_t const idx, + size_t const p, + LCS* const lcs) { - ptrdiff_t const delta = context.len_obs - context.len_ref; + intmax_t const delta = context.len_obs - context.len_ref; size_t const offset = context.len_ref + 1; size_t row; @@ -124,19 +36,19 @@ expand(Context const context, { row = context.diagonals[offset + idx]; col = row + idx; - end = umax(context.diagonals[offset + idx - 1] - 1, context.diagonals[offset + idx + 1]); + end = MAX(context.diagonals[offset + idx - 1] - 1, context.diagonals[offset + idx + 1]); } // if else if (idx < 0) { col = context.diagonals[offset + idx]; row = col - idx; - end = umax(context.diagonals[offset + idx - 1], context.diagonals[offset + idx + 1] - 1); + end = MAX(context.diagonals[offset + idx - 1], context.diagonals[offset + idx + 1] - 1); } // if else { row = context.diagonals[offset + idx]; col = row + idx; - end = umax(context.diagonals[offset + idx - 1], context.diagonals[offset + idx + 1]); + end = MAX(context.diagonals[offset + idx - 1], context.diagonals[offset + idx + 1]); } // else size_t steps = end + 1; @@ -144,7 +56,6 @@ expand(Context const context, bool matching = false; size_t match_row = 0; size_t match_col = 0; - for (size_t i = context.diagonals[offset + idx]; i < end; ++i) { if (context.reference[row] == context.observed[col]) @@ -158,19 +69,27 @@ expand(Context const context, } // if else if (matching) { - ptrdiff_t const d_row = context.len_ref - row; - ptrdiff_t const d_col = context.len_obs - col; - size_t const lcs_pos = (row + col - imaxabs(delta) - 2 * p + imaxabs(d_row - d_col)) / 2 - 1; - if (lcs_pos + 1 > *len_lcs) + intmax_t const d_row = context.len_ref - row; + intmax_t const d_col = context.len_obs - col; + size_t const lcs_pos = (row + col - ABS(delta) - 2 * p + ABS(d_row - d_col)) / 2 - 1; + size_t const length = row - match_row; + gva_uint const len = ARRAY_APPEND(context.allocator, lcs->nodes, ((LCS_Node) { + match_row, match_col, length, false, 0, GVA_NULL, GVA_NULL + })) - 1; + if (lcs->index[lcs_pos].head != GVA_NULL) { - *len_lcs = lcs_pos + 1; + lcs->nodes[lcs->index[lcs_pos].tail].next = len; } // if - size_t const length = row - match_row; - if (context.lcs_nodes[lcs_pos] == NULL) + else { - context.lcs_nodes[lcs_pos] = va_array_init(context.allocator, 256, sizeof(*context.lcs_nodes[lcs_pos])); + lcs->index[lcs_pos].head = len; + } // else + lcs->index[lcs_pos].tail = len; + + if (lcs_pos + 1 > lcs->length) + { + lcs->length = lcs_pos + 1; } // if - va_array_append(context.allocator, context.lcs_nodes[lcs_pos], ((VA_LCS_Node) {match_row, match_col, length, -1, -1})); matching = false; } // if row += 1; @@ -191,42 +110,42 @@ expand(Context const context, } // while if (matching) { - ptrdiff_t const d_row = context.len_ref - row; - ptrdiff_t const d_col = context.len_obs - col; - size_t const lcs_pos = (row + col - imaxabs(delta) - 2 * p + imaxabs(d_row - d_col)) / 2 - 1; - if (lcs_pos + 1 > *len_lcs) + intmax_t const d_row = context.len_ref - row; + intmax_t const d_col = context.len_obs - col; + size_t const lcs_pos = (row + col - ABS(delta) - 2 * p + ABS(d_row - d_col)) / 2 - 1; + size_t const length = row - match_row; + gva_uint const len = ARRAY_APPEND(context.allocator, lcs->nodes, ((LCS_Node) { + match_row, match_col, length, false, 0, GVA_NULL, GVA_NULL + })) - 1; + if (lcs->index[lcs_pos].head != GVA_NULL) { - *len_lcs = lcs_pos + 1; + lcs->nodes[lcs->index[lcs_pos].tail].next = len; } // if - size_t const length = row - match_row; - if (context.lcs_nodes[lcs_pos] == NULL) + else { - context.lcs_nodes[lcs_pos] = va_array_init(context.allocator, 256, sizeof(*context.lcs_nodes[lcs_pos])); + lcs->index[lcs_pos].head = len; + } // else + lcs->index[lcs_pos].tail = len; + + if (lcs_pos + 1 > lcs->length) + { + lcs->length = lcs_pos + 1; } // if - va_array_append(context.allocator, context.lcs_nodes[lcs_pos], ((VA_LCS_Node) {match_row, match_col, length, -1, -1})); } // if - return steps; } // expand -size_t -va_edit(VA_Allocator const allocator, - size_t const len_ref, - char const reference[static restrict len_ref], - size_t const len_obs, - char const observed[static restrict len_obs], - VA_LCS_Node*** restrict lcs_nodes) +LCS +edit(GVA_Allocator const allocator, + size_t const len_ref, char const reference[static restrict len_ref], + size_t const len_obs, char const observed[static restrict len_obs]) { - ptrdiff_t const delta = len_obs - len_ref; + intmax_t const delta = len_obs - len_ref; size_t const offset = len_ref + 1; size_t const size = len_ref + len_obs + 3; - *lcs_nodes = NULL; - if (len_ref == 0 || len_obs == 0) - { - return 0; - } // if + LCS lcs = {0, NULL, NULL}; Context const context = { @@ -235,14 +154,18 @@ va_edit(VA_Allocator const allocator, reference, len_obs, observed, - .diagonals = allocator.alloc(allocator.context, NULL, 0, size * sizeof(*context.diagonals)), - .lcs_nodes = allocator.alloc(allocator.context, NULL, 0, umin(len_ref, len_obs) * sizeof(*context.lcs_nodes)), + .diagonals = allocator.allocate(allocator.context, NULL, 0, size * sizeof(*context.diagonals)), }; - if (context.diagonals == NULL || context.lcs_nodes == NULL) + if (context.diagonals == NULL) + { + return lcs; + } // if + + lcs.index = allocator.allocate(allocator.context, NULL, 0, MIN(len_ref, len_obs) * sizeof(*lcs.index)); + if (lcs.index == NULL) { - allocator.alloc(allocator.context, context.diagonals, size * sizeof(*context.diagonals), 0); - allocator.alloc(allocator.context, context.lcs_nodes, umin(len_ref, len_obs) * sizeof(*context.lcs_nodes), 0); - return -1; + allocator.allocate(allocator.context, NULL, 0, size * sizeof(*context.diagonals)); + return lcs; } // if for (size_t i = 0; i < size; ++i) @@ -250,35 +173,33 @@ va_edit(VA_Allocator const allocator, context.diagonals[i] = 0; } // for - for (size_t i = 0; i < umin(len_ref, len_obs); ++i) + for (size_t i = 0; i < MIN(len_ref, len_obs); ++i) { - context.lcs_nodes[i] = NULL; + lcs.index[i].head = GVA_NULL; + lcs.index[i].tail = GVA_NULL; } // for size_t const lower = delta > 0 ? 0 : delta; size_t const upper = delta > 0 ? delta : 0; - size_t const len = umax(len_ref, len_obs) - imaxabs(delta); + size_t const len = MAX(len_ref, len_obs) - ABS(delta); size_t p = 0; - size_t max_lcs_pos = 0; while (context.diagonals[offset + delta] <= len) { - for (ptrdiff_t idx = lower - p; idx < delta; ++idx) + for (intmax_t idx = lower - p; idx < delta; ++idx) { - context.diagonals[offset + idx] = expand(context, idx, p, &max_lcs_pos); + context.diagonals[offset + idx] = expand(context, idx, p, &lcs); } // for - for (ptrdiff_t idx = upper + p; idx > delta; --idx) + for (intmax_t idx = upper + p; idx > delta; --idx) { - context.diagonals[offset + idx] = expand(context, idx, p, &max_lcs_pos); + context.diagonals[offset + idx] = expand(context, idx, p, &lcs); } // for - context.diagonals[offset + delta] = expand(context, delta, p, &max_lcs_pos); + context.diagonals[offset + delta] = expand(context, delta, p, &lcs); p += 1; } // while - allocator.alloc(allocator.context, context.diagonals, size * sizeof(*context.diagonals), 0); - - // transfer ownership - *lcs_nodes = allocator.alloc(allocator.context, context.lcs_nodes, umin(len_ref, len_obs) * sizeof(*context.lcs_nodes), max_lcs_pos * sizeof(*context.lcs_nodes)); - return max_lcs_pos; -} // va_edit + allocator.allocate(allocator.context, context.diagonals, size * sizeof(*context.diagonals), 0); + lcs.index = allocator.allocate(allocator.context, lcs.index, MIN(len_ref, len_obs) * sizeof(*lcs.index), lcs.length * sizeof(*lcs.index)); + return lcs; +} // edit diff --git a/src/edit.h b/src/edit.h new file mode 100644 index 0000000..cd18cf0 --- /dev/null +++ b/src/edit.h @@ -0,0 +1,40 @@ +#ifndef GVA_EDIT_H +#define GVA_EDIT_H + + +#include // size_t + +#include "../include/types.h" // gva_uint + + +typedef struct +{ + gva_uint row; + gva_uint col; + gva_uint length : 31; + gva_uint moved : 1; + gva_uint incoming; + gva_uint idx; + gva_uint next; +} LCS_Node; + + +typedef struct +{ + size_t length; + struct + { + gva_uint head; + gva_uint tail; + }* index; + LCS_Node* nodes; +} LCS; + + +LCS +edit(GVA_Allocator const allocator, + size_t const len_ref, char const reference[static restrict len_ref], + size_t const len_obs, char const observed[static restrict len_obs]); + + +#endif // GVA_EDIT_H diff --git a/src/edit2.c b/src/edit2.c deleted file mode 100644 index 72d1f07..0000000 --- a/src/edit2.c +++ /dev/null @@ -1,234 +0,0 @@ -#include // imaxabs -#include // bool, false, true -#include // NULL, ptrdiff_t, size_t - -#include "../include/alloc.h" // VA_Allocator -#include "../include/array.h" // va_array_* -#include "../include/edit.h" - - -static inline size_t -umax(size_t const a, size_t const b) -{ - return a > b ? a : b; -} // umax - - -static inline size_t -umin(size_t const a, size_t const b) -{ - return a < b ? a : b; -} // umin - - -typedef struct -{ - VA_Allocator const allocator; - size_t const len_ref; - char const* const restrict reference; - size_t const len_obs; - char const* const restrict observed; - size_t* const restrict diagonals; -} Context; - - -static size_t -expand(Context const context, - ptrdiff_t const idx, - size_t const p, - size_t* const len_lcs, - VA_LCS_List lcs_index[static restrict 1], - VA_LCS_Node2** lcs_nodes) -{ - ptrdiff_t const delta = context.len_obs - context.len_ref; - size_t const offset = context.len_ref + 1; - - size_t row; - size_t col; - size_t end; - if (idx > 0) - { - row = context.diagonals[offset + idx]; - col = row + idx; - end = umax(context.diagonals[offset + idx - 1] - 1, context.diagonals[offset + idx + 1]); - } // if - else if (idx < 0) - { - col = context.diagonals[offset + idx]; - row = col - idx; - end = umax(context.diagonals[offset + idx - 1], context.diagonals[offset + idx + 1] - 1); - } // if - else - { - row = context.diagonals[offset + idx]; - col = row + idx; - end = umax(context.diagonals[offset + idx - 1], context.diagonals[offset + idx + 1]); - } // else - - size_t steps = end + 1; - - bool matching = false; - size_t match_row = 0; - size_t match_col = 0; - - for (size_t i = context.diagonals[offset + idx]; i < end; ++i) - { - if (context.reference[row] == context.observed[col]) - { - if (!matching) - { - match_row = row; - match_col = col; - matching = true; - } // if - } // if - else if (matching) - { - ptrdiff_t const d_row = context.len_ref - row; - ptrdiff_t const d_col = context.len_obs - col; - size_t const lcs_pos = (row + col - imaxabs(delta) - 2 * p + imaxabs(d_row - d_col)) / 2 - 1; - size_t const length = row - match_row; - va_array_append(context.allocator, *lcs_nodes, ((VA_LCS_Node2) {match_row, match_col, length, lcs_pos, lcs_index[lcs_pos].tail, -1, -1, -1})); - lcs_index[lcs_pos].tail = va_array_length(*lcs_nodes) - 1; - if (lcs_pos + 1 > *len_lcs) - { - *len_lcs = lcs_pos + 1; - } // if - if (lcs_index[lcs_pos].head == (uint32_t) -1) - { - lcs_index[lcs_pos].head = lcs_index[lcs_pos].tail; - } // if - matching = false; - } // if - row += 1; - col += 1; - } // for - - if (!matching) - { - match_row = row; - match_col = col; - } // if - while (row < context.len_ref && col < context.len_obs && context.reference[row] == context.observed[col]) - { - matching = true; - row += 1; - col += 1; - steps += 1; - } // while - if (matching) - { - ptrdiff_t const d_row = context.len_ref - row; - ptrdiff_t const d_col = context.len_obs - col; - size_t const lcs_pos = (row + col - imaxabs(delta) - 2 * p + imaxabs(d_row - d_col)) / 2 - 1; - size_t const length = row - match_row; - va_array_append(context.allocator, *lcs_nodes, ((VA_LCS_Node2) {match_row, match_col, length, lcs_pos, lcs_index[lcs_pos].tail, -1, -1, -1})); - lcs_index[lcs_pos].tail = va_array_length(*lcs_nodes) - 1; - if (lcs_pos + 1 > *len_lcs) - { - *len_lcs = lcs_pos + 1; - } // if - if (lcs_index[lcs_pos].head == (uint32_t) -1) - { - lcs_index[lcs_pos].head = lcs_index[lcs_pos].tail; - } // if - } // if - - return steps; -} // expand - - -size_t -va_edit2(VA_Allocator const allocator, - size_t const len_ref, char const reference[static restrict len_ref], - size_t const len_obs, char const observed[static restrict len_obs], - VA_LCS_List** restrict lcs_index, - VA_LCS_Node2** restrict lcs_nodes) -{ - ptrdiff_t const delta = len_obs - len_ref; - size_t const offset = len_ref + 1; - size_t const size = len_ref + len_obs + 3; - - *lcs_index = NULL; - *lcs_nodes = NULL; - if (len_ref == 0 || len_obs == 0) - { - return 0; - } // if - - Context const context = - { - allocator, - len_ref, - reference, - len_obs, - observed, - .diagonals = allocator.alloc(allocator.context, NULL, 0, size * sizeof(*context.diagonals)), - }; - if (context.diagonals == NULL) - { - return -1; - } // if - - *lcs_index = allocator.alloc(allocator.context, NULL, 0, umin(len_ref, len_obs) * sizeof(**lcs_index)); - if (*lcs_index == NULL) - { - allocator.alloc(allocator.context, NULL, 0, size * sizeof(*context.diagonals)); - return -1; - } // if - - for (size_t i = 0; i < size; ++i) - { - context.diagonals[i] = 0; - } // for - - for (size_t i = 0; i < umin(len_ref, len_obs); ++i) - { - (*lcs_index)[i].head = -1; - (*lcs_index)[i].tail = -1; - } // for - - size_t const lower = delta > 0 ? 0 : delta; - size_t const upper = delta > 0 ? delta : 0; - - size_t const len = umax(len_ref, len_obs) - imaxabs(delta); - size_t p = 0; - size_t len_lcs = 0; - while (context.diagonals[offset + delta] <= len) - { - for (ptrdiff_t idx = lower - p; idx < delta; ++idx) - { - context.diagonals[offset + idx] = expand(context, idx, p, &len_lcs, *lcs_index, lcs_nodes); - } // for - for (ptrdiff_t idx = upper + p; idx > delta; --idx) - { - context.diagonals[offset + idx] = expand(context, idx, p, &len_lcs, *lcs_index, lcs_nodes); - } // for - context.diagonals[offset + delta] = expand(context, delta, p, &len_lcs, *lcs_index, lcs_nodes); - - p += 1; - } // while - - uint32_t prev = 0; - for (size_t i = 1; i < len_lcs; ++i) - { - if ((*lcs_index)[i].head != (uint32_t) -1) - { - (*lcs_nodes)[(*lcs_index)[i].head].next = (*lcs_index)[prev].tail; - prev = i; - } // if - } // for - - for (uint32_t i = 0; i < va_array_length(*lcs_nodes); ++i) - { - if ((*lcs_nodes)[i].next != (uint32_t) -1) - { - (*lcs_nodes)[(*lcs_nodes)[i].next].inext = i; - } // if - } // for - - allocator.alloc(allocator.context, context.diagonals, size * sizeof(*context.diagonals), 0); - *lcs_index = allocator.alloc(allocator.context, *lcs_index, umin(len_ref, len_obs) * sizeof(**lcs_index), len_lcs * sizeof(**lcs_index)); - - return len_lcs; -} // va_edit2 diff --git a/src/edit3.c b/src/edit3.c deleted file mode 100644 index 0c88495..0000000 --- a/src/edit3.c +++ /dev/null @@ -1,217 +0,0 @@ -#include // imaxabs -#include // bool, false, true -#include // NULL, ptrdiff_t, size_t - - -#include "../include/alloc.h" // VA_Allocator -#include "../include/array.h" // va_array_* -#include "../include/edit.h" - - -typedef struct -{ - VA_Allocator const allocator; - size_t const len_ref; - char const* const restrict reference; - size_t const len_obs; - char const* const restrict observed; - size_t* const restrict diagonals; -} Context; - - -static inline size_t -umax(size_t const a, size_t const b) -{ - return a > b ? a : b; -} // umax - - -static inline size_t -umin(size_t const a, size_t const b) -{ - return a < b ? a : b; -} // umin - - -static size_t -expand(Context const context, - ptrdiff_t const idx, - size_t const p, - VA_LCS* const lcs) -{ - ptrdiff_t const delta = context.len_obs - context.len_ref; - size_t const offset = context.len_ref + 1; - - size_t row; - size_t col; - size_t end; - if (idx > 0) - { - row = context.diagonals[offset + idx]; - col = row + idx; - end = umax(context.diagonals[offset + idx - 1] - 1, context.diagonals[offset + idx + 1]); - } // if - else if (idx < 0) - { - col = context.diagonals[offset + idx]; - row = col - idx; - end = umax(context.diagonals[offset + idx - 1], context.diagonals[offset + idx + 1] - 1); - } // if - else - { - row = context.diagonals[offset + idx]; - col = row + idx; - end = umax(context.diagonals[offset + idx - 1], context.diagonals[offset + idx + 1]); - } // else - - size_t steps = end + 1; - - bool matching = false; - size_t match_row = 0; - size_t match_col = 0; - - for (size_t i = context.diagonals[offset + idx]; i < end; ++i) - { - if (context.reference[row] == context.observed[col]) - { - if (!matching) - { - match_row = row; - match_col = col; - matching = true; - } // if - } // if - else if (matching) - { - ptrdiff_t const d_row = context.len_ref - row; - ptrdiff_t const d_col = context.len_obs - col; - size_t const lcs_pos = (row + col - imaxabs(delta) - 2 * p + imaxabs(d_row - d_col)) / 2 - 1; - size_t const length = row - match_row; - va_array_append(context.allocator, lcs->nodes, ((VA_LCS_Node3) {match_row, match_col, length, false, 0, -1, -1})); - if (lcs->index[lcs_pos].head != (uint32_t) -1) - { - lcs->nodes[lcs->index[lcs_pos].tail].next = va_array_length(lcs->nodes) - 1; - } // if - else - { - lcs->index[lcs_pos].head = va_array_length(lcs->nodes) - 1; - } // else - lcs->index[lcs_pos].tail = va_array_length(lcs->nodes) - 1; - - if (lcs_pos + 1 > lcs->length) - { - lcs->length = lcs_pos + 1; - } // if - matching = false; - } // if - row += 1; - col += 1; - } // for - - if (!matching) - { - match_row = row; - match_col = col; - } // if - while (row < context.len_ref && col < context.len_obs && context.reference[row] == context.observed[col]) - { - matching = true; - row += 1; - col += 1; - steps += 1; - } // while - if (matching) - { - ptrdiff_t const d_row = context.len_ref - row; - ptrdiff_t const d_col = context.len_obs - col; - size_t const lcs_pos = (row + col - imaxabs(delta) - 2 * p + imaxabs(d_row - d_col)) / 2 - 1; - size_t const length = row - match_row; - va_array_append(context.allocator, lcs->nodes, ((VA_LCS_Node3) {match_row, match_col, length, false, 0, -1, -1})); - if (lcs->index[lcs_pos].head != (uint32_t) -1) - { - lcs->nodes[lcs->index[lcs_pos].tail].next = va_array_length(lcs->nodes) - 1; - } // if - else - { - lcs->index[lcs_pos].head = va_array_length(lcs->nodes) - 1; - } // else - lcs->index[lcs_pos].tail = va_array_length(lcs->nodes) - 1; - - if (lcs_pos + 1 > lcs->length) - { - lcs->length = lcs_pos + 1; - } // if - } // if - - return steps; -} // expand - - -VA_LCS -va_edit3(VA_Allocator const allocator, - size_t const len_ref, char const reference[static restrict len_ref], - size_t const len_obs, char const observed[static restrict len_obs]) -{ - ptrdiff_t const delta = len_obs - len_ref; - size_t const offset = len_ref + 1; - size_t const size = len_ref + len_obs + 3; - - VA_LCS lcs = {0, NULL, NULL}; - - Context const context = - { - allocator, - len_ref, - reference, - len_obs, - observed, - .diagonals = allocator.alloc(allocator.context, NULL, 0, size * sizeof(*context.diagonals)), - }; - if (context.diagonals == NULL) - { - return lcs; - } // if - - lcs.index = allocator.alloc(allocator.context, NULL, 0, umin(len_ref, len_obs) * sizeof(*lcs.index)); - if (lcs.index == NULL) - { - allocator.alloc(allocator.context, NULL, 0, size * sizeof(*context.diagonals)); - return lcs; - } // if - - for (size_t i = 0; i < size; ++i) - { - context.diagonals[i] = 0; - } // for - - for (size_t i = 0; i < umin(len_ref, len_obs); ++i) - { - lcs.index[i].head = -1; - lcs.index[i].tail = -1; - } // for - - size_t const lower = delta > 0 ? 0 : delta; - size_t const upper = delta > 0 ? delta : 0; - - size_t const len = umax(len_ref, len_obs) - imaxabs(delta); - size_t p = 0; - while (context.diagonals[offset + delta] <= len) - { - for (ptrdiff_t idx = lower - p; idx < delta; ++idx) - { - context.diagonals[offset + idx] = expand(context, idx, p, &lcs); - } // for - for (ptrdiff_t idx = upper + p; idx > delta; --idx) - { - context.diagonals[offset + idx] = expand(context, idx, p, &lcs); - } // for - context.diagonals[offset + delta] = expand(context, delta, p, &lcs); - - p += 1; - } // while - - allocator.alloc(allocator.context, context.diagonals, size * sizeof(*context.diagonals), 0); - lcs.index = allocator.alloc(allocator.context, lcs.index, umin(len_ref, len_obs) * sizeof(*lcs.index), lcs.length * sizeof(*lcs.index)); - - return lcs; -} // va_edit3 diff --git a/src/extract.c b/src/extract.c deleted file mode 100644 index 69b5bba..0000000 --- a/src/extract.c +++ /dev/null @@ -1,359 +0,0 @@ -#include // NULL, size_t -#include // uint32_t -#include // stderr, fprintf, printf - -#include "../include/alloc.h" // VA_Allocator -#include "../include/array.h" // va_array_* -#include "../include/variant.h" // VA_Variant -#include "../include/graph.h" // Edge, Edge2, Graph, Node - -#define MAX(lhs, rhs) (((lhs) > (rhs)) ? (lhs) : (rhs)) -#define MIN(lhs, rhs) (((lhs) < (rhs)) ? (lhs) : (rhs)) - -#define print_variant(variant, observed) variant.start, variant.end, (int) variant.obs_end - variant.obs_start, observed + variant.obs_start -#define VAR_FMT "%u:%u/%.*s" - - -typedef struct -{ - uint32_t post; - uint32_t rank; - uint32_t edge; - uint32_t start; - uint32_t end; - uint32_t next; -} Post_Table; - - -static uint32_t -intersection(uint32_t lhs, uint32_t rhs, size_t const length, Post_Table const visited[static length]) -{ - if (lhs == (uint32_t) -1) - { - return rhs; - } // if - while (lhs != rhs) - { - while (visited[lhs].rank > visited[rhs].rank) - { - lhs = visited[lhs].post; - } // while - while (visited[rhs].rank > visited[lhs].rank) - { - rhs = visited[rhs].post; - } // while - } // while - return lhs; -} // intersection - - -void -local_supremal(VA_Allocator const allocator, Graph const graph, size_t const len_obs, char const observed[static len_obs]) -{ - uint32_t const length = va_array_length(graph.nodes); - Post_Table* visited = allocator.alloc(allocator.context, NULL, 0, sizeof(*visited) * length); - if (visited == NULL) - { - return; - } // if - - for (uint32_t i = 0; i < length; ++i) - { - visited[i].post = -1; - visited[i].start = 0; - visited[i].end = -1; - visited[i].next = -1; - } // for - - uint32_t rank = 0; - uint32_t head = graph.source; - visited[head].edge = graph.nodes[head].edges; - - while (head != (uint32_t) -1) - { - uint32_t edge = visited[head].edge; - if (edge == (uint32_t) -1) - { - uint32_t const lambda = graph.nodes[head].lambda; - if (lambda != (uint32_t) -1) - { - if (visited[lambda].next == (uint32_t) -1) - { - visited[lambda].edge = graph.nodes[lambda].edges; - visited[lambda].next = head; - head = lambda; - continue; - } // if - visited[head].post = intersection(visited[head].post, lambda, length, visited); - } // if - - visited[head].rank = rank; - rank += 1; - head = visited[head].next; - continue; - } // if - - if (visited[graph.edges[edge].tail].next != (uint32_t) -1) - { - visited[head].post = intersection(visited[head].post, graph.edges[edge].tail, length, visited); - visited[head].edge = graph.edges[edge].next; - } // if - while (edge != (uint32_t) -1) - { - uint32_t const tail = graph.edges[edge].tail; - visited[head].end = MIN(visited[head].end, graph.edges[edge].variant.start); - visited[tail].start = MAX(visited[tail].start, graph.edges[edge].variant.end); - if (visited[tail].next == (uint32_t) -1) - { - visited[tail].edge = graph.nodes[tail].edges; - visited[tail].next = head; - head = tail; - break; - } // if - visited[head].post = intersection(visited[head].post, tail, length, visited); - edge = graph.edges[edge].next; - } // while - } // while - - /* - printf(" # \tpost\trank\tstart\tend\n"); - for (uint32_t i = 0; i < length; ++i) - { - printf("%2u:\t%4d\t%4u\t%5u\t%3d\n", i, visited[i].post, visited[i].rank, visited[i].start, visited[i].end); - } // for - */ - - head = graph.source; - uint32_t shift = 0; - for (uint32_t tail = visited[head].post; tail != (uint32_t) -1; head = tail, tail = visited[head].post) - { - uint32_t const start = visited[head].end; - uint32_t const end = visited[tail].start; - VA_Variant const variant = {start, end, graph.nodes[head].col + start - graph.nodes[head].row - shift, graph.nodes[tail].col + end - graph.nodes[tail].row - shift}; - if (head != graph.source) - { - printf(",\n"); - } // if - printf(" \"" VAR_FMT "\"", print_variant(variant, observed)); - } // for - - visited = allocator.alloc(allocator.context, visited, sizeof(*visited) * length, 0); -} // local_supremal - - -typedef struct -{ - uint32_t lca; - uint32_t rank; - uint32_t depth; - uint32_t start; - uint32_t end; - uint32_t prev; - uint32_t next; -} LCA_Table; - - -static inline uint32_t -lca(uint32_t* const start, uint32_t lhs, uint32_t rhs, size_t const length, LCA_Table const visited[static length], bool const debug) -{ - uint32_t lhs_start = *start; - uint32_t rhs_start = *start; - while (lhs != rhs) - { - if (debug) - fprintf(stderr, " lca %u (%d), %u (%d)\n", lhs, lhs_start, rhs, rhs_start); - - while (visited[lhs].rank > visited[rhs].rank) - { - if (debug) - fprintf(stderr, " left\n"); - lhs_start = visited[lhs].start; - lhs = visited[lhs].lca; - } // if - while (visited[rhs].rank > visited[lhs].rank) - { - if (debug) - fprintf(stderr, " right\n"); - rhs_start = visited[rhs].start; - rhs = visited[rhs].lca; - } // if - } // while - *start = MIN(lhs_start, rhs_start); - return lhs; -} // lca - - -static void -print_lca_table(size_t const length, LCA_Table const visited[static length], uint32_t const head, uint32_t const tail) -{ - fprintf(stderr, " # \tlca\trank\tdepth\tstart\tend\tprev\tnext\n"); - for (uint32_t i = 0; i < length; ++i) - { - fprintf(stderr, "%2u:\t%3d\t%4d\t%5d\t%5d\t%3d\t%4d\t%4d\n", i, visited[i].lca, visited[i].rank, visited[i].depth, visited[i].start, visited[i].end, visited[i].prev, visited[i].next); - } // for - fprintf(stderr, "head: %d\ntail: %d\n", head, tail); -} // print_lca_table - - -void -canonical(VA_Allocator const allocator, Graph const graph, size_t const len_obs, char const observed[static len_obs], bool const debug) -{ - uint32_t const length = va_array_length(graph.nodes); - LCA_Table* visited = allocator.alloc(allocator.context, NULL, 0, sizeof(*visited) * length); - if (visited == NULL) - { - return; - } // if - - for (uint32_t i = 0; i < length; ++i) - { - visited[i].depth = -1; - - visited[i].lca = -1; - visited[i].rank = -1; - visited[i].start = -1; - visited[i].end = -1; - visited[i].prev = -1; - visited[i].next = -1; - - } // for - - uint32_t sink = -1; - visited[graph.source] = (LCA_Table) {-1, 0, 0, -1, -1, -1, -1}; - uint32_t rank = 1; - // main loop over a queue - for (uint32_t head = graph.source, tail = graph.source; head != (uint32_t) -1; head = visited[head].next) - { - if (debug) - fprintf(stderr, "pop %u @ %u\n", head, visited[head].depth); - - if (graph.nodes[head].edges == (uint32_t) -1) - { - if (debug) - fprintf(stderr, " sink\n"); - sink = head; - continue; - } // if - - uint32_t const lambda = graph.nodes[head].lambda; - if (lambda != (uint32_t) -1) - { - if (visited[lambda].depth == (uint32_t) -1) - { - // add lambda in stack order - if (debug) - fprintf(stderr, " push lambda %u @ %u\n", lambda, visited[head].depth); - - visited[visited[head].next].prev = lambda; - visited[lambda] = (LCA_Table) {head, rank, visited[head].depth, -1, -1, head, visited[head].next}; - rank += 1; - visited[head].next = lambda; - } // if - else if (visited[lambda].depth == visited[head].depth) - { - if (debug) { - fprintf(stderr, " update lambda %u @ %u\n", lambda, visited[head].depth); - fprintf(stderr, " lca(%u, %u)\n", visited[lambda].lca, head); - } - visited[lambda].lca = lca(&visited[lambda].start, visited[lambda].lca, head, length, visited, false); - - // FIXME: what is correct here? - // AGGCCG CGCAGCCTC ignores the common end position - // ACAGGA CAAGGCG - // TAATTGGTAG CTATTCAG needs the common end position - // TTAAG TAACA - - //visited[lambda].end = graph.nodes[head].row; // this simulates the empty variant on a lambda edge - - if (debug) - fprintf(stderr, " = %u (%u:%u)\n", visited[lambda].lca, visited[lambda].start, visited[lambda].end); - } // if - else if (visited[head].next == lambda) - { - if (debug) - fprintf(stderr, " improve lambda in place %u @ %u\n", lambda, visited[head].depth); - visited[lambda] = (LCA_Table) {head, visited[lambda].rank, visited[head].depth, -1, -1, visited[lambda].prev, visited[lambda].next}; - } // if - else - { - if (debug) - fprintf(stderr, " improve lambda %u @ %u\n", lambda, visited[head].depth); - - if (lambda == tail) - { - tail = visited[lambda].prev; - } // if - else - { - visited[visited[lambda].next].prev = visited[lambda].prev; - } // else - visited[visited[head].next].prev = lambda; - visited[visited[lambda].prev].next = visited[lambda].next; - visited[lambda] = (LCA_Table) {head, visited[lambda].rank, visited[head].depth, -1, -1, head, visited[head].next}; - visited[head].next = lambda; - } // else - - //print_lca_table(length, visited, head, tail); - - } // if - - for (uint32_t i = graph.nodes[head].edges; i != (uint32_t) -1; i = graph.edges[i].next) - { - uint32_t const edge_tail = graph.edges[i].tail; - if (visited[edge_tail].depth == (uint32_t) -1) - { - // add regular successors in queue order - if (debug) - fprintf(stderr, " push %u @ %u\n", edge_tail, visited[head].depth + 1); - visited[edge_tail] = (LCA_Table) {head, rank, visited[head].depth + 1, graph.edges[i].variant.start, graph.edges[i].variant.end, tail, -1}; - rank += 1; - visited[tail].next = edge_tail; - tail = edge_tail; - } // if - else if (visited[edge_tail].depth - 1 == visited[head].depth) - { - if (debug) - { - fprintf(stderr, " update %u @ %u\n", edge_tail, visited[edge_tail].depth); - fprintf(stderr, " lca(%u, %u)\n", visited[edge_tail].lca, head); - } - visited[edge_tail].start = MIN(visited[edge_tail].start, graph.edges[i].variant.start); - visited[edge_tail].lca = lca(&visited[edge_tail].start, visited[edge_tail].lca, head, length, visited, false); - visited[edge_tail].end = MAX(visited[edge_tail].end, graph.edges[i].variant.end); - if (debug) - fprintf(stderr, " = %u (%u:%u)\n", visited[edge_tail].lca, visited[edge_tail].start, visited[edge_tail].end); - } // if - else - { - if (debug) - fprintf(stderr, " skip %u @ %u\n", edge_tail, visited[edge_tail].depth); - } // else - - //print_lca_table(length, visited, head, tail); - } // for - } // for - - if (debug) - print_lca_table(length, visited, -1, -1); - - // the canonical variant is given in the reverse order (for now): the Python checker needs to reverse this list - for (uint32_t tail = sink; tail != (uint32_t) -1; tail = visited[tail].lca) - { - uint32_t const head = visited[tail].lca; - if (head != (uint32_t) - 1 && visited[tail].start != (uint32_t) -1) - { - // we need to skip lambda edges: start && end == -1 - uint32_t const start_offset = visited[tail].start - graph.nodes[head].row; - uint32_t const end_offset = visited[tail].end - graph.nodes[tail].row; - VA_Variant const variant = {visited[tail].start, visited[tail].end, graph.nodes[head].col + start_offset, graph.nodes[tail].col + end_offset}; - - if (tail != sink) - { - printf(",\n"); - } // if - printf(" \"" VAR_FMT "\"", print_variant(variant, observed)); - } // if - } // while - - visited = allocator.alloc(allocator.context, visited, sizeof(*visited) * length, 0); -} // canonical \ No newline at end of file diff --git a/src/graph.c b/src/graph.c deleted file mode 100644 index d331e6c..0000000 --- a/src/graph.c +++ /dev/null @@ -1,807 +0,0 @@ -#include // bool, false, true -#include // NULL, size_t -#include // intmax_t, uint32_t -#include // stderr, fprintf, printf -#include // EXIT_*, atoi, rand, srand -#include // strlen, strncmp - -#include "../include/alloc.h" // VA_Allocator -#include "../include/array.h" // va_array_* -#include "../include/edit.h" // VA_LCS_Node, va_edit -#include "../include/extract.h" // canonical, local_supremal -#include "../include/std_alloc.h" // va_std_allocator -#include "../include/variant.h" // VA_Variant -// #include "../include/graph.h" // Edge, Graph, Node - - -#define MAX(lhs, rhs) (((lhs) > (rhs)) ? (lhs) : (rhs)) -#define MIN(lhs, rhs) (((lhs) < (rhs)) ? (lhs) : (rhs)) - -#define print_variant(variant, observed) variant.start, variant.end, (int) variant.obs_end - variant.obs_start, observed + variant.obs_start -#define VAR_FMT "%u:%u/%.*s" - - -static uint32_t const GVA_NULL = UINT32_MAX; - - -static inline size_t -add_node(VA_Allocator const allocator, Graph* const graph, size_t const row, size_t const col, size_t const length) -{ - va_array_append(allocator, graph->nodes, ((Node) {row, col, length, -1, -1})); - return va_array_length(graph->nodes) - 1; -} // add_node - - -static inline size_t -add_edge(VA_Allocator const allocator, Graph* const graph, size_t const tail, size_t const next, VA_Variant const variant) -{ - va_array_append(allocator, graph->edges, ((Edge) {tail, next, variant})); - return va_array_length(graph->edges) - 1; -} // add_edge - - -inline void -destroy(VA_Allocator const allocator, Graph* const graph) -{ - graph->nodes = va_array_destroy(allocator, graph->nodes); - graph->edges = va_array_destroy(allocator, graph->edges); -} // destroy - - -static uint32_t -edges42(Node const head, Node const tail, - bool const is_source, bool const is_sink, - VA_Variant* const variant) -{ -// printf("%u %u %u -> %u %u %u %s %s\n", head.row, head.col, head.length, tail.row, tail.col, tail.length, is_source ? "SOURCE" : "", is_sink ? "SINK" : ""); - - intmax_t const row = (intmax_t) head.row - is_source; - intmax_t const col = (intmax_t) head.col - is_source; - uint32_t const head_length = head.length + is_source; - uint32_t const tail_length = tail.length + is_sink; - - intmax_t const offset = MIN((intmax_t) tail.row - row, (intmax_t) tail.col - col) - 1; - - uint32_t const head_offset = offset > 0 ? MIN(head_length, offset + 1) : 1; - uint32_t const tail_offset = offset < 0 ? MIN(tail_length, -offset) : 0; - - //printf(" %ld: (%u, %u)\n", offset, head_offset, tail_offset); - - if (head_offset > head_length || (tail_length > 0 && tail_offset >= tail_length)) - { - //fprintf(stderr, "NO EDGE\n"); - return 0; - } // if - - uint32_t const count = MIN(head_length - head_offset, tail_length - tail_offset - 1) + 1; - - *variant = (VA_Variant) {row + head_offset, tail.row + tail_offset, col + head_offset, tail.col + tail_offset}; - - //fprintf(stderr, VAR_FMT " x %u\n", print_variant((*variant), observed), count); - return count; -} // edges42 - - -Graph -build_graph(VA_Allocator const allocator, - size_t const len_ref, size_t const len_obs, - size_t const len_lcs, VA_LCS_Node* lcs_nodes[static len_lcs], - size_t const shift, bool const debug) -{ - Graph graph = {.nodes = NULL, .edges = NULL}; - - if (len_lcs == 0 || lcs_nodes == NULL) - { - graph.source = add_node(allocator, &graph, shift, shift, 0); - if (len_ref == 0 && len_obs == 0) - { - graph.supremal = (VA_Variant) {0, 0, 0, 0}; - return graph; - } // if - uint32_t const sink = add_node(allocator, &graph, len_ref, len_obs, 0); - graph.supremal = (VA_Variant) {shift, shift + len_ref, 0, len_obs}; - graph.nodes[graph.source].edges = add_edge(allocator, &graph, sink, -1, graph.supremal); - return graph; - } // if - - VA_LCS_Node sink = lcs_nodes[len_lcs - 1][va_array_length(lcs_nodes[len_lcs - 1]) - 1]; - if (sink.row + sink.length == len_ref + shift && sink.col + sink.length == len_obs + shift) - { - va_array_header(lcs_nodes[len_lcs - 1])->length -= 1; // del - sink.length += 1; - } // if - else - { - sink = (VA_LCS_Node) {.row = len_ref + shift, .col = len_obs + shift, .length = 1}; - } // else - - uint32_t max_sink = 0; - sink.idx = add_node(allocator, &graph, sink.row, sink.col, sink.length - 1); - if (debug) - printf("MAKE NODE %u: (%u, %u, %u)\n", sink.idx, sink.row, sink.col, sink.length - 1); - size_t here = 0; - VA_LCS_Node* const heads = lcs_nodes[len_lcs - 1]; - for (size_t i = 0; i < va_array_length(heads); ++i) - { - eq_count += 1; - //fprintf(stderr, "(%u, %u, %u) vs (%u, %u, %u)\n", heads[i].row, heads[i].col, heads[i].length, sink.row, sink.col, sink.length); - - if (heads[i].row + heads[i].length < sink.row + sink.length && heads[i].col + heads[i].length < sink.col + sink.length) - { - VA_Variant const variant = {heads[i].row + heads[i].length, sink.row + sink.length - 1, heads[i].col + heads[i].length - shift, sink.col + sink.length - 1 - shift}; - - max_sink = MAX(max_sink, sink.row + sink.length - 1); - heads[i].idx = add_node(allocator, &graph, heads[i].row, heads[i].col, heads[i].length); - if (debug) - printf("MAKE NODE %u: (%u, %u, %u)\n", heads[i].idx, heads[i].row, heads[i].col, heads[i].length); - graph.nodes[heads[i].idx].edges = add_edge(allocator, &graph, sink.idx, graph.nodes[heads[i].idx].edges, variant); - if (debug) - printf("MAKE EDGE (%u %u %u) -> (%u %u %u): " VAR_FMT "\n", heads[i].row, heads[i].col, heads[i].length, sink.row, sink.col, sink.length, print_variant(variant, "0123456789")); - - here = i + 1; - } // if - } // for - - if (sink.length > 1) - { - sink.length -= 1; - sink.incoming = len_lcs - 1; - va_array_insert(allocator, lcs_nodes[len_lcs - 1], sink, here); - if (debug) - printf("INSERT (%u %u %u) here: %zu\n", sink.row, sink.col, sink.length, here); - } // if - - for (size_t i = len_lcs - 1; i >= 1; --i) - { - for (size_t j = 0; j < va_array_length(lcs_nodes[i]); ++j) - { - if (lcs_nodes[i][j].idx == GVA_NULL) - { - continue; - } // if - - here = 0; - VA_LCS_Node const tail = lcs_nodes[i][j]; - VA_LCS_Node* const heads = lcs_nodes[i - 1]; - for (size_t k = 0; k < va_array_length(heads); ++k) - { - /* - if (heads[k].idx != GVA_NULL && graph.nodes[heads[k].idx].length != heads[k].length && - tail.length != graph.nodes[tail.idx].length) - { - continue; - } // if - */ - eq_count += 1; - //fprintf(stderr, "(%u, %u, %u) vs (%u, %u, %u)\n", heads[k].row, heads[k].col, heads[k].length, tail.row, tail.col, tail.length); - - if (heads[k].row + heads[k].length < tail.row + tail.length && - heads[k].col + heads[k].length < tail.col + tail.length) - { - max_sink = MAX(max_sink, tail.row + tail.length - 1); - - VA_Variant const variant = {heads[k].row + heads[k].length, tail.row + tail.length - 1, heads[k].col + heads[k].length - shift, tail.col + tail.length - 1 - shift}; - - if (heads[k].incoming == i) - { - if (debug) - fprintf(stderr, "SPLIT at %zu\n", i); - uint32_t const split_idx = heads[k].idx; - heads[k].idx = add_node(allocator, &graph, heads[k].row, heads[k].col, heads[k].length); - if (debug) - printf("MAKE NODE %u: (%u, %u, %u)\n", heads[k].idx, heads[k].row, heads[k].col, heads[k].length); - heads[k].incoming = 0; - - // lambda-edge - graph.nodes[heads[k].idx].lambda = split_idx; - - graph.nodes[split_idx].row += heads[k].length; - graph.nodes[split_idx].col += heads[k].length; - graph.nodes[split_idx].length -= heads[k].length; - if (debug) - printf("RELABEL NODE %u: (%u, %u, %u)\n", split_idx, graph.nodes[split_idx].row,graph.nodes[split_idx].col, graph.nodes[split_idx].length); - } // if - else if (heads[k].idx == GVA_NULL) - { - heads[k].idx = add_node(allocator, &graph, heads[k].row, heads[k].col, heads[k].length); - if (debug) - printf("MAKE NODE %u: (%u, %u, %u)\n", heads[k].idx, heads[k].row, heads[k].col, heads[k].length); - } // if - - graph.nodes[heads[k].idx].edges = add_edge(allocator, &graph, tail.idx, graph.nodes[heads[k].idx].edges, variant); - if (debug) - printf("MAKE EDGE (%u %u %u) -> (%u %u %u): " VAR_FMT "\n", heads[k].row, heads[k].col, heads[k].length, tail.row, tail.col, tail.length, print_variant(variant, "0123456789")); - - here = k + 1; - } // if - } // for - - if (lcs_nodes[i][j].length > 1) - { - lcs_nodes[i][j].length -= 1; - if (here > 0) - { - lcs_nodes[i][j].incoming = i; - } // if - va_array_insert(allocator, lcs_nodes[i - 1], lcs_nodes[i][j], here); - if (debug) - printf("INSERT (%u %u %u) here: %zu\n", lcs_nodes[i][j].row, lcs_nodes[i][j].col, lcs_nodes[i][j].length, here); - } // if - } // for - lcs_nodes[i] = va_array_destroy(allocator, lcs_nodes[i]); - } // for - - VA_LCS_Node source = lcs_nodes[0][0]; - - size_t start = 0; - if (source.row == shift && source.col == shift) - { - start = 1; - } // if - else - { - source = (VA_LCS_Node) {.row = shift, .col = shift, .length = 0}; - source.idx = add_node(allocator, &graph, source.row, source.col, source.length); - if (debug) - printf("MAKE NODE %u: (%u, %u, %u)\n", source.idx, source.row, source.col, source.length); - } // else - - for (size_t i = start; i < va_array_length(lcs_nodes[0]); ++i) - { - if (lcs_nodes[0][i].idx == GVA_NULL) - { - continue; - } // if - - eq_count += 1; - //fprintf(stderr, "(%u, %u, %u) vs (%u, %u, %u)\n", source.row, source.col, source.length, lcs_nodes[0][i].row, lcs_nodes[0][i].col, lcs_nodes[0][i].length); - - if (source.row < lcs_nodes[0][i].row + lcs_nodes[0][i].length && source.col < lcs_nodes[0][i].col + lcs_nodes[0][i].length) - { - max_sink = MAX(max_sink, lcs_nodes[0][i].row + lcs_nodes[0][i].length - 1); - - VA_Variant const variant = {source.row, lcs_nodes[0][i].row + lcs_nodes[0][i].length - 1, source.col - shift, lcs_nodes[0][i].col + lcs_nodes[0][i].length - 1 - shift}; - - graph.nodes[source.idx].edges = add_edge(allocator, &graph, lcs_nodes[0][i].idx, graph.nodes[source.idx].edges, variant); - if (debug) - printf("MAKE EDGE (%u %u %u) -> (%u %u %u): " VAR_FMT "\n", source.row, source.col, source.length, lcs_nodes[0][i].row, lcs_nodes[0][i].col, lcs_nodes[0][i].length, print_variant(variant, "0123456789")); - } // if - } // for - lcs_nodes[0] = va_array_destroy(allocator, lcs_nodes[0]); - lcs_nodes = allocator.alloc(allocator.context, lcs_nodes, len_lcs * sizeof(*lcs_nodes), 0); - - uint32_t min_source = max_sink; - for (uint32_t i = graph.nodes[source.idx].edges; i != GVA_NULL; i = graph.edges[i].next) - { - min_source = MIN(min_source, graph.edges[i].variant.start); - } // for - uint32_t const min_offset = min_source - graph.nodes[source.idx].row; - - graph.nodes[source.idx].row += min_offset; - graph.nodes[source.idx].col += min_offset; - graph.nodes[source.idx].length -= min_offset; - graph.nodes[sink.idx].length -= graph.nodes[sink.idx].row + graph.nodes[sink.idx].length - max_sink; - - graph.supremal = (VA_Variant) {min_source, max_sink, graph.nodes[source.idx].col - shift, graph.nodes[sink.idx].col + graph.nodes[sink.idx].length - shift}; - graph.source = source.idx; - - return graph; -} // build_graph - - -Graph3 -build3(VA_Allocator const allocator, - size_t const len_ref, char const reference[static restrict len_ref], - size_t const len_obs, char const observed[static restrict len_obs], - size_t const shift) -{ - VA_LCS const lcs = va_edit3(allocator, len_ref, reference, len_obs, observed); - - Graph3 graph = {.nodes = NULL, .edges = NULL}; - - if (lcs.nodes == NULL) - { - va_array_append(va_std_allocator, graph.nodes, ((Node) {len_ref, len_obs, 0, GVA_NULL, GVA_NULL})); - uint32_t const sink = va_array_length(graph.nodes) - 1; - if (len_ref == 0 && len_obs == 0) - { - graph.source = sink; - return graph; - } // if - - va_array_append(va_std_allocator, graph.edges, ((Edge3) {sink, GVA_NULL})); - va_array_append(va_std_allocator, graph.nodes, ((Node) {shift, shift, 0, va_array_length(graph.edges) - 1, GVA_NULL})); - graph.source = va_array_length(graph.nodes) - 1; - return graph; - } // if - - uint32_t tail_idx = lcs.index[lcs.length - 1].tail; - VA_LCS_Node3 sink = lcs.nodes[tail_idx]; - if (sink.row + sink.length == len_ref + shift && sink.col + sink.length == len_obs + shift) - { - va_array_append(allocator, graph.nodes, ((Node) {sink.row, sink.col, sink.length, GVA_NULL, GVA_NULL})); - lcs.nodes[tail_idx].idx = va_array_length(graph.nodes) - 1; - lcs.nodes[tail_idx].moved = true; - sink = lcs.nodes[tail_idx]; - } // if - else - { - sink = (VA_LCS_Node3) {.row = len_ref + shift, .col = len_obs + shift, .length = 0}; - va_array_append(allocator, graph.nodes, ((Node) {sink.row, sink.col, sink.length, GVA_NULL, GVA_NULL})); - sink.idx = va_array_length(graph.nodes) - 1; - tail_idx = GVA_NULL; - } // else - for (uint32_t i = lcs.index[lcs.length - 1].head; i != tail_idx; i = lcs.nodes[i].next) - { - eq_count += 1; - - va_array_append(allocator, graph.nodes, ((Node) {lcs.nodes[i].row, lcs.nodes[i].col, lcs.nodes[i].length, GVA_NULL, GVA_NULL})); - lcs.nodes[i].idx = va_array_length(graph.nodes) - 1; - va_array_append(allocator, graph.edges, ((Edge3) {sink.idx, graph.nodes[lcs.nodes[i].idx].edges})); - graph.nodes[lcs.nodes[i].idx].edges = va_array_length(graph.edges) - 1; - } // for - - for (uint32_t i = lcs.length - 1; i >= 1; --i) - { - uint32_t next = GVA_NULL; - for (uint32_t j = lcs.index[i].head; j != GVA_NULL; j = next) - { - VA_LCS_Node3* const tail = &lcs.nodes[j]; - next = tail->next; - if (lcs.nodes[j].idx == GVA_NULL) - { - continue; - } // if - - uint32_t here = GVA_NULL; - for (uint32_t k = lcs.index[i - 1].head; k != GVA_NULL; k = lcs.nodes[k].next) - { - VA_LCS_Node3* const head = &lcs.nodes[k]; - eq_count += 1; - - if (k > j || - head->row + head->length >= tail->row + tail->length || - head->col + head->length >= tail->col + tail->length) - { - continue; - } // if - - here = k; - if (head->incoming == i) - { - uint32_t const split_idx = head->idx; - va_array_append(allocator, graph.nodes, ((Node) {head->row, head->col, head->length, GVA_NULL, split_idx})); - head->idx = va_array_length(graph.nodes) - 1; - head->moved = false; - head->incoming = 0; - - graph.nodes[split_idx].row += head->length; - graph.nodes[split_idx].col += head->length; - graph.nodes[split_idx].length -= head->length; - - va_array_append(allocator, graph.edges, ((Edge3) {tail->idx, graph.nodes[head->idx].edges})); - graph.nodes[head->idx].edges = va_array_length(graph.edges) - 1; - } // if - else if (head->idx == GVA_NULL) - { - va_array_append(allocator, graph.nodes, ((Node) {head->row, head->col, head->length, GVA_NULL, GVA_NULL})); - head->idx = va_array_length(graph.nodes) - 1; - - va_array_append(allocator, graph.edges, ((Edge3) {tail->idx, graph.nodes[head->idx].edges})); - graph.nodes[head->idx].edges = va_array_length(graph.edges) - 1; - } // if - else if (!head->moved || !tail->moved) - { - va_array_append(allocator, graph.edges, ((Edge3) {tail->idx, graph.nodes[head->idx].edges})); - graph.nodes[head->idx].edges = va_array_length(graph.edges) - 1; - } // if - } // for - - if (tail->length > 1) - { - tail->length -= 1; - tail->moved = true; - if (here != GVA_NULL) - { - tail->incoming = i; - tail->next = lcs.nodes[here].next; - lcs.nodes[here].next = j; - } // if - else - { - tail->next = lcs.index[i - 1].head; - lcs.index[i - 1].head = j; - } // else - } // if - } // for - } // for - - size_t head_idx = lcs.index[0].head; - VA_LCS_Node3 source = lcs.nodes[head_idx]; - if (source.row == shift && source.col == shift) - { - head_idx = source.next; - } // if - else - { - source = (VA_LCS_Node3) {.row = shift, .col = shift, .length = 0}; - va_array_append(allocator, graph.nodes, ((Node) {source.row, source.col, source.length, GVA_NULL, GVA_NULL})); - source.idx = va_array_length(graph.nodes) - 1; - } // else - for (uint32_t i = head_idx; i != GVA_NULL; i = lcs.nodes[i].next) - { - if (lcs.nodes[i].idx == GVA_NULL) - { - continue; - } // if - eq_count += 1; - - if (source.length == 0 || !lcs.nodes[i].moved) - { - va_array_append(allocator, graph.edges, ((Edge3) {lcs.nodes[i].idx, graph.nodes[source.idx].edges})); - graph.nodes[source.idx].edges = va_array_length(graph.edges) - 1; - } // if - } // for - - uint32_t min_source = -1; - for (uint32_t i = graph.nodes[source.idx].edges; i != GVA_NULL; i = graph.edges[i].next) - { - VA_Variant variant; - edges42(graph.nodes[source.idx], graph.nodes[graph.edges[i].tail], true, false, &variant); - min_source = MIN(min_source, variant.start); - } // for - if (min_source != (uint32_t) -1) - { - graph.nodes[source.idx].row += min_source; - graph.nodes[source.idx].col += min_source; - graph.nodes[source.idx].length -= min_source; - } // if - else - { - graph.nodes[source.idx].length = 0; - } // else - - graph.source = source.idx; - - va_std_allocator.alloc(va_std_allocator.context, lcs.index, lcs.length * sizeof(*lcs.index), 0); - va_array_destroy(va_std_allocator, lcs.nodes); - return graph; -} // build3 - - -void -to_dot(Graph const graph, size_t const len_obs, char const observed[static len_obs]) -{ - fprintf(stderr, "digraph{\nrankdir=LR\nedge[fontname=monospace]\nnode[fixedsize=true,fontname=serif,shape=circle,width=1]\nsi[label=\"\",shape=none,width=0]\nsi->s%u\n", graph.source); - for (uint32_t i = 0; i < va_array_length(graph.nodes); ++i) - { - fprintf(stderr, "s%u[label=\"(%u, %u, %u)\"%s]\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, graph.nodes[i].edges == (uint32_t) -1 ? ",peripheries=2" : ""); - if (graph.nodes[i].lambda != (uint32_t) -1) - { - fprintf(stderr, "s%u->s%u[label=\"λ\",style=\"dashed\"]\n", i, graph.nodes[i].lambda); - } // if - for (uint32_t j = graph.nodes[i].edges; j != (uint32_t) -1; j = graph.edges[j].next) - { - fprintf(stderr, "s%u->s%u[label=\"%u:%u/%.*s\"]\n", i, graph.edges[j].tail, graph.edges[j].variant.start, graph.edges[j].variant.end, (int) graph.edges[j].variant.obs_end - graph.edges[j].variant.obs_start, observed + graph.edges[j].variant.obs_start); - } // for - } // for - fprintf(stderr, "}\n"); -} // to_dot - - -static size_t -bfs_traversal(VA_Allocator const allocator, Graph const graph, size_t const len_obs, char const observed[static len_obs]) -{ - struct - { - uint32_t depth; - uint32_t next; - }* table = allocator.alloc(allocator.context, NULL, 0, sizeof(*table) * va_array_length(graph.nodes)); - - if (table == NULL) - { - return -1; - } - - for (size_t i = 0; i < va_array_length(graph.nodes); ++i) - { - table[i].depth = 0; - table[i].next = -1; - } // for - uint32_t head = graph.source; - uint32_t tail = graph.source; - - size_t count = 0; - //printf("digraph{\nrankdir=LR\nedge[fontname=monospace]\nnode[fixedsize=true,fontname=serif,shape=circle,width=1]\nsi[shape=point,width=.1]\n"); - //printf("si->s%u\n", graph.source); - - printf(" \"edges\": [\n"); - while (head != (uint32_t) -1) - { - //printf("pop %u\n", head); - for (uint32_t i = head; i != (uint32_t) -1; i = graph.nodes[i].lambda) - { - //printf("s%u[label=\"(%u, %u, %u)\"%s]\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, graph.nodes[i].edges == (uint32_t) -1 ? ",peripheries=2" : ""); - if (i != head) - { - //printf("lambda %u\n", i); - } // if - for (uint32_t j = graph.nodes[i].edges; j != (uint32_t) -1; j = graph.edges[j].next) - { - if (count > 0) - { - printf(",\n"); - } // if - count += 1; - printf(" {\"head\": \"s%u\", \"tail\": \"s%u\", \"variant\": \"%u:%u/%.*s\"}", head, graph.edges[j].tail, graph.edges[j].variant.start, graph.edges[j].variant.end, (int) graph.edges[j].variant.obs_end - graph.edges[j].variant.obs_start, observed + graph.edges[j].variant.obs_start); - //printf("s%u->s%u[label=\"%u:%u/%.*s\"]\n", head, graph.edges[j].tail, graph.edges[j].variant.start, graph.edges[j].variant.end, (int) graph.edges[j].variant.obs_end - graph.edges[j].variant.obs_start, observed + graph.edges[j].variant.obs_start); - - if (table[graph.edges[j].tail].depth > 0) - { - //printf("skip %u\n", graph.edges[j].tail); - continue; - } // if - - //printf("push %u\n", graph.edges[j].tail); - table[graph.edges[j].tail].depth = table[i].depth + 1; - table[tail].next = graph.edges[j].tail; - tail = graph.edges[j].tail; - } // for - } // for - head = table[head].next; - - /* - printf(" # \tdepth\tnext\n"); - for (size_t i = 0; i < va_array_length(graph.nodes); ++i) - { - printf("%3zu:\t%5u\t%4d\n", i, table[i].depth, table[i].next); - } // for - printf("head: %d\ntail: %d\n", head, tail); - */ - } // while - - printf("\n ]\n"); - - table = allocator.alloc(allocator.context, table, sizeof(*table) * va_array_length(graph.nodes), 0); - - return count; -} // bfs_traversal - - -static void -lambda_edges(Graph const graph, size_t const len_obs, char const observed[static len_obs]) -{ - printf(" \"edges\": [\n"); - size_t count = 0; - for (uint32_t i = 0; i < va_array_length(graph.nodes); ++i) - { - if (graph.nodes[i].lambda != (uint32_t) -1) - { - if (count > 0) - { - printf(",\n"); - } // if - count += 1; - printf(" {\"head\": \"s%u\", \"tail\": \"s%u\", \"variant\": \"lambda\"}", i, graph.nodes[i].lambda); - } // if - for (uint32_t j = graph.nodes[i].edges; j != (uint32_t) -1; j = graph.edges[j].next) - { - if (count > 0) - { - printf(",\n"); - } // if - count += 1; - printf(" {\"head\": \"s%u\", \"tail\": \"s%u\", \"variant\": \"%u:%u/%.*s\"}", i, graph.edges[j].tail, graph.edges[j].variant.start, graph.edges[j].variant.end, (int) graph.edges[j].variant.obs_end - graph.edges[j].variant.obs_start, observed + graph.edges[j].variant.obs_start); - } // for - } // for - printf("\n ]\n"); -} // lambda_edges - - -void -to_json(Graph const graph, size_t const len_obs, char const observed[static len_obs], bool const lambda) -{ - printf("{\n \"source\": \"s%u\",\n \"nodes\": {\n", graph.source); - for (uint32_t i = 0; i < va_array_length(graph.nodes); ++i) - { - printf(" \"s%u\": {\"row\": %u, \"col\": %u, \"length\": %u}%s\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, i < va_array_length(graph.nodes) - 1 ? "," : ""); - } // for - printf(" },\n"); - if (lambda) { - lambda_edges(graph, len_obs, observed); - } else { - bfs_traversal(va_std_allocator, graph, len_obs, observed); - } - //printf(" \"supremal\": \"%u:%u/%.*s\",\n", graph.supremal.start, graph.supremal.end, (int) graph.supremal.obs_end - graph.supremal.obs_start, observed + graph.supremal.obs_start); - //printf(" \"local_supremal\": [\n"); - //local_supremal(va_std_allocator, graph, len_obs, observed, false); - //printf("\n ],\n"); - //printf(" \"canonical\": [\n"); - //canonical(va_std_allocator, graph, len_obs, observed, false); - //printf("\n ]\n"); - printf("}"); -} // to_json - - -static size_t -bfs_traversal3(Graph3 const graph, size_t const len_obs, char const observed[static len_obs]) -{ - struct - { - uint32_t depth; - uint32_t next; - }* table = va_std_allocator.alloc(va_std_allocator.context, NULL, 0, sizeof(*table) * va_array_length(graph.nodes)); - - if (table == NULL) - { - return -1; - } // if - - for (size_t i = 0; i < va_array_length(graph.nodes); ++i) - { - table[i].depth = 0; - table[i].next = GVA_NULL; - } // for - uint32_t head = graph.source; - uint32_t tail = graph.source; - - size_t count = 0; - fprintf(stderr, "digraph{\nrankdir=LR\nedge[fontname=monospace]\nnode[fixedsize=true,fontname=serif,shape=circle,width=1]\nsi[label=\"\",shape=none,width=0]\n"); - fprintf(stderr, "si->s%u\n", graph.source); - - bool first = true; - - printf(" \"edges\": [\n"); - while (head != GVA_NULL) - { - uint32_t len = graph.nodes[head].length; - //printf("pop %u\n", head); - for (uint32_t i = head; i != GVA_NULL; i = graph.nodes[i].lambda) - { - fprintf(stderr, "s%u[label=\"(%u, %u, %u)\"%s]\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, graph.nodes[i].edges == GVA_NULL && graph.nodes[i].lambda == GVA_NULL ? ",peripheries=2" : ""); - if (i != head) - { - len += graph.nodes[i].length; - //printf("lambda %u\n", i); - } // if - for (uint32_t j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) - { - if (count > 0) - { - //printf(",\n"); - } // if - count += 1; - VA_Variant variant; - uint32_t const count2 = edges2(((VA_LCS_Node) {.row = graph.nodes[i].row, .col =graph.nodes[i].col, .length = graph.nodes[i].length}), - ((VA_LCS_Node) {.row = graph.nodes[graph.edges[j].tail].row, .col = graph.nodes[graph.edges[j].tail].col, .length = graph.nodes[graph.edges[j].tail].length}), - graph.nodes[head].row == graph.nodes[graph.source].row && graph.nodes[head].col == graph.nodes[graph.source].col, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, &variant); - - for (uint32_t k = 0; k < count2; ++k) - { - if (!first) - { - printf(",\n"); - } // if - first = false; - fprintf(stderr, "s%u->s%u[label=\"" VAR_FMT "\"]\n", head, graph.edges[j].tail, print_variant(variant, observed)); - printf(" {\"head\": \"s%u\", \"tail\": \"s%u\", \"variant\": \"" VAR_FMT "\"}", head, graph.edges[j].tail, print_variant(variant, observed)); - variant.start += 1; - variant.end += 1; - variant.obs_start += 1; - variant.obs_end += 1; - } // for - - if (table[graph.edges[j].tail].depth > 0) - { - //printf("skip %u\n", graph.edges[j].tail); - continue; - } // if - - //printf("push %u\n", graph.edges[j].tail); - table[graph.edges[j].tail].depth = table[i].depth + 1; - table[tail].next = graph.edges[j].tail; - tail = graph.edges[j].tail; - } // for - } // for - head = table[head].next; - - /* - printf(" # \tdepth\tnext\n"); - for (size_t i = 0; i < va_array_length(graph.nodes); ++i) - { - printf("%3zu:\t%5u\t%4d\n", i, table[i].depth, table[i].next); - } // for - printf("head: %d\ntail: %d\n", head, tail); - */ - } // while - - fprintf(stderr, "}\n"); - printf("\n ]\n"); - - table = va_std_allocator.alloc(va_std_allocator.context, table, sizeof(*table) * va_array_length(graph.nodes), 0); - - return count; -} // bfs_traversal3 - - -void -to_json3(Graph3 const graph, size_t const len_obs, char const observed[static len_obs]) -{ - printf("{\n \"source\": \"s%u\",\n \"nodes\": {\n", graph.source); - for (uint32_t i = 0; i < va_array_length(graph.nodes); ++i) - { - printf(" \"s%u\": {\"row\": %u, \"col\": %u, \"length\": %u}%s\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, i < va_array_length(graph.nodes) - 1 ? "," : ""); - } // for - printf(" },\n"); - bfs_traversal3(graph, len_obs, observed); - printf("}"); -} // to_json3 - - -size_t -edges(uint32_t const head_row, uint32_t const head_col, uint32_t const head_length, - uint32_t const tail_row, uint32_t const tail_col, uint32_t const tail_length, - bool const is_source, - size_t const len_obs, char const observed[static len_obs], - VA_Variant const edge) -{ - printf( - "(%u, %u, %u) -> (%u, %u, %u) source: %d\n", - head_row, head_col, head_length, - tail_row, tail_col, tail_length, - is_source - ); - //printf(VAR_FMT "\n", print_variant(edge, observed)); - printf("%u %u %u %u\n", edge.start, edge.end, edge.obs_start, edge.obs_end); - - ptrdiff_t const row = (ptrdiff_t) head_row - is_source; - ptrdiff_t const col = (ptrdiff_t) head_col - is_source; - uint32_t const length = head_length + is_source; - - printf("%zd, %zd, %u\n", row, col, length); - - ptrdiff_t const offset = MIN((ptrdiff_t) tail_row - row, (ptrdiff_t) tail_col - col) - 1; - uint32_t const head_start = offset > 0 ? MIN(offset, length - 1) : 0; - uint32_t const tail_start = offset < 0 ? MIN(-offset, tail_length - 1) : 0; - - uint32_t const count = MIN(length - head_start, tail_length - tail_start); - - printf(" %zd: (%u, %u) :: %u\n", offset, head_start, tail_start, count); - - if (offset < 0 && tail_length <= -offset) - { - printf(" X\n"); - return 0; - } // if - - bool found = false; - for (uint32_t j = 0; j < count; ++j) - { - VA_Variant const variant = - { - row + head_start + j + 1, - tail_row + tail_start + j, - col + head_start + j + 1, - tail_col + tail_start + j - }; - - if (edge.start == variant.start && edge.end == variant.end && - edge.obs_start == variant.obs_start && edge.obs_end == variant.obs_end) - { - found = true; - } // if - - printf(" (%u, %u) -> (%u, %u) :: " VAR_FMT "\n", //"%u %u %u %u\n", - head_row + head_start + j, head_col + head_start + j, - tail_row + tail_start + j, tail_col + tail_start + j, - print_variant(variant, observed) //, - //variant.start, variant.end, variant.obs_start, variant.obs_end - ); - } // for - - if (!found) - { - return -1; - } // if - return count; -} // edges diff --git a/src/graph2.c b/src/graph2.c deleted file mode 100644 index 3f31720..0000000 --- a/src/graph2.c +++ /dev/null @@ -1,580 +0,0 @@ -#include // bool, false, true -#include // NULL, size_t -#include // intmax_t, uint32_t -#include // stderr, fprintf, printf - -#include "../include/alloc.h" // VA_Allocator -#include "../include/array.h" // va_array_* -#include "../include/edit.h" // VA_LCS_Node, va_edit -#include "../include/std_alloc.h" // va_std_allocator -#include "../include/variant.h" // VA_Variant -#include "../include/graph2.h" // Edge2, Graph2, Node2 - - -#define MAX(lhs, rhs) (((lhs) > (rhs)) ? (lhs) : (rhs)) -#define MIN(lhs, rhs) (((lhs) < (rhs)) ? (lhs) : (rhs)) - -#define print_variant(variant, observed) variant.start, variant.end, (int) variant.obs_end - variant.obs_start, observed + variant.obs_start -#define VAR_FMT "%u:%u/%.*s" - - -size_t eq_count; - - -static uint32_t const GVA_NULL = UINT32_MAX; - - -uint32_t -edges2(VA_LCS_Node const head, VA_LCS_Node const tail, - bool const is_source, bool const is_sink, - VA_Variant* const variant) -{ -// printf("%u %u %u -> %u %u %u %s %s\n", head.row, head.col, head.length, tail.row, tail.col, tail.length, is_source ? "SOURCE" : "", is_sink ? "SINK" : ""); - - intmax_t const row = (intmax_t) head.row - is_source; - intmax_t const col = (intmax_t) head.col - is_source; - uint32_t const head_length = head.length + is_source; - uint32_t const tail_length = tail.length + is_sink; - - intmax_t const offset = MIN((intmax_t) tail.row - row, (intmax_t) tail.col - col) - 1; - - uint32_t const head_offset = offset > 0 ? MIN(head_length, offset + 1) : 1; - uint32_t const tail_offset = offset < 0 ? MIN(tail_length, -offset) : 0; - - //printf(" %ld: (%u, %u)\n", offset, head_offset, tail_offset); - - if (head_offset > head_length || (tail_length > 0 && tail_offset >= tail_length)) - { - //fprintf(stderr, "NO EDGE\n"); - return 0; - } // if - - uint32_t const count = MIN(head_length - head_offset, tail_length - tail_offset - 1) + 1; - - *variant = (VA_Variant) {row + head_offset, tail.row + tail_offset, col + head_offset, tail.col + tail_offset}; - - //fprintf(stderr, VAR_FMT " x %u\n", print_variant((*variant), observed), count); - return count; -} // edges2 - - -static size_t -bfs_traversal2(Graph2 const graph, size_t const len_obs, char const observed[static len_obs]) -{ - struct - { - uint32_t depth; - uint32_t next; - }* table = va_std_allocator.alloc(va_std_allocator.context, NULL, 0, sizeof(*table) * va_array_length(graph.nodes)); - - if (table == NULL) - { - return -1; - } // if - - for (size_t i = 0; i < va_array_length(graph.nodes); ++i) - { - table[i].depth = 0; - table[i].next = GVA_NULL; - } // for - uint32_t head = graph.source; - uint32_t tail = graph.source; - - size_t count = 0; - fprintf(stderr, "digraph{\nrankdir=LR\nedge[fontname=monospace]\nnode[fixedsize=true,fontname=serif,shape=circle,width=1]\nsi[label=\"\",shape=none,width=0]\n"); - fprintf(stderr, "si->s%u\n", graph.source); - - bool first = true; - - printf(" \"edges\": [\n"); - while (head != GVA_NULL) - { - uint32_t len = graph.nodes[head].length; - //printf("pop %u\n", head); - for (uint32_t i = head; i != GVA_NULL; i = graph.nodes[i].lambda) - { - fprintf(stderr, "s%u[label=\"(%u, %u, %u)\"%s]\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, graph.nodes[i].edges == GVA_NULL && graph.nodes[i].lambda == GVA_NULL ? ",peripheries=2" : ""); - if (i != head) - { - len += graph.nodes[i].length; - //printf("lambda %u\n", i); - } // if - for (uint32_t j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) - { - if (count > 0) - { - //printf(",\n"); - } // if - count += 1; - VA_Variant variant; - uint32_t const count2 = edges2(((VA_LCS_Node) {.row = graph.nodes[i].row, .col =graph.nodes[i].col, .length = graph.nodes[i].length}), - ((VA_LCS_Node) {.row = graph.nodes[graph.edges[j].tail].row, .col = graph.nodes[graph.edges[j].tail].col, .length = graph.nodes[graph.edges[j].tail].length}), - graph.nodes[head].row == graph.nodes[graph.source].row && graph.nodes[head].col == graph.nodes[graph.source].col, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, &variant); - - for (uint32_t k = 0; k < count2; ++k) - { - if (!first) - { - printf(",\n"); - } // if - first = false; - fprintf(stderr, "s%u->s%u[label=\"" VAR_FMT "\"]\n", head, graph.edges[j].tail, print_variant(variant, observed)); - printf(" {\"head\": \"s%u\", \"tail\": \"s%u\", \"variant\": \"" VAR_FMT "\"}", head, graph.edges[j].tail, print_variant(variant, observed)); - variant.start += 1; - variant.end += 1; - variant.obs_start += 1; - variant.obs_end += 1; - } // for - - if (table[graph.edges[j].tail].depth > 0) - { - //printf("skip %u\n", graph.edges[j].tail); - continue; - } // if - - //printf("push %u\n", graph.edges[j].tail); - table[graph.edges[j].tail].depth = table[i].depth + 1; - table[tail].next = graph.edges[j].tail; - tail = graph.edges[j].tail; - } // for - } // for - head = table[head].next; - - /* - printf(" # \tdepth\tnext\n"); - for (size_t i = 0; i < va_array_length(graph.nodes); ++i) - { - printf("%3zu:\t%5u\t%4d\n", i, table[i].depth, table[i].next); - } // for - printf("head: %d\ntail: %d\n", head, tail); - */ - } // while - - fprintf(stderr, "}\n"); - printf("\n ]\n"); - - table = va_std_allocator.alloc(va_std_allocator.context, table, sizeof(*table) * va_array_length(graph.nodes), 0); - - return count; -} // bfs_traversal2 - - -static void -print_graph(Graph2 const graph, size_t const len_obs, char const observed[static len_obs]) { - fprintf(stderr, "#nodes: %zu\n#edges: %zu\n", va_array_length(graph.nodes), va_array_length(graph.edges)); - fprintf(stderr, "source: %u\n", graph.source); - if (graph.nodes == NULL) - { - return; - } // if - for (size_t i = 0; i < va_array_length(graph.nodes); ++i) { - fprintf(stderr, "%zu: (%u, %u, %u):\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length); - if (graph.nodes[i].lambda != GVA_NULL) { - fprintf(stderr, " (%u, %u, %u): lambda\n", graph.nodes[graph.nodes[i].lambda].row, graph.nodes[graph.nodes[i].lambda].col, graph.nodes[graph.nodes[i].lambda].length); - } // if - for (uint32_t j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) { - fprintf(stderr, " %u: (%u, %u, %u): ", graph.edges[j].tail, graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length); - VA_Variant variant; - uint32_t const count = edges2( - ((VA_LCS_Node) {.row = graph.nodes[i].row, .col = graph.nodes[i].col, .length = graph.nodes[i].length}), - ((VA_LCS_Node) {.row = graph.nodes[graph.edges[j].tail].row, .col = graph.nodes[graph.edges[j].tail].col, .length = graph.nodes[graph.edges[j].tail].length}), - i == graph.source, - graph.nodes[graph.edges[j].tail].edges == GVA_NULL && graph.nodes[graph.edges[j].tail].edges == GVA_NULL, - &variant); - fprintf(stderr, VAR_FMT " x %u\n", print_variant(variant, observed), count); - } // for - } // for -} // print_graph - - -static inline void -split(VA_LCS_Node2 const* const node, - uint32_t const in_count, VA_Variant const incoming, - uint32_t const split_point, - Graph2* const graph) -{ -/* - fprintf(stderr, "\n***SPLIT (%u, %u, %u) because of first outgoing edge at %u\n", node->row, node->col, node->length, node->outgoing); - fprintf(stderr, "fsp: %u lsp: %u\n", MIN(split_point - 1, incoming.end + in_count - 1), MAX(incoming.end, node->outgoing)); -*/ - uint32_t pos = 0; - for (pos = MIN(split_point - 1, incoming.end + in_count - 1); pos >= MAX(incoming.end, node->outgoing); --pos) - { - uint32_t head_head = GVA_NULL; - uint32_t head_tail = GVA_NULL; - uint32_t tail_head = GVA_NULL; - uint32_t tail_tail = GVA_NULL; - // FIXME: only once after creating all the nodes - for (uint32_t j = graph->nodes[node->idx].edges; j != GVA_NULL; j = graph->edges[j].next) - { - Node2 const* const tail = &graph->nodes[graph->edges[j].tail]; - VA_Variant outgoing; - uint32_t const out_count = edges2( - (VA_LCS_Node) {.row = node->row, .col = node->col, .length = node->length}, - (VA_LCS_Node) {.row = tail->row, .col = tail->col, .length = tail->length}, - false, tail->edges == GVA_NULL && tail->lambda == GVA_NULL, &outgoing); - //fprintf(stderr, " %u: (%u, %u, %u): x %u ", graph->edges[j].tail, tail->row, tail->col, tail->length, out_count); - - // TODO: can we avoid reordering the tail list? Yes? XOR-linked? - if (outgoing.start > pos) - { - if (tail_tail != GVA_NULL) - { - graph->edges[tail_tail].next = j; - } // if - if (tail_head == GVA_NULL) - { - tail_head = j; - } // if - tail_tail = j; - - //fprintf(stderr, "tail\n"); - } // if - else if (outgoing.start + out_count - 1 <= pos) - { - if (head_tail != GVA_NULL) - { - graph->edges[head_tail].next = j; - } // if - if (head_head == GVA_NULL) - { - head_head = j; - } // if - head_tail = j; - - //fprintf(stderr, "head\n"); - } // if - else - { - if (tail_tail != GVA_NULL) - { - graph->edges[tail_tail].next = j; - } // if - if (tail_head == GVA_NULL) - { - tail_head = j; - } // if - tail_tail = j; - va_array_append(va_std_allocator, graph->edges, ((Edge2) {graph->edges[j].tail, head_head})); - head_head = va_array_length(graph->edges) - 1; - if (head_tail == GVA_NULL) - { - head_tail = head_head; - } // if - - //fprintf(stderr, "both\n"); - } // else - } // for - if (head_tail != GVA_NULL) - { - graph->edges[head_tail].next = GVA_NULL; - } // if - if (tail_tail != GVA_NULL) - { - graph->edges[tail_tail].next = GVA_NULL; - } // if - graph->nodes[node->idx].edges = head_head; - uint32_t const length = pos - node->row; - - va_array_append(va_std_allocator, graph->nodes, ((Node2) {node->row + length, node->col + length, graph->nodes[node->idx].length - length, tail_head, graph->nodes[node->idx].lambda})); - graph->nodes[node->idx].lambda = va_array_length(graph->nodes) - 1; - graph->nodes[node->idx].length = length; - - /* - Node2 const* const lambda = &graph->nodes[graph->nodes[node->idx].lambda]; - fprintf(stderr, "(%u, %u, %u) l> (%u, %u, %u) @ %u\n", - graph->nodes[node->idx].row, graph->nodes[node->idx].col, graph->nodes[node->idx].length, - lambda->row, lambda->col, lambda->length, pos); - */ - } // for - - //fprintf(stderr, "***\n\n"); -} // split - - -static inline void -distribute(VA_LCS_Node2 const* const tail, VA_LCS_Node2 const* const head, - uint32_t const count, VA_Variant const variant, - Graph2* const graph) -{ - uint32_t lambda = tail->idx; - for (uint32_t i = 0; i < count; ++i) - { - //fprintf(stderr, "LAMBDA: %u\n", lambda); - //fprintf(stderr, " variant: %u\n", variant.end + i); - bool is_lambda = false; - while (graph->nodes[lambda].lambda != GVA_NULL && - variant.end + i >= graph->nodes[lambda].row + graph->nodes[lambda].length) - { - lambda = graph->nodes[lambda].lambda; - is_lambda = true; - } // while - - if (is_lambda || i == 0) - { - va_array_append(va_std_allocator, graph->edges, ((Edge2) {lambda, graph->nodes[head->idx].edges})); - graph->nodes[head->idx].edges = va_array_length(graph->edges) - 1; - } // if - - //fprintf(stderr, " next: %d\n", graph->nodes[lambda].lambda); - if (graph->nodes[lambda].lambda == GVA_NULL || variant.end + count <= graph->nodes[lambda].row + graph->nodes[lambda].length) - { - break; - } // if - } // for -} // distribute - - -static inline uint32_t -edges3(VA_LCS_Node2 const* const head, VA_LCS_Node2 const* const tail, - bool const is_source, bool const is_sink, - VA_Variant* const variant) -{ - uint32_t const h_min = head->lcs_pos - (head->length - 1); - uint32_t const t_min = tail->lcs_pos - (tail->length - 1); - - uint32_t const start = MAX(h_min + 1 - is_source, t_min); - uint32_t const end = MIN(head->lcs_pos + 1, tail->lcs_pos + is_sink); - - if (start > end) - { - return 0; - } // if - - uint32_t const h_offset = (head->length - 1) - (head->lcs_pos - start); - uint32_t const t_offset = (tail->length - 1) - (tail->lcs_pos - start); - - if (head->row + h_offset > tail->row + t_offset || head->col + h_offset > tail->col + t_offset) - { - return 0; - } // if - - *variant = (VA_Variant) {head->row + h_offset, tail->row + t_offset, head->col + h_offset, tail->col + t_offset}; - return end - start + 1; -} // edges3 - - -Graph2 -build(size_t const len_ref, char const reference[static restrict len_ref], - size_t const len_obs, char const observed[static restrict len_obs], - size_t const shift) -{ - VA_LCS_List* lcs_index = NULL; - VA_LCS_Node2* lcs_nodes = NULL; - size_t const len_lcs = va_edit2(va_std_allocator, len_ref, reference, len_obs, observed, &lcs_index, &lcs_nodes); - - Graph2 graph = {NULL, NULL, GVA_NULL}; - - if (lcs_nodes == NULL) - { - va_array_append(va_std_allocator, graph.nodes, ((Node2) {len_ref, len_obs, 0, GVA_NULL, GVA_NULL})); - uint32_t const sink = va_array_length(graph.nodes) - 1; - if (len_ref == 0 && len_obs == 0) - { - graph.source = sink; - return graph; - } // if - - va_array_append(va_std_allocator, graph.edges, ((Edge2) {sink, GVA_NULL})); - va_array_append(va_std_allocator, graph.nodes, ((Node2) {shift, shift, 0, va_array_length(graph.edges) - 1, GVA_NULL})); - graph.source = va_array_length(graph.nodes) - 1; - return graph; - } // if - - for (size_t i = 0; i < va_array_length(lcs_nodes); ++i) - { - fprintf(stderr, "%2zu: (%u, %u, %u) %u %2d %2d\n", i, lcs_nodes[i].row, lcs_nodes[i].col, lcs_nodes[i].length, lcs_nodes[i].lcs_pos, lcs_nodes[i].next, lcs_nodes[i].inext); - } // for - fprintf(stderr, "\n"); - - /* - for (size_t i = 0; i < len_lcs; ++i) - { - fprintf(stderr, "%zu: ", i); - for (uint32_t j = lcs_index[i].tail; j != GVA_NULL; j = lcs_nodes[j].next) - { - fprintf(stderr, "(%u, %u, %u) ", lcs_nodes[j].row, lcs_nodes[j].col, lcs_nodes[j].length); - if (j == lcs_index[i].head) - { - break; - } // if - } // for - fprintf(stderr, "\n"); - } // for - */ - - uint32_t last_idx = lcs_index[len_lcs - 1].tail; - - VA_LCS_Node2 source = {shift, shift, 0, -1, GVA_NULL, GVA_NULL, GVA_NULL, -1}; - bool found_source = false; - size_t const len = va_array_length(lcs_nodes); - VA_LCS_Node2* const last = &lcs_nodes[last_idx]; - if (last->row + last->length == len_ref + shift && last->col + last->length == len_obs + shift) - { - va_array_append(va_std_allocator, graph.nodes, ((Node2) {last->row, last->col, last->length, GVA_NULL, GVA_NULL})); - last->idx = va_array_length(graph.nodes) - 1; - if (last->row == shift && last->col == shift) - { - found_source = true; - source.idx = last->idx; - } // if - } // if - else - { - VA_LCS_Node2 const sink = {len_ref, len_obs, 0, lcs_nodes[last_idx].lcs_pos, GVA_NULL, GVA_NULL, GVA_NULL, -1}; - va_array_append(va_std_allocator, graph.nodes, ((Node2) {sink.row, sink.col, sink.length, GVA_NULL, GVA_NULL})); - uint32_t const sink_idx = va_array_length(graph.nodes) - 1; - for (uint32_t j = last_idx; j != GVA_NULL && lcs_nodes[j].lcs_pos == lcs_nodes[last_idx].lcs_pos; j = lcs_nodes[j].next) - { - VA_LCS_Node2* const head = &lcs_nodes[j]; - va_array_append(va_std_allocator, graph.edges, ((Edge2) {sink_idx, GVA_NULL})); - va_array_append(va_std_allocator, graph.nodes, ((Node2) {head->row, head->col, head->length, va_array_length(graph.edges) - 1, GVA_NULL})); - head->idx = va_array_length(graph.nodes) - 1; - head->outgoing = head->row + head->length; - if (head->row == shift && head->col == shift) - { - found_source = true; - source.idx = head->idx; - source.outgoing = head->outgoing; - } // if - - eq_count += 1; - fprintf(stderr, "(%u, %u, %u) vs (%u, %u, %u)\n", head->row, head->col, head->length, sink.row, sink.col, sink.length); - - //VA_Variant variant; - //uint32_t const count = edges3(head, &sink, head->row == shift && head->col == shift, true, &variant); - //fprintf(stderr, "(%u, %u, %u) -> (%u, %u, %u) " VAR_FMT " x %u\n", head->row, head->col, head->length, sink.row, sink.col, sink.length, print_variant(variant, observed), count); - } // for - } // else - - for (size_t i = 0; i < len; ++i) - { - uint32_t const idx = len - i - 1; - VA_LCS_Node2 const* const restrict tail = &lcs_nodes[idx]; - - if (lcs_nodes[idx].inext != GVA_NULL) - { - lcs_nodes[lcs_nodes[idx].inext].next = lcs_nodes[idx].next; - } // if - else - { - last_idx = lcs_nodes[idx].next; - } // else - if (lcs_nodes[idx].next != GVA_NULL) - { - lcs_nodes[lcs_nodes[idx].next].inext = lcs_nodes[idx].inext; - } // if - - if (tail->idx == GVA_NULL) - { - continue; - } // if - bool const is_sink = tail->row + tail->length == len_ref + shift && tail->col + tail->length == len_obs + shift; - - uint32_t split_point = -1; - - uint32_t const lcs_low = tail->length > tail->lcs_pos ? 0 : tail->lcs_pos - tail->length; - - uint32_t j = last_idx; - //fprintf(stderr, "%d\n", last_idx); - if (tail->length == 1 && lcs_index[tail->lcs_pos].head < last_idx) - { - //j = lcs_nodes[lcs_index[tail->lcs_pos].head].next; - } - for (; j != GVA_NULL && lcs_nodes[j].lcs_pos >= lcs_low; j = lcs_nodes[j].next) - { - VA_LCS_Node2* const head = &lcs_nodes[j]; - bool const is_source = head->row == shift && head->col == shift; - - eq_count += 1; - fprintf(stderr, "(%u, %u, %u) vs (%u, %u, %u)\n", head->row, head->col, head->length, tail->row, tail->col, tail->length); - - VA_Variant variant; - uint32_t const count = edges3(head, tail, is_source, is_sink, &variant); - if (count == 0) - { - continue; - } // if - - if (head->idx == GVA_NULL) - { - va_array_append(va_std_allocator, graph.nodes, ((Node2) {head->row, head->col, head->length, GVA_NULL, GVA_NULL})); - head->idx = va_array_length(graph.nodes) - 1; - if (is_source) - { - found_source = true; - source.idx = head->idx; - } // if - } // if - - //fprintf(stderr, "(%u, %u, %u) -> (%u, %u, %u) " VAR_FMT " x %u\n", head->row, head->col, head->length, tail->row, tail->col, tail->length, print_variant(variant, observed), count); - - if (variant.end + count > tail->outgoing && split_point != tail->outgoing) - { - split(tail, count, variant, split_point, &graph); - split_point = MIN(split_point, MAX(variant.end, tail->outgoing)); - } // if - distribute(tail, head, count, variant, &graph); - head->outgoing = MIN(head->outgoing, variant.start); - source.outgoing = MIN(source.outgoing, variant.start); - -// NO SPLIT NODES -// va_array_append(va_std_allocator, graph.edges, ((Edge2) {tail->idx, graph.nodes[head->idx].edges})); -// graph.nodes[head->idx].edges = va_array_length(graph.edges); - - } // for - - if (!found_source && tail->length > tail->lcs_pos) - { - eq_count += 1; - fprintf(stderr, "(%u, %u, %u) vs (%u, %u, %u)\n", source.row, source.col, source.length, tail->row, tail->col, tail->length); - - if (source.idx == GVA_NULL) - { - va_array_append(va_std_allocator, graph.nodes, ((Node2) {source.row, source.col, source.length, GVA_NULL, GVA_NULL})); - source.idx = va_array_length(graph.nodes) - 1; - source.outgoing = 0; - } // if - va_array_append(va_std_allocator, graph.edges, ((Edge2) {tail->idx, graph.nodes[source.idx].edges})); - graph.nodes[source.idx].edges = va_array_length(graph.edges) - 1; - - //VA_Variant variant; - //uint32_t const count = edges3(&source, tail, true, is_sink, &variant); - //fprintf(stderr, "(%u, %u, %u) -> (%u, %u, %u) " VAR_FMT " x %u\n", source.row, source.col, source.length, tail->row, tail->col, tail->length, print_variant(variant, observed), count); - } // if - } // for - - lcs_nodes = va_array_destroy(va_std_allocator, lcs_nodes); - va_std_allocator.alloc(va_std_allocator.context, lcs_index, len_lcs * sizeof(*lcs_index), 0); - - //fprintf(stderr, "SOURCE first outgoing edge at %d\n", source.outgoing); - if (source.outgoing != (uint32_t) -1) - { - graph.nodes[source.idx].row += source.outgoing; - graph.nodes[source.idx].col += source.outgoing; - graph.nodes[source.idx].length -= source.outgoing; - } // if - else - { - graph.nodes[source.idx].length = 0; - } // else - - graph.source = source.idx; - //print_graph(graph, len_obs, observed); - - return graph; -} // build - - -void -to_json2(Graph2 const graph, size_t const len_obs, char const observed[static len_obs]) -{ - printf("{\n \"source\": \"s%u\",\n \"nodes\": {\n", graph.source); - for (uint32_t i = 0; i < va_array_length(graph.nodes); ++i) - { - printf(" \"s%u\": {\"row\": %u, \"col\": %u, \"length\": %u}%s\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, i < va_array_length(graph.nodes) - 1 ? "," : ""); - } // for - printf(" },\n"); - bfs_traversal2(graph, len_obs, observed); - printf("}"); -} // to_json2 diff --git a/src/lcs_graph.c b/src/lcs_graph.c new file mode 100644 index 0000000..399142a --- /dev/null +++ b/src/lcs_graph.c @@ -0,0 +1,230 @@ +#include // intmax_t +#include // bool, false, true +#include // size_t + +#include "../include/allocator.h" // GVA_Allocator +#include "../include/lcs_graph.h" // GVA_LCS_Graph, GVA_Variant, gva_lcs_graph_* +#include "array.h" // ARRAY_*, array_length +#include "base.h" // gva_uint, MAX, MIN +#include "edit.h" // LCS, edit + + +gva_uint +gva_edges(GVA_Node const head, GVA_Node const tail, + bool const is_source, bool const is_sink, + GVA_Variant* const variant) +{ + intmax_t const row = (intmax_t) head.row - is_source; + intmax_t const col = (intmax_t) head.col - is_source; + gva_uint const head_length = head.length + is_source; + gva_uint const tail_length = tail.length + is_sink; + + intmax_t const offset = MIN((intmax_t) tail.row - row, (intmax_t) tail.col - col) - 1; + + gva_uint const head_offset = offset > 0 ? MIN(head_length, offset + 1) : 1; + gva_uint const tail_offset = offset < 0 ? MIN(tail_length, -offset) : 0; + + if (head_offset > head_length || (tail_length > 0 && tail_offset >= tail_length)) + { + return 0; + } // if + + *variant = (GVA_Variant) { + row + head_offset, tail.row + tail_offset, + col + head_offset, tail.col + tail_offset + }; + return MIN(head_length - head_offset, tail_length - tail_offset - 1) + 1; +} // gva_edges + + +GVA_LCS_Graph +gva_lcs_graph_init(GVA_Allocator const allocator, + size_t const len_ref, char const reference[static restrict len_ref], + size_t const len_obs, char const observed[static restrict len_obs], + size_t const shift) +{ + LCS const lcs = edit(allocator, len_ref, reference, len_obs, observed); + + GVA_LCS_Graph graph = {.nodes = NULL, .edges = NULL}; + + if (lcs.nodes == NULL) + { + gva_uint const sink = ARRAY_APPEND(allocator, graph.nodes, ((GVA_Node) { + len_ref, len_obs, 0, GVA_NULL, GVA_NULL + })) - 1; + if (len_ref == 0 && len_obs == 0) + { + graph.source = sink; + return graph; + } // if + + graph.source = ARRAY_APPEND(allocator, graph.nodes, ((GVA_Node) { + shift, shift, 0, + ARRAY_APPEND(allocator, graph.edges, ((GVA_Edge) {sink, GVA_NULL})) - 1, + GVA_NULL + })) - 1; + return graph; + } // if + + gva_uint tail_idx = lcs.index[lcs.length - 1].tail; + LCS_Node sink = lcs.nodes[tail_idx]; + if (sink.row + sink.length == len_ref + shift && sink.col + sink.length == len_obs + shift) + { + lcs.nodes[tail_idx].idx = ARRAY_APPEND(allocator, graph.nodes, ((GVA_Node) { + sink.row, sink.col, sink.length, GVA_NULL, GVA_NULL + })) - 1; + lcs.nodes[tail_idx].moved = true; + sink = lcs.nodes[tail_idx]; + } // if + else + { + sink = (LCS_Node) {.row = len_ref + shift, .col = len_obs + shift, .length = 0}; + sink.idx = ARRAY_APPEND(allocator, graph.nodes, ((GVA_Node) { + sink.row, sink.col, sink.length, GVA_NULL, GVA_NULL + })) - 1; + tail_idx = GVA_NULL; + } // else + for (gva_uint i = lcs.index[lcs.length - 1].head; i != tail_idx; i = lcs.nodes[i].next) + { + lcs.nodes[i].idx = ARRAY_APPEND(allocator, graph.nodes, ((GVA_Node) { + lcs.nodes[i].row, lcs.nodes[i].col, lcs.nodes[i].length, + ARRAY_APPEND(allocator, graph.edges, ((GVA_Edge) {sink.idx, GVA_NULL})) - 1, + GVA_NULL + })) - 1; + } // for + + for (gva_uint i = lcs.length - 1; i >= 1; --i) + { + gva_uint next = GVA_NULL; + for (gva_uint j = lcs.index[i].head; j != GVA_NULL; j = next) + { + LCS_Node* const tail = &lcs.nodes[j]; + next = tail->next; + if (lcs.nodes[j].idx == GVA_NULL) + { + continue; + } // if + + gva_uint here = GVA_NULL; + for (gva_uint k = lcs.index[i - 1].head; k != GVA_NULL; k = lcs.nodes[k].next) + { + LCS_Node* const head = &lcs.nodes[k]; + + if (k > j || + head->row + head->length >= tail->row + tail->length || + head->col + head->length >= tail->col + tail->length) + { + continue; + } // if + + here = k; + if (head->incoming == i) + { + gva_uint const split_idx = head->idx; + head->idx = ARRAY_APPEND(allocator, graph.nodes, ((GVA_Node) { + head->row, head->col, head->length, + ARRAY_APPEND(allocator, graph.edges, ((GVA_Edge) {tail->idx, GVA_NULL})) - 1, + split_idx + })) - 1; + head->moved = false; + head->incoming = 0; + + graph.nodes[split_idx].row += head->length; + graph.nodes[split_idx].col += head->length; + graph.nodes[split_idx].length -= head->length; + } // if + else if (head->idx == GVA_NULL) + { + head->idx = ARRAY_APPEND(allocator, graph.nodes, ((GVA_Node) { + head->row, head->col, head->length, + ARRAY_APPEND(allocator, graph.edges, ((GVA_Edge) {tail->idx, GVA_NULL})) - 1, + GVA_NULL + })) - 1; + } // if + else if (!head->moved || !tail->moved) + { + graph.nodes[head->idx].edges = ARRAY_APPEND(allocator, graph.edges, ((GVA_Edge) { + tail->idx, graph.nodes[head->idx].edges + })) - 1; + } // if + } // for + + if (tail->length > 1) + { + tail->length -= 1; + tail->moved = true; + if (here != GVA_NULL) + { + tail->incoming = i; + tail->next = lcs.nodes[here].next; + lcs.nodes[here].next = j; + } // if + else + { + tail->next = lcs.index[i - 1].head; + lcs.index[i - 1].head = j; + } // else + } // if + } // for + } // for + + gva_uint head_idx = lcs.index[0].head; + LCS_Node source = lcs.nodes[head_idx]; + if (source.row == shift && source.col == shift) + { + head_idx = source.next; + } // if + else + { + source = (LCS_Node) {.row = shift, .col = shift, .length = 0}; + source.idx = ARRAY_APPEND(allocator, graph.nodes, ((GVA_Node) { + source.row, source.col, source.length, GVA_NULL, GVA_NULL + })) - 1; + } // else + for (gva_uint i = head_idx; i != GVA_NULL; i = lcs.nodes[i].next) + { + if (lcs.nodes[i].idx == GVA_NULL) + { + continue; + } // if + + if (source.length == 0 || !lcs.nodes[i].moved) + { + graph.nodes[source.idx].edges = ARRAY_APPEND(allocator, graph.edges, ((GVA_Edge) { + lcs.nodes[i].idx, graph.nodes[source.idx].edges + })) - 1; + } // if + } // for + + gva_uint min_source = GVA_NULL; + for (gva_uint i = graph.nodes[source.idx].edges; i != GVA_NULL; i = graph.edges[i].next) + { + GVA_Variant variant; + gva_edges(graph.nodes[source.idx], graph.nodes[graph.edges[i].tail], true, false, &variant); + min_source = MIN(min_source, variant.start); + } // for + if (min_source != GVA_NULL) + { + graph.nodes[source.idx].row += min_source; + graph.nodes[source.idx].col += min_source; + graph.nodes[source.idx].length -= min_source; + } // if + else + { + graph.nodes[source.idx].length = 0; + } // else + + graph.source = source.idx; + + allocator.allocate(allocator.context, lcs.index, lcs.length * sizeof(*lcs.index), 0); + ARRAY_DESTROY(allocator, lcs.nodes); + return graph; +} // gva_lcs_graph_init + + +inline void +gva_lcs_graph_destroy(GVA_Allocator const allocator, GVA_LCS_Graph self) +{ + self.nodes = ARRAY_DESTROY(allocator, self.nodes); + self.edges = ARRAY_DESTROY(allocator, self.edges); +} // gva_lcs_graph_destroy diff --git a/src/main.c b/src/main.c index af81ec8..d108019 100644 --- a/src/main.c +++ b/src/main.c @@ -1,301 +1,191 @@ -#include // bool, false, true -#include // NULL, size_t -#include // uint32_t -#include // stderr, fprintf, printf -#include // EXIT_*, atoi, rand, srand +#include // size_t +#include // FILE, stderr, fprintf +#include // EXIT_* #include // strlen -#include "../include/array.h" // va_array_* -#include "../include/edit.h" // va_edit -#include "../include/graph.h" // Graph, to_dot -#include "../include/graph2.h" // build -#include "../include/std_alloc.h" // va_std_allocator - -#define print_variant(variant, observed) variant.start, variant.end, (int) variant.obs_end - variant.obs_start, observed + variant.obs_start -#define VAR_FMT "%u:%u/%.*s" +#include "../include/lcs_graph.h" // GVA_LCS_Graph, GVA_Variant, gva_lcs_graph_*, gva_edges +#include "../include/std_alloc.h" // gva_std_allocator +#include "../include/types.h" // GVA_NULL, gva_uint +#include "array.h" // array_length -static uint32_t const GVA_NULL = UINT32_MAX; +#define PRI_VAR(variant, observed) variant.start, variant.end, (int) variant.obs_end - variant.obs_start, observed + variant.obs_start +#define VAR_FMT "%u:%u/%.*s" -static size_t -random_sequence(size_t const min, size_t const max, char sequence[static max]) +static void +lcs_graph_dot(FILE* const stream, GVA_LCS_Graph const graph, + size_t const len_obs, char const observed[static len_obs]) { - size_t const len = rand() % (max - min) + min; - - for (size_t i = 0; i < len; ++i) + fprintf(stream, "strict digraph{\nrankdir=LR\nedge[fontname=monospace]\nnode[fixedsize=true,fontname=serif,shape=circle,width=1]\ni[label=\"\",shape=none,width=0]\ni->%u\n", graph.source); + for (size_t i = 0; i < array_length(graph.nodes); ++i) { - sequence[i] = "ACGT"[rand() % 4]; + fprintf(stream, "%zu[label=\"(%u, %u, %u)\"%s]\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, graph.nodes[i].edges == GVA_NULL ? ",peripheries=2" : ""); + if (graph.nodes[i].lambda != GVA_NULL) + { + fprintf(stream, "%zu->%u[label=\"λ\",style=dashed]\n", i, graph.nodes[i].lambda); + } // if + for (gva_uint j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) + { + GVA_Variant variant; + gva_uint const count = gva_edges(graph.nodes[i], graph.nodes[graph.edges[j].tail], + i == graph.source, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, + &variant); + if (count > 1) + { + fprintf(stream, "%zu->%u[label=\"" VAR_FMT " x %u\",penwidth=2]\n", i, graph.edges[j].tail, PRI_VAR(variant, observed), count); + } // if + else + { + fprintf(stream, "%zu->%u[label=\"" VAR_FMT "\"]\n", i, graph.edges[j].tail, PRI_VAR(variant, observed)); + } // else + } // for } // for - - return len; -} // random_sequence + fprintf(stream, "}\n"); +} // lcs_graph_dot -static int -check(size_t const len_ref, char const reference[static len_ref], - size_t const len_obs, char const observed[static len_obs], - bool const debug) +static void +bfs_traversal(FILE* const stream, GVA_LCS_Graph const graph, + size_t const len_obs, char const observed[static len_obs]) { - VA_LCS_Node** lcs_nodes = NULL; - size_t const len_lcs = va_edit(va_std_allocator, len_ref, reference, len_obs, observed, &lcs_nodes); - - if (debug) + struct { - fprintf(stderr, "%zu\n", len_lcs); - for (size_t i = 0; i < len_lcs; ++i) - { - fprintf(stderr, "%zu: ", i); - for (size_t j = 0; j < va_array_length(lcs_nodes[i]); ++j) - { - fprintf(stderr, "(%u, %u, %u) ", lcs_nodes[i][j].row, lcs_nodes[i][j].col, lcs_nodes[i][j].length); - } // for - fprintf(stderr, "\n"); - } // for - } // if + gva_uint depth; + gva_uint next; + }* table = gva_std_allocator.allocate(gva_std_allocator.context, NULL, 0, sizeof(*table) * array_length(graph.nodes)); - Graph graph = build_graph(va_std_allocator, len_ref, len_obs, len_lcs, lcs_nodes, 0, false); - - if (debug) + if (table == NULL) { - to_dot(graph, len_obs, observed); + return; } // if - printf("#nodes: %zu\n#edges: %zu\n", va_array_length(graph.nodes), va_array_length(graph.edges)); - printf("source: %u\n", graph.source); - for (size_t i = 0; i < va_array_length(graph.nodes); ++i) + for (size_t i = 0; i < array_length(graph.nodes); ++i) { - printf("%zu: (%u, %u, %u):\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length); - if (graph.nodes[i].lambda != GVA_NULL) - { - printf(" (%u, %u, %u): lambda\n", graph.nodes[graph.nodes[i].lambda].row, graph.nodes[graph.nodes[i].lambda].col, graph.nodes[graph.nodes[i].lambda].length); - } - for (uint32_t j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) - { - printf(" (%u, %u, %u): " VAR_FMT "\n", graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length, print_variant(graph.edges[j].variant, observed)); - } // for + table[i].depth = 0; + table[i].next = GVA_NULL; } // for + gva_uint head = graph.source; + gva_uint tail = graph.source; - size_t count = 0; - for (uint32_t head = 0; head < va_array_length(graph.nodes); ++head) + bool first = true; + fprintf(stream, " \"edges\": [\n"); + while (head != GVA_NULL) { - uint32_t* tails = va_array_init(va_std_allocator, 10, sizeof(*tails)); - for (uint32_t i = graph.nodes[head].edges; i != (uint32_t) -1; i = graph.edges[i].next) + gva_uint len = graph.nodes[head].length; + for (gva_uint i = head; i != GVA_NULL; i = graph.nodes[i].lambda) { - uint32_t const tail = graph.edges[i].tail; - - bool found = false; - for (uint32_t j = 0; j < va_array_length(tails); ++j) + if (i != head) { - if (tail == tails[j]) + len += graph.nodes[i].length; + } // if + for (gva_uint j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) + { + GVA_Variant variant; + gva_uint const count = gva_edges(graph.nodes[i], graph.nodes[graph.edges[j].tail], + i == graph.source, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, + &variant); + + for (gva_uint k = 0; k < count; ++k) { - found = true; - break; + if (!first) + { + printf(",\n"); + } // if + first = false; + fprintf(stream, " {\"head\": \"s%u\", \"tail\": \"s%u\", \"variant\": \"" VAR_FMT "\"}", head, graph.edges[j].tail, PRI_VAR(variant, observed)); + variant.start += 1; + variant.end += 1; + variant.obs_start += 1; + variant.obs_end += 1; + } // for + + if (table[graph.edges[j].tail].depth > 0) + { + continue; } // if - } // for - va_array_append(va_std_allocator, tails, tail); - - size_t const n = edges( - graph.nodes[head].row, graph.nodes[head].col, graph.nodes[head].length, - graph.nodes[tail].row, graph.nodes[tail].col, graph.nodes[tail].length + (graph.nodes[tail].edges == (uint32_t) -1), - graph.source == head, - len_obs, observed, - graph.edges[i].variant - ); - if (n == (size_t) -1) - { - printf("EDGE NOT FOUND: " VAR_FMT "\n", print_variant(graph.edges[i].variant, observed)); - return EXIT_FAILURE; - } // if - if (!found) - { - count += n; - } // if + table[graph.edges[j].tail].depth = table[i].depth + 1; + table[tail].next = graph.edges[j].tail; + tail = graph.edges[j].tail; + } // for } // for - tails = va_array_destroy(va_std_allocator, tails); - } // for + head = table[head].next; + } // while - if (count != va_array_length(graph.edges)) - { - printf("COUNTS: %zu vs %zu\n", count, va_array_length(graph.edges)); - return EXIT_FAILURE; - } // if + fprintf(stream, "\n ]\n"); - destroy(va_std_allocator, &graph); - return EXIT_SUCCESS; -} // check + table = gva_std_allocator.allocate(gva_std_allocator.context, table, sizeof(*table) * array_length(graph.nodes), 0); +} // bfs_traversal static void -print_graph(Graph const graph, size_t const len_obs, char const observed[static len_obs]) { - fprintf(stderr, "#nodes: %zu\n#edges: %zu\n", va_array_length(graph.nodes), va_array_length(graph.edges)); - fprintf(stderr, "source: %u\n", graph.source); - if (graph.nodes == NULL) +lcs_graph_json(FILE* const stream, GVA_LCS_Graph const graph, + size_t const len_obs, char const observed[static len_obs]) +{ + fprintf(stream, "{\n \"source\": \"s%u\",\n \"nodes\": {\n", graph.source); + for (gva_uint i = 0; i < array_length(graph.nodes); ++i) { - return; - } // if - for (size_t i = 0; i < va_array_length(graph.nodes); ++i) { - fprintf(stderr, "%zu: (%u, %u, %u):\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length); - if (graph.nodes[i].lambda != GVA_NULL) { - fprintf(stderr, " (%u, %u, %u): lambda\n", graph.nodes[graph.nodes[i].lambda].row, graph.nodes[graph.nodes[i].lambda].col, graph.nodes[graph.nodes[i].lambda].length); - } // if - for (uint32_t j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) { - fprintf(stderr, " %u: (%u, %u, %u): ", graph.edges[j].tail, graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length); - fprintf(stderr, VAR_FMT "\n", print_variant(graph.edges[j].variant, observed)); - } // for + fprintf(stream, " \"s%u\": {\"row\": %u, \"col\": %u, \"length\": %u}%s\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, i < array_length(graph.nodes) - 1 ? "," : ""); } // for -} // print_graph + fprintf(stream, " },\n"); + bfs_traversal(stream, graph, len_obs, observed); + fprintf(stream, "}\n"); +} // lcs_graph_json static void -print_graph3(Graph3 const graph, size_t const len_obs, char const observed[static len_obs]) { - fprintf(stderr, "#nodes: %zu\n#edges: %zu\n", va_array_length(graph.nodes), va_array_length(graph.edges)); - fprintf(stderr, "source: %u\n", graph.source); +lcs_graph_raw(FILE* const stream, GVA_LCS_Graph const graph, + size_t const len_obs, char const observed[static len_obs]) +{ + fprintf(stream, "#nodes: %zu\n#edges: %zu\n", array_length(graph.nodes), array_length(graph.edges)); + fprintf(stream, "source: %u\n", graph.source); if (graph.nodes == NULL) { return; } // if - for (size_t i = 0; i < va_array_length(graph.nodes); ++i) { - fprintf(stderr, "%zu: (%u, %u, %u):\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length); - if (graph.nodes[i].lambda != GVA_NULL) { - fprintf(stderr, " (%u, %u, %u): lambda\n", graph.nodes[graph.nodes[i].lambda].row, graph.nodes[graph.nodes[i].lambda].col, graph.nodes[graph.nodes[i].lambda].length); + + for (size_t i = 0; i < array_length(graph.nodes); ++i) + { + fprintf(stream, "%zu: (%u, %u, %u):\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length); + if (graph.nodes[i].lambda != GVA_NULL) + { + fprintf(stream, " lambda: (%u, %u, %u)\n", graph.nodes[graph.nodes[i].lambda].row, graph.nodes[graph.nodes[i].lambda].col, graph.nodes[graph.nodes[i].lambda].length); } // if - for (uint32_t j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) { - fprintf(stderr, " %u: (%u, %u, %u): ", graph.edges[j].tail, graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length); - VA_Variant variant; - uint32_t const count = edges2( - ((VA_LCS_Node) {.row = graph.nodes[i].row, .col = graph.nodes[i].col, .length = graph.nodes[i].length}), - ((VA_LCS_Node) {.row = graph.nodes[graph.edges[j].tail].row, .col = graph.nodes[graph.edges[j].tail].col, .length = graph.nodes[graph.edges[j].tail].length}), - i == graph.source, - graph.nodes[graph.edges[j].tail].edges == GVA_NULL && graph.nodes[graph.edges[j].tail].edges == GVA_NULL, - &variant); - fprintf(stderr, VAR_FMT " x %u\n", print_variant(variant, observed), count); + for (gva_uint j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) + { + fprintf(stream, " %u: (%u, %u, %u): ", graph.edges[j].tail, graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length); + GVA_Variant variant; + gva_uint const count = gva_edges(graph.nodes[i], graph.nodes[graph.edges[j].tail], + i == graph.source, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, + &variant); + fprintf(stream, VAR_FMT " x %u\n", PRI_VAR(variant, observed), count); } // for } // for -} // print_graph3 +} // lcs_graph_raw int main(int argc, char* argv[static argc + 1]) { -/* - (void) argv; - char const* const restrict reference = "ATTCTATCTTCTGTCTACATAAGATGTCATACTAGAGGGCATATCTGCAATGTATACATATTATCTTTTCCAGCATGCATTCAGTTGTGTTGGAATAATTTATGTACACCTTTATAAACGCTGAGCCTCACAAGAGCCATGTGCCACGTATTGTTTTCTTACTACTTTTTGGGATACCTGGCACGTAATAGACACTCATTGAAAGTTTCCTAATGAATGAAGTACAAAGATAAAACAAGTTATAGACTGATTCTTTTGAGCTGTCAAGGTTGTAAATAGACTTTTGCTCAATCAATTCAAATGGTGGCAGGTAGTGGGGGTAGAGGGATTGGTATGAAAAACATAAGCTTTCAGAACTCCTGTGTTTATTTTTAGAATGTCAACTGCTTGAGTGTTTTTAACTCTGTGGTATCTGAACTATCTTCTCTAACTGCAGGTTGGGCTCAGATCTGTGATAGAACAGTTTCCTGGGAAGCTTGACTTTGTCCTTGTGGATGGGGGCTGTGTCCTAAGCCATGGCCACAAGCAGTTGATGTGCTTGGCTAGATCTGTTCTCAGTAAGGCGAAGATCTTGCTGCTTGATGAACCCAGTGCTCATTTGGATCCAGTGTGAGTTTCAGATGTTCTGTTACTTAATAGCACAGTGGGAACAGAATCATTATGCCTGCTTCATGGTGACACATATTTCTATTAGGCTGTCATGTCTGCGTGTGGGGGTCTCCCCCAAGATATGAAATAATTGCCCAGTGGAAATGAGCATAAATGCATATTTCCTTGCTAAGAGTCTTGTGTTTTCTTCCGAAGATAGTTTTTAGTTTCATACAAACTCTTCCCCCTTGTCAACACATGATGAAGCTTTTAAATACATGGGCCTAATCTGATCCTTATGATTTGCCTTTGTATCCCATTTATACCATAAGCATGTTTATAGCCCCAAATAAAGAAGTACTGGTGATTCTACATAATGAAAAATGTACTCATTTATTAAAGTTTCTTTGAAATATTTGTCCTGTTTATTTATGGATACTTAGAGTCTACCCCATGGTTGAAAAGCTGATTGTGGCTAACGCTATATCAACATTATGTGAAAAGAACTTAAAGAAATAAGTAATTTAAAGAGATAATAGAACAATAGACATATTATCAAGGTAAATACAGATCATTACTGTTCTGTGATATTATGTGTGGTATTTTCTTTCTTTTCTAGAACATACCAAATAATTAGAAGAACTCTAAAACAAGCATTTGCTGATTGCACAGTAATTCTCTGTGAACACAGGATAGAAGCAATGCTGGAATGCCAACAATTTTTGGTGAGTCTTTATAACTTTACTTAAGATCTCATTGCCCTTGTAATTCTTGATAACAATCTCACATGTGATAGTTCCTGCAAATTGCAACAATGTACAAGTTCTTTTCAAAAATATGTATCATACAGCCATCCAGCTTTACTCAAAATAGCTGCACAAGTTTTTCACTTTGATCTGAGCCATGTGGTGAGGTTGAAATATAGTAAATCTAAAATGGCAGCATATTACTAAGTTATGTTTATAAATAGGATATATATACTTTTTGAGCCCTTTATTTGGGGACCAAGTCATACAAAATACTCTACTGTTTAAGATTTTAAAAAAGGTCCCTGTGATTCTTTCAATAACTAAATGTCCCATGGATGTGGTCTGGGACAGGCCTAGTTGTCTTACAGTCTGATTTATGGTATTAATGACAAAGTTGAGAGGCACATTTCATTTTT"; - char const* const restrict observed = "ATTCTATCTTCTGTCTACATAAGATGTCATACTAGAGGGCATATCTGCAATGTATACATATTATCTTTTCCAGCATGCATTCAGTTGTGTTGGAATAATTTATGTACACCTTTATAAACGCTGAGCCTCACAAGAGCCATGTGCCACGTATTGTTTTCTTACTACTTTTTGGGATACCTGGCACGTAATAGACACTCATTGAAAGTTTCCTAATGAATGAAGTACAAAGATAAAACAAGTTATAGACTGATTCTTTTGAGCTGTCAAGGTTGTAAATAGACTTTTGCTCAATCAATTCAAATGGTGGCAGGTAGTGGGGGTAGAGGGATTGGTATGAAAAACATAAGCTTTCAGAACTCCTGTGTTTATTTTTAGAATGTCAACTGCTTGAGTGTTTTTAACTCTGTGGTATCTGAACTATCTTCTCTAACTGCAGGTGAGTCTTTATAACTTTACTTAAGATCTCATTGCCCTTGTAATTCTTGATAACAATCTCACATGTGATAGTTCCTGCAAATTGCAACAATGTACAAGTTCTTTTCAAAAATATGTATCATACAGCCATCCAGCTTTACTCAAAATAGCTGCACAAGTTTTTCACTTTGATCTGAGCCATGTGGTGAGGTTGAAATATAGTAAATCTAAAATGGCAGCATATTACTAAGTTATGTTTATAAATAGGATATATATACTTTTTGAGCCCTTTATTTGGGGACCAAGTCATACAAAATACTCTACTGTTTAAGATTTTAAAAAAGGTCCCTGTGATTCTTTCAATAACTAAATGTCCCATGGATGTGGTCTGGGACAGGCCTAGTTGTCTTACAGTCTGATTTATGGTATTAATGACAAAGTTGAGAGGCACATTTCATTTTT"; - size_t const len_ref = strlen(reference); - size_t const len_obs = strlen(observed); - eq_count = 0; - //Graph2 graph = build(len_ref, reference, len_obs, observed, 0); - //VA_LCS_Node2* lcs_nodes = va_edit2(va_std_allocator, len_ref, reference, len_obs, observed, &(uint32_t) {0}); - //VA_LCS_Node** lcs_nodes = NULL; - //size_t const len_lcs = va_edit(va_std_allocator, len_ref, reference, len_obs, observed, &lcs_nodes); - //Graph graph = build_graph(va_std_allocator, len_ref, len_obs, len_lcs, lcs_nodes, 0, false); - Graph3 graph = build3(va_std_allocator, len_ref, reference, len_obs, observed, 0); - - printf("nodes: %zu\nedges: %zu\n", va_array_length(graph.nodes), va_array_length(graph.edges)); - printf("%zu\n", eq_count); - va_array_destroy(va_std_allocator, graph.nodes); - va_array_destroy(va_std_allocator, graph.edges); - return 0; -*/ - if (argc == 2) - { - srand(atoi(argv[1])); - size_t count = 0; - while (true) - { - char reference[4096]; - char observed[4096]; - size_t const len_ref = random_sequence(0, 40, reference); - size_t const len_obs = random_sequence(0, 40, observed); - - printf("%zu: %.*s %.*s\n", count, (int) len_ref, reference, (int) len_obs, observed); - if (check(len_ref, reference, len_obs, observed, false) == EXIT_FAILURE) - { - return EXIT_FAILURE; - } // if - count += 1; - } // while - } // if - else if (argc == 3) + if (argc != 3) { - char const* const restrict reference = argv[1]; - char const* const restrict observed = argv[2]; - size_t const len_ref = strlen(reference); - size_t const len_obs = strlen(observed); - - Graph3 graph = build3(va_std_allocator, len_ref, reference, len_obs, observed, 0); - print_graph3(graph, len_obs, observed); - to_json3(graph, len_obs, observed); - - va_array_destroy(va_std_allocator, graph.nodes); - va_array_destroy(va_std_allocator, graph.edges); - - //to_json(graph, len_obs, observed, false); - - //destroy(va_std_allocator, &graph); -/* - for (size_t i = 0; i < len_lcs; ++i) - { - fprintf(stderr, "%2zu: ", i); - for (size_t j = 0; j < va_array_length(lcs_nodes[i]); ++j) - { - fprintf(stderr, "(%u, %u, %u) ", lcs_nodes[i][j].row, lcs_nodes[i][j].col, lcs_nodes[i][j].length); - } // for - fprintf(stderr, "\n"); - } // for - fprintf(stderr, "\n"); - - eq_count = 0; - //check(len_ref, reference, len_obs, observed, true); - Graph2 graph2 = build(len_ref, reference, len_obs, observed, 0); - fprintf(stderr, "new count: %zu\n", eq_count); -*/ - //to_json2(graph2, len_obs, observed); -/* - VA_LCS_Node** lcs_nodes = NULL; - size_t const len_lcs = va_edit(va_std_allocator, len_ref, reference, len_obs, observed, &lcs_nodes); - eq_count = 0; - Graph graph_old = build_graph(va_std_allocator, len_ref, len_obs, len_lcs, lcs_nodes, 0, false); - fprintf(stderr, "old count: %zu\n\n", eq_count); - - print_graph(graph_old, len_obs, observed); - // to_dot(graph, len_obs, observed); - // to_json(graph, len_obs, observed, false); - - // destroy graph2 - //va_array_destroy(va_std_allocator, graph2.nodes); - //va_array_destroy(va_std_allocator, graph2.edges); - - destroy(va_std_allocator, &graph_old); - */ - } // if - else - { - fprintf(stderr, "usage: %s\n", argv[0]); + fprintf(stderr, "usage %s reference observed\n", argv[0]); return EXIT_FAILURE; - } // else - -/* - printf("nodes (%zu)\n #\t(row, col, len)\tedges\tlambda\n", va_array_length(graph.nodes)); - for (size_t i = 0; i < va_array_length(graph.nodes); ++i) + } // if - { - printf("%c%2zu:\t(%u, %u, %u)\t%5d\t%6d\n", i == graph.source ? '*' : ' ', i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, (signed) graph.nodes[i].edges, (signed) graph.nodes[i].lambda); - } // for - printf("edges (%zu)\n #\ttail\t\"start:end/seq\"\tnext\n", va_array_length(graph.edges)); - for (size_t i = 0; i < va_array_length(graph.edges); ++i) - { - printf("%3zu:\t%4u\t \"%u:%u/%.*s\"\t%4d\n", i, graph.edges[i].tail, graph.edges[i].variant.start, graph.edges[i].variant.end, (int) graph.edges[i].variant.obs_end - graph.edges[i].variant.obs_start, observed + graph.edges[i].variant.obs_start, (signed) graph.edges[i].next); - } // for -*/ + char const* const restrict reference = argv[1]; + char const* const restrict observed = argv[2]; + size_t const len_ref = strlen(reference); + size_t const len_obs = strlen(observed); - //local_supremal(va_std_allocator, graph, len_obs, observed); + GVA_LCS_Graph graph = gva_lcs_graph_init(gva_std_allocator, len_ref, reference, len_obs, observed, 0); - //canonical(va_std_allocator, graph, len_obs, observed); + lcs_graph_raw(stderr, graph, len_obs, observed); + lcs_graph_dot(stderr, graph, len_obs, observed); + lcs_graph_json(stdout, graph, len_obs, observed); - //to_json(graph, len_obs, observed, lambda); + gva_lcs_graph_destroy(gva_std_allocator, graph); return EXIT_SUCCESS; } // main diff --git a/src/parser.c b/src/parser.c deleted file mode 100644 index 633987f..0000000 --- a/src/parser.c +++ /dev/null @@ -1,319 +0,0 @@ -#include // bool -#include // size_t -#include // uint32_t - -#include "../include/parser.h" // va_parse_* -#include "../include/variant.h" // VA_Variant - - -static inline bool -is_digit(char const ch) -{ - return ch >= '0' && ch <= '9'; -} // is_digit - - -static inline bool -is_dna_nucleotide(char const ch) -{ - return ch == 'A' || ch == 'C' || ch == 'G' || ch == 'T'; -} // is_dna_nucleotide - - -static size_t -match_number(size_t const len, char const expression[static len], - uint32_t* const num) -{ - size_t idx = 0; - while (idx < len && is_digit(expression[idx])) - { - *num = *num * 10 + expression[idx] - '0'; // OVERFLOW - idx += 1; - } // while - return idx; -} // match_number - - -static size_t -match_sequence(size_t const len, char const expression[static len]) -{ - size_t idx = 0; - while (idx < len && is_dna_nucleotide(expression[idx])) - { - idx += 1; - } // while - return idx; -} // match_sequence - - -static size_t -match_location(size_t const len, char const expression[static len], - uint32_t* const start, uint32_t* const end) -{ - size_t idx = match_number(len, expression, start); - if (idx == 0) - { - return 0; // expected number - } // if - if (idx < len && expression[idx] == '_') - { - idx += 1; - size_t const tok = match_number(len - idx, expression + idx, end); - if (tok == 0) - { - return 0; // expected number - } // if - if (*start >= *end) - { - return 0; // invalid range - } // if - return idx + tok; - } // if - *end = *start; - return idx; -} // match_location - - -static size_t -match(size_t const len, char const expression[static len], char const word[static 1]) -{ - size_t idx = 0; - while (idx < len && word[idx] != '\0' && expression[idx] == word[idx]) - { - idx += 1; - } // while - return word[idx] == '\0' ? idx : 0; -} // match - - -static size_t -match_until(size_t const len, char const expression[static len], char const delim) -{ - size_t idx = 0; - while (idx < len && expression[idx] != delim) - { - idx += 1; - } // while - return idx < len && expression[idx] == delim ? idx : 0; -} // match_until - - -static size_t -match_variant(size_t const len, char const expression[static len], - VA_Variant* const variant) -{ - size_t idx = match_location(len, expression, &variant->start, &variant->end); - if (idx == 0) - { - return 0; // expected location - } // if - - size_t tok = match(len - idx, expression + idx, "del"); - if (tok != 0) - { - if (variant->start == 0) - { - return 0; // invalid location - } // if - idx += tok; - variant->start -= 1; - - // optional sequence - idx += match_sequence(len - idx, expression + idx); - - tok = match(len - idx, expression + idx, "ins"); - if (tok != 0) - { - idx += tok; - - variant->obs_start = idx; // OVERFLOW - tok = match_sequence(len - idx, expression + idx); - if (tok == 0) - { - return 0; // expected sequence; - } // if - idx += tok; - - variant->obs_end = idx; // OVERFLOW - } // if - - return idx; - } // if - - tok = match(len - idx, expression + idx, "ins"); - if (tok != 0) - { - if (variant->end - variant->start != 1) - { - return 0; // expected 1-interval - } // if - idx += tok; - variant->end = variant->start; - - variant->obs_start = idx; // OVERFLOW - tok = match_sequence(len - idx, expression + idx); - if (tok == 0) - { - return 0; // expected sequence - } // if - idx += tok; - variant->obs_end = idx; // OVERFLOW - - return idx; - } // if - - if (variant->start == 0) - { - return 0; // invalid location - } // if - variant->start -= 1; - - // optional sequence - idx += match_sequence(len - idx, expression + idx); - - if (idx < len && expression[idx] == '>') - { - idx += 1; // '>' - - variant->obs_start = idx; // OVERFLOW - tok = match_sequence(len - idx, expression + idx); - if (tok == 0) - { - return 0; // expected sequence - } // if - idx += tok; - variant->obs_end = idx; // OVERFLOW - - return idx; - } // if - - return 0; -} // match_variant - - -size_t -va_parse_hgvs(size_t const len, char const expression[static len], - size_t const len_var, VA_Variant variants[static len_var]) -{ - size_t idx = match_until(len, expression, ':'); - if (idx >= len) - { - return 0; // expected ':' - } // if - if (idx > 0) - { - idx += 1; // ':' - } // if - idx += match(len - idx, expression + idx, "g."); - - if (idx < len && expression[idx] == '[') - { - idx += 1; - - size_t tok = match_variant(len - idx, expression + idx, &variants[0]); - if (tok == 0) - { - return 0; // expected variant - } // if - idx += tok; - - size_t count = 1; - while (idx < len && expression[idx] == ';') - { - idx += 1; // ';' - - if (count >= len_var) - { - return 0; // too many variants - } // if - - tok = match_variant(len - idx, expression + idx, &variants[count]); - if (tok == 0) - { - return 0; // expected variant - } // if - idx += tok; - count += 1; - } // while - - if (idx >= len || expression[idx] != ']') - { - return 0; // expected ']' - } // if - idx += 1; // ']' - - return idx == len ? count : 0; - } // if - - if (idx < len && expression[idx] == '=') - { - idx += 1; - return idx == len; - } // if - - size_t tok = match_variant(len - idx, expression + idx, &variants[0]); - if (tok == 0) - { - return 0; // expected variant - } // if - idx += tok; - - return idx == len; -} // va_parse_hgvs - - -size_t -va_parse_spdi(size_t const len, char const expression[static len], - VA_Variant variants[static 1]) -{ - // sequence - size_t idx = match_until(len, expression, ':'); - if (idx >= len) - { - return 0; // expected ':' - } // if - idx += 1; // ':' - - size_t tok = match_number(len - idx, expression + idx, &variants[0].start); - if (tok == 0) - { - return 0; // expected number (location) - } // if - idx += tok; - - if (idx >= len || expression[idx] != ':') - { - return 0; // expected ':' - } // if - idx += 1; - - tok = match_number(len - idx, expression + idx, &variants[0].end); - if (tok == 0) - { - tok = match_sequence(len - idx, expression + idx); - if (tok == 0) - { - return 0; // expected number (length) or sequence - } // if - variants[0].end = tok; // OVERFLOW - } // if - idx += tok; - variants[0].end += variants[0].start; - - if (idx >= len || expression[idx] != ':') - { - return 0; // expected ':' - } // if - idx += 1; - - variants[0].obs_start = idx; // OVERFLOW - tok = match_sequence(len - idx, expression + idx); - if (tok == 0) - { - return 0; // expected sequence - } // if - idx += tok; - variants[0].obs_end = idx; - - return idx == len; -} // va_parse_spdi diff --git a/src/variant.c b/src/variant.c deleted file mode 100644 index 67dabd4..0000000 --- a/src/variant.c +++ /dev/null @@ -1,77 +0,0 @@ -#include // bool -#include // size_t - -#include "../include/variant.h" // VA_*, va_* - - -static void -string_copy(size_t const len, char const source[static restrict len], - char dest[static restrict len]) -{ - for (size_t i = 0; i < len; ++i) - { - dest[i] = source[i]; - } // for -} // string_copy - - -bool -va_variant_eq(VA_Variant const lhs, VA_Variant const rhs) -{ - return lhs.start == rhs.start && lhs.end == rhs.end && - lhs.obs_start == rhs.obs_start && lhs.obs_end == rhs.obs_end; -} // va_variant_eq - - -size_t -va_variant_len(VA_Variant const variant) -{ - return variant.end - variant.start + variant.obs_end - variant.obs_start; -} // va_variant_len - - -size_t -va_patch(size_t const len_ref, char const reference[static restrict len_ref], - size_t const len_obs, char const observed[static restrict len_obs], - size_t const len_var, VA_Variant const variants[len_var], - size_t const len, char string[static restrict len]) -{ - size_t idx = 0; - size_t start = 0; - for (size_t i = 0; i < len_var; ++i) - { - size_t len_slice = variants[i].start - start; - if (len - idx < len_slice) - { - return 0; // not enough space in dest - } // if - if (len_ref - start < len_slice) - { - return 0; // not in reference - } // if - string_copy(len_slice, reference + start, string + idx); - idx += len_slice; - - len_slice = variants[i].obs_end - variants[i].obs_start; - if (len - idx < len_slice) - { - return 0; // not enough space in dest - } // if - if (len_obs - variants[i].obs_start < len_slice) - { - return 0; // not in observed - } // if - string_copy(len_slice, observed + variants[i].obs_start, string + idx); - idx += len_slice; - - start = variants[i].end; - } // for - - size_t const len_slice = len_ref - start; - if (len - idx < len_slice) - { - return 0; // not enough space - } // if - string_copy(len_slice, reference + start, string + idx); - return idx + len_slice; -} // va_patch diff --git a/tests/test_array.c b/tests/test_array.c deleted file mode 100644 index acf53a5..0000000 --- a/tests/test_array.c +++ /dev/null @@ -1,123 +0,0 @@ -#include // assert -#include // NULL, size_t -#include // uint32_t -#include // stderr, fprintf -#include // EXIT_SUCCESS -#include // memcmp - -#include "../include/alloc.h" // VA_Allocator -#include "../include/std_alloc.h" // va_std_allocator - - -#include "../src/array.c" - - -static inline void* -null_alloc(void* const restrict context, void* const restrict ptr, size_t const old_size, size_t const size) -{ - (void) context; - (void) ptr; - (void) old_size; - (void) size; - return NULL; -} // null_alloc - - -static VA_Allocator const null_allocator = { .alloc = null_alloc }; - - -static void -test_va_array_init(void) -{ - static struct { - size_t const capacity; - VA_Array const header; - } const tests[] = - { - { 1, { 1, 0}}, - { 10, { 10, 0}}, - {100, {100, 0}}, - }; // tests - - fprintf(stderr, "%s:%s: ", __FILE__, __func__); - for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) - { - uint32_t* array = va_array_init(va_std_allocator, tests[i].capacity, sizeof(*array)); - assert(memcmp(va_array_header(array), &tests[i].header, sizeof(tests[i].header)) == 0); - array = va_array_destroy(va_std_allocator, array); - assert(array == NULL); - fprintf(stderr, "."); - } // for - fprintf(stderr, " passed\n"); -} // test_va_array_init - - -static void -test_va_array_init_zero(void) -{ - static struct { - VA_Allocator const allocator; - size_t const capacity; - } const tests[] = - { - {va_std_allocator, 0}, - {null_allocator, 0}, - }; // tests - - fprintf(stderr, "%s:%s: ", __FILE__, __func__); - for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) - { - uint32_t* array = va_array_init(tests[i].allocator, tests[i].capacity, sizeof(*array)); - assert(array == NULL); - array = va_array_destroy(tests[i].allocator, array); - assert(array == NULL); - fprintf(stderr, "."); - } // for - fprintf(stderr, " passed\n"); -} // test_va_array_init_zero - - -static void -test_va_array_init_null(void) -{ - fprintf(stderr, "%s:%s: ", __FILE__, __func__); - uint32_t* array = va_array_init(null_allocator, 100, sizeof(*array)); - assert(array == NULL); - array = va_array_destroy(null_allocator, array); - assert(array == NULL); - fprintf(stderr, "."); - fprintf(stderr, " passed\n"); -} // test_va_array_init_null - - -static void -test_va_array_append(void) -{ - uint32_t const n = 100; - fprintf(stderr, "%s:%s: ", __FILE__, __func__); - uint32_t* array = NULL; - for (uint32_t i = 0; i < n; ++i) - { - va_array_append(va_std_allocator, array, i); - } // for - assert(va_array_length(array) == n); - for (uint32_t i = 0; i < va_array_length(array); ++i) - { - assert(array[i] == i); - } // for - array = va_array_destroy(va_std_allocator, array); - assert(array == NULL); - fprintf(stderr, "."); - fprintf(stderr, " passed\n"); -} // test_va_array_append - - -int -main(void) -{ - test_va_array_init(); - test_va_array_init_zero(); - test_va_array_init_null(); - test_va_array_append(); - return EXIT_SUCCESS; -} // main diff --git a/tests/test_edit.c b/tests/test_edit.c deleted file mode 100644 index b4403ba..0000000 --- a/tests/test_edit.c +++ /dev/null @@ -1,60 +0,0 @@ -#include // assert -#include // size_t -#include // stderr, fprintf -#include // EXIT_SUCCESS -#include // strlen - -#include "../include/alloc.h" // VA_Allocator -#include "../include/std_alloc.h" // va_std_allocator - - -#include "../src/array.c" -#include "../src/edit.c" - - -static void -test_wu_compare(void) -{ - static struct - { - char const* const restrict a; - char const* const restrict b; - size_t const distance; - } const tests[] = - { - { "", "", 0}, - { "a", "a", 0}, - { "a", "b", 2}, - { "abcf", "abcdf", 1}, - { "abcdf", "abcf", 1}, - { "aa", "aaaaaaaaa", 7}, - { "aaaaaaaaa", "aa", 7}, - { "acbdeacbed", "acebdabbabed", 6}, - {"acebdabbabed", "acbdeacbed", 6}, - { "ACCTGACT", "ATCTTACTT", 5}, - { "ATCTTACTT", "ACCTGACT", 5}, - }; - - fprintf(stderr, "%s:%s: ", __FILE__, __func__); - for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) - { - size_t const m = strlen(tests[i].a); - size_t const n = strlen(tests[i].b); - - size_t const wu_distance = m > n ? - wu_compare(va_std_allocator, n, tests[i].b, m, tests[i].a) : - wu_compare(va_std_allocator, m, tests[i].a, n, tests[i].b); - assert(wu_distance == tests[i].distance); - - fprintf(stderr, "."); - } // for - fprintf(stderr, " passed\n"); -} // test_wu_compare - - -int -main(void) -{ - test_wu_compare(); - return EXIT_SUCCESS; -} // main diff --git a/tests/test_parser.c b/tests/test_parser.c deleted file mode 100644 index 391a01c..0000000 --- a/tests/test_parser.c +++ /dev/null @@ -1,394 +0,0 @@ -#include // assert -#include // bool, false, true -#include // NULL, size_t -#include // UINT32_MAX, uint32_t -#include // stderr, fprintf -#include // EXIT_SUCCESS -#include // memcmp - - -#include "../src/parser.c" - - -#define MAX_VARIANTS 2 - - -static void -test_is_digit(void) -{ - static struct { - char const ch; - bool const expected; - } const tests[] = - { - { '\0', false}, - { '/', false}, - { '0', true}, - { '1', true}, - { '2', true}, - { '3', true}, - { '4', true}, - { '5', true}, - { '6', true}, - { '7', true}, - { '8', true}, - { '9', true}, - { ':', false}, - { 'a', false}, - { 'A', false}, - {'\xFF', false}, - }; // tests - - fprintf(stderr, "%s:%s: ", __FILE__, __func__); - for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) - { - assert(tests[i].expected == is_digit(tests[i].ch)); - fprintf(stderr, "."); - } // for - fprintf(stderr, " passed\n"); -} // test_is_digit - - -static void -test_is_dna_nucleotide(void) -{ - static struct { - char const ch; - bool const expected; - } const tests[] = - { - { '\0', false}, - { '0', false}, - { 'a', false}, - { 'A', true}, - { 'C', true}, - { 'G', true}, - { 'T', true}, - { 'B', false}, - {'\xFF', false}, - }; // tests - - fprintf(stderr, "%s:%s: ", __FILE__, __func__); - for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) - { - assert(tests[i].expected == is_dna_nucleotide(tests[i].ch)); - fprintf(stderr, "."); - } // for - fprintf(stderr, " passed\n"); -} // test_is_dna_nucleotide - - -static void -test_match_number(void) -{ - static struct { - size_t const len; - char const* const expression; - size_t const matched; - uint32_t const expected; - } const tests[] = - { - { 0, NULL, 0, 0}, - { 0, "", 0, 0}, - { 1, "1", 1, 1}, - {10, "10", 2, 10}, // saved by \0 - { 1, "10", 1, 1}, - {10, "123a123a12", 3, 123}, - { 5, "-1000", 0, 0}, - {10, "1234567890", 10, 1234567890}, - {10, "4294967295", 10, UINT32_MAX}, - {10, "4294967296", 10, 0}, // overflow - }; // tests - - fprintf(stderr, "%s:%s: ", __FILE__, __func__); - for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) - { - uint32_t num = 0; - size_t const tok = match_number(tests[i].len, tests[i].expression, &num); - assert(tok == tests[i].matched); - assert(num == tests[i].expected); - fprintf(stderr, "."); - } // for - fprintf(stderr, " passed\n"); -} // test_match_number - - -static void -test_match_sequence(void) -{ - static struct { - size_t const len; - char const* const expression; - size_t const matched; - } const tests[] = - { - {0, NULL, 0}, - {0, "", 0}, - {1, "A", 1}, - {4, "ACGT", 4}, - {4, "acgt", 0}, - {4, "ACgt", 2}, - }; // tests - - fprintf(stderr, "%s:%s: ", __FILE__, __func__); - for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) - { - size_t const tok = match_sequence(tests[i].len, tests[i].expression); - assert(tok == tests[i].matched); - fprintf(stderr, "."); - } // for - fprintf(stderr, " passed\n"); -} // test_match_sequence - - -static void -test_match_location(void) -{ - static struct { - size_t const len; - char const* const expression; - size_t const matched; - uint32_t const expected_start; - uint32_t const expected_end; - } const tests[] = - { - { 0, NULL, 0, 0, 0}, - { 0, "", 0, 0, 0}, - { 1, "0", 1, 0, 0}, - { 1, "1", 1, 1, 1}, - { 1, "a", 0, 0, 0}, - { 2, "9a", 1, 9, 9}, - { 3, "0_1", 3, 0, 1}, - { 2, "0_", 0, 0, 0}, - { 3, "0_a", 0, 0, 0}, - { 3, "1_1", 0, 1, 1}, - { 3, "1_0", 0, 1, 0}, - {10, "1234_56789", 10, 1234, 56789}, - }; // tests - - fprintf(stderr, "%s:%s: ", __FILE__, __func__); - for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) - { - uint32_t start = 0; - uint32_t end = 0; - size_t const tok = match_location(tests[i].len, tests[i].expression, &start, &end); - assert(tok == tests[i].matched); - assert(start == tests[i].expected_start); - assert(end == tests[i].expected_end); - fprintf(stderr, "."); - } // for - fprintf(stderr, " passed\n"); -} // test_match_location - - -static void -test_match(void) -{ - static struct { - size_t const len; - char const* const expression; - char const* const word; - size_t const matched; - } const tests[] = - { - {0, NULL, "", 0}, - {0, "", "", 0}, - {1, "a", "", 0}, - {1, "a", "aa", 0}, - {1, "a", "a", 1}, - {3, "del", "del", 3}, - {8, "deletion", "del", 3}, - {3, "del", "deletion", 0}, - }; // tests - - fprintf(stderr, "%s:%s: ", __FILE__, __func__); - for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) - { - size_t const tok = match(tests[i].len, tests[i].expression, tests[i].word); - assert(tok == tests[i].matched); - fprintf(stderr, "."); - } // for - fprintf(stderr, " passed\n"); -} // test_match - - -static void -test_match_until(void) -{ - static struct { - size_t const len; - char const* const expression; - char const delim; - size_t const matched; - } const tests[] = - { - {0, NULL, '\0', 0}, - {0, "", '\0', 0}, - {1, "1", ':', 0}, - {1, ":", ':', 0}, - {8, "AATT:ATT", ':', 4}, - {3, ":::", ':', 0}, - }; // tests - - fprintf(stderr, "%s:%s: ", __FILE__, __func__); - for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) - { - size_t const tok = match_until(tests[i].len, tests[i].expression, tests[i].delim); - assert(tok == tests[i].matched); - fprintf(stderr, "."); - } // for - fprintf(stderr, " passed\n"); -} // test_match_until - - -static void -test_match_variant(void) -{ - static struct { - size_t const len; - char const* const expression; - size_t const matched; - VA_Variant const variant; - } const tests[] = - { - {0, NULL, 0, {0}}, - {0, "", 0, {0}}, - {1, "1", 0, {0, 1, 0, 0}}, - {4, "1del", 4, {0, 1, 0, 0}}, - {4, "0del", 0, {0}}, - {5, "1delT", 5, {0, 1, 0, 0}}, - {7, "1delins", 0, {0, 1, 7, 0}}, - {8, "1delinsA", 8, {0, 1, 7, 8}}, - {9, "1delAinsA", 9, {0, 1, 8, 9}}, - {6, "1_2ins", 0, {1, 1, 6, 0}}, - {4, "1ins", 0, {1, 1, 0, 0}}, - {6, "0_1ins", 0, {0, 0, 6, 0}}, - {7, "0_1insA", 7, {0, 0, 6, 7}}, - {6, "1_3ins", 0, {1, 3, 0, 0}}, - {7, "1_2insT", 7, {1, 1, 6, 7}}, - {2, "0>", 0, {0}}, - {2, "1>", 0, {0, 1, 2, 0}}, - {3, "1A>", 0, {0, 1, 3, 0}}, - {4, "1A>T", 4, {0, 1, 3, 4}}, - }; // tests - - fprintf(stderr, "%s:%s: ", __FILE__, __func__); - for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) - { - VA_Variant variant = {0}; - size_t const tok = match_variant(tests[i].len, tests[i].expression, &variant); - assert(tok == tests[i].matched); - assert(memcmp(&variant, &tests[i].variant, sizeof(variant)) == 0); - fprintf(stderr, "."); - } // for - fprintf(stderr, " passed\n"); -} // test_match_variant - - -static void -test_va_parse_hgvs(void) -{ - static struct { - size_t const len; - char const* const expression; - size_t const count; - VA_Variant const variants[MAX_VARIANTS]; - } const tests[] = - { - { 0, NULL, 0, {{0}}}, - { 0, "", 0, {{0}}}, - { 1, "A", 0, {{0}}}, - { 1, ":", 0, {{0}}}, - { 1, "g", 0, {{0}}}, - { 2, "g.", 0, {{0}}}, - { 3, ":g.", 0, {{0}}}, - { 1, "1", 0, {{0}}}, - { 3, "A:1", 0, {{0}}}, - { 5, "A:g.1", 0, {{0}}}, - { 7, "A:g.1_2", 0, {{0}}}, - { 1, "=", 1, {{0}}}, - { 3, "g.=", 1, {{0}}}, - { 4, "1del", 1, {{0, 1, 0, 0}}}, - { 6, "g.1del", 1, {{0, 1, 0, 0}}}, - { 6, "A:1del", 1, {{0, 1, 0, 0}}}, - { 8, "A:g.1del", 1, {{0, 1, 0, 0}}}, - { 5, "1del ", 0, {{0}}}, - { 1, "[", 0, {{0}}}, - { 5, "[1del", 0, {{0}}}, - { 6, "[1del;", 0, {{0}}}, - { 6, "[1del]", 1, {{0, 1, 0, 0}}}, - { 7, "[1del] ", 0, {{0}}}, - {10, "[1del;2del", 0, {{0}}}, - {11, "[1del;2del]", 2, {{0, 1, 0, 0}, {1, 2, 0, 0}}}, - {10, "[1del2del]", 0, {{0}}}, - {16, "[1del;2del;3del]", 0, {{0}}}, - }; // tests - - fprintf(stderr, "%s:%s: ", __FILE__, __func__); - for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) - { - VA_Variant variants[MAX_VARIANTS] = {{0}}; - size_t const tok = va_parse_hgvs(tests[i].len, tests[i].expression, MAX_VARIANTS, variants); - assert(tok == tests[i].count); - assert(memcmp(&variants, &tests[i].variants, sizeof(variants[0]) * tests[i].count) == 0); - fprintf(stderr, "."); - } // for - fprintf(stderr, " passed\n"); -} // test_va_parse_hgvs - - -static void -test_va_parse_spdi(void) -{ - static struct { - size_t const len; - char const* const expression; - size_t const count; - VA_Variant const variants; - } const tests[] = - { - {0, NULL, 0, {0}}, - {0, "", 0, {0}}, - {1, "A", 0, {0}}, - {1, ":", 0, {0}}, - {2, "A:", 0, {0}}, - {3, "A:1", 0, {1, 0, 0, 0}}, - {4, "A:1:", 0, {1, 0, 0, 0}}, - {5, "A:1:1", 0, {1, 2, 0, 0}}, - {5, "A:1:A", 0, {1, 2, 0, 0}}, - {6, "A:1:1:", 0, {1, 2, 6, 0}}, - {6, "A:1:A:", 0, {1, 2, 6, 0}}, - {7, "A:1:1:A", 1, {1, 2, 6, 7}}, - {7, "A:1:A:A", 1, {1, 2, 6, 7}}, - {8, "A:1:A:A ", 0, {1, 2, 6, 7}}, - {6, ":1:A:A", 1, {1, 2, 5, 6}}, - }; // tests - - fprintf(stderr, "%s:%s: ", __FILE__, __func__); - for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) - { - VA_Variant variants[1] = {{0}}; - size_t const tok = va_parse_spdi(tests[i].len, tests[i].expression, variants); - assert(tok == tests[i].count); - assert(memcmp(&variants, &tests[i].variants, sizeof(variants[0])) == 0); - fprintf(stderr, "."); - } // for - fprintf(stderr, " passed\n"); -} // test_va_parse_spdi - - -int -main(void) -{ - test_is_digit(); - test_is_dna_nucleotide(); - test_match_number(); - test_match_sequence(); - test_match_location(); - test_match(); - test_match_until(); - test_match_variant(); - test_va_parse_hgvs(); - test_va_parse_spdi(); - return EXIT_SUCCESS; -} // main diff --git a/tests/test_variant.c b/tests/test_variant.c deleted file mode 100644 index 5ab8569..0000000 --- a/tests/test_variant.c +++ /dev/null @@ -1,113 +0,0 @@ -#include // assert -#include // bool, false, true -#include // size_t -#include // stderr, fprintf -#include // EXIT_SUCCESS -#include // strncmp - - -#include "../src/variant.c" - - -static void -test_va_variant_eq(void) -{ - static struct { - VA_Variant const lhs; - VA_Variant const rhs; - bool const eq; - } const tests[] = - { - { {0}, {0}, true}, - {{0, 0, 0, 0}, {0, 0, 0, 0}, true}, - {{0, 0, 0, 0}, {0, 0, 0, 1}, false}, - {{0, 0, 0, 0}, {0, 0, 1, 0}, false}, - {{0, 0, 0, 0}, {0, 1, 0, 0}, false}, - {{0, 0, 0, 0}, {1, 0, 0, 0}, false}, - }; // tests - - fprintf(stderr, "%s:%s: ", __FILE__, __func__); - for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) - { - bool const eq = va_variant_eq(tests[i].lhs, tests[i].rhs); - assert(eq == tests[i].eq); - fprintf(stderr, "."); - } // for - fprintf(stderr, " passed\n"); -} // test_va_variant_eq - - -static void -test_va_variant_len(void) -{ - static struct { - VA_Variant const variant; - size_t const len; - } const tests[] = - { - { {0}, 0}, - {{0, 0, 0, 0}, 0}, - {{0, 1, 0, 0}, 1}, - {{0, 0, 0, 1}, 1}, - {{0, 1, 0, 1}, 2}, - }; // tests - - fprintf(stderr, "%s:%s: ", __FILE__, __func__); - for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) - { - size_t const len = va_variant_len(tests[i].variant); - assert(len == tests[i].len); - fprintf(stderr, "."); - } // for - fprintf(stderr, " passed\n"); -} // test_va_variant_len - - -static void -test_va_patch(void) -{ - static struct { - size_t const len_ref; - char const* const reference; - size_t const len_obs; - char const* const observed; - size_t const len_var; - VA_Variant const variants[256]; - char const* const expected; - } const tests[] = - { - {5, "AAAAA", 0, "", 0, {{0, 0, 0, 0}}, "AAAAA"}, - {5, "AAAAA", 0, "", 1, {{0, 1, 0, 0}}, "AAAA"}, - {5, "AAAAA", 1, "T", 1, {{0, 1, 0, 1}}, "TAAAA"}, - {5, "AAAAA", 1, "T", 1, {{2, 3, 0, 1}}, "AATAA"}, - {5, "AAAAA", 1, "T", 1, {{8, 9, 0, 1}}, ""}, - {5, "AAAAA", 1, "T", 1, {{0, 0, 0, 1}}, ""}, - {3, "AAA", 0, "", 1, {{4, 5, 0, 0}}, ""}, - {5, "AAAAA", 0, "", 1, {{1, 1, 0, 1}}, ""}, - {5, "AAAAA", 2, "TT", 1, {{4, 4, 0, 2}}, ""}, - }; // tests - - fprintf(stderr, "%s:%s: ", __FILE__, __func__); - for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) - { - char buffer[5] = {'\0'}; - size_t const len = va_patch(tests[i].len_ref, tests[i].reference, - tests[i].len_obs, tests[i].observed, - tests[i].len_var, tests[i].variants, - 5, buffer); - //printf("%zu\n", len); - assert(strncmp(buffer, tests[i].expected, len) == 0); - fprintf(stderr, "."); - } // for - fprintf(stderr, " passed\n"); -} // test_va_patch - - -int -main(void) -{ - test_va_variant_eq(); - test_va_variant_len(); - test_va_patch(); - return EXIT_SUCCESS; -} // main From faf2616c3edc52647d8001d004550aeabc0746e5 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 5 Jun 2025 23:48:14 +0200 Subject: [PATCH 217/704] Cleanup --- src/array.c | 2 +- src/array.h | 5 +++-- src/edit.c | 3 +-- src/edit.h | 3 ++- test.py | 1 - 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/array.c b/src/array.c index db4dd38..3091c61 100644 --- a/src/array.c +++ b/src/array.c @@ -33,7 +33,7 @@ array_header(void* const self) void* -array_ensure_one(GVA_Allocator const allocator, void* const restrict self, +array_ensure_one(GVA_Allocator const allocator, void* const self, size_t const item_size) { // Initial allocation diff --git a/src/array.h b/src/array.h index b674cf9..c29c896 100644 --- a/src/array.h +++ b/src/array.h @@ -42,9 +42,9 @@ array_header(void* const self); // Internal: Returns the possibly (re)allocated array with place for -// `capacity` number of additional elements. +// one additional element. void* -array_ensure_one(GVA_Allocator const allocator, void* const restrict self, +array_ensure_one(GVA_Allocator const allocator, void* const self, size_t const item_size); @@ -52,6 +52,7 @@ array_ensure_one(GVA_Allocator const allocator, void* const restrict self, // Returns `NULL`. // Usage: // a = ARRAY_DESTROY(gva_std_allocator, a); +// Warning: `self` is evaluated multiple times. #define ARRAY_DESTROY(allocator, self) ( \ (self) == NULL ? NULL : \ allocator.allocate( \ diff --git a/src/edit.c b/src/edit.c index 93f7eab..f7cf836 100644 --- a/src/edit.c +++ b/src/edit.c @@ -5,7 +5,7 @@ #include "../include/allocator.h" // GVA_Allocator #include "array.h" // ARRAY_APPEND -#include "base.h" // ABS, MAX, MIN, GVA_NULL +#include "base.h" // GVA_NULL, ABS, MAX, MIN #include "edit.h" // LCS, LCS_Node, edit @@ -181,7 +181,6 @@ edit(GVA_Allocator const allocator, size_t const lower = delta > 0 ? 0 : delta; size_t const upper = delta > 0 ? delta : 0; - size_t const len = MAX(len_ref, len_obs) - ABS(delta); size_t p = 0; while (context.diagonals[offset + delta] <= len) diff --git a/src/edit.h b/src/edit.h index cd18cf0..c2f8218 100644 --- a/src/edit.h +++ b/src/edit.h @@ -4,7 +4,8 @@ #include // size_t -#include "../include/types.h" // gva_uint +#include "../include/allocator.h" // GVA_Allocator +#include "../include/types.h" // gva_uint typedef struct diff --git a/test.py b/test.py index 682544c..38bbb6a 100644 --- a/test.py +++ b/test.py @@ -126,7 +126,6 @@ def check(reference, observed, debug=False, timeout=2): #if debug: # print(list(reversed(cgraph["canonical"])), canonical(graph)) - #print() #print(cgraph["canonical"]) #print(canonical(graph)) From 75128c4bf40c55c509fe6df5dd3a4f95297a70e2 Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 6 Jun 2025 08:28:54 +0200 Subject: [PATCH 218/704] Restrict and includes --- include/std_alloc.h | 2 +- src/array.c | 1 + src/array.h | 4 ++-- src/lcs_graph.c | 12 ++++-------- src/main.c | 1 + 5 files changed, 9 insertions(+), 11 deletions(-) diff --git a/include/std_alloc.h b/include/std_alloc.h index 63524f3..978c41e 100644 --- a/include/std_alloc.h +++ b/include/std_alloc.h @@ -23,7 +23,7 @@ gva_std_allocate(void* const restrict context, void* const restrict ptr, size_t return NULL; } // if - void* const restrict new_ptr = realloc(ptr, new_size); + void* const new_ptr = realloc(ptr, new_size); if (new_ptr == NULL) { free(ptr); diff --git a/src/array.c b/src/array.c index 3091c61..cf0d8ad 100644 --- a/src/array.c +++ b/src/array.c @@ -1,5 +1,6 @@ #include // NULL, size_t + #include "../include/allocator.h" // GVA_Allocator #include "array.h" // GVA_Array, gva_array_* diff --git a/src/array.h b/src/array.h index c29c896..5a2803d 100644 --- a/src/array.h +++ b/src/array.h @@ -65,11 +65,11 @@ array_ensure_one(GVA_Allocator const allocator, void* const self, // Adds an element at the end of the array. Returns the new length of the -// array. -1 if (re)allocation failed. +// array. 0 if (re)allocation failed. // Warning: `self` is evaluated multiple times. #define ARRAY_APPEND(allocator, self, value) ( \ (self) = array_ensure_one(allocator, self, sizeof(*(self))), \ - (self) == NULL ? (size_t) -1 : ( \ + (self) == NULL ? 0 : ( \ (self)[array_header(self)->length] = (value), \ array_header(self)->length += 1 \ ) \ diff --git a/src/lcs_graph.c b/src/lcs_graph.c index 399142a..29f8e61 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -2,6 +2,7 @@ #include // bool, false, true #include // size_t + #include "../include/allocator.h" // GVA_Allocator #include "../include/lcs_graph.h" // GVA_LCS_Graph, GVA_Variant, gva_lcs_graph_* #include "array.h" // ARRAY_*, array_length @@ -24,11 +25,6 @@ gva_edges(GVA_Node const head, GVA_Node const tail, gva_uint const head_offset = offset > 0 ? MIN(head_length, offset + 1) : 1; gva_uint const tail_offset = offset < 0 ? MIN(tail_length, -offset) : 0; - if (head_offset > head_length || (tail_length > 0 && tail_offset >= tail_length)) - { - return 0; - } // if - *variant = (GVA_Variant) { row + head_offset, tail.row + tail_offset, col + head_offset, tail.col + tail_offset @@ -98,7 +94,7 @@ gva_lcs_graph_init(GVA_Allocator const allocator, gva_uint next = GVA_NULL; for (gva_uint j = lcs.index[i].head; j != GVA_NULL; j = next) { - LCS_Node* const tail = &lcs.nodes[j]; + LCS_Node* const restrict tail = &lcs.nodes[j]; next = tail->next; if (lcs.nodes[j].idx == GVA_NULL) { @@ -108,9 +104,9 @@ gva_lcs_graph_init(GVA_Allocator const allocator, gva_uint here = GVA_NULL; for (gva_uint k = lcs.index[i - 1].head; k != GVA_NULL; k = lcs.nodes[k].next) { - LCS_Node* const head = &lcs.nodes[k]; + LCS_Node* const restrict head = &lcs.nodes[k]; - if (k > j || + if (k >= j || head->row + head->length >= tail->row + tail->length || head->col + head->length >= tail->col + tail->length) { diff --git a/src/main.c b/src/main.c index d108019..a3b0f9d 100644 --- a/src/main.c +++ b/src/main.c @@ -3,6 +3,7 @@ #include // EXIT_* #include // strlen + #include "../include/lcs_graph.h" // GVA_LCS_Graph, GVA_Variant, gva_lcs_graph_*, gva_edges #include "../include/std_alloc.h" // gva_std_allocator #include "../include/types.h" // GVA_NULL, gva_uint From af16a2ab91042f541a23babeba638e5b3a86b4fe Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 6 Jun 2025 10:55:24 +0200 Subject: [PATCH 219/704] WIP: (local) supremal --- src/{edit.c => align.c} | 12 ++++---- src/{edit.h => align.h} | 12 ++++---- src/lcs_graph.c | 66 +++++++++++++++++++++++++++++++++++++---- src/main.c | 7 +++-- 4 files changed, 78 insertions(+), 19 deletions(-) rename src/{edit.c => align.c} (96%) rename src/{edit.h => align.h} (81%) diff --git a/src/edit.c b/src/align.c similarity index 96% rename from src/edit.c rename to src/align.c index f7cf836..af1e018 100644 --- a/src/edit.c +++ b/src/align.c @@ -4,9 +4,9 @@ #include "../include/allocator.h" // GVA_Allocator +#include "align.h" // LCS_Alignment, LCS_Node, lcs_align #include "array.h" // ARRAY_APPEND #include "base.h" // GVA_NULL, ABS, MAX, MIN -#include "edit.h" // LCS, LCS_Node, edit typedef struct @@ -24,7 +24,7 @@ static size_t expand(Context const context, intmax_t const idx, size_t const p, - LCS* const lcs) + LCS_Alignment* const lcs) { intmax_t const delta = context.len_obs - context.len_ref; size_t const offset = context.len_ref + 1; @@ -136,8 +136,8 @@ expand(Context const context, } // expand -LCS -edit(GVA_Allocator const allocator, +LCS_Alignment +lcs_align(GVA_Allocator const allocator, size_t const len_ref, char const reference[static restrict len_ref], size_t const len_obs, char const observed[static restrict len_obs]) { @@ -145,7 +145,7 @@ edit(GVA_Allocator const allocator, size_t const offset = len_ref + 1; size_t const size = len_ref + len_obs + 3; - LCS lcs = {0, NULL, NULL}; + LCS_Alignment lcs = {0, NULL, NULL}; Context const context = { @@ -201,4 +201,4 @@ edit(GVA_Allocator const allocator, allocator.allocate(allocator.context, context.diagonals, size * sizeof(*context.diagonals), 0); lcs.index = allocator.allocate(allocator.context, lcs.index, MIN(len_ref, len_obs) * sizeof(*lcs.index), lcs.length * sizeof(*lcs.index)); return lcs; -} // edit +} // align diff --git a/src/edit.h b/src/align.h similarity index 81% rename from src/edit.h rename to src/align.h index c2f8218..b8567b4 100644 --- a/src/edit.h +++ b/src/align.h @@ -1,5 +1,5 @@ -#ifndef GVA_EDIT_H -#define GVA_EDIT_H +#ifndef GVA_ALIGN_H +#define GVA_ALIGN_H #include // size_t @@ -29,13 +29,13 @@ typedef struct gva_uint tail; }* index; LCS_Node* nodes; -} LCS; +} LCS_Alignment; -LCS -edit(GVA_Allocator const allocator, +LCS_Alignment +lcs_align(GVA_Allocator const allocator, size_t const len_ref, char const reference[static restrict len_ref], size_t const len_obs, char const observed[static restrict len_obs]); -#endif // GVA_EDIT_H +#endif // GVA_ALIGN_H diff --git a/src/lcs_graph.c b/src/lcs_graph.c index 29f8e61..5470d05 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -1,13 +1,16 @@ #include // intmax_t #include // bool, false, true -#include // size_t +#include // NULL, size_t + + +#include // DEBUG #include "../include/allocator.h" // GVA_Allocator #include "../include/lcs_graph.h" // GVA_LCS_Graph, GVA_Variant, gva_lcs_graph_* +#include "align.h" // LCS_Alignment, lcs_align #include "array.h" // ARRAY_*, array_length #include "base.h" // gva_uint, MAX, MIN -#include "edit.h" // LCS, edit gva_uint @@ -39,7 +42,7 @@ gva_lcs_graph_init(GVA_Allocator const allocator, size_t const len_obs, char const observed[static restrict len_obs], size_t const shift) { - LCS const lcs = edit(allocator, len_ref, reference, len_obs, observed); + LCS_Alignment lcs = lcs_align(allocator, len_ref, reference, len_obs, observed); GVA_LCS_Graph graph = {.nodes = NULL, .edges = NULL}; @@ -62,6 +65,24 @@ gva_lcs_graph_init(GVA_Allocator const allocator, return graph; } // if + struct + { + gva_uint count; + gva_uint idx; + }* table = allocator.allocate(allocator.context, NULL, 0, sizeof(*table) * lcs.length); + + for (gva_uint i = 0; i < lcs.length; ++i) + { + table[i].count = 0; + table[i].idx = GVA_NULL; + fprintf(stderr, "%u: ", i); + for (gva_uint j = lcs.index[i].head; j != GVA_NULL; j = lcs.nodes[j].next) + { + fprintf(stderr, "(%u, %u, %u) ", lcs.nodes[j].row, lcs.nodes[j].col, lcs.nodes[j].length); + } // for + fprintf(stderr, "\n"); + } // for + gva_uint tail_idx = lcs.index[lcs.length - 1].tail; LCS_Node sink = lcs.nodes[tail_idx]; if (sink.row + sink.length == len_ref + shift && sink.col + sink.length == len_obs + shift) @@ -101,6 +122,9 @@ gva_lcs_graph_init(GVA_Allocator const allocator, continue; } // if + table[i].count += 1; + table[i].idx = j; + gva_uint here = GVA_NULL; for (gva_uint k = lcs.index[i - 1].head; k != GVA_NULL; k = lcs.nodes[k].next) { @@ -168,6 +192,9 @@ gva_lcs_graph_init(GVA_Allocator const allocator, LCS_Node source = lcs.nodes[head_idx]; if (source.row == shift && source.col == shift) { + table[0].count += 1; + table[0].idx = head_idx; + head_idx = source.next; } // if else @@ -184,6 +211,9 @@ gva_lcs_graph_init(GVA_Allocator const allocator, continue; } // if + table[0].count += 1; + table[0].idx = i; + if (source.length == 0 || !lcs.nodes[i].moved) { graph.nodes[source.idx].edges = ARRAY_APPEND(allocator, graph.edges, ((GVA_Edge) { @@ -192,6 +222,31 @@ gva_lcs_graph_init(GVA_Allocator const allocator, } // if } // for + gva_uint uniq_match = 0; + for (gva_uint i = 0; i < lcs.length; ++i) + { + gva_uint const idx = lcs.nodes[table[i].idx].idx; + fprintf(stderr, "%u: %u (%u, %u, %u)\n", i, table[i].count, graph.nodes[idx].row, graph.nodes[idx].col, graph.nodes[idx].length); + if (table[i].count > 1) + { + if (uniq_match != 0) + { + gva_uint const idx = lcs.nodes[table[i - 1].idx].idx; + fprintf(stderr, "#uniq_match: %u in (%u, %u, %u)\n", uniq_match, graph.nodes[idx].row, graph.nodes[idx].col, graph.nodes[idx].length); + } // if + uniq_match = 0; + } // if + else + { + uniq_match += 1; + } // else + } // for + if (uniq_match != 0) + { + gva_uint const idx = lcs.nodes[table[lcs.length - 1].idx].idx; + fprintf(stderr, "#uniq_match: %u in (%u, %u, %u)\n", uniq_match, graph.nodes[idx].row, graph.nodes[idx].col, graph.nodes[idx].length); + } // if + gva_uint min_source = GVA_NULL; for (gva_uint i = graph.nodes[source.idx].edges; i != GVA_NULL; i = graph.edges[i].next) { @@ -212,8 +267,9 @@ gva_lcs_graph_init(GVA_Allocator const allocator, graph.source = source.idx; - allocator.allocate(allocator.context, lcs.index, lcs.length * sizeof(*lcs.index), 0); - ARRAY_DESTROY(allocator, lcs.nodes); + table = allocator.allocate(allocator.context, table, sizeof(*table) * lcs.length, 0); + lcs.index = allocator.allocate(allocator.context, lcs.index, lcs.length * sizeof(*lcs.index), 0); + lcs.nodes = ARRAY_DESTROY(allocator, lcs.nodes); return graph; } // gva_lcs_graph_init diff --git a/src/main.c b/src/main.c index a3b0f9d..5c5f2d9 100644 --- a/src/main.c +++ b/src/main.c @@ -175,16 +175,19 @@ main(int argc, char* argv[static argc + 1]) return EXIT_FAILURE; } // if + //char const* const restrict reference = "ATTCTATCTTCTGTCTACATAAGATGTCATACTAGAGGGCATATCTGCAATGTATACATATTATCTTTTCCAGCATGCATTCAGTTGTGTTGGAATAATTTATGTACACCTTTATAAACGCTGAGCCTCACAAGAGCCATGTGCCACGTATTGTTTTCTTACTACTTTTTGGGATACCTGGCACGTAATAGACACTCATTGAAAGTTTCCTAATGAATGAAGTACAAAGATAAAACAAGTTATAGACTGATTCTTTTGAGCTGTCAAGGTTGTAAATAGACTTTTGCTCAATCAATTCAAATGGTGGCAGGTAGTGGGGGTAGAGGGATTGGTATGAAAAACATAAGCTTTCAGAACTCCTGTGTTTATTTTTAGAATGTCAACTGCTTGAGTGTTTTTAACTCTGTGGTATCTGAACTATCTTCTCTAACTGCAGGTTGGGCTCAGATCTGTGATAGAACAGTTTCCTGGGAAGCTTGACTTTGTCCTTGTGGATGGGGGCTGTGTCCTAAGCCATGGCCACAAGCAGTTGATGTGCTTGGCTAGATCTGTTCTCAGTAAGGCGAAGATCTTGCTGCTTGATGAACCCAGTGCTCATTTGGATCCAGTGTGAGTTTCAGATGTTCTGTTACTTAATAGCACAGTGGGAACAGAATCATTATGCCTGCTTCATGGTGACACATATTTCTATTAGGCTGTCATGTCTGCGTGTGGGGGTCTCCCCCAAGATATGAAATAATTGCCCAGTGGAAATGAGCATAAATGCATATTTCCTTGCTAAGAGTCTTGTGTTTTCTTCCGAAGATAGTTTTTAGTTTCATACAAACTCTTCCCCCTTGTCAACACATGATGAAGCTTTTAAATACATGGGCCTAATCTGATCCTTATGATTTGCCTTTGTATCCCATTTATACCATAAGCATGTTTATAGCCCCAAATAAAGAAGTACTGGTGATTCTACATAATGAAAAATGTACTCATTTATTAAAGTTTCTTTGAAATATTTGTCCTGTTTATTTATGGATACTTAGAGTCTACCCCATGGTTGAAAAGCTGATTGTGGCTAACGCTATATCAACATTATGTGAAAAGAACTTAAAGAAATAAGTAATTTAAAGAGATAATAGAACAATAGACATATTATCAAGGTAAATACAGATCATTACTGTTCTGTGATATTATGTGTGGTATTTTCTTTCTTTTCTAGAACATACCAAATAATTAGAAGAACTCTAAAACAAGCATTTGCTGATTGCACAGTAATTCTCTGTGAACACAGGATAGAAGCAATGCTGGAATGCCAACAATTTTTGGTGAGTCTTTATAACTTTACTTAAGATCTCATTGCCCTTGTAATTCTTGATAACAATCTCACATGTGATAGTTCCTGCAAATTGCAACAATGTACAAGTTCTTTTCAAAAATATGTATCATACAGCCATCCAGCTTTACTCAAAATAGCTGCACAAGTTTTTCACTTTGATCTGAGCCATGTGGTGAGGTTGAAATATAGTAAATCTAAAATGGCAGCATATTACTAAGTTATGTTTATAAATAGGATATATATACTTTTTGAGCCCTTTATTTGGGGACCAAGTCATACAAAATACTCTACTGTTTAAGATTTTAAAAAAGGTCCCTGTGATTCTTTCAATAACTAAATGTCCCATGGATGTGGTCTGGGACAGGCCTAGTTGTCTTACAGTCTGATTTATGGTATTAATGACAAAGTTGAGAGGCACATTTCATTTTT"; + //char const* const restrict observed = "ATTCTATCTTCTGTCTACATAAGATGTCATACTAGAGGGCATATCTGCAATGTATACATATTATCTTTTCCAGCATGCATTCAGTTGTGTTGGAATAATTTATGTACACCTTTATAAACGCTGAGCCTCACAAGAGCCATGTGCCACGTATTGTTTTCTTACTACTTTTTGGGATACCTGGCACGTAATAGACACTCATTGAAAGTTTCCTAATGAATGAAGTACAAAGATAAAACAAGTTATAGACTGATTCTTTTGAGCTGTCAAGGTTGTAAATAGACTTTTGCTCAATCAATTCAAATGGTGGCAGGTAGTGGGGGTAGAGGGATTGGTATGAAAAACATAAGCTTTCAGAACTCCTGTGTTTATTTTTAGAATGTCAACTGCTTGAGTGTTTTTAACTCTGTGGTATCTGAACTATCTTCTCTAACTGCAGGTGAGTCTTTATAACTTTACTTAAGATCTCATTGCCCTTGTAATTCTTGATAACAATCTCACATGTGATAGTTCCTGCAAATTGCAACAATGTACAAGTTCTTTTCAAAAATATGTATCATACAGCCATCCAGCTTTACTCAAAATAGCTGCACAAGTTTTTCACTTTGATCTGAGCCATGTGGTGAGGTTGAAATATAGTAAATCTAAAATGGCAGCATATTACTAAGTTATGTTTATAAATAGGATATATATACTTTTTGAGCCCTTTATTTGGGGACCAAGTCATACAAAATACTCTACTGTTTAAGATTTTAAAAAAGGTCCCTGTGATTCTTTCAATAACTAAATGTCCCATGGATGTGGTCTGGGACAGGCCTAGTTGTCTTACAGTCTGATTTATGGTATTAATGACAAAGTTGAGAGGCACATTTCATTTTT"; char const* const restrict reference = argv[1]; char const* const restrict observed = argv[2]; + size_t const len_ref = strlen(reference); size_t const len_obs = strlen(observed); GVA_LCS_Graph graph = gva_lcs_graph_init(gva_std_allocator, len_ref, reference, len_obs, observed, 0); lcs_graph_raw(stderr, graph, len_obs, observed); - lcs_graph_dot(stderr, graph, len_obs, observed); - lcs_graph_json(stdout, graph, len_obs, observed); + //lcs_graph_dot(stderr, graph, len_obs, observed); + //lcs_graph_json(stdout, graph, len_obs, observed); gva_lcs_graph_destroy(gva_std_allocator, graph); From c9b997141a99260a7c0bd52567dfccf35cb8e925 Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 6 Jun 2025 12:40:09 +0200 Subject: [PATCH 220/704] WIP: detecting uniq matches --- src/lcs_graph.c | 29 ++++++++++++++--------------- src/main.c | 4 ++-- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/src/lcs_graph.c b/src/lcs_graph.c index 5470d05..94c1840 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -222,29 +222,28 @@ gva_lcs_graph_init(GVA_Allocator const allocator, } // if } // for - gva_uint uniq_match = 0; + gva_uint len = 0; + gva_uint prev = GVA_NULL; for (gva_uint i = 0; i < lcs.length; ++i) { - gva_uint const idx = lcs.nodes[table[i].idx].idx; - fprintf(stderr, "%u: %u (%u, %u, %u)\n", i, table[i].count, graph.nodes[idx].row, graph.nodes[idx].col, graph.nodes[idx].length); - if (table[i].count > 1) + //gva_uint const idx = lcs.nodes[table[i].idx].idx; + //fprintf(stderr, "%u: %u (%u, %u, %u)\n", i, table[i].count, graph.nodes[idx].row, graph.nodes[idx].col, graph.nodes[idx].length); + if ((prev != table[i].idx || table[i].count > 1) && len > 0) { - if (uniq_match != 0) - { - gva_uint const idx = lcs.nodes[table[i - 1].idx].idx; - fprintf(stderr, "#uniq_match: %u in (%u, %u, %u)\n", uniq_match, graph.nodes[idx].row, graph.nodes[idx].col, graph.nodes[idx].length); - } // if - uniq_match = 0; + gva_uint const idx = lcs.nodes[table[i - 1].idx].idx; + fprintf(stderr, "uniq_match in (%u, %u, %u) @ %u of length %u\n", graph.nodes[idx].row, graph.nodes[idx].col, graph.nodes[idx].length, i - len, len); + len = 0; } // if - else + if (table[i].count == 1) { - uniq_match += 1; - } // else + len += 1; + } // if + prev = table[i].idx; } // for - if (uniq_match != 0) + if (len > 0) { gva_uint const idx = lcs.nodes[table[lcs.length - 1].idx].idx; - fprintf(stderr, "#uniq_match: %u in (%u, %u, %u)\n", uniq_match, graph.nodes[idx].row, graph.nodes[idx].col, graph.nodes[idx].length); + fprintf(stderr, "uniq_match in (%u, %u, %u) @ %zu of length %u\n", graph.nodes[idx].row, graph.nodes[idx].col, graph.nodes[idx].length, lcs.length - len - 1, len); } // if gva_uint min_source = GVA_NULL; diff --git a/src/main.c b/src/main.c index 5c5f2d9..f71dbdf 100644 --- a/src/main.c +++ b/src/main.c @@ -186,8 +186,8 @@ main(int argc, char* argv[static argc + 1]) GVA_LCS_Graph graph = gva_lcs_graph_init(gva_std_allocator, len_ref, reference, len_obs, observed, 0); lcs_graph_raw(stderr, graph, len_obs, observed); - //lcs_graph_dot(stderr, graph, len_obs, observed); - //lcs_graph_json(stdout, graph, len_obs, observed); + lcs_graph_dot(stderr, graph, len_obs, observed); + lcs_graph_json(stdout, graph, len_obs, observed); gva_lcs_graph_destroy(gva_std_allocator, graph); From 7dd488a223a0ab23f3b170690d13d802b8f7efca Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 6 Jun 2025 13:17:03 +0200 Subject: [PATCH 221/704] Added edit distance only --- benchmark.txt | 93 ---------------------------------------- include/edit.h | 17 ++++++++ src/align.c | 6 +-- src/{base.h => common.h} | 6 +-- src/edit.c | 75 ++++++++++++++++++++++++++++++++ src/lcs_graph.c | 6 +-- src/main.c | 6 ++- 7 files changed, 106 insertions(+), 103 deletions(-) delete mode 100644 benchmark.txt create mode 100644 include/edit.h rename src/{base.h => common.h} (86%) create mode 100644 src/edit.c diff --git a/benchmark.txt b/benchmark.txt deleted file mode 100644 index afa272e..0000000 --- a/benchmark.txt +++ /dev/null @@ -1,93 +0,0 @@ -Empty main - -Python -9,768 kB - -C -1,260 kB - - -LCS alignment -len lcs 876 (136 empty) -102641 {row, col, length} @ 12 b = 1,231,692 b - -Python -0:00.33 -32,688 kB - -C (no pre alloc) -0:00.03 -20,528 kB - -C (256 pre alloc) -0:00.02 -3,276 kB (256 * (876 - 136)) @ 12 b = 2,273,280 b - - -LCS graph -71,858 nodes 8,096,506 edges (19,823 splits) - -Python -0:37.77 -1,792,004 kB - -C (only nodes) -0:00.03 -4,940 kB - -C (flat lambda edges: 5,874,991) (pre alloc makes no difference) -0:00.13 -142,468 kB - - -LCS construction - -flat edge stack order -0:00.13 -142,468 kB - -flat edge stack order + reorder -0:00.26 -279,412 kB - -flat edge list order -0:00.13 -142,948 kB - -nested edge arrays (256 pre alloc) -0:00.21 -355,336 kB - -nested edge arrays (150 pre alloc) -0:00.19 -279,468 kB - -nested edge arrays (no pre alloc) -0:00.98 -1,739,560 kB - -LCS edge count - -flat edge stack order -0:00.33 -142,476 kB - -flat edge stack order + reorder -0:00.31 -279,328 kB - -flat edge list order -0:00.33 -143,072 kB - -nested edge arrays (256 pre alloc) -0:00.23 -355,548 kB - -nested edge arrays (150 pre alloc) -0:00.21 -279,752 kB - -nested edge arrays (no pre alloc) -0:01.00 -1,739,728 kB diff --git a/include/edit.h b/include/edit.h new file mode 100644 index 0000000..0e4fa8e --- /dev/null +++ b/include/edit.h @@ -0,0 +1,17 @@ +#ifndef GVA_EDIT_H +#define GVA_EDIT_H + + +#include // size_t + + +#include "allocator.h" // GVA_Allocator + + +size_t +gva_edit_distance(GVA_Allocator const allocator, + size_t const len_ref, char const reference[static restrict len_ref], + size_t const len_obs, char const observed[static restrict len_obs]); + + +#endif // GVA_EDIT_H diff --git a/src/align.c b/src/align.c index af1e018..f043932 100644 --- a/src/align.c +++ b/src/align.c @@ -4,9 +4,9 @@ #include "../include/allocator.h" // GVA_Allocator -#include "align.h" // LCS_Alignment, LCS_Node, lcs_align -#include "array.h" // ARRAY_APPEND -#include "base.h" // GVA_NULL, ABS, MAX, MIN +#include "align.h" // LCS_Alignment, LCS_Node, lcs_align +#include "array.h" // ARRAY_APPEND +#include "common.h" // GVA_NULL, ABS, MAX, MIN typedef struct diff --git a/src/base.h b/src/common.h similarity index 86% rename from src/base.h rename to src/common.h index df92b1f..a4d8663 100644 --- a/src/base.h +++ b/src/common.h @@ -1,5 +1,5 @@ -#ifndef GVA_BASE_H -#define GVA_BASE_H +#ifndef GVA_COMMON_H +#define GVA_COMMON_H #include "../include/types.h" // GVA_NULL, gva_uint @@ -17,4 +17,4 @@ #define MIN(lhs, rhs) (((lhs) < (rhs)) ? (lhs) : (rhs)) -#endif // GVA_BASE_H +#endif // GVA_COMMON_H diff --git a/src/edit.c b/src/edit.c new file mode 100644 index 0000000..36513fa --- /dev/null +++ b/src/edit.c @@ -0,0 +1,75 @@ +#include // intmax_t +#include // NULL, size_t + + +#include "../include/allocator.h" // GVA_Allocator +#include "../include/edit.h" // gva_edit_distance +#include "common.h" // MAX + + +static inline size_t +onp_snake(size_t const m, char const a[static restrict m], + size_t const n, char const b[static restrict n], + intmax_t const k, + intmax_t const lower, + intmax_t const upper) +{ + size_t col = MAX(lower, upper); + size_t row = col - k; + while (row < m && col < n && a[row] == b[col]) + { + row += 1; + col += 1; + } // while + return col; +} // onp_snake + + +static size_t +onp_compare(GVA_Allocator const allocator, + size_t const m, char const a[static restrict m], + size_t const n, char const b[static restrict n]) +{ + intmax_t const delta = n - m; + size_t const offset = m + 1; + size_t const size = m + n + 3; + intmax_t* const restrict fp = allocator.allocate(allocator.context, NULL, 0, size * sizeof(*fp)); + if (fp == NULL) + { + return -1; + } // if + + for (size_t i = 0; i < size; ++i) + { + fp[i] = -1; + } // for + + size_t p = 0; + while ((size_t) fp[delta + offset] != n) + { + for (intmax_t k = -p; k <= delta - 1; ++k) + { + fp[k + offset] = onp_snake(m, a, n, b, k, fp[k - 1 + offset] + 1, fp[k + 1 + offset]); + } // for + for (intmax_t k = delta + p; k >= delta + 1; --k) + { + fp[k + offset] = onp_snake(m, a, n, b, k, fp[k - 1 + offset] + 1, fp[k + 1 + offset]); + } // for + fp[delta + offset] = onp_snake(m, a, n, b, delta, fp[delta - 1 + offset] + 1, fp[delta + 1 + offset]); + p += 1; + } // while + + allocator.allocate(allocator.context, fp, size * sizeof(*fp), 0); + return delta + 2 * (p - 1); +} // onp_compare + + +inline size_t +gva_edit_distance(GVA_Allocator const allocator, + size_t const len_ref, char const reference[static restrict len_ref], + size_t const len_obs, char const observed[static restrict len_obs]) +{ + return len_ref > len_obs ? + onp_compare(allocator, len_obs, observed, len_ref, reference) : + onp_compare(allocator, len_ref, reference, len_obs, observed); +} // gva_edit_distance diff --git a/src/lcs_graph.c b/src/lcs_graph.c index 94c1840..af01019 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -8,9 +8,9 @@ #include "../include/allocator.h" // GVA_Allocator #include "../include/lcs_graph.h" // GVA_LCS_Graph, GVA_Variant, gva_lcs_graph_* -#include "align.h" // LCS_Alignment, lcs_align -#include "array.h" // ARRAY_*, array_length -#include "base.h" // gva_uint, MAX, MIN +#include "align.h" // LCS_Alignment, lcs_align +#include "array.h" // ARRAY_*, array_length +#include "common.h" // gva_uint, MAX, MIN gva_uint diff --git a/src/main.c b/src/main.c index f71dbdf..eab425e 100644 --- a/src/main.c +++ b/src/main.c @@ -1,9 +1,10 @@ -#include // size_t +#include // NULL, size_t #include // FILE, stderr, fprintf #include // EXIT_* #include // strlen +#include "../include/edit.h" // gva_edit_distance #include "../include/lcs_graph.h" // GVA_LCS_Graph, GVA_Variant, gva_lcs_graph_*, gva_edges #include "../include/std_alloc.h" // gva_std_allocator #include "../include/types.h" // GVA_NULL, gva_uint @@ -189,6 +190,9 @@ main(int argc, char* argv[static argc + 1]) lcs_graph_dot(stderr, graph, len_obs, observed); lcs_graph_json(stdout, graph, len_obs, observed); + size_t const distance = gva_edit_distance(gva_std_allocator, len_ref, reference, len_obs, observed); + fprintf(stderr, "distance: %zu\n", distance); + gva_lcs_graph_destroy(gva_std_allocator, graph); return EXIT_SUCCESS; From ae395a289693cf4e23b6add5a775f9b55580c45f Mon Sep 17 00:00:00 2001 From: jkvis Date: Sat, 7 Jun 2025 12:47:03 +0200 Subject: [PATCH 222/704] Simple fasta reader --- .gitignore | 1 + include/utils.h | 28 ++++++++++++++++++++++++++++ src/lcs_graph.c | 2 +- src/main.c | 23 ++++++++++++++--------- src/utils.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 91 insertions(+), 10 deletions(-) create mode 100644 include/utils.h create mode 100644 src/utils.c diff --git a/.gitignore b/.gitignore index 9aec59f..e4db7b2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +data/ *.dSYM/ *.o *.d diff --git a/include/utils.h b/include/utils.h new file mode 100644 index 0000000..4c2af0f --- /dev/null +++ b/include/utils.h @@ -0,0 +1,28 @@ +// NOT FREESTANDING +#ifndef GVA_UTILS_H +#define GVA_UTILS_H + + +#include // size_t +#include // FILE + + +#include "allocator.h" // GVA_Allocator + + +#define GVA_VARIANT_PRINT(variant, observed) variant.start, variant.end, (int) variant.obs_end - variant.obs_start, observed + variant.obs_start +#define GVA_VARIANT_FMT "%u:%u/%.*s" + + +typedef struct +{ + size_t len; + char* str; +} GVA_String; + + +GVA_String +gva_fasta_sequence(GVA_Allocator const allocator, FILE* const restrict stream); + + +#endif // GVA_UTILS_H \ No newline at end of file diff --git a/src/lcs_graph.c b/src/lcs_graph.c index af01019..cd00b44 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -243,7 +243,7 @@ gva_lcs_graph_init(GVA_Allocator const allocator, if (len > 0) { gva_uint const idx = lcs.nodes[table[lcs.length - 1].idx].idx; - fprintf(stderr, "uniq_match in (%u, %u, %u) @ %zu of length %u\n", graph.nodes[idx].row, graph.nodes[idx].col, graph.nodes[idx].length, lcs.length - len - 1, len); + fprintf(stderr, "uniq_match in (%u, %u, %u) @ %zu of length %u\n", graph.nodes[idx].row, graph.nodes[idx].col, graph.nodes[idx].length, lcs.length - len, len); } // if gva_uint min_source = GVA_NULL; diff --git a/src/main.c b/src/main.c index eab425e..94b6498 100644 --- a/src/main.c +++ b/src/main.c @@ -1,5 +1,5 @@ #include // NULL, size_t -#include // FILE, stderr, fprintf +#include // FILE, stderr, fclose, fopen, fprintf #include // EXIT_* #include // strlen @@ -8,13 +8,10 @@ #include "../include/lcs_graph.h" // GVA_LCS_Graph, GVA_Variant, gva_lcs_graph_*, gva_edges #include "../include/std_alloc.h" // gva_std_allocator #include "../include/types.h" // GVA_NULL, gva_uint +#include "../include/utils.h" // GVA_String, gva_fasta_sequence, GVA_VARIANT_* #include "array.h" // array_length -#define PRI_VAR(variant, observed) variant.start, variant.end, (int) variant.obs_end - variant.obs_start, observed + variant.obs_start -#define VAR_FMT "%u:%u/%.*s" - - static void lcs_graph_dot(FILE* const stream, GVA_LCS_Graph const graph, size_t const len_obs, char const observed[static len_obs]) @@ -35,11 +32,11 @@ lcs_graph_dot(FILE* const stream, GVA_LCS_Graph const graph, &variant); if (count > 1) { - fprintf(stream, "%zu->%u[label=\"" VAR_FMT " x %u\",penwidth=2]\n", i, graph.edges[j].tail, PRI_VAR(variant, observed), count); + fprintf(stream, "%zu->%u[label=\"" GVA_VARIANT_FMT " x %u\",penwidth=2]\n", i, graph.edges[j].tail, GVA_VARIANT_PRINT(variant, observed), count); } // if else { - fprintf(stream, "%zu->%u[label=\"" VAR_FMT "\"]\n", i, graph.edges[j].tail, PRI_VAR(variant, observed)); + fprintf(stream, "%zu->%u[label=\"" GVA_VARIANT_FMT "\"]\n", i, graph.edges[j].tail, GVA_VARIANT_PRINT(variant, observed)); } // else } // for } // for @@ -95,7 +92,7 @@ bfs_traversal(FILE* const stream, GVA_LCS_Graph const graph, printf(",\n"); } // if first = false; - fprintf(stream, " {\"head\": \"s%u\", \"tail\": \"s%u\", \"variant\": \"" VAR_FMT "\"}", head, graph.edges[j].tail, PRI_VAR(variant, observed)); + fprintf(stream, " {\"head\": \"s%u\", \"tail\": \"s%u\", \"variant\": \"" GVA_VARIANT_FMT "\"}", head, graph.edges[j].tail, GVA_VARIANT_PRINT(variant, observed)); variant.start += 1; variant.end += 1; variant.obs_start += 1; @@ -161,7 +158,7 @@ lcs_graph_raw(FILE* const stream, GVA_LCS_Graph const graph, gva_uint const count = gva_edges(graph.nodes[i], graph.nodes[graph.edges[j].tail], i == graph.source, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, &variant); - fprintf(stream, VAR_FMT " x %u\n", PRI_VAR(variant, observed), count); + fprintf(stream, GVA_VARIANT_FMT " x %u\n", GVA_VARIANT_PRINT(variant, observed), count); } // for } // for } // lcs_graph_raw @@ -176,6 +173,14 @@ main(int argc, char* argv[static argc + 1]) return EXIT_FAILURE; } // if + FILE* const restrict stream = fopen("data/NC_000001.11.fasta", "r"); + if (stream != NULL) + { + GVA_String seq = gva_fasta_sequence(gva_std_allocator, stream); + gva_std_allocator.allocate(gva_std_allocator.context, seq.str, seq.len, 0); + fclose(stream); + } // if + //char const* const restrict reference = "ATTCTATCTTCTGTCTACATAAGATGTCATACTAGAGGGCATATCTGCAATGTATACATATTATCTTTTCCAGCATGCATTCAGTTGTGTTGGAATAATTTATGTACACCTTTATAAACGCTGAGCCTCACAAGAGCCATGTGCCACGTATTGTTTTCTTACTACTTTTTGGGATACCTGGCACGTAATAGACACTCATTGAAAGTTTCCTAATGAATGAAGTACAAAGATAAAACAAGTTATAGACTGATTCTTTTGAGCTGTCAAGGTTGTAAATAGACTTTTGCTCAATCAATTCAAATGGTGGCAGGTAGTGGGGGTAGAGGGATTGGTATGAAAAACATAAGCTTTCAGAACTCCTGTGTTTATTTTTAGAATGTCAACTGCTTGAGTGTTTTTAACTCTGTGGTATCTGAACTATCTTCTCTAACTGCAGGTTGGGCTCAGATCTGTGATAGAACAGTTTCCTGGGAAGCTTGACTTTGTCCTTGTGGATGGGGGCTGTGTCCTAAGCCATGGCCACAAGCAGTTGATGTGCTTGGCTAGATCTGTTCTCAGTAAGGCGAAGATCTTGCTGCTTGATGAACCCAGTGCTCATTTGGATCCAGTGTGAGTTTCAGATGTTCTGTTACTTAATAGCACAGTGGGAACAGAATCATTATGCCTGCTTCATGGTGACACATATTTCTATTAGGCTGTCATGTCTGCGTGTGGGGGTCTCCCCCAAGATATGAAATAATTGCCCAGTGGAAATGAGCATAAATGCATATTTCCTTGCTAAGAGTCTTGTGTTTTCTTCCGAAGATAGTTTTTAGTTTCATACAAACTCTTCCCCCTTGTCAACACATGATGAAGCTTTTAAATACATGGGCCTAATCTGATCCTTATGATTTGCCTTTGTATCCCATTTATACCATAAGCATGTTTATAGCCCCAAATAAAGAAGTACTGGTGATTCTACATAATGAAAAATGTACTCATTTATTAAAGTTTCTTTGAAATATTTGTCCTGTTTATTTATGGATACTTAGAGTCTACCCCATGGTTGAAAAGCTGATTGTGGCTAACGCTATATCAACATTATGTGAAAAGAACTTAAAGAAATAAGTAATTTAAAGAGATAATAGAACAATAGACATATTATCAAGGTAAATACAGATCATTACTGTTCTGTGATATTATGTGTGGTATTTTCTTTCTTTTCTAGAACATACCAAATAATTAGAAGAACTCTAAAACAAGCATTTGCTGATTGCACAGTAATTCTCTGTGAACACAGGATAGAAGCAATGCTGGAATGCCAACAATTTTTGGTGAGTCTTTATAACTTTACTTAAGATCTCATTGCCCTTGTAATTCTTGATAACAATCTCACATGTGATAGTTCCTGCAAATTGCAACAATGTACAAGTTCTTTTCAAAAATATGTATCATACAGCCATCCAGCTTTACTCAAAATAGCTGCACAAGTTTTTCACTTTGATCTGAGCCATGTGGTGAGGTTGAAATATAGTAAATCTAAAATGGCAGCATATTACTAAGTTATGTTTATAAATAGGATATATATACTTTTTGAGCCCTTTATTTGGGGACCAAGTCATACAAAATACTCTACTGTTTAAGATTTTAAAAAAGGTCCCTGTGATTCTTTCAATAACTAAATGTCCCATGGATGTGGTCTGGGACAGGCCTAGTTGTCTTACAGTCTGATTTATGGTATTAATGACAAAGTTGAGAGGCACATTTCATTTTT"; //char const* const restrict observed = "ATTCTATCTTCTGTCTACATAAGATGTCATACTAGAGGGCATATCTGCAATGTATACATATTATCTTTTCCAGCATGCATTCAGTTGTGTTGGAATAATTTATGTACACCTTTATAAACGCTGAGCCTCACAAGAGCCATGTGCCACGTATTGTTTTCTTACTACTTTTTGGGATACCTGGCACGTAATAGACACTCATTGAAAGTTTCCTAATGAATGAAGTACAAAGATAAAACAAGTTATAGACTGATTCTTTTGAGCTGTCAAGGTTGTAAATAGACTTTTGCTCAATCAATTCAAATGGTGGCAGGTAGTGGGGGTAGAGGGATTGGTATGAAAAACATAAGCTTTCAGAACTCCTGTGTTTATTTTTAGAATGTCAACTGCTTGAGTGTTTTTAACTCTGTGGTATCTGAACTATCTTCTCTAACTGCAGGTGAGTCTTTATAACTTTACTTAAGATCTCATTGCCCTTGTAATTCTTGATAACAATCTCACATGTGATAGTTCCTGCAAATTGCAACAATGTACAAGTTCTTTTCAAAAATATGTATCATACAGCCATCCAGCTTTACTCAAAATAGCTGCACAAGTTTTTCACTTTGATCTGAGCCATGTGGTGAGGTTGAAATATAGTAAATCTAAAATGGCAGCATATTACTAAGTTATGTTTATAAATAGGATATATATACTTTTTGAGCCCTTTATTTGGGGACCAAGTCATACAAAATACTCTACTGTTTAAGATTTTAAAAAAGGTCCCTGTGATTCTTTCAATAACTAAATGTCCCATGGATGTGGTCTGGGACAGGCCTAGTTGTCTTACAGTCTGATTTATGGTATTAATGACAAAGTTGAGAGGCACATTTCATTTTT"; char const* const restrict reference = argv[1]; diff --git a/src/utils.c b/src/utils.c new file mode 100644 index 0000000..ac44fe0 --- /dev/null +++ b/src/utils.c @@ -0,0 +1,47 @@ +// NOT FREESTANDING +#include // NULL, size_t +#include // FILE, fgets +#include // strcspn + + +#include "../include/allocator.h" // GVA_Allocator +#include "../include/utils.h" // GVA_String, gva_fasta_sequence + + +GVA_String +gva_fasta_sequence(GVA_Allocator const allocator, FILE* const restrict stream) +{ + static size_t const FASTA_LINE_SIZE = 65536; + size_t capacity = FASTA_LINE_SIZE; + GVA_String seq = {0, allocator.allocate(allocator.context, NULL, 0, capacity)}; + if (seq.str == NULL) + { + return seq; + } // if + + while (fgets(seq.str + seq.len, FASTA_LINE_SIZE, stream) != NULL) + { + if (seq.str[seq.len] == '>') + { + if (seq.len == 0) + { + continue; + } // if + break; + } // if + seq.len += strcspn(seq.str + seq.len, "\n"); + + if (capacity - FASTA_LINE_SIZE < seq.len) + { + seq.str = allocator.allocate(allocator.context, seq.str, capacity, capacity + FASTA_LINE_SIZE); + if (seq.str == NULL) + { + seq.len = 0; + return seq; + } // if + capacity += FASTA_LINE_SIZE; + } // if + } // while + seq.str = allocator.allocate(allocator.context, seq.str, capacity, seq.len); + return seq; +} // gva_fasta_sequence From 3fc39ab4ddcb10ab6817e5acccd2efe60aacbf67 Mon Sep 17 00:00:00 2001 From: jkvis Date: Sat, 7 Jun 2025 13:12:38 +0200 Subject: [PATCH 223/704] Fix proper dealloc on failure --- src/align.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/align.c b/src/align.c index f043932..20b7911 100644 --- a/src/align.c +++ b/src/align.c @@ -164,7 +164,7 @@ lcs_align(GVA_Allocator const allocator, lcs.index = allocator.allocate(allocator.context, NULL, 0, MIN(len_ref, len_obs) * sizeof(*lcs.index)); if (lcs.index == NULL) { - allocator.allocate(allocator.context, NULL, 0, size * sizeof(*context.diagonals)); + allocator.allocate(allocator.context, context.diagonals, size * sizeof(*context.diagonals), 0); return lcs; } // if From 73aa20a33fb0eb64632638b5b1ce5789697a8609 Mon Sep 17 00:00:00 2001 From: jkvis Date: Sat, 7 Jun 2025 13:14:50 +0200 Subject: [PATCH 224/704] WIP: local supremals --- include/lcs_graph.h | 1 + src/lcs_graph.c | 16 +++++++++++++++- src/main.c | 12 ++++++++++++ test.py | 2 +- 4 files changed, 29 insertions(+), 2 deletions(-) diff --git a/include/lcs_graph.h b/include/lcs_graph.h index b9eaada..625c4cf 100644 --- a/include/lcs_graph.h +++ b/include/lcs_graph.h @@ -39,6 +39,7 @@ typedef struct { GVA_Node* nodes; GVA_Edge* edges; + GVA_Node* local_supremal; gva_uint source; } GVA_LCS_Graph; diff --git a/src/lcs_graph.c b/src/lcs_graph.c index cd00b44..e611a2c 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -44,7 +44,7 @@ gva_lcs_graph_init(GVA_Allocator const allocator, { LCS_Alignment lcs = lcs_align(allocator, len_ref, reference, len_obs, observed); - GVA_LCS_Graph graph = {.nodes = NULL, .edges = NULL}; + GVA_LCS_Graph graph = {NULL, NULL, NULL, GVA_NULL}; if (lcs.nodes == NULL) { @@ -203,6 +203,9 @@ gva_lcs_graph_init(GVA_Allocator const allocator, source.idx = ARRAY_APPEND(allocator, graph.nodes, ((GVA_Node) { source.row, source.col, source.length, GVA_NULL, GVA_NULL })) - 1; + ARRAY_APPEND(allocator, graph.local_supremal, ((GVA_Node) { + source.row, source.col, source.length, GVA_NULL, GVA_NULL + })); } // else for (gva_uint i = head_idx; i != GVA_NULL; i = lcs.nodes[i].next) { @@ -232,6 +235,9 @@ gva_lcs_graph_init(GVA_Allocator const allocator, { gva_uint const idx = lcs.nodes[table[i - 1].idx].idx; fprintf(stderr, "uniq_match in (%u, %u, %u) @ %u of length %u\n", graph.nodes[idx].row, graph.nodes[idx].col, graph.nodes[idx].length, i - len, len); + ARRAY_APPEND(allocator, graph.local_supremal, ((GVA_Node) { + graph.nodes[idx].row, graph.nodes[idx].col, len, GVA_NULL, GVA_NULL + })); len = 0; } // if if (table[i].count == 1) @@ -244,6 +250,13 @@ gva_lcs_graph_init(GVA_Allocator const allocator, { gva_uint const idx = lcs.nodes[table[lcs.length - 1].idx].idx; fprintf(stderr, "uniq_match in (%u, %u, %u) @ %zu of length %u\n", graph.nodes[idx].row, graph.nodes[idx].col, graph.nodes[idx].length, lcs.length - len, len); + ARRAY_APPEND(allocator, graph.local_supremal, ((GVA_Node) { + graph.nodes[idx].row, graph.nodes[idx].col, len, GVA_NULL, GVA_NULL + })); + } // if + if (lcs.nodes[table[lcs.length - 1].idx].idx != 0) + { + ARRAY_APPEND(allocator, graph.local_supremal, graph.nodes[0]); } // if gva_uint min_source = GVA_NULL; @@ -278,4 +291,5 @@ gva_lcs_graph_destroy(GVA_Allocator const allocator, GVA_LCS_Graph self) { self.nodes = ARRAY_DESTROY(allocator, self.nodes); self.edges = ARRAY_DESTROY(allocator, self.edges); + self.local_supremal = ARRAY_DESTROY(allocator, self.local_supremal); } // gva_lcs_graph_destroy diff --git a/src/main.c b/src/main.c index 94b6498..0d27e09 100644 --- a/src/main.c +++ b/src/main.c @@ -173,6 +173,7 @@ main(int argc, char* argv[static argc + 1]) return EXIT_FAILURE; } // if + /* FILE* const restrict stream = fopen("data/NC_000001.11.fasta", "r"); if (stream != NULL) { @@ -180,6 +181,7 @@ main(int argc, char* argv[static argc + 1]) gva_std_allocator.allocate(gva_std_allocator.context, seq.str, seq.len, 0); fclose(stream); } // if + */ //char const* const restrict reference = "ATTCTATCTTCTGTCTACATAAGATGTCATACTAGAGGGCATATCTGCAATGTATACATATTATCTTTTCCAGCATGCATTCAGTTGTGTTGGAATAATTTATGTACACCTTTATAAACGCTGAGCCTCACAAGAGCCATGTGCCACGTATTGTTTTCTTACTACTTTTTGGGATACCTGGCACGTAATAGACACTCATTGAAAGTTTCCTAATGAATGAAGTACAAAGATAAAACAAGTTATAGACTGATTCTTTTGAGCTGTCAAGGTTGTAAATAGACTTTTGCTCAATCAATTCAAATGGTGGCAGGTAGTGGGGGTAGAGGGATTGGTATGAAAAACATAAGCTTTCAGAACTCCTGTGTTTATTTTTAGAATGTCAACTGCTTGAGTGTTTTTAACTCTGTGGTATCTGAACTATCTTCTCTAACTGCAGGTTGGGCTCAGATCTGTGATAGAACAGTTTCCTGGGAAGCTTGACTTTGTCCTTGTGGATGGGGGCTGTGTCCTAAGCCATGGCCACAAGCAGTTGATGTGCTTGGCTAGATCTGTTCTCAGTAAGGCGAAGATCTTGCTGCTTGATGAACCCAGTGCTCATTTGGATCCAGTGTGAGTTTCAGATGTTCTGTTACTTAATAGCACAGTGGGAACAGAATCATTATGCCTGCTTCATGGTGACACATATTTCTATTAGGCTGTCATGTCTGCGTGTGGGGGTCTCCCCCAAGATATGAAATAATTGCCCAGTGGAAATGAGCATAAATGCATATTTCCTTGCTAAGAGTCTTGTGTTTTCTTCCGAAGATAGTTTTTAGTTTCATACAAACTCTTCCCCCTTGTCAACACATGATGAAGCTTTTAAATACATGGGCCTAATCTGATCCTTATGATTTGCCTTTGTATCCCATTTATACCATAAGCATGTTTATAGCCCCAAATAAAGAAGTACTGGTGATTCTACATAATGAAAAATGTACTCATTTATTAAAGTTTCTTTGAAATATTTGTCCTGTTTATTTATGGATACTTAGAGTCTACCCCATGGTTGAAAAGCTGATTGTGGCTAACGCTATATCAACATTATGTGAAAAGAACTTAAAGAAATAAGTAATTTAAAGAGATAATAGAACAATAGACATATTATCAAGGTAAATACAGATCATTACTGTTCTGTGATATTATGTGTGGTATTTTCTTTCTTTTCTAGAACATACCAAATAATTAGAAGAACTCTAAAACAAGCATTTGCTGATTGCACAGTAATTCTCTGTGAACACAGGATAGAAGCAATGCTGGAATGCCAACAATTTTTGGTGAGTCTTTATAACTTTACTTAAGATCTCATTGCCCTTGTAATTCTTGATAACAATCTCACATGTGATAGTTCCTGCAAATTGCAACAATGTACAAGTTCTTTTCAAAAATATGTATCATACAGCCATCCAGCTTTACTCAAAATAGCTGCACAAGTTTTTCACTTTGATCTGAGCCATGTGGTGAGGTTGAAATATAGTAAATCTAAAATGGCAGCATATTACTAAGTTATGTTTATAAATAGGATATATATACTTTTTGAGCCCTTTATTTGGGGACCAAGTCATACAAAATACTCTACTGTTTAAGATTTTAAAAAAGGTCCCTGTGATTCTTTCAATAACTAAATGTCCCATGGATGTGGTCTGGGACAGGCCTAGTTGTCTTACAGTCTGATTTATGGTATTAATGACAAAGTTGAGAGGCACATTTCATTTTT"; //char const* const restrict observed = "ATTCTATCTTCTGTCTACATAAGATGTCATACTAGAGGGCATATCTGCAATGTATACATATTATCTTTTCCAGCATGCATTCAGTTGTGTTGGAATAATTTATGTACACCTTTATAAACGCTGAGCCTCACAAGAGCCATGTGCCACGTATTGTTTTCTTACTACTTTTTGGGATACCTGGCACGTAATAGACACTCATTGAAAGTTTCCTAATGAATGAAGTACAAAGATAAAACAAGTTATAGACTGATTCTTTTGAGCTGTCAAGGTTGTAAATAGACTTTTGCTCAATCAATTCAAATGGTGGCAGGTAGTGGGGGTAGAGGGATTGGTATGAAAAACATAAGCTTTCAGAACTCCTGTGTTTATTTTTAGAATGTCAACTGCTTGAGTGTTTTTAACTCTGTGGTATCTGAACTATCTTCTCTAACTGCAGGTGAGTCTTTATAACTTTACTTAAGATCTCATTGCCCTTGTAATTCTTGATAACAATCTCACATGTGATAGTTCCTGCAAATTGCAACAATGTACAAGTTCTTTTCAAAAATATGTATCATACAGCCATCCAGCTTTACTCAAAATAGCTGCACAAGTTTTTCACTTTGATCTGAGCCATGTGGTGAGGTTGAAATATAGTAAATCTAAAATGGCAGCATATTACTAAGTTATGTTTATAAATAGGATATATATACTTTTTGAGCCCTTTATTTGGGGACCAAGTCATACAAAATACTCTACTGTTTAAGATTTTAAAAAAGGTCCCTGTGATTCTTTCAATAACTAAATGTCCCATGGATGTGGTCTGGGACAGGCCTAGTTGTCTTACAGTCTGATTTATGGTATTAATGACAAAGTTGAGAGGCACATTTCATTTTT"; @@ -195,6 +197,16 @@ main(int argc, char* argv[static argc + 1]) lcs_graph_dot(stderr, graph, len_obs, observed); lcs_graph_json(stdout, graph, len_obs, observed); + if (graph.local_supremal != NULL) + { + for (size_t i = 0; i < array_length(graph.local_supremal) - 1; ++i) + { + fprintf(stderr, "(%u, %u, %u) -> (%u, %u, %u)\n", + graph.local_supremal[i].row, graph.local_supremal[i].col, graph.local_supremal[i].length, + graph.local_supremal[i + 1].row, graph.local_supremal[i + 1].col, graph.local_supremal[i + 1].length); + } // for + } // if + size_t const distance = gva_edit_distance(gva_std_allocator, len_ref, reference, len_obs, observed); fprintf(stderr, "distance: %zu\n", distance); diff --git a/test.py b/test.py index 38bbb6a..d96d6a3 100644 --- a/test.py +++ b/test.py @@ -79,7 +79,7 @@ def str2var(desc): assert lhs == str(rhs), f'canonical elements differ: {lhs} vs {rhs}' -def check(reference, observed, debug=False, timeout=2): +def check(reference, observed, debug=True, timeout=2): #graph = LCSgraph.from_sequence(reference, observed) graph = LCSgraph(reference, observed) valgrind = [] From 32977955981591420d75b29d5ed94930e779e132 Mon Sep 17 00:00:00 2001 From: jkvis Date: Sun, 8 Jun 2025 18:23:00 +0200 Subject: [PATCH 225/704] WIP: local supremal --- src/lcs_graph.c | 29 ++++++++++++++++++----------- src/main.c | 11 +++++++++-- 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/src/lcs_graph.c b/src/lcs_graph.c index e611a2c..7bb0cda 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -69,12 +69,12 @@ gva_lcs_graph_init(GVA_Allocator const allocator, { gva_uint count; gva_uint idx; + gva_uint offset; }* table = allocator.allocate(allocator.context, NULL, 0, sizeof(*table) * lcs.length); for (gva_uint i = 0; i < lcs.length; ++i) { table[i].count = 0; - table[i].idx = GVA_NULL; fprintf(stderr, "%u: ", i); for (gva_uint j = lcs.index[i].head; j != GVA_NULL; j = lcs.nodes[j].next) { @@ -117,13 +117,14 @@ gva_lcs_graph_init(GVA_Allocator const allocator, { LCS_Node* const restrict tail = &lcs.nodes[j]; next = tail->next; - if (lcs.nodes[j].idx == GVA_NULL) + if (tail->idx == GVA_NULL) { continue; } // if table[i].count += 1; table[i].idx = j; + table[i].offset = graph.nodes[tail->idx].length - tail->length; gva_uint here = GVA_NULL; for (gva_uint k = lcs.index[i - 1].head; k != GVA_NULL; k = lcs.nodes[k].next) @@ -194,6 +195,7 @@ gva_lcs_graph_init(GVA_Allocator const allocator, { table[0].count += 1; table[0].idx = head_idx; + table[0].offset = graph.nodes[source.idx].length - source.length; head_idx = source.next; } // if @@ -204,7 +206,7 @@ gva_lcs_graph_init(GVA_Allocator const allocator, source.row, source.col, source.length, GVA_NULL, GVA_NULL })) - 1; ARRAY_APPEND(allocator, graph.local_supremal, ((GVA_Node) { - source.row, source.col, source.length, GVA_NULL, GVA_NULL + source.row, source.col, source.length, GVA_NULL, source.idx })); } // else for (gva_uint i = head_idx; i != GVA_NULL; i = lcs.nodes[i].next) @@ -216,6 +218,7 @@ gva_lcs_graph_init(GVA_Allocator const allocator, table[0].count += 1; table[0].idx = i; + table[0].offset = graph.nodes[lcs.nodes[i].idx].length - lcs.nodes[i].length; if (source.length == 0 || !lcs.nodes[i].moved) { @@ -229,14 +232,13 @@ gva_lcs_graph_init(GVA_Allocator const allocator, gva_uint prev = GVA_NULL; for (gva_uint i = 0; i < lcs.length; ++i) { - //gva_uint const idx = lcs.nodes[table[i].idx].idx; - //fprintf(stderr, "%u: %u (%u, %u, %u)\n", i, table[i].count, graph.nodes[idx].row, graph.nodes[idx].col, graph.nodes[idx].length); if ((prev != table[i].idx || table[i].count > 1) && len > 0) { gva_uint const idx = lcs.nodes[table[i - 1].idx].idx; - fprintf(stderr, "uniq_match in (%u, %u, %u) @ %u of length %u\n", graph.nodes[idx].row, graph.nodes[idx].col, graph.nodes[idx].length, i - len, len); + gva_uint const offset = graph.nodes[idx].length - table[i - len].offset + (graph.nodes[idx].length == table[i - len].offset ? 0 : -1); + fprintf(stderr, "uniq_match in (%u, %u, %u) @ %u of length %u offset: %u\n", graph.nodes[idx].row, graph.nodes[idx].col, graph.nodes[idx].length, i - len, len, offset); ARRAY_APPEND(allocator, graph.local_supremal, ((GVA_Node) { - graph.nodes[idx].row, graph.nodes[idx].col, len, GVA_NULL, GVA_NULL + graph.nodes[idx].row + offset, graph.nodes[idx].col + offset, len, GVA_NULL, idx })); len = 0; } // if @@ -245,18 +247,23 @@ gva_lcs_graph_init(GVA_Allocator const allocator, len += 1; } // if prev = table[i].idx; + gva_uint const idx = lcs.nodes[table[i].idx].idx; + fprintf(stderr, "%u: %u (%u, %u, %u) @ %u\n", i, table[i].count, graph.nodes[idx].row, graph.nodes[idx].col, graph.nodes[idx].length, table[i].offset); } // for if (len > 0) { gva_uint const idx = lcs.nodes[table[lcs.length - 1].idx].idx; - fprintf(stderr, "uniq_match in (%u, %u, %u) @ %zu of length %u\n", graph.nodes[idx].row, graph.nodes[idx].col, graph.nodes[idx].length, lcs.length - len, len); + gva_uint const offset = graph.nodes[idx].length - table[lcs.length - len].offset + (graph.nodes[idx].length == table[lcs.length - len].offset ? 0 : -1); + fprintf(stderr, "uniq_match in (%u, %u, %u) @ %zu of length %u offset: %u\n", graph.nodes[idx].row, graph.nodes[idx].col, graph.nodes[idx].length, lcs.length - len, len, offset); ARRAY_APPEND(allocator, graph.local_supremal, ((GVA_Node) { - graph.nodes[idx].row, graph.nodes[idx].col, len, GVA_NULL, GVA_NULL + graph.nodes[idx].row + offset, graph.nodes[idx].col + offset, len, GVA_NULL, idx })); } // if - if (lcs.nodes[table[lcs.length - 1].idx].idx != 0) + if (table[lcs.length - 1].count > 1 || lcs.nodes[table[lcs.length - 1].idx].idx != 0) { - ARRAY_APPEND(allocator, graph.local_supremal, graph.nodes[0]); + ARRAY_APPEND(allocator, graph.local_supremal, ((GVA_Node) { + graph.nodes[0].row + graph.nodes[0].length, graph.nodes[0].col + graph.nodes[0].length, len, GVA_NULL, 0 + })); } // if gva_uint min_source = GVA_NULL; diff --git a/src/main.c b/src/main.c index 0d27e09..6455275 100644 --- a/src/main.c +++ b/src/main.c @@ -40,6 +40,10 @@ lcs_graph_dot(FILE* const stream, GVA_LCS_Graph const graph, } // else } // for } // for + for (size_t i = 0; i < array_length(graph.local_supremal); ++i) + { + fprintf(stream, "%u[penwidth=2]\n", graph.local_supremal[i].lambda); + } // for fprintf(stream, "}\n"); } // lcs_graph_dot @@ -201,9 +205,12 @@ main(int argc, char* argv[static argc + 1]) { for (size_t i = 0; i < array_length(graph.local_supremal) - 1; ++i) { - fprintf(stderr, "(%u, %u, %u) -> (%u, %u, %u)\n", + GVA_Variant variant; + gva_edges(graph.local_supremal[i], graph.local_supremal[i + 1], i == 0, i == array_length(graph.local_supremal) - 2, &variant); + fprintf(stderr, "(%u, %u, %u) -> (%u, %u, %u): " GVA_VARIANT_FMT "\n", graph.local_supremal[i].row, graph.local_supremal[i].col, graph.local_supremal[i].length, - graph.local_supremal[i + 1].row, graph.local_supremal[i + 1].col, graph.local_supremal[i + 1].length); + graph.local_supremal[i + 1].row, graph.local_supremal[i + 1].col, graph.local_supremal[i + 1].length, + GVA_VARIANT_PRINT(variant, observed)); } // for } // if From 94573b3e4a6b8552fd64e6bdf51879f9ecc27fdf Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 10 Jun 2025 12:55:02 +0200 Subject: [PATCH 226/704] Distance, supremal and local supremal --- include/lcs_graph.h | 1 + regres.sh | 24 ++++++++++ src/lcs_graph.c | 110 ++++++++++++++++++++++---------------------- src/main.c | 63 +++++++++++++++++-------- test.py | 8 ++-- 5 files changed, 128 insertions(+), 78 deletions(-) diff --git a/include/lcs_graph.h b/include/lcs_graph.h index 625c4cf..f884923 100644 --- a/include/lcs_graph.h +++ b/include/lcs_graph.h @@ -41,6 +41,7 @@ typedef struct GVA_Edge* edges; GVA_Node* local_supremal; gva_uint source; + gva_uint distance; } GVA_LCS_Graph; diff --git a/regres.sh b/regres.sh index 1f2dea7..ad66dcd 100755 --- a/regres.sh +++ b/regres.sh @@ -30,6 +30,30 @@ CTGGGGAG CCACCTGGGC CATTTCACGA TCGCCC GCC CGACGAGCCC AGAGAAAAA AAAA +#from algebra +"" "" +"" C +C "" +C G +CATC GATG +AGAATTGCTTGAA AGGGTTAAA +CTCTAGAGACTTTATTTTCCAC GTCTCAGACTTTCTTTATCCCC +ATATACCTTTTA CTATAGCCTTTTTC +CAGGGGAAGTG GCAGGGGCCTA +TCGTGGT CTAACAT +TGCATTAGGGCAAGGGTCTTCGACTTTCCACGAAAATCGCGTCGGTTTGAC TGCATTAGGGCAAGGGTCTTCGACTTCCACGAAAATCGCGTCGGTTTGAC +TGCATTAGGGCAAGGGTCTTCGACTTTCCACGAAAATCGCGTCGGTTTGAC TGCATTAGGGCAAGGGTCTTCGACTTCCACGAAAATCGCGTCGGTTGAC +CTCGGCATTA GGCTGGCTGT +TTT TTTTAT +TTTTAT TTT +TTAATTGACA CTACTGAGTT +TCTCTATCGTA TCTA +AAAATA GAAAAGAAA +CATATATCG CTTATAGCAT +TCTC TC +TTGTA TTTGTGTT +AA ACA +ACA AA ) for ((i=0; i<${#TESTS[@]}; i+=2)); do diff --git a/src/lcs_graph.c b/src/lcs_graph.c index 7bb0cda..4c20f04 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -3,9 +3,6 @@ #include // NULL, size_t -#include // DEBUG - - #include "../include/allocator.h" // GVA_Allocator #include "../include/lcs_graph.h" // GVA_LCS_Graph, GVA_Variant, gva_lcs_graph_* #include "align.h" // LCS_Alignment, lcs_align @@ -44,16 +41,25 @@ gva_lcs_graph_init(GVA_Allocator const allocator, { LCS_Alignment lcs = lcs_align(allocator, len_ref, reference, len_obs, observed); - GVA_LCS_Graph graph = {NULL, NULL, NULL, GVA_NULL}; + GVA_LCS_Graph graph = {NULL, NULL, NULL, GVA_NULL, len_ref + len_obs - 2 * lcs.length}; - if (lcs.nodes == NULL) + if (lcs.nodes == NULL || graph.distance == 0) { gva_uint const sink = ARRAY_APPEND(allocator, graph.nodes, ((GVA_Node) { len_ref, len_obs, 0, GVA_NULL, GVA_NULL })) - 1; - if (len_ref == 0 && len_obs == 0) + if ((len_ref == 0 && len_obs == 0) || graph.distance == 0) { graph.source = sink; + graph.nodes[sink].row = 0; + graph.nodes[sink].col = 0; + graph.nodes[sink].length = 0; + ARRAY_APPEND(allocator, graph.local_supremal, ((GVA_Node) { + shift, shift, 0, GVA_NULL, graph.source + })); + + lcs.index = allocator.allocate(allocator.context, lcs.index, lcs.length * sizeof(*lcs.index), 0); + lcs.nodes = ARRAY_DESTROY(allocator, lcs.nodes); return graph; } // if @@ -62,6 +68,13 @@ gva_lcs_graph_init(GVA_Allocator const allocator, ARRAY_APPEND(allocator, graph.edges, ((GVA_Edge) {sink, GVA_NULL})) - 1, GVA_NULL })) - 1; + + ARRAY_APPEND(allocator, graph.local_supremal, ((GVA_Node) { + shift, shift, 0, GVA_NULL, GVA_NULL + })); + ARRAY_APPEND(allocator, graph.local_supremal, ((GVA_Node) { + len_ref, len_obs, 0, GVA_NULL, GVA_NULL + })); return graph; } // if @@ -70,17 +83,11 @@ gva_lcs_graph_init(GVA_Allocator const allocator, gva_uint count; gva_uint idx; gva_uint offset; - }* table = allocator.allocate(allocator.context, NULL, 0, sizeof(*table) * lcs.length); + }* matches = allocator.allocate(allocator.context, NULL, 0, sizeof(*matches) * lcs.length); for (gva_uint i = 0; i < lcs.length; ++i) { - table[i].count = 0; - fprintf(stderr, "%u: ", i); - for (gva_uint j = lcs.index[i].head; j != GVA_NULL; j = lcs.nodes[j].next) - { - fprintf(stderr, "(%u, %u, %u) ", lcs.nodes[j].row, lcs.nodes[j].col, lcs.nodes[j].length); - } // for - fprintf(stderr, "\n"); + matches[i].count = 0; } // for gva_uint tail_idx = lcs.index[lcs.length - 1].tail; @@ -122,9 +129,9 @@ gva_lcs_graph_init(GVA_Allocator const allocator, continue; } // if - table[i].count += 1; - table[i].idx = j; - table[i].offset = graph.nodes[tail->idx].length - tail->length; + matches[i].count += 1; + matches[i].idx = j; + matches[i].offset = graph.nodes[tail->idx].length - tail->length; gva_uint here = GVA_NULL; for (gva_uint k = lcs.index[i - 1].head; k != GVA_NULL; k = lcs.nodes[k].next) @@ -193,9 +200,9 @@ gva_lcs_graph_init(GVA_Allocator const allocator, LCS_Node source = lcs.nodes[head_idx]; if (source.row == shift && source.col == shift) { - table[0].count += 1; - table[0].idx = head_idx; - table[0].offset = graph.nodes[source.idx].length - source.length; + matches[0].count += 1; + matches[0].idx = head_idx; + matches[0].offset = graph.nodes[source.idx].length - source.length; head_idx = source.next; } // if @@ -205,9 +212,6 @@ gva_lcs_graph_init(GVA_Allocator const allocator, source.idx = ARRAY_APPEND(allocator, graph.nodes, ((GVA_Node) { source.row, source.col, source.length, GVA_NULL, GVA_NULL })) - 1; - ARRAY_APPEND(allocator, graph.local_supremal, ((GVA_Node) { - source.row, source.col, source.length, GVA_NULL, source.idx - })); } // else for (gva_uint i = head_idx; i != GVA_NULL; i = lcs.nodes[i].next) { @@ -216,9 +220,9 @@ gva_lcs_graph_init(GVA_Allocator const allocator, continue; } // if - table[0].count += 1; - table[0].idx = i; - table[0].offset = graph.nodes[lcs.nodes[i].idx].length - lcs.nodes[i].length; + matches[0].count += 1; + matches[0].idx = i; + matches[0].offset = graph.nodes[lcs.nodes[i].idx].length - lcs.nodes[i].length; if (source.length == 0 || !lcs.nodes[i].moved) { @@ -232,61 +236,55 @@ gva_lcs_graph_init(GVA_Allocator const allocator, gva_uint prev = GVA_NULL; for (gva_uint i = 0; i < lcs.length; ++i) { - if ((prev != table[i].idx || table[i].count > 1) && len > 0) + if (prev == GVA_NULL && lcs.nodes[matches[i].idx].idx != source.idx) { - gva_uint const idx = lcs.nodes[table[i - 1].idx].idx; - gva_uint const offset = graph.nodes[idx].length - table[i - len].offset + (graph.nodes[idx].length == table[i - len].offset ? 0 : -1); - fprintf(stderr, "uniq_match in (%u, %u, %u) @ %u of length %u offset: %u\n", graph.nodes[idx].row, graph.nodes[idx].col, graph.nodes[idx].length, i - len, len, offset); + ARRAY_APPEND(allocator, graph.local_supremal, ((GVA_Node) { + graph.nodes[source.idx].row + len, graph.nodes[source.idx].col + len, 0, GVA_NULL, source.idx + })); + } // if + if (len > 0 && (matches[i].count > 1 || prev != matches[i].idx)) + { + gva_uint const idx = lcs.nodes[prev].idx; + gva_uint const offset = graph.nodes[idx].length - matches[i - 1].offset - len; ARRAY_APPEND(allocator, graph.local_supremal, ((GVA_Node) { graph.nodes[idx].row + offset, graph.nodes[idx].col + offset, len, GVA_NULL, idx })); len = 0; } // if - if (table[i].count == 1) + if (matches[i].count == 1) { len += 1; } // if - prev = table[i].idx; - gva_uint const idx = lcs.nodes[table[i].idx].idx; - fprintf(stderr, "%u: %u (%u, %u, %u) @ %u\n", i, table[i].count, graph.nodes[idx].row, graph.nodes[idx].col, graph.nodes[idx].length, table[i].offset); + + prev = matches[i].idx; } // for if (len > 0) { - gva_uint const idx = lcs.nodes[table[lcs.length - 1].idx].idx; - gva_uint const offset = graph.nodes[idx].length - table[lcs.length - len].offset + (graph.nodes[idx].length == table[lcs.length - len].offset ? 0 : -1); - fprintf(stderr, "uniq_match in (%u, %u, %u) @ %zu of length %u offset: %u\n", graph.nodes[idx].row, graph.nodes[idx].col, graph.nodes[idx].length, lcs.length - len, len, offset); + gva_uint const idx = lcs.nodes[prev].idx; + gva_uint const offset = graph.nodes[idx].length - matches[lcs.length - 1].offset - len; ARRAY_APPEND(allocator, graph.local_supremal, ((GVA_Node) { graph.nodes[idx].row + offset, graph.nodes[idx].col + offset, len, GVA_NULL, idx })); } // if - if (table[lcs.length - 1].count > 1 || lcs.nodes[table[lcs.length - 1].idx].idx != 0) + if (len == 0 || lcs.nodes[prev].idx != 0) { ARRAY_APPEND(allocator, graph.local_supremal, ((GVA_Node) { - graph.nodes[0].row + graph.nodes[0].length, graph.nodes[0].col + graph.nodes[0].length, len, GVA_NULL, 0 + graph.nodes[0].row + graph.nodes[0].length, graph.nodes[0].col + graph.nodes[0].length, 0, GVA_NULL, 0 })); - } // if + } //if - gva_uint min_source = GVA_NULL; - for (gva_uint i = graph.nodes[source.idx].edges; i != GVA_NULL; i = graph.edges[i].next) + if (graph.local_supremal != NULL) { - GVA_Variant variant; - gva_edges(graph.nodes[source.idx], graph.nodes[graph.edges[i].tail], true, false, &variant); - min_source = MIN(min_source, variant.start); - } // for - if (min_source != GVA_NULL) - { - graph.nodes[source.idx].row += min_source; - graph.nodes[source.idx].col += min_source; - graph.nodes[source.idx].length -= min_source; + graph.nodes[source.idx].row += graph.local_supremal[0].length; + graph.nodes[source.idx].col += graph.local_supremal[0].length; + graph.nodes[source.idx].length -= graph.local_supremal[0].length; + + graph.nodes[0].length -= len; } // if - else - { - graph.nodes[source.idx].length = 0; - } // else graph.source = source.idx; - table = allocator.allocate(allocator.context, table, sizeof(*table) * lcs.length, 0); + matches = allocator.allocate(allocator.context, matches, sizeof(*matches) * lcs.length, 0); lcs.index = allocator.allocate(allocator.context, lcs.index, lcs.length * sizeof(*lcs.index), 0); lcs.nodes = ARRAY_DESTROY(allocator, lcs.nodes); return graph; diff --git a/src/main.c b/src/main.c index 6455275..f887131 100644 --- a/src/main.c +++ b/src/main.c @@ -116,7 +116,7 @@ bfs_traversal(FILE* const stream, GVA_LCS_Graph const graph, head = table[head].next; } // while - fprintf(stream, "\n ]\n"); + fprintf(stream, "\n ],\n"); table = gva_std_allocator.allocate(gva_std_allocator.context, table, sizeof(*table) * array_length(graph.nodes), 0); } // bfs_traversal @@ -133,6 +133,28 @@ lcs_graph_json(FILE* const stream, GVA_LCS_Graph const graph, } // for fprintf(stream, " },\n"); bfs_traversal(stream, graph, len_obs, observed); + fprintf(stream, " \"local_supremal\": [\n"); + if (array_length(graph.local_supremal) > 1) + { + for (size_t i = 0; i < array_length(graph.local_supremal) - 1; ++i) + { + GVA_Variant variant; + gva_edges(graph.local_supremal[i], graph.local_supremal[i + 1], i == 0, i == array_length(graph.local_supremal) - 2, &variant); + fprintf(stream, " \"" GVA_VARIANT_FMT "\"%s\n", GVA_VARIANT_PRINT(variant, observed), i < array_length(graph.local_supremal) - 2 ? "," : ""); + } // for + } // if + fprintf(stream, " ],\n \"supremal\": "); + if (array_length(graph.local_supremal) > 1) + { + GVA_Variant variant; + gva_edges(graph.local_supremal[0], graph.local_supremal[array_length(graph.local_supremal) - 1], true, true, &variant); + fprintf(stream, "\"" GVA_VARIANT_FMT "\",\n", GVA_VARIANT_PRINT(variant, observed)); + } // if + else + { + fprintf(stream, "\"0:0/\",\n"); + } // else + fprintf(stream, " \"distance\": %u\n", graph.distance); fprintf(stream, "}\n"); } // lcs_graph_json @@ -142,7 +164,22 @@ lcs_graph_raw(FILE* const stream, GVA_LCS_Graph const graph, size_t const len_obs, char const observed[static len_obs]) { fprintf(stream, "#nodes: %zu\n#edges: %zu\n", array_length(graph.nodes), array_length(graph.edges)); + fprintf(stream, "distance: %u\n", graph.distance); fprintf(stream, "source: %u\n", graph.source); + fprintf(stream, "local supremal:\n"); + if (array_length(graph.local_supremal) > 1) + { + for (size_t i = 0; i < array_length(graph.local_supremal) - 1; ++i) + { + GVA_Variant variant; + gva_edges(graph.local_supremal[i], graph.local_supremal[i + 1], i == 0, i == array_length(graph.local_supremal) - 2, &variant); + fprintf(stream, " (%u, %u, %u) -> (%u, %u, %u): " GVA_VARIANT_FMT "\n", + graph.local_supremal[i].row, graph.local_supremal[i].col, graph.local_supremal[i].length, + graph.local_supremal[i + 1].row, graph.local_supremal[i + 1].col, graph.local_supremal[i + 1].length, + GVA_VARIANT_PRINT(variant, observed)); + } // for + } // if + if (graph.nodes == NULL) { return; @@ -187,8 +224,10 @@ main(int argc, char* argv[static argc + 1]) } // if */ - //char const* const restrict reference = "ATTCTATCTTCTGTCTACATAAGATGTCATACTAGAGGGCATATCTGCAATGTATACATATTATCTTTTCCAGCATGCATTCAGTTGTGTTGGAATAATTTATGTACACCTTTATAAACGCTGAGCCTCACAAGAGCCATGTGCCACGTATTGTTTTCTTACTACTTTTTGGGATACCTGGCACGTAATAGACACTCATTGAAAGTTTCCTAATGAATGAAGTACAAAGATAAAACAAGTTATAGACTGATTCTTTTGAGCTGTCAAGGTTGTAAATAGACTTTTGCTCAATCAATTCAAATGGTGGCAGGTAGTGGGGGTAGAGGGATTGGTATGAAAAACATAAGCTTTCAGAACTCCTGTGTTTATTTTTAGAATGTCAACTGCTTGAGTGTTTTTAACTCTGTGGTATCTGAACTATCTTCTCTAACTGCAGGTTGGGCTCAGATCTGTGATAGAACAGTTTCCTGGGAAGCTTGACTTTGTCCTTGTGGATGGGGGCTGTGTCCTAAGCCATGGCCACAAGCAGTTGATGTGCTTGGCTAGATCTGTTCTCAGTAAGGCGAAGATCTTGCTGCTTGATGAACCCAGTGCTCATTTGGATCCAGTGTGAGTTTCAGATGTTCTGTTACTTAATAGCACAGTGGGAACAGAATCATTATGCCTGCTTCATGGTGACACATATTTCTATTAGGCTGTCATGTCTGCGTGTGGGGGTCTCCCCCAAGATATGAAATAATTGCCCAGTGGAAATGAGCATAAATGCATATTTCCTTGCTAAGAGTCTTGTGTTTTCTTCCGAAGATAGTTTTTAGTTTCATACAAACTCTTCCCCCTTGTCAACACATGATGAAGCTTTTAAATACATGGGCCTAATCTGATCCTTATGATTTGCCTTTGTATCCCATTTATACCATAAGCATGTTTATAGCCCCAAATAAAGAAGTACTGGTGATTCTACATAATGAAAAATGTACTCATTTATTAAAGTTTCTTTGAAATATTTGTCCTGTTTATTTATGGATACTTAGAGTCTACCCCATGGTTGAAAAGCTGATTGTGGCTAACGCTATATCAACATTATGTGAAAAGAACTTAAAGAAATAAGTAATTTAAAGAGATAATAGAACAATAGACATATTATCAAGGTAAATACAGATCATTACTGTTCTGTGATATTATGTGTGGTATTTTCTTTCTTTTCTAGAACATACCAAATAATTAGAAGAACTCTAAAACAAGCATTTGCTGATTGCACAGTAATTCTCTGTGAACACAGGATAGAAGCAATGCTGGAATGCCAACAATTTTTGGTGAGTCTTTATAACTTTACTTAAGATCTCATTGCCCTTGTAATTCTTGATAACAATCTCACATGTGATAGTTCCTGCAAATTGCAACAATGTACAAGTTCTTTTCAAAAATATGTATCATACAGCCATCCAGCTTTACTCAAAATAGCTGCACAAGTTTTTCACTTTGATCTGAGCCATGTGGTGAGGTTGAAATATAGTAAATCTAAAATGGCAGCATATTACTAAGTTATGTTTATAAATAGGATATATATACTTTTTGAGCCCTTTATTTGGGGACCAAGTCATACAAAATACTCTACTGTTTAAGATTTTAAAAAAGGTCCCTGTGATTCTTTCAATAACTAAATGTCCCATGGATGTGGTCTGGGACAGGCCTAGTTGTCTTACAGTCTGATTTATGGTATTAATGACAAAGTTGAGAGGCACATTTCATTTTT"; - //char const* const restrict observed = "ATTCTATCTTCTGTCTACATAAGATGTCATACTAGAGGGCATATCTGCAATGTATACATATTATCTTTTCCAGCATGCATTCAGTTGTGTTGGAATAATTTATGTACACCTTTATAAACGCTGAGCCTCACAAGAGCCATGTGCCACGTATTGTTTTCTTACTACTTTTTGGGATACCTGGCACGTAATAGACACTCATTGAAAGTTTCCTAATGAATGAAGTACAAAGATAAAACAAGTTATAGACTGATTCTTTTGAGCTGTCAAGGTTGTAAATAGACTTTTGCTCAATCAATTCAAATGGTGGCAGGTAGTGGGGGTAGAGGGATTGGTATGAAAAACATAAGCTTTCAGAACTCCTGTGTTTATTTTTAGAATGTCAACTGCTTGAGTGTTTTTAACTCTGTGGTATCTGAACTATCTTCTCTAACTGCAGGTGAGTCTTTATAACTTTACTTAAGATCTCATTGCCCTTGTAATTCTTGATAACAATCTCACATGTGATAGTTCCTGCAAATTGCAACAATGTACAAGTTCTTTTCAAAAATATGTATCATACAGCCATCCAGCTTTACTCAAAATAGCTGCACAAGTTTTTCACTTTGATCTGAGCCATGTGGTGAGGTTGAAATATAGTAAATCTAAAATGGCAGCATATTACTAAGTTATGTTTATAAATAGGATATATATACTTTTTGAGCCCTTTATTTGGGGACCAAGTCATACAAAATACTCTACTGTTTAAGATTTTAAAAAAGGTCCCTGTGATTCTTTCAATAACTAAATGTCCCATGGATGTGGTCTGGGACAGGCCTAGTTGTCTTACAGTCTGATTTATGGTATTAATGACAAAGTTGAGAGGCACATTTCATTTTT"; + /* + char const* const restrict reference = "ATTCTATCTTCTGTCTACATAAGATGTCATACTAGAGGGCATATCTGCAATGTATACATATTATCTTTTCCAGCATGCATTCAGTTGTGTTGGAATAATTTATGTACACCTTTATAAACGCTGAGCCTCACAAGAGCCATGTGCCACGTATTGTTTTCTTACTACTTTTTGGGATACCTGGCACGTAATAGACACTCATTGAAAGTTTCCTAATGAATGAAGTACAAAGATAAAACAAGTTATAGACTGATTCTTTTGAGCTGTCAAGGTTGTAAATAGACTTTTGCTCAATCAATTCAAATGGTGGCAGGTAGTGGGGGTAGAGGGATTGGTATGAAAAACATAAGCTTTCAGAACTCCTGTGTTTATTTTTAGAATGTCAACTGCTTGAGTGTTTTTAACTCTGTGGTATCTGAACTATCTTCTCTAACTGCAGGTTGGGCTCAGATCTGTGATAGAACAGTTTCCTGGGAAGCTTGACTTTGTCCTTGTGGATGGGGGCTGTGTCCTAAGCCATGGCCACAAGCAGTTGATGTGCTTGGCTAGATCTGTTCTCAGTAAGGCGAAGATCTTGCTGCTTGATGAACCCAGTGCTCATTTGGATCCAGTGTGAGTTTCAGATGTTCTGTTACTTAATAGCACAGTGGGAACAGAATCATTATGCCTGCTTCATGGTGACACATATTTCTATTAGGCTGTCATGTCTGCGTGTGGGGGTCTCCCCCAAGATATGAAATAATTGCCCAGTGGAAATGAGCATAAATGCATATTTCCTTGCTAAGAGTCTTGTGTTTTCTTCCGAAGATAGTTTTTAGTTTCATACAAACTCTTCCCCCTTGTCAACACATGATGAAGCTTTTAAATACATGGGCCTAATCTGATCCTTATGATTTGCCTTTGTATCCCATTTATACCATAAGCATGTTTATAGCCCCAAATAAAGAAGTACTGGTGATTCTACATAATGAAAAATGTACTCATTTATTAAAGTTTCTTTGAAATATTTGTCCTGTTTATTTATGGATACTTAGAGTCTACCCCATGGTTGAAAAGCTGATTGTGGCTAACGCTATATCAACATTATGTGAAAAGAACTTAAAGAAATAAGTAATTTAAAGAGATAATAGAACAATAGACATATTATCAAGGTAAATACAGATCATTACTGTTCTGTGATATTATGTGTGGTATTTTCTTTCTTTTCTAGAACATACCAAATAATTAGAAGAACTCTAAAACAAGCATTTGCTGATTGCACAGTAATTCTCTGTGAACACAGGATAGAAGCAATGCTGGAATGCCAACAATTTTTGGTGAGTCTTTATAACTTTACTTAAGATCTCATTGCCCTTGTAATTCTTGATAACAATCTCACATGTGATAGTTCCTGCAAATTGCAACAATGTACAAGTTCTTTTCAAAAATATGTATCATACAGCCATCCAGCTTTACTCAAAATAGCTGCACAAGTTTTTCACTTTGATCTGAGCCATGTGGTGAGGTTGAAATATAGTAAATCTAAAATGGCAGCATATTACTAAGTTATGTTTATAAATAGGATATATATACTTTTTGAGCCCTTTATTTGGGGACCAAGTCATACAAAATACTCTACTGTTTAAGATTTTAAAAAAGGTCCCTGTGATTCTTTCAATAACTAAATGTCCCATGGATGTGGTCTGGGACAGGCCTAGTTGTCTTACAGTCTGATTTATGGTATTAATGACAAAGTTGAGAGGCACATTTCATTTTT"; + char const* const restrict observed = "ATTCTATCTTCTGTCTACATAAGATGTCATACTAGAGGGCATATCTGCAATGTATACATATTATCTTTTCCAGCATGCATTCAGTTGTGTTGGAATAATTTATGTACACCTTTATAAACGCTGAGCCTCACAAGAGCCATGTGCCACGTATTGTTTTCTTACTACTTTTTGGGATACCTGGCACGTAATAGACACTCATTGAAAGTTTCCTAATGAATGAAGTACAAAGATAAAACAAGTTATAGACTGATTCTTTTGAGCTGTCAAGGTTGTAAATAGACTTTTGCTCAATCAATTCAAATGGTGGCAGGTAGTGGGGGTAGAGGGATTGGTATGAAAAACATAAGCTTTCAGAACTCCTGTGTTTATTTTTAGAATGTCAACTGCTTGAGTGTTTTTAACTCTGTGGTATCTGAACTATCTTCTCTAACTGCAGGTGAGTCTTTATAACTTTACTTAAGATCTCATTGCCCTTGTAATTCTTGATAACAATCTCACATGTGATAGTTCCTGCAAATTGCAACAATGTACAAGTTCTTTTCAAAAATATGTATCATACAGCCATCCAGCTTTACTCAAAATAGCTGCACAAGTTTTTCACTTTGATCTGAGCCATGTGGTGAGGTTGAAATATAGTAAATCTAAAATGGCAGCATATTACTAAGTTATGTTTATAAATAGGATATATATACTTTTTGAGCCCTTTATTTGGGGACCAAGTCATACAAAATACTCTACTGTTTAAGATTTTAAAAAAGGTCCCTGTGATTCTTTCAATAACTAAATGTCCCATGGATGTGGTCTGGGACAGGCCTAGTTGTCTTACAGTCTGATTTATGGTATTAATGACAAAGTTGAGAGGCACATTTCATTTTT"; + */ char const* const restrict reference = argv[1]; char const* const restrict observed = argv[2]; @@ -201,23 +240,11 @@ main(int argc, char* argv[static argc + 1]) lcs_graph_dot(stderr, graph, len_obs, observed); lcs_graph_json(stdout, graph, len_obs, observed); - if (graph.local_supremal != NULL) - { - for (size_t i = 0; i < array_length(graph.local_supremal) - 1; ++i) - { - GVA_Variant variant; - gva_edges(graph.local_supremal[i], graph.local_supremal[i + 1], i == 0, i == array_length(graph.local_supremal) - 2, &variant); - fprintf(stderr, "(%u, %u, %u) -> (%u, %u, %u): " GVA_VARIANT_FMT "\n", - graph.local_supremal[i].row, graph.local_supremal[i].col, graph.local_supremal[i].length, - graph.local_supremal[i + 1].row, graph.local_supremal[i + 1].col, graph.local_supremal[i + 1].length, - GVA_VARIANT_PRINT(variant, observed)); - } // for - } // if - + /* size_t const distance = gva_edit_distance(gva_std_allocator, len_ref, reference, len_obs, observed); - fprintf(stderr, "distance: %zu\n", distance); - + fprintf(stderr, "distance only: %zu\n", distance); gva_lcs_graph_destroy(gva_std_allocator, graph); + */ return EXIT_SUCCESS; } // main diff --git a/test.py b/test.py index d96d6a3..e666eb3 100644 --- a/test.py +++ b/test.py @@ -96,7 +96,7 @@ def check(reference, observed, debug=True, timeout=2): print(f'\"{stdout}\"') raise exc - #assert str(graph.supremal) == cgraph["supremal"], f'supremals differ: {cgraph["supremal"]} vs {graph.supremal}' + assert str(graph.supremal) == cgraph["supremal"], f'supremals differ: {cgraph["supremal"]} vs {graph.supremal}' nodes = list(graph.nodes()) edges = list(graph.bfs_traversal()) @@ -118,10 +118,10 @@ def check(reference, observed, debug=True, timeout=2): except StopIteration: raise ValueError(f'{cedge} not in edges of {head}') from None - #assert len(cgraph["local_supremal"]) == len(local_supremal(reference, graph)), f'local supremal length' + assert len(cgraph["local_supremal"]) == len(local_supremal(reference, graph)), f'local supremal length' - #for lhs, rhs in zip(cgraph["local_supremal"], local_supremal(reference, graph)): - # assert lhs == str(rhs), f'local supremal elements differ: {lhs} vs {rhs}' + for lhs, rhs in zip(cgraph["local_supremal"], local_supremal(reference, graph)): + assert lhs == str(rhs), f'local supremal elements differ: {lhs} vs {rhs}' #if debug: # print(list(reversed(cgraph["canonical"])), canonical(graph)) From 8b996e3278e479a986c89888159a3ba5fdcb8f43 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 10 Jun 2025 13:12:12 +0200 Subject: [PATCH 227/704] Oops --- src/main.c | 3 ++- test.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main.c b/src/main.c index f887131..c7ea328 100644 --- a/src/main.c +++ b/src/main.c @@ -243,8 +243,9 @@ main(int argc, char* argv[static argc + 1]) /* size_t const distance = gva_edit_distance(gva_std_allocator, len_ref, reference, len_obs, observed); fprintf(stderr, "distance only: %zu\n", distance); - gva_lcs_graph_destroy(gva_std_allocator, graph); */ + gva_lcs_graph_destroy(gva_std_allocator, graph); + return EXIT_SUCCESS; } // main diff --git a/test.py b/test.py index e666eb3..547d71b 100644 --- a/test.py +++ b/test.py @@ -79,7 +79,7 @@ def str2var(desc): assert lhs == str(rhs), f'canonical elements differ: {lhs} vs {rhs}' -def check(reference, observed, debug=True, timeout=2): +def check(reference, observed, debug=False, timeout=2): #graph = LCSgraph.from_sequence(reference, observed) graph = LCSgraph(reference, observed) valgrind = [] From 2aa3239c2b42f3fb5926edaf07b5a056e0a82a5b Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 10 Jun 2025 14:30:13 +0200 Subject: [PATCH 228/704] WIP: extract --- include/extract.h | 17 ++++ src/extract.c | 212 ++++++++++++++++++++++++++++++++++++++++++++++ src/lcs_graph.c | 2 +- src/main.c | 3 + 4 files changed, 233 insertions(+), 1 deletion(-) create mode 100644 include/extract.h create mode 100644 src/extract.c diff --git a/include/extract.h b/include/extract.h new file mode 100644 index 0000000..7e8f3c9 --- /dev/null +++ b/include/extract.h @@ -0,0 +1,17 @@ +#ifndef GVA_EXTRACT_H +#define GVA_EXTRACT_H + + +#include // size_t + + +#include "allocator.h" // GVA_Allocator +#include "lcs_graph.h" // GVA_LCS_Graph + + +void +gva_extract(GVA_Allocator const allocator, + GVA_LCS_Graph const graph, size_t const len_obs, char const observed[static len_obs]); + + +#endif // GVA_EXTRACT_H diff --git a/src/extract.c b/src/extract.c new file mode 100644 index 0000000..888ddae --- /dev/null +++ b/src/extract.c @@ -0,0 +1,212 @@ +#include // NULL, size_t + + +#include // DEBUG +#include "../include/utils.h" // DEBUG + + +#include "../include/lcs_graph.h" // GVA_LCS_Graph, gva_edges +#include "array.h" // array_length +#include "common.h" // GVA_NULL, MAX, MIN, gva_uint + + +typedef struct +{ + gva_uint lca; + gva_uint rank; + gva_uint depth; + gva_uint start; + gva_uint end; + gva_uint prev; + gva_uint next; +} LCA_Table; + + +static void +print_lca_table(size_t const length, LCA_Table const visited[static length], gva_uint const head, gva_uint const tail) +{ + fprintf(stderr, " # \tlca\trank\tdepth\tstart\tend\tprev\tnext\n"); + for (gva_uint i = 0; i < length; ++i) + { + fprintf(stderr, "%2u:\t%3d\t%4d\t%5d\t%5d\t%3d\t%4d\t%4d\n", i, visited[i].lca, visited[i].rank, visited[i].depth, visited[i].start, visited[i].end, visited[i].prev, visited[i].next); + } // for + fprintf(stderr, "head: %d\ntail: %d\n", head, tail); +} // print_lca_table + + +static inline gva_uint +lca(gva_uint* const start, gva_uint lhs, gva_uint rhs, size_t const length, LCA_Table const visited[static length]) +{ + gva_uint lhs_start = *start; + gva_uint rhs_start = *start; + while (lhs != rhs) + { + fprintf(stderr, " lca %u (%d), %u (%d)\n", lhs, lhs_start, rhs, rhs_start); + + while (visited[lhs].rank > visited[rhs].rank) + { + fprintf(stderr, " left\n"); + lhs_start = visited[lhs].start; + lhs = visited[lhs].lca; + } // if + while (visited[rhs].rank > visited[lhs].rank) + { + fprintf(stderr, " right\n"); + rhs_start = visited[rhs].start; + rhs = visited[rhs].lca; + } // if + } // while + *start = MIN(lhs_start, rhs_start); + return lhs; +} // lca + + +void +gva_extract(GVA_Allocator const allocator, + GVA_LCS_Graph const graph, size_t const len_obs, char const observed[static len_obs]) +{ + gva_uint const length = array_length(graph.nodes); + LCA_Table* visited = allocator.allocate(allocator.context, NULL, 0, sizeof(*visited) * length); + if (visited == NULL) + { + return; + } // if + + for (gva_uint i = 0; i < length; ++i) + { + visited[i].depth = GVA_NULL; + visited[i].lca = GVA_NULL; + visited[i].rank = GVA_NULL; + visited[i].start = GVA_NULL; + visited[i].end = GVA_NULL; + visited[i].prev = GVA_NULL; + visited[i].next = GVA_NULL; + } // for + + gva_uint sink = GVA_NULL; + visited[graph.source] = (LCA_Table) {GVA_NULL, 0, 0, GVA_NULL, GVA_NULL, GVA_NULL, GVA_NULL}; + gva_uint rank = 1; + // main loop over a queue + for (gva_uint head = graph.source, tail = graph.source; head != GVA_NULL; head = visited[head].next) + { + fprintf(stderr, "pop %u @ %u\n", head, visited[head].depth); + + if (graph.nodes[head].edges == GVA_NULL) + { + fprintf(stderr, " sink\n"); + sink = head; + continue; + } // if + + gva_uint const lambda = graph.nodes[head].lambda; + if (lambda != GVA_NULL) + { + if (visited[lambda].depth == GVA_NULL) + { + // add lambda in stack order + fprintf(stderr, " push lambda %u @ %u\n", lambda, visited[head].depth); + + visited[visited[head].next].prev = lambda; + visited[lambda] = (LCA_Table) {head, rank, visited[head].depth, GVA_NULL, GVA_NULL, head, visited[head].next}; + rank += 1; + visited[head].next = lambda; + } // if + else if (visited[lambda].depth == visited[head].depth) + { + fprintf(stderr, " update lambda %u @ %u\n", lambda, visited[head].depth); + fprintf(stderr, " lca(%u, %u)\n", visited[lambda].lca, head); + visited[lambda].lca = lca(&visited[lambda].start, visited[lambda].lca, head, length, visited); + + // FIXME: what is correct here? + // AGGCCG CGCAGCCTC ignores the common end position + // ACAGGA CAAGGCG + // TAATTGGTAG CTATTCAG needs the common end position + // TTAAG TAACA + + //visited[lambda].end = graph.nodes[head].row; // this simulates the empty variant on a lambda edge + + fprintf(stderr, " = %u (%u:%u)\n", visited[lambda].lca, visited[lambda].start, visited[lambda].end); + } // if + else if (visited[head].next == lambda) + { + fprintf(stderr, " improve lambda in place %u @ %u\n", lambda, visited[head].depth); + visited[lambda] = (LCA_Table) {head, visited[lambda].rank, visited[head].depth, GVA_NULL, GVA_NULL, visited[lambda].prev, visited[lambda].next}; + } // if + else + { + fprintf(stderr, " improve lambda %u @ %u\n", lambda, visited[head].depth); + + if (lambda == tail) + { + tail = visited[lambda].prev; + } // if + else + { + visited[visited[lambda].next].prev = visited[lambda].prev; + } // else + visited[visited[head].next].prev = lambda; + visited[visited[lambda].prev].next = visited[lambda].next; + visited[lambda] = (LCA_Table) {head, visited[lambda].rank, visited[head].depth, GVA_NULL, GVA_NULL, head, visited[head].next}; + visited[head].next = lambda; + } // else + + //print_lca_table(length, visited, head, tail); + } // if + + for (gva_uint i = graph.nodes[head].edges; i != GVA_NULL; i = graph.edges[i].next) + { + gva_uint const edge_tail = graph.edges[i].tail; + if (visited[edge_tail].depth == GVA_NULL) + { + // add regular successors in queue order + fprintf(stderr, " push %u @ %u\n", edge_tail, visited[head].depth + 1); + GVA_Variant variant; + gva_uint const count = gva_edges(graph.nodes[head], graph.nodes[edge_tail], head == graph.source, edge_tail == 0, &variant); + visited[edge_tail] = (LCA_Table) {head, rank, visited[head].depth + 1, variant.start, variant.end + count - 1, tail, GVA_NULL}; + rank += 1; + visited[tail].next = edge_tail; + tail = edge_tail; + } // if + else if (visited[edge_tail].depth - 1 == visited[head].depth) + { + fprintf(stderr, " update %u @ %u\n", edge_tail, visited[edge_tail].depth); + fprintf(stderr, " lca(%u, %u)\n", visited[edge_tail].lca, head); + GVA_Variant variant; + gva_uint const count = gva_edges(graph.nodes[head], graph.nodes[edge_tail], head == graph.source, edge_tail == 0, &variant); + visited[edge_tail].start = MIN(visited[edge_tail].start, variant.start); + visited[edge_tail].lca = lca(&visited[edge_tail].start, visited[edge_tail].lca, head, length, visited); + visited[edge_tail].end = MAX(visited[edge_tail].end, variant.end + count - 1); + fprintf(stderr, " = %u (%u:%u)\n", visited[edge_tail].lca, visited[edge_tail].start, visited[edge_tail].end); + } // if + else + { + fprintf(stderr, " skip %u @ %u\n", edge_tail, visited[edge_tail].depth); + } // else + + //print_lca_table(length, visited, head, tail); + } // for + } // for + + print_lca_table(length, visited, GVA_NULL, GVA_NULL); + + // the canonical variant is given in the reverse order (for now): the Python checker needs to reverse this list + for (gva_uint tail = sink; tail != GVA_NULL; tail = visited[tail].lca) + { + gva_uint const head = visited[tail].lca; + if (head != GVA_NULL && visited[tail].start != GVA_NULL) + { + // we need to skip lambda edges: start && end == -1 + gva_uint const start_offset = visited[tail].start - graph.nodes[head].row; + gva_uint const end_offset = visited[tail].end - graph.nodes[tail].row; + GVA_Variant const variant = {visited[tail].start, visited[tail].end, graph.nodes[head].col + start_offset, graph.nodes[tail].col + end_offset}; + + if (tail != sink) + { + fprintf(stderr, ",\n"); + } // if + fprintf(stderr, " \"" GVA_VARIANT_FMT "\"", GVA_VARIANT_PRINT(variant, observed)); + } // if + } // while + + visited = allocator.allocate(allocator.context, visited, sizeof(*visited) * length, 0); +} // gva_extract diff --git a/src/lcs_graph.c b/src/lcs_graph.c index 4c20f04..56e96ff 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -7,7 +7,7 @@ #include "../include/lcs_graph.h" // GVA_LCS_Graph, GVA_Variant, gva_lcs_graph_* #include "align.h" // LCS_Alignment, lcs_align #include "array.h" // ARRAY_*, array_length -#include "common.h" // gva_uint, MAX, MIN +#include "common.h" // GVA_NULL, gva_uint, MAX, MIN gva_uint diff --git a/src/main.c b/src/main.c index c7ea328..b9b8af8 100644 --- a/src/main.c +++ b/src/main.c @@ -5,6 +5,7 @@ #include "../include/edit.h" // gva_edit_distance +#include "../include/extract.h" // gva_extract #include "../include/lcs_graph.h" // GVA_LCS_Graph, GVA_Variant, gva_lcs_graph_*, gva_edges #include "../include/std_alloc.h" // gva_std_allocator #include "../include/types.h" // GVA_NULL, gva_uint @@ -240,6 +241,8 @@ main(int argc, char* argv[static argc + 1]) lcs_graph_dot(stderr, graph, len_obs, observed); lcs_graph_json(stdout, graph, len_obs, observed); + gva_extract(gva_std_allocator, graph, len_obs, observed); + /* size_t const distance = gva_edit_distance(gva_std_allocator, len_ref, reference, len_obs, observed); fprintf(stderr, "distance only: %zu\n", distance); From 02d15ff6707db6ec075053c421219c428c6c4a86 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 10 Jun 2025 17:23:03 +0200 Subject: [PATCH 229/704] Also test distances --- test.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test.py b/test.py index 547d71b..4e48749 100644 --- a/test.py +++ b/test.py @@ -96,7 +96,8 @@ def check(reference, observed, debug=False, timeout=2): print(f'\"{stdout}\"') raise exc - assert str(graph.supremal) == cgraph["supremal"], f'supremals differ: {cgraph["supremal"]} vs {graph.supremal}' + assert cgraph["distance"] == graph.distance, f'disances differ: {cgraph["distance"]} vs {graph.distance}' + assert cgraph["supremal"] == str(graph.supremal), f'supremals differ: {cgraph["supremal"]} vs {graph.supremal}' nodes = list(graph.nodes()) edges = list(graph.bfs_traversal()) From 5eaf81f3159e6c53ecaa3d6fcd6660d218528258 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Wed, 11 Jun 2025 12:02:27 +0200 Subject: [PATCH 230/704] Guard expression and add example from paper. --- regres.sh | 2 ++ src/array.h | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/regres.sh b/regres.sh index ad66dcd..13eed01 100755 --- a/regres.sh +++ b/regres.sh @@ -54,6 +54,8 @@ TCTC TC TTGTA TTTGTGTT AA ACA ACA AA +# paper +ACCTGACT ATCTTACTT ) for ((i=0; i<${#TESTS[@]}; i+=2)); do diff --git a/src/array.h b/src/array.h index 5a2803d..635ff0f 100644 --- a/src/array.h +++ b/src/array.h @@ -68,7 +68,7 @@ array_ensure_one(GVA_Allocator const allocator, void* const self, // array. 0 if (re)allocation failed. // Warning: `self` is evaluated multiple times. #define ARRAY_APPEND(allocator, self, value) ( \ - (self) = array_ensure_one(allocator, self, sizeof(*(self))), \ + (self) = array_ensure_one(allocator, (self), sizeof(*(self))), \ (self) == NULL ? 0 : ( \ (self)[array_header(self)->length] = (value), \ array_header(self)->length += 1 \ From e78a07fd5a55b74ac28291b6a48357121776283e Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 11 Jun 2025 17:29:09 +0200 Subject: [PATCH 231/704] More tests --- regres.sh | 6 +++++- src/extract.c | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/regres.sh b/regres.sh index 13eed01..fbaba9b 100755 --- a/regres.sh +++ b/regres.sh @@ -30,7 +30,7 @@ CTGGGGAG CCACCTGGGC CATTTCACGA TCGCCC GCC CGACGAGCCC AGAGAAAAA AAAA -#from algebra +# Python algebra "" "" "" C C "" @@ -54,6 +54,10 @@ TCTC TC TTGTA TTTGTGTT AA ACA ACA AA +AGGCCG CGCAGCCTC +ACAGGA CAAGGCG +TAATTGGTAG CTATTCAG +TTAAG TAACA # paper ACCTGACT ATCTTACTT ) diff --git a/src/extract.c b/src/extract.c index 888ddae..123bd2d 100644 --- a/src/extract.c +++ b/src/extract.c @@ -198,7 +198,7 @@ gva_extract(GVA_Allocator const allocator, // we need to skip lambda edges: start && end == -1 gva_uint const start_offset = visited[tail].start - graph.nodes[head].row; gva_uint const end_offset = visited[tail].end - graph.nodes[tail].row; - GVA_Variant const variant = {visited[tail].start, visited[tail].end, graph.nodes[head].col + start_offset, graph.nodes[tail].col + end_offset}; + GVA_Variant const variant = {visited[tail].start, visited[tail].end, graph.nodes[head].col + start_offset, graph.nodes[tail].col + end_offset}; if (tail != sink) { From 4e643d80f23891a30f45079a9ba53e7ceefe737c Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 11 Jun 2025 22:33:40 +0200 Subject: [PATCH 232/704] String pointer in variant class --- include/extract.h | 3 +- include/lcs_graph.h | 23 +++++++-------- include/types.h | 11 ++++++++ include/utils.h | 12 +------- src/extract.c | 18 +++++++----- src/lcs_graph.c | 11 +++++--- src/main.c | 69 +++++++++++++++++++++++++-------------------- src/utils.c | 8 +++--- 8 files changed, 85 insertions(+), 70 deletions(-) diff --git a/include/extract.h b/include/extract.h index 7e8f3c9..31a7164 100644 --- a/include/extract.h +++ b/include/extract.h @@ -10,8 +10,7 @@ void -gva_extract(GVA_Allocator const allocator, - GVA_LCS_Graph const graph, size_t const len_obs, char const observed[static len_obs]); +gva_extract(GVA_Allocator const allocator, GVA_LCS_Graph const graph); #endif // GVA_EXTRACT_H diff --git a/include/lcs_graph.h b/include/lcs_graph.h index f884923..328d710 100644 --- a/include/lcs_graph.h +++ b/include/lcs_graph.h @@ -6,7 +6,7 @@ #include // size_t #include "allocator.h" // GVA_Allocator -#include "types.h" // gva_uint +#include "types.h" // GVA_String, gva_uint // Internal: Each edge tracks its tail as an index to a node (in the @@ -37,20 +37,20 @@ typedef struct // entry point in the `nodes` array. typedef struct { - GVA_Node* nodes; - GVA_Edge* edges; - GVA_Node* local_supremal; - gva_uint source; - gva_uint distance; + GVA_String observed; + GVA_Node* nodes; + GVA_Edge* edges; + GVA_Node* local_supremal; + gva_uint source; + gva_uint distance; } GVA_LCS_Graph; typedef struct { - gva_uint start; - gva_uint end; - gva_uint obs_start; - gva_uint obs_end; + gva_uint start; + gva_uint end; + GVA_String sequence; } GVA_Variant; @@ -66,7 +66,8 @@ gva_lcs_graph_destroy(GVA_Allocator const allocator, GVA_LCS_Graph self); gva_uint -gva_edges(GVA_Node const head, GVA_Node const tail, +gva_edges(char const* const restrict observed, + GVA_Node const head, GVA_Node const tail, bool const is_source, bool const is_sink, GVA_Variant* const variant); diff --git a/include/types.h b/include/types.h index 643c0cf..4c8683c 100644 --- a/include/types.h +++ b/include/types.h @@ -5,6 +5,10 @@ #include // uint32_t, UINT32_MAX +#define GVA_VARIANT_PRINT(variant) variant.start, variant.end, (int) variant.sequence.len, variant.sequence.str +#define GVA_VARIANT_FMT "%u:%u/%.*s" + + // An unsigned integer type to store any position on a reference // sequence. For human DNA a 32-bit value is enough. // Smaller integer types reduce storage requirements. @@ -15,4 +19,11 @@ typedef uint32_t gva_uint; static gva_uint const GVA_NULL = UINT32_MAX; +typedef struct +{ + char const* str; + gva_uint len; +} GVA_String; + + #endif // GVA_TYPES_H diff --git a/include/utils.h b/include/utils.h index 4c2af0f..d1b087d 100644 --- a/include/utils.h +++ b/include/utils.h @@ -8,17 +8,7 @@ #include "allocator.h" // GVA_Allocator - - -#define GVA_VARIANT_PRINT(variant, observed) variant.start, variant.end, (int) variant.obs_end - variant.obs_start, observed + variant.obs_start -#define GVA_VARIANT_FMT "%u:%u/%.*s" - - -typedef struct -{ - size_t len; - char* str; -} GVA_String; +#include "types.h" // GVA_String GVA_String diff --git a/src/extract.c b/src/extract.c index 123bd2d..02706ec 100644 --- a/src/extract.c +++ b/src/extract.c @@ -7,7 +7,7 @@ #include "../include/lcs_graph.h" // GVA_LCS_Graph, gva_edges #include "array.h" // array_length -#include "common.h" // GVA_NULL, MAX, MIN, gva_uint +#include "common.h" // GVA_NULL, MAX, MIN, GVA_String, gva_uint typedef struct @@ -62,8 +62,7 @@ lca(gva_uint* const start, gva_uint lhs, gva_uint rhs, size_t const length, LCA_ void -gva_extract(GVA_Allocator const allocator, - GVA_LCS_Graph const graph, size_t const len_obs, char const observed[static len_obs]) +gva_extract(GVA_Allocator const allocator, GVA_LCS_Graph const graph) { gva_uint const length = array_length(graph.nodes); LCA_Table* visited = allocator.allocate(allocator.context, NULL, 0, sizeof(*visited) * length); @@ -161,7 +160,7 @@ gva_extract(GVA_Allocator const allocator, // add regular successors in queue order fprintf(stderr, " push %u @ %u\n", edge_tail, visited[head].depth + 1); GVA_Variant variant; - gva_uint const count = gva_edges(graph.nodes[head], graph.nodes[edge_tail], head == graph.source, edge_tail == 0, &variant); + gva_uint const count = gva_edges(graph.observed.str, graph.nodes[head], graph.nodes[edge_tail], head == graph.source, edge_tail == 0, &variant); visited[edge_tail] = (LCA_Table) {head, rank, visited[head].depth + 1, variant.start, variant.end + count - 1, tail, GVA_NULL}; rank += 1; visited[tail].next = edge_tail; @@ -172,7 +171,7 @@ gva_extract(GVA_Allocator const allocator, fprintf(stderr, " update %u @ %u\n", edge_tail, visited[edge_tail].depth); fprintf(stderr, " lca(%u, %u)\n", visited[edge_tail].lca, head); GVA_Variant variant; - gva_uint const count = gva_edges(graph.nodes[head], graph.nodes[edge_tail], head == graph.source, edge_tail == 0, &variant); + gva_uint const count = gva_edges(graph.observed.str, graph.nodes[head], graph.nodes[edge_tail], head == graph.source, edge_tail == 0, &variant); visited[edge_tail].start = MIN(visited[edge_tail].start, variant.start); visited[edge_tail].lca = lca(&visited[edge_tail].start, visited[edge_tail].lca, head, length, visited); visited[edge_tail].end = MAX(visited[edge_tail].end, variant.end + count - 1); @@ -198,13 +197,18 @@ gva_extract(GVA_Allocator const allocator, // we need to skip lambda edges: start && end == -1 gva_uint const start_offset = visited[tail].start - graph.nodes[head].row; gva_uint const end_offset = visited[tail].end - graph.nodes[tail].row; - GVA_Variant const variant = {visited[tail].start, visited[tail].end, graph.nodes[head].col + start_offset, graph.nodes[tail].col + end_offset}; + GVA_Variant const variant = { + visited[tail].start, visited[tail].end, { + graph.observed.str + graph.nodes[head].col + start_offset, + (graph.nodes[tail].col + end_offset) - (graph.nodes[head].col + start_offset) + } + }; if (tail != sink) { fprintf(stderr, ",\n"); } // if - fprintf(stderr, " \"" GVA_VARIANT_FMT "\"", GVA_VARIANT_PRINT(variant, observed)); + fprintf(stderr, " \"" GVA_VARIANT_FMT "\"", GVA_VARIANT_PRINT(variant)); } // if } // while diff --git a/src/lcs_graph.c b/src/lcs_graph.c index 56e96ff..4384028 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -11,7 +11,8 @@ gva_uint -gva_edges(GVA_Node const head, GVA_Node const tail, +gva_edges(char const* const restrict observed, + GVA_Node const head, GVA_Node const tail, bool const is_source, bool const is_sink, GVA_Variant* const variant) { @@ -26,8 +27,10 @@ gva_edges(GVA_Node const head, GVA_Node const tail, gva_uint const tail_offset = offset < 0 ? MIN(tail_length, -offset) : 0; *variant = (GVA_Variant) { - row + head_offset, tail.row + tail_offset, - col + head_offset, tail.col + tail_offset + row + head_offset, tail.row + tail_offset, { + observed + col + head_offset, + (tail.col + tail_offset) - (col + head_offset) + } }; return MIN(head_length - head_offset, tail_length - tail_offset - 1) + 1; } // gva_edges @@ -41,7 +44,7 @@ gva_lcs_graph_init(GVA_Allocator const allocator, { LCS_Alignment lcs = lcs_align(allocator, len_ref, reference, len_obs, observed); - GVA_LCS_Graph graph = {NULL, NULL, NULL, GVA_NULL, len_ref + len_obs - 2 * lcs.length}; + GVA_LCS_Graph graph = {{observed, len_obs}, NULL, NULL, NULL, GVA_NULL, len_ref + len_obs - 2 * lcs.length}; if (lcs.nodes == NULL || graph.distance == 0) { diff --git a/src/main.c b/src/main.c index b9b8af8..1a408c0 100644 --- a/src/main.c +++ b/src/main.c @@ -8,14 +8,13 @@ #include "../include/extract.h" // gva_extract #include "../include/lcs_graph.h" // GVA_LCS_Graph, GVA_Variant, gva_lcs_graph_*, gva_edges #include "../include/std_alloc.h" // gva_std_allocator -#include "../include/types.h" // GVA_NULL, gva_uint -#include "../include/utils.h" // GVA_String, gva_fasta_sequence, GVA_VARIANT_* +#include "../include/types.h" // GVA_NULL, GVA_String, gva_uint +#include "../include/utils.h" // gva_fasta_sequence, GVA_VARIANT_* #include "array.h" // array_length static void -lcs_graph_dot(FILE* const stream, GVA_LCS_Graph const graph, - size_t const len_obs, char const observed[static len_obs]) +lcs_graph_dot(FILE* const stream, GVA_LCS_Graph const graph) { fprintf(stream, "strict digraph{\nrankdir=LR\nedge[fontname=monospace]\nnode[fixedsize=true,fontname=serif,shape=circle,width=1]\ni[label=\"\",shape=none,width=0]\ni->%u\n", graph.source); for (size_t i = 0; i < array_length(graph.nodes); ++i) @@ -28,16 +27,17 @@ lcs_graph_dot(FILE* const stream, GVA_LCS_Graph const graph, for (gva_uint j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) { GVA_Variant variant; - gva_uint const count = gva_edges(graph.nodes[i], graph.nodes[graph.edges[j].tail], + gva_uint const count = gva_edges(graph.observed.str, + graph.nodes[i], graph.nodes[graph.edges[j].tail], i == graph.source, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, &variant); if (count > 1) { - fprintf(stream, "%zu->%u[label=\"" GVA_VARIANT_FMT " x %u\",penwidth=2]\n", i, graph.edges[j].tail, GVA_VARIANT_PRINT(variant, observed), count); + fprintf(stream, "%zu->%u[label=\"" GVA_VARIANT_FMT " x %u\",penwidth=2]\n", i, graph.edges[j].tail, GVA_VARIANT_PRINT(variant), count); } // if else { - fprintf(stream, "%zu->%u[label=\"" GVA_VARIANT_FMT "\"]\n", i, graph.edges[j].tail, GVA_VARIANT_PRINT(variant, observed)); + fprintf(stream, "%zu->%u[label=\"" GVA_VARIANT_FMT "\"]\n", i, graph.edges[j].tail, GVA_VARIANT_PRINT(variant)); } // else } // for } // for @@ -50,8 +50,7 @@ lcs_graph_dot(FILE* const stream, GVA_LCS_Graph const graph, static void -bfs_traversal(FILE* const stream, GVA_LCS_Graph const graph, - size_t const len_obs, char const observed[static len_obs]) +bfs_traversal(FILE* const stream, GVA_LCS_Graph const graph) { struct { @@ -86,7 +85,8 @@ bfs_traversal(FILE* const stream, GVA_LCS_Graph const graph, for (gva_uint j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) { GVA_Variant variant; - gva_uint const count = gva_edges(graph.nodes[i], graph.nodes[graph.edges[j].tail], + gva_uint const count = gva_edges(graph.observed.str, + graph.nodes[i], graph.nodes[graph.edges[j].tail], i == graph.source, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, &variant); @@ -97,11 +97,10 @@ bfs_traversal(FILE* const stream, GVA_LCS_Graph const graph, printf(",\n"); } // if first = false; - fprintf(stream, " {\"head\": \"s%u\", \"tail\": \"s%u\", \"variant\": \"" GVA_VARIANT_FMT "\"}", head, graph.edges[j].tail, GVA_VARIANT_PRINT(variant, observed)); + fprintf(stream, " {\"head\": \"s%u\", \"tail\": \"s%u\", \"variant\": \"" GVA_VARIANT_FMT "\"}", head, graph.edges[j].tail, GVA_VARIANT_PRINT(variant)); variant.start += 1; variant.end += 1; - variant.obs_start += 1; - variant.obs_end += 1; + variant.sequence.str += 1; } // for if (table[graph.edges[j].tail].depth > 0) @@ -124,8 +123,7 @@ bfs_traversal(FILE* const stream, GVA_LCS_Graph const graph, static void -lcs_graph_json(FILE* const stream, GVA_LCS_Graph const graph, - size_t const len_obs, char const observed[static len_obs]) +lcs_graph_json(FILE* const stream, GVA_LCS_Graph const graph) { fprintf(stream, "{\n \"source\": \"s%u\",\n \"nodes\": {\n", graph.source); for (gva_uint i = 0; i < array_length(graph.nodes); ++i) @@ -133,23 +131,29 @@ lcs_graph_json(FILE* const stream, GVA_LCS_Graph const graph, fprintf(stream, " \"s%u\": {\"row\": %u, \"col\": %u, \"length\": %u}%s\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, i < array_length(graph.nodes) - 1 ? "," : ""); } // for fprintf(stream, " },\n"); - bfs_traversal(stream, graph, len_obs, observed); + bfs_traversal(stream, graph); fprintf(stream, " \"local_supremal\": [\n"); if (array_length(graph.local_supremal) > 1) { for (size_t i = 0; i < array_length(graph.local_supremal) - 1; ++i) { GVA_Variant variant; - gva_edges(graph.local_supremal[i], graph.local_supremal[i + 1], i == 0, i == array_length(graph.local_supremal) - 2, &variant); - fprintf(stream, " \"" GVA_VARIANT_FMT "\"%s\n", GVA_VARIANT_PRINT(variant, observed), i < array_length(graph.local_supremal) - 2 ? "," : ""); + gva_edges(graph.observed.str, + graph.local_supremal[i], graph.local_supremal[i + 1], + i == 0, i == array_length(graph.local_supremal) - 2, + &variant); + fprintf(stream, " \"" GVA_VARIANT_FMT "\"%s\n", GVA_VARIANT_PRINT(variant), i < array_length(graph.local_supremal) - 2 ? "," : ""); } // for } // if fprintf(stream, " ],\n \"supremal\": "); if (array_length(graph.local_supremal) > 1) { GVA_Variant variant; - gva_edges(graph.local_supremal[0], graph.local_supremal[array_length(graph.local_supremal) - 1], true, true, &variant); - fprintf(stream, "\"" GVA_VARIANT_FMT "\",\n", GVA_VARIANT_PRINT(variant, observed)); + gva_edges(graph.observed.str, + graph.local_supremal[0], graph.local_supremal[array_length(graph.local_supremal) - 1], + true, true, + &variant); + fprintf(stream, "\"" GVA_VARIANT_FMT "\",\n", GVA_VARIANT_PRINT(variant)); } // if else { @@ -161,8 +165,7 @@ lcs_graph_json(FILE* const stream, GVA_LCS_Graph const graph, static void -lcs_graph_raw(FILE* const stream, GVA_LCS_Graph const graph, - size_t const len_obs, char const observed[static len_obs]) +lcs_graph_raw(FILE* const stream, GVA_LCS_Graph const graph) { fprintf(stream, "#nodes: %zu\n#edges: %zu\n", array_length(graph.nodes), array_length(graph.edges)); fprintf(stream, "distance: %u\n", graph.distance); @@ -173,11 +176,14 @@ lcs_graph_raw(FILE* const stream, GVA_LCS_Graph const graph, for (size_t i = 0; i < array_length(graph.local_supremal) - 1; ++i) { GVA_Variant variant; - gva_edges(graph.local_supremal[i], graph.local_supremal[i + 1], i == 0, i == array_length(graph.local_supremal) - 2, &variant); + gva_edges(graph.observed.str, + graph.local_supremal[i], graph.local_supremal[i + 1], + i == 0, i == array_length(graph.local_supremal) - 2, + &variant); fprintf(stream, " (%u, %u, %u) -> (%u, %u, %u): " GVA_VARIANT_FMT "\n", graph.local_supremal[i].row, graph.local_supremal[i].col, graph.local_supremal[i].length, graph.local_supremal[i + 1].row, graph.local_supremal[i + 1].col, graph.local_supremal[i + 1].length, - GVA_VARIANT_PRINT(variant, observed)); + GVA_VARIANT_PRINT(variant)); } // for } // if @@ -197,10 +203,11 @@ lcs_graph_raw(FILE* const stream, GVA_LCS_Graph const graph, { fprintf(stream, " %u: (%u, %u, %u): ", graph.edges[j].tail, graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length); GVA_Variant variant; - gva_uint const count = gva_edges(graph.nodes[i], graph.nodes[graph.edges[j].tail], + gva_uint const count = gva_edges(graph.observed.str, + graph.nodes[i], graph.nodes[graph.edges[j].tail], i == graph.source, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, &variant); - fprintf(stream, GVA_VARIANT_FMT " x %u\n", GVA_VARIANT_PRINT(variant, observed), count); + fprintf(stream, GVA_VARIANT_FMT " x %u\n", GVA_VARIANT_PRINT(variant), count); } // for } // for } // lcs_graph_raw @@ -220,7 +227,7 @@ main(int argc, char* argv[static argc + 1]) if (stream != NULL) { GVA_String seq = gva_fasta_sequence(gva_std_allocator, stream); - gva_std_allocator.allocate(gva_std_allocator.context, seq.str, seq.len, 0); + gva_std_allocator.allocate(gva_std_allocator.context, (char*) seq.str, seq.len, 0); fclose(stream); } // if */ @@ -237,11 +244,11 @@ main(int argc, char* argv[static argc + 1]) GVA_LCS_Graph graph = gva_lcs_graph_init(gva_std_allocator, len_ref, reference, len_obs, observed, 0); - lcs_graph_raw(stderr, graph, len_obs, observed); - lcs_graph_dot(stderr, graph, len_obs, observed); - lcs_graph_json(stdout, graph, len_obs, observed); + lcs_graph_raw(stderr, graph); + lcs_graph_dot(stderr, graph); + lcs_graph_json(stdout, graph); - gva_extract(gva_std_allocator, graph, len_obs, observed); + gva_extract(gva_std_allocator, graph); /* size_t const distance = gva_edit_distance(gva_std_allocator, len_ref, reference, len_obs, observed); diff --git a/src/utils.c b/src/utils.c index ac44fe0..9282b19 100644 --- a/src/utils.c +++ b/src/utils.c @@ -13,13 +13,13 @@ gva_fasta_sequence(GVA_Allocator const allocator, FILE* const restrict stream) { static size_t const FASTA_LINE_SIZE = 65536; size_t capacity = FASTA_LINE_SIZE; - GVA_String seq = {0, allocator.allocate(allocator.context, NULL, 0, capacity)}; + GVA_String seq = {allocator.allocate(allocator.context, NULL, 0, capacity), 0}; if (seq.str == NULL) { return seq; } // if - while (fgets(seq.str + seq.len, FASTA_LINE_SIZE, stream) != NULL) + while (fgets((char*) seq.str + seq.len, FASTA_LINE_SIZE, stream) != NULL) { if (seq.str[seq.len] == '>') { @@ -33,7 +33,7 @@ gva_fasta_sequence(GVA_Allocator const allocator, FILE* const restrict stream) if (capacity - FASTA_LINE_SIZE < seq.len) { - seq.str = allocator.allocate(allocator.context, seq.str, capacity, capacity + FASTA_LINE_SIZE); + seq.str = allocator.allocate(allocator.context, (char*) seq.str, capacity, capacity + FASTA_LINE_SIZE); if (seq.str == NULL) { seq.len = 0; @@ -42,6 +42,6 @@ gva_fasta_sequence(GVA_Allocator const allocator, FILE* const restrict stream) capacity += FASTA_LINE_SIZE; } // if } // while - seq.str = allocator.allocate(allocator.context, seq.str, capacity, seq.len); + seq.str = allocator.allocate(allocator.context, (char*) seq.str, capacity, seq.len); return seq; } // gva_fasta_sequence From 3af9bf9ab7636cf1217c59c56cf71d7c24acd800 Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 11 Jun 2025 22:48:14 +0200 Subject: [PATCH 233/704] Refactored lcs index data structure --- src/align.c | 1 + src/align.h | 2 ++ src/lcs_graph.c | 43 +++++++++++++++---------------------------- 3 files changed, 18 insertions(+), 28 deletions(-) diff --git a/src/align.c b/src/align.c index 20b7911..4de7037 100644 --- a/src/align.c +++ b/src/align.c @@ -177,6 +177,7 @@ lcs_align(GVA_Allocator const allocator, { lcs.index[i].head = GVA_NULL; lcs.index[i].tail = GVA_NULL; + lcs.index[i].count = 0; } // for size_t const lower = delta > 0 ? 0 : delta; diff --git a/src/align.h b/src/align.h index b8567b4..4e671fe 100644 --- a/src/align.h +++ b/src/align.h @@ -27,6 +27,8 @@ typedef struct { gva_uint head; gva_uint tail; + gva_uint count; + gva_uint offset; }* index; LCS_Node* nodes; } LCS_Alignment; diff --git a/src/lcs_graph.c b/src/lcs_graph.c index 4384028..59264ab 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -81,18 +81,6 @@ gva_lcs_graph_init(GVA_Allocator const allocator, return graph; } // if - struct - { - gva_uint count; - gva_uint idx; - gva_uint offset; - }* matches = allocator.allocate(allocator.context, NULL, 0, sizeof(*matches) * lcs.length); - - for (gva_uint i = 0; i < lcs.length; ++i) - { - matches[i].count = 0; - } // for - gva_uint tail_idx = lcs.index[lcs.length - 1].tail; LCS_Node sink = lcs.nodes[tail_idx]; if (sink.row + sink.length == len_ref + shift && sink.col + sink.length == len_obs + shift) @@ -132,9 +120,9 @@ gva_lcs_graph_init(GVA_Allocator const allocator, continue; } // if - matches[i].count += 1; - matches[i].idx = j; - matches[i].offset = graph.nodes[tail->idx].length - tail->length; + lcs.index[i].tail = j; + lcs.index[i].count += 1; + lcs.index[i].offset = graph.nodes[tail->idx].length - tail->length; gva_uint here = GVA_NULL; for (gva_uint k = lcs.index[i - 1].head; k != GVA_NULL; k = lcs.nodes[k].next) @@ -203,9 +191,9 @@ gva_lcs_graph_init(GVA_Allocator const allocator, LCS_Node source = lcs.nodes[head_idx]; if (source.row == shift && source.col == shift) { - matches[0].count += 1; - matches[0].idx = head_idx; - matches[0].offset = graph.nodes[source.idx].length - source.length; + lcs.index[0].tail = head_idx; + lcs.index[0].count += 1; + lcs.index[0].offset = graph.nodes[source.idx].length - source.length; head_idx = source.next; } // if @@ -223,9 +211,9 @@ gva_lcs_graph_init(GVA_Allocator const allocator, continue; } // if - matches[0].count += 1; - matches[0].idx = i; - matches[0].offset = graph.nodes[lcs.nodes[i].idx].length - lcs.nodes[i].length; + lcs.index[0].tail = i; + lcs.index[0].count += 1; + lcs.index[0].offset = graph.nodes[lcs.nodes[i].idx].length - lcs.nodes[i].length; if (source.length == 0 || !lcs.nodes[i].moved) { @@ -239,32 +227,32 @@ gva_lcs_graph_init(GVA_Allocator const allocator, gva_uint prev = GVA_NULL; for (gva_uint i = 0; i < lcs.length; ++i) { - if (prev == GVA_NULL && lcs.nodes[matches[i].idx].idx != source.idx) + if (prev == GVA_NULL && lcs.nodes[lcs.index[i].tail].idx != source.idx) { ARRAY_APPEND(allocator, graph.local_supremal, ((GVA_Node) { graph.nodes[source.idx].row + len, graph.nodes[source.idx].col + len, 0, GVA_NULL, source.idx })); } // if - if (len > 0 && (matches[i].count > 1 || prev != matches[i].idx)) + if (len > 0 && (lcs.index[i].count > 1 || prev != lcs.index[i].tail)) { gva_uint const idx = lcs.nodes[prev].idx; - gva_uint const offset = graph.nodes[idx].length - matches[i - 1].offset - len; + gva_uint const offset = graph.nodes[idx].length - lcs.index[i - 1].offset - len; ARRAY_APPEND(allocator, graph.local_supremal, ((GVA_Node) { graph.nodes[idx].row + offset, graph.nodes[idx].col + offset, len, GVA_NULL, idx })); len = 0; } // if - if (matches[i].count == 1) + if (lcs.index[i].count == 1) { len += 1; } // if - prev = matches[i].idx; + prev = lcs.index[i].tail; } // for if (len > 0) { gva_uint const idx = lcs.nodes[prev].idx; - gva_uint const offset = graph.nodes[idx].length - matches[lcs.length - 1].offset - len; + gva_uint const offset = graph.nodes[idx].length - lcs.index[lcs.length - 1].offset - len; ARRAY_APPEND(allocator, graph.local_supremal, ((GVA_Node) { graph.nodes[idx].row + offset, graph.nodes[idx].col + offset, len, GVA_NULL, idx })); @@ -287,7 +275,6 @@ gva_lcs_graph_init(GVA_Allocator const allocator, graph.source = source.idx; - matches = allocator.allocate(allocator.context, matches, sizeof(*matches) * lcs.length, 0); lcs.index = allocator.allocate(allocator.context, lcs.index, lcs.length * sizeof(*lcs.index), 0); lcs.nodes = ARRAY_DESTROY(allocator, lcs.nodes); return graph; From f94864c78db794797bf810218b2437ed4712e6f4 Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 11 Jun 2025 22:56:22 +0200 Subject: [PATCH 234/704] struct layout --- include/lcs_graph.h | 2 +- src/lcs_graph.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/lcs_graph.h b/include/lcs_graph.h index 328d710..a4a3044 100644 --- a/include/lcs_graph.h +++ b/include/lcs_graph.h @@ -37,10 +37,10 @@ typedef struct // entry point in the `nodes` array. typedef struct { - GVA_String observed; GVA_Node* nodes; GVA_Edge* edges; GVA_Node* local_supremal; + GVA_String observed; gva_uint source; gva_uint distance; } GVA_LCS_Graph; diff --git a/src/lcs_graph.c b/src/lcs_graph.c index 59264ab..5a631b7 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -44,7 +44,7 @@ gva_lcs_graph_init(GVA_Allocator const allocator, { LCS_Alignment lcs = lcs_align(allocator, len_ref, reference, len_obs, observed); - GVA_LCS_Graph graph = {{observed, len_obs}, NULL, NULL, NULL, GVA_NULL, len_ref + len_obs - 2 * lcs.length}; + GVA_LCS_Graph graph = {NULL, NULL, NULL, {observed, len_obs}, GVA_NULL, len_ref + len_obs - 2 * lcs.length}; if (lcs.nodes == NULL || graph.distance == 0) { From 84ae30e9edba7c98353d38c6f46de2de6190f7eb Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 12 Jun 2025 09:10:51 +0200 Subject: [PATCH 235/704] Returning from extract --- include/extract.h | 7 ++----- include/lcs_graph.h | 2 +- src/align.c | 16 ++++++++-------- src/extract.c | 41 +++++++++++++++++++---------------------- src/lcs_graph.c | 2 +- src/main.c | 11 ++++++++--- 6 files changed, 39 insertions(+), 40 deletions(-) diff --git a/include/extract.h b/include/extract.h index 31a7164..bccddeb 100644 --- a/include/extract.h +++ b/include/extract.h @@ -2,14 +2,11 @@ #define GVA_EXTRACT_H -#include // size_t - - #include "allocator.h" // GVA_Allocator -#include "lcs_graph.h" // GVA_LCS_Graph +#include "lcs_graph.h" // GVA_LCS_Graph, GVA_Variant -void +GVA_Variant* gva_extract(GVA_Allocator const allocator, GVA_LCS_Graph const graph); diff --git a/include/lcs_graph.h b/include/lcs_graph.h index a4a3044..2d54a41 100644 --- a/include/lcs_graph.h +++ b/include/lcs_graph.h @@ -69,7 +69,7 @@ gva_uint gva_edges(char const* const restrict observed, GVA_Node const head, GVA_Node const tail, bool const is_source, bool const is_sink, - GVA_Variant* const variant); + GVA_Variant* const restrict variant); #endif // GVA_LCS_GRAPH_H diff --git a/src/align.c b/src/align.c index 4de7037..ce96c1c 100644 --- a/src/align.c +++ b/src/align.c @@ -147,6 +147,12 @@ lcs_align(GVA_Allocator const allocator, LCS_Alignment lcs = {0, NULL, NULL}; + lcs.index = allocator.allocate(allocator.context, NULL, 0, MIN(len_ref, len_obs) * sizeof(*lcs.index)); + if (lcs.index == NULL) + { + return lcs; + } // if + Context const context = { allocator, @@ -158,13 +164,7 @@ lcs_align(GVA_Allocator const allocator, }; if (context.diagonals == NULL) { - return lcs; - } // if - - lcs.index = allocator.allocate(allocator.context, NULL, 0, MIN(len_ref, len_obs) * sizeof(*lcs.index)); - if (lcs.index == NULL) - { - allocator.allocate(allocator.context, context.diagonals, size * sizeof(*context.diagonals), 0); + lcs.index = allocator.allocate(allocator.context, lcs.index, MIN(len_ref, len_obs) * sizeof(*lcs.index), lcs.length * sizeof(*lcs.index)); return lcs; } // if @@ -199,7 +199,7 @@ lcs_align(GVA_Allocator const allocator, p += 1; } // while - allocator.allocate(allocator.context, context.diagonals, size * sizeof(*context.diagonals), 0); lcs.index = allocator.allocate(allocator.context, lcs.index, MIN(len_ref, len_obs) * sizeof(*lcs.index), lcs.length * sizeof(*lcs.index)); + allocator.allocate(allocator.context, context.diagonals, size * sizeof(*context.diagonals), 0); return lcs; } // align diff --git a/src/extract.c b/src/extract.c index 02706ec..64bb722 100644 --- a/src/extract.c +++ b/src/extract.c @@ -6,7 +6,7 @@ #include "../include/lcs_graph.h" // GVA_LCS_Graph, gva_edges -#include "array.h" // array_length +#include "array.h" // ARRAY_APPEND, array_length #include "common.h" // GVA_NULL, MAX, MIN, GVA_String, gva_uint @@ -35,7 +35,9 @@ print_lca_table(size_t const length, LCA_Table const visited[static length], gva static inline gva_uint -lca(gva_uint* const start, gva_uint lhs, gva_uint rhs, size_t const length, LCA_Table const visited[static length]) +lca(gva_uint* const start, + gva_uint lhs, gva_uint rhs, + size_t const length, LCA_Table const visited[static length]) { gva_uint lhs_start = *start; gva_uint rhs_start = *start; @@ -61,25 +63,19 @@ lca(gva_uint* const start, gva_uint lhs, gva_uint rhs, size_t const length, LCA_ } // lca -void +GVA_Variant* gva_extract(GVA_Allocator const allocator, GVA_LCS_Graph const graph) { gva_uint const length = array_length(graph.nodes); LCA_Table* visited = allocator.allocate(allocator.context, NULL, 0, sizeof(*visited) * length); if (visited == NULL) { - return; + return NULL; } // if for (gva_uint i = 0; i < length; ++i) { visited[i].depth = GVA_NULL; - visited[i].lca = GVA_NULL; - visited[i].rank = GVA_NULL; - visited[i].start = GVA_NULL; - visited[i].end = GVA_NULL; - visited[i].prev = GVA_NULL; - visited[i].next = GVA_NULL; } // for gva_uint sink = GVA_NULL; @@ -148,8 +144,6 @@ gva_extract(GVA_Allocator const allocator, GVA_LCS_Graph const graph) visited[lambda] = (LCA_Table) {head, visited[lambda].rank, visited[head].depth, GVA_NULL, GVA_NULL, head, visited[head].next}; visited[head].next = lambda; } // else - - //print_lca_table(length, visited, head, tail); } // if for (gva_uint i = graph.nodes[head].edges; i != GVA_NULL; i = graph.edges[i].next) @@ -181,14 +175,12 @@ gva_extract(GVA_Allocator const allocator, GVA_LCS_Graph const graph) { fprintf(stderr, " skip %u @ %u\n", edge_tail, visited[edge_tail].depth); } // else - - //print_lca_table(length, visited, head, tail); } // for } // for print_lca_table(length, visited, GVA_NULL, GVA_NULL); - // the canonical variant is given in the reverse order (for now): the Python checker needs to reverse this list + GVA_Variant* canonical = NULL; for (gva_uint tail = sink; tail != GVA_NULL; tail = visited[tail].lca) { gva_uint const head = visited[tail].lca; @@ -203,14 +195,19 @@ gva_extract(GVA_Allocator const allocator, GVA_LCS_Graph const graph) (graph.nodes[tail].col + end_offset) - (graph.nodes[head].col + start_offset) } }; - - if (tail != sink) - { - fprintf(stderr, ",\n"); - } // if - fprintf(stderr, " \"" GVA_VARIANT_FMT "\"", GVA_VARIANT_PRINT(variant)); + ARRAY_APPEND(allocator, canonical, variant); } // if - } // while + } // for + if (canonical != NULL) + { + for (gva_uint i = 0; i < array_length(canonical) / 2; ++i) + { + GVA_Variant const temp = canonical[i]; + canonical[i] = canonical[array_length(canonical) - i - 1]; + canonical[array_length(canonical) - i - 1] = temp; + } // for + } // if visited = allocator.allocate(allocator.context, visited, sizeof(*visited) * length, 0); + return canonical; } // gva_extract diff --git a/src/lcs_graph.c b/src/lcs_graph.c index 5a631b7..524b41d 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -14,7 +14,7 @@ gva_uint gva_edges(char const* const restrict observed, GVA_Node const head, GVA_Node const tail, bool const is_source, bool const is_sink, - GVA_Variant* const variant) + GVA_Variant* const restrict variant) { intmax_t const row = (intmax_t) head.row - is_source; intmax_t const col = (intmax_t) head.col - is_source; diff --git a/src/main.c b/src/main.c index 1a408c0..e823585 100644 --- a/src/main.c +++ b/src/main.c @@ -10,7 +10,7 @@ #include "../include/std_alloc.h" // gva_std_allocator #include "../include/types.h" // GVA_NULL, GVA_String, gva_uint #include "../include/utils.h" // gva_fasta_sequence, GVA_VARIANT_* -#include "array.h" // array_length +#include "array.h" // ARRAY_DESTROY, array_length static void @@ -57,7 +57,6 @@ bfs_traversal(FILE* const stream, GVA_LCS_Graph const graph) gva_uint depth; gva_uint next; }* table = gva_std_allocator.allocate(gva_std_allocator.context, NULL, 0, sizeof(*table) * array_length(graph.nodes)); - if (table == NULL) { return; @@ -248,7 +247,13 @@ main(int argc, char* argv[static argc + 1]) lcs_graph_dot(stderr, graph); lcs_graph_json(stdout, graph); - gva_extract(gva_std_allocator, graph); + GVA_Variant* canonical = gva_extract(gva_std_allocator, graph); + for (size_t i = 0; i < array_length(canonical); ++i) + { + fprintf(stderr, GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(canonical[i])); + } // for + + ARRAY_DESTROY(gva_std_allocator, canonical); /* size_t const distance = gva_edit_distance(gva_std_allocator, len_ref, reference, len_obs, observed); From 02202cd0812a09a361ff4f83fe87db04c679ed9d Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 12 Jun 2025 10:40:52 +0200 Subject: [PATCH 236/704] Also testing canonical --- src/main.c | 13 +++++++++++-- test.py | 12 +++--------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/main.c b/src/main.c index e823585..ae8d815 100644 --- a/src/main.c +++ b/src/main.c @@ -158,7 +158,16 @@ lcs_graph_json(FILE* const stream, GVA_LCS_Graph const graph) { fprintf(stream, "\"0:0/\",\n"); } // else - fprintf(stream, " \"distance\": %u\n", graph.distance); + + fprintf(stream, " \"canonical\": [\n"); + GVA_Variant* canonical = gva_extract(gva_std_allocator, graph); + for (size_t i = 0; i < array_length(canonical); ++i) + { + fprintf(stream, " \"" GVA_VARIANT_FMT "\"%s\n", GVA_VARIANT_PRINT(canonical[i]), i < array_length(canonical) - 1 ? "," : ""); + } // for + canonical = ARRAY_DESTROY(gva_std_allocator, canonical); + + fprintf(stream, " ],\n \"distance\": %u\n", graph.distance); fprintf(stream, "}\n"); } // lcs_graph_json @@ -253,7 +262,7 @@ main(int argc, char* argv[static argc + 1]) fprintf(stderr, GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(canonical[i])); } // for - ARRAY_DESTROY(gva_std_allocator, canonical); + canonical = ARRAY_DESTROY(gva_std_allocator, canonical); /* size_t const distance = gva_edit_distance(gva_std_allocator, len_ref, reference, len_obs, observed); diff --git a/test.py b/test.py index 4e48749..57708cf 100644 --- a/test.py +++ b/test.py @@ -124,16 +124,10 @@ def check(reference, observed, debug=False, timeout=2): for lhs, rhs in zip(cgraph["local_supremal"], local_supremal(reference, graph)): assert lhs == str(rhs), f'local supremal elements differ: {lhs} vs {rhs}' - #if debug: - # print(list(reversed(cgraph["canonical"])), canonical(graph)) + assert len(cgraph["canonical"]) == len(canonical(graph)), f'canonical length' - #print() - #print(cgraph["canonical"]) - #print(canonical(graph)) - #assert len(cgraph["canonical"]) == len(canonical(graph)), f'canonical length' - - #for lhs, rhs in zip(reversed(cgraph["canonical"]), canonical(graph)): - # assert lhs == str(rhs), f'canonical elements differ: {lhs} vs {rhs}' + for lhs, rhs in zip(cgraph["canonical"], canonical(graph)): + assert lhs == str(rhs), f'canonical elements differ: {lhs} vs {rhs}' def main(): From a8662b67575bc1626b4a5a5efe8814c2e0e4d2ea Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 12 Jun 2025 10:53:21 +0200 Subject: [PATCH 237/704] Timing extraction on large deletion --- src/extract.c | 50 -------------------------------------------------- src/main.c | 1 - 2 files changed, 51 deletions(-) diff --git a/src/extract.c b/src/extract.c index 64bb722..65dee59 100644 --- a/src/extract.c +++ b/src/extract.c @@ -1,10 +1,6 @@ #include // NULL, size_t -#include // DEBUG -#include "../include/utils.h" // DEBUG - - #include "../include/lcs_graph.h" // GVA_LCS_Graph, gva_edges #include "array.h" // ARRAY_APPEND, array_length #include "common.h" // GVA_NULL, MAX, MIN, GVA_String, gva_uint @@ -22,18 +18,6 @@ typedef struct } LCA_Table; -static void -print_lca_table(size_t const length, LCA_Table const visited[static length], gva_uint const head, gva_uint const tail) -{ - fprintf(stderr, " # \tlca\trank\tdepth\tstart\tend\tprev\tnext\n"); - for (gva_uint i = 0; i < length; ++i) - { - fprintf(stderr, "%2u:\t%3d\t%4d\t%5d\t%5d\t%3d\t%4d\t%4d\n", i, visited[i].lca, visited[i].rank, visited[i].depth, visited[i].start, visited[i].end, visited[i].prev, visited[i].next); - } // for - fprintf(stderr, "head: %d\ntail: %d\n", head, tail); -} // print_lca_table - - static inline gva_uint lca(gva_uint* const start, gva_uint lhs, gva_uint rhs, @@ -43,17 +27,13 @@ lca(gva_uint* const start, gva_uint rhs_start = *start; while (lhs != rhs) { - fprintf(stderr, " lca %u (%d), %u (%d)\n", lhs, lhs_start, rhs, rhs_start); - while (visited[lhs].rank > visited[rhs].rank) { - fprintf(stderr, " left\n"); lhs_start = visited[lhs].start; lhs = visited[lhs].lca; } // if while (visited[rhs].rank > visited[lhs].rank) { - fprintf(stderr, " right\n"); rhs_start = visited[rhs].start; rhs = visited[rhs].lca; } // if @@ -84,11 +64,8 @@ gva_extract(GVA_Allocator const allocator, GVA_LCS_Graph const graph) // main loop over a queue for (gva_uint head = graph.source, tail = graph.source; head != GVA_NULL; head = visited[head].next) { - fprintf(stderr, "pop %u @ %u\n", head, visited[head].depth); - if (graph.nodes[head].edges == GVA_NULL) { - fprintf(stderr, " sink\n"); sink = head; continue; } // if @@ -99,8 +76,6 @@ gva_extract(GVA_Allocator const allocator, GVA_LCS_Graph const graph) if (visited[lambda].depth == GVA_NULL) { // add lambda in stack order - fprintf(stderr, " push lambda %u @ %u\n", lambda, visited[head].depth); - visited[visited[head].next].prev = lambda; visited[lambda] = (LCA_Table) {head, rank, visited[head].depth, GVA_NULL, GVA_NULL, head, visited[head].next}; rank += 1; @@ -108,29 +83,14 @@ gva_extract(GVA_Allocator const allocator, GVA_LCS_Graph const graph) } // if else if (visited[lambda].depth == visited[head].depth) { - fprintf(stderr, " update lambda %u @ %u\n", lambda, visited[head].depth); - fprintf(stderr, " lca(%u, %u)\n", visited[lambda].lca, head); visited[lambda].lca = lca(&visited[lambda].start, visited[lambda].lca, head, length, visited); - - // FIXME: what is correct here? - // AGGCCG CGCAGCCTC ignores the common end position - // ACAGGA CAAGGCG - // TAATTGGTAG CTATTCAG needs the common end position - // TTAAG TAACA - - //visited[lambda].end = graph.nodes[head].row; // this simulates the empty variant on a lambda edge - - fprintf(stderr, " = %u (%u:%u)\n", visited[lambda].lca, visited[lambda].start, visited[lambda].end); } // if else if (visited[head].next == lambda) { - fprintf(stderr, " improve lambda in place %u @ %u\n", lambda, visited[head].depth); visited[lambda] = (LCA_Table) {head, visited[lambda].rank, visited[head].depth, GVA_NULL, GVA_NULL, visited[lambda].prev, visited[lambda].next}; } // if else { - fprintf(stderr, " improve lambda %u @ %u\n", lambda, visited[head].depth); - if (lambda == tail) { tail = visited[lambda].prev; @@ -152,7 +112,6 @@ gva_extract(GVA_Allocator const allocator, GVA_LCS_Graph const graph) if (visited[edge_tail].depth == GVA_NULL) { // add regular successors in queue order - fprintf(stderr, " push %u @ %u\n", edge_tail, visited[head].depth + 1); GVA_Variant variant; gva_uint const count = gva_edges(graph.observed.str, graph.nodes[head], graph.nodes[edge_tail], head == graph.source, edge_tail == 0, &variant); visited[edge_tail] = (LCA_Table) {head, rank, visited[head].depth + 1, variant.start, variant.end + count - 1, tail, GVA_NULL}; @@ -162,24 +121,15 @@ gva_extract(GVA_Allocator const allocator, GVA_LCS_Graph const graph) } // if else if (visited[edge_tail].depth - 1 == visited[head].depth) { - fprintf(stderr, " update %u @ %u\n", edge_tail, visited[edge_tail].depth); - fprintf(stderr, " lca(%u, %u)\n", visited[edge_tail].lca, head); GVA_Variant variant; gva_uint const count = gva_edges(graph.observed.str, graph.nodes[head], graph.nodes[edge_tail], head == graph.source, edge_tail == 0, &variant); visited[edge_tail].start = MIN(visited[edge_tail].start, variant.start); visited[edge_tail].lca = lca(&visited[edge_tail].start, visited[edge_tail].lca, head, length, visited); visited[edge_tail].end = MAX(visited[edge_tail].end, variant.end + count - 1); - fprintf(stderr, " = %u (%u:%u)\n", visited[edge_tail].lca, visited[edge_tail].start, visited[edge_tail].end); } // if - else - { - fprintf(stderr, " skip %u @ %u\n", edge_tail, visited[edge_tail].depth); - } // else } // for } // for - print_lca_table(length, visited, GVA_NULL, GVA_NULL); - GVA_Variant* canonical = NULL; for (gva_uint tail = sink; tail != GVA_NULL; tail = visited[tail].lca) { diff --git a/src/main.c b/src/main.c index ae8d815..2ca4f76 100644 --- a/src/main.c +++ b/src/main.c @@ -261,7 +261,6 @@ main(int argc, char* argv[static argc + 1]) { fprintf(stderr, GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(canonical[i])); } // for - canonical = ARRAY_DESTROY(gva_std_allocator, canonical); /* From c523bcfa4427dce32486e92c110612626b517a5e Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 12 Jun 2025 14:41:45 +0200 Subject: [PATCH 238/704] SPDI parser --- include/extract.h | 3 +- include/lcs_graph.h | 11 +---- include/types.h | 4 -- include/variant.h | 28 +++++++++++ src/lcs_graph.c | 2 +- src/main.c | 36 ++++++++++---- src/variant.c | 115 ++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 174 insertions(+), 25 deletions(-) create mode 100644 include/variant.h create mode 100644 src/variant.c diff --git a/include/extract.h b/include/extract.h index bccddeb..9f45780 100644 --- a/include/extract.h +++ b/include/extract.h @@ -3,7 +3,8 @@ #include "allocator.h" // GVA_Allocator -#include "lcs_graph.h" // GVA_LCS_Graph, GVA_Variant +#include "lcs_graph.h" // GVA_LCS_Graph +#include "variant.h" // GVA_Variant GVA_Variant* diff --git a/include/lcs_graph.h b/include/lcs_graph.h index 2d54a41..09dd06e 100644 --- a/include/lcs_graph.h +++ b/include/lcs_graph.h @@ -7,6 +7,7 @@ #include "allocator.h" // GVA_Allocator #include "types.h" // GVA_String, gva_uint +#include "variant.h" // GVA_Variant // Internal: Each edge tracks its tail as an index to a node (in the @@ -46,14 +47,6 @@ typedef struct } GVA_LCS_Graph; -typedef struct -{ - gva_uint start; - gva_uint end; - GVA_String sequence; -} GVA_Variant; - - GVA_LCS_Graph gva_lcs_graph_init(GVA_Allocator const allocator, size_t const len_ref, char const reference[static restrict len_ref], @@ -69,7 +62,7 @@ gva_uint gva_edges(char const* const restrict observed, GVA_Node const head, GVA_Node const tail, bool const is_source, bool const is_sink, - GVA_Variant* const restrict variant); + GVA_Variant variant[static restrict 1]); #endif // GVA_LCS_GRAPH_H diff --git a/include/types.h b/include/types.h index 4c8683c..44019fc 100644 --- a/include/types.h +++ b/include/types.h @@ -5,10 +5,6 @@ #include // uint32_t, UINT32_MAX -#define GVA_VARIANT_PRINT(variant) variant.start, variant.end, (int) variant.sequence.len, variant.sequence.str -#define GVA_VARIANT_FMT "%u:%u/%.*s" - - // An unsigned integer type to store any position on a reference // sequence. For human DNA a 32-bit value is enough. // Smaller integer types reduce storage requirements. diff --git a/include/variant.h b/include/variant.h new file mode 100644 index 0000000..37332f1 --- /dev/null +++ b/include/variant.h @@ -0,0 +1,28 @@ +#ifndef GVA_VARIANT_H +#define GVA_VARIANT_H + + +#include // size_t + + +#include "types.h" // GVA_String + + +#define GVA_VARIANT_PRINT(variant) variant.start, variant.end, (int) variant.sequence.len, variant.sequence.str +#define GVA_VARIANT_FMT "%u:%u/%.*s" + + +typedef struct +{ + gva_uint start; + gva_uint end; + GVA_String sequence; +} GVA_Variant; + + +size_t +gva_parse_spdi(size_t const len, char const expression[static restrict len], + GVA_Variant variants[static restrict 1]); + + +#endif // GVA_VARIANT_H diff --git a/src/lcs_graph.c b/src/lcs_graph.c index 524b41d..86cfb39 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -14,7 +14,7 @@ gva_uint gva_edges(char const* const restrict observed, GVA_Node const head, GVA_Node const tail, bool const is_source, bool const is_sink, - GVA_Variant* const restrict variant) + GVA_Variant variant[static restrict 1]) { intmax_t const row = (intmax_t) head.row - is_source; intmax_t const col = (intmax_t) head.col - is_source; diff --git a/src/main.c b/src/main.c index 2ca4f76..d7c5a33 100644 --- a/src/main.c +++ b/src/main.c @@ -9,7 +9,8 @@ #include "../include/lcs_graph.h" // GVA_LCS_Graph, GVA_Variant, gva_lcs_graph_*, gva_edges #include "../include/std_alloc.h" // gva_std_allocator #include "../include/types.h" // GVA_NULL, GVA_String, gva_uint -#include "../include/utils.h" // gva_fasta_sequence, GVA_VARIANT_* +#include "../include/utils.h" // gva_fasta_sequence +#include "../include/variant.h" // GVA_VARIANT_*, GVA_Variant, gva_parse_spdi #include "array.h" // ARRAY_DESTROY, array_length @@ -224,21 +225,36 @@ lcs_graph_raw(FILE* const stream, GVA_LCS_Graph const graph) int main(int argc, char* argv[static argc + 1]) { - if (argc != 3) - { - fprintf(stderr, "usage %s reference observed\n", argv[0]); - return EXIT_FAILURE; - } // if - - /* FILE* const restrict stream = fopen("data/NC_000001.11.fasta", "r"); if (stream != NULL) { GVA_String seq = gva_fasta_sequence(gva_std_allocator, stream); - gva_std_allocator.allocate(gva_std_allocator.context, (char*) seq.str, seq.len, 0); + seq.str = gva_std_allocator.allocate(gva_std_allocator.context, (char*) seq.str, seq.len, 0); fclose(stream); } // if - */ + + size_t rsid; + char spdi[4096]; + char hgvs[4096]; + size_t count = 0; + while (fscanf(stdin, "%zu\t%4096s\t%4096s\n", &rsid, spdi, hgvs) == 3) + { + count += 1; + GVA_Variant variant; + gva_parse_spdi(strlen(spdi), spdi, &variant); + fprintf(stderr, "%s: " GVA_VARIANT_FMT "\n", spdi, GVA_VARIANT_PRINT(variant)); + } // while + + fprintf(stderr, "%zu\n", count); + + return EXIT_SUCCESS; + + + if (argc != 3) + { + fprintf(stderr, "usage %s reference observed\n", argv[0]); + return EXIT_FAILURE; + } // if /* char const* const restrict reference = "ATTCTATCTTCTGTCTACATAAGATGTCATACTAGAGGGCATATCTGCAATGTATACATATTATCTTTTCCAGCATGCATTCAGTTGTGTTGGAATAATTTATGTACACCTTTATAAACGCTGAGCCTCACAAGAGCCATGTGCCACGTATTGTTTTCTTACTACTTTTTGGGATACCTGGCACGTAATAGACACTCATTGAAAGTTTCCTAATGAATGAAGTACAAAGATAAAACAAGTTATAGACTGATTCTTTTGAGCTGTCAAGGTTGTAAATAGACTTTTGCTCAATCAATTCAAATGGTGGCAGGTAGTGGGGGTAGAGGGATTGGTATGAAAAACATAAGCTTTCAGAACTCCTGTGTTTATTTTTAGAATGTCAACTGCTTGAGTGTTTTTAACTCTGTGGTATCTGAACTATCTTCTCTAACTGCAGGTTGGGCTCAGATCTGTGATAGAACAGTTTCCTGGGAAGCTTGACTTTGTCCTTGTGGATGGGGGCTGTGTCCTAAGCCATGGCCACAAGCAGTTGATGTGCTTGGCTAGATCTGTTCTCAGTAAGGCGAAGATCTTGCTGCTTGATGAACCCAGTGCTCATTTGGATCCAGTGTGAGTTTCAGATGTTCTGTTACTTAATAGCACAGTGGGAACAGAATCATTATGCCTGCTTCATGGTGACACATATTTCTATTAGGCTGTCATGTCTGCGTGTGGGGGTCTCCCCCAAGATATGAAATAATTGCCCAGTGGAAATGAGCATAAATGCATATTTCCTTGCTAAGAGTCTTGTGTTTTCTTCCGAAGATAGTTTTTAGTTTCATACAAACTCTTCCCCCTTGTCAACACATGATGAAGCTTTTAAATACATGGGCCTAATCTGATCCTTATGATTTGCCTTTGTATCCCATTTATACCATAAGCATGTTTATAGCCCCAAATAAAGAAGTACTGGTGATTCTACATAATGAAAAATGTACTCATTTATTAAAGTTTCTTTGAAATATTTGTCCTGTTTATTTATGGATACTTAGAGTCTACCCCATGGTTGAAAAGCTGATTGTGGCTAACGCTATATCAACATTATGTGAAAAGAACTTAAAGAAATAAGTAATTTAAAGAGATAATAGAACAATAGACATATTATCAAGGTAAATACAGATCATTACTGTTCTGTGATATTATGTGTGGTATTTTCTTTCTTTTCTAGAACATACCAAATAATTAGAAGAACTCTAAAACAAGCATTTGCTGATTGCACAGTAATTCTCTGTGAACACAGGATAGAAGCAATGCTGGAATGCCAACAATTTTTGGTGAGTCTTTATAACTTTACTTAAGATCTCATTGCCCTTGTAATTCTTGATAACAATCTCACATGTGATAGTTCCTGCAAATTGCAACAATGTACAAGTTCTTTTCAAAAATATGTATCATACAGCCATCCAGCTTTACTCAAAATAGCTGCACAAGTTTTTCACTTTGATCTGAGCCATGTGGTGAGGTTGAAATATAGTAAATCTAAAATGGCAGCATATTACTAAGTTATGTTTATAAATAGGATATATATACTTTTTGAGCCCTTTATTTGGGGACCAAGTCATACAAAATACTCTACTGTTTAAGATTTTAAAAAAGGTCCCTGTGATTCTTTCAATAACTAAATGTCCCATGGATGTGGTCTGGGACAGGCCTAGTTGTCTTACAGTCTGATTTATGGTATTAATGACAAAGTTGAGAGGCACATTTCATTTTT"; diff --git a/src/variant.c b/src/variant.c new file mode 100644 index 0000000..232d61c --- /dev/null +++ b/src/variant.c @@ -0,0 +1,115 @@ +#include // bool +#include // size_t + + +#include "../include/variant.h" // gva_parse_spdi +#include "common.h" // gva_uint + + +static inline bool +is_digit(char const ch) +{ + return ch >= '0' && ch <= '9'; +} // is_digit + + +static inline bool +is_dna_nucleotide(char const ch) +{ + return ch == 'A' || ch == 'C' || ch == 'G' || ch == 'T'; +} // is_dna_nucleotide + + +static size_t +match_number(size_t const len, char const expression[static restrict len], + gva_uint* const restrict num) +{ + size_t idx = 0; + while (idx < len && is_digit(expression[idx])) + { + *num = *num * 10 + expression[idx] - '0'; // OVERFLOW + idx += 1; + } // while + return idx; +} // match_number + + +static size_t +match_sequence(size_t const len, char const expression[static len]) +{ + size_t idx = 0; + while (idx < len && is_dna_nucleotide(expression[idx])) + { + idx += 1; + } // while + return idx; +} // match_sequence + + +static size_t +match_until(size_t const len, char const expression[static len], char const delim) +{ + size_t idx = 0; + while (idx < len && expression[idx] != delim) + { + idx += 1; + } // while + return idx < len && expression[idx] == delim ? idx : 0; +} // match_until + + +size_t +gva_parse_spdi(size_t const len, char const expression[static restrict len], + GVA_Variant variants[static restrict 1]) +{ + // sequence + size_t idx = match_until(len, expression, ':'); + if (idx >= len) + { + return 0; // expected ':' + } // if + idx += 1; // ':' + + size_t tok = match_number(len - idx, expression + idx, &variants[0].start); + if (tok == 0) + { + return 0; // expected number (location) + } // if + idx += tok; + + if (idx >= len || expression[idx] != ':') + { + return 0; // expected ':' + } // if + idx += 1; + + tok = match_number(len - idx, expression + idx, &variants[0].end); + if (tok == 0) + { + tok = match_sequence(len - idx, expression + idx); + if (tok == 0) + { + return 0; // expected number (length) or sequence + } // if + variants[0].end = tok; // OVERFLOW + } // if + idx += tok; + variants[0].end += variants[0].start; + + if (idx >= len || expression[idx] != ':') + { + return 0; // expected ':' + } // if + idx += 1; + + variants[0].sequence.str = expression + idx; + tok = match_sequence(len - idx, expression + idx); + if (tok == 0) + { + return 0; // expected sequence + } // if + variants[0].sequence.len = tok; + idx += tok; + + return idx == len; +} // gva_parse_spdi From 23af3395323eb14e5bd6ce69616bf10670328778 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 12 Jun 2025 16:22:02 +0200 Subject: [PATCH 239/704] WIP: LCS graph from variant --- include/lcs_graph.h | 6 +++++ include/variant.h | 4 ++++ src/lcs_graph.c | 54 ++++++++++++++++++++++++++++++++++++++++++++- src/variant.c | 7 ++++++ 4 files changed, 70 insertions(+), 1 deletion(-) diff --git a/include/lcs_graph.h b/include/lcs_graph.h index 09dd06e..4fa8c86 100644 --- a/include/lcs_graph.h +++ b/include/lcs_graph.h @@ -54,6 +54,12 @@ gva_lcs_graph_init(GVA_Allocator const allocator, size_t const shift); +GVA_LCS_Graph +gva_lcs_graph_from_variant(GVA_Allocator const allocator, + size_t const len_ref, char const reference[static len_ref], + GVA_Variant const variant); + + void gva_lcs_graph_destroy(GVA_Allocator const allocator, GVA_LCS_Graph self); diff --git a/include/variant.h b/include/variant.h index 37332f1..b2975c6 100644 --- a/include/variant.h +++ b/include/variant.h @@ -25,4 +25,8 @@ gva_parse_spdi(size_t const len, char const expression[static restrict len], GVA_Variant variants[static restrict 1]); +size_t +gva_variant_length(GVA_Variant const variant); + + #endif // GVA_VARIANT_H diff --git a/src/lcs_graph.c b/src/lcs_graph.c index 86cfb39..78ff7da 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -4,7 +4,8 @@ #include "../include/allocator.h" // GVA_Allocator -#include "../include/lcs_graph.h" // GVA_LCS_Graph, GVA_Variant, gva_lcs_graph_* +#include "../include/lcs_graph.h" // GVA_LCS_Graph, gva_lcs_graph_* +#include "../include/variant.h" // GVA_Variant, gva_variant_length #include "align.h" // LCS_Alignment, lcs_align #include "array.h" // ARRAY_*, array_length #include "common.h" // GVA_NULL, gva_uint, MAX, MIN @@ -281,6 +282,57 @@ gva_lcs_graph_init(GVA_Allocator const allocator, } // gva_lcs_graph_init +GVA_LCS_Graph +gva_lcs_graph_from_variant(GVA_Allocator const allocator, + size_t const len_ref, char const reference[static len_ref], + GVA_Variant const variant) +{ + gva_uint offset = MAX(1, gva_variant_length(variant) / 2); + size_t old_len = 0; + char* observed = NULL; + + while (true) + { + gva_uint const start = MAX(0, (intmax_t) variant.start - offset); + gva_uint const end = MIN(len_ref, variant.end + offset); + + size_t const len = (variant.start - start) + variant.sequence.len + (end - variant.end); + observed = allocator.allocate(allocator.context, observed, old_len, len); + if (observed == NULL) + { + return (GVA_LCS_Graph) {NULL, NULL, NULL, {NULL, 0}, GVA_NULL, 0}; + } // if + + for (size_t i = start; i < variant.start; ++i) + { + observed[i - start] = reference[i]; + } // for + for (size_t i = 0; i < variant.sequence.len; ++i) + { + observed[i + (variant.start - start)] = variant.sequence.str[i]; + } // for + for (size_t i = variant.end; i < end; ++i) + { + observed[i + (variant.end - start)] = reference[i]; + } // for + + GVA_LCS_Graph graph = gva_lcs_graph_init(allocator, end - start, reference + start, len, observed, start); + return graph; + /* + if ((graph.supremal.start > start || graph.supremal.start == 0) && + (graph.supremal.end < end || graph.supremal.end == len_ref)) + { + return graph; + } // if + */ + gva_lcs_graph_destroy(allocator, graph); + + old_len = len; + offset *= 2; // OVERFLOW + } // while +} // gva_lcs_graph_from_variant + + inline void gva_lcs_graph_destroy(GVA_Allocator const allocator, GVA_LCS_Graph self) { diff --git a/src/variant.c b/src/variant.c index 232d61c..cf7f67f 100644 --- a/src/variant.c +++ b/src/variant.c @@ -113,3 +113,10 @@ gva_parse_spdi(size_t const len, char const expression[static restrict len], return idx == len; } // gva_parse_spdi + + +inline size_t +gva_variant_length(GVA_Variant const variant) +{ + return variant.end - variant.start + variant.sequence.len; +} // gva_variant_length From 589c7dbbfc6f24ffcb23c79d225c8036dd0d684f Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 12 Jun 2025 19:27:37 +0200 Subject: [PATCH 240/704] WIP: from variant --- src/lcs_graph.c | 24 ++++++++++++++++++------ src/main.c | 8 ++++++-- src/variant.c | 1 + 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/src/lcs_graph.c b/src/lcs_graph.c index 78ff7da..b5a3e16 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -282,12 +282,15 @@ gva_lcs_graph_init(GVA_Allocator const allocator, } // gva_lcs_graph_init +#include // DEBUG + + GVA_LCS_Graph gva_lcs_graph_from_variant(GVA_Allocator const allocator, size_t const len_ref, char const reference[static len_ref], GVA_Variant const variant) { - gva_uint offset = MAX(1, gva_variant_length(variant) / 2); + gva_uint offset = MAX(10, gva_variant_length(variant) / 2); size_t old_len = 0; char* observed = NULL; @@ -313,18 +316,27 @@ gva_lcs_graph_from_variant(GVA_Allocator const allocator, } // for for (size_t i = variant.end; i < end; ++i) { - observed[i + (variant.end - start)] = reference[i]; + observed[i - start] = reference[i]; } // for GVA_LCS_Graph graph = gva_lcs_graph_init(allocator, end - start, reference + start, len, observed, start); + fprintf(stderr, "OK\n"); + + GVA_Variant supremal; + gva_edges(graph.observed.str, + graph.local_supremal[0], graph.local_supremal[array_length(graph.local_supremal) - 1], + true, true, + &supremal); return graph; - /* - if ((graph.supremal.start > start || graph.supremal.start == 0) && - (graph.supremal.end < end || graph.supremal.end == len_ref)) + + fprintf(stderr, GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(supremal)); + + if ((supremal.start > start || supremal.start == 0) && + (supremal.end < end || supremal.end == len_ref)) { return graph; } // if - */ + gva_lcs_graph_destroy(allocator, graph); old_len = len; diff --git a/src/main.c b/src/main.c index d7c5a33..146559c 100644 --- a/src/main.c +++ b/src/main.c @@ -225,11 +225,11 @@ lcs_graph_raw(FILE* const stream, GVA_LCS_Graph const graph) int main(int argc, char* argv[static argc + 1]) { + GVA_String seq = {NULL, 0}; FILE* const restrict stream = fopen("data/NC_000001.11.fasta", "r"); if (stream != NULL) { - GVA_String seq = gva_fasta_sequence(gva_std_allocator, stream); - seq.str = gva_std_allocator.allocate(gva_std_allocator.context, (char*) seq.str, seq.len, 0); + seq = gva_fasta_sequence(gva_std_allocator, stream); fclose(stream); } // if @@ -243,6 +243,10 @@ main(int argc, char* argv[static argc + 1]) GVA_Variant variant; gva_parse_spdi(strlen(spdi), spdi, &variant); fprintf(stderr, "%s: " GVA_VARIANT_FMT "\n", spdi, GVA_VARIANT_PRINT(variant)); + GVA_LCS_Graph graph = gva_lcs_graph_from_variant(gva_std_allocator, seq.len, seq.str, variant); + + graph.observed.str = gva_std_allocator.allocate(gva_std_allocator.context, (char*) graph.observed.str, graph.observed.len, 0); + gva_lcs_graph_destroy(gva_std_allocator, graph); } // while fprintf(stderr, "%zu\n", count); diff --git a/src/variant.c b/src/variant.c index cf7f67f..80046b0 100644 --- a/src/variant.c +++ b/src/variant.c @@ -62,6 +62,7 @@ size_t gva_parse_spdi(size_t const len, char const expression[static restrict len], GVA_Variant variants[static restrict 1]) { + variants[0] = (GVA_Variant) {0, 0, {NULL, 0}}; // sequence size_t idx = match_until(len, expression, ':'); if (idx >= len) From 620a2b3a160037174c855735c975a848117c96b2 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 12 Jun 2025 22:16:16 +0200 Subject: [PATCH 241/704] WIP: work on graphs on slices --- src/align.c | 9 ++++++--- src/align.h | 3 ++- src/lcs_graph.c | 29 +++++++++++++++-------------- src/main.c | 2 ++ 4 files changed, 25 insertions(+), 18 deletions(-) diff --git a/src/align.c b/src/align.c index ce96c1c..3a0de7b 100644 --- a/src/align.c +++ b/src/align.c @@ -16,6 +16,7 @@ typedef struct char const* const restrict reference; size_t const len_obs; char const* const restrict observed; + size_t const shift; size_t* const restrict diagonals; } Context; @@ -74,7 +75,7 @@ expand(Context const context, size_t const lcs_pos = (row + col - ABS(delta) - 2 * p + ABS(d_row - d_col)) / 2 - 1; size_t const length = row - match_row; gva_uint const len = ARRAY_APPEND(context.allocator, lcs->nodes, ((LCS_Node) { - match_row, match_col, length, false, 0, GVA_NULL, GVA_NULL + match_row + context.shift, match_col, length, false, 0, GVA_NULL, GVA_NULL })) - 1; if (lcs->index[lcs_pos].head != GVA_NULL) { @@ -115,7 +116,7 @@ expand(Context const context, size_t const lcs_pos = (row + col - ABS(delta) - 2 * p + ABS(d_row - d_col)) / 2 - 1; size_t const length = row - match_row; gva_uint const len = ARRAY_APPEND(context.allocator, lcs->nodes, ((LCS_Node) { - match_row, match_col, length, false, 0, GVA_NULL, GVA_NULL + match_row + context.shift, match_col + context.shift, length, false, 0, GVA_NULL, GVA_NULL })) - 1; if (lcs->index[lcs_pos].head != GVA_NULL) { @@ -139,7 +140,8 @@ expand(Context const context, LCS_Alignment lcs_align(GVA_Allocator const allocator, size_t const len_ref, char const reference[static restrict len_ref], - size_t const len_obs, char const observed[static restrict len_obs]) + size_t const len_obs, char const observed[static restrict len_obs], + size_t const shift) { intmax_t const delta = len_obs - len_ref; size_t const offset = len_ref + 1; @@ -160,6 +162,7 @@ lcs_align(GVA_Allocator const allocator, reference, len_obs, observed, + shift, .diagonals = allocator.allocate(allocator.context, NULL, 0, size * sizeof(*context.diagonals)), }; if (context.diagonals == NULL) diff --git a/src/align.h b/src/align.h index 4e671fe..d7ff0e9 100644 --- a/src/align.h +++ b/src/align.h @@ -37,7 +37,8 @@ typedef struct LCS_Alignment lcs_align(GVA_Allocator const allocator, size_t const len_ref, char const reference[static restrict len_ref], - size_t const len_obs, char const observed[static restrict len_obs]); + size_t const len_obs, char const observed[static restrict len_obs], + size_t const shift); #endif // GVA_ALIGN_H diff --git a/src/lcs_graph.c b/src/lcs_graph.c index b5a3e16..9746363 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -3,6 +3,9 @@ #include // NULL, size_t +#include // DEBUG + + #include "../include/allocator.h" // GVA_Allocator #include "../include/lcs_graph.h" // GVA_LCS_Graph, gva_lcs_graph_* #include "../include/variant.h" // GVA_Variant, gva_variant_length @@ -43,7 +46,7 @@ gva_lcs_graph_init(GVA_Allocator const allocator, size_t const len_obs, char const observed[static restrict len_obs], size_t const shift) { - LCS_Alignment lcs = lcs_align(allocator, len_ref, reference, len_obs, observed); + LCS_Alignment lcs = lcs_align(allocator, len_ref, reference, len_obs, observed, shift); GVA_LCS_Graph graph = {NULL, NULL, NULL, {observed, len_obs}, GVA_NULL, len_ref + len_obs - 2 * lcs.length}; @@ -59,7 +62,7 @@ gva_lcs_graph_init(GVA_Allocator const allocator, graph.nodes[sink].col = 0; graph.nodes[sink].length = 0; ARRAY_APPEND(allocator, graph.local_supremal, ((GVA_Node) { - shift, shift, 0, GVA_NULL, graph.source + shift, 0, 0, GVA_NULL, graph.source })); lcs.index = allocator.allocate(allocator.context, lcs.index, lcs.length * sizeof(*lcs.index), 0); @@ -68,13 +71,13 @@ gva_lcs_graph_init(GVA_Allocator const allocator, } // if graph.source = ARRAY_APPEND(allocator, graph.nodes, ((GVA_Node) { - shift, shift, 0, + shift, 0, 0, ARRAY_APPEND(allocator, graph.edges, ((GVA_Edge) {sink, GVA_NULL})) - 1, GVA_NULL })) - 1; ARRAY_APPEND(allocator, graph.local_supremal, ((GVA_Node) { - shift, shift, 0, GVA_NULL, GVA_NULL + shift, 0, 0, GVA_NULL, GVA_NULL })); ARRAY_APPEND(allocator, graph.local_supremal, ((GVA_Node) { len_ref, len_obs, 0, GVA_NULL, GVA_NULL @@ -84,7 +87,7 @@ gva_lcs_graph_init(GVA_Allocator const allocator, gva_uint tail_idx = lcs.index[lcs.length - 1].tail; LCS_Node sink = lcs.nodes[tail_idx]; - if (sink.row + sink.length == len_ref + shift && sink.col + sink.length == len_obs + shift) + if (sink.row + sink.length == len_ref + shift && sink.col + sink.length == len_obs) { lcs.nodes[tail_idx].idx = ARRAY_APPEND(allocator, graph.nodes, ((GVA_Node) { sink.row, sink.col, sink.length, GVA_NULL, GVA_NULL @@ -94,7 +97,7 @@ gva_lcs_graph_init(GVA_Allocator const allocator, } // if else { - sink = (LCS_Node) {.row = len_ref + shift, .col = len_obs + shift, .length = 0}; + sink = (LCS_Node) {.row = len_ref + shift, .col = len_obs, .length = 0}; sink.idx = ARRAY_APPEND(allocator, graph.nodes, ((GVA_Node) { sink.row, sink.col, sink.length, GVA_NULL, GVA_NULL })) - 1; @@ -190,7 +193,7 @@ gva_lcs_graph_init(GVA_Allocator const allocator, gva_uint head_idx = lcs.index[0].head; LCS_Node source = lcs.nodes[head_idx]; - if (source.row == shift && source.col == shift) + if (source.row == shift && source.col == 0) { lcs.index[0].tail = head_idx; lcs.index[0].count += 1; @@ -200,7 +203,7 @@ gva_lcs_graph_init(GVA_Allocator const allocator, } // if else { - source = (LCS_Node) {.row = shift, .col = shift, .length = 0}; + source = (LCS_Node) {.row = shift, .col = 0, .length = 0}; source.idx = ARRAY_APPEND(allocator, graph.nodes, ((GVA_Node) { source.row, source.col, source.length, GVA_NULL, GVA_NULL })) - 1; @@ -231,7 +234,7 @@ gva_lcs_graph_init(GVA_Allocator const allocator, if (prev == GVA_NULL && lcs.nodes[lcs.index[i].tail].idx != source.idx) { ARRAY_APPEND(allocator, graph.local_supremal, ((GVA_Node) { - graph.nodes[source.idx].row + len, graph.nodes[source.idx].col + len, 0, GVA_NULL, source.idx + graph.nodes[source.idx].row, graph.nodes[source.idx].col, 0, GVA_NULL, source.idx })); } // if if (len > 0 && (lcs.index[i].count > 1 || prev != lcs.index[i].tail)) @@ -282,9 +285,6 @@ gva_lcs_graph_init(GVA_Allocator const allocator, } // gva_lcs_graph_init -#include // DEBUG - - GVA_LCS_Graph gva_lcs_graph_from_variant(GVA_Allocator const allocator, size_t const len_ref, char const reference[static len_ref], @@ -319,15 +319,16 @@ gva_lcs_graph_from_variant(GVA_Allocator const allocator, observed[i - start] = reference[i]; } // for + fprintf(stderr, "%u--%u\n", start, end); + fprintf(stderr, "%.*s\n%.*s\n", (int) (end - start), reference + start, (int) len, observed); + GVA_LCS_Graph graph = gva_lcs_graph_init(allocator, end - start, reference + start, len, observed, start); - fprintf(stderr, "OK\n"); GVA_Variant supremal; gva_edges(graph.observed.str, graph.local_supremal[0], graph.local_supremal[array_length(graph.local_supremal) - 1], true, true, &supremal); - return graph; fprintf(stderr, GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(supremal)); diff --git a/src/main.c b/src/main.c index 146559c..395d072 100644 --- a/src/main.c +++ b/src/main.c @@ -245,6 +245,8 @@ main(int argc, char* argv[static argc + 1]) fprintf(stderr, "%s: " GVA_VARIANT_FMT "\n", spdi, GVA_VARIANT_PRINT(variant)); GVA_LCS_Graph graph = gva_lcs_graph_from_variant(gva_std_allocator, seq.len, seq.str, variant); + lcs_graph_raw(stderr, graph); + graph.observed.str = gva_std_allocator.allocate(gva_std_allocator.context, (char*) graph.observed.str, graph.observed.len, 0); gva_lcs_graph_destroy(gva_std_allocator, graph); } // while From 326350f4ff35ca8a906b9e80d48fbc1f4b79d490 Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 13 Jun 2025 12:54:52 +0200 Subject: [PATCH 242/704] Fix: only offset reference --- src/align.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/align.c b/src/align.c index 3a0de7b..e2b1e3a 100644 --- a/src/align.c +++ b/src/align.c @@ -116,7 +116,7 @@ expand(Context const context, size_t const lcs_pos = (row + col - ABS(delta) - 2 * p + ABS(d_row - d_col)) / 2 - 1; size_t const length = row - match_row; gva_uint const len = ARRAY_APPEND(context.allocator, lcs->nodes, ((LCS_Node) { - match_row + context.shift, match_col + context.shift, length, false, 0, GVA_NULL, GVA_NULL + match_row + context.shift, match_col, length, false, 0, GVA_NULL, GVA_NULL })) - 1; if (lcs->index[lcs_pos].head != GVA_NULL) { From b0ff05985112f47d7d23aba2827e292cdda9c9a6 Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 13 Jun 2025 12:55:48 +0200 Subject: [PATCH 243/704] Fix: empty sequences in SPDI --- src/variant.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/variant.c b/src/variant.c index 80046b0..2b9e535 100644 --- a/src/variant.c +++ b/src/variant.c @@ -88,10 +88,6 @@ gva_parse_spdi(size_t const len, char const expression[static restrict len], if (tok == 0) { tok = match_sequence(len - idx, expression + idx); - if (tok == 0) - { - return 0; // expected number (length) or sequence - } // if variants[0].end = tok; // OVERFLOW } // if idx += tok; @@ -105,10 +101,6 @@ gva_parse_spdi(size_t const len, char const expression[static restrict len], variants[0].sequence.str = expression + idx; tok = match_sequence(len - idx, expression + idx); - if (tok == 0) - { - return 0; // expected sequence - } // if variants[0].sequence.len = tok; idx += tok; From f656e482a435792bffd75cab423f375e6bbc1bea Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 13 Jun 2025 12:56:48 +0200 Subject: [PATCH 244/704] WIP: making graphs from slices --- src/lcs_graph.c | 34 +++++++++++++++++++--------------- src/main.c | 12 +++++++++--- 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/src/lcs_graph.c b/src/lcs_graph.c index 9746363..c7cab92 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -290,10 +290,12 @@ gva_lcs_graph_from_variant(GVA_Allocator const allocator, size_t const len_ref, char const reference[static len_ref], GVA_Variant const variant) { - gva_uint offset = MAX(10, gva_variant_length(variant) / 2); + gva_uint offset = MAX(8, gva_variant_length(variant) / 2); size_t old_len = 0; char* observed = NULL; + fprintf(stderr, GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(variant)); + while (true) { gva_uint const start = MAX(0, (intmax_t) variant.start - offset); @@ -306,22 +308,22 @@ gva_lcs_graph_from_variant(GVA_Allocator const allocator, return (GVA_LCS_Graph) {NULL, NULL, NULL, {NULL, 0}, GVA_NULL, 0}; } // if - for (size_t i = start; i < variant.start; ++i) - { - observed[i - start] = reference[i]; - } // for - for (size_t i = 0; i < variant.sequence.len; ++i) - { - observed[i + (variant.start - start)] = variant.sequence.str[i]; - } // for - for (size_t i = variant.end; i < end; ++i) + for (size_t i = 0; i < len; ++i) { - observed[i - start] = reference[i]; + if (i + start < variant.start) + { + observed[i] = reference[i + start]; + } // if + else if (i + start < variant.start + variant.sequence.len) + { + observed[i] = variant.sequence.str[i - (variant.start - start)]; + } // if + else + { + observed[i] = reference[i + (variant.end - variant.start) + start - variant.sequence.len]; + } // else } // for - fprintf(stderr, "%u--%u\n", start, end); - fprintf(stderr, "%.*s\n%.*s\n", (int) (end - start), reference + start, (int) len, observed); - GVA_LCS_Graph graph = gva_lcs_graph_init(allocator, end - start, reference + start, len, observed, start); GVA_Variant supremal; @@ -330,7 +332,9 @@ gva_lcs_graph_from_variant(GVA_Allocator const allocator, true, true, &supremal); - fprintf(stderr, GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(supremal)); + fprintf(stderr, "%u--%u\n", start, end); + fprintf(stderr, "%.*s\n%.*s\n", (int) (end - start), reference + start, (int) len, observed); + fprintf(stderr, "SUPREMAL: " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(supremal)); if ((supremal.start > start || supremal.start == 0) && (supremal.end < end || supremal.end == len_ref)) diff --git a/src/main.c b/src/main.c index 395d072..bcd403e 100644 --- a/src/main.c +++ b/src/main.c @@ -239,11 +239,15 @@ main(int argc, char* argv[static argc + 1]) size_t count = 0; while (fscanf(stdin, "%zu\t%4096s\t%4096s\n", &rsid, spdi, hgvs) == 3) { - count += 1; GVA_Variant variant; - gva_parse_spdi(strlen(spdi), spdi, &variant); - fprintf(stderr, "%s: " GVA_VARIANT_FMT "\n", spdi, GVA_VARIANT_PRINT(variant)); + if (!gva_parse_spdi(strlen(spdi), spdi, &variant)) + { + fprintf(stderr, "PARSE ERROR: %zu\t%s\t%s\n", rsid, spdi, hgvs); + continue; + } // if + count += 1; GVA_LCS_Graph graph = gva_lcs_graph_from_variant(gva_std_allocator, seq.len, seq.str, variant); + fprintf(stdout, "%zu\t%s\t%s\t" GVA_VARIANT_FMT "\n", rsid, spdi, hgvs, GVA_VARIANT_PRINT(variant)); lcs_graph_raw(stderr, graph); @@ -253,6 +257,8 @@ main(int argc, char* argv[static argc + 1]) fprintf(stderr, "%zu\n", count); + seq.str = gva_std_allocator.allocate(gva_std_allocator.context, (char*) seq.str, seq.len, 0); + return EXIT_SUCCESS; From 5bb368638f52aeab1b34335c2135a2592ffe48e4 Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 13 Jun 2025 15:58:28 +0200 Subject: [PATCH 245/704] WIP: supremals? --- src/lcs_graph.c | 4 ++-- src/main.c | 11 +++++++++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/lcs_graph.c b/src/lcs_graph.c index c7cab92..1a055b2 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -294,8 +294,6 @@ gva_lcs_graph_from_variant(GVA_Allocator const allocator, size_t old_len = 0; char* observed = NULL; - fprintf(stderr, GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(variant)); - while (true) { gva_uint const start = MAX(0, (intmax_t) variant.start - offset); @@ -332,9 +330,11 @@ gva_lcs_graph_from_variant(GVA_Allocator const allocator, true, true, &supremal); +/* fprintf(stderr, "%u--%u\n", start, end); fprintf(stderr, "%.*s\n%.*s\n", (int) (end - start), reference + start, (int) len, observed); fprintf(stderr, "SUPREMAL: " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(supremal)); +*/ if ((supremal.start > start || supremal.start == 0) && (supremal.end < end || supremal.end == len_ref)) diff --git a/src/main.c b/src/main.c index bcd403e..508961f 100644 --- a/src/main.c +++ b/src/main.c @@ -247,9 +247,16 @@ main(int argc, char* argv[static argc + 1]) } // if count += 1; GVA_LCS_Graph graph = gva_lcs_graph_from_variant(gva_std_allocator, seq.len, seq.str, variant); - fprintf(stdout, "%zu\t%s\t%s\t" GVA_VARIANT_FMT "\n", rsid, spdi, hgvs, GVA_VARIANT_PRINT(variant)); - lcs_graph_raw(stderr, graph); + GVA_Variant supremal; + gva_edges(graph.observed.str, + graph.local_supremal[0], graph.local_supremal[array_length(graph.local_supremal) - 1], + true, true, + &supremal); + + fprintf(stdout, "%zu\t%s\t%s\t" GVA_VARIANT_FMT "\n", rsid, spdi, hgvs, GVA_VARIANT_PRINT(supremal)); + + //lcs_graph_raw(stderr, graph); graph.observed.str = gva_std_allocator.allocate(gva_std_allocator.context, (char*) graph.observed.str, graph.observed.len, 0); gva_lcs_graph_destroy(gva_std_allocator, graph); From 87c9a33c3a165c7a74be94092fbfb4923f28d88b Mon Sep 17 00:00:00 2001 From: jkvis Date: Sun, 15 Jun 2025 08:41:25 +0200 Subject: [PATCH 246/704] Supremals ok --- src/main.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/main.c b/src/main.c index 508961f..b378ff1 100644 --- a/src/main.c +++ b/src/main.c @@ -236,13 +236,17 @@ main(int argc, char* argv[static argc + 1]) size_t rsid; char spdi[4096]; char hgvs[4096]; + char python[4096]; + size_t distance; + size_t nodes; + size_t edges; size_t count = 0; - while (fscanf(stdin, "%zu\t%4096s\t%4096s\n", &rsid, spdi, hgvs) == 3) + while (fscanf(stdin, "%zu %4096s %4096s %4096s %zu %zu %zu\n", &rsid, spdi, hgvs, python, &distance, &nodes, &edges) == 7) { GVA_Variant variant; if (!gva_parse_spdi(strlen(spdi), spdi, &variant)) { - fprintf(stderr, "PARSE ERROR: %zu\t%s\t%s\n", rsid, spdi, hgvs); + fprintf(stderr, "PARSE ERROR: %zu %s %s %s %zu %zu %zu\n", rsid, spdi, hgvs, python, distance, nodes, edges); continue; } // if count += 1; @@ -254,9 +258,10 @@ main(int argc, char* argv[static argc + 1]) true, true, &supremal); - fprintf(stdout, "%zu\t%s\t%s\t" GVA_VARIANT_FMT "\n", rsid, spdi, hgvs, GVA_VARIANT_PRINT(supremal)); + fprintf(stdout, "%zu %s %s %s %zu %zu %zu " GVA_VARIANT_FMT " %u %zu %zu\n", rsid, spdi, hgvs, python, distance, nodes, edges, GVA_VARIANT_PRINT(supremal), graph.distance, array_length(graph.nodes), array_length(graph.edges)); //lcs_graph_raw(stderr, graph); + //lcs_graph_dot(stderr, graph); graph.observed.str = gva_std_allocator.allocate(gva_std_allocator.context, (char*) graph.observed.str, graph.observed.len, 0); gva_lcs_graph_destroy(gva_std_allocator, graph); From 4bd2024fe1ac0420ec1ae058f195b93611867f4a Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 19 Jun 2025 19:48:44 +0200 Subject: [PATCH 247/704] Supremal, bitset, and allocation --- include/allocator.h | 2 +- include/lcs_graph.h | 15 +++++++------ include/std_alloc.h | 8 +++---- include/types.h | 3 ++- src/array.c | 4 ++-- src/array.h | 4 ++-- src/bitset.c | 52 +++++++++++++++++++++++++++++++++++++++++++++ src/bitset.h | 27 +++++++++++++++++++++++ src/lcs_graph.c | 33 +++++++++++----------------- src/main.c | 28 ++++-------------------- 10 files changed, 114 insertions(+), 62 deletions(-) create mode 100644 src/bitset.c create mode 100644 src/bitset.h diff --git a/include/allocator.h b/include/allocator.h index 21fcf91..4b9b365 100644 --- a/include/allocator.h +++ b/include/allocator.h @@ -18,7 +18,7 @@ // See `std_alloc.h` for a simple libc wrapper. typedef struct { - void* (*allocate)(void* const restrict context, void* const restrict ptr, size_t const old_size, size_t const new_size); + void* (*allocate)(void* const restrict context, void const* const restrict ptr, size_t const old_size, size_t const new_size); void* context; } GVA_Allocator; diff --git a/include/lcs_graph.h b/include/lcs_graph.h index 4fa8c86..dc3871f 100644 --- a/include/lcs_graph.h +++ b/include/lcs_graph.h @@ -38,12 +38,13 @@ typedef struct // entry point in the `nodes` array. typedef struct { - GVA_Node* nodes; - GVA_Edge* edges; - GVA_Node* local_supremal; - GVA_String observed; - gva_uint source; - gva_uint distance; + GVA_Node* nodes; + GVA_Edge* edges; + GVA_Node* local_supremal; + GVA_Variant supremal; + GVA_String observed; // FIXME: ownership and destroy + gva_uint source; + gva_uint distance; } GVA_LCS_Graph; @@ -65,7 +66,7 @@ gva_lcs_graph_destroy(GVA_Allocator const allocator, GVA_LCS_Graph self); gva_uint -gva_edges(char const* const restrict observed, +gva_edges(char const observed[static restrict 1], GVA_Node const head, GVA_Node const tail, bool const is_source, bool const is_sink, GVA_Variant variant[static restrict 1]); diff --git a/include/std_alloc.h b/include/std_alloc.h index 978c41e..3d6d220 100644 --- a/include/std_alloc.h +++ b/include/std_alloc.h @@ -12,21 +12,21 @@ // Provides a simple global allocation strategy based on `realloc` from // libc. static inline void* -gva_std_allocate(void* const restrict context, void* const restrict ptr, size_t const old_size, size_t const new_size) +gva_std_allocate(void* const restrict context, void const* const restrict ptr, size_t const old_size, size_t const new_size) { (void) context; (void) old_size; if (new_size == 0) { - free(ptr); + free((void*) ptr); return NULL; } // if - void* const new_ptr = realloc(ptr, new_size); + void* const new_ptr = realloc((void*) ptr, new_size); if (new_ptr == NULL) { - free(ptr); + free((void*) ptr); return NULL; // OOM } // if diff --git a/include/types.h b/include/types.h index 44019fc..b7b4514 100644 --- a/include/types.h +++ b/include/types.h @@ -2,6 +2,7 @@ #define GVA_TYPES_H +#include // size_t #include // uint32_t, UINT32_MAX @@ -18,7 +19,7 @@ static gva_uint const GVA_NULL = UINT32_MAX; typedef struct { char const* str; - gva_uint len; + size_t len; } GVA_String; diff --git a/src/array.c b/src/array.c index cf0d8ad..29f9e82 100644 --- a/src/array.c +++ b/src/array.c @@ -20,14 +20,14 @@ array_init(GVA_Allocator const allocator, size_t const capacity, inline size_t -array_length(void* const self) +array_length(void const* const self) { return self == NULL ? 0 : array_header(self)->length; } // array_length inline Array* -array_header(void* const self) +array_header(void const* const self) { return (Array*) self - 1; } // array_header diff --git a/src/array.h b/src/array.h index 635ff0f..52a1e94 100644 --- a/src/array.h +++ b/src/array.h @@ -32,13 +32,13 @@ array_init(GVA_Allocator const allocator, size_t const capacity, // Returns the number of elements currently in use by the array. size_t -array_length(void* const self); +array_length(void const* const self); // Internal: Returns the metadata of the array. // `self` must not be `NULL`. Array* -array_header(void* const self); +array_header(void const* const self); // Internal: Returns the possibly (re)allocated array with place for diff --git a/src/bitset.c b/src/bitset.c new file mode 100644 index 0000000..136c3e3 --- /dev/null +++ b/src/bitset.c @@ -0,0 +1,52 @@ +// FIXME: __builtin_popcountll +#include // CHAR_BIT +#include // NULL, size_t + + +#include "../include/allocator.h" // GVA_Allocator +#include "array.h" // ARRAY_*, array_* + + +inline size_t* +bitset_init(GVA_Allocator const allocator, size_t const size) +{ + size_t const len = (size + sizeof(size_t) * CHAR_BIT - 1) / (sizeof(size_t) * CHAR_BIT); + size_t* bitset = array_init(allocator, len, sizeof(*bitset)); + if (bitset == NULL) + { + return NULL; + } // if + array_header(bitset)->length = len; + for (size_t i = 0; i < len; ++i) + { + bitset[i] = 0; + } // for + return bitset; +} // bitset_init + + +inline void +bitset_add(size_t bitset[static 1], size_t const value) +{ + bitset[value / (sizeof(size_t) * CHAR_BIT)] |= (1ULL << (value % (sizeof(size_t) * CHAR_BIT))); +} // bitset_add + + +inline size_t +bitset_intersection_cnt(size_t const lhs[static 1], size_t const rhs[static 1]) +{ + size_t const len = array_length(lhs); + size_t count = 0; + for (size_t i = 0; i < len; ++i) + { + count += __builtin_popcountll(lhs[i] & rhs[i]); + } // for + return count; +} // bitset_intersection_cnt + + +inline size_t* +bitset_destroy(GVA_Allocator const allocator, size_t bitset[static 1]) +{ + return ARRAY_DESTROY(allocator, bitset); +} // bitset_destroy diff --git a/src/bitset.h b/src/bitset.h new file mode 100644 index 0000000..8155f1e --- /dev/null +++ b/src/bitset.h @@ -0,0 +1,27 @@ +#ifndef GVA_BITSET_H +#define GVA_BITSET_H + + +#include // size_t + + +#include "../include/allocator.h" // GVA_Allocator + + +size_t* +bitset_init(GVA_Allocator const allocator, size_t const size); + + +void +bitset_add(size_t bitset[static 1], size_t const value); + + +size_t +bitset_intersection_cnt(size_t const lhs[static 1], size_t const rhs[static 1]); + + +size_t* +bitset_destroy(GVA_Allocator const allocator, size_t bitset[static 1]); + + +#endif // GVA_BITSET_H diff --git a/src/lcs_graph.c b/src/lcs_graph.c index 1a055b2..3b966b4 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -3,9 +3,6 @@ #include // NULL, size_t -#include // DEBUG - - #include "../include/allocator.h" // GVA_Allocator #include "../include/lcs_graph.h" // GVA_LCS_Graph, gva_lcs_graph_* #include "../include/variant.h" // GVA_Variant, gva_variant_length @@ -15,7 +12,7 @@ gva_uint -gva_edges(char const* const restrict observed, +gva_edges(char const observed[static restrict 1], GVA_Node const head, GVA_Node const tail, bool const is_source, bool const is_sink, GVA_Variant variant[static restrict 1]) @@ -48,7 +45,7 @@ gva_lcs_graph_init(GVA_Allocator const allocator, { LCS_Alignment lcs = lcs_align(allocator, len_ref, reference, len_obs, observed, shift); - GVA_LCS_Graph graph = {NULL, NULL, NULL, {observed, len_obs}, GVA_NULL, len_ref + len_obs - 2 * lcs.length}; + GVA_LCS_Graph graph = {NULL, NULL, NULL, {0, 0, {observed, 0}}, {observed, len_obs}, GVA_NULL, len_ref + len_obs - 2 * lcs.length}; if (lcs.nodes == NULL || graph.distance == 0) { @@ -82,6 +79,7 @@ gva_lcs_graph_init(GVA_Allocator const allocator, ARRAY_APPEND(allocator, graph.local_supremal, ((GVA_Node) { len_ref, len_obs, 0, GVA_NULL, GVA_NULL })); + graph.supremal = (GVA_Variant) {shift, len_ref, {observed, len_obs}}; return graph; } // if @@ -261,7 +259,7 @@ gva_lcs_graph_init(GVA_Allocator const allocator, graph.nodes[idx].row + offset, graph.nodes[idx].col + offset, len, GVA_NULL, idx })); } // if - if (len == 0 || lcs.nodes[prev].idx != 0) + if (graph.nodes != NULL && (len == 0 || lcs.nodes[prev].idx != 0)) { ARRAY_APPEND(allocator, graph.local_supremal, ((GVA_Node) { graph.nodes[0].row + graph.nodes[0].length, graph.nodes[0].col + graph.nodes[0].length, 0, GVA_NULL, 0 @@ -275,6 +273,11 @@ gva_lcs_graph_init(GVA_Allocator const allocator, graph.nodes[source.idx].length -= graph.local_supremal[0].length; graph.nodes[0].length -= len; + + gva_edges(graph.observed.str, + graph.local_supremal[0], graph.local_supremal[array_length(graph.local_supremal) - 1], + true, true, + &graph.supremal); } // if graph.source = source.idx; @@ -303,7 +306,7 @@ gva_lcs_graph_from_variant(GVA_Allocator const allocator, observed = allocator.allocate(allocator.context, observed, old_len, len); if (observed == NULL) { - return (GVA_LCS_Graph) {NULL, NULL, NULL, {NULL, 0}, GVA_NULL, 0}; + return (GVA_LCS_Graph) {NULL, NULL, NULL, {0, 0, {NULL, 0}}, {NULL, 0}, GVA_NULL, 0}; } // if for (size_t i = 0; i < len; ++i) @@ -324,20 +327,8 @@ gva_lcs_graph_from_variant(GVA_Allocator const allocator, GVA_LCS_Graph graph = gva_lcs_graph_init(allocator, end - start, reference + start, len, observed, start); - GVA_Variant supremal; - gva_edges(graph.observed.str, - graph.local_supremal[0], graph.local_supremal[array_length(graph.local_supremal) - 1], - true, true, - &supremal); - -/* - fprintf(stderr, "%u--%u\n", start, end); - fprintf(stderr, "%.*s\n%.*s\n", (int) (end - start), reference + start, (int) len, observed); - fprintf(stderr, "SUPREMAL: " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(supremal)); -*/ - - if ((supremal.start > start || supremal.start == 0) && - (supremal.end < end || supremal.end == len_ref)) + if ((graph.supremal.start > start || graph.supremal.start == 0) && + (graph.supremal.end < end || graph.supremal.end == len_ref)) { return graph; } // if diff --git a/src/main.c b/src/main.c index b378ff1..837b91e 100644 --- a/src/main.c +++ b/src/main.c @@ -145,21 +145,7 @@ lcs_graph_json(FILE* const stream, GVA_LCS_Graph const graph) fprintf(stream, " \"" GVA_VARIANT_FMT "\"%s\n", GVA_VARIANT_PRINT(variant), i < array_length(graph.local_supremal) - 2 ? "," : ""); } // for } // if - fprintf(stream, " ],\n \"supremal\": "); - if (array_length(graph.local_supremal) > 1) - { - GVA_Variant variant; - gva_edges(graph.observed.str, - graph.local_supremal[0], graph.local_supremal[array_length(graph.local_supremal) - 1], - true, true, - &variant); - fprintf(stream, "\"" GVA_VARIANT_FMT "\",\n", GVA_VARIANT_PRINT(variant)); - } // if - else - { - fprintf(stream, "\"0:0/\",\n"); - } // else - + fprintf(stream, " ],\n \"supremal\": \"" GVA_VARIANT_FMT "\",\n", GVA_VARIANT_PRINT(graph.supremal)); fprintf(stream, " \"canonical\": [\n"); GVA_Variant* canonical = gva_extract(gva_std_allocator, graph); for (size_t i = 0; i < array_length(canonical); ++i) @@ -252,24 +238,18 @@ main(int argc, char* argv[static argc + 1]) count += 1; GVA_LCS_Graph graph = gva_lcs_graph_from_variant(gva_std_allocator, seq.len, seq.str, variant); - GVA_Variant supremal; - gva_edges(graph.observed.str, - graph.local_supremal[0], graph.local_supremal[array_length(graph.local_supremal) - 1], - true, true, - &supremal); - - fprintf(stdout, "%zu %s %s %s %zu %zu %zu " GVA_VARIANT_FMT " %u %zu %zu\n", rsid, spdi, hgvs, python, distance, nodes, edges, GVA_VARIANT_PRINT(supremal), graph.distance, array_length(graph.nodes), array_length(graph.edges)); + fprintf(stdout, "%zu %s %s %s %zu %zu %zu " GVA_VARIANT_FMT " %u %zu %zu\n", rsid, spdi, hgvs, python, distance, nodes, edges, GVA_VARIANT_PRINT(graph.supremal), graph.distance, array_length(graph.nodes), array_length(graph.edges)); //lcs_graph_raw(stderr, graph); //lcs_graph_dot(stderr, graph); - graph.observed.str = gva_std_allocator.allocate(gva_std_allocator.context, (char*) graph.observed.str, graph.observed.len, 0); + graph.observed.str = gva_std_allocator.allocate(gva_std_allocator.context, graph.observed.str, graph.observed.len, 0); gva_lcs_graph_destroy(gva_std_allocator, graph); } // while fprintf(stderr, "%zu\n", count); - seq.str = gva_std_allocator.allocate(gva_std_allocator.context, (char*) seq.str, seq.len, 0); + seq.str = gva_std_allocator.allocate(gva_std_allocator.context, seq.str, seq.len, 0); return EXIT_SUCCESS; From 88ea020483ff78c507260d73a89b93fcfaf178f9 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 19 Jun 2025 20:20:11 +0200 Subject: [PATCH 248/704] WIP: calculating bitsets --- src/bitset.c | 3 +- src/main.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 91 insertions(+), 3 deletions(-) diff --git a/src/bitset.c b/src/bitset.c index 136c3e3..f38c81f 100644 --- a/src/bitset.c +++ b/src/bitset.c @@ -4,7 +4,8 @@ #include "../include/allocator.h" // GVA_Allocator -#include "array.h" // ARRAY_*, array_* +#include "array.h" // ARRAY_*, array_* +#include "bitset.h" // bitset_* inline size_t* diff --git a/src/main.c b/src/main.c index 837b91e..21bf7fe 100644 --- a/src/main.c +++ b/src/main.c @@ -11,7 +11,8 @@ #include "../include/types.h" // GVA_NULL, GVA_String, gva_uint #include "../include/utils.h" // gva_fasta_sequence #include "../include/variant.h" // GVA_VARIANT_*, GVA_Variant, gva_parse_spdi -#include "array.h" // ARRAY_DESTROY, array_length +#include "array.h" // ARRAY_DESTROY, array_length +#include "bitset.h" // bitset_* static void @@ -211,6 +212,7 @@ lcs_graph_raw(FILE* const stream, GVA_LCS_Graph const graph) int main(int argc, char* argv[static argc + 1]) { + /* GVA_String seq = {NULL, 0}; FILE* const restrict stream = fopen("data/NC_000001.11.fasta", "r"); if (stream != NULL) @@ -252,7 +254,7 @@ main(int argc, char* argv[static argc + 1]) seq.str = gva_std_allocator.allocate(gva_std_allocator.context, seq.str, seq.len, 0); return EXIT_SUCCESS; - + */ if (argc != 3) { @@ -283,6 +285,91 @@ main(int argc, char* argv[static argc + 1]) } // for canonical = ARRAY_DESTROY(gva_std_allocator, canonical); + size_t* dels = bitset_init(gva_std_allocator, graph.supremal.end - graph.supremal.start); + size_t* as = bitset_init(gva_std_allocator, graph.supremal.end - graph.supremal.start + 1); + size_t* cs = bitset_init(gva_std_allocator, graph.supremal.end - graph.supremal.start + 1); + size_t* gs = bitset_init(gva_std_allocator, graph.supremal.end - graph.supremal.start + 1); + size_t* ts = bitset_init(gva_std_allocator, graph.supremal.end - graph.supremal.start + 1); + + for (size_t i = 0; i < array_length(graph.nodes); ++i) + { + for (gva_uint j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) + { + GVA_Variant variant; + gva_uint const count = gva_edges(graph.observed.str, + graph.nodes[i], graph.nodes[graph.edges[j].tail], + i == graph.source, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, + &variant); + for (gva_uint k = variant.start; k < variant.end + count - 1; ++k) + { + bitset_add(dels, k - graph.supremal.start); + } // for + size_t mask = 0; + for (size_t k = 0; k < variant.sequence.len; ++k) + { + if (variant.sequence.str[k] == 'A') + { + mask |= 1; + } // if + else if (variant.sequence.str[k] == 'C') + { + mask |= 2; + } // if + else if (variant.sequence.str[k] == 'G') + { + mask |= 4; + } // if + else if (variant.sequence.str[k] == 'T') + { + mask |= 8; + } // if + } // for + if ((mask & 1) == 1) + { + for (gva_uint k = variant.start; k < variant.end + count; ++k) + { + bitset_add(as, k - graph.supremal.start); + } // for + } // if + if ((mask & 2) == 2) + { + for (gva_uint k = variant.start; k < variant.end + count; ++k) + { + bitset_add(cs, k - graph.supremal.start); + } // for + } // if + if ((mask & 4) == 4) + { + for (gva_uint k = variant.start; k < variant.end + count; ++k) + { + bitset_add(gs, k - graph.supremal.start); + } // for + } // if + if ((mask & 8) == 8) + { + for (gva_uint k = variant.start; k < variant.end + count; ++k) + { + bitset_add(ts, k - graph.supremal.start); + } // for + } // if + } // for + } // for + + for (size_t i = 0; i < array_length(dels); ++i) + { + fprintf(stderr, "%2zu: %064zx\n", i, dels[i]); + fprintf(stderr, "%2zu: %064zx\n", i, as[i]); + fprintf(stderr, "%2zu: %064zx\n", i, cs[i]); + fprintf(stderr, "%2zu: %064zx\n", i, gs[i]); + fprintf(stderr, "%2zu: %064zx\n", i, ts[i]); + } // for + + ts = bitset_destroy(gva_std_allocator, ts); + gs = bitset_destroy(gva_std_allocator, gs); + cs = bitset_destroy(gva_std_allocator, cs); + as = bitset_destroy(gva_std_allocator, as); + dels = bitset_destroy(gva_std_allocator, dels); + /* size_t const distance = gva_edit_distance(gva_std_allocator, len_ref, reference, len_obs, observed); fprintf(stderr, "distance only: %zu\n", distance); From c8a850cbbdcb854a158211cf5f19000748a8828f Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 26 Jun 2025 16:47:06 +0200 Subject: [PATCH 249/704] Reordered string struct --- include/types.h | 2 +- src/extract.c | 4 ++-- src/lcs_graph.c | 10 +++++----- src/utils.c | 2 +- src/variant.c | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/include/types.h b/include/types.h index b7b4514..4bac456 100644 --- a/include/types.h +++ b/include/types.h @@ -18,8 +18,8 @@ static gva_uint const GVA_NULL = UINT32_MAX; typedef struct { - char const* str; size_t len; + char const* str; } GVA_String; diff --git a/src/extract.c b/src/extract.c index 65dee59..98ae28b 100644 --- a/src/extract.c +++ b/src/extract.c @@ -141,8 +141,8 @@ gva_extract(GVA_Allocator const allocator, GVA_LCS_Graph const graph) gva_uint const end_offset = visited[tail].end - graph.nodes[tail].row; GVA_Variant const variant = { visited[tail].start, visited[tail].end, { - graph.observed.str + graph.nodes[head].col + start_offset, - (graph.nodes[tail].col + end_offset) - (graph.nodes[head].col + start_offset) + (graph.nodes[tail].col + end_offset) - (graph.nodes[head].col + start_offset), + graph.observed.str + graph.nodes[head].col + start_offset } }; ARRAY_APPEND(allocator, canonical, variant); diff --git a/src/lcs_graph.c b/src/lcs_graph.c index 3b966b4..1d405f2 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -29,8 +29,8 @@ gva_edges(char const observed[static restrict 1], *variant = (GVA_Variant) { row + head_offset, tail.row + tail_offset, { - observed + col + head_offset, - (tail.col + tail_offset) - (col + head_offset) + (tail.col + tail_offset) - (col + head_offset), + observed + col + head_offset } }; return MIN(head_length - head_offset, tail_length - tail_offset - 1) + 1; @@ -45,7 +45,7 @@ gva_lcs_graph_init(GVA_Allocator const allocator, { LCS_Alignment lcs = lcs_align(allocator, len_ref, reference, len_obs, observed, shift); - GVA_LCS_Graph graph = {NULL, NULL, NULL, {0, 0, {observed, 0}}, {observed, len_obs}, GVA_NULL, len_ref + len_obs - 2 * lcs.length}; + GVA_LCS_Graph graph = {NULL, NULL, NULL, {0, 0, {0, observed}}, {len_obs, observed}, GVA_NULL, len_ref + len_obs - 2 * lcs.length}; if (lcs.nodes == NULL || graph.distance == 0) { @@ -79,7 +79,7 @@ gva_lcs_graph_init(GVA_Allocator const allocator, ARRAY_APPEND(allocator, graph.local_supremal, ((GVA_Node) { len_ref, len_obs, 0, GVA_NULL, GVA_NULL })); - graph.supremal = (GVA_Variant) {shift, len_ref, {observed, len_obs}}; + graph.supremal = (GVA_Variant) {shift, len_ref, {len_obs, observed}}; return graph; } // if @@ -306,7 +306,7 @@ gva_lcs_graph_from_variant(GVA_Allocator const allocator, observed = allocator.allocate(allocator.context, observed, old_len, len); if (observed == NULL) { - return (GVA_LCS_Graph) {NULL, NULL, NULL, {0, 0, {NULL, 0}}, {NULL, 0}, GVA_NULL, 0}; + return (GVA_LCS_Graph) {NULL, NULL, NULL, {0, 0, {0, NULL}}, {0, NULL}, GVA_NULL, 0}; } // if for (size_t i = 0; i < len; ++i) diff --git a/src/utils.c b/src/utils.c index 9282b19..f801202 100644 --- a/src/utils.c +++ b/src/utils.c @@ -13,7 +13,7 @@ gva_fasta_sequence(GVA_Allocator const allocator, FILE* const restrict stream) { static size_t const FASTA_LINE_SIZE = 65536; size_t capacity = FASTA_LINE_SIZE; - GVA_String seq = {allocator.allocate(allocator.context, NULL, 0, capacity), 0}; + GVA_String seq = {0, allocator.allocate(allocator.context, NULL, 0, capacity)}; if (seq.str == NULL) { return seq; diff --git a/src/variant.c b/src/variant.c index 2b9e535..9422753 100644 --- a/src/variant.c +++ b/src/variant.c @@ -62,7 +62,7 @@ size_t gva_parse_spdi(size_t const len, char const expression[static restrict len], GVA_Variant variants[static restrict 1]) { - variants[0] = (GVA_Variant) {0, 0, {NULL, 0}}; + variants[0] = (GVA_Variant) {0, 0, {0, NULL}}; // sequence size_t idx = match_until(len, expression, ':'); if (idx >= len) From 21900b67a787182da276918d0a2a6a393f799c4c Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 26 Jun 2025 17:20:29 +0200 Subject: [PATCH 250/704] memset / memcpy --- src/align.c | 6 ++---- src/bitset.c | 7 ++----- src/lcs_graph.c | 20 +++++--------------- 3 files changed, 9 insertions(+), 24 deletions(-) diff --git a/src/align.c b/src/align.c index e2b1e3a..29cf7f1 100644 --- a/src/align.c +++ b/src/align.c @@ -1,6 +1,7 @@ #include // intmax_t #include // bool, false, true #include // NULL, size_t +#include // memset #include "../include/allocator.h" // GVA_Allocator @@ -171,10 +172,7 @@ lcs_align(GVA_Allocator const allocator, return lcs; } // if - for (size_t i = 0; i < size; ++i) - { - context.diagonals[i] = 0; - } // for + memset(context.diagonals, 0, size * sizeof(*context.diagonals)); for (size_t i = 0; i < MIN(len_ref, len_obs); ++i) { diff --git a/src/bitset.c b/src/bitset.c index f38c81f..e5fa619 100644 --- a/src/bitset.c +++ b/src/bitset.c @@ -1,6 +1,7 @@ // FIXME: __builtin_popcountll #include // CHAR_BIT #include // NULL, size_t +#include // memset #include "../include/allocator.h" // GVA_Allocator @@ -18,11 +19,7 @@ bitset_init(GVA_Allocator const allocator, size_t const size) return NULL; } // if array_header(bitset)->length = len; - for (size_t i = 0; i < len; ++i) - { - bitset[i] = 0; - } // for - return bitset; + return memset(bitset, 0, len * sizeof(*bitset)); } // bitset_init diff --git a/src/lcs_graph.c b/src/lcs_graph.c index 1d405f2..85be443 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -1,6 +1,7 @@ #include // intmax_t #include // bool, false, true #include // NULL, size_t +#include // memcpy #include "../include/allocator.h" // GVA_Allocator @@ -302,6 +303,7 @@ gva_lcs_graph_from_variant(GVA_Allocator const allocator, gva_uint const start = MAX(0, (intmax_t) variant.start - offset); gva_uint const end = MIN(len_ref, variant.end + offset); + // FIXME: len == 0? size_t const len = (variant.start - start) + variant.sequence.len + (end - variant.end); observed = allocator.allocate(allocator.context, observed, old_len, len); if (observed == NULL) @@ -309,21 +311,9 @@ gva_lcs_graph_from_variant(GVA_Allocator const allocator, return (GVA_LCS_Graph) {NULL, NULL, NULL, {0, 0, {0, NULL}}, {0, NULL}, GVA_NULL, 0}; } // if - for (size_t i = 0; i < len; ++i) - { - if (i + start < variant.start) - { - observed[i] = reference[i + start]; - } // if - else if (i + start < variant.start + variant.sequence.len) - { - observed[i] = variant.sequence.str[i - (variant.start - start)]; - } // if - else - { - observed[i] = reference[i + (variant.end - variant.start) + start - variant.sequence.len]; - } // else - } // for + memcpy(observed, reference + start, variant.start - start); + memcpy(observed + variant.start - start, variant.sequence.str, variant.sequence.len); + memcpy(observed + variant.start - start + variant.sequence.len, reference + variant.end, end - variant.end); GVA_LCS_Graph graph = gva_lcs_graph_init(allocator, end - start, reference + start, len, observed, start); From e8fb8489aab1ada73d0992eabcd51673866f1011 Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 27 Jun 2025 16:10:00 +0200 Subject: [PATCH 251/704] Variant patching --- include/utils.h | 2 +- include/variant.h | 9 ++++++++- src/utils.c | 3 ++- src/variant.c | 48 ++++++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 56 insertions(+), 6 deletions(-) diff --git a/include/utils.h b/include/utils.h index d1b087d..c337113 100644 --- a/include/utils.h +++ b/include/utils.h @@ -15,4 +15,4 @@ GVA_String gva_fasta_sequence(GVA_Allocator const allocator, FILE* const restrict stream); -#endif // GVA_UTILS_H \ No newline at end of file +#endif // GVA_UTILS_H diff --git a/include/variant.h b/include/variant.h index b2975c6..9897b5e 100644 --- a/include/variant.h +++ b/include/variant.h @@ -5,7 +5,8 @@ #include // size_t -#include "types.h" // GVA_String +#include "allocator.h" // GVA_Allocator +#include "types.h" // gva_uint, GVA_String #define GVA_VARIANT_PRINT(variant) variant.start, variant.end, (int) variant.sequence.len, variant.sequence.str @@ -29,4 +30,10 @@ size_t gva_variant_length(GVA_Variant const variant); +GVA_String +gva_patch(GVA_Allocator const allocator, + size_t const len_ref, char const reference[static restrict len_ref], + size_t const n, GVA_Variant const variants[static restrict n]); + + #endif // GVA_VARIANT_H diff --git a/src/utils.c b/src/utils.c index f801202..296c064 100644 --- a/src/utils.c +++ b/src/utils.c @@ -5,7 +5,8 @@ #include "../include/allocator.h" // GVA_Allocator -#include "../include/utils.h" // GVA_String, gva_fasta_sequence +#include "../include/types.h" // GVA_String +#include "../include/utils.h" // gva_fasta_sequence GVA_String diff --git a/src/variant.c b/src/variant.c index 9422753..1a69808 100644 --- a/src/variant.c +++ b/src/variant.c @@ -1,9 +1,11 @@ #include // bool -#include // size_t +#include // NULL, size_t +#include // memcpy -#include "../include/variant.h" // gva_parse_spdi -#include "common.h" // gva_uint +#include "../include/allocator.h" // GVA_Allocator +#include "../include/types.h" // gva_uint, GVA_String +#include "../include/variant.h" // gva_parse_spdi, gva_patch static inline bool @@ -58,6 +60,23 @@ match_until(size_t const len, char const expression[static len], char const deli } // match_until +static inline GVA_String +concat(GVA_Allocator const allocator, + GVA_String lhs, GVA_String const rhs) +{ + size_t const len = lhs.len + rhs.len; + lhs.str = allocator.allocate(allocator.context, lhs.str, lhs.len, len); + if (lhs.str == NULL) + { + return (GVA_String) {0, NULL}; + } // if + + memcpy((char*) lhs.str + lhs.len, rhs.str, rhs.len); + lhs.len = len; + return lhs; +} // concat + + size_t gva_parse_spdi(size_t const len, char const expression[static restrict len], GVA_Variant variants[static restrict 1]) @@ -113,3 +132,26 @@ gva_variant_length(GVA_Variant const variant) { return variant.end - variant.start + variant.sequence.len; } // gva_variant_length + + +GVA_String +gva_patch(GVA_Allocator const allocator, + size_t const len_ref, char const reference[static restrict len_ref], + size_t const n, GVA_Variant const variants[static restrict n]) +{ + GVA_String observed = {0, NULL}; + size_t start = 0; + for (size_t i = 0; i < n; ++i) + { + observed = concat(allocator, observed, (GVA_String) {variants[i].start - start, reference + start}); + observed = concat(allocator, observed, variants[i].sequence); + start = variants[i].end; + } // for + + if (start < len_ref) + { + observed = concat(allocator, observed, (GVA_String) {len_ref - start, reference + start}); + } // if + + return observed; +} // gva_patch From cf4a29df15c0ef3a4a29169a8fcd611a3502e279 Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 27 Jun 2025 18:30:18 +0200 Subject: [PATCH 252/704] Formal print format specifier --- include/types.h | 4 ++++ include/variant.h | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/include/types.h b/include/types.h index 4bac456..57b6d21 100644 --- a/include/types.h +++ b/include/types.h @@ -2,10 +2,14 @@ #define GVA_TYPES_H +#include // PRIu32 #include // size_t #include // uint32_t, UINT32_MAX +#define GVA_UINT_FMT PRIu32 + + // An unsigned integer type to store any position on a reference // sequence. For human DNA a 32-bit value is enough. // Smaller integer types reduce storage requirements. diff --git a/include/variant.h b/include/variant.h index b2975c6..cde26e3 100644 --- a/include/variant.h +++ b/include/variant.h @@ -5,11 +5,11 @@ #include // size_t -#include "types.h" // GVA_String +#include "types.h" // GVA_UINT_FMT, GVA_String #define GVA_VARIANT_PRINT(variant) variant.start, variant.end, (int) variant.sequence.len, variant.sequence.str -#define GVA_VARIANT_FMT "%u:%u/%.*s" +#define GVA_VARIANT_FMT "%" GVA_UINT_FMT ":%" GVA_UINT_FMT "/%.*s" typedef struct From 7efbbeaba92fd226a6de6cf39b24672b4c604180 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Tue, 1 Jul 2025 11:20:05 +0200 Subject: [PATCH 253/704] Compare WIP. Seems to work with LCS graph fix (pending). --- include/compare.h | 15 +++ include/relations.h | 25 +++++ src/compare.c | 222 ++++++++++++++++++++++++++++++++++++++++++++ src/main.c | 83 ++++++++++++++--- 4 files changed, 330 insertions(+), 15 deletions(-) create mode 100644 include/compare.h create mode 100644 include/relations.h create mode 100644 src/compare.c diff --git a/include/compare.h b/include/compare.h new file mode 100644 index 0000000..9ae4699 --- /dev/null +++ b/include/compare.h @@ -0,0 +1,15 @@ +#ifndef GVA_COMPARE_H +#define GVA_COMPARE_H + + +#include "allocator.h" // GVA_Allocator +#include "relations.h" // GVA_Relation +#include "variant.h" // GVA_VARIANT + + +GVA_Relation +gva_compare(GVA_Allocator const allocator, size_t const len_ref, char const reference[static len_ref], + GVA_Variant const lhs, GVA_Variant const rhs); + + +#endif // GVA_COMPARE_H \ No newline at end of file diff --git a/include/relations.h b/include/relations.h new file mode 100644 index 0000000..5bb0c4a --- /dev/null +++ b/include/relations.h @@ -0,0 +1,25 @@ +#ifndef GVA_RELATIONS_H +#define GVA_RELATIONS_H + + +typedef enum +{ + GVA_DISJOINT, + GVA_OVERLAP, + GVA_CONTAINS, + GVA_IS_CONTAINED, + GVA_EQUIVALENT, +} GVA_Relation; + + +static char const* const GVA_RELATION_LABELS[] = +{ + [GVA_DISJOINT] = "disjoint", + [GVA_OVERLAP] = "overlap", + [GVA_CONTAINS] = "contains", + [GVA_IS_CONTAINED] = "is_contained", + [GVA_EQUIVALENT] = "equivalent", +}; + + +#endif // GVA_RELATIONS_H \ No newline at end of file diff --git a/src/compare.c b/src/compare.c new file mode 100644 index 0000000..33a9108 --- /dev/null +++ b/src/compare.c @@ -0,0 +1,222 @@ +#include +#include // memcpy, strncmp +#include "../include/allocator.h" // GVA_Allocator +#include "../include/edit.h" // gva_edit_distance +#include "../include/lcs_graph.h" // GVA_LCS_Graph, gva_lcs_graph_*, gva_edges +#include "../include/relations.h" // GVA_Relation, GVA_DISJOINT +#include "../include/variant.h" // GVA_Variant +#include "array.h" // ARRAY_DESTROY, array_length +#include "common.h" // GVA_NULL, gva_uint, MAX, MIN +#include "bitset.h" // bitset_* + + +void bitfill(GVA_LCS_Graph graph, gva_uint start, size_t* dels, size_t* as, size_t* cs, size_t* gs, size_t* ts) { + for (size_t i = 0; i < array_length(graph.nodes); ++i) { + for (gva_uint j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) { + GVA_Variant variant; + gva_uint const count = gva_edges(graph.observed.str, + graph.nodes[i], graph.nodes[graph.edges[j].tail], + i == graph.source, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, + &variant); +// fprintf(stderr, "count: %d\n", count); +// fprintf(stderr, "\"" GVA_VARIANT_FMT "\"\n", GVA_VARIANT_PRINT(variant)); +// printf("variant start: %d end: %d str: %s \n", variant.start, variant.end, variant.sequence.str); + for (gva_uint z = 0; z < count; ++z) + { + for (gva_uint k = variant.start; k < variant.end; ++k) { + bitset_add(dels, k + z - start); + } // for + } + size_t mask = 0x0; + for (size_t k = 0; k < variant.sequence.len && mask < 0xFULL; ++k) { + if (variant.sequence.str[k] == 'A') { + mask |= 0x1ULL; + } // if + else if (variant.sequence.str[k] == 'C') { + mask |= 0x2ULL; + } // if + else if (variant.sequence.str[k] == 'G') { + mask |= 0x4ULL; + } // if + else if (variant.sequence.str[k] == 'T') { + mask |= 0x8ULL; + } // if + } // for + + if ((mask & 0x1ULL) == 0x1ULL) { + for (gva_uint k = variant.start; k < variant.end + count; ++k) { + bitset_add(as, k - start); + } // for + } // if + if ((mask & 0x2ULL) == 0x2ULL) { + for (gva_uint k = variant.start; k < variant.end + count; ++k) { + bitset_add(cs, k - start); + } // for + } // if + if ((mask & 0x4ULL) == 0x4ULL) { + for (gva_uint k = variant.start; k < variant.end + count; ++k) { + bitset_add(gs, k - start); + } // for + } // if + if ((mask & 0x8ULL) == 0x8ULL) { + for (gva_uint k = variant.start; k < variant.end + count; ++k) { + bitset_add(ts, k - start); + } // for + } // if + } // for + } // for +} + +GVA_Relation +gva_compare(GVA_Allocator const allocator, + size_t const len_ref, char const reference[static len_ref], + GVA_Variant const lhs, GVA_Variant const rhs) +{ + GVA_Relation relation; + + if (lhs.start == rhs.start && lhs.end == rhs.end && + lhs.sequence.len == rhs.sequence.len && + strncmp(lhs.sequence.str, rhs.sequence.str, MIN(lhs.sequence.len, rhs.sequence.len)) == 0) + { + return GVA_EQUIVALENT; + } + + if (lhs.start > rhs.end || rhs.start > lhs.end) + { + return GVA_DISJOINT; + } + + size_t const start = MIN(lhs.start, rhs.start); + size_t const end = MAX(lhs.end, rhs.end); +// fprintf(stderr, "start: %zu end: %zu\n", start, end); + + size_t const lhs_len = (lhs.start - start) + lhs.sequence.len + (end - lhs.end); +// fprintf(stderr, "lhs_len: %zu\n", lhs_len); + char* lhs_obs = allocator.allocate(allocator.context, NULL, 0, lhs_len); + if (lhs_len > 0 && lhs_obs == NULL) + { + return -1; + } + + size_t const rhs_len = (rhs.start - start) + rhs.sequence.len + (end - rhs.end); +// fprintf(stderr, "rhs_len: %zu\n", rhs_len); + char* rhs_obs = allocator.allocate(allocator.context, NULL, 0, rhs_len); + if (rhs_len > 0 && rhs_obs == NULL) + { + lhs_obs = allocator.allocate(allocator.context, lhs_obs, lhs_len, 0); + return -1; + } + + size_t const lhs_dist = gva_edit_distance(allocator, lhs.end - lhs.start, reference + lhs.start, lhs.sequence.len, lhs.sequence.str); + size_t const rhs_dist = gva_edit_distance(allocator, rhs.end - rhs.start, reference + rhs.start, rhs.sequence.len, rhs.sequence.str); + + memcpy(lhs_obs, reference + start, lhs.start - start); + memcpy(lhs_obs + lhs.start - start, lhs.sequence.str, lhs.sequence.len); + memcpy(lhs_obs + lhs.start - start + lhs.sequence.len, reference + lhs.end, end - lhs.end); + +// fprintf(stderr, "lhs_obs(%zu): %.*s\n", lhs_len, (int) lhs_len, lhs_obs); + + memcpy(rhs_obs, reference + start, rhs.start - start); + memcpy(rhs_obs + rhs.start - start, rhs.sequence.str, rhs.sequence.len); + memcpy(rhs_obs + rhs.start - start + rhs.sequence.len, reference + rhs.end, end - rhs.end); + +// fprintf(stderr, "rhs_obs(%zu): %.*s\n", rhs_len, (int) rhs_len, rhs_obs); + + size_t const dist = gva_edit_distance(allocator, lhs_len, lhs_obs, rhs_len, rhs_obs); + +// fprintf(stderr, "distances: %zu, %zu, %zu\n", lhs_dist, rhs_dist, dist); + + if (lhs_dist + rhs_dist == dist) + { + relation = GVA_DISJOINT; + } // + else if (lhs_dist - rhs_dist == dist) + { + relation = GVA_CONTAINS; + } // if + else if (rhs_dist - lhs_dist == dist) + { + relation = GVA_IS_CONTAINED; + } // if + else { + + // inject random bits + GVA_LCS_Graph lhs_graph = gva_lcs_graph_init(allocator, end - start, reference + start, lhs_len, lhs_obs, start); + GVA_LCS_Graph rhs_graph = gva_lcs_graph_init(allocator, end - start, reference + start, rhs_len, rhs_obs, start); + + gva_uint lhs_sup_len = end - start; +// fprintf(stderr, "lhs suplen %d\n", lhs_sup_len); + size_t* lhs_dels = bitset_init(allocator, lhs_sup_len + 1); // can be one shorter + size_t* lhs_as = bitset_init(allocator, lhs_sup_len + 1); + size_t* lhs_cs = bitset_init(allocator, lhs_sup_len + 1); + size_t* lhs_gs = bitset_init(allocator, lhs_sup_len + 1); + size_t* lhs_ts = bitset_init(allocator, lhs_sup_len + 1); + + gva_uint rhs_sup_len = end - start; +// fprintf(stderr, "rhs suplen %d\n", rhs_sup_len); + size_t* rhs_dels = bitset_init(allocator, rhs_sup_len + 1); // can be one shorter + size_t* rhs_as = bitset_init(allocator, rhs_sup_len + 1); + size_t* rhs_cs = bitset_init(allocator, rhs_sup_len + 1); + size_t* rhs_gs = bitset_init(allocator, rhs_sup_len + 1); + size_t* rhs_ts = bitset_init(allocator, rhs_sup_len + 1); + + // could be done on intersection instead of union + bitfill(lhs_graph, start, lhs_dels, lhs_as, lhs_cs, lhs_gs, lhs_ts); + gva_lcs_graph_destroy(allocator, lhs_graph); + +// for (size_t i = 0; i < array_length(lhs_dels); ++i) +// { +// fprintf(stderr, "%2zu: %016zx\n", i, lhs_dels[i]); +// fprintf(stderr, "%2zu: %016zx\n", i, lhs_as[i]); +// fprintf(stderr, "%2zu: %016zx\n", i, lhs_cs[i]); +// fprintf(stderr, "%2zu: %016zx\n", i, lhs_gs[i]); +// fprintf(stderr, "%2zu: %016zx\n", i, lhs_ts[i]); +// } // for + + bitfill(rhs_graph, start, rhs_dels, rhs_as, rhs_cs, rhs_gs, rhs_ts); + gva_lcs_graph_destroy(allocator, rhs_graph); + +// for (size_t i = 0; i < array_length(rhs_dels); ++i) +// { +// fprintf(stderr, "%2zu: %016zx\n", i, rhs_dels[i]); +// fprintf(stderr, "%2zu: %016zx\n", i, rhs_as[i]); +// fprintf(stderr, "%2zu: %016zx\n", i, rhs_cs[i]); +// fprintf(stderr, "%2zu: %016zx\n", i, rhs_gs[i]); +// fprintf(stderr, "%2zu: %016zx\n", i, rhs_ts[i]); +// } // for + + + size_t const common = + bitset_intersection_cnt(lhs_dels, rhs_dels) + + bitset_intersection_cnt(lhs_as, rhs_as) + + bitset_intersection_cnt(lhs_cs, rhs_cs) + + bitset_intersection_cnt(lhs_gs, rhs_gs) + + bitset_intersection_cnt(lhs_ts, rhs_ts); + + lhs_ts = bitset_destroy(allocator, lhs_ts); + lhs_gs = bitset_destroy(allocator, lhs_gs); + lhs_cs = bitset_destroy(allocator, lhs_cs); + lhs_as = bitset_destroy(allocator, lhs_as); + lhs_dels = bitset_destroy(allocator, lhs_dels); + + rhs_ts = bitset_destroy(allocator, rhs_ts); + rhs_gs = bitset_destroy(allocator, rhs_gs); + rhs_cs = bitset_destroy(allocator, rhs_cs); + rhs_as = bitset_destroy(allocator, rhs_as); + rhs_dels = bitset_destroy(allocator, rhs_dels); + + if (common > 0) + { + relation = GVA_OVERLAP; + } + else { + relation = GVA_DISJOINT; + } + + } // else + + rhs_obs = allocator.allocate(allocator.context, rhs_obs, rhs_len, 0); + lhs_obs = allocator.allocate(allocator.context, lhs_obs, lhs_len, 0); + + return relation; +} \ No newline at end of file diff --git a/src/main.c b/src/main.c index 21bf7fe..237fba9 100644 --- a/src/main.c +++ b/src/main.c @@ -4,6 +4,7 @@ #include // strlen +#include "../include/compare.h" #include "../include/edit.h" // gva_edit_distance #include "../include/extract.h" // gva_extract #include "../include/lcs_graph.h" // GVA_LCS_Graph, GVA_Variant, gva_lcs_graph_*, gva_edges @@ -212,6 +213,58 @@ lcs_graph_raw(FILE* const stream, GVA_LCS_Graph const graph) int main(int argc, char* argv[static argc + 1]) { + GVA_String seq = {0, NULL}; + FILE* const restrict stream = fopen("data/NC_000001.11.fasta", "r"); + if (stream != NULL) + { + seq = gva_fasta_sequence(gva_std_allocator, stream); + fclose(stream); + } // if + + // NC_000001.11:169556314:6:TTTTTCTCT 3 NC_000001.11:169556314:8:TTTTTGTCTGGCTGC 7 4 is_contained + char lhs_spdi[4096]; + size_t lhs_dist; + char rhs_spdi[4096]; + size_t rhs_dist; + size_t dist; + char python[32]; + size_t count = 0; + while (fscanf(stdin, "%4096s %zu %4096s %zu %zu %32s\n", lhs_spdi, &lhs_dist, rhs_spdi, &rhs_dist, &dist, python) == 6) + { + GVA_Variant lhs; + if (!gva_parse_spdi(strlen(lhs_spdi), lhs_spdi, &lhs)) + { + fprintf(stderr, "PARSE ERROR: %s\n", lhs_spdi); + continue; + } // if + GVA_Variant rhs; + if (!gva_parse_spdi(strlen(rhs_spdi), rhs_spdi, &rhs)) + { + fprintf(stderr, "PARSE ERROR: %s\n", rhs_spdi); + continue; + } // if + count += 1; +// printf("%d\n", gva_compare(gva_std_allocator, seq.len, seq.str, lhs, rhs)); + if (strcmp(python, GVA_RELATION_LABELS[gva_compare(gva_std_allocator, seq.len, seq.str, lhs, rhs)]) != 0) + { + printf("different %s %zu %s %zu %zu %s %s\n", lhs_spdi, lhs_dist, rhs_spdi, rhs_dist, dist, python, GVA_RELATION_LABELS[gva_compare(gva_std_allocator, seq.len, seq.str, lhs, rhs)]); + } + + } + printf("%zu\n", count); + + return 0; + + + char const* const r = "CCACC"; + GVA_Variant lhs = {1, 1, {1, "T"}}; + GVA_Variant rhs = {1, 1, {1, "G"}}; + + printf("%s\n", GVA_RELATION_LABELS[gva_compare(gva_std_allocator, strlen(r), r, lhs, rhs)]); +// return gva_compare(gva_std_allocator, strlen(r), r, lhs, rhs); + + return 0; + /* GVA_String seq = {NULL, 0}; FILE* const restrict stream = fopen("data/NC_000001.11.fasta", "r"); @@ -304,48 +357,48 @@ main(int argc, char* argv[static argc + 1]) { bitset_add(dels, k - graph.supremal.start); } // for - size_t mask = 0; - for (size_t k = 0; k < variant.sequence.len; ++k) + size_t mask = 0x0; + for (size_t k = 0; k < variant.sequence.len && mask < 0xFULL; ++k) { if (variant.sequence.str[k] == 'A') { - mask |= 1; + mask |= 0x1ULL; } // if else if (variant.sequence.str[k] == 'C') { - mask |= 2; + mask |= 0x2ULL; } // if else if (variant.sequence.str[k] == 'G') { - mask |= 4; + mask |= 0x4ULL; } // if else if (variant.sequence.str[k] == 'T') { - mask |= 8; + mask |= 0x8ULL; } // if } // for - if ((mask & 1) == 1) + if ((mask & 0x1ULL) == 0x1ULL) { for (gva_uint k = variant.start; k < variant.end + count; ++k) { bitset_add(as, k - graph.supremal.start); } // for } // if - if ((mask & 2) == 2) + if ((mask & 0x2ULL) == 0x2ULL) { for (gva_uint k = variant.start; k < variant.end + count; ++k) { bitset_add(cs, k - graph.supremal.start); } // for } // if - if ((mask & 4) == 4) + if ((mask & 0x4ULL) == 0x4ULL) { for (gva_uint k = variant.start; k < variant.end + count; ++k) { bitset_add(gs, k - graph.supremal.start); } // for } // if - if ((mask & 8) == 8) + if ((mask & 0x8ULL) == 0x8ULL) { for (gva_uint k = variant.start; k < variant.end + count; ++k) { @@ -357,11 +410,11 @@ main(int argc, char* argv[static argc + 1]) for (size_t i = 0; i < array_length(dels); ++i) { - fprintf(stderr, "%2zu: %064zx\n", i, dels[i]); - fprintf(stderr, "%2zu: %064zx\n", i, as[i]); - fprintf(stderr, "%2zu: %064zx\n", i, cs[i]); - fprintf(stderr, "%2zu: %064zx\n", i, gs[i]); - fprintf(stderr, "%2zu: %064zx\n", i, ts[i]); + fprintf(stderr, "%2zu: %016zx\n", i, dels[i]); + fprintf(stderr, "%2zu: %016zx\n", i, as[i]); + fprintf(stderr, "%2zu: %016zx\n", i, cs[i]); + fprintf(stderr, "%2zu: %016zx\n", i, gs[i]); + fprintf(stderr, "%2zu: %016zx\n", i, ts[i]); } // for ts = bitset_destroy(gva_std_allocator, ts); From 2a859e96fba3c5f123e8afb974084668cd1c25fb Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Tue, 1 Jul 2025 11:34:50 +0200 Subject: [PATCH 254/704] Correct positions in sink and source for graphs without matches. --- src/lcs_graph.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lcs_graph.c b/src/lcs_graph.c index 85be443..6cdc3e6 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -51,7 +51,7 @@ gva_lcs_graph_init(GVA_Allocator const allocator, if (lcs.nodes == NULL || graph.distance == 0) { gva_uint const sink = ARRAY_APPEND(allocator, graph.nodes, ((GVA_Node) { - len_ref, len_obs, 0, GVA_NULL, GVA_NULL + len_ref + shift, len_obs, 0, GVA_NULL, GVA_NULL })) - 1; if ((len_ref == 0 && len_obs == 0) || graph.distance == 0) { @@ -78,9 +78,9 @@ gva_lcs_graph_init(GVA_Allocator const allocator, shift, 0, 0, GVA_NULL, GVA_NULL })); ARRAY_APPEND(allocator, graph.local_supremal, ((GVA_Node) { - len_ref, len_obs, 0, GVA_NULL, GVA_NULL + len_ref + shift, len_obs, 0, GVA_NULL, GVA_NULL })); - graph.supremal = (GVA_Variant) {shift, len_ref, {len_obs, observed}}; + graph.supremal = (GVA_Variant) {shift, len_ref + shift, {len_obs, observed}}; return graph; } // if From 66664448c8370fa97a0216dcde5755d55c8296e3 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Tue, 1 Jul 2025 14:09:15 +0200 Subject: [PATCH 255/704] Cut bitfill in half. --- src/compare.c | 76 ++++++++++++++++++++++++--------------------------- 1 file changed, 35 insertions(+), 41 deletions(-) diff --git a/src/compare.c b/src/compare.c index 33a9108..1456c43 100644 --- a/src/compare.c +++ b/src/compare.c @@ -1,5 +1,5 @@ #include -#include // memcpy, strncmp +#include // memchr, memcpy, strncmp #include "../include/allocator.h" // GVA_Allocator #include "../include/edit.h" // gva_edit_distance #include "../include/lcs_graph.h" // GVA_LCS_Graph, gva_lcs_graph_*, gva_edges @@ -10,56 +10,50 @@ #include "bitset.h" // bitset_* -void bitfill(GVA_LCS_Graph graph, gva_uint start, size_t* dels, size_t* as, size_t* cs, size_t* gs, size_t* ts) { - for (size_t i = 0; i < array_length(graph.nodes); ++i) { - for (gva_uint j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) { +static void +bitfill(GVA_LCS_Graph graph, gva_uint start, size_t* dels, size_t* as, size_t* cs, size_t* gs, size_t* ts) +{ + for (size_t i = 0; i < array_length(graph.nodes); ++i) + { + for (gva_uint j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) + { GVA_Variant variant; gva_uint const count = gva_edges(graph.observed.str, graph.nodes[i], graph.nodes[graph.edges[j].tail], i == graph.source, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, &variant); -// fprintf(stderr, "count: %d\n", count); -// fprintf(stderr, "\"" GVA_VARIANT_FMT "\"\n", GVA_VARIANT_PRINT(variant)); -// printf("variant start: %d end: %d str: %s \n", variant.start, variant.end, variant.sequence.str); for (gva_uint z = 0; z < count; ++z) { - for (gva_uint k = variant.start; k < variant.end; ++k) { + for (gva_uint k = variant.start; k < variant.end; ++k) + { bitset_add(dels, k + z - start); } // for - } - size_t mask = 0x0; - for (size_t k = 0; k < variant.sequence.len && mask < 0xFULL; ++k) { - if (variant.sequence.str[k] == 'A') { - mask |= 0x1ULL; - } // if - else if (variant.sequence.str[k] == 'C') { - mask |= 0x2ULL; - } // if - else if (variant.sequence.str[k] == 'G') { - mask |= 0x4ULL; - } // if - else if (variant.sequence.str[k] == 'T') { - mask |= 0x8ULL; - } // if } // for - - if ((mask & 0x1ULL) == 0x1ULL) { - for (gva_uint k = variant.start; k < variant.end + count; ++k) { + if (memchr(variant.sequence.str, 'A', variant.sequence.len)) + { + for (gva_uint k = variant.start; k < variant.end + count; ++k) + { bitset_add(as, k - start); } // for } // if - if ((mask & 0x2ULL) == 0x2ULL) { - for (gva_uint k = variant.start; k < variant.end + count; ++k) { + if (memchr(variant.sequence.str, 'C', variant.sequence.len)) + { + for (gva_uint k = variant.start; k < variant.end + count; ++k) + { bitset_add(cs, k - start); } // for } // if - if ((mask & 0x4ULL) == 0x4ULL) { - for (gva_uint k = variant.start; k < variant.end + count; ++k) { + if (memchr(variant.sequence.str, 'G', variant.sequence.len)) + { + for (gva_uint k = variant.start; k < variant.end + count; ++k) + { bitset_add(gs, k - start); } // for } // if - if ((mask & 0x8ULL) == 0x8ULL) { - for (gva_uint k = variant.start; k < variant.end + count; ++k) { + if (memchr(variant.sequence.str, 'T', variant.sequence.len)) + { + for (gva_uint k = variant.start; k < variant.end + count; ++k) + { bitset_add(ts, k - start); } // for } // if @@ -185,7 +179,6 @@ gva_compare(GVA_Allocator const allocator, // fprintf(stderr, "%2zu: %016zx\n", i, rhs_ts[i]); // } // for - size_t const common = bitset_intersection_cnt(lhs_dels, rhs_dels) + bitset_intersection_cnt(lhs_as, rhs_as) + @@ -193,6 +186,15 @@ gva_compare(GVA_Allocator const allocator, bitset_intersection_cnt(lhs_gs, rhs_gs) + bitset_intersection_cnt(lhs_ts, rhs_ts); + if (common > 0) + { + relation = GVA_OVERLAP; + } // if + else + { + relation = GVA_DISJOINT; + } // else + lhs_ts = bitset_destroy(allocator, lhs_ts); lhs_gs = bitset_destroy(allocator, lhs_gs); lhs_cs = bitset_destroy(allocator, lhs_cs); @@ -205,14 +207,6 @@ gva_compare(GVA_Allocator const allocator, rhs_as = bitset_destroy(allocator, rhs_as); rhs_dels = bitset_destroy(allocator, rhs_dels); - if (common > 0) - { - relation = GVA_OVERLAP; - } - else { - relation = GVA_DISJOINT; - } - } // else rhs_obs = allocator.allocate(allocator.context, rhs_obs, rhs_len, 0); From 07ebd2bba500fa7abafafdf94475ce953dba5f55 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Tue, 1 Jul 2025 14:09:39 +0200 Subject: [PATCH 256/704] Deallocate reference. --- src/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main.c b/src/main.c index 237fba9..2afc7e5 100644 --- a/src/main.c +++ b/src/main.c @@ -252,6 +252,7 @@ main(int argc, char* argv[static argc + 1]) } printf("%zu\n", count); + seq.str = gva_std_allocator.allocate(gva_std_allocator.context, seq.str, seq.len, 0); return 0; From 2a84b572287a7d8fa4cf9f1c03010969819f1328 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Tue, 1 Jul 2025 15:41:58 +0200 Subject: [PATCH 257/704] Skip unrelated edges. --- src/compare.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/compare.c b/src/compare.c index 1456c43..ebcfe3c 100644 --- a/src/compare.c +++ b/src/compare.c @@ -11,12 +11,16 @@ static void -bitfill(GVA_LCS_Graph graph, gva_uint start, size_t* dels, size_t* as, size_t* cs, size_t* gs, size_t* ts) +bitfill(GVA_LCS_Graph graph, gva_uint start, gva_uint start_accent, gva_uint end_accent, size_t* dels, size_t* as, size_t* cs, size_t* gs, size_t* ts) { for (size_t i = 0; i < array_length(graph.nodes); ++i) { for (gva_uint j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) { + if (graph.nodes[i].row > end_accent || graph.nodes[graph.edges[j].tail].row + graph.nodes[graph.edges[j].tail].length <= start_accent) + { + continue; + } GVA_Variant variant; gva_uint const count = gva_edges(graph.observed.str, graph.nodes[i], graph.nodes[graph.edges[j].tail], @@ -154,8 +158,11 @@ gva_compare(GVA_Allocator const allocator, size_t* rhs_gs = bitset_init(allocator, rhs_sup_len + 1); size_t* rhs_ts = bitset_init(allocator, rhs_sup_len + 1); + size_t const start_accent = MAX(lhs.start, rhs.start); + size_t const end_accent = MIN(lhs.end, rhs.end); + // could be done on intersection instead of union - bitfill(lhs_graph, start, lhs_dels, lhs_as, lhs_cs, lhs_gs, lhs_ts); + bitfill(lhs_graph, start, start_accent, end_accent, lhs_dels, lhs_as, lhs_cs, lhs_gs, lhs_ts); gva_lcs_graph_destroy(allocator, lhs_graph); // for (size_t i = 0; i < array_length(lhs_dels); ++i) @@ -167,7 +174,7 @@ gva_compare(GVA_Allocator const allocator, // fprintf(stderr, "%2zu: %016zx\n", i, lhs_ts[i]); // } // for - bitfill(rhs_graph, start, rhs_dels, rhs_as, rhs_cs, rhs_gs, rhs_ts); + bitfill(rhs_graph, start, start_accent, end_accent, rhs_dels, rhs_as, rhs_cs, rhs_gs, rhs_ts); gva_lcs_graph_destroy(allocator, rhs_graph); // for (size_t i = 0; i < array_length(rhs_dels); ++i) From ea10f07c696c22fbb69e2bcbbe32f20f79d71865 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Tue, 1 Jul 2025 15:42:18 +0200 Subject: [PATCH 258/704] What do to with this?! --- src/lcs_graph.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/lcs_graph.c b/src/lcs_graph.c index 6cdc3e6..d8dac81 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -273,7 +273,8 @@ gva_lcs_graph_init(GVA_Allocator const allocator, graph.nodes[source.idx].col += graph.local_supremal[0].length; graph.nodes[source.idx].length -= graph.local_supremal[0].length; - graph.nodes[0].length -= len; + // TODO: what to do with length?! + // graph.nodes[0].length -= len; gva_edges(graph.observed.str, graph.local_supremal[0], graph.local_supremal[array_length(graph.local_supremal) - 1], From c59f07715eac7b5aebddad6852b82d5c2caa2fc1 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Tue, 1 Jul 2025 16:37:11 +0200 Subject: [PATCH 259/704] Remove bitset stuff from main. --- src/main.c | 84 ------------------------------------------------------ 1 file changed, 84 deletions(-) diff --git a/src/main.c b/src/main.c index 2afc7e5..3eed1ec 100644 --- a/src/main.c +++ b/src/main.c @@ -339,90 +339,6 @@ main(int argc, char* argv[static argc + 1]) } // for canonical = ARRAY_DESTROY(gva_std_allocator, canonical); - size_t* dels = bitset_init(gva_std_allocator, graph.supremal.end - graph.supremal.start); - size_t* as = bitset_init(gva_std_allocator, graph.supremal.end - graph.supremal.start + 1); - size_t* cs = bitset_init(gva_std_allocator, graph.supremal.end - graph.supremal.start + 1); - size_t* gs = bitset_init(gva_std_allocator, graph.supremal.end - graph.supremal.start + 1); - size_t* ts = bitset_init(gva_std_allocator, graph.supremal.end - graph.supremal.start + 1); - - for (size_t i = 0; i < array_length(graph.nodes); ++i) - { - for (gva_uint j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) - { - GVA_Variant variant; - gva_uint const count = gva_edges(graph.observed.str, - graph.nodes[i], graph.nodes[graph.edges[j].tail], - i == graph.source, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, - &variant); - for (gva_uint k = variant.start; k < variant.end + count - 1; ++k) - { - bitset_add(dels, k - graph.supremal.start); - } // for - size_t mask = 0x0; - for (size_t k = 0; k < variant.sequence.len && mask < 0xFULL; ++k) - { - if (variant.sequence.str[k] == 'A') - { - mask |= 0x1ULL; - } // if - else if (variant.sequence.str[k] == 'C') - { - mask |= 0x2ULL; - } // if - else if (variant.sequence.str[k] == 'G') - { - mask |= 0x4ULL; - } // if - else if (variant.sequence.str[k] == 'T') - { - mask |= 0x8ULL; - } // if - } // for - if ((mask & 0x1ULL) == 0x1ULL) - { - for (gva_uint k = variant.start; k < variant.end + count; ++k) - { - bitset_add(as, k - graph.supremal.start); - } // for - } // if - if ((mask & 0x2ULL) == 0x2ULL) - { - for (gva_uint k = variant.start; k < variant.end + count; ++k) - { - bitset_add(cs, k - graph.supremal.start); - } // for - } // if - if ((mask & 0x4ULL) == 0x4ULL) - { - for (gva_uint k = variant.start; k < variant.end + count; ++k) - { - bitset_add(gs, k - graph.supremal.start); - } // for - } // if - if ((mask & 0x8ULL) == 0x8ULL) - { - for (gva_uint k = variant.start; k < variant.end + count; ++k) - { - bitset_add(ts, k - graph.supremal.start); - } // for - } // if - } // for - } // for - - for (size_t i = 0; i < array_length(dels); ++i) - { - fprintf(stderr, "%2zu: %016zx\n", i, dels[i]); - fprintf(stderr, "%2zu: %016zx\n", i, as[i]); - fprintf(stderr, "%2zu: %016zx\n", i, cs[i]); - fprintf(stderr, "%2zu: %016zx\n", i, gs[i]); - fprintf(stderr, "%2zu: %016zx\n", i, ts[i]); - } // for - - ts = bitset_destroy(gva_std_allocator, ts); - gs = bitset_destroy(gva_std_allocator, gs); - cs = bitset_destroy(gva_std_allocator, cs); - as = bitset_destroy(gva_std_allocator, as); - dels = bitset_destroy(gva_std_allocator, dels); /* size_t const distance = gva_edit_distance(gva_std_allocator, len_ref, reference, len_obs, observed); From 8e82a358c140379367fbeb65199882dde321d267 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Tue, 1 Jul 2025 16:43:25 +0200 Subject: [PATCH 260/704] Restructure main. --- src/main.c | 43 ++++++++++++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/src/main.c b/src/main.c index 3eed1ec..d91e338 100644 --- a/src/main.c +++ b/src/main.c @@ -209,9 +209,8 @@ lcs_graph_raw(FILE* const stream, GVA_LCS_Graph const graph) } // for } // lcs_graph_raw - int -main(int argc, char* argv[static argc + 1]) +compare() { GVA_String seq = {0, NULL}; FILE* const restrict stream = fopen("data/NC_000001.11.fasta", "r"); @@ -245,29 +244,25 @@ main(int argc, char* argv[static argc + 1]) } // if count += 1; // printf("%d\n", gva_compare(gva_std_allocator, seq.len, seq.str, lhs, rhs)); + if (strcmp(python, GVA_RELATION_LABELS[gva_compare(gva_std_allocator, seq.len, seq.str, lhs, rhs)]) != 0) { printf("different %s %zu %s %zu %zu %s %s\n", lhs_spdi, lhs_dist, rhs_spdi, rhs_dist, dist, python, GVA_RELATION_LABELS[gva_compare(gva_std_allocator, seq.len, seq.str, lhs, rhs)]); } +// printf("%s %s\n", lhs_spdi, rhs_spdi); } printf("%zu\n", count); seq.str = gva_std_allocator.allocate(gva_std_allocator.context, seq.str, seq.len, 0); return 0; +} - char const* const r = "CCACC"; - GVA_Variant lhs = {1, 1, {1, "T"}}; - GVA_Variant rhs = {1, 1, {1, "G"}}; - - printf("%s\n", GVA_RELATION_LABELS[gva_compare(gva_std_allocator, strlen(r), r, lhs, rhs)]); -// return gva_compare(gva_std_allocator, strlen(r), r, lhs, rhs); - - return 0; - - /* - GVA_String seq = {NULL, 0}; +int +all_graphs() +{ + GVA_String seq = {0, NULL}; FILE* const restrict stream = fopen("data/NC_000001.11.fasta", "r"); if (stream != NULL) { @@ -308,8 +303,12 @@ main(int argc, char* argv[static argc + 1]) seq.str = gva_std_allocator.allocate(gva_std_allocator.context, seq.str, seq.len, 0); return EXIT_SUCCESS; - */ +} + +int +extract(int argc, char* argv[static argc + 1]) +{ if (argc != 3) { fprintf(stderr, "usage %s reference observed\n", argv[0]); @@ -339,7 +338,6 @@ main(int argc, char* argv[static argc + 1]) } // for canonical = ARRAY_DESTROY(gva_std_allocator, canonical); - /* size_t const distance = gva_edit_distance(gva_std_allocator, len_ref, reference, len_obs, observed); fprintf(stderr, "distance only: %zu\n", distance); @@ -348,4 +346,19 @@ main(int argc, char* argv[static argc + 1]) gva_lcs_graph_destroy(gva_std_allocator, graph); return EXIT_SUCCESS; + +} + +int +main(int argc, char* argv[static argc + 1]) +{ + //check python relation output + return compare(); + + //calcuate graphs for all inputs + //return all_graphs(); + + //extract single variant + //return extract(argc, argv); + } // main From 43ba1a9da9e9900615e60788fffd1af126061667 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 1 Jul 2025 17:09:27 +0200 Subject: [PATCH 261/704] Style --- include/compare.h | 7 ++++--- src/compare.c | 52 ++++++++++++++++++++++++++++++----------------- 2 files changed, 37 insertions(+), 22 deletions(-) diff --git a/include/compare.h b/include/compare.h index 9ae4699..bed0ac2 100644 --- a/include/compare.h +++ b/include/compare.h @@ -8,8 +8,9 @@ GVA_Relation -gva_compare(GVA_Allocator const allocator, size_t const len_ref, char const reference[static len_ref], - GVA_Variant const lhs, GVA_Variant const rhs); +gva_compare(GVA_Allocator const allocator, + size_t const len_ref, char const reference[static len_ref], + GVA_Variant const lhs, GVA_Variant const rhs); -#endif // GVA_COMPARE_H \ No newline at end of file +#endif // GVA_COMPARE_H diff --git a/src/compare.c b/src/compare.c index ebcfe3c..754e66f 100644 --- a/src/compare.c +++ b/src/compare.c @@ -1,9 +1,15 @@ -#include -#include // memchr, memcpy, strncmp +#include // FIXME: DEBUG + + +#include // NULL, size_t +#include // memchr, memcpy, strncmp + + #include "../include/allocator.h" // GVA_Allocator #include "../include/edit.h" // gva_edit_distance #include "../include/lcs_graph.h" // GVA_LCS_Graph, gva_lcs_graph_*, gva_edges -#include "../include/relations.h" // GVA_Relation, GVA_DISJOINT +#include "../include/relations.h" // GVA_Relation, GVA_CONTAINS, GVA_DISJOINT, + // GVA_EQUIVALENT GVA_IS_CONTAINED, GVA_OVERLAP #include "../include/variant.h" // GVA_Variant #include "array.h" // ARRAY_DESTROY, array_length #include "common.h" // GVA_NULL, gva_uint, MAX, MIN @@ -11,7 +17,13 @@ static void -bitfill(GVA_LCS_Graph graph, gva_uint start, gva_uint start_accent, gva_uint end_accent, size_t* dels, size_t* as, size_t* cs, size_t* gs, size_t* ts) +bitfill(GVA_LCS_Graph const graph, + gva_uint const start, gva_uint const start_accent, gva_uint const end_accent, + size_t dels[static restrict 1], + size_t as[static restrict 1], + size_t cs[static restrict 1], + size_t gs[static restrict 1], + size_t ts[static restrict 1]) { for (size_t i = 0; i < array_length(graph.nodes); ++i) { @@ -20,7 +32,8 @@ bitfill(GVA_LCS_Graph graph, gva_uint start, gva_uint start_accent, gva_uint end if (graph.nodes[i].row > end_accent || graph.nodes[graph.edges[j].tail].row + graph.nodes[graph.edges[j].tail].length <= start_accent) { continue; - } + } // if + GVA_Variant variant; gva_uint const count = gva_edges(graph.observed.str, graph.nodes[i], graph.nodes[graph.edges[j].tail], @@ -33,6 +46,7 @@ bitfill(GVA_LCS_Graph graph, gva_uint start, gva_uint start_accent, gva_uint end bitset_add(dels, k + z - start); } // for } // for + if (memchr(variant.sequence.str, 'A', variant.sequence.len)) { for (gva_uint k = variant.start; k < variant.end + count; ++k) @@ -63,12 +77,13 @@ bitfill(GVA_LCS_Graph graph, gva_uint start, gva_uint start_accent, gva_uint end } // if } // for } // for -} +} // bitfill + GVA_Relation gva_compare(GVA_Allocator const allocator, - size_t const len_ref, char const reference[static len_ref], - GVA_Variant const lhs, GVA_Variant const rhs) + size_t const len_ref, char const reference[static len_ref], + GVA_Variant const lhs, GVA_Variant const rhs) { GVA_Relation relation; @@ -77,12 +92,12 @@ gva_compare(GVA_Allocator const allocator, strncmp(lhs.sequence.str, rhs.sequence.str, MIN(lhs.sequence.len, rhs.sequence.len)) == 0) { return GVA_EQUIVALENT; - } + } // if if (lhs.start > rhs.end || rhs.start > lhs.end) { return GVA_DISJOINT; - } + } // if size_t const start = MIN(lhs.start, rhs.start); size_t const end = MAX(lhs.end, rhs.end); @@ -94,7 +109,7 @@ gva_compare(GVA_Allocator const allocator, if (lhs_len > 0 && lhs_obs == NULL) { return -1; - } + } // if size_t const rhs_len = (rhs.start - start) + rhs.sequence.len + (end - rhs.end); // fprintf(stderr, "rhs_len: %zu\n", rhs_len); @@ -103,7 +118,7 @@ gva_compare(GVA_Allocator const allocator, { lhs_obs = allocator.allocate(allocator.context, lhs_obs, lhs_len, 0); return -1; - } + } // if size_t const lhs_dist = gva_edit_distance(allocator, lhs.end - lhs.start, reference + lhs.start, lhs.sequence.len, lhs.sequence.str); size_t const rhs_dist = gva_edit_distance(allocator, rhs.end - rhs.start, reference + rhs.start, rhs.sequence.len, rhs.sequence.str); @@ -127,7 +142,7 @@ gva_compare(GVA_Allocator const allocator, if (lhs_dist + rhs_dist == dist) { relation = GVA_DISJOINT; - } // + } // if else if (lhs_dist - rhs_dist == dist) { relation = GVA_CONTAINS; @@ -136,13 +151,13 @@ gva_compare(GVA_Allocator const allocator, { relation = GVA_IS_CONTAINED; } // if - else { - + else + { // inject random bits GVA_LCS_Graph lhs_graph = gva_lcs_graph_init(allocator, end - start, reference + start, lhs_len, lhs_obs, start); GVA_LCS_Graph rhs_graph = gva_lcs_graph_init(allocator, end - start, reference + start, rhs_len, rhs_obs, start); - gva_uint lhs_sup_len = end - start; + gva_uint const lhs_sup_len = end - start; // fprintf(stderr, "lhs suplen %d\n", lhs_sup_len); size_t* lhs_dels = bitset_init(allocator, lhs_sup_len + 1); // can be one shorter size_t* lhs_as = bitset_init(allocator, lhs_sup_len + 1); @@ -150,7 +165,7 @@ gva_compare(GVA_Allocator const allocator, size_t* lhs_gs = bitset_init(allocator, lhs_sup_len + 1); size_t* lhs_ts = bitset_init(allocator, lhs_sup_len + 1); - gva_uint rhs_sup_len = end - start; + gva_uint const rhs_sup_len = end - start; // fprintf(stderr, "rhs suplen %d\n", rhs_sup_len); size_t* rhs_dels = bitset_init(allocator, rhs_sup_len + 1); // can be one shorter size_t* rhs_as = bitset_init(allocator, rhs_sup_len + 1); @@ -213,11 +228,10 @@ gva_compare(GVA_Allocator const allocator, rhs_cs = bitset_destroy(allocator, rhs_cs); rhs_as = bitset_destroy(allocator, rhs_as); rhs_dels = bitset_destroy(allocator, rhs_dels); - } // else rhs_obs = allocator.allocate(allocator.context, rhs_obs, rhs_len, 0); lhs_obs = allocator.allocate(allocator.context, lhs_obs, lhs_len, 0); return relation; -} \ No newline at end of file +} // gva_compare From 3faabac6634b0e2f362c0287a94f2680a40897bf Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 1 Jul 2025 17:17:19 +0200 Subject: [PATCH 262/704] More style --- src/main.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/main.c b/src/main.c index d91e338..6a6d6aa 100644 --- a/src/main.c +++ b/src/main.c @@ -1,13 +1,14 @@ #include // NULL, size_t #include // FILE, stderr, fclose, fopen, fprintf #include // EXIT_* -#include // strlen +#include // strcmp, strlen -#include "../include/compare.h" +#include "../include/compare.h" // gva_compare #include "../include/edit.h" // gva_edit_distance #include "../include/extract.h" // gva_extract #include "../include/lcs_graph.h" // GVA_LCS_Graph, GVA_Variant, gva_lcs_graph_*, gva_edges +#include "../include/relations.h" // GVA_RELATION_LABELS #include "../include/std_alloc.h" // gva_std_allocator #include "../include/types.h" // GVA_NULL, GVA_String, gva_uint #include "../include/utils.h" // gva_fasta_sequence @@ -209,8 +210,9 @@ lcs_graph_raw(FILE* const stream, GVA_LCS_Graph const graph) } // for } // lcs_graph_raw -int -compare() + +static int +compare(void) { GVA_String seq = {0, NULL}; FILE* const restrict stream = fopen("data/NC_000001.11.fasta", "r"); @@ -256,11 +258,12 @@ compare() seq.str = gva_std_allocator.allocate(gva_std_allocator.context, seq.str, seq.len, 0); return 0; -} +} // compare +// FIXME: static int -all_graphs() +all_graphs(void) { GVA_String seq = {0, NULL}; FILE* const restrict stream = fopen("data/NC_000001.11.fasta", "r"); @@ -303,11 +306,12 @@ all_graphs() seq.str = gva_std_allocator.allocate(gva_std_allocator.context, seq.str, seq.len, 0); return EXIT_SUCCESS; -} +} // all_graphs +// FIXME: static int -extract(int argc, char* argv[static argc + 1]) +extract(int const argc, char* argv[static argc + 1]) { if (argc != 3) { @@ -346,12 +350,13 @@ extract(int argc, char* argv[static argc + 1]) gva_lcs_graph_destroy(gva_std_allocator, graph); return EXIT_SUCCESS; +} // extract -} int main(int argc, char* argv[static argc + 1]) { + (void) argv; //check python relation output return compare(); @@ -360,5 +365,4 @@ main(int argc, char* argv[static argc + 1]) //extract single variant //return extract(argc, argv); - } // main From da91cd2331d64f5879ccad3635a2538dafb09c97 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Tue, 1 Jul 2025 21:55:09 +0200 Subject: [PATCH 263/704] Move bitfill to bitset.[ch]. --- src/bitset.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++ src/bitset.h | 3 +++ src/compare.c | 58 ++------------------------------------------------- 3 files changed, 61 insertions(+), 56 deletions(-) diff --git a/src/bitset.c b/src/bitset.c index e5fa619..cdeaf1c 100644 --- a/src/bitset.c +++ b/src/bitset.c @@ -48,3 +48,59 @@ bitset_destroy(GVA_Allocator const allocator, size_t bitset[static 1]) { return ARRAY_DESTROY(allocator, bitset); } // bitset_destroy + + +void +bitset_fill(GVA_LCS_Graph graph, gva_uint start, gva_uint start_accent, gva_uint end_accent, size_t* dels, size_t* as, size_t* cs, size_t* gs, size_t* ts) +{ + for (size_t i = 0; i < array_length(graph.nodes); ++i) + { + for (gva_uint j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) + { + if (graph.nodes[i].row > end_accent || graph.nodes[graph.edges[j].tail].row + graph.nodes[graph.edges[j].tail].length <= start_accent) + { + continue; + } + GVA_Variant variant; + gva_uint const count = gva_edges(graph.observed.str, + graph.nodes[i], graph.nodes[graph.edges[j].tail], + i == graph.source, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, + &variant); + for (gva_uint z = 0; z < count; ++z) + { + for (gva_uint k = variant.start; k < variant.end; ++k) + { + bitset_add(dels, k + z - start); + } // for + } // for + if (memchr(variant.sequence.str, 'A', variant.sequence.len)) + { + for (gva_uint k = variant.start; k < variant.end + count; ++k) + { + bitset_add(as, k - start); + } // for + } // if + if (memchr(variant.sequence.str, 'C', variant.sequence.len)) + { + for (gva_uint k = variant.start; k < variant.end + count; ++k) + { + bitset_add(cs, k - start); + } // for + } // if + if (memchr(variant.sequence.str, 'G', variant.sequence.len)) + { + for (gva_uint k = variant.start; k < variant.end + count; ++k) + { + bitset_add(gs, k - start); + } // for + } // if + if (memchr(variant.sequence.str, 'T', variant.sequence.len)) + { + for (gva_uint k = variant.start; k < variant.end + count; ++k) + { + bitset_add(ts, k - start); + } // for + } // if + } // for + } // for +} diff --git a/src/bitset.h b/src/bitset.h index 8155f1e..c6520a5 100644 --- a/src/bitset.h +++ b/src/bitset.h @@ -6,6 +6,7 @@ #include "../include/allocator.h" // GVA_Allocator +#include "../include/lcs_graph.h" // GVA_LCS_Graph size_t* @@ -23,5 +24,7 @@ bitset_intersection_cnt(size_t const lhs[static 1], size_t const rhs[static 1]); size_t* bitset_destroy(GVA_Allocator const allocator, size_t bitset[static 1]); +void +bitset_fill(GVA_LCS_Graph graph, gva_uint start, gva_uint start_accent, gva_uint end_accent, size_t* dels, size_t* as, size_t* cs, size_t* gs, size_t* ts); #endif // GVA_BITSET_H diff --git a/src/compare.c b/src/compare.c index ebcfe3c..f5dfbb8 100644 --- a/src/compare.c +++ b/src/compare.c @@ -10,60 +10,6 @@ #include "bitset.h" // bitset_* -static void -bitfill(GVA_LCS_Graph graph, gva_uint start, gva_uint start_accent, gva_uint end_accent, size_t* dels, size_t* as, size_t* cs, size_t* gs, size_t* ts) -{ - for (size_t i = 0; i < array_length(graph.nodes); ++i) - { - for (gva_uint j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) - { - if (graph.nodes[i].row > end_accent || graph.nodes[graph.edges[j].tail].row + graph.nodes[graph.edges[j].tail].length <= start_accent) - { - continue; - } - GVA_Variant variant; - gva_uint const count = gva_edges(graph.observed.str, - graph.nodes[i], graph.nodes[graph.edges[j].tail], - i == graph.source, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, - &variant); - for (gva_uint z = 0; z < count; ++z) - { - for (gva_uint k = variant.start; k < variant.end; ++k) - { - bitset_add(dels, k + z - start); - } // for - } // for - if (memchr(variant.sequence.str, 'A', variant.sequence.len)) - { - for (gva_uint k = variant.start; k < variant.end + count; ++k) - { - bitset_add(as, k - start); - } // for - } // if - if (memchr(variant.sequence.str, 'C', variant.sequence.len)) - { - for (gva_uint k = variant.start; k < variant.end + count; ++k) - { - bitset_add(cs, k - start); - } // for - } // if - if (memchr(variant.sequence.str, 'G', variant.sequence.len)) - { - for (gva_uint k = variant.start; k < variant.end + count; ++k) - { - bitset_add(gs, k - start); - } // for - } // if - if (memchr(variant.sequence.str, 'T', variant.sequence.len)) - { - for (gva_uint k = variant.start; k < variant.end + count; ++k) - { - bitset_add(ts, k - start); - } // for - } // if - } // for - } // for -} GVA_Relation gva_compare(GVA_Allocator const allocator, @@ -162,7 +108,7 @@ gva_compare(GVA_Allocator const allocator, size_t const end_accent = MIN(lhs.end, rhs.end); // could be done on intersection instead of union - bitfill(lhs_graph, start, start_accent, end_accent, lhs_dels, lhs_as, lhs_cs, lhs_gs, lhs_ts); + bitset_fill(lhs_graph, start, start_accent, end_accent, lhs_dels, lhs_as, lhs_cs, lhs_gs, lhs_ts); gva_lcs_graph_destroy(allocator, lhs_graph); // for (size_t i = 0; i < array_length(lhs_dels); ++i) @@ -174,7 +120,7 @@ gva_compare(GVA_Allocator const allocator, // fprintf(stderr, "%2zu: %016zx\n", i, lhs_ts[i]); // } // for - bitfill(rhs_graph, start, start_accent, end_accent, rhs_dels, rhs_as, rhs_cs, rhs_gs, rhs_ts); + bitset_fill(rhs_graph, start, start_accent, end_accent, rhs_dels, rhs_as, rhs_cs, rhs_gs, rhs_ts); gva_lcs_graph_destroy(allocator, rhs_graph); // for (size_t i = 0; i < array_length(rhs_dels); ++i) From 48f8224309b4c719bb60be5c556f4801d8a0fdcb Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Tue, 1 Jul 2025 21:56:05 +0200 Subject: [PATCH 264/704] Bitset from main. --- src/main.c | 52 +++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 41 insertions(+), 11 deletions(-) diff --git a/src/main.c b/src/main.c index d91e338..baefa15 100644 --- a/src/main.c +++ b/src/main.c @@ -270,30 +270,60 @@ all_graphs() fclose(stream); } // if + bool check = true; size_t rsid; char spdi[4096]; char hgvs[4096]; - char python[4096]; - size_t distance; - size_t nodes; - size_t edges; + char python_sup[4096]; + char c_sup[4096]; + size_t python_distance; + size_t python_nodes; + size_t python_edges; size_t count = 0; - while (fscanf(stdin, "%zu %4096s %4096s %4096s %zu %zu %zu\n", &rsid, spdi, hgvs, python, &distance, &nodes, &edges) == 7) + while (fscanf(stdin, "%zu %4096s %4096s %4096s %zu %zu %zu\n", &rsid, spdi, hgvs, python_sup, &python_distance, &python_nodes, &python_edges) == 7) { GVA_Variant variant; if (!gva_parse_spdi(strlen(spdi), spdi, &variant)) { - fprintf(stderr, "PARSE ERROR: %zu %s %s %s %zu %zu %zu\n", rsid, spdi, hgvs, python, distance, nodes, edges); + fprintf(stderr, "PARSE ERROR: %zu %s %s %s %zu %zu %zu\n", rsid, spdi, hgvs, python_sup, python_distance, python_nodes, python_edges); continue; } // if count += 1; GVA_LCS_Graph graph = gva_lcs_graph_from_variant(gva_std_allocator, seq.len, seq.str, variant); - fprintf(stdout, "%zu %s %s %s %zu %zu %zu " GVA_VARIANT_FMT " %u %zu %zu\n", rsid, spdi, hgvs, python, distance, nodes, edges, GVA_VARIANT_PRINT(graph.supremal), graph.distance, array_length(graph.nodes), array_length(graph.edges)); + //fprintf(stdout, "%zu %s %s %s %zu %zu %zu " GVA_VARIANT_FMT " %u %zu %zu\n", + // rsid, spdi, hgvs, python_sup, python_distance, python_nodes, python_edges, GVA_VARIANT_PRINT(graph.supremal), graph.distance, array_length(graph.nodes), array_length(graph.edges)); + sprintf(c_sup, GVA_VARIANT_FMT, GVA_VARIANT_PRINT(graph.supremal)); + fprintf(stderr, "%s %s\n", python_sup, c_sup); + if (check && strcmp(python_sup, c_sup)) + { + fprintf(stderr, "Different supremal!\n"); + } //lcs_graph_raw(stderr, graph); //lcs_graph_dot(stderr, graph); + gva_uint start = 42; + gva_uint end = 42; + gva_uint start_accent = 42; + gva_uint end_accent = 42; + + gva_uint sup_len = end - start; + size_t* dels = bitset_init(gva_std_allocator, sup_len + 1); + size_t* as = bitset_init(gva_std_allocator, sup_len + 1); + size_t* cs = bitset_init(gva_std_allocator, sup_len + 1); + size_t* gs = bitset_init(gva_std_allocator, sup_len + 1); + size_t* ts = bitset_init(gva_std_allocator, sup_len + 1); + bitset_fill(graph, start, start_accent, end_accent, dels, as, cs, gs, ts); + for (size_t i = 0; i < array_length(dels); ++i) + { + fprintf(stderr, "%2zu: %016zx\n", i, dels[i]); + fprintf(stderr, "%2zu: %016zx\n", i, as[i]); + fprintf(stderr, "%2zu: %016zx\n", i, cs[i]); + fprintf(stderr, "%2zu: %016zx\n", i, gs[i]); + fprintf(stderr, "%2zu: %016zx\n", i, ts[i]); + } // for + graph.observed.str = gva_std_allocator.allocate(gva_std_allocator.context, graph.observed.str, graph.observed.len, 0); gva_lcs_graph_destroy(gva_std_allocator, graph); } // while @@ -352,11 +382,11 @@ extract(int argc, char* argv[static argc + 1]) int main(int argc, char* argv[static argc + 1]) { - //check python relation output - return compare(); + // check python relation output + //return compare(); - //calcuate graphs for all inputs - //return all_graphs(); + // calculate graphs for all inputs + return all_graphs(); //extract single variant //return extract(argc, argv); From e541010aa75ff32c313316b0977588c4256cf84d Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Wed, 2 Jul 2025 00:14:18 +0200 Subject: [PATCH 265/704] Create bitsets and dont clean up. --- src/main.c | 51 ++++++++++++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/src/main.c b/src/main.c index a13539a..7dc14c8 100644 --- a/src/main.c +++ b/src/main.c @@ -272,12 +272,12 @@ all_graphs(void) fclose(stream); } // if - bool check = true; + //bool check = false; size_t rsid; char spdi[4096]; char hgvs[4096]; char python_sup[4096]; - char c_sup[4096]; + //char c_sup[4096]; size_t python_distance; size_t python_nodes; size_t python_edges; @@ -295,36 +295,41 @@ all_graphs(void) //fprintf(stdout, "%zu %s %s %s %zu %zu %zu " GVA_VARIANT_FMT " %u %zu %zu\n", // rsid, spdi, hgvs, python_sup, python_distance, python_nodes, python_edges, GVA_VARIANT_PRINT(graph.supremal), graph.distance, array_length(graph.nodes), array_length(graph.edges)); - sprintf(c_sup, GVA_VARIANT_FMT, GVA_VARIANT_PRINT(graph.supremal)); - fprintf(stderr, "%s %s\n", python_sup, c_sup); - if (check && strcmp(python_sup, c_sup)) - { - fprintf(stderr, "Different supremal!\n"); - } + //fprintf(stdout, "%zu %s %s %s %zu %zu %zu " GVA_VARIANT_FMT " %u %zu %zu\n", + // rsid, spdi, hgvs, python_sup, python_distance, python_nodes, python_edges, GVA_VARIANT_PRINT(graph.supremal), graph.distance, array_length(graph.nodes), array_length(graph.edges)); + //sprintf(c_sup, GVA_VARIANT_FMT, GVA_VARIANT_PRINT(graph.supremal)); + //fprintf(stderr, "%s %s\n", python_sup, c_sup); + //if (check && strcmp(python_sup, c_sup)) + //{ + // fprintf(stderr, "Different supremal!\n"); + //} //lcs_graph_raw(stderr, graph); //lcs_graph_dot(stderr, graph); - gva_uint start = 42; - gva_uint end = 42; - gva_uint start_accent = 42; - gva_uint end_accent = 42; - - gva_uint sup_len = end - start; + gva_uint sup_len = graph.supremal.end - graph.supremal.start; size_t* dels = bitset_init(gva_std_allocator, sup_len + 1); size_t* as = bitset_init(gva_std_allocator, sup_len + 1); size_t* cs = bitset_init(gva_std_allocator, sup_len + 1); size_t* gs = bitset_init(gva_std_allocator, sup_len + 1); size_t* ts = bitset_init(gva_std_allocator, sup_len + 1); - bitset_fill(graph, start, start_accent, end_accent, dels, as, cs, gs, ts); - for (size_t i = 0; i < array_length(dels); ++i) - { - fprintf(stderr, "%2zu: %016zx\n", i, dels[i]); - fprintf(stderr, "%2zu: %016zx\n", i, as[i]); - fprintf(stderr, "%2zu: %016zx\n", i, cs[i]); - fprintf(stderr, "%2zu: %016zx\n", i, gs[i]); - fprintf(stderr, "%2zu: %016zx\n", i, ts[i]); - } // for + + bitset_fill(graph, graph.supremal.start, graph.supremal.start, graph.supremal.end, dels, as, cs, gs, ts); + + //for (size_t i = 0; i < array_length(dels); ++i) + //{ + // fprintf(stderr, "%2zu: %016zx\n", i, dels[i]); + // fprintf(stderr, "%2zu: %016zx\n", i, as[i]); + // fprintf(stderr, "%2zu: %016zx\n", i, cs[i]); + // fprintf(stderr, "%2zu: %016zx\n", i, gs[i]); + // fprintf(stderr, "%2zu: %016zx\n", i, ts[i]); + //} // for + + //ts = bitset_destroy(gva_std_allocator, ts); + //gs = bitset_destroy(gva_std_allocator, gs); + //cs = bitset_destroy(gva_std_allocator, cs); + //as = bitset_destroy(gva_std_allocator, as); + //dels = bitset_destroy(gva_std_allocator, dels); graph.observed.str = gva_std_allocator.allocate(gva_std_allocator.context, graph.observed.str, graph.observed.len, 0); gva_lcs_graph_destroy(gva_std_allocator, graph); From b50f9a02909277c0bcc98da6a4ebcc068632ef6c Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Wed, 2 Jul 2025 12:02:58 +0200 Subject: [PATCH 266/704] Add counter for bitset_add "calls". --- src/bitset.c | 9 ++++++++- src/bitset.h | 2 +- src/main.c | 5 +++-- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/bitset.c b/src/bitset.c index bfd4538..4dbb088 100644 --- a/src/bitset.c +++ b/src/bitset.c @@ -50,7 +50,7 @@ bitset_destroy(GVA_Allocator const allocator, size_t bitset[static 1]) } // bitset_destroy -void +size_t bitset_fill(GVA_LCS_Graph const graph, gva_uint const start, gva_uint const start_accent, gva_uint const end_accent, size_t dels[static restrict 1], @@ -59,6 +59,7 @@ bitset_fill(GVA_LCS_Graph const graph, size_t gs[static restrict 1], size_t ts[static restrict 1]) { + size_t counter = 0; for (size_t i = 0; i < array_length(graph.nodes); ++i) { for (gva_uint j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) @@ -78,6 +79,7 @@ bitset_fill(GVA_LCS_Graph const graph, for (gva_uint k = variant.start; k < variant.end; ++k) { bitset_add(dels, k + z - start); + counter += 1; } // for } // for @@ -86,6 +88,7 @@ bitset_fill(GVA_LCS_Graph const graph, for (gva_uint k = variant.start; k < variant.end + count; ++k) { bitset_add(as, k - start); + counter += 1; } // for } // if if (memchr(variant.sequence.str, 'C', variant.sequence.len)) @@ -93,6 +96,7 @@ bitset_fill(GVA_LCS_Graph const graph, for (gva_uint k = variant.start; k < variant.end + count; ++k) { bitset_add(cs, k - start); + counter += 1; } // for } // if if (memchr(variant.sequence.str, 'G', variant.sequence.len)) @@ -100,6 +104,7 @@ bitset_fill(GVA_LCS_Graph const graph, for (gva_uint k = variant.start; k < variant.end + count; ++k) { bitset_add(gs, k - start); + counter += 1; } // for } // if if (memchr(variant.sequence.str, 'T', variant.sequence.len)) @@ -107,8 +112,10 @@ bitset_fill(GVA_LCS_Graph const graph, for (gva_uint k = variant.start; k < variant.end + count; ++k) { bitset_add(ts, k - start); + counter += 1; } // for } // if } // for } // for + return counter; } // bitfill \ No newline at end of file diff --git a/src/bitset.h b/src/bitset.h index 2674768..55bb76e 100644 --- a/src/bitset.h +++ b/src/bitset.h @@ -25,7 +25,7 @@ size_t* bitset_destroy(GVA_Allocator const allocator, size_t bitset[static 1]); -void +size_t bitset_fill(GVA_LCS_Graph const graph, gva_uint const start, gva_uint const start_accent, gva_uint const end_accent, size_t dels[static restrict 1], diff --git a/src/main.c b/src/main.c index 7dc14c8..b931eea 100644 --- a/src/main.c +++ b/src/main.c @@ -282,6 +282,7 @@ all_graphs(void) size_t python_nodes; size_t python_edges; size_t count = 0; + size_t counter = 0; while (fscanf(stdin, "%zu %4096s %4096s %4096s %zu %zu %zu\n", &rsid, spdi, hgvs, python_sup, &python_distance, &python_nodes, &python_edges) == 7) { GVA_Variant variant; @@ -314,7 +315,7 @@ all_graphs(void) size_t* gs = bitset_init(gva_std_allocator, sup_len + 1); size_t* ts = bitset_init(gva_std_allocator, sup_len + 1); - bitset_fill(graph, graph.supremal.start, graph.supremal.start, graph.supremal.end, dels, as, cs, gs, ts); + counter += bitset_fill(graph, graph.supremal.start, graph.supremal.start, graph.supremal.end, dels, as, cs, gs, ts); //for (size_t i = 0; i < array_length(dels); ++i) //{ @@ -335,7 +336,7 @@ all_graphs(void) gva_lcs_graph_destroy(gva_std_allocator, graph); } // while - fprintf(stderr, "%zu\n", count); + fprintf(stderr, "%zu %zu\n", count, counter); seq.str = gva_std_allocator.allocate(gva_std_allocator.context, seq.str, seq.len, 0); From 647245078095e4b40c1f199b559d1f3a425705a7 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Wed, 2 Jul 2025 22:56:37 +0200 Subject: [PATCH 267/704] Add as is. --- src/faststabber.c | 468 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 468 insertions(+) create mode 100644 src/faststabber.c diff --git a/src/faststabber.c b/src/faststabber.c new file mode 100644 index 0000000..48ffee9 --- /dev/null +++ b/src/faststabber.c @@ -0,0 +1,468 @@ +#define _XOPEN_SOURCE + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + +#define TIC(X) clock_t const X = clock() +#define TOC(X) fprintf(stderr, "time %s: %.3f s\n", (#X), (double)(clock() - (X)) / CLOCKS_PER_SEC) + + +typedef struct Node +{ + uint32_t start; + uint32_t end; + + struct Node* restrict parent; + struct Node* restrict leftsibling; + struct Node* restrict rightchild; +} Node; + + +typedef struct Stack +{ + Node* restrict node; + struct Stack* restrict next; +} Stack; + + +static inline Node* +stack_top(Stack const* const restrict stack) +{ + assert(stack != NULL); + return stack->node; +} // stack_top + + +static inline Stack* +stack_push(Stack* const restrict stack, Node* const restrict node) +{ + Stack* const restrict top = malloc(sizeof(*top)); + assert(top != NULL); + top->node = node; + top->next = stack; + return top; +} // stack_push + + +static inline Stack* +stack_pop(Stack* const restrict stack) +{ + assert(stack != NULL); + Stack* const restrict top = stack->next; + free(stack); + return top; +} // stack_pop + + +static inline Node* +create_node(uint32_t const start, uint32_t const end) +{ + Node* const restrict node = malloc(sizeof(*node)); + assert(node != NULL); + + node->start = start; + node->end = end; + node->parent = NULL; + node->leftsibling = NULL; + node->rightchild = NULL; + return node; +} // create_node + + +static inline Node* +add_node(Node* const restrict last_node, Node* const restrict node) +{ + assert(node != NULL); + + // get parent + node->parent = last_node; + while (node->parent != NULL && node->parent->end < node->end) + { + node->parent = node->parent->parent; + } // while + + assert(node->parent != NULL); + + // push new sibling + node->leftsibling = node->parent->rightchild; + node->parent->rightchild = node; + + return node; +} // add_node + + +static size_t +draw_edge(Node const* const restrict node, void* const restrict arg) +{ + assert(node != NULL); + if (node->parent != NULL) + { + return fprintf(arg, "n%p -> n%p[dir=none];\n", (void*) node->parent, (void*) node); + } // if + return 0; +} // draw_edge + + +static size_t +draw_node(Node const* const restrict node, void* const restrict arg) +{ + return fprintf(arg, "n%p[label=\"%u–%u\"];\n", (void*) node, node->start, node->end); +} // draw_node + + +static size_t +traverse(Node* const restrict node, + size_t (*func)(Node const* const restrict, void* const restrict), + void* const restrict arg) +{ + if (node == NULL) + { + return 0; + } // if + + return traverse(node->leftsibling, func, arg) + + func(node, arg) + + traverse(node->rightchild, func, arg); +} // traverse + + +static size_t +write_dot(FILE* const restrict fp, Node* const restrict root) +{ + assert(fp != NULL); + + return fputs("digraph G {\n", fp) + + traverse(root, draw_node, fp) + + traverse(root, draw_edge, fp) + + fputs("}\n", fp); +} // write_dot + + +static void +destroy(Node* const restrict node) +{ + if (node == NULL) + { + return; + } // if + + destroy(node->leftsibling); + destroy(node->rightchild); + free(node); +} // destroy + + +static void +read_bed(FILE* const restrict fp, + uint32_t const max, + Node** tree, + Node* start_table[]) +{ + assert(fp != NULL); + + // push root node on the stack + Node* last_node = create_node(0, max); + *tree = last_node; + + Stack* restrict stack = stack_push(NULL, last_node); + Node* restrict top = stack_top(stack); + + // read first entry + char reference[128] = {0}; + uint32_t start = 0; + uint32_t end = 0; + int ret = fscanf(fp, "%127s %" PRIu32 " %" PRIu32, reference, &start, &end); + assert(ret == 3); + + for (uint32_t i = 0; i < max; ++i) + { + //fprintf(stderr, "index iteration: %" PRIu32 "\n", i); + + // pop while end smaller than index + while (top->end < i) + { + assert(stack != NULL); + //fprintf(stderr, "Popping %" PRIu32 "--%" PRIu32 " from stack\n", top->start, top->end); + stack = stack_pop(stack); + top = stack_top(stack); + } // while + + while (i >= start && i <= end && !(start == top->start && end == top->end)) + { + do + { + Node* const node = create_node(start, end); + //fprintf(stderr, "Pushing %" PRIu32 "--%" PRIu32 " on stack\n", start, end); + stack = stack_push(stack, node); + top = stack_top(stack); + + last_node = add_node(last_node, node); + + ret = fscanf(fp, "%127s %" PRIu32 " %" PRIu32, reference, &start, &end); + if (ret == -1) + { + break; + } // if + assert(ret == 3); + } while (start == top->start && end == top->end); + } /// while + + //fprintf(stderr, "start_table[%" PRIu32 "] := %" PRIu32 "--%" PRIu32 "\n", i, top->start, top->end); + start_table[i] = top; + } // for + + assert(stack != NULL); + stack = stack_pop(stack); + assert(stack == NULL); +} // read_bed + + +static size_t +trav(Node* const node, + uint32_t const start, + uint32_t const end, + Stack* restrict* const restrict output) +{ + size_t count = 0; + Node* restrict tmp = node; + while (tmp != NULL && end <= tmp->end) + { + //fprintf(stderr, "trav: %p: %" PRIu32 "--%" PRIu32 "\n", (void*) tmp, tmp->start, tmp->end); + if (start >= tmp->start) + { + count += trav(tmp->rightchild, start, end, output) + 1; + //*output = stack_push(*output, tmp); + } // if + tmp = tmp->leftsibling; + } // while + return count; +} // trav + + +static size_t +stab(Node* const node, + uint32_t const start, + uint32_t const end, + Stack* restrict* const restrict output) +{ + size_t count = 0; + Node* restrict tmp = node; + while (tmp != NULL && tmp->parent != NULL) + { + //fprintf(stderr, "stab: %p: %" PRIu32 "--%" PRIu32 "\n", (void*) tmp, tmp->start, tmp->end); + if (start >= tmp->start) + { + count += 1; + //*output = stack_push(*output, tmp); + } // if + count += trav(tmp->leftsibling, start, end, output); + tmp = tmp->parent; + } // while + return count; +} // stab + + +struct Bed_entry +{ + char reference[32]; + size_t count; + size_t node_count; + int start; + int end; +}; // Bed_entry + + +static struct Bed_entry bed[250000000]; + + +static void +query_bed(FILE* const restrict fp, + Node* const start_table[restrict]) +{ + assert(fp != NULL); + + TIC(read_bed); + size_t idx = 0; + while (fscanf(fp, "%31s %d %d", bed[idx].reference, &bed[idx].start, &bed[idx].end) == 3) + { + idx += 1; + } // while + TOC(read_bed); + + TIC(annotate); + for (size_t i = 0; i < idx; ++i) + { + Stack* restrict output = NULL; + bed[i].count = stab(start_table[bed[i].end], bed[i].start, bed[i].end, &output); + bed[i].node_count = 0; + /* + while (output != NULL) + { + output = stack_pop(output); + bed[i].count += 1; + } // while + */ + } // for + TOC(annotate); + + TIC(write_ann); + for (size_t i = 0; i < idx; ++i) + { + printf("%s\t%d\t%d\t%zu\t%zu\n", bed[i].reference, bed[i].start, bed[i].end, bed[i].count, bed[i].node_count); + } // for + TOC(write_ann); +} // query_bed + + +int +main(int argc, char* argv[]) +{ +/* + check(stdin, 38); + return -1; +*/ + uint32_t n = 0; + uint32_t q = 0; + uint32_t r = 0; + char *dot_path = NULL, *vcf_path = NULL, *bed_path = NULL; + int opt = -1; + while ((opt = getopt(argc, argv, "b:hd:n:q:r:v:")) != -1) + { + switch (opt) + { + case 'b': + bed_path = malloc(strlen(optarg) +1); + assert(NULL != bed_path); + strcpy(bed_path, optarg); + break; + case 'd': + dot_path = malloc(strlen(optarg) + 1); + assert(dot_path != NULL); + strcpy(dot_path, optarg); + break; + case 'n': + n = atoi(optarg); + break; + case 'q': + q = atoi(optarg); + break; + case 'r': + r = atoi(optarg); + break; + case 'v': + vcf_path = malloc(strlen(optarg) + 1); + assert(vcf_path != NULL); + strcpy(vcf_path, optarg); + break; + case 'h': + default: + fprintf(stderr, "Usage: %s [-h] [-d path] -b bed_file -n size [ -q left [-r right] | -v vcf_file ] \n", argv[0]); + return EXIT_FAILURE; + } // switch + } // while + + if ((bed_path && !strncmp("-", bed_path, 1)) && (vcf_path && !strncmp("-", vcf_path, 1))) { + fprintf(stderr, "Can't read both VCF and BED from STDIN\n"); + return EXIT_FAILURE; + } + + if (!bed_path) { + fprintf(stderr, "BED file not specified!\n"); + return EXIT_FAILURE; + } + if (vcf_path && q) { + fprintf(stderr, "Either specify a 'VCF file' or a query range, not both!\n"); + return EXIT_FAILURE; + } + + if (0 == n) + { + fprintf(stderr, "Specify size with -n\n"); + return EXIT_FAILURE; + } // if + + if (!vcf_path && q >= n) + { + fprintf(stderr, "Invalid parameter combination (n > q): n=%" PRIu32 ", q=%" PRIu32 "\n", n, q); + return EXIT_FAILURE; + } // if + + if (r < q) + { + r = q; + } // if + + // allocate start node lookup table + Node** start_table = malloc(n * sizeof(*start_table)); + assert(start_table != NULL); + + Node* tree = NULL; + FILE *restrict fp = NULL; + if (1 == strlen(bed_path) && !strncmp("-", bed_path, 1)) { + fp = stdin; + } else { + fp = fopen(bed_path, "r"); + } + free(bed_path); + assert(fp != NULL); + + TIC(construct); + read_bed(fp, n, &tree, start_table); + TOC(construct); + + fclose(fp); + + if (dot_path != NULL) + { + FILE* const restrict fp_dot = fopen(dot_path, "w"); + assert(fp_dot != NULL); + + write_dot(fp_dot, tree); + + fclose(fp_dot); + free(dot_path); + } // if + + if (q) + { + Stack *output = NULL; + stab(start_table[r], q, r, &output); + + printf("q: %" PRIu32 "--%" PRIu32 "\n", q, r); + while (output != NULL) { + printf("%" PRIu32 "--%" PRIu32 "\n", stack_top(output)->start, stack_top(output)->end); + output = stack_pop(output); + } // while + + } // if + else if (vcf_path != NULL) + { + + FILE* restrict fp_vcf = NULL; + if (1 == strlen(vcf_path) && !strncmp("-", vcf_path, 1)) { + fp_vcf = stdin; + } else { + fp_vcf = fopen(vcf_path, "r"); + } + free(vcf_path); + assert(fp_vcf != NULL); + query_bed(fp_vcf, start_table); + } // if + + destroy(tree); + + free(start_table); + + return EXIT_SUCCESS; +} // main From e225407474603d7b32483127a53c927a55539c9f Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Thu, 3 Jul 2025 00:04:09 +0200 Subject: [PATCH 268/704] Minimal and WIP integration of faststabber. --- include/faststabber.h | 88 ++++++++++++++++++ src/faststabber.c | 204 ++++-------------------------------------- src/main.c | 161 ++++++++++++++++++++++++++++++++- 3 files changed, 261 insertions(+), 192 deletions(-) create mode 100644 include/faststabber.h diff --git a/include/faststabber.h b/include/faststabber.h new file mode 100644 index 0000000..5899248 --- /dev/null +++ b/include/faststabber.h @@ -0,0 +1,88 @@ +#ifndef GVA_FASTSTABBER_H +#define GVA_FASTSTABBER_H + + +typedef struct Node +{ + uint32_t start; + uint32_t end; + + struct Node* restrict parent; + struct Node* restrict leftsibling; + struct Node* restrict rightchild; +} Node; + + +typedef struct Stack +{ + Node* restrict node; + struct Stack* restrict next; +} Stack; + + +struct Bed_entry +{ + char reference[32]; + size_t count; + size_t node_count; + int start; + int end; +}; // Bed_entry + + + +Node* +stack_top(Stack const* const restrict stack); + +Stack* +stack_push(Stack* const restrict stack, Node* const restrict node); + +Stack* +stack_pop(Stack* const restrict stack); + +Node* +create_node(uint32_t const start, uint32_t const end); + +Node* +add_node(Node* const restrict last_node, Node* const restrict node); + +size_t +draw_edge(Node const* const restrict node, void* const restrict arg); + +size_t +draw_node(Node const* const restrict node, void* const restrict arg); + +size_t +traverse(Node* const restrict node, + size_t (*func)(Node const* const restrict, void* const restrict), + void* const restrict arg); + +size_t +write_dot(FILE* const restrict fp, Node* const restrict root); + +void +destroy(Node* const restrict node); + +void +read_bed(FILE* const restrict fp, + uint32_t const max, + Node** tree, + Node* start_table[]); + +size_t +trav(Node* const node, + uint32_t const start, + uint32_t const end, + Stack* restrict* const restrict output); + +size_t +stab(Node* const node, + uint32_t const start, + uint32_t const end, + Stack* restrict* const restrict output); + +void +query_bed(FILE* const restrict fp, + Node* const start_table[restrict]); + +#endif // GVA_FASTSTABBER_H \ No newline at end of file diff --git a/src/faststabber.c b/src/faststabber.c index 48ffee9..7573949 100644 --- a/src/faststabber.c +++ b/src/faststabber.c @@ -11,32 +11,14 @@ #include #include -#include +#include "../include/faststabber.h" // Node, Stack #define TIC(X) clock_t const X = clock() #define TOC(X) fprintf(stderr, "time %s: %.3f s\n", (#X), (double)(clock() - (X)) / CLOCKS_PER_SEC) -typedef struct Node -{ - uint32_t start; - uint32_t end; - - struct Node* restrict parent; - struct Node* restrict leftsibling; - struct Node* restrict rightchild; -} Node; - - -typedef struct Stack -{ - Node* restrict node; - struct Stack* restrict next; -} Stack; - - -static inline Node* +Node* stack_top(Stack const* const restrict stack) { assert(stack != NULL); @@ -44,7 +26,7 @@ stack_top(Stack const* const restrict stack) } // stack_top -static inline Stack* +Stack* stack_push(Stack* const restrict stack, Node* const restrict node) { Stack* const restrict top = malloc(sizeof(*top)); @@ -55,7 +37,7 @@ stack_push(Stack* const restrict stack, Node* const restrict node) } // stack_push -static inline Stack* +Stack* stack_pop(Stack* const restrict stack) { assert(stack != NULL); @@ -65,7 +47,7 @@ stack_pop(Stack* const restrict stack) } // stack_pop -static inline Node* +Node* create_node(uint32_t const start, uint32_t const end) { Node* const restrict node = malloc(sizeof(*node)); @@ -80,7 +62,7 @@ create_node(uint32_t const start, uint32_t const end) } // create_node -static inline Node* +Node* add_node(Node* const restrict last_node, Node* const restrict node) { assert(node != NULL); @@ -102,7 +84,7 @@ add_node(Node* const restrict last_node, Node* const restrict node) } // add_node -static size_t +size_t draw_edge(Node const* const restrict node, void* const restrict arg) { assert(node != NULL); @@ -114,14 +96,14 @@ draw_edge(Node const* const restrict node, void* const restrict arg) } // draw_edge -static size_t +size_t draw_node(Node const* const restrict node, void* const restrict arg) { return fprintf(arg, "n%p[label=\"%u–%u\"];\n", (void*) node, node->start, node->end); } // draw_node -static size_t +size_t traverse(Node* const restrict node, size_t (*func)(Node const* const restrict, void* const restrict), void* const restrict arg) @@ -137,7 +119,7 @@ traverse(Node* const restrict node, } // traverse -static size_t +size_t write_dot(FILE* const restrict fp, Node* const restrict root) { assert(fp != NULL); @@ -149,7 +131,7 @@ write_dot(FILE* const restrict fp, Node* const restrict root) } // write_dot -static void +void destroy(Node* const restrict node) { if (node == NULL) @@ -163,7 +145,7 @@ destroy(Node* const restrict node) } // destroy -static void +void read_bed(FILE* const restrict fp, uint32_t const max, Node** tree, @@ -228,7 +210,7 @@ read_bed(FILE* const restrict fp, } // read_bed -static size_t +size_t trav(Node* const node, uint32_t const start, uint32_t const end, @@ -250,7 +232,7 @@ trav(Node* const node, } // trav -static size_t +size_t stab(Node* const node, uint32_t const start, uint32_t const end, @@ -273,20 +255,9 @@ stab(Node* const node, } // stab -struct Bed_entry -{ - char reference[32]; - size_t count; - size_t node_count; - int start; - int end; -}; // Bed_entry - - static struct Bed_entry bed[250000000]; - -static void +void query_bed(FILE* const restrict fp, Node* const start_table[restrict]) { @@ -322,147 +293,4 @@ query_bed(FILE* const restrict fp, printf("%s\t%d\t%d\t%zu\t%zu\n", bed[i].reference, bed[i].start, bed[i].end, bed[i].count, bed[i].node_count); } // for TOC(write_ann); -} // query_bed - - -int -main(int argc, char* argv[]) -{ -/* - check(stdin, 38); - return -1; -*/ - uint32_t n = 0; - uint32_t q = 0; - uint32_t r = 0; - char *dot_path = NULL, *vcf_path = NULL, *bed_path = NULL; - int opt = -1; - while ((opt = getopt(argc, argv, "b:hd:n:q:r:v:")) != -1) - { - switch (opt) - { - case 'b': - bed_path = malloc(strlen(optarg) +1); - assert(NULL != bed_path); - strcpy(bed_path, optarg); - break; - case 'd': - dot_path = malloc(strlen(optarg) + 1); - assert(dot_path != NULL); - strcpy(dot_path, optarg); - break; - case 'n': - n = atoi(optarg); - break; - case 'q': - q = atoi(optarg); - break; - case 'r': - r = atoi(optarg); - break; - case 'v': - vcf_path = malloc(strlen(optarg) + 1); - assert(vcf_path != NULL); - strcpy(vcf_path, optarg); - break; - case 'h': - default: - fprintf(stderr, "Usage: %s [-h] [-d path] -b bed_file -n size [ -q left [-r right] | -v vcf_file ] \n", argv[0]); - return EXIT_FAILURE; - } // switch - } // while - - if ((bed_path && !strncmp("-", bed_path, 1)) && (vcf_path && !strncmp("-", vcf_path, 1))) { - fprintf(stderr, "Can't read both VCF and BED from STDIN\n"); - return EXIT_FAILURE; - } - - if (!bed_path) { - fprintf(stderr, "BED file not specified!\n"); - return EXIT_FAILURE; - } - if (vcf_path && q) { - fprintf(stderr, "Either specify a 'VCF file' or a query range, not both!\n"); - return EXIT_FAILURE; - } - - if (0 == n) - { - fprintf(stderr, "Specify size with -n\n"); - return EXIT_FAILURE; - } // if - - if (!vcf_path && q >= n) - { - fprintf(stderr, "Invalid parameter combination (n > q): n=%" PRIu32 ", q=%" PRIu32 "\n", n, q); - return EXIT_FAILURE; - } // if - - if (r < q) - { - r = q; - } // if - - // allocate start node lookup table - Node** start_table = malloc(n * sizeof(*start_table)); - assert(start_table != NULL); - - Node* tree = NULL; - FILE *restrict fp = NULL; - if (1 == strlen(bed_path) && !strncmp("-", bed_path, 1)) { - fp = stdin; - } else { - fp = fopen(bed_path, "r"); - } - free(bed_path); - assert(fp != NULL); - - TIC(construct); - read_bed(fp, n, &tree, start_table); - TOC(construct); - - fclose(fp); - - if (dot_path != NULL) - { - FILE* const restrict fp_dot = fopen(dot_path, "w"); - assert(fp_dot != NULL); - - write_dot(fp_dot, tree); - - fclose(fp_dot); - free(dot_path); - } // if - - if (q) - { - Stack *output = NULL; - stab(start_table[r], q, r, &output); - - printf("q: %" PRIu32 "--%" PRIu32 "\n", q, r); - while (output != NULL) { - printf("%" PRIu32 "--%" PRIu32 "\n", stack_top(output)->start, stack_top(output)->end); - output = stack_pop(output); - } // while - - } // if - else if (vcf_path != NULL) - { - - FILE* restrict fp_vcf = NULL; - if (1 == strlen(vcf_path) && !strncmp("-", vcf_path, 1)) { - fp_vcf = stdin; - } else { - fp_vcf = fopen(vcf_path, "r"); - } - free(vcf_path); - assert(fp_vcf != NULL); - query_bed(fp_vcf, start_table); - } // if - - destroy(tree); - - free(start_table); - - return EXIT_SUCCESS; -} // main +} // query_bed \ No newline at end of file diff --git a/src/main.c b/src/main.c index b931eea..1900bc8 100644 --- a/src/main.c +++ b/src/main.c @@ -1,12 +1,16 @@ +#define _XOPEN_SOURCE +#include #include // NULL, size_t #include // FILE, stderr, fclose, fopen, fprintf #include // EXIT_* #include // strcmp, strlen +#include // optarg #include "../include/compare.h" // gva_compare #include "../include/edit.h" // gva_edit_distance #include "../include/extract.h" // gva_extract +#include "../include/faststabber.h" // Node, Stack #include "../include/lcs_graph.h" // GVA_LCS_Graph, GVA_Variant, gva_lcs_graph_*, gva_edges #include "../include/relations.h" // GVA_RELATION_LABELS #include "../include/std_alloc.h" // gva_std_allocator @@ -387,16 +391,165 @@ extract(int const argc, char* argv[static argc + 1]) } // extract +int +faststabber(int argc, char* argv[static argc + 1]) +{ +/* + check(stdin, 38); + return -1; +*/ + uint32_t n = 0; + uint32_t q = 0; + uint32_t r = 0; + char *dot_path = NULL, *vcf_path = NULL, *bed_path = NULL; + int opt = -1; + while ((opt = getopt(argc, argv, "b:hd:n:q:r:v:")) != -1) + { + switch (opt) + { + case 'b': + bed_path = malloc(strlen(optarg) +1); + assert(NULL != bed_path); + strcpy(bed_path, optarg); + break; + case 'd': + dot_path = malloc(strlen(optarg) + 1); + assert(dot_path != NULL); + strcpy(dot_path, optarg); + break; + case 'n': + n = atoi(optarg); + break; + case 'q': + q = atoi(optarg); + break; + case 'r': + r = atoi(optarg); + break; + case 'v': + vcf_path = malloc(strlen(optarg) + 1); + assert(vcf_path != NULL); + strcpy(vcf_path, optarg); + break; + case 'h': + default: + fprintf(stderr, "Usage: %s [-h] [-d path] -b bed_file -n size [ -q left [-r right] | -v vcf_file ] \n", argv[0]); + return EXIT_FAILURE; + } // switch + } // while + + if ((bed_path && !strncmp("-", bed_path, 1)) && (vcf_path && !strncmp("-", vcf_path, 1))) { + fprintf(stderr, "Can't read both VCF and BED from STDIN\n"); + return EXIT_FAILURE; + } + + if (!bed_path) { + fprintf(stderr, "BED file not specified!\n"); + return EXIT_FAILURE; + } + if (vcf_path && q) { + fprintf(stderr, "Either specify a 'VCF file' or a query range, not both!\n"); + return EXIT_FAILURE; + } + + if (0 == n) + { + fprintf(stderr, "Specify size with -n\n"); + return EXIT_FAILURE; + } // if + + if (!vcf_path && q >= n) + { + fprintf(stderr, "Invalid parameter combination (n > q): n=%" PRIu32 ", q=%" PRIu32 "\n", n, q); + return EXIT_FAILURE; + } // if + + if (r < q) + { + r = q; + } // if + + // allocate start node lookup table + Node** start_table = malloc(n * sizeof(*start_table)); + assert(start_table != NULL); + + Node* tree = NULL; + FILE *restrict fp = NULL; + if (1 == strlen(bed_path) && !strncmp("-", bed_path, 1)) { + fp = stdin; + } else { + fp = fopen(bed_path, "r"); + } + free(bed_path); + assert(fp != NULL); + + //TIC(construct); + read_bed(fp, n, &tree, start_table); + //TOC(construct); + + fclose(fp); + + if (dot_path != NULL) + { + FILE* const restrict fp_dot = fopen(dot_path, "w"); + assert(fp_dot != NULL); + + write_dot(fp_dot, tree); + + fclose(fp_dot); + free(dot_path); + } // if + + if (q) + { + Stack *output = NULL; + stab(start_table[r], q, r, &output); + + printf("q: %" PRIu32 "--%" PRIu32 "\n", q, r); + while (output != NULL) { + printf("%" PRIu32 "--%" PRIu32 "\n", stack_top(output)->start, stack_top(output)->end); + output = stack_pop(output); + } // while + + } // if + else if (vcf_path != NULL) + { + + FILE* restrict fp_vcf = NULL; + if (1 == strlen(vcf_path) && !strncmp("-", vcf_path, 1)) { + fp_vcf = stdin; + } else { + fp_vcf = fopen(vcf_path, "r"); + } + free(vcf_path); + assert(fp_vcf != NULL); + query_bed(fp_vcf, start_table); + } // if + + destroy(tree); + + free(start_table); + + return EXIT_SUCCESS; + +} + + int main(int argc, char* argv[static argc + 1]) { (void) argv; // check python relation output - //return compare(); + // return compare(); // calculate graphs for all inputs - return all_graphs(); + // return all_graphs(); + + // extract single variant + // return extract(argc, argv); + + // faststabber + return faststabber(argc, argv); + - //extract single variant - //return extract(argc, argv); } // main From 8d4b9c4fa00c0f2fcdbe37070815870c1f82a912 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Thu, 3 Jul 2025 13:36:15 +0200 Subject: [PATCH 269/704] Actually return results. --- src/faststabber.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/faststabber.c b/src/faststabber.c index 7573949..da6e4d0 100644 --- a/src/faststabber.c +++ b/src/faststabber.c @@ -224,7 +224,7 @@ trav(Node* const node, if (start >= tmp->start) { count += trav(tmp->rightchild, start, end, output) + 1; - //*output = stack_push(*output, tmp); + *output = stack_push(*output, tmp); } // if tmp = tmp->leftsibling; } // while @@ -246,7 +246,7 @@ stab(Node* const node, if (start >= tmp->start) { count += 1; - //*output = stack_push(*output, tmp); + *output = stack_push(*output, tmp); } // if count += trav(tmp->leftsibling, start, end, output); tmp = tmp->parent; From 18661648883312815dcaa599853cb4e33f4bf2e6 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Thu, 3 Jul 2025 14:07:44 +0200 Subject: [PATCH 270/704] Add free. --- src/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main.c b/src/main.c index 1900bc8..f5db92d 100644 --- a/src/main.c +++ b/src/main.c @@ -440,6 +440,7 @@ faststabber(int argc, char* argv[static argc + 1]) if ((bed_path && !strncmp("-", bed_path, 1)) && (vcf_path && !strncmp("-", vcf_path, 1))) { fprintf(stderr, "Can't read both VCF and BED from STDIN\n"); + free(bed_path); return EXIT_FAILURE; } From 525c4f3fbf6a0356b626de9cf48b9ccb81d5c496 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Thu, 3 Jul 2025 14:08:46 +0200 Subject: [PATCH 271/704] Disable some code for now. --- src/faststabber.c | 78 +++++++++++++++++++++++------------------------ src/main.c | 26 ++++++++-------- 2 files changed, 52 insertions(+), 52 deletions(-) diff --git a/src/faststabber.c b/src/faststabber.c index da6e4d0..0991e58 100644 --- a/src/faststabber.c +++ b/src/faststabber.c @@ -255,42 +255,42 @@ stab(Node* const node, } // stab -static struct Bed_entry bed[250000000]; - -void -query_bed(FILE* const restrict fp, - Node* const start_table[restrict]) -{ - assert(fp != NULL); - - TIC(read_bed); - size_t idx = 0; - while (fscanf(fp, "%31s %d %d", bed[idx].reference, &bed[idx].start, &bed[idx].end) == 3) - { - idx += 1; - } // while - TOC(read_bed); - - TIC(annotate); - for (size_t i = 0; i < idx; ++i) - { - Stack* restrict output = NULL; - bed[i].count = stab(start_table[bed[i].end], bed[i].start, bed[i].end, &output); - bed[i].node_count = 0; - /* - while (output != NULL) - { - output = stack_pop(output); - bed[i].count += 1; - } // while - */ - } // for - TOC(annotate); - - TIC(write_ann); - for (size_t i = 0; i < idx; ++i) - { - printf("%s\t%d\t%d\t%zu\t%zu\n", bed[i].reference, bed[i].start, bed[i].end, bed[i].count, bed[i].node_count); - } // for - TOC(write_ann); -} // query_bed \ No newline at end of file +//static struct Bed_entry bed[250000000]; +// +//void +//query_bed(FILE* const restrict fp, +// Node* const start_table[restrict]) +//{ +// assert(fp != NULL); +// +// TIC(read_bed); +// size_t idx = 0; +// while (fscanf(fp, "%31s %d %d", bed[idx].reference, &bed[idx].start, &bed[idx].end) == 3) +// { +// idx += 1; +// } // while +// TOC(read_bed); +// +// TIC(annotate); +// for (size_t i = 0; i < idx; ++i) +// { +// Stack* restrict output = NULL; +// bed[i].count = stab(start_table[bed[i].end], bed[i].start, bed[i].end, &output); +// bed[i].node_count = 0; +// /* +// while (output != NULL) +// { +// output = stack_pop(output); +// bed[i].count += 1; +// } // while +// */ +// } // for +// TOC(annotate); +// +// TIC(write_ann); +// for (size_t i = 0; i < idx; ++i) +// { +// printf("%s\t%d\t%d\t%zu\t%zu\n", bed[i].reference, bed[i].start, bed[i].end, bed[i].count, bed[i].node_count); +// } // for +// TOC(write_ann); +//} // query_bed \ No newline at end of file diff --git a/src/main.c b/src/main.c index f5db92d..1416a5e 100644 --- a/src/main.c +++ b/src/main.c @@ -513,19 +513,19 @@ faststabber(int argc, char* argv[static argc + 1]) } // while } // if - else if (vcf_path != NULL) - { - - FILE* restrict fp_vcf = NULL; - if (1 == strlen(vcf_path) && !strncmp("-", vcf_path, 1)) { - fp_vcf = stdin; - } else { - fp_vcf = fopen(vcf_path, "r"); - } - free(vcf_path); - assert(fp_vcf != NULL); - query_bed(fp_vcf, start_table); - } // if + //else if (vcf_path != NULL) + //{ + // + // FILE* restrict fp_vcf = NULL; + // if (1 == strlen(vcf_path) && !strncmp("-", vcf_path, 1)) { + // fp_vcf = stdin; + // } else { + // fp_vcf = fopen(vcf_path, "r"); + // } + // free(vcf_path); + // assert(fp_vcf != NULL); + // query_bed(fp_vcf, start_table); + //} // if destroy(tree); From 3c5c2c8d5ee613161107a42a0db23eb39a5648cc Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 3 Jul 2025 15:49:37 +0200 Subject: [PATCH 272/704] Sink length relabelling? --- include/faststabber.h | 3 ++- src/bitset.c | 18 ++++++++++-------- src/bitset.h | 14 ++++++++------ src/lcs_graph.c | 11 ++++++----- src/main.c | 9 +++------ 5 files changed, 29 insertions(+), 26 deletions(-) diff --git a/include/faststabber.h b/include/faststabber.h index 5899248..7e07330 100644 --- a/include/faststabber.h +++ b/include/faststabber.h @@ -85,4 +85,5 @@ void query_bed(FILE* const restrict fp, Node* const start_table[restrict]); -#endif // GVA_FASTSTABBER_H \ No newline at end of file + +#endif // GVA_FASTSTABBER_H diff --git a/src/bitset.c b/src/bitset.c index 4dbb088..c38041b 100644 --- a/src/bitset.c +++ b/src/bitset.c @@ -52,7 +52,8 @@ bitset_destroy(GVA_Allocator const allocator, size_t bitset[static 1]) size_t bitset_fill(GVA_LCS_Graph const graph, - gva_uint const start, gva_uint const start_accent, gva_uint const end_accent, + gva_uint const offset, + gva_uint const start, gva_uint const end, size_t dels[static restrict 1], size_t as[static restrict 1], size_t cs[static restrict 1], @@ -64,7 +65,7 @@ bitset_fill(GVA_LCS_Graph const graph, { for (gva_uint j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) { - if (graph.nodes[i].row > end_accent || graph.nodes[graph.edges[j].tail].row + graph.nodes[graph.edges[j].tail].length <= start_accent) + if (graph.nodes[i].row > end || graph.nodes[graph.edges[j].tail].row + graph.nodes[graph.edges[j].tail].length <= start) { continue; } // if @@ -74,11 +75,12 @@ bitset_fill(GVA_LCS_Graph const graph, graph.nodes[i], graph.nodes[graph.edges[j].tail], i == graph.source, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, &variant); + for (gva_uint z = 0; z < count; ++z) { for (gva_uint k = variant.start; k < variant.end; ++k) { - bitset_add(dels, k + z - start); + bitset_add(dels, k + z - offset); counter += 1; } // for } // for @@ -87,7 +89,7 @@ bitset_fill(GVA_LCS_Graph const graph, { for (gva_uint k = variant.start; k < variant.end + count; ++k) { - bitset_add(as, k - start); + bitset_add(as, k - offset); counter += 1; } // for } // if @@ -95,7 +97,7 @@ bitset_fill(GVA_LCS_Graph const graph, { for (gva_uint k = variant.start; k < variant.end + count; ++k) { - bitset_add(cs, k - start); + bitset_add(cs, k - offset); counter += 1; } // for } // if @@ -103,7 +105,7 @@ bitset_fill(GVA_LCS_Graph const graph, { for (gva_uint k = variant.start; k < variant.end + count; ++k) { - bitset_add(gs, k - start); + bitset_add(gs, k - offset); counter += 1; } // for } // if @@ -111,11 +113,11 @@ bitset_fill(GVA_LCS_Graph const graph, { for (gva_uint k = variant.start; k < variant.end + count; ++k) { - bitset_add(ts, k - start); + bitset_add(ts, k - offset); counter += 1; } // for } // if } // for } // for return counter; -} // bitfill \ No newline at end of file +} // bitfill diff --git a/src/bitset.h b/src/bitset.h index 55bb76e..133cb42 100644 --- a/src/bitset.h +++ b/src/bitset.h @@ -27,11 +27,13 @@ bitset_destroy(GVA_Allocator const allocator, size_t bitset[static 1]); size_t bitset_fill(GVA_LCS_Graph const graph, - gva_uint const start, gva_uint const start_accent, gva_uint const end_accent, - size_t dels[static restrict 1], - size_t as[static restrict 1], - size_t cs[static restrict 1], - size_t gs[static restrict 1], - size_t ts[static restrict 1]); + gva_uint const offset, + gva_uint const start, gva_uint const end, + size_t dels[static restrict 1], + size_t as[static restrict 1], + size_t cs[static restrict 1], + size_t gs[static restrict 1], + size_t ts[static restrict 1]); + #endif // GVA_BITSET_H diff --git a/src/lcs_graph.c b/src/lcs_graph.c index d8dac81..87995d8 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -252,18 +252,20 @@ gva_lcs_graph_init(GVA_Allocator const allocator, prev = lcs.index[i].tail; } // for - if (len > 0) + + if (len > 0 && lcs.nodes[prev].idx != 0) { gva_uint const idx = lcs.nodes[prev].idx; gva_uint const offset = graph.nodes[idx].length - lcs.index[lcs.length - 1].offset - len; ARRAY_APPEND(allocator, graph.local_supremal, ((GVA_Node) { graph.nodes[idx].row + offset, graph.nodes[idx].col + offset, len, GVA_NULL, idx })); + len = 0; } // if - if (graph.nodes != NULL && (len == 0 || lcs.nodes[prev].idx != 0)) + if (graph.nodes != NULL) { ARRAY_APPEND(allocator, graph.local_supremal, ((GVA_Node) { - graph.nodes[0].row + graph.nodes[0].length, graph.nodes[0].col + graph.nodes[0].length, 0, GVA_NULL, 0 + graph.nodes[0].row + graph.nodes[0].length - len, graph.nodes[0].col + graph.nodes[0].length - len, 0, GVA_NULL, 0 })); } //if @@ -273,8 +275,7 @@ gva_lcs_graph_init(GVA_Allocator const allocator, graph.nodes[source.idx].col += graph.local_supremal[0].length; graph.nodes[source.idx].length -= graph.local_supremal[0].length; - // TODO: what to do with length?! - // graph.nodes[0].length -= len; + graph.nodes[0].length -= len; gva_edges(graph.observed.str, graph.local_supremal[0], graph.local_supremal[array_length(graph.local_supremal) - 1], diff --git a/src/main.c b/src/main.c index 1416a5e..0ec3dfe 100644 --- a/src/main.c +++ b/src/main.c @@ -312,7 +312,7 @@ all_graphs(void) //lcs_graph_raw(stderr, graph); //lcs_graph_dot(stderr, graph); - gva_uint sup_len = graph.supremal.end - graph.supremal.start; + gva_uint const sup_len = graph.supremal.end - graph.supremal.start; size_t* dels = bitset_init(gva_std_allocator, sup_len + 1); size_t* as = bitset_init(gva_std_allocator, sup_len + 1); size_t* cs = bitset_init(gva_std_allocator, sup_len + 1); @@ -532,8 +532,7 @@ faststabber(int argc, char* argv[static argc + 1]) free(start_table); return EXIT_SUCCESS; - -} +} // faststabber int @@ -547,10 +546,8 @@ main(int argc, char* argv[static argc + 1]) // return all_graphs(); // extract single variant - // return extract(argc, argv); + //return extract(argc, argv); // faststabber return faststabber(argc, argv); - - } // main From 0c2811b715f136daf671d9a5ceb8795d65ef9d5d Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 3 Jul 2025 20:43:12 +0200 Subject: [PATCH 273/704] Debug comments --- src/compare.c | 43 ++++++++++++++++++++----------------------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/src/compare.c b/src/compare.c index dd13b59..124f648 100644 --- a/src/compare.c +++ b/src/compare.c @@ -1,6 +1,3 @@ -#include // FIXME: DEBUG - - #include // NULL, size_t #include // memchr, memcpy, strncmp @@ -115,28 +112,28 @@ gva_compare(GVA_Allocator const allocator, // could be done on intersection instead of union bitset_fill(lhs_graph, start, start_accent, end_accent, lhs_dels, lhs_as, lhs_cs, lhs_gs, lhs_ts); gva_lcs_graph_destroy(allocator, lhs_graph); - -// for (size_t i = 0; i < array_length(lhs_dels); ++i) -// { -// fprintf(stderr, "%2zu: %016zx\n", i, lhs_dels[i]); -// fprintf(stderr, "%2zu: %016zx\n", i, lhs_as[i]); -// fprintf(stderr, "%2zu: %016zx\n", i, lhs_cs[i]); -// fprintf(stderr, "%2zu: %016zx\n", i, lhs_gs[i]); -// fprintf(stderr, "%2zu: %016zx\n", i, lhs_ts[i]); -// } // for - +/* + for (size_t i = 0; i < array_length(lhs_dels); ++i) + { + fprintf(stderr, "%2zu: %016zx\n", i, lhs_dels[i]); + fprintf(stderr, "%2zu: %016zx\n", i, lhs_as[i]); + fprintf(stderr, "%2zu: %016zx\n", i, lhs_cs[i]); + fprintf(stderr, "%2zu: %016zx\n", i, lhs_gs[i]); + fprintf(stderr, "%2zu: %016zx\n", i, lhs_ts[i]); + } // for +*/ bitset_fill(rhs_graph, start, start_accent, end_accent, rhs_dels, rhs_as, rhs_cs, rhs_gs, rhs_ts); gva_lcs_graph_destroy(allocator, rhs_graph); - -// for (size_t i = 0; i < array_length(rhs_dels); ++i) -// { -// fprintf(stderr, "%2zu: %016zx\n", i, rhs_dels[i]); -// fprintf(stderr, "%2zu: %016zx\n", i, rhs_as[i]); -// fprintf(stderr, "%2zu: %016zx\n", i, rhs_cs[i]); -// fprintf(stderr, "%2zu: %016zx\n", i, rhs_gs[i]); -// fprintf(stderr, "%2zu: %016zx\n", i, rhs_ts[i]); -// } // for - +/* + for (size_t i = 0; i < array_length(rhs_dels); ++i) + { + fprintf(stderr, "%2zu: %016zx\n", i, rhs_dels[i]); + fprintf(stderr, "%2zu: %016zx\n", i, rhs_as[i]); + fprintf(stderr, "%2zu: %016zx\n", i, rhs_cs[i]); + fprintf(stderr, "%2zu: %016zx\n", i, rhs_gs[i]); + fprintf(stderr, "%2zu: %016zx\n", i, rhs_ts[i]); + } // for +*/ size_t const common = bitset_intersection_cnt(lhs_dels, rhs_dels) + bitset_intersection_cnt(lhs_as, rhs_as) + From b44793a3a1164febb1874ca2d13b5aa0bac373bb Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 3 Jul 2025 20:44:23 +0200 Subject: [PATCH 274/704] Calculate relation once --- src/main.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/main.c b/src/main.c index 0ec3dfe..f1514b7 100644 --- a/src/main.c +++ b/src/main.c @@ -251,10 +251,11 @@ compare(void) count += 1; // printf("%d\n", gva_compare(gva_std_allocator, seq.len, seq.str, lhs, rhs)); - if (strcmp(python, GVA_RELATION_LABELS[gva_compare(gva_std_allocator, seq.len, seq.str, lhs, rhs)]) != 0) + size_t const relation = gva_compare(gva_std_allocator, seq.len, seq.str, lhs, rhs); + if (strcmp(python, GVA_RELATION_LABELS[relation]) != 0) { - printf("different %s %zu %s %zu %zu %s %s\n", lhs_spdi, lhs_dist, rhs_spdi, rhs_dist, dist, python, GVA_RELATION_LABELS[gva_compare(gva_std_allocator, seq.len, seq.str, lhs, rhs)]); - } + printf("different %s %zu %s %zu %zu %s %s\n", lhs_spdi, lhs_dist, rhs_spdi, rhs_dist, dist, python, GVA_RELATION_LABELS[relation]); + } // if // printf("%s %s\n", lhs_spdi, rhs_spdi); } @@ -540,7 +541,7 @@ main(int argc, char* argv[static argc + 1]) { (void) argv; // check python relation output - // return compare(); + return compare(); // calculate graphs for all inputs // return all_graphs(); @@ -549,5 +550,5 @@ main(int argc, char* argv[static argc + 1]) //return extract(argc, argv); // faststabber - return faststabber(argc, argv); + //return faststabber(argc, argv); } // main From 7e993a55f0c0bf26dcc851aa56e45dce288217fe Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 3 Jul 2025 20:44:47 +0200 Subject: [PATCH 275/704] FIX: proper interval? --- src/bitset.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bitset.c b/src/bitset.c index c38041b..2408086 100644 --- a/src/bitset.c +++ b/src/bitset.c @@ -65,7 +65,7 @@ bitset_fill(GVA_LCS_Graph const graph, { for (gva_uint j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) { - if (graph.nodes[i].row > end || graph.nodes[graph.edges[j].tail].row + graph.nodes[graph.edges[j].tail].length <= start) + if (graph.nodes[i].row > end || graph.nodes[graph.edges[j].tail].row + graph.nodes[graph.edges[j].tail].length < start) { continue; } // if From 809aa4d73af57bcf7cf6e610057a3cae53563972 Mon Sep 17 00:00:00 2001 From: jkvis Date: Sun, 6 Jul 2025 14:17:28 +0200 Subject: [PATCH 276/704] Bitset block --- src/bitset.c | 22 +++++++++++++++++++++- src/bitset.h | 4 ++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/bitset.c b/src/bitset.c index 2408086..2eecd5f 100644 --- a/src/bitset.c +++ b/src/bitset.c @@ -26,10 +26,30 @@ bitset_init(GVA_Allocator const allocator, size_t const size) inline void bitset_add(size_t bitset[static 1], size_t const value) { - bitset[value / (sizeof(size_t) * CHAR_BIT)] |= (1ULL << (value % (sizeof(size_t) * CHAR_BIT))); + bitset[value / (sizeof(*bitset) * CHAR_BIT)] |= (1ULL << (value % (sizeof(*bitset) * CHAR_BIT))); } // bitset_add +inline void +bitset_add_block(size_t bitset[static 1], size_t const start, size_t const end) +{ + size_t const len = ((end - start) + sizeof(*bitset) * CHAR_BIT - 1) / (sizeof(*bitset) * CHAR_BIT); + for (size_t i = 0; i < len; ++i) + { + size_t mask = ~0x0ULL; + if (i == len - 1) + { + mask &= ~0x0ULL >> (sizeof(*bitset) * CHAR_BIT - (end % (sizeof(*bitset) * CHAR_BIT))); + } // if + if (i == 0) + { + mask &= ~0x0ULL << (start % (sizeof(*bitset) * CHAR_BIT)); + } // if + bitset[start / (sizeof(*bitset) * CHAR_BIT) + i] |= mask; + } // for +} // bitset_add_block + + inline size_t bitset_intersection_cnt(size_t const lhs[static 1], size_t const rhs[static 1]) { diff --git a/src/bitset.h b/src/bitset.h index 133cb42..76af373 100644 --- a/src/bitset.h +++ b/src/bitset.h @@ -17,6 +17,10 @@ void bitset_add(size_t bitset[static 1], size_t const value); +void +bitset_add_block(size_t bitset[static 1], size_t const start, size_t const end); + + size_t bitset_intersection_cnt(size_t const lhs[static 1], size_t const rhs[static 1]); From ff056fcbc554a61d7b334e65c5ccc1a01d7a788e Mon Sep 17 00:00:00 2001 From: jkvis Date: Sun, 6 Jul 2025 14:17:54 +0200 Subject: [PATCH 277/704] Bitset debug print --- src/main.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/main.c b/src/main.c index f1514b7..fcfe899 100644 --- a/src/main.c +++ b/src/main.c @@ -1,5 +1,6 @@ #define _XOPEN_SOURCE #include +#include // CHAR_BIT #include // NULL, size_t #include // FILE, stderr, fclose, fopen, fprintf #include // EXIT_* @@ -536,6 +537,31 @@ faststabber(int argc, char* argv[static argc + 1]) } // faststabber +void +bitset_print(size_t const bitset[static 1], size_t const size) +{ + for (intmax_t i = array_length(bitset) * sizeof(*bitset) * CHAR_BIT - 1; i >= 0; --i) + { + if ((size_t) i > size) + { + fprintf(stderr, " "); + } // if + else + { + fprintf(stderr, "%zu", bitset[i / (sizeof(*bitset) * CHAR_BIT)] >> (i % (sizeof(*bitset) * CHAR_BIT)) & 0x1); + } // else + if (i % (sizeof(*bitset) * CHAR_BIT) == 0) + { + fprintf(stderr, "\n"); + } // if + else if (i % CHAR_BIT == 0) + { + fprintf(stderr, " "); + } // if + } // for +} // bitset_print + + int main(int argc, char* argv[static argc + 1]) { From 0af3eeb1b3df3247a17bb73823c38bff05b12a0c Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 8 Jul 2025 14:24:38 +0200 Subject: [PATCH 278/704] Compare supremals --- src/bitset.c | 99 ++++---------------------------- src/bitset.h | 17 +----- src/compare.c | 155 +++++++++++++++++++++++++++++++++----------------- src/main.c | 51 +++-------------- 4 files changed, 123 insertions(+), 199 deletions(-) diff --git a/src/bitset.c b/src/bitset.c index 2eecd5f..d3e9196 100644 --- a/src/bitset.c +++ b/src/bitset.c @@ -24,30 +24,24 @@ bitset_init(GVA_Allocator const allocator, size_t const size) inline void -bitset_add(size_t bitset[static 1], size_t const value) +bitset_add(size_t bitset[static 1], size_t const start, size_t const end) { - bitset[value / (sizeof(*bitset) * CHAR_BIT)] |= (1ULL << (value % (sizeof(*bitset) * CHAR_BIT))); -} // bitset_add - - -inline void -bitset_add_block(size_t bitset[static 1], size_t const start, size_t const end) -{ - size_t const len = ((end - start) + sizeof(*bitset) * CHAR_BIT - 1) / (sizeof(*bitset) * CHAR_BIT); - for (size_t i = 0; i < len; ++i) + size_t const start_idx = start / (sizeof(*bitset) * CHAR_BIT); + size_t const end_idx = (end - 1) / (sizeof(*bitset) * CHAR_BIT); + for (size_t i = start_idx; i <= end_idx; ++i) { size_t mask = ~0x0ULL; - if (i == len - 1) + if (i == start_idx) { - mask &= ~0x0ULL >> (sizeof(*bitset) * CHAR_BIT - (end % (sizeof(*bitset) * CHAR_BIT))); + mask &= ~0x0ULL << (start % (sizeof(*bitset) * CHAR_BIT)); } // if - if (i == 0) + if (i == end_idx) { - mask &= ~0x0ULL << (start % (sizeof(*bitset) * CHAR_BIT)); + mask &= ~0x0ULL >> (sizeof(*bitset) * CHAR_BIT - (end % (sizeof(*bitset) * CHAR_BIT))); } // if - bitset[start / (sizeof(*bitset) * CHAR_BIT) + i] |= mask; + bitset[i] |= mask; } // for -} // bitset_add_block +} // bitset_add inline size_t @@ -68,76 +62,3 @@ bitset_destroy(GVA_Allocator const allocator, size_t bitset[static 1]) { return ARRAY_DESTROY(allocator, bitset); } // bitset_destroy - - -size_t -bitset_fill(GVA_LCS_Graph const graph, - gva_uint const offset, - gva_uint const start, gva_uint const end, - size_t dels[static restrict 1], - size_t as[static restrict 1], - size_t cs[static restrict 1], - size_t gs[static restrict 1], - size_t ts[static restrict 1]) -{ - size_t counter = 0; - for (size_t i = 0; i < array_length(graph.nodes); ++i) - { - for (gva_uint j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) - { - if (graph.nodes[i].row > end || graph.nodes[graph.edges[j].tail].row + graph.nodes[graph.edges[j].tail].length < start) - { - continue; - } // if - - GVA_Variant variant; - gva_uint const count = gva_edges(graph.observed.str, - graph.nodes[i], graph.nodes[graph.edges[j].tail], - i == graph.source, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, - &variant); - - for (gva_uint z = 0; z < count; ++z) - { - for (gva_uint k = variant.start; k < variant.end; ++k) - { - bitset_add(dels, k + z - offset); - counter += 1; - } // for - } // for - - if (memchr(variant.sequence.str, 'A', variant.sequence.len)) - { - for (gva_uint k = variant.start; k < variant.end + count; ++k) - { - bitset_add(as, k - offset); - counter += 1; - } // for - } // if - if (memchr(variant.sequence.str, 'C', variant.sequence.len)) - { - for (gva_uint k = variant.start; k < variant.end + count; ++k) - { - bitset_add(cs, k - offset); - counter += 1; - } // for - } // if - if (memchr(variant.sequence.str, 'G', variant.sequence.len)) - { - for (gva_uint k = variant.start; k < variant.end + count; ++k) - { - bitset_add(gs, k - offset); - counter += 1; - } // for - } // if - if (memchr(variant.sequence.str, 'T', variant.sequence.len)) - { - for (gva_uint k = variant.start; k < variant.end + count; ++k) - { - bitset_add(ts, k - offset); - counter += 1; - } // for - } // if - } // for - } // for - return counter; -} // bitfill diff --git a/src/bitset.h b/src/bitset.h index 76af373..fb5f8de 100644 --- a/src/bitset.h +++ b/src/bitset.h @@ -14,11 +14,7 @@ bitset_init(GVA_Allocator const allocator, size_t const size); void -bitset_add(size_t bitset[static 1], size_t const value); - - -void -bitset_add_block(size_t bitset[static 1], size_t const start, size_t const end); +bitset_add(size_t bitset[static 1], size_t const start, size_t const end); size_t @@ -29,15 +25,4 @@ size_t* bitset_destroy(GVA_Allocator const allocator, size_t bitset[static 1]); -size_t -bitset_fill(GVA_LCS_Graph const graph, - gva_uint const offset, - gva_uint const start, gva_uint const end, - size_t dels[static restrict 1], - size_t as[static restrict 1], - size_t cs[static restrict 1], - size_t gs[static restrict 1], - size_t ts[static restrict 1]); - - #endif // GVA_BITSET_H diff --git a/src/compare.c b/src/compare.c index 124f648..a3733b4 100644 --- a/src/compare.c +++ b/src/compare.c @@ -1,5 +1,6 @@ +#include // uint8_t #include // NULL, size_t -#include // memchr, memcpy, strncmp +#include // memcpy, strncmp #include "../include/allocator.h" // GVA_Allocator @@ -13,6 +14,87 @@ #include "bitset.h" // bitset_* +static uint8_t const NUC_A = 0x1; +static uint8_t const NUC_C = 0x2; +static uint8_t const NUC_G = 0x4; +static uint8_t const NUC_T = 0x8; + + +static inline uint8_t +nucleotides(size_t const len, char const sequence[static len]) +{ + static uint8_t const MASK[256] = + { + ['A'] = NUC_A, + ['C'] = NUC_C, + ['G'] = NUC_G, + ['T'] = NUC_T, + }; + static uint8_t const UNIVERSE = 0xF; + + uint8_t mask = 0x0; + for (size_t i = 0; mask < UNIVERSE && i < len; ++i) + { + mask |= MASK[(size_t) sequence[i]]; + } // for + return mask; +} // nucleotides + + +static size_t +bitset_fill(GVA_LCS_Graph const graph, + gva_uint const offset, + gva_uint const start, gva_uint const end, + size_t dels[static restrict 1], + size_t as[static restrict 1], + size_t cs[static restrict 1], + size_t gs[static restrict 1], + size_t ts[static restrict 1]) +{ + size_t counter = 0; + for (size_t i = 0; i < array_length(graph.nodes); ++i) + { + for (gva_uint j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) + { + if (graph.nodes[i].row > end || graph.nodes[graph.edges[j].tail].row + graph.nodes[graph.edges[j].tail].length < start) + { + continue; + } // if + + GVA_Variant variant; + gva_uint const count = gva_edges(graph.observed.str, + graph.nodes[i], graph.nodes[graph.edges[j].tail], + i == graph.source, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, + &variant); + + if (variant.end > variant.start) + { + bitset_add(dels, variant.start - offset, variant.end + count - 1 - offset); + } // if + + uint8_t const mask = nucleotides(variant.sequence.len, variant.sequence.str); + if ((mask & NUC_A) == NUC_A) + { + bitset_add(as, variant.start - offset, variant.end + count - offset); + } // if + if ((mask & NUC_C) == NUC_C) + { + bitset_add(cs, variant.start - offset, variant.end + count - offset); + } // if + if ((mask & NUC_G) == NUC_G) + { + bitset_add(gs, variant.start - offset, variant.end + count - offset); + } // if + if ((mask & NUC_T) == NUC_T) + { + bitset_add(ts, variant.start - offset, variant.end + count - offset); + } // if + } // for + } // for + return counter; +} // bitset_fill + + GVA_Relation gva_compare(GVA_Allocator const allocator, size_t const len_ref, char const reference[static len_ref], @@ -34,10 +116,8 @@ gva_compare(GVA_Allocator const allocator, size_t const start = MIN(lhs.start, rhs.start); size_t const end = MAX(lhs.end, rhs.end); -// fprintf(stderr, "start: %zu end: %zu\n", start, end); size_t const lhs_len = (lhs.start - start) + lhs.sequence.len + (end - lhs.end); -// fprintf(stderr, "lhs_len: %zu\n", lhs_len); char* lhs_obs = allocator.allocate(allocator.context, NULL, 0, lhs_len); if (lhs_len > 0 && lhs_obs == NULL) { @@ -45,7 +125,6 @@ gva_compare(GVA_Allocator const allocator, } // if size_t const rhs_len = (rhs.start - start) + rhs.sequence.len + (end - rhs.end); -// fprintf(stderr, "rhs_len: %zu\n", rhs_len); char* rhs_obs = allocator.allocate(allocator.context, NULL, 0, rhs_len); if (rhs_len > 0 && rhs_obs == NULL) { @@ -60,18 +139,12 @@ gva_compare(GVA_Allocator const allocator, memcpy(lhs_obs + lhs.start - start, lhs.sequence.str, lhs.sequence.len); memcpy(lhs_obs + lhs.start - start + lhs.sequence.len, reference + lhs.end, end - lhs.end); -// fprintf(stderr, "lhs_obs(%zu): %.*s\n", lhs_len, (int) lhs_len, lhs_obs); - memcpy(rhs_obs, reference + start, rhs.start - start); memcpy(rhs_obs + rhs.start - start, rhs.sequence.str, rhs.sequence.len); memcpy(rhs_obs + rhs.start - start + rhs.sequence.len, reference + rhs.end, end - rhs.end); -// fprintf(stderr, "rhs_obs(%zu): %.*s\n", rhs_len, (int) rhs_len, rhs_obs); - size_t const dist = gva_edit_distance(allocator, lhs_len, lhs_obs, rhs_len, rhs_obs); -// fprintf(stderr, "distances: %zu, %zu, %zu\n", lhs_dist, rhs_dist, dist); - if (lhs_dist + rhs_dist == dist) { relation = GVA_DISJOINT; @@ -86,54 +159,32 @@ gva_compare(GVA_Allocator const allocator, } // if else { - // inject random bits GVA_LCS_Graph lhs_graph = gva_lcs_graph_init(allocator, end - start, reference + start, lhs_len, lhs_obs, start); GVA_LCS_Graph rhs_graph = gva_lcs_graph_init(allocator, end - start, reference + start, rhs_len, rhs_obs, start); - gva_uint const lhs_sup_len = end - start; -// fprintf(stderr, "lhs suplen %d\n", lhs_sup_len); - size_t* lhs_dels = bitset_init(allocator, lhs_sup_len + 1); // can be one shorter - size_t* lhs_as = bitset_init(allocator, lhs_sup_len + 1); - size_t* lhs_cs = bitset_init(allocator, lhs_sup_len + 1); - size_t* lhs_gs = bitset_init(allocator, lhs_sup_len + 1); - size_t* lhs_ts = bitset_init(allocator, lhs_sup_len + 1); - - gva_uint const rhs_sup_len = end - start; -// fprintf(stderr, "rhs suplen %d\n", rhs_sup_len); - size_t* rhs_dels = bitset_init(allocator, rhs_sup_len + 1); // can be one shorter - size_t* rhs_as = bitset_init(allocator, rhs_sup_len + 1); - size_t* rhs_cs = bitset_init(allocator, rhs_sup_len + 1); - size_t* rhs_gs = bitset_init(allocator, rhs_sup_len + 1); - size_t* rhs_ts = bitset_init(allocator, rhs_sup_len + 1); - - size_t const start_accent = MAX(lhs.start, rhs.start); - size_t const end_accent = MIN(lhs.end, rhs.end); + gva_uint const len = end - start + 1; + size_t* lhs_dels = bitset_init(allocator, len); // can be one shorter + size_t* lhs_as = bitset_init(allocator, len); + size_t* lhs_cs = bitset_init(allocator, len); + size_t* lhs_gs = bitset_init(allocator, len); + size_t* lhs_ts = bitset_init(allocator, len); + + size_t* rhs_dels = bitset_init(allocator, len); // can be one shorter + size_t* rhs_as = bitset_init(allocator, len); + size_t* rhs_cs = bitset_init(allocator, len); + size_t* rhs_gs = bitset_init(allocator, len); + size_t* rhs_ts = bitset_init(allocator, len); + + size_t const start_intersection = MAX(lhs.start, rhs.start); + size_t const end_intersection = MIN(lhs.end, rhs.end); // could be done on intersection instead of union - bitset_fill(lhs_graph, start, start_accent, end_accent, lhs_dels, lhs_as, lhs_cs, lhs_gs, lhs_ts); + bitset_fill(lhs_graph, start, start_intersection, end_intersection, lhs_dels, lhs_as, lhs_cs, lhs_gs, lhs_ts); gva_lcs_graph_destroy(allocator, lhs_graph); -/* - for (size_t i = 0; i < array_length(lhs_dels); ++i) - { - fprintf(stderr, "%2zu: %016zx\n", i, lhs_dels[i]); - fprintf(stderr, "%2zu: %016zx\n", i, lhs_as[i]); - fprintf(stderr, "%2zu: %016zx\n", i, lhs_cs[i]); - fprintf(stderr, "%2zu: %016zx\n", i, lhs_gs[i]); - fprintf(stderr, "%2zu: %016zx\n", i, lhs_ts[i]); - } // for -*/ - bitset_fill(rhs_graph, start, start_accent, end_accent, rhs_dels, rhs_as, rhs_cs, rhs_gs, rhs_ts); + + bitset_fill(rhs_graph, start, start_intersection, end_intersection, rhs_dels, rhs_as, rhs_cs, rhs_gs, rhs_ts); gva_lcs_graph_destroy(allocator, rhs_graph); -/* - for (size_t i = 0; i < array_length(rhs_dels); ++i) - { - fprintf(stderr, "%2zu: %016zx\n", i, rhs_dels[i]); - fprintf(stderr, "%2zu: %016zx\n", i, rhs_as[i]); - fprintf(stderr, "%2zu: %016zx\n", i, rhs_cs[i]); - fprintf(stderr, "%2zu: %016zx\n", i, rhs_gs[i]); - fprintf(stderr, "%2zu: %016zx\n", i, rhs_ts[i]); - } // for -*/ + size_t const common = bitset_intersection_cnt(lhs_dels, rhs_dels) + bitset_intersection_cnt(lhs_as, rhs_as) + @@ -167,4 +218,4 @@ gva_compare(GVA_Allocator const allocator, lhs_obs = allocator.allocate(allocator.context, lhs_obs, lhs_len, 0); return relation; -} // gva_compare \ No newline at end of file +} // gva_compare diff --git a/src/main.c b/src/main.c index fcfe899..7ca8f49 100644 --- a/src/main.c +++ b/src/main.c @@ -252,10 +252,11 @@ compare(void) count += 1; // printf("%d\n", gva_compare(gva_std_allocator, seq.len, seq.str, lhs, rhs)); + //fprintf(stderr, "%s %zu %s %zu %zu %s\n", lhs_spdi, lhs_dist, rhs_spdi, rhs_dist, dist, python); size_t const relation = gva_compare(gva_std_allocator, seq.len, seq.str, lhs, rhs); if (strcmp(python, GVA_RELATION_LABELS[relation]) != 0) { - printf("different %s %zu %s %zu %zu %s %s\n", lhs_spdi, lhs_dist, rhs_spdi, rhs_dist, dist, python, GVA_RELATION_LABELS[relation]); + printf("%s %zu %s %zu %zu %s %s\n", lhs_spdi, lhs_dist, rhs_spdi, rhs_dist, dist, python, GVA_RELATION_LABELS[relation]); } // if // printf("%s %s\n", lhs_spdi, rhs_spdi); @@ -314,23 +315,14 @@ all_graphs(void) //lcs_graph_raw(stderr, graph); //lcs_graph_dot(stderr, graph); - gva_uint const sup_len = graph.supremal.end - graph.supremal.start; - size_t* dels = bitset_init(gva_std_allocator, sup_len + 1); - size_t* as = bitset_init(gva_std_allocator, sup_len + 1); - size_t* cs = bitset_init(gva_std_allocator, sup_len + 1); - size_t* gs = bitset_init(gva_std_allocator, sup_len + 1); - size_t* ts = bitset_init(gva_std_allocator, sup_len + 1); + //gva_uint const sup_len = graph.supremal.end - graph.supremal.start; + //size_t* dels = bitset_init(gva_std_allocator, sup_len + 1); + //size_t* as = bitset_init(gva_std_allocator, sup_len + 1); + //size_t* cs = bitset_init(gva_std_allocator, sup_len + 1); + //size_t* gs = bitset_init(gva_std_allocator, sup_len + 1); + //size_t* ts = bitset_init(gva_std_allocator, sup_len + 1); - counter += bitset_fill(graph, graph.supremal.start, graph.supremal.start, graph.supremal.end, dels, as, cs, gs, ts); - - //for (size_t i = 0; i < array_length(dels); ++i) - //{ - // fprintf(stderr, "%2zu: %016zx\n", i, dels[i]); - // fprintf(stderr, "%2zu: %016zx\n", i, as[i]); - // fprintf(stderr, "%2zu: %016zx\n", i, cs[i]); - // fprintf(stderr, "%2zu: %016zx\n", i, gs[i]); - // fprintf(stderr, "%2zu: %016zx\n", i, ts[i]); - //} // for + //counter += bitset_fill(graph, graph.supremal.start, graph.supremal.start, graph.supremal.end, dels, as, cs, gs, ts); //ts = bitset_destroy(gva_std_allocator, ts); //gs = bitset_destroy(gva_std_allocator, gs); @@ -537,31 +529,6 @@ faststabber(int argc, char* argv[static argc + 1]) } // faststabber -void -bitset_print(size_t const bitset[static 1], size_t const size) -{ - for (intmax_t i = array_length(bitset) * sizeof(*bitset) * CHAR_BIT - 1; i >= 0; --i) - { - if ((size_t) i > size) - { - fprintf(stderr, " "); - } // if - else - { - fprintf(stderr, "%zu", bitset[i / (sizeof(*bitset) * CHAR_BIT)] >> (i % (sizeof(*bitset) * CHAR_BIT)) & 0x1); - } // else - if (i % (sizeof(*bitset) * CHAR_BIT) == 0) - { - fprintf(stderr, "\n"); - } // if - else if (i % CHAR_BIT == 0) - { - fprintf(stderr, " "); - } // if - } // for -} // bitset_print - - int main(int argc, char* argv[static argc + 1]) { From 23b62ae2a2b4bc324aa738640e8300c9db581cf4 Mon Sep 17 00:00:00 2001 From: jkvis Date: Sun, 13 Jul 2025 10:07:49 +0200 Subject: [PATCH 279/704] Simple SVG --- src/main.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/src/main.c b/src/main.c index 7ca8f49..3258040 100644 --- a/src/main.c +++ b/src/main.c @@ -22,6 +22,70 @@ #include "bitset.h" // bitset_* +static void +lcs_graph_svg(FILE* const stream, GVA_LCS_Graph const graph) +{ + gva_uint const offset = graph.nodes[graph.source].row; + gva_uint const scale = 30; + fprintf(stream, "\n", (graph.nodes[0].col + graph.nodes[0].length) * scale + 2 * scale, (graph.nodes[0].row + graph.nodes[0].length - offset) * scale + 2 * scale); + + fprintf(stream, "\n"); + for (size_t i = 0; i < array_length(graph.nodes); ++i) + { + if (graph.nodes[i].lambda != GVA_NULL) + { + gva_uint const row = (graph.nodes[i].row - offset) * scale + scale; + gva_uint const col = graph.nodes[i].col * scale + scale; + gva_uint const to_row = (graph.nodes[graph.nodes[i].lambda].row - offset) * scale + scale; + gva_uint const to_col = graph.nodes[graph.nodes[i].lambda].col * scale + scale; + fprintf(stream, "\n", col, row, to_col, to_row); + } // if + + for (gva_uint j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) + { + GVA_Variant variant; + gva_uint const count = gva_edges(graph.observed.str, + graph.nodes[i], graph.nodes[graph.edges[j].tail], + i == graph.source, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, + &variant); + + gva_uint const row = (variant.start - (variant.start > 0) - offset); // * scale + scale; + gva_uint const col = (variant.sequence.str - graph.observed.str - (variant.start > 0)); // * scale + scale; + gva_uint const to_row = (variant.end + count - 1 - offset); // * scale + scale; + gva_uint const to_col = (col + count - (variant.start == 0) + variant.sequence.len); // * scale + scale; + + fprintf(stream, "\n", col * scale + scale, row * scale + scale, to_col * scale + scale, to_row * scale + scale, (double) count / 2.0); + } // for + } // for + fprintf(stream, "\n"); + + for (size_t i = 0; i < array_length(graph.nodes); ++i) + { + gva_uint const row = (graph.nodes[i].row - offset) * scale + scale; + gva_uint const col = graph.nodes[i].col * scale + scale; + if (graph.nodes[i].length < 2) + { + fprintf(stream, "\n", col, row); + } // if + else + { + gva_uint const to_row = (graph.nodes[i].row - offset + graph.nodes[i].length) * scale + scale; + gva_uint const to_col = (graph.nodes[i].col + graph.nodes[i].length) * scale + scale; + fprintf(stream, "\n", col, row, to_col, to_row); + fprintf(stream, "\n", col, row, to_col, to_row); + } // else + fprintf(stream, "(%u, %u, %u)\n", col, row + 1, graph.nodes[i].row - offset, graph.nodes[i].col, graph.nodes[i].length); + if (graph.nodes[i].lambda != GVA_NULL) + { + gva_uint const row = (graph.nodes[graph.nodes[i].lambda].row - offset) * scale + scale; + gva_uint const col = graph.nodes[graph.nodes[i].lambda].col * scale + scale; + fprintf(stream, "(%u, %u, %u)\n", col, row + 1, graph.nodes[graph.nodes[i].lambda].row - offset, graph.nodes[graph.nodes[i].lambda].col, graph.nodes[graph.nodes[i].lambda].length); + } // ifr + } // for + fprintf(stream, "\n"); +} // lcs_graph_svg + + static void lcs_graph_dot(FILE* const stream, GVA_LCS_Graph const graph) { @@ -366,6 +430,7 @@ extract(int const argc, char* argv[static argc + 1]) lcs_graph_raw(stderr, graph); lcs_graph_dot(stderr, graph); lcs_graph_json(stdout, graph); + lcs_graph_svg(stderr, graph); GVA_Variant* canonical = gva_extract(gva_std_allocator, graph); for (size_t i = 0; i < array_length(canonical); ++i) From 9831446feb88c24d668a86a4ab804c1527de0961 Mon Sep 17 00:00:00 2001 From: jkvis Date: Sun, 13 Jul 2025 10:08:57 +0200 Subject: [PATCH 280/704] Count difficult disjoints --- include/compare.h | 3 +++ src/compare.c | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/include/compare.h b/include/compare.h index bed0ac2..ad95e0a 100644 --- a/include/compare.h +++ b/include/compare.h @@ -7,6 +7,9 @@ #include "variant.h" // GVA_VARIANT +extern size_t disjoint_count; + + GVA_Relation gva_compare(GVA_Allocator const allocator, size_t const len_ref, char const reference[static len_ref], diff --git a/src/compare.c b/src/compare.c index a3733b4..f944a22 100644 --- a/src/compare.c +++ b/src/compare.c @@ -95,6 +95,9 @@ bitset_fill(GVA_LCS_Graph const graph, } // bitset_fill +size_t disjoint_count = 0; + + GVA_Relation gva_compare(GVA_Allocator const allocator, size_t const len_ref, char const reference[static len_ref], @@ -199,6 +202,7 @@ gva_compare(GVA_Allocator const allocator, else { relation = GVA_DISJOINT; + disjoint_count += 1; } // else lhs_ts = bitset_destroy(allocator, lhs_ts); From 430dcfec0d5a140034ff1e5c24bb31f7648f747b Mon Sep 17 00:00:00 2001 From: jkvis Date: Sun, 13 Jul 2025 10:09:30 +0200 Subject: [PATCH 281/704] Exclude nodes in compare --- src/compare.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/compare.c b/src/compare.c index f944a22..37bbe6b 100644 --- a/src/compare.c +++ b/src/compare.c @@ -54,9 +54,14 @@ bitset_fill(GVA_LCS_Graph const graph, size_t counter = 0; for (size_t i = 0; i < array_length(graph.nodes); ++i) { + if (graph.nodes[i].row > end) + { + continue; + } // if + for (gva_uint j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) { - if (graph.nodes[i].row > end || graph.nodes[graph.edges[j].tail].row + graph.nodes[graph.edges[j].tail].length < start) + if (graph.nodes[graph.edges[j].tail].row + graph.nodes[graph.edges[j].tail].length < start) { continue; } // if From 34a5e48fd5d8ab0877312f0e71b03306fb2dc0b2 Mon Sep 17 00:00:00 2001 From: jkvis Date: Sun, 13 Jul 2025 10:09:46 +0200 Subject: [PATCH 282/704] VKGL experiment --- src/main.c | 72 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 42 insertions(+), 30 deletions(-) diff --git a/src/main.c b/src/main.c index 3258040..05ef06b 100644 --- a/src/main.c +++ b/src/main.c @@ -1,11 +1,12 @@ -#define _XOPEN_SOURCE -#include +//#define _XOPEN_SOURCE +//#include +#include // errno #include // CHAR_BIT #include // NULL, size_t #include // FILE, stderr, fclose, fopen, fprintf #include // EXIT_* -#include // strcmp, strlen -#include // optarg +#include // strcmp, strerror, strlen +//#include // optarg #include "../include/compare.h" // gva_compare @@ -281,25 +282,35 @@ lcs_graph_raw(FILE* const stream, GVA_LCS_Graph const graph) int -compare(void) +compare(int argc, char* argv[static argc + 1]) { - GVA_String seq = {0, NULL}; - FILE* const restrict stream = fopen("data/NC_000001.11.fasta", "r"); - if (stream != NULL) + GVA_String reference = {0, NULL}; + errno = 0; + FILE* const restrict stream = fopen(argv[1], "r"); + if (stream == NULL) { - seq = gva_fasta_sequence(gva_std_allocator, stream); - fclose(stream); + fprintf(stderr, "error: %s\n", strerror(errno)); + return EXIT_FAILURE; } // if + reference = gva_fasta_sequence(gva_std_allocator, stream); + fclose(stream); + + disjoint_count = 0; // NC_000001.11:169556314:6:TTTTTCTCT 3 NC_000001.11:169556314:8:TTTTTGTCTGGCTGC 7 4 is_contained + // NC_000001.10:g.103496806_103496807delAA NC_000001.10:103496805:13:AAAAAAAAAAA NC_000001.10:g.103496811A>C NC_000001.10:103496805:13:AAAAACAAAAAAA overlap + char lhs_hgvs[4096]; char lhs_spdi[4096]; - size_t lhs_dist; + //size_t lhs_dist; + char rhs_hgvs[4096]; char rhs_spdi[4096]; - size_t rhs_dist; - size_t dist; - char python[32]; + //size_t rhs_dist; + //size_t dist; + //char python[32]; + char relation[32]; size_t count = 0; - while (fscanf(stdin, "%4096s %zu %4096s %zu %zu %32s\n", lhs_spdi, &lhs_dist, rhs_spdi, &rhs_dist, &dist, python) == 6) + //while (fscanf(stdin, "%4096s %zu %4096s %zu %zu %32s\n", lhs_spdi, &lhs_dist, rhs_spdi, &rhs_dist, &dist, python) == 6) + while (fscanf(stdin, "%4096s %4096s %4096s %4096s %32s\n", lhs_hgvs, lhs_spdi, rhs_hgvs, rhs_spdi, relation) == 5) { GVA_Variant lhs; if (!gva_parse_spdi(strlen(lhs_spdi), lhs_spdi, &lhs)) @@ -313,20 +324,20 @@ compare(void) fprintf(stderr, "PARSE ERROR: %s\n", rhs_spdi); continue; } // if - count += 1; -// printf("%d\n", gva_compare(gva_std_allocator, seq.len, seq.str, lhs, rhs)); //fprintf(stderr, "%s %zu %s %zu %zu %s\n", lhs_spdi, lhs_dist, rhs_spdi, rhs_dist, dist, python); - size_t const relation = gva_compare(gva_std_allocator, seq.len, seq.str, lhs, rhs); - if (strcmp(python, GVA_RELATION_LABELS[relation]) != 0) + size_t const relation = gva_compare(gva_std_allocator, reference.len, reference.str, lhs, rhs); + //if (strcmp(python, GVA_RELATION_LABELS[relation]) != 0) { - printf("%s %zu %s %zu %zu %s %s\n", lhs_spdi, lhs_dist, rhs_spdi, rhs_dist, dist, python, GVA_RELATION_LABELS[relation]); + //printf("%s %zu %s %zu %zu %s %s\n", lhs_spdi, lhs_dist, rhs_spdi, rhs_dist, dist, python, GVA_RELATION_LABELS[relation]); + printf("%s %s %s %s %s\n", lhs_hgvs, lhs_spdi, rhs_hgvs, rhs_spdi, GVA_RELATION_LABELS[relation]); } // if -// printf("%s %s\n", lhs_spdi, rhs_spdi); - } - printf("%zu\n", count); - seq.str = gva_std_allocator.allocate(gva_std_allocator.context, seq.str, seq.len, 0); + count += 1; + } // while + fprintf(stderr, "total: %zu\n", count); + fprintf(stderr, "disjoint: %zu\n", disjoint_count); + reference.str = gva_std_allocator.allocate(gva_std_allocator.context, reference.str, reference.len, 0); return 0; } // compare @@ -450,13 +461,13 @@ extract(int const argc, char* argv[static argc + 1]) } // extract +/* int faststabber(int argc, char* argv[static argc + 1]) { -/* - check(stdin, 38); - return -1; -*/ + //check(stdin, 38); + //return -1; + uint32_t n = 0; uint32_t q = 0; uint32_t r = 0; @@ -592,6 +603,7 @@ faststabber(int argc, char* argv[static argc + 1]) return EXIT_SUCCESS; } // faststabber +*/ int @@ -599,10 +611,10 @@ main(int argc, char* argv[static argc + 1]) { (void) argv; // check python relation output - return compare(); + return compare(argc, argv); // calculate graphs for all inputs - // return all_graphs(); + //return all_graphs(); // extract single variant //return extract(argc, argv); From 602091e220f7d7bb1214ab9a229e330903d2f066 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 17 Jul 2025 12:12:46 +0200 Subject: [PATCH 283/704] Array-based faststabber --- include/faststabber.h | 89 ------------- include/stabbing.h | 44 +++++++ src/faststabber.c | 296 ------------------------------------------ src/main.c | 208 ++++++++++------------------- src/stabbing.c | 153 ++++++++++++++++++++++ 5 files changed, 263 insertions(+), 527 deletions(-) delete mode 100644 include/faststabber.h create mode 100644 include/stabbing.h delete mode 100644 src/faststabber.c create mode 100644 src/stabbing.c diff --git a/include/faststabber.h b/include/faststabber.h deleted file mode 100644 index 7e07330..0000000 --- a/include/faststabber.h +++ /dev/null @@ -1,89 +0,0 @@ -#ifndef GVA_FASTSTABBER_H -#define GVA_FASTSTABBER_H - - -typedef struct Node -{ - uint32_t start; - uint32_t end; - - struct Node* restrict parent; - struct Node* restrict leftsibling; - struct Node* restrict rightchild; -} Node; - - -typedef struct Stack -{ - Node* restrict node; - struct Stack* restrict next; -} Stack; - - -struct Bed_entry -{ - char reference[32]; - size_t count; - size_t node_count; - int start; - int end; -}; // Bed_entry - - - -Node* -stack_top(Stack const* const restrict stack); - -Stack* -stack_push(Stack* const restrict stack, Node* const restrict node); - -Stack* -stack_pop(Stack* const restrict stack); - -Node* -create_node(uint32_t const start, uint32_t const end); - -Node* -add_node(Node* const restrict last_node, Node* const restrict node); - -size_t -draw_edge(Node const* const restrict node, void* const restrict arg); - -size_t -draw_node(Node const* const restrict node, void* const restrict arg); - -size_t -traverse(Node* const restrict node, - size_t (*func)(Node const* const restrict, void* const restrict), - void* const restrict arg); - -size_t -write_dot(FILE* const restrict fp, Node* const restrict root); - -void -destroy(Node* const restrict node); - -void -read_bed(FILE* const restrict fp, - uint32_t const max, - Node** tree, - Node* start_table[]); - -size_t -trav(Node* const node, - uint32_t const start, - uint32_t const end, - Stack* restrict* const restrict output); - -size_t -stab(Node* const node, - uint32_t const start, - uint32_t const end, - Stack* restrict* const restrict output); - -void -query_bed(FILE* const restrict fp, - Node* const start_table[restrict]); - - -#endif // GVA_FASTSTABBER_H diff --git a/include/stabbing.h b/include/stabbing.h new file mode 100644 index 0000000..6286158 --- /dev/null +++ b/include/stabbing.h @@ -0,0 +1,44 @@ +#ifndef GVA_STABBING_H +#define GVA_STABBING_H + + +#include // size_t + +#include "allocator.h" // GVA_Allocator +#include "types.h" // gva_uint + + +typedef struct +{ + gva_uint parent; + gva_uint leftsibling; + gva_uint rightchild; + + gva_uint start; + gva_uint end; + // TODO: inserted seq, data +} GVA_Stabbing_Entry; + + +typedef struct +{ + GVA_Stabbing_Entry* entries; + gva_uint* start_table; + size_t len_ref; +} GVA_Stabbing_Index; + + +GVA_Stabbing_Index +gva_stabbing_index_init(GVA_Allocator const allocator, size_t const len_ref, GVA_Stabbing_Entry* const entries); + + +void +gva_stabbing_index_destroy(GVA_Allocator const allocator, GVA_Stabbing_Index index); + + +gva_uint* +gva_stabbing_index_stab(GVA_Allocator const allocator, GVA_Stabbing_Index const index, + gva_uint const start, gva_uint const end); + + +#endif // GVA_STABBING_H diff --git a/src/faststabber.c b/src/faststabber.c deleted file mode 100644 index 0991e58..0000000 --- a/src/faststabber.c +++ /dev/null @@ -1,296 +0,0 @@ -#define _XOPEN_SOURCE - - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "../include/faststabber.h" // Node, Stack - - -#define TIC(X) clock_t const X = clock() -#define TOC(X) fprintf(stderr, "time %s: %.3f s\n", (#X), (double)(clock() - (X)) / CLOCKS_PER_SEC) - - -Node* -stack_top(Stack const* const restrict stack) -{ - assert(stack != NULL); - return stack->node; -} // stack_top - - -Stack* -stack_push(Stack* const restrict stack, Node* const restrict node) -{ - Stack* const restrict top = malloc(sizeof(*top)); - assert(top != NULL); - top->node = node; - top->next = stack; - return top; -} // stack_push - - -Stack* -stack_pop(Stack* const restrict stack) -{ - assert(stack != NULL); - Stack* const restrict top = stack->next; - free(stack); - return top; -} // stack_pop - - -Node* -create_node(uint32_t const start, uint32_t const end) -{ - Node* const restrict node = malloc(sizeof(*node)); - assert(node != NULL); - - node->start = start; - node->end = end; - node->parent = NULL; - node->leftsibling = NULL; - node->rightchild = NULL; - return node; -} // create_node - - -Node* -add_node(Node* const restrict last_node, Node* const restrict node) -{ - assert(node != NULL); - - // get parent - node->parent = last_node; - while (node->parent != NULL && node->parent->end < node->end) - { - node->parent = node->parent->parent; - } // while - - assert(node->parent != NULL); - - // push new sibling - node->leftsibling = node->parent->rightchild; - node->parent->rightchild = node; - - return node; -} // add_node - - -size_t -draw_edge(Node const* const restrict node, void* const restrict arg) -{ - assert(node != NULL); - if (node->parent != NULL) - { - return fprintf(arg, "n%p -> n%p[dir=none];\n", (void*) node->parent, (void*) node); - } // if - return 0; -} // draw_edge - - -size_t -draw_node(Node const* const restrict node, void* const restrict arg) -{ - return fprintf(arg, "n%p[label=\"%u–%u\"];\n", (void*) node, node->start, node->end); -} // draw_node - - -size_t -traverse(Node* const restrict node, - size_t (*func)(Node const* const restrict, void* const restrict), - void* const restrict arg) -{ - if (node == NULL) - { - return 0; - } // if - - return traverse(node->leftsibling, func, arg) + - func(node, arg) + - traverse(node->rightchild, func, arg); -} // traverse - - -size_t -write_dot(FILE* const restrict fp, Node* const restrict root) -{ - assert(fp != NULL); - - return fputs("digraph G {\n", fp) + - traverse(root, draw_node, fp) + - traverse(root, draw_edge, fp) + - fputs("}\n", fp); -} // write_dot - - -void -destroy(Node* const restrict node) -{ - if (node == NULL) - { - return; - } // if - - destroy(node->leftsibling); - destroy(node->rightchild); - free(node); -} // destroy - - -void -read_bed(FILE* const restrict fp, - uint32_t const max, - Node** tree, - Node* start_table[]) -{ - assert(fp != NULL); - - // push root node on the stack - Node* last_node = create_node(0, max); - *tree = last_node; - - Stack* restrict stack = stack_push(NULL, last_node); - Node* restrict top = stack_top(stack); - - // read first entry - char reference[128] = {0}; - uint32_t start = 0; - uint32_t end = 0; - int ret = fscanf(fp, "%127s %" PRIu32 " %" PRIu32, reference, &start, &end); - assert(ret == 3); - - for (uint32_t i = 0; i < max; ++i) - { - //fprintf(stderr, "index iteration: %" PRIu32 "\n", i); - - // pop while end smaller than index - while (top->end < i) - { - assert(stack != NULL); - //fprintf(stderr, "Popping %" PRIu32 "--%" PRIu32 " from stack\n", top->start, top->end); - stack = stack_pop(stack); - top = stack_top(stack); - } // while - - while (i >= start && i <= end && !(start == top->start && end == top->end)) - { - do - { - Node* const node = create_node(start, end); - //fprintf(stderr, "Pushing %" PRIu32 "--%" PRIu32 " on stack\n", start, end); - stack = stack_push(stack, node); - top = stack_top(stack); - - last_node = add_node(last_node, node); - - ret = fscanf(fp, "%127s %" PRIu32 " %" PRIu32, reference, &start, &end); - if (ret == -1) - { - break; - } // if - assert(ret == 3); - } while (start == top->start && end == top->end); - } /// while - - //fprintf(stderr, "start_table[%" PRIu32 "] := %" PRIu32 "--%" PRIu32 "\n", i, top->start, top->end); - start_table[i] = top; - } // for - - assert(stack != NULL); - stack = stack_pop(stack); - assert(stack == NULL); -} // read_bed - - -size_t -trav(Node* const node, - uint32_t const start, - uint32_t const end, - Stack* restrict* const restrict output) -{ - size_t count = 0; - Node* restrict tmp = node; - while (tmp != NULL && end <= tmp->end) - { - //fprintf(stderr, "trav: %p: %" PRIu32 "--%" PRIu32 "\n", (void*) tmp, tmp->start, tmp->end); - if (start >= tmp->start) - { - count += trav(tmp->rightchild, start, end, output) + 1; - *output = stack_push(*output, tmp); - } // if - tmp = tmp->leftsibling; - } // while - return count; -} // trav - - -size_t -stab(Node* const node, - uint32_t const start, - uint32_t const end, - Stack* restrict* const restrict output) -{ - size_t count = 0; - Node* restrict tmp = node; - while (tmp != NULL && tmp->parent != NULL) - { - //fprintf(stderr, "stab: %p: %" PRIu32 "--%" PRIu32 "\n", (void*) tmp, tmp->start, tmp->end); - if (start >= tmp->start) - { - count += 1; - *output = stack_push(*output, tmp); - } // if - count += trav(tmp->leftsibling, start, end, output); - tmp = tmp->parent; - } // while - return count; -} // stab - - -//static struct Bed_entry bed[250000000]; -// -//void -//query_bed(FILE* const restrict fp, -// Node* const start_table[restrict]) -//{ -// assert(fp != NULL); -// -// TIC(read_bed); -// size_t idx = 0; -// while (fscanf(fp, "%31s %d %d", bed[idx].reference, &bed[idx].start, &bed[idx].end) == 3) -// { -// idx += 1; -// } // while -// TOC(read_bed); -// -// TIC(annotate); -// for (size_t i = 0; i < idx; ++i) -// { -// Stack* restrict output = NULL; -// bed[i].count = stab(start_table[bed[i].end], bed[i].start, bed[i].end, &output); -// bed[i].node_count = 0; -// /* -// while (output != NULL) -// { -// output = stack_pop(output); -// bed[i].count += 1; -// } // while -// */ -// } // for -// TOC(annotate); -// -// TIC(write_ann); -// for (size_t i = 0; i < idx; ++i) -// { -// printf("%s\t%d\t%d\t%zu\t%zu\n", bed[i].reference, bed[i].start, bed[i].end, bed[i].count, bed[i].node_count); -// } // for -// TOC(write_ann); -//} // query_bed \ No newline at end of file diff --git a/src/main.c b/src/main.c index 05ef06b..01e73b7 100644 --- a/src/main.c +++ b/src/main.c @@ -12,9 +12,9 @@ #include "../include/compare.h" // gva_compare #include "../include/edit.h" // gva_edit_distance #include "../include/extract.h" // gva_extract -#include "../include/faststabber.h" // Node, Stack #include "../include/lcs_graph.h" // GVA_LCS_Graph, GVA_Variant, gva_lcs_graph_*, gva_edges #include "../include/relations.h" // GVA_RELATION_LABELS +#include "../include/stabbing.h" // GVA_Stabbing_*, gva_stabbing_* #include "../include/std_alloc.h" // gva_std_allocator #include "../include/types.h" // GVA_NULL, GVA_String, gva_uint #include "../include/utils.h" // gva_fasta_sequence @@ -299,18 +299,18 @@ compare(int argc, char* argv[static argc + 1]) // NC_000001.11:169556314:6:TTTTTCTCT 3 NC_000001.11:169556314:8:TTTTTGTCTGGCTGC 7 4 is_contained // NC_000001.10:g.103496806_103496807delAA NC_000001.10:103496805:13:AAAAAAAAAAA NC_000001.10:g.103496811A>C NC_000001.10:103496805:13:AAAAACAAAAAAA overlap - char lhs_hgvs[4096]; - char lhs_spdi[4096]; - //size_t lhs_dist; - char rhs_hgvs[4096]; - char rhs_spdi[4096]; - //size_t rhs_dist; - //size_t dist; - //char python[32]; - char relation[32]; + char lhs_hgvs[4096] = {0}; + char lhs_spdi[4096] = {0}; + //size_t lhs_dist = 0; + char rhs_hgvs[4096] = {0}; + char rhs_spdi[4096] = {0}; + //size_t rhs_dist = 0; + //size_t dist = 0; + //char python[32] = {0}; + char relation[32] = {0}; size_t count = 0; //while (fscanf(stdin, "%4096s %zu %4096s %zu %zu %32s\n", lhs_spdi, &lhs_dist, rhs_spdi, &rhs_dist, &dist, python) == 6) - while (fscanf(stdin, "%4096s %4096s %4096s %4096s %32s\n", lhs_hgvs, lhs_spdi, rhs_hgvs, rhs_spdi, relation) == 5) + while (fscanf(stdin, "%4095s %4095s %4095s %4095s %31s\n", lhs_hgvs, lhs_spdi, rhs_hgvs, rhs_spdi, relation) == 5) { GVA_Variant lhs; if (!gva_parse_spdi(strlen(lhs_spdi), lhs_spdi, &lhs)) @@ -355,17 +355,17 @@ all_graphs(void) } // if //bool check = false; - size_t rsid; - char spdi[4096]; - char hgvs[4096]; - char python_sup[4096]; - //char c_sup[4096]; - size_t python_distance; - size_t python_nodes; - size_t python_edges; + size_t rsid = 0; + char spdi[4096] = {0}; + char hgvs[4096] = {0}; + char python_sup[4096] = {0}; + //char c_sup[4096] = {0}; + size_t python_distance = 0; + size_t python_nodes = 0; + size_t python_edges = 0; size_t count = 0; size_t counter = 0; - while (fscanf(stdin, "%zu %4096s %4096s %4096s %zu %zu %zu\n", &rsid, spdi, hgvs, python_sup, &python_distance, &python_nodes, &python_edges) == 7) + while (fscanf(stdin, "%zu %4095s %4095s %4095s %zu %zu %zu\n", &rsid, spdi, hgvs, python_sup, &python_distance, &python_nodes, &python_edges) == 7) { GVA_Variant variant; if (!gva_parse_spdi(strlen(spdi), spdi, &variant)) @@ -461,157 +461,81 @@ extract(int const argc, char* argv[static argc + 1]) } // extract -/* -int -faststabber(int argc, char* argv[static argc + 1]) +static void +index_dot(FILE* const stream, GVA_Stabbing_Index const index) { - //check(stdin, 38); - //return -1; - - uint32_t n = 0; - uint32_t q = 0; - uint32_t r = 0; - char *dot_path = NULL, *vcf_path = NULL, *bed_path = NULL; - int opt = -1; - while ((opt = getopt(argc, argv, "b:hd:n:q:r:v:")) != -1) + fprintf(stream, "strict digraph{\nrankdir=BT\n%u[label=\"\"]\n", GVA_NULL); + for (gva_uint i = 0; i < array_length(index.entries); ++i) { - switch (opt) + fprintf(stream, "%u[label=\"[%u, %u]\"]\n", i, index.entries[i].start, index.entries[i].end); + if (index.entries[i].leftsibling != GVA_NULL) { - case 'b': - bed_path = malloc(strlen(optarg) +1); - assert(NULL != bed_path); - strcpy(bed_path, optarg); - break; - case 'd': - dot_path = malloc(strlen(optarg) + 1); - assert(dot_path != NULL); - strcpy(dot_path, optarg); - break; - case 'n': - n = atoi(optarg); - break; - case 'q': - q = atoi(optarg); - break; - case 'r': - r = atoi(optarg); - break; - case 'v': - vcf_path = malloc(strlen(optarg) + 1); - assert(vcf_path != NULL); - strcpy(vcf_path, optarg); - break; - case 'h': - default: - fprintf(stderr, "Usage: %s [-h] [-d path] -b bed_file -n size [ -q left [-r right] | -v vcf_file ] \n", argv[0]); - return EXIT_FAILURE; - } // switch - } // while - - if ((bed_path && !strncmp("-", bed_path, 1)) && (vcf_path && !strncmp("-", vcf_path, 1))) { - fprintf(stderr, "Can't read both VCF and BED from STDIN\n"); - free(bed_path); - return EXIT_FAILURE; - } + fprintf(stream, "%u->%u[dir=None,style=\"dashed\"]\n", i, index.entries[i].leftsibling); + } // if + if (index.entries[i].rightchild != GVA_NULL) + { + fprintf(stream, "%u->%u\n", i, index.entries[i].rightchild); + } // if + fprintf(stream, "%u->%u\n", i, index.entries[i].parent); + } // for + fprintf(stream, "}\n"); +} // index_dot - if (!bed_path) { - fprintf(stderr, "BED file not specified!\n"); - return EXIT_FAILURE; - } - if (vcf_path && q) { - fprintf(stderr, "Either specify a 'VCF file' or a query range, not both!\n"); - return EXIT_FAILURE; - } - if (0 == n) +int +faststabber(int const argc, char* argv[static argc + 1]) +{ + if (argc < 2) { - fprintf(stderr, "Specify size with -n\n"); + fprintf(stderr, "usage: %s path_to_variant_tsv\n", argv[0]); return EXIT_FAILURE; } // if - if (!vcf_path && q >= n) + errno = 0; + FILE* stream = fopen(argv[1], "r"); + if (stream == NULL) { - fprintf(stderr, "Invalid parameter combination (n > q): n=%" PRIu32 ", q=%" PRIu32 "\n", n, q); + fprintf(stderr, "error: %s\n", strerror(errno)); return EXIT_FAILURE; } // if - if (r < q) - { - r = q; - } // if - - // allocate start node lookup table - Node** start_table = malloc(n * sizeof(*start_table)); - assert(start_table != NULL); - - Node* tree = NULL; - FILE *restrict fp = NULL; - if (1 == strlen(bed_path) && !strncmp("-", bed_path, 1)) { - fp = stdin; - } else { - fp = fopen(bed_path, "r"); - } - free(bed_path); - assert(fp != NULL); - - //TIC(construct); - read_bed(fp, n, &tree, start_table); - //TOC(construct); - - fclose(fp); + GVA_Stabbing_Entry* entries = NULL; - if (dot_path != NULL) + char reference[128] = {0}; + gva_uint start = 0; + gva_uint end = 0;; + char inserted[4096] = {0}; + while (fscanf(stream, "%127s %u %u %4095s\n", reference, &start, &end, inserted) == 4) { - FILE* const restrict fp_dot = fopen(dot_path, "w"); - assert(fp_dot != NULL); + ARRAY_APPEND(gva_std_allocator, entries, ((GVA_Stabbing_Entry) {GVA_NULL, GVA_NULL, GVA_NULL, start, end})); + } // while + fclose(stream); - write_dot(fp_dot, tree); + fprintf(stderr, "%zu\n", array_length(entries)); + GVA_Stabbing_Index index = gva_stabbing_index_init(gva_std_allocator, 30, entries); - fclose(fp_dot); - free(dot_path); - } // if + index_dot(stderr, index); - if (q) + gva_uint* result = gva_stabbing_index_stab(gva_std_allocator, index, 13, 13); + for (size_t i = 0; i < array_length(result); ++i) { - Stack *output = NULL; - stab(start_table[r], q, r, &output); - - printf("q: %" PRIu32 "--%" PRIu32 "\n", q, r); - while (output != NULL) { - printf("%" PRIu32 "--%" PRIu32 "\n", stack_top(output)->start, stack_top(output)->end); - output = stack_pop(output); - } // while + fprintf(stderr, "%2zu: (%2u) [%2u, %2u]\n", i, result[i], index.entries[result[i]].start, index.entries[result[i]].end); + } // for + result = ARRAY_DESTROY(gva_std_allocator, result); - } // if - //else if (vcf_path != NULL) - //{ - // - // FILE* restrict fp_vcf = NULL; - // if (1 == strlen(vcf_path) && !strncmp("-", vcf_path, 1)) { - // fp_vcf = stdin; - // } else { - // fp_vcf = fopen(vcf_path, "r"); - // } - // free(vcf_path); - // assert(fp_vcf != NULL); - // query_bed(fp_vcf, start_table); - //} // if - - destroy(tree); - - free(start_table); + gva_stabbing_index_destroy(gva_std_allocator, index); return EXIT_SUCCESS; } // faststabber -*/ int main(int argc, char* argv[static argc + 1]) { (void) argv; + // check python relation output - return compare(argc, argv); + //return compare(argc, argv); // calculate graphs for all inputs //return all_graphs(); @@ -620,5 +544,5 @@ main(int argc, char* argv[static argc + 1]) //return extract(argc, argv); // faststabber - //return faststabber(argc, argv); + return faststabber(argc, argv); } // main diff --git a/src/stabbing.c b/src/stabbing.c new file mode 100644 index 0000000..ff5b8ad --- /dev/null +++ b/src/stabbing.c @@ -0,0 +1,153 @@ +#include // bool, false, true +#include // NULL, size_t + + +#include // DEBUG + + +#include "../include/allocator.h" // GVA_Allocator +#include "../include/stabbing.h" // GVA_Stabbing_Entry, GVA_Stabbing_Index, gva_stabbing_index_* +#include "array.h" // ARRAY_*, array_length +#include "common.h" // GVA_NULL, gva_uint, MAX + + +GVA_Stabbing_Index +gva_stabbing_index_init(GVA_Allocator const allocator, size_t const len_ref, GVA_Stabbing_Entry* const entries) +{ + GVA_Stabbing_Index index = {entries, NULL, len_ref}; + + index.start_table = allocator.allocate(allocator.context, NULL, 0, index.len_ref * sizeof(*index.start_table)); + gva_uint* stack = allocator.allocate(allocator.context, NULL, 0, index.len_ref * sizeof(*stack)); + if (index.start_table == NULL || stack == NULL) + { + stack = allocator.allocate(allocator.context, NULL, index.len_ref * sizeof(*stack), 0); + index.entries = ARRAY_DESTROY(allocator, index.entries); + index.start_table = allocator.allocate(allocator.context, index.start_table, index.len_ref * sizeof(*index.start_table), 0); + index.len_ref = 0; + return index; + } // if + + gva_uint prev = GVA_NULL; + gva_uint idx = 0; + gva_uint top = GVA_NULL; + for (gva_uint i = 0; i < index.len_ref; ++i) + { + index.start_table[i] = GVA_NULL; + fprintf(stderr, "index iteration: %u\n", i); + + while (top != GVA_NULL && entries[stack[top]].end < i) + { + fprintf(stderr, "Popping %u [%u--%u] from stack\n", top, entries[stack[top]].start, entries[stack[top]].end); + top -= 1; + } // while + + while (idx < array_length(entries) && + i >= entries[idx].start && i <= entries[idx].end && + !(top != GVA_NULL && entries[idx].start == entries[stack[top]].start && entries[idx].end == entries[stack[top]].end)) + { + do + { + fprintf(stderr, "Pushing %u [%u--%u] on stack\n", idx, entries[idx].start, entries[idx].end); + top += 1; + stack[top] = idx; + + entries[idx].parent = prev; + while (entries[idx].parent != GVA_NULL && entries[entries[idx].parent].end < entries[idx].end) + { + entries[idx].parent = entries[entries[idx].parent].parent; + } // while + + if (entries[idx].parent != GVA_NULL) + { + entries[idx].leftsibling = entries[entries[idx].parent].rightchild; + entries[entries[idx].parent].rightchild = idx; + } // if + else if (idx != stack[0]) + { + entries[idx].leftsibling = stack[0]; + } // else + prev = idx; + + idx += 1; + } while (idx < array_length(entries) && + entries[idx].start == entries[stack[top]].start && entries[idx].end == entries[stack[top]].end); + } // while + + if (top != GVA_NULL) + { + fprintf(stderr, "start_table[%u] := %d\n", i, top); + index.start_table[i] = stack[top]; + } // if + } // for + stack = allocator.allocate(allocator.context, stack, index.len_ref * sizeof(*stack), 0); + + return index; +} // gva_stabbing_index_init + + +void +gva_stabbing_index_destroy(GVA_Allocator const allocator, GVA_Stabbing_Index index) +{ + index.entries = ARRAY_DESTROY(allocator, index.entries); + index.start_table = allocator.allocate(allocator.context, index.start_table, index.len_ref * sizeof(*index.start_table), 0); + index.len_ref = 0; +} // gva_stabbing_index_destroy + + +gva_uint* +gva_stabbing_index_stab(GVA_Allocator const allocator, GVA_Stabbing_Index const index, + gva_uint const start, gva_uint const end) +{ + gva_uint* results = NULL; + gva_uint stab = index.start_table[end]; + while (stab != GVA_NULL) + { + if (start >= index.entries[stab].start) + { + fprintf(stderr, "stab: %u: [%u, %u]\n", stab, index.entries[stab].start, index.entries[stab].end); + ARRAY_APPEND(allocator, results, stab); + } // if + + bool rightdone = false; + gva_uint trav = index.entries[stab].leftsibling; + while (trav != GVA_NULL && end <= index.entries[trav].end) + { + if (!rightdone) + { + while (index.entries[trav].rightchild != GVA_NULL && + start >= index.entries[index.entries[trav].rightchild].start && end <= index.entries[index.entries[trav].rightchild].end) + { + fprintf(stderr, "trav: %u: [%u, %u]\n", trav, index.entries[trav].start, index.entries[trav].end); + ARRAY_APPEND(allocator, results, trav); + + trav = index.entries[trav].rightchild; + } // while + + fprintf(stderr, "trav: %u: [%u, %u]\n", trav, index.entries[trav].start, index.entries[trav].end); + ARRAY_APPEND(allocator, results, trav); + } // if + rightdone = true; + + if (index.entries[trav].leftsibling != GVA_NULL && end <= index.entries[index.entries[trav].leftsibling].end) + { + trav = index.entries[trav].leftsibling; + rightdone = false; + } // if + else + { + while (index.entries[trav].parent != GVA_NULL && trav == index.entries[index.entries[trav].parent].rightchild) + { + trav = index.entries[trav].parent; + } // while + if (trav == index.entries[stab].leftsibling) + { + break; + } // if + trav = index.entries[trav].parent; + } // else + } // while + stab = index.entries[stab].parent; + } // while + + return results; +} // gva_stabbing_index_stab From 8c4364d26063ccc6ac83592a2952be1696ee558b Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 17 Jul 2025 17:41:30 +0200 Subject: [PATCH 284/704] Stack-based stabbing --- src/main.c | 27 ++++++++++++++++++---- src/stabbing.c | 61 ++++++++++++++++++-------------------------------- 2 files changed, 45 insertions(+), 43 deletions(-) diff --git a/src/main.c b/src/main.c index 01e73b7..985fdd9 100644 --- a/src/main.c +++ b/src/main.c @@ -468,6 +468,7 @@ index_dot(FILE* const stream, GVA_Stabbing_Index const index) for (gva_uint i = 0; i < array_length(index.entries); ++i) { fprintf(stream, "%u[label=\"[%u, %u]\"]\n", i, index.entries[i].start, index.entries[i].end); + /* if (index.entries[i].leftsibling != GVA_NULL) { fprintf(stream, "%u->%u[dir=None,style=\"dashed\"]\n", i, index.entries[i].leftsibling); @@ -476,6 +477,7 @@ index_dot(FILE* const stream, GVA_Stabbing_Index const index) { fprintf(stream, "%u->%u\n", i, index.entries[i].rightchild); } // if + */ fprintf(stream, "%u->%u\n", i, index.entries[i].parent); } // for fprintf(stream, "}\n"); @@ -512,17 +514,34 @@ faststabber(int const argc, char* argv[static argc + 1]) fclose(stream); fprintf(stderr, "%zu\n", array_length(entries)); + // 248956422 GVA_Stabbing_Index index = gva_stabbing_index_init(gva_std_allocator, 30, entries); + fprintf(stderr, "init done\n"); + index_dot(stderr, index); - gva_uint* result = gva_stabbing_index_stab(gva_std_allocator, index, 13, 13); - for (size_t i = 0; i < array_length(result); ++i) + gva_uint* results = gva_stabbing_index_stab(gva_std_allocator, index, 10, 13); + for (size_t j = 0; j < array_length(results); ++j) { - fprintf(stderr, "%2zu: (%2u) [%2u, %2u]\n", i, result[i], index.entries[result[i]].start, index.entries[result[i]].end); + printf("%u [%u, %u]\n", results[j], index.entries[results[j]].start, index.entries[results[j]].end); + } // for + results = ARRAY_DESTROY(gva_std_allocator, results); + +/* + size_t count = 0; + for (size_t i = 0; i < array_length(index.entries); ++i) + { + gva_uint* result = gva_stabbing_index_stab(gva_std_allocator, index, index.entries[i].start, index.entries[i].end); + for (size_t j = 0; j < array_length(result); ++j) + { + printf("%2zu [%u, %u] %u [%u, %u]\n", i + 1, index.entries[i].start, index.entries[i].end, result[j] + 1, index.entries[result[j]].start, index.entries[result[j]].end); + } // for + result = ARRAY_DESTROY(gva_std_allocator, result); } // for - result = ARRAY_DESTROY(gva_std_allocator, result); +*/ + //entries = ARRAY_DESTROY(gva_std_allocator, entries); gva_stabbing_index_destroy(gva_std_allocator, index); return EXIT_SUCCESS; diff --git a/src/stabbing.c b/src/stabbing.c index ff5b8ad..02cebbe 100644 --- a/src/stabbing.c +++ b/src/stabbing.c @@ -7,7 +7,7 @@ #include "../include/allocator.h" // GVA_Allocator #include "../include/stabbing.h" // GVA_Stabbing_Entry, GVA_Stabbing_Index, gva_stabbing_index_* -#include "array.h" // ARRAY_*, array_length +#include "array.h" // ARRAY_*, array_* #include "common.h" // GVA_NULL, gva_uint, MAX @@ -33,11 +33,11 @@ gva_stabbing_index_init(GVA_Allocator const allocator, size_t const len_ref, GVA for (gva_uint i = 0; i < index.len_ref; ++i) { index.start_table[i] = GVA_NULL; - fprintf(stderr, "index iteration: %u\n", i); + //fprintf(stderr, "index iteration: %u\n", i); while (top != GVA_NULL && entries[stack[top]].end < i) { - fprintf(stderr, "Popping %u [%u--%u] from stack\n", top, entries[stack[top]].start, entries[stack[top]].end); + //fprintf(stderr, "Popping %u [%u--%u] from stack\n", top, entries[stack[top]].start, entries[stack[top]].end); top -= 1; } // while @@ -47,7 +47,7 @@ gva_stabbing_index_init(GVA_Allocator const allocator, size_t const len_ref, GVA { do { - fprintf(stderr, "Pushing %u [%u--%u] on stack\n", idx, entries[idx].start, entries[idx].end); + //fprintf(stderr, "Pushing %u [%u--%u] on stack\n", idx, entries[idx].start, entries[idx].end); top += 1; stack[top] = idx; @@ -75,7 +75,7 @@ gva_stabbing_index_init(GVA_Allocator const allocator, size_t const len_ref, GVA if (top != GVA_NULL) { - fprintf(stderr, "start_table[%u] := %d\n", i, top); + //fprintf(stderr, "start_table[%u] := %d\n", i, top); index.start_table[i] = stack[top]; } // if } // for @@ -99,55 +99,38 @@ gva_stabbing_index_stab(GVA_Allocator const allocator, GVA_Stabbing_Index const gva_uint const start, gva_uint const end) { gva_uint* results = NULL; + gva_uint* stack = NULL; gva_uint stab = index.start_table[end]; while (stab != GVA_NULL) { - if (start >= index.entries[stab].start) - { - fprintf(stderr, "stab: %u: [%u, %u]\n", stab, index.entries[stab].start, index.entries[stab].end); - ARRAY_APPEND(allocator, results, stab); - } // if + fprintf(stderr, "stab: %u: [%u, %u]\n", stab, index.entries[stab].start, index.entries[stab].end); + ARRAY_APPEND(allocator, results, stab); - bool rightdone = false; - gva_uint trav = index.entries[stab].leftsibling; - while (trav != GVA_NULL && end <= index.entries[trav].end) + if (index.entries[stab].leftsibling != GVA_NULL) { - if (!rightdone) + ARRAY_APPEND(allocator, stack, index.entries[stab].leftsibling); + while (array_length(stack) > 0) { - while (index.entries[trav].rightchild != GVA_NULL && - start >= index.entries[index.entries[trav].rightchild].start && end <= index.entries[index.entries[trav].rightchild].end) - { - fprintf(stderr, "trav: %u: [%u, %u]\n", trav, index.entries[trav].start, index.entries[trav].end); - ARRAY_APPEND(allocator, results, trav); - - trav = index.entries[trav].rightchild; - } // while + array_header(stack)->length -= 1; + gva_uint trav = stack[array_length(stack)]; fprintf(stderr, "trav: %u: [%u, %u]\n", trav, index.entries[trav].start, index.entries[trav].end); ARRAY_APPEND(allocator, results, trav); - } // if - rightdone = true; - if (index.entries[trav].leftsibling != GVA_NULL && end <= index.entries[index.entries[trav].leftsibling].end) - { - trav = index.entries[trav].leftsibling; - rightdone = false; - } // if - else - { - while (index.entries[trav].parent != GVA_NULL && trav == index.entries[index.entries[trav].parent].rightchild) + if (index.entries[trav].leftsibling != GVA_NULL) { - trav = index.entries[trav].parent; - } // while - if (trav == index.entries[stab].leftsibling) + ARRAY_APPEND(allocator, stack, index.entries[trav].leftsibling); + } // if + + if (index.entries[trav].rightchild != GVA_NULL) { - break; + ARRAY_APPEND(allocator, stack, index.entries[trav].rightchild); } // if - trav = index.entries[trav].parent; - } // else - } // while + } // while + } // if stab = index.entries[stab].parent; } // while + stack = ARRAY_DESTROY(allocator, stack); return results; } // gva_stabbing_index_stab From f0f8bf29da9cf5c3f317452cb5c9419cb36738b2 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 17 Jul 2025 20:47:45 +0200 Subject: [PATCH 285/704] Interval intersection? --- src/main.c | 30 +++++++++++++----------------- src/stabbing.c | 10 +++++----- 2 files changed, 18 insertions(+), 22 deletions(-) diff --git a/src/main.c b/src/main.c index 985fdd9..62aea1f 100644 --- a/src/main.c +++ b/src/main.c @@ -514,34 +514,30 @@ faststabber(int const argc, char* argv[static argc + 1]) fclose(stream); fprintf(stderr, "%zu\n", array_length(entries)); - // 248956422 - GVA_Stabbing_Index index = gva_stabbing_index_init(gva_std_allocator, 30, entries); - fprintf(stderr, "init done\n"); + GVA_Stabbing_Index index = gva_stabbing_index_init(gva_std_allocator, 248956422, entries); - index_dot(stderr, index); + fprintf(stderr, "init done\n"); - gva_uint* results = gva_stabbing_index_stab(gva_std_allocator, index, 10, 13); - for (size_t j = 0; j < array_length(results); ++j) - { - printf("%u [%u, %u]\n", results[j], index.entries[results[j]].start, index.entries[results[j]].end); - } // for - results = ARRAY_DESTROY(gva_std_allocator, results); + //index_dot(stderr, index); -/* size_t count = 0; for (size_t i = 0; i < array_length(index.entries); ++i) { - gva_uint* result = gva_stabbing_index_stab(gva_std_allocator, index, index.entries[i].start, index.entries[i].end); - for (size_t j = 0; j < array_length(result); ++j) + gva_uint* results = gva_stabbing_index_stab(gva_std_allocator, index, index.entries[i].start, index.entries[i].end); + //count += array_length(results); + for (size_t j = 0; j < array_length(results); ++j) { - printf("%2zu [%u, %u] %u [%u, %u]\n", i + 1, index.entries[i].start, index.entries[i].end, result[j] + 1, index.entries[result[j]].start, index.entries[result[j]].end); + if (i < results[j]) + { + printf("%2zu [%u, %u] %u [%u, %u]\n", i + 1, index.entries[i].start, index.entries[i].end, results[j] + 1, index.entries[results[j]].start, index.entries[results[j]].end); + count += 1; + } // if } // for - result = ARRAY_DESTROY(gva_std_allocator, result); + results = ARRAY_DESTROY(gva_std_allocator, results); } // for -*/ + fprintf(stderr, "total: %zu\n", count); - //entries = ARRAY_DESTROY(gva_std_allocator, entries); gva_stabbing_index_destroy(gva_std_allocator, index); return EXIT_SUCCESS; diff --git a/src/stabbing.c b/src/stabbing.c index 02cebbe..b0d1438 100644 --- a/src/stabbing.c +++ b/src/stabbing.c @@ -103,10 +103,10 @@ gva_stabbing_index_stab(GVA_Allocator const allocator, GVA_Stabbing_Index const gva_uint stab = index.start_table[end]; while (stab != GVA_NULL) { - fprintf(stderr, "stab: %u: [%u, %u]\n", stab, index.entries[stab].start, index.entries[stab].end); + //fprintf(stderr, "stab: %2u: [%2u, %2u]\n", stab, index.entries[stab].start, index.entries[stab].end); ARRAY_APPEND(allocator, results, stab); - if (index.entries[stab].leftsibling != GVA_NULL) + if (index.entries[stab].leftsibling != GVA_NULL && start <= index.entries[index.entries[stab].leftsibling].end) { ARRAY_APPEND(allocator, stack, index.entries[stab].leftsibling); while (array_length(stack) > 0) @@ -114,15 +114,15 @@ gva_stabbing_index_stab(GVA_Allocator const allocator, GVA_Stabbing_Index const array_header(stack)->length -= 1; gva_uint trav = stack[array_length(stack)]; - fprintf(stderr, "trav: %u: [%u, %u]\n", trav, index.entries[trav].start, index.entries[trav].end); + //fprintf(stderr, "trav: %2u: [%2u, %2u]\n", trav, index.entries[trav].start, index.entries[trav].end); ARRAY_APPEND(allocator, results, trav); - if (index.entries[trav].leftsibling != GVA_NULL) + if (index.entries[trav].leftsibling != GVA_NULL && start <= index.entries[index.entries[trav].leftsibling].end) { ARRAY_APPEND(allocator, stack, index.entries[trav].leftsibling); } // if - if (index.entries[trav].rightchild != GVA_NULL) + if (index.entries[trav].rightchild != GVA_NULL && start <= index.entries[index.entries[trav].rightchild].end) { ARRAY_APPEND(allocator, stack, index.entries[trav].rightchild); } // if From 448d6d5dbf96df47d644f3e674f4de7ef0abafce Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 18 Jul 2025 19:35:35 +0200 Subject: [PATCH 286/704] WIP: intersection not working --- include/stabbing.h | 19 ++++-- src/main.c | 42 ++++++-------- src/stabbing.c | 140 ++++++++++++++++++++++++++++----------------- 3 files changed, 119 insertions(+), 82 deletions(-) diff --git a/include/stabbing.h b/include/stabbing.h index 6286158..0c71bbd 100644 --- a/include/stabbing.h +++ b/include/stabbing.h @@ -22,22 +22,31 @@ typedef struct typedef struct { - GVA_Stabbing_Entry* entries; - gva_uint* start_table; size_t len_ref; + gva_uint* start_table; + GVA_Stabbing_Entry* entries; } GVA_Stabbing_Index; GVA_Stabbing_Index -gva_stabbing_index_init(GVA_Allocator const allocator, size_t const len_ref, GVA_Stabbing_Entry* const entries); +gva_stabbing_index_init(GVA_Allocator const allocator, size_t const len_ref); + + +size_t +gva_stabbing_index_add(GVA_Allocator const allocator, GVA_Stabbing_Index index[static 1], + size_t const start, size_t const end); + + +void +gva_stabbing_index_build(GVA_Allocator const allocator, GVA_Stabbing_Index const index); void -gva_stabbing_index_destroy(GVA_Allocator const allocator, GVA_Stabbing_Index index); +gva_stabbing_index_destroy(GVA_Allocator const allocator, GVA_Stabbing_Index index[static 1]); gva_uint* -gva_stabbing_index_stab(GVA_Allocator const allocator, GVA_Stabbing_Index const index, +gva_stabbing_index_intersect(GVA_Allocator const allocator, GVA_Stabbing_Index const index, gva_uint const start, gva_uint const end); diff --git a/src/main.c b/src/main.c index 62aea1f..4a1d16a 100644 --- a/src/main.c +++ b/src/main.c @@ -464,21 +464,14 @@ extract(int const argc, char* argv[static argc + 1]) static void index_dot(FILE* const stream, GVA_Stabbing_Index const index) { - fprintf(stream, "strict digraph{\nrankdir=BT\n%u[label=\"\"]\n", GVA_NULL); + fprintf(stream, "strict digraph{\nrankdir=BT\n"); for (gva_uint i = 0; i < array_length(index.entries); ++i) { - fprintf(stream, "%u[label=\"[%u, %u]\"]\n", i, index.entries[i].start, index.entries[i].end); - /* - if (index.entries[i].leftsibling != GVA_NULL) + fprintf(stream, "%u[label=\"%u\\n[%u, %u]\"]\n", i, i, index.entries[i].start, index.entries[i].end); + if (index.entries[i].parent != GVA_NULL) { - fprintf(stream, "%u->%u[dir=None,style=\"dashed\"]\n", i, index.entries[i].leftsibling); + fprintf(stream, "%u->%u\n", i, index.entries[i].parent); } // if - if (index.entries[i].rightchild != GVA_NULL) - { - fprintf(stream, "%u->%u\n", i, index.entries[i].rightchild); - } // if - */ - fprintf(stream, "%u->%u\n", i, index.entries[i].parent); } // for fprintf(stream, "}\n"); } // index_dot @@ -501,36 +494,35 @@ faststabber(int const argc, char* argv[static argc + 1]) return EXIT_FAILURE; } // if - GVA_Stabbing_Entry* entries = NULL; + //248956422 + GVA_Stabbing_Index index = gva_stabbing_index_init(gva_std_allocator, 30); char reference[128] = {0}; - gva_uint start = 0; - gva_uint end = 0;; + size_t start = 0; + size_t end = 0;; char inserted[4096] = {0}; - while (fscanf(stream, "%127s %u %u %4095s\n", reference, &start, &end, inserted) == 4) + while (fscanf(stream, "%127s %zu %zu %4095s\n", reference, &start, &end, inserted) == 4) { - ARRAY_APPEND(gva_std_allocator, entries, ((GVA_Stabbing_Entry) {GVA_NULL, GVA_NULL, GVA_NULL, start, end})); + gva_stabbing_index_add(gva_std_allocator, &index, start, end); } // while fclose(stream); - fprintf(stderr, "%zu\n", array_length(entries)); - - GVA_Stabbing_Index index = gva_stabbing_index_init(gva_std_allocator, 248956422, entries); + fprintf(stderr, "%zu\n", array_length(index.entries)); - fprintf(stderr, "init done\n"); + gva_stabbing_index_build(gva_std_allocator, index); - //index_dot(stderr, index); + index_dot(stderr, index); size_t count = 0; - for (size_t i = 0; i < array_length(index.entries); ++i) + for (size_t i = 1; i < 2; ++i) { - gva_uint* results = gva_stabbing_index_stab(gva_std_allocator, index, index.entries[i].start, index.entries[i].end); + gva_uint* results = gva_stabbing_index_intersect(gva_std_allocator, index, index.entries[i].start, index.entries[i].end); //count += array_length(results); for (size_t j = 0; j < array_length(results); ++j) { if (i < results[j]) { - printf("%2zu [%u, %u] %u [%u, %u]\n", i + 1, index.entries[i].start, index.entries[i].end, results[j] + 1, index.entries[results[j]].start, index.entries[results[j]].end); + printf("%2zu [%u, %u] %2u [%u, %u]\n", i, index.entries[i].start, index.entries[i].end, results[j], index.entries[results[j]].start, index.entries[results[j]].end); count += 1; } // if } // for @@ -538,7 +530,7 @@ faststabber(int const argc, char* argv[static argc + 1]) } // for fprintf(stderr, "total: %zu\n", count); - gva_stabbing_index_destroy(gva_std_allocator, index); + gva_stabbing_index_destroy(gva_std_allocator, &index); return EXIT_SUCCESS; } // faststabber diff --git a/src/stabbing.c b/src/stabbing.c index b0d1438..6474957 100644 --- a/src/stabbing.c +++ b/src/stabbing.c @@ -1,5 +1,6 @@ #include // bool, false, true #include // NULL, size_t +#include // memset #include // DEBUG @@ -12,98 +13,108 @@ GVA_Stabbing_Index -gva_stabbing_index_init(GVA_Allocator const allocator, size_t const len_ref, GVA_Stabbing_Entry* const entries) +gva_stabbing_index_init(GVA_Allocator const allocator, size_t const len_ref) { - GVA_Stabbing_Index index = {entries, NULL, len_ref}; + gva_uint* start_table = allocator.allocate(allocator.context, NULL, 0, len_ref * sizeof(*start_table)); // OVERFLOW + if (start_table == NULL) + { + return (GVA_Stabbing_Index) {0, NULL, NULL}; + } // if + + memset(start_table, 0, len_ref * sizeof(*start_table)); + GVA_Stabbing_Entry* entries = NULL; + ARRAY_APPEND(allocator, entries, ((GVA_Stabbing_Entry) {GVA_NULL, GVA_NULL, GVA_NULL, 0, len_ref})); + + return (GVA_Stabbing_Index) {len_ref, start_table, entries}; +} // gva_stabbing_index_init + + +inline size_t +gva_stabbing_index_add(GVA_Allocator const allocator, GVA_Stabbing_Index index[static 1], + size_t const start, size_t const end) +{ + return ARRAY_APPEND(allocator, index->entries, ((GVA_Stabbing_Entry) {GVA_NULL, GVA_NULL, GVA_NULL, start, end})); +} // gva_stabbing_index_add + + +void +gva_stabbing_index_build(GVA_Allocator const allocator, GVA_Stabbing_Index const index) +{ + gva_uint const len = array_length(index.entries); + if (len <= 1) + { + return; + } // if - index.start_table = allocator.allocate(allocator.context, NULL, 0, index.len_ref * sizeof(*index.start_table)); gva_uint* stack = allocator.allocate(allocator.context, NULL, 0, index.len_ref * sizeof(*stack)); - if (index.start_table == NULL || stack == NULL) + if (stack == NULL) { - stack = allocator.allocate(allocator.context, NULL, index.len_ref * sizeof(*stack), 0); - index.entries = ARRAY_DESTROY(allocator, index.entries); - index.start_table = allocator.allocate(allocator.context, index.start_table, index.len_ref * sizeof(*index.start_table), 0); - index.len_ref = 0; - return index; + return; } // if - gva_uint prev = GVA_NULL; - gva_uint idx = 0; - gva_uint top = GVA_NULL; + gva_uint prev = 0; + gva_uint idx = 1; + gva_uint top = 0; + stack[top] = 0; for (gva_uint i = 0; i < index.len_ref; ++i) { - index.start_table[i] = GVA_NULL; - //fprintf(stderr, "index iteration: %u\n", i); + fprintf(stderr, "index iteration: %u\n", i); - while (top != GVA_NULL && entries[stack[top]].end < i) + while (index.entries[stack[top]].end < i) { - //fprintf(stderr, "Popping %u [%u--%u] from stack\n", top, entries[stack[top]].start, entries[stack[top]].end); + fprintf(stderr, "Popping [%u, %u] from stack\n", index.entries[stack[top]].start, index.entries[stack[top]].end); top -= 1; } // while - while (idx < array_length(entries) && - i >= entries[idx].start && i <= entries[idx].end && - !(top != GVA_NULL && entries[idx].start == entries[stack[top]].start && entries[idx].end == entries[stack[top]].end)) + while (idx < len && i >= index.entries[idx].start && i <= index.entries[idx].end && + !(index.entries[idx].start == index.entries[stack[top]].start && index.entries[idx].end == index.entries[stack[top]].end)) { do { - //fprintf(stderr, "Pushing %u [%u--%u] on stack\n", idx, entries[idx].start, entries[idx].end); + fprintf(stderr, "Pushing [%u, %u] on stack\n", index.entries[idx].start, index.entries[idx].end); top += 1; stack[top] = idx; - entries[idx].parent = prev; - while (entries[idx].parent != GVA_NULL && entries[entries[idx].parent].end < entries[idx].end) + index.entries[idx].parent = prev; + while (index.entries[idx].parent != GVA_NULL && index.entries[index.entries[idx].parent].end < index.entries[idx].end) { - entries[idx].parent = entries[entries[idx].parent].parent; + index.entries[idx].parent = index.entries[index.entries[idx].parent].parent; } // while - - if (entries[idx].parent != GVA_NULL) - { - entries[idx].leftsibling = entries[entries[idx].parent].rightchild; - entries[entries[idx].parent].rightchild = idx; - } // if - else if (idx != stack[0]) - { - entries[idx].leftsibling = stack[0]; - } // else + index.entries[idx].leftsibling = index.entries[index.entries[idx].parent].rightchild; + index.entries[index.entries[idx].parent].rightchild = idx; prev = idx; idx += 1; - } while (idx < array_length(entries) && - entries[idx].start == entries[stack[top]].start && entries[idx].end == entries[stack[top]].end); - } // while + } while (idx < len && index.entries[idx].start == index.entries[stack[top]].start && index.entries[idx].end == index.entries[stack[top]].end); + } /// while - if (top != GVA_NULL) - { - //fprintf(stderr, "start_table[%u] := %d\n", i, top); - index.start_table[i] = stack[top]; - } // if + fprintf(stderr, "start_table[%u] := [%u, %u]\n", i, index.entries[stack[top]].start, index.entries[stack[top]].end); + index.start_table[i] = stack[top]; } // for - stack = allocator.allocate(allocator.context, stack, index.len_ref * sizeof(*stack), 0); - return index; + stack = allocator.allocate(allocator.context, stack, index.len_ref * sizeof(*stack), 0); } // gva_stabbing_index_init void -gva_stabbing_index_destroy(GVA_Allocator const allocator, GVA_Stabbing_Index index) +gva_stabbing_index_destroy(GVA_Allocator const allocator, GVA_Stabbing_Index index[static 1]) { - index.entries = ARRAY_DESTROY(allocator, index.entries); - index.start_table = allocator.allocate(allocator.context, index.start_table, index.len_ref * sizeof(*index.start_table), 0); - index.len_ref = 0; + index->entries = ARRAY_DESTROY(allocator, index->entries); + index->start_table = allocator.allocate(allocator.context, index->start_table, index->len_ref * sizeof(*index->start_table), 0); + index->len_ref = 0; } // gva_stabbing_index_destroy gva_uint* -gva_stabbing_index_stab(GVA_Allocator const allocator, GVA_Stabbing_Index const index, +gva_stabbing_index_intersect(GVA_Allocator const allocator, GVA_Stabbing_Index const index, gva_uint const start, gva_uint const end) { gva_uint* results = NULL; gva_uint* stack = NULL; gva_uint stab = index.start_table[end]; - while (stab != GVA_NULL) + while (stab != GVA_NULL && index.entries[stab].parent != GVA_NULL) { - //fprintf(stderr, "stab: %2u: [%2u, %2u]\n", stab, index.entries[stab].start, index.entries[stab].end); + fprintf(stderr, "stab: %2u: [%2u, %2u]\n", stab, index.entries[stab].start, index.entries[stab].end); ARRAY_APPEND(allocator, results, stab); if (index.entries[stab].leftsibling != GVA_NULL && start <= index.entries[index.entries[stab].leftsibling].end) @@ -114,7 +125,7 @@ gva_stabbing_index_stab(GVA_Allocator const allocator, GVA_Stabbing_Index const array_header(stack)->length -= 1; gva_uint trav = stack[array_length(stack)]; - //fprintf(stderr, "trav: %2u: [%2u, %2u]\n", trav, index.entries[trav].start, index.entries[trav].end); + fprintf(stderr, "trav: %2u: [%2u, %2u]\n", trav, index.entries[trav].start, index.entries[trav].end); ARRAY_APPEND(allocator, results, trav); if (index.entries[trav].leftsibling != GVA_NULL && start <= index.entries[index.entries[trav].leftsibling].end) @@ -130,7 +141,32 @@ gva_stabbing_index_stab(GVA_Allocator const allocator, GVA_Stabbing_Index const } // if stab = index.entries[stab].parent; } // while + + if (index.entries[stab].rightchild != GVA_NULL && start <= index.entries[index.entries[stab].rightchild].end) + { + ARRAY_APPEND(allocator, stack, index.entries[stab].rightchild); + while (array_length(stack) > 0) + { + array_header(stack)->length -= 1; + gva_uint trav = stack[array_length(stack)]; + + fprintf(stderr, "Rtrav: %2u: [%2u, %2u]\n", trav, index.entries[trav].start, index.entries[trav].end); + ARRAY_APPEND(allocator, results, trav); + + if (index.entries[trav].leftsibling != GVA_NULL && start <= index.entries[index.entries[trav].leftsibling].end) + { + ARRAY_APPEND(allocator, stack, index.entries[trav].leftsibling); + } // if + + if (index.entries[trav].rightchild != GVA_NULL && start <= index.entries[index.entries[trav].rightchild].end) + { + ARRAY_APPEND(allocator, stack, index.entries[trav].rightchild); + } // if + } // while + } // if + + stack = ARRAY_DESTROY(allocator, stack); return results; -} // gva_stabbing_index_stab +} // gva_stabbing_index_intersect From 42a9b8d04782284e9344df79d9a97605ba77744f Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 18 Jul 2025 22:34:43 +0200 Subject: [PATCH 287/704] WIP: correct interval intersections for fs paper --- src/main.c | 26 +++++++++++++++++- src/stabbing.c | 71 ++++++++++++++++++++++++++------------------------ 2 files changed, 62 insertions(+), 35 deletions(-) diff --git a/src/main.c b/src/main.c index 4a1d16a..af0faef 100644 --- a/src/main.c +++ b/src/main.c @@ -477,6 +477,14 @@ index_dot(FILE* const stream, GVA_Stabbing_Index const index) } // index_dot +static inline bool +intersect(size_t const lhs_start, size_t const lhs_end, + size_t const rhs_start, size_t const rhs_end) +{ + return rhs_end >= lhs_start && rhs_start <= lhs_end; +} // intersect + + int faststabber(int const argc, char* argv[static argc + 1]) { @@ -512,9 +520,11 @@ faststabber(int const argc, char* argv[static argc + 1]) gva_stabbing_index_build(gva_std_allocator, index); index_dot(stderr, index); + //gva_uint* results = gva_stabbing_index_intersect(gva_std_allocator, index, 2, 10); + //results = ARRAY_DESTROY(gva_std_allocator, results); size_t count = 0; - for (size_t i = 1; i < 2; ++i) + for (size_t i = 1; i < array_length(index.entries); ++i) { gva_uint* results = gva_stabbing_index_intersect(gva_std_allocator, index, index.entries[i].start, index.entries[i].end); //count += array_length(results); @@ -530,6 +540,20 @@ faststabber(int const argc, char* argv[static argc + 1]) } // for fprintf(stderr, "total: %zu\n", count); + count = 0; + for (size_t i = 1; i < array_length(index.entries); ++i) + { + for (size_t j = i + 1; j < array_length(index.entries); ++j) + { + if (intersect(index.entries[i].start, index.entries[i].end, index.entries[j].start, index.entries[j].end)) + { + printf("%2zu [%u, %u] %2zu [%u, %u]\n", i, index.entries[i].start, index.entries[i].end, j, index.entries[j].start, index.entries[j].end); + count += 1; + } // if + } // for + } // for + fprintf(stderr, "total: %zu\n", count); + gva_stabbing_index_destroy(gva_std_allocator, &index); return EXIT_SUCCESS; diff --git a/src/stabbing.c b/src/stabbing.c index 6474957..a12ff30 100644 --- a/src/stabbing.c +++ b/src/stabbing.c @@ -58,11 +58,11 @@ gva_stabbing_index_build(GVA_Allocator const allocator, GVA_Stabbing_Index const stack[top] = 0; for (gva_uint i = 0; i < index.len_ref; ++i) { - fprintf(stderr, "index iteration: %u\n", i); + //fprintf(stderr, "index iteration: %u\n", i); while (index.entries[stack[top]].end < i) { - fprintf(stderr, "Popping [%u, %u] from stack\n", index.entries[stack[top]].start, index.entries[stack[top]].end); + //fprintf(stderr, "Popping [%u, %u] from stack\n", index.entries[stack[top]].start, index.entries[stack[top]].end); top -= 1; } // while @@ -71,7 +71,7 @@ gva_stabbing_index_build(GVA_Allocator const allocator, GVA_Stabbing_Index const { do { - fprintf(stderr, "Pushing [%u, %u] on stack\n", index.entries[idx].start, index.entries[idx].end); + //fprintf(stderr, "Pushing [%u, %u] on stack\n", index.entries[idx].start, index.entries[idx].end); top += 1; stack[top] = idx; @@ -88,7 +88,7 @@ gva_stabbing_index_build(GVA_Allocator const allocator, GVA_Stabbing_Index const } while (idx < len && index.entries[idx].start == index.entries[stack[top]].start && index.entries[idx].end == index.entries[stack[top]].end); } /// while - fprintf(stderr, "start_table[%u] := [%u, %u]\n", i, index.entries[stack[top]].start, index.entries[stack[top]].end); + //fprintf(stderr, "start_table[%u] := [%u, %u]\n", i, index.entries[stack[top]].start, index.entries[stack[top]].end); index.start_table[i] = stack[top]; } // for @@ -112,10 +112,38 @@ gva_stabbing_index_intersect(GVA_Allocator const allocator, GVA_Stabbing_Index c gva_uint* results = NULL; gva_uint* stack = NULL; gva_uint stab = index.start_table[end]; - while (stab != GVA_NULL && index.entries[stab].parent != GVA_NULL) + + //fprintf(stderr, "start_table: %2u\n", index.start_table[end]); + + if (index.entries[stab].rightchild != GVA_NULL && start <= index.entries[index.entries[stab].rightchild].end && end >= index.entries[index.entries[stab].rightchild].start) { - fprintf(stderr, "stab: %2u: [%2u, %2u]\n", stab, index.entries[stab].start, index.entries[stab].end); - ARRAY_APPEND(allocator, results, stab); + ARRAY_APPEND(allocator, stack, index.entries[stab].rightchild); + while (array_length(stack) > 0) + { + array_header(stack)->length -= 1; + gva_uint trav = stack[array_length(stack)]; + //fprintf(stderr, "Rtrav: %2u: [%2u, %2u]\n", trav, index.entries[trav].start, index.entries[trav].end); + ARRAY_APPEND(allocator, results, trav); + + if (index.entries[trav].leftsibling != GVA_NULL && start <= index.entries[index.entries[trav].leftsibling].end) + { + ARRAY_APPEND(allocator, stack, index.entries[trav].leftsibling); + } // if + + if (index.entries[trav].rightchild != GVA_NULL && start <= index.entries[index.entries[trav].rightchild].end) + { + ARRAY_APPEND(allocator, stack, index.entries[trav].rightchild); + } // if + } // while + } // if + + while (stab != GVA_NULL) + { + if (stab > 0) + { + //fprintf(stderr, "stab: %2u: [%2u, %2u]\n", stab, index.entries[stab].start, index.entries[stab].end); + ARRAY_APPEND(allocator, results, stab); + } // if if (index.entries[stab].leftsibling != GVA_NULL && start <= index.entries[index.entries[stab].leftsibling].end) { @@ -124,8 +152,7 @@ gva_stabbing_index_intersect(GVA_Allocator const allocator, GVA_Stabbing_Index c { array_header(stack)->length -= 1; gva_uint trav = stack[array_length(stack)]; - - fprintf(stderr, "trav: %2u: [%2u, %2u]\n", trav, index.entries[trav].start, index.entries[trav].end); + //fprintf(stderr, "trav: %2u: [%2u, %2u]\n", trav, index.entries[trav].start, index.entries[trav].end); ARRAY_APPEND(allocator, results, trav); if (index.entries[trav].leftsibling != GVA_NULL && start <= index.entries[index.entries[trav].leftsibling].end) @@ -139,33 +166,9 @@ gva_stabbing_index_intersect(GVA_Allocator const allocator, GVA_Stabbing_Index c } // if } // while } // if + stab = index.entries[stab].parent; } // while - - if (index.entries[stab].rightchild != GVA_NULL && start <= index.entries[index.entries[stab].rightchild].end) - { - ARRAY_APPEND(allocator, stack, index.entries[stab].rightchild); - while (array_length(stack) > 0) - { - array_header(stack)->length -= 1; - gva_uint trav = stack[array_length(stack)]; - - fprintf(stderr, "Rtrav: %2u: [%2u, %2u]\n", trav, index.entries[trav].start, index.entries[trav].end); - ARRAY_APPEND(allocator, results, trav); - - if (index.entries[trav].leftsibling != GVA_NULL && start <= index.entries[index.entries[trav].leftsibling].end) - { - ARRAY_APPEND(allocator, stack, index.entries[trav].leftsibling); - } // if - - if (index.entries[trav].rightchild != GVA_NULL && start <= index.entries[index.entries[trav].rightchild].end) - { - ARRAY_APPEND(allocator, stack, index.entries[trav].rightchild); - } // if - } // while - } // if - - stack = ARRAY_DESTROY(allocator, stack); return results; From 2d01f7a4c79bfc70cc11cfd652b6e8643d1191ea Mon Sep 17 00:00:00 2001 From: jkvis Date: Sat, 19 Jul 2025 11:50:51 +0200 Subject: [PATCH 288/704] WIP: intersection stabbing against naive --- src/main.c | 23 ++++++++++++++--------- src/stabbing.c | 15 +++++++++------ 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/src/main.c b/src/main.c index af0faef..88a545d 100644 --- a/src/main.c +++ b/src/main.c @@ -503,24 +503,25 @@ faststabber(int const argc, char* argv[static argc + 1]) } // if //248956422 - GVA_Stabbing_Index index = gva_stabbing_index_init(gva_std_allocator, 30); + GVA_Stabbing_Index index = gva_stabbing_index_init(gva_std_allocator, 248956422); - char reference[128] = {0}; + size_t rsid = 0; size_t start = 0; - size_t end = 0;; + size_t end = 0; char inserted[4096] = {0}; - while (fscanf(stream, "%127s %zu %zu %4095s\n", reference, &start, &end, inserted) == 4) + size_t distance = 0; + while (fscanf(stream, "%zu %zu %zu %4095s %zu\n", &rsid, &start, &end, inserted, &distance) == 5) { gva_stabbing_index_add(gva_std_allocator, &index, start, end); } // while fclose(stream); - fprintf(stderr, "%zu\n", array_length(index.entries)); + fprintf(stderr, "%zu\n", array_length(index.entries) - 1); gva_stabbing_index_build(gva_std_allocator, index); - index_dot(stderr, index); - //gva_uint* results = gva_stabbing_index_intersect(gva_std_allocator, index, 2, 10); + //index_dot(stdout, index); + //gva_uint* results = gva_stabbing_index_intersect(gva_std_allocator, index, 15807, 15813); //results = ARRAY_DESTROY(gva_std_allocator, results); size_t count = 0; @@ -532,7 +533,7 @@ faststabber(int const argc, char* argv[static argc + 1]) { if (i < results[j]) { - printf("%2zu [%u, %u] %2u [%u, %u]\n", i, index.entries[i].start, index.entries[i].end, results[j], index.entries[results[j]].start, index.entries[results[j]].end); + //fprintf(stdout, "%2zu [%u, %u] %2u [%u, %u]\n", i, index.entries[i].start, index.entries[i].end, results[j], index.entries[results[j]].start, index.entries[results[j]].end); count += 1; } // if } // for @@ -545,9 +546,13 @@ faststabber(int const argc, char* argv[static argc + 1]) { for (size_t j = i + 1; j < array_length(index.entries); ++j) { + if (index.entries[i].end < index.entries[j].start) + { + break; + } // if if (intersect(index.entries[i].start, index.entries[i].end, index.entries[j].start, index.entries[j].end)) { - printf("%2zu [%u, %u] %2zu [%u, %u]\n", i, index.entries[i].start, index.entries[i].end, j, index.entries[j].start, index.entries[j].end); + //fprintf(stdout, "%2zu [%u, %u] %2zu [%u, %u]\n", i, index.entries[i].start, index.entries[i].end, j, index.entries[j].start, index.entries[j].end); count += 1; } // if } // for diff --git a/src/stabbing.c b/src/stabbing.c index a12ff30..bdd1bcc 100644 --- a/src/stabbing.c +++ b/src/stabbing.c @@ -115,22 +115,25 @@ gva_stabbing_index_intersect(GVA_Allocator const allocator, GVA_Stabbing_Index c //fprintf(stderr, "start_table: %2u\n", index.start_table[end]); - if (index.entries[stab].rightchild != GVA_NULL && start <= index.entries[index.entries[stab].rightchild].end && end >= index.entries[index.entries[stab].rightchild].start) + if (index.entries[stab].rightchild != GVA_NULL) { ARRAY_APPEND(allocator, stack, index.entries[stab].rightchild); while (array_length(stack) > 0) { array_header(stack)->length -= 1; gva_uint trav = stack[array_length(stack)]; - //fprintf(stderr, "Rtrav: %2u: [%2u, %2u]\n", trav, index.entries[trav].start, index.entries[trav].end); - ARRAY_APPEND(allocator, results, trav); + if (end >= index.entries[trav].start) + { + //fprintf(stderr, "Rtrav: %2u: [%2u, %2u]\n", trav, index.entries[trav].start, index.entries[trav].end); + ARRAY_APPEND(allocator, results, trav); + } // if - if (index.entries[trav].leftsibling != GVA_NULL && start <= index.entries[index.entries[trav].leftsibling].end) + if (index.entries[trav].leftsibling != GVA_NULL) { ARRAY_APPEND(allocator, stack, index.entries[trav].leftsibling); } // if - if (index.entries[trav].rightchild != GVA_NULL && start <= index.entries[index.entries[trav].rightchild].end) + if (index.entries[trav].rightchild != GVA_NULL && end >= index.entries[index.entries[trav].rightchild].start) { ARRAY_APPEND(allocator, stack, index.entries[trav].rightchild); } // if @@ -160,7 +163,7 @@ gva_stabbing_index_intersect(GVA_Allocator const allocator, GVA_Stabbing_Index c ARRAY_APPEND(allocator, stack, index.entries[trav].leftsibling); } // if - if (index.entries[trav].rightchild != GVA_NULL && start <= index.entries[index.entries[trav].rightchild].end) + if (index.entries[trav].rightchild != GVA_NULL) { ARRAY_APPEND(allocator, stack, index.entries[trav].rightchild); } // if From 25093163b181d3cfc859456858ab5fa1ca7735ef Mon Sep 17 00:00:00 2001 From: jkvis Date: Sat, 19 Jul 2025 15:18:51 +0200 Subject: [PATCH 289/704] WIP: faster parsing; do not use self_intersection --- include/stabbing.h | 4 +++ src/main.c | 57 +++++++++++++++++++++++++++-------- src/stabbing.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 123 insertions(+), 12 deletions(-) diff --git a/include/stabbing.h b/include/stabbing.h index 0c71bbd..45db9a3 100644 --- a/include/stabbing.h +++ b/include/stabbing.h @@ -45,6 +45,10 @@ void gva_stabbing_index_destroy(GVA_Allocator const allocator, GVA_Stabbing_Index index[static 1]); +gva_uint* +gva_stabbing_index_self_intersect(GVA_Allocator const allocator, GVA_Stabbing_Index const index); + + gva_uint* gva_stabbing_index_intersect(GVA_Allocator const allocator, GVA_Stabbing_Index const index, gva_uint const start, gva_uint const end); diff --git a/src/main.c b/src/main.c index 88a545d..2f483d4 100644 --- a/src/main.c +++ b/src/main.c @@ -485,6 +485,19 @@ intersect(size_t const lhs_start, size_t const lhs_end, } // intersect +static inline size_t +parse_number(char const buffer[static 1], size_t idx[static 1]) +{ + size_t number = 0; + while (buffer[*idx] >= '0' && buffer[*idx] <= '9') + { + number = number * 10 + buffer[*idx] - '0'; + *idx += 1; + } // while + return number; +} // parse_number + + int faststabber(int const argc, char* argv[static argc + 1]) { @@ -505,25 +518,45 @@ faststabber(int const argc, char* argv[static argc + 1]) //248956422 GVA_Stabbing_Index index = gva_stabbing_index_init(gva_std_allocator, 248956422); - size_t rsid = 0; - size_t start = 0; - size_t end = 0; - char inserted[4096] = {0}; - size_t distance = 0; - while (fscanf(stream, "%zu %zu %zu %4095s %zu\n", &rsid, &start, &end, inserted, &distance) == 5) + size_t line_count = 0; + char line[4096] = {0}; + while (fgets(line, sizeof(line), stream) != NULL) { + size_t idx = 0; + + // ignore rsid + parse_number(line, &idx); + idx += 1; + size_t const start = parse_number(line, &idx); + idx += 1; + size_t const end = parse_number(line, &idx); + // ignore remainder of the line + gva_stabbing_index_add(gva_std_allocator, &index, start, end); + line_count += 1; } // while + + errno = 0; + if (feof(stream) == 0) + { + fprintf(stderr, "error: %s\n", strerror(errno)); + fclose(stream); + gva_stabbing_index_destroy(gva_std_allocator, &index); + return EXIT_FAILURE; + } // if fclose(stream); - fprintf(stderr, "%zu\n", array_length(index.entries) - 1); + fprintf(stderr, "line count: %zu\n", line_count); + fprintf(stderr, "entry count: %zu\n", array_length(index.entries) - 1); - gva_stabbing_index_build(gva_std_allocator, index); + //gva_stabbing_index_build(gva_std_allocator, index); - //index_dot(stdout, index); - //gva_uint* results = gva_stabbing_index_intersect(gva_std_allocator, index, 15807, 15813); + //index_dot(stderr, index); + //gva_uint* results = gva_stabbing_index_self_intersect(gva_std_allocator, index); + //fprintf(stderr, "total: %zu\n", array_length(results)); //results = ARRAY_DESTROY(gva_std_allocator, results); +/* size_t count = 0; for (size_t i = 1; i < array_length(index.entries); ++i) { @@ -540,8 +573,8 @@ faststabber(int const argc, char* argv[static argc + 1]) results = ARRAY_DESTROY(gva_std_allocator, results); } // for fprintf(stderr, "total: %zu\n", count); - - count = 0; +*/ + size_t count = 0; for (size_t i = 1; i < array_length(index.entries); ++i) { for (size_t j = i + 1; j < array_length(index.entries); ++j) diff --git a/src/stabbing.c b/src/stabbing.c index bdd1bcc..a89ac33 100644 --- a/src/stabbing.c +++ b/src/stabbing.c @@ -105,6 +105,80 @@ gva_stabbing_index_destroy(GVA_Allocator const allocator, GVA_Stabbing_Index ind } // gva_stabbing_index_destroy +gva_uint* +gva_stabbing_index_self_intersect(GVA_Allocator const allocator, GVA_Stabbing_Index const index) +{ + gva_uint* results = NULL; + gva_uint* stack = NULL; + + for (gva_uint i = 1; i < array_length(index.entries); ++i) + { + //fprintf(stderr, "%2u: [%u, %u]\n", i, index.entries[i].start, index.entries[i].end); + if (index.entries[i].rightchild != GVA_NULL) + { + ARRAY_APPEND(allocator, stack, index.entries[i].rightchild); + while (array_length(stack) > 0) + { + array_header(stack)->length -= 1; + gva_uint trav = stack[array_length(stack)]; + //fprintf(stderr, " Strav: %2u: [%u, %u]\n", trav, index.entries[trav].start, index.entries[trav].end); + //printf("%2u [%u, %u] %2u [%u, %u]\n", i, index.entries[i].start, index.entries[i].end, trav, index.entries[trav].start, index.entries[trav].end); + ARRAY_APPEND(allocator, results, trav); + + if (index.entries[trav].leftsibling != GVA_NULL) + { + ARRAY_APPEND(allocator, stack, index.entries[trav].leftsibling); + } // if + + if (index.entries[trav].rightchild != GVA_NULL) + { + ARRAY_APPEND(allocator, stack, index.entries[trav].rightchild); + } // if + } // while + } // if + + gva_uint stab = index.entries[i].parent; + while (stab != GVA_NULL) + { + if (index.entries[stab].rightchild != GVA_NULL) + { + ARRAY_APPEND(allocator, stack, index.entries[stab].rightchild); + while (array_length(stack) > 0) + { + array_header(stack)->length -= 1; + gva_uint trav = stack[array_length(stack)]; + + //fprintf(stderr, " VISIT: %2u: [%u, %u]\n", trav, index.entries[trav].start, index.entries[trav].end); + + if (trav > i && index.entries[i].end >= index.entries[trav].start) + { + //fprintf(stderr, " Rtrav: %2u: [%u, %u]\n", trav, index.entries[trav].start, index.entries[trav].end); + //printf("%2u [%u, %u] %2u [%u, %u]\n", i, index.entries[i].start, index.entries[i].end, trav, index.entries[trav].start, index.entries[trav].end); + ARRAY_APPEND(allocator, results, trav); + + if (index.entries[trav].rightchild != GVA_NULL) + { + ARRAY_APPEND(allocator, stack, index.entries[trav].rightchild); + } // if + } // if + + if (index.entries[trav].leftsibling != GVA_NULL && index.entries[trav].leftsibling > i) + { + ARRAY_APPEND(allocator, stack, index.entries[trav].leftsibling); + } // if + } // while + } // if + + stab = index.entries[stab].parent; + } // while + + } // for + stack = ARRAY_DESTROY(allocator, stack); + + return results; +} // gva_stabbing_index_self_intersect + + gva_uint* gva_stabbing_index_intersect(GVA_Allocator const allocator, GVA_Stabbing_Index const index, gva_uint const start, gva_uint const end) From a5ebbb614c609295bd19a5156a70be7ad6ae7879 Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 21 Jul 2025 08:58:04 +0200 Subject: [PATCH 290/704] Plain intervals --- src/main.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 62 insertions(+), 11 deletions(-) diff --git a/src/main.c b/src/main.c index 2f483d4..3f79898 100644 --- a/src/main.c +++ b/src/main.c @@ -498,6 +498,39 @@ parse_number(char const buffer[static 1], size_t idx[static 1]) } // parse_number +typedef struct +{ + gva_uint start; + gva_uint end; +} Interval; + + +static inline int +interval_cmp(void const* lhs, void const* rhs) +{ + Interval const* const lhs_interval = lhs; + Interval const* const rhs_interval = rhs; + + if (lhs_interval->start < rhs_interval->start) + { + return -1; + } // if + if (lhs_interval->start > rhs_interval->start) + { + return 1; + } // if + if (lhs_interval->end > rhs_interval->end) + { + return -1; + } // if + if (lhs_interval->end < rhs_interval->end) + { + return 1; + } // if + return 0; +} // interval cmp + + int faststabber(int const argc, char* argv[static argc + 1]) { @@ -516,10 +549,12 @@ faststabber(int const argc, char* argv[static argc + 1]) } // if //248956422 - GVA_Stabbing_Index index = gva_stabbing_index_init(gva_std_allocator, 248956422); + //GVA_Stabbing_Index index = gva_stabbing_index_init(gva_std_allocator, 248956422); + + Interval* intervals = NULL; size_t line_count = 0; - char line[4096] = {0}; + static char line[4096] = {0}; while (fgets(line, sizeof(line), stream) != NULL) { size_t idx = 0; @@ -532,7 +567,8 @@ faststabber(int const argc, char* argv[static argc + 1]) size_t const end = parse_number(line, &idx); // ignore remainder of the line - gva_stabbing_index_add(gva_std_allocator, &index, start, end); + //gva_stabbing_index_add(gva_std_allocator, &index, start, end); + ARRAY_APPEND(gva_std_allocator, intervals, ((Interval) {start, end})); line_count += 1; } // while @@ -541,13 +577,27 @@ faststabber(int const argc, char* argv[static argc + 1]) { fprintf(stderr, "error: %s\n", strerror(errno)); fclose(stream); - gva_stabbing_index_destroy(gva_std_allocator, &index); + //gva_stabbing_index_destroy(gva_std_allocator, &index); + intervals = ARRAY_DESTROY(gva_std_allocator, intervals); return EXIT_FAILURE; } // if fclose(stream); fprintf(stderr, "line count: %zu\n", line_count); - fprintf(stderr, "entry count: %zu\n", array_length(index.entries) - 1); + if (intervals == NULL) + { + return EXIT_FAILURE; + } // if + + qsort(intervals, array_length(intervals), sizeof(*intervals), interval_cmp); + //fprintf(stderr, "entry count: %zu\n", array_length(index.entries) - 1); + + /* + for (size_t i = 0; i < array_length(intervals); ++i) + { + printf("%u %u\n", intervals[i].start, intervals[i].end); + } // for + */ //gva_stabbing_index_build(gva_std_allocator, index); @@ -555,7 +605,6 @@ faststabber(int const argc, char* argv[static argc + 1]) //gva_uint* results = gva_stabbing_index_self_intersect(gva_std_allocator, index); //fprintf(stderr, "total: %zu\n", array_length(results)); //results = ARRAY_DESTROY(gva_std_allocator, results); - /* size_t count = 0; for (size_t i = 1; i < array_length(index.entries); ++i) @@ -574,16 +623,17 @@ faststabber(int const argc, char* argv[static argc + 1]) } // for fprintf(stderr, "total: %zu\n", count); */ + size_t count = 0; - for (size_t i = 1; i < array_length(index.entries); ++i) + for (size_t i = 0; i < array_length(intervals); ++i) { - for (size_t j = i + 1; j < array_length(index.entries); ++j) + for (size_t j = i + 1; j < array_length(intervals); ++j) { - if (index.entries[i].end < index.entries[j].start) + if (intervals[i].end < intervals[j].start) { break; } // if - if (intersect(index.entries[i].start, index.entries[i].end, index.entries[j].start, index.entries[j].end)) + if (intersect(intervals[i].start, intervals[i].end, intervals[j].start, intervals[j].end)) { //fprintf(stdout, "%2zu [%u, %u] %2zu [%u, %u]\n", i, index.entries[i].start, index.entries[i].end, j, index.entries[j].start, index.entries[j].end); count += 1; @@ -592,7 +642,8 @@ faststabber(int const argc, char* argv[static argc + 1]) } // for fprintf(stderr, "total: %zu\n", count); - gva_stabbing_index_destroy(gva_std_allocator, &index); +// gva_stabbing_index_destroy(gva_std_allocator, &index); + intervals = ARRAY_DESTROY(gva_std_allocator, intervals); return EXIT_SUCCESS; } // faststabber From 975feae8be6956113016e6a90ffc832f97495b69 Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 21 Jul 2025 15:50:30 +0200 Subject: [PATCH 291/704] Pointer-based trie --- src/main.c | 102 ++++++++++++++++++++++++++++++++++++++- src/trie.c | 138 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/trie.h | 33 +++++++++++++ 3 files changed, 271 insertions(+), 2 deletions(-) create mode 100644 src/trie.c create mode 100644 src/trie.h diff --git a/src/main.c b/src/main.c index 3f79898..dc9ad5d 100644 --- a/src/main.c +++ b/src/main.c @@ -21,6 +21,7 @@ #include "../include/variant.h" // GVA_VARIANT_*, GVA_Variant, gva_parse_spdi #include "array.h" // ARRAY_DESTROY, array_length #include "bitset.h" // bitset_* +#include "trie.h" // Trie, trie_* static void @@ -589,7 +590,7 @@ faststabber(int const argc, char* argv[static argc + 1]) return EXIT_FAILURE; } // if - qsort(intervals, array_length(intervals), sizeof(*intervals), interval_cmp); + //qsort(intervals, array_length(intervals), sizeof(*intervals), interval_cmp); //fprintf(stderr, "entry count: %zu\n", array_length(index.entries) - 1); /* @@ -649,6 +650,101 @@ faststabber(int const argc, char* argv[static argc + 1]) } // faststabber +static void +trie_dot_node(FILE* const stream, Trie const* const trie) +{ + if (trie == NULL) + { + return; + } // if + + fprintf(stream, "\"%p\"[label=\"%.*s\"]\n", (void*) trie, (int) trie->len, trie->key); + for (Trie const* child = trie->link; child != NULL; child = child->next) + { + fprintf(stream, "\"%p\"->\"%p\"\n", (void*) trie, (void*) child); + trie_dot_node(stream, child); + } // for +} // trie_dot_node + + +static void +trie_dot(FILE* const stream, Trie const* const trie) +{ + fprintf(stream, "strict digraph{\n"); + trie_dot_node(stream, trie); + fprintf(stream, "}\n"); +} // trie_dot + + +static void +trie_print(FILE* const stream, Trie const* const trie, int const indent) +{ + if (trie == NULL) + { + return; + } // if + + enum + { + INDENT = 4 + }; // constants + + trie_print(stream, trie->next, indent); + fprintf(stream, "%*s%.*s (%p) %zu\n", indent, "", (int) trie->len, trie->key, (void*) trie, trie->len); + trie_print(stream, trie->link, indent + INDENT); +} // trie_print + + +int +trie(int argc, char* argv[static argc + 1]) +{ + if (argc < 2) + { + fprintf(stderr, "usage %s path_to_strings\n", argv[0]); + return EXIT_FAILURE; + } // if + + errno = 0; + FILE* stream = fopen(argv[1], "r"); + if (stream == NULL) + { + fprintf(stderr, "error: %s\n", strerror(errno)); + return EXIT_FAILURE; + } // if + + Trie* trie = NULL; + + size_t count = 0; + static char line[4096] = {0}; + while (fgets(line, sizeof(line), stream) != NULL) + { + trie = trie_insert(trie, strlen(line) - 1, line); + count += 1; + } // while + + errno = 0; + if (feof(stream) == 0) + { + fprintf(stderr, "error: %s\n", strerror(errno)); + fclose(stream); + trie_destroy(trie); + return EXIT_FAILURE; + } // if + fclose(stream); + + fprintf(stderr, "total: %zu\n", count); + + trie_print(stderr, trie, 0); + trie_dot(stderr, trie); + + fprintf(stderr, "%p\n", (void*) trie_find(trie, 4, "ruber")); + + trie_destroy(trie); + + return EXIT_SUCCESS; +} // trie + + int main(int argc, char* argv[static argc + 1]) { @@ -664,5 +760,7 @@ main(int argc, char* argv[static argc + 1]) //return extract(argc, argv); // faststabber - return faststabber(argc, argv); + //return faststabber(argc, argv); + // trie + return trie(argc, argv); } // main diff --git a/src/trie.c b/src/trie.c new file mode 100644 index 0000000..c18777f --- /dev/null +++ b/src/trie.c @@ -0,0 +1,138 @@ +#include // NULL, size_t +#include // free, malloc +#include // strncpy + +#include "trie.h" // Trie, trie_* + + +inline Trie* +trie_init(size_t const len, char const key[static len]) +{ + Trie* const trie = malloc(sizeof(*trie)); + if (trie == NULL) + { + return NULL; + } // if + + trie->key = malloc(len); + if (trie->key == NULL) + { + free(trie); + return NULL; + } // if + + strncpy(trie->key, key, len); + trie->len = len; + + trie->link = NULL; + trie->next = NULL; + + return trie; +} // trie_init + + +void +trie_destroy(Trie* const trie) +{ + if (trie == NULL) + { + return; + } // if + + trie_destroy(trie->link); + trie_destroy(trie->next); + free(trie->key); + free(trie); +} // if + + +static inline size_t +prefix_length(size_t const len_lhs, char const lhs[static len_lhs], + size_t const len_rhs, char const rhs[static len_rhs]) +{ + for (size_t i = 0; i < len_lhs; ++i) + { + if (i >= len_rhs || lhs[i] != rhs[i]) + { + return i; + } // if + } // for + return len_lhs; +} // prefix_length + + +Trie const* +trie_find(Trie* const trie, size_t const len, char const key[static len]) +{ + if (trie == NULL) + { + return NULL; + } // if + + size_t const k = prefix_length(len, key, trie->len, trie->key); + if (k == 0) + { + return trie_find(trie->next, len, key); + } // if + if (k == len) + { + return trie; + } // if + if (k == trie->len) + { + return trie_find(trie->link, len - k, key + k); + } // if + + return NULL; +} // trie_find + + +static inline void +split(Trie* const trie, size_t const k) +{ + Trie* const suffix = trie_init(trie->len - k, trie->key + k); + if (suffix == NULL) + { + return; + } // if + + char* const key = malloc(k); + if (key == NULL) + { + trie_destroy(suffix); + return; + } // if + strncpy(key, trie->key, k); + free(trie->key); + + suffix->link = trie->link; + trie->link = suffix; + + trie->key = key; + trie->len = k; +} // split + + +Trie* +trie_insert(Trie* const trie, size_t const len, char const key[static len]) +{ + if (trie == NULL) + { + return trie_init(len, key); + } // if + + size_t const k = prefix_length(len, key, trie->len, trie->key); + if (k == 0) + { + trie->next = trie_insert(trie->next, len, key); + } // if + else if (k < len) + { + if (k < trie->len) + { + split(trie, k); + } // if + trie->link = trie_insert(trie->link, len - k, key + k); + } // if + return trie; +} // trie_insert diff --git a/src/trie.h b/src/trie.h new file mode 100644 index 0000000..e65cca5 --- /dev/null +++ b/src/trie.h @@ -0,0 +1,33 @@ +#ifndef GVA_TRIE_H +#define GVA_TRIE_H + + +#include // size_t + + +typedef struct Trie +{ + struct Trie* link; + struct Trie* next; + size_t len; + char* key; +} Trie; + + +Trie* +trie_init(size_t const len, char const key[static len]); + + +void +trie_destroy(Trie* const trie); + + +Trie const* +trie_find(Trie* const trie, size_t const len, char const key[static len]); + + +Trie* +trie_insert(Trie* const trie, size_t const len, char const key[static len]); + + +#endif // GVA_TRIE_H From df42e3148d4d1b91938362ff2069f2f24c54b765 Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 21 Jul 2025 17:18:45 +0200 Subject: [PATCH 292/704] Fix trie dot --- src/main.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/main.c b/src/main.c index dc9ad5d..1603134 100644 --- a/src/main.c +++ b/src/main.c @@ -670,8 +670,12 @@ trie_dot_node(FILE* const stream, Trie const* const trie) static void trie_dot(FILE* const stream, Trie const* const trie) { - fprintf(stream, "strict digraph{\n"); - trie_dot_node(stream, trie); + fprintf(stream, "strict digraph{\n\"root\"[label=\"\",shape=point]\n"); + for (Trie const* child = trie; child != NULL; child = child->next) + { + fprintf(stream, "\"root\"->\"%p\"\n", (void*) child); + trie_dot_node(stream, child); + } // for fprintf(stream, "}\n"); } // trie_dot @@ -734,10 +738,8 @@ trie(int argc, char* argv[static argc + 1]) fprintf(stderr, "total: %zu\n", count); - trie_print(stderr, trie, 0); - trie_dot(stderr, trie); - - fprintf(stderr, "%p\n", (void*) trie_find(trie, 4, "ruber")); + //trie_print(stderr, trie, 0); + trie_dot(stdout, trie); trie_destroy(trie); From ff32810742134c3f3c6dd30754080f23be342436 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 22 Jul 2025 09:05:56 +0200 Subject: [PATCH 293/704] Arbitrary growth in array --- src/array.c | 36 +++++++++++++++++++----------------- src/array.h | 8 ++++---- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/src/array.c b/src/array.c index 29f9e82..ffcfdea 100644 --- a/src/array.c +++ b/src/array.c @@ -9,13 +9,23 @@ inline void* array_init(GVA_Allocator const allocator, size_t const capacity, size_t const item_size) { + if (capacity == 0) + { + return NULL; // Empty array + } // if Array* const header = allocator.allocate( allocator.context, NULL, 0, sizeof(*header) + capacity * item_size // OVERFLOW ); - return header == NULL ? NULL : header + 1; + if (header == NULL) + { + return NULL; // OOM + } // if + header->capacity = capacity; + header->length = 0; + return header + 1; } // array_init @@ -34,36 +44,28 @@ array_header(void const* const self) void* -array_ensure_one(GVA_Allocator const allocator, void* const self, - size_t const item_size) +array_ensure(GVA_Allocator const allocator, void* const self, + size_t const item_size, size_t const extra) { // Initial allocation if (self == NULL) { - Array* const restrict header = allocator.allocate( - allocator.context, - NULL, - 0, - sizeof(*header) + item_size // OVERFLOW - ); - if (header == NULL) - { - return NULL; // OOM - } // if - header->capacity = 1; - header->length = 0; - return header + 1; + return array_init(allocator, extra, item_size); } // if // The current capacity is sufficient. Array* const restrict header = array_header(self); - if (header->capacity > header->length) + if (header->capacity - header->length >= extra) { return header + 1; } // if // A simple geometric growth reallocation scheme. size_t new_capacity = header->capacity * 2; // OVERFLOW + while (new_capacity - header->length < extra) + { + new_capacity *= 2; // OVERFLOW + } // while Array* const restrict new_header = allocator.allocate( allocator.context, diff --git a/src/array.h b/src/array.h index 52a1e94..e1b9622 100644 --- a/src/array.h +++ b/src/array.h @@ -42,10 +42,10 @@ array_header(void const* const self); // Internal: Returns the possibly (re)allocated array with place for -// one additional element. +// `extra` additional element(s). void* -array_ensure_one(GVA_Allocator const allocator, void* const self, - size_t const item_size); +array_ensure(GVA_Allocator const allocator, void* const self, + size_t const item_size, size_t const extra); // Destroys an array. Does not destroy the elements of the array. @@ -68,7 +68,7 @@ array_ensure_one(GVA_Allocator const allocator, void* const self, // array. 0 if (re)allocation failed. // Warning: `self` is evaluated multiple times. #define ARRAY_APPEND(allocator, self, value) ( \ - (self) = array_ensure_one(allocator, (self), sizeof(*(self))), \ + (self) = array_ensure(allocator, (self), sizeof(*(self)), 1), \ (self) == NULL ? 0 : ( \ (self)[array_header(self)->length] = (value), \ array_header(self)->length += 1 \ From 07839d38d4732ed495359c95cfa9377f0c6364c4 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 22 Jul 2025 10:41:41 +0200 Subject: [PATCH 294/704] Clean up --- src/align.c | 2 +- src/bitset.c | 19 +++++++++---------- src/bitset.h | 6 ++---- 3 files changed, 12 insertions(+), 15 deletions(-) diff --git a/src/align.c b/src/align.c index 29cf7f1..9c2b1dc 100644 --- a/src/align.c +++ b/src/align.c @@ -26,7 +26,7 @@ static size_t expand(Context const context, intmax_t const idx, size_t const p, - LCS_Alignment* const lcs) + LCS_Alignment lcs[static 1]) { intmax_t const delta = context.len_obs - context.len_ref; size_t const offset = context.len_ref + 1; diff --git a/src/bitset.c b/src/bitset.c index d3e9196..3d75633 100644 --- a/src/bitset.c +++ b/src/bitset.c @@ -3,7 +3,6 @@ #include // NULL, size_t #include // memset - #include "../include/allocator.h" // GVA_Allocator #include "array.h" // ARRAY_*, array_* #include "bitset.h" // bitset_* @@ -13,7 +12,7 @@ inline size_t* bitset_init(GVA_Allocator const allocator, size_t const size) { size_t const len = (size + sizeof(size_t) * CHAR_BIT - 1) / (sizeof(size_t) * CHAR_BIT); - size_t* bitset = array_init(allocator, len, sizeof(*bitset)); + size_t* const bitset = array_init(allocator, len, sizeof(*bitset)); if (bitset == NULL) { return NULL; @@ -24,22 +23,22 @@ bitset_init(GVA_Allocator const allocator, size_t const size) inline void -bitset_add(size_t bitset[static 1], size_t const start, size_t const end) +bitset_add(size_t self[static 1], size_t const start, size_t const end) { - size_t const start_idx = start / (sizeof(*bitset) * CHAR_BIT); - size_t const end_idx = (end - 1) / (sizeof(*bitset) * CHAR_BIT); + size_t const start_idx = start / (sizeof(*self) * CHAR_BIT); + size_t const end_idx = (end - 1) / (sizeof(*self) * CHAR_BIT); for (size_t i = start_idx; i <= end_idx; ++i) { size_t mask = ~0x0ULL; if (i == start_idx) { - mask &= ~0x0ULL << (start % (sizeof(*bitset) * CHAR_BIT)); + mask &= ~0x0ULL << (start % (sizeof(*self) * CHAR_BIT)); } // if if (i == end_idx) { - mask &= ~0x0ULL >> (sizeof(*bitset) * CHAR_BIT - (end % (sizeof(*bitset) * CHAR_BIT))); + mask &= ~0x0ULL >> (sizeof(*self) * CHAR_BIT - (end % (sizeof(*self) * CHAR_BIT))); } // if - bitset[i] |= mask; + self[i] |= mask; } // for } // bitset_add @@ -58,7 +57,7 @@ bitset_intersection_cnt(size_t const lhs[static 1], size_t const rhs[static 1]) inline size_t* -bitset_destroy(GVA_Allocator const allocator, size_t bitset[static 1]) +bitset_destroy(GVA_Allocator const allocator, size_t self[static 1]) { - return ARRAY_DESTROY(allocator, bitset); + return ARRAY_DESTROY(allocator, self); } // bitset_destroy diff --git a/src/bitset.h b/src/bitset.h index fb5f8de..bca57d1 100644 --- a/src/bitset.h +++ b/src/bitset.h @@ -4,9 +4,7 @@ #include // size_t - #include "../include/allocator.h" // GVA_Allocator -#include "../include/lcs_graph.h" // GVA_LCS_Graph size_t* @@ -14,7 +12,7 @@ bitset_init(GVA_Allocator const allocator, size_t const size); void -bitset_add(size_t bitset[static 1], size_t const start, size_t const end); +bitset_add(size_t self[static 1], size_t const start, size_t const end); size_t @@ -22,7 +20,7 @@ bitset_intersection_cnt(size_t const lhs[static 1], size_t const rhs[static 1]); size_t* -bitset_destroy(GVA_Allocator const allocator, size_t bitset[static 1]); +bitset_destroy(GVA_Allocator const allocator, size_t self[static 1]); #endif // GVA_BITSET_H From a832d633d77d4ff7e677616ba970c36de0a6d29d Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 22 Jul 2025 16:11:57 +0200 Subject: [PATCH 295/704] WIP: iterative array-based trie --- src/main.c | 34 +++++++++-- src/trie.c | 170 ++++++++++++++++++++--------------------------------- src/trie.h | 33 +++++------ 3 files changed, 108 insertions(+), 129 deletions(-) diff --git a/src/main.c b/src/main.c index 1603134..e611a3f 100644 --- a/src/main.c +++ b/src/main.c @@ -650,6 +650,7 @@ faststabber(int const argc, char* argv[static argc + 1]) } // faststabber +/* static void trie_dot_node(FILE* const stream, Trie const* const trie) { @@ -697,6 +698,19 @@ trie_print(FILE* const stream, Trie const* const trie, int const indent) fprintf(stream, "%*s%.*s (%p) %zu\n", indent, "", (int) trie->len, trie->key, (void*) trie, trie->len); trie_print(stream, trie->link, indent + INDENT); } // trie_print +*/ + + +static void +trie_raw(FILE* const stream, Trie const self) +{ + fprintf(stream, "strings (%zu): %.*s\n", array_length(self.strings), (int) array_length(self.strings), self.strings); + fprintf(stream, "nodes (%zu):\n", array_length(self.nodes)); + for (size_t i = 0; i < array_length(self.nodes); ++i) + { + fprintf(stream, "[%zu]\n .link: %2d\n .next: %2d\n .start: %2u\n .end: %2u\n", i, self.nodes[i].link, self.nodes[i].next, self.nodes[i].start, self.nodes[i].end); + } // for +} // trie_raw int @@ -716,13 +730,17 @@ trie(int argc, char* argv[static argc + 1]) return EXIT_FAILURE; } // if - Trie* trie = NULL; + Trie trie = {NULL, NULL}; size_t count = 0; static char line[4096] = {0}; while (fgets(line, sizeof(line), stream) != NULL) { - trie = trie_insert(trie, strlen(line) - 1, line); + size_t const len = strlen(line) - 1; + line[len] = '\0'; + fprintf(stderr, "insert \"%s\" (%.*s)[%zu]\n", line, (int) len, line, len); + trie_insert(gva_std_allocator, &trie, len, line); + trie_raw(stderr, trie); count += 1; } // while @@ -731,17 +749,23 @@ trie(int argc, char* argv[static argc + 1]) { fprintf(stderr, "error: %s\n", strerror(errno)); fclose(stream); - trie_destroy(trie); + //trie_destroy(trie); return EXIT_FAILURE; } // if fclose(stream); fprintf(stderr, "total: %zu\n", count); + + trie.strings = ARRAY_DESTROY(gva_std_allocator, trie.strings); + trie.nodes = ARRAY_DESTROY(gva_std_allocator, trie.nodes); + //trie_print(stderr, trie, 0); - trie_dot(stdout, trie); + //trie_dot(stdout, trie); + + //fprintf(stderr, "%p\n", (void*) trie_find(trie, 1, "AA")); - trie_destroy(trie); + //trie_destroy(trie); return EXIT_SUCCESS; } // trie diff --git a/src/trie.c b/src/trie.c index c18777f..ad8548f 100644 --- a/src/trie.c +++ b/src/trie.c @@ -1,54 +1,19 @@ -#include // NULL, size_t -#include // free, malloc -#include // strncpy +#include // true +#include // size_t +#include // memcpy -#include "trie.h" // Trie, trie_* +#include // DEBUG -inline Trie* -trie_init(size_t const len, char const key[static len]) -{ - Trie* const trie = malloc(sizeof(*trie)); - if (trie == NULL) - { - return NULL; - } // if - - trie->key = malloc(len); - if (trie->key == NULL) - { - free(trie); - return NULL; - } // if - - strncpy(trie->key, key, len); - trie->len = len; - - trie->link = NULL; - trie->next = NULL; - - return trie; -} // trie_init - - -void -trie_destroy(Trie* const trie) -{ - if (trie == NULL) - { - return; - } // if - - trie_destroy(trie->link); - trie_destroy(trie->next); - free(trie->key); - free(trie); -} // if +#include "../include/allocator.h" // GVA_Allocator +#include "../include/types.h" // GVA_NULL +#include "array.h" // ARRAY_APPEND, array_* +#include "trie.h" // Trie, TrieNode, trie_* static inline size_t -prefix_length(size_t const len_lhs, char const lhs[static len_lhs], - size_t const len_rhs, char const rhs[static len_rhs]) +prefix_length(size_t const len_lhs, char const lhs[static restrict len_lhs], + size_t const len_rhs, char const rhs[static restrict len_rhs]) { for (size_t i = 0; i < len_lhs; ++i) { @@ -61,78 +26,69 @@ prefix_length(size_t const len_lhs, char const lhs[static len_lhs], } // prefix_length -Trie const* -trie_find(Trie* const trie, size_t const len, char const key[static len]) +static inline size_t +concat(GVA_Allocator const allocator, Trie self[static restrict 1], + size_t const len, char const key[static restrict len]) { - if (trie == NULL) - { - return NULL; - } // if - - size_t const k = prefix_length(len, key, trie->len, trie->key); - if (k == 0) - { - return trie_find(trie->next, len, key); - } // if - if (k == len) - { - return trie; - } // if - if (k == trie->len) - { - return trie_find(trie->link, len - k, key + k); - } // if + size_t const start = array_length(self->strings); + self->strings = array_ensure(allocator, self->strings, sizeof(*self->strings), len); + memcpy(self->strings + start, key, len); + array_header(self->strings)->length += len; + return start; +} // concat - return NULL; -} // trie_find - -static inline void -split(Trie* const trie, size_t const k) +void +trie_insert(GVA_Allocator const allocator, Trie self[static restrict 1], + size_t const len, char const key[static restrict len]) { - Trie* const suffix = trie_init(trie->len - k, trie->key + k); - if (suffix == NULL) - { - return; - } // if - - char* const key = malloc(k); - if (key == NULL) + if (self->nodes == NULL) { - trie_destroy(suffix); + ARRAY_APPEND(allocator, self->nodes, ((TrieNode) {GVA_NULL, GVA_NULL, concat(allocator, self, len, key), len})); return; } // if - strncpy(key, trie->key, k); - free(trie->key); - - suffix->link = trie->link; - trie->link = suffix; - - trie->key = key; - trie->len = k; -} // split - -Trie* -trie_insert(Trie* const trie, size_t const len, char const key[static len]) -{ - if (trie == NULL) + size_t prefix = 0; + gva_uint idx = 0; + while (true) { - return trie_init(len, key); - } // if + size_t const k = prefix_length(len - prefix, key + prefix, self->nodes[idx].end - self->nodes[idx].start, self->strings + self->nodes[idx].start); + if (k == len - prefix) + { + return; // duplicate found + } // if - size_t const k = prefix_length(len, key, trie->len, trie->key); - if (k == 0) - { - trie->next = trie_insert(trie->next, len, key); - } // if - else if (k < len) - { - if (k < trie->len) + if (k == 0) { - split(trie, k); + if (self->nodes[idx].next == GVA_NULL) + { + gva_uint const next = ARRAY_APPEND(allocator, self->nodes, ((TrieNode) {GVA_NULL, GVA_NULL, concat(allocator, self, len - prefix, key + prefix), len - prefix})) - 1; + self->nodes[idx].next = next; + return; + } // if + idx = self->nodes[idx].next; } // if - trie->link = trie_insert(trie->link, len - k, key + k); - } // if - return trie; + else if (k == self->nodes[idx].end - self->nodes[idx].start) + { + prefix += k; + if (self->nodes[idx].link == GVA_NULL) + { + gva_uint const link = ARRAY_APPEND(allocator, self->nodes, ((TrieNode) {GVA_NULL, GVA_NULL, concat(allocator, self, len - prefix, key + prefix), len - prefix})) - 1; + self->nodes[idx].link = link; + return; + } // if + idx = self->nodes[idx].link; + } // if + else + { + fprintf(stderr, "split %u at %zu\n", idx, k); + prefix += k; + gva_uint const next = ARRAY_APPEND(allocator, self->nodes, ((TrieNode) {GVA_NULL, GVA_NULL, concat(allocator, self, len - prefix, key + prefix), array_length(self->strings)})) - 1; + gva_uint const link = ARRAY_APPEND(allocator, self->nodes, ((TrieNode) {self->nodes[idx].link, next, self->nodes[idx].start + k, self->nodes[idx].end})) - 1; + self->nodes[idx].link = link; + self->nodes[idx].end = self->nodes[idx].start + k; + return; + } // else + } // while } // trie_insert + diff --git a/src/trie.h b/src/trie.h index e65cca5..0339397 100644 --- a/src/trie.h +++ b/src/trie.h @@ -4,30 +4,29 @@ #include // size_t +#include "../include/allocator.h" // GVA_Allocator +#include "../include/types.h" // gva_uint -typedef struct Trie + +typedef struct { - struct Trie* link; - struct Trie* next; - size_t len; - char* key; -} Trie; + gva_uint link; + gva_uint next; + gva_uint start; + gva_uint end; +} TrieNode; -Trie* -trie_init(size_t const len, char const key[static len]); +typedef struct +{ + char* strings; + TrieNode* nodes; +} Trie; void -trie_destroy(Trie* const trie); - - -Trie const* -trie_find(Trie* const trie, size_t const len, char const key[static len]); - - -Trie* -trie_insert(Trie* const trie, size_t const len, char const key[static len]); +trie_insert(GVA_Allocator const allocator, Trie self[static restrict 1], + size_t const len, char const key[static restrict len]); #endif // GVA_TRIE_H From da4323bc06d63756dbf30ea52e570e84bd3e557b Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 22 Jul 2025 20:50:04 +0200 Subject: [PATCH 296/704] WIP: testing array-based trie --- src/main.c | 79 +++++++++++++++++++----------------------------------- src/trie.c | 28 ++++++++++++------- src/trie.h | 4 +++ 3 files changed, 49 insertions(+), 62 deletions(-) diff --git a/src/main.c b/src/main.c index e611a3f..33159e7 100644 --- a/src/main.c +++ b/src/main.c @@ -650,57 +650,29 @@ faststabber(int const argc, char* argv[static argc + 1]) } // faststabber -/* -static void -trie_dot_node(FILE* const stream, Trie const* const trie) -{ - if (trie == NULL) - { - return; - } // if - - fprintf(stream, "\"%p\"[label=\"%.*s\"]\n", (void*) trie, (int) trie->len, trie->key); - for (Trie const* child = trie->link; child != NULL; child = child->next) - { - fprintf(stream, "\"%p\"->\"%p\"\n", (void*) trie, (void*) child); - trie_dot_node(stream, child); - } // for -} // trie_dot_node - - static void -trie_dot(FILE* const stream, Trie const* const trie) +trie_dot(FILE* const stream, Trie const self) { fprintf(stream, "strict digraph{\n\"root\"[label=\"\",shape=point]\n"); - for (Trie const* child = trie; child != NULL; child = child->next) + if (self.nodes != NULL) { - fprintf(stream, "\"root\"->\"%p\"\n", (void*) child); - trie_dot_node(stream, child); - } // for + for (gva_uint i = 0; i != GVA_NULL; i = self.nodes[i].next) + { + fprintf(stream, "root->%u\n", i); + } // for + for (size_t i = 0; i < array_length(self.nodes); ++i) + { + fprintf(stream, "%zu[label=\"%.*s\"]\n", i, (int) (self.nodes[i].end - self.nodes[i].start), self.strings + self.nodes[i].start); + for (gva_uint j = self.nodes[i].link; j != GVA_NULL; j = self.nodes[j].next) + { + fprintf(stream, "%zu->%u\n", i, j); + } // for + } // for + } // if fprintf(stream, "}\n"); } // trie_dot -static void -trie_print(FILE* const stream, Trie const* const trie, int const indent) -{ - if (trie == NULL) - { - return; - } // if - - enum - { - INDENT = 4 - }; // constants - - trie_print(stream, trie->next, indent); - fprintf(stream, "%*s%.*s (%p) %zu\n", indent, "", (int) trie->len, trie->key, (void*) trie, trie->len); - trie_print(stream, trie->link, indent + INDENT); -} // trie_print -*/ - - static void trie_raw(FILE* const stream, Trie const self) { @@ -737,10 +709,13 @@ trie(int argc, char* argv[static argc + 1]) while (fgets(line, sizeof(line), stream) != NULL) { size_t const len = strlen(line) - 1; + if (len == 1 && line[0] == '.') + { + continue; + } // if line[len] = '\0'; - fprintf(stderr, "insert \"%s\" (%.*s)[%zu]\n", line, (int) len, line, len); + //fprintf(stderr, "INSERT %.*s\n", (int) len, line); trie_insert(gva_std_allocator, &trie, len, line); - trie_raw(stderr, trie); count += 1; } // while @@ -749,23 +724,23 @@ trie(int argc, char* argv[static argc + 1]) { fprintf(stderr, "error: %s\n", strerror(errno)); fclose(stream); - //trie_destroy(trie); + trie_destroy(gva_std_allocator, &trie); return EXIT_FAILURE; } // if fclose(stream); fprintf(stderr, "total: %zu\n", count); - - trie.strings = ARRAY_DESTROY(gva_std_allocator, trie.strings); - trie.nodes = ARRAY_DESTROY(gva_std_allocator, trie.nodes); - //trie_print(stderr, trie, 0); - //trie_dot(stdout, trie); + trie_dot(stdout, trie); //fprintf(stderr, "%p\n", (void*) trie_find(trie, 1, "AA")); - //trie_destroy(trie); + + trie.strings = ARRAY_DESTROY(gva_std_allocator, trie.strings); + trie.nodes = ARRAY_DESTROY(gva_std_allocator, trie.nodes); + + trie_destroy(gva_std_allocator, &trie); return EXIT_SUCCESS; } // trie diff --git a/src/trie.c b/src/trie.c index ad8548f..b67f70b 100644 --- a/src/trie.c +++ b/src/trie.c @@ -2,15 +2,20 @@ #include // size_t #include // memcpy -#include // DEBUG - - #include "../include/allocator.h" // GVA_Allocator #include "../include/types.h" // GVA_NULL -#include "array.h" // ARRAY_APPEND, array_* +#include "array.h" // ARRAY_*, array_* #include "trie.h" // Trie, TrieNode, trie_* +inline void +trie_destroy(GVA_Allocator const allocator, Trie self[static 1]) +{ + self->strings = ARRAY_DESTROY(allocator, self->strings); + self->nodes = ARRAY_DESTROY(allocator, self->nodes); +} // trie_destroy + + static inline size_t prefix_length(size_t const len_lhs, char const lhs[static restrict len_lhs], size_t const len_rhs, char const rhs[static restrict len_rhs]) @@ -53,7 +58,7 @@ trie_insert(GVA_Allocator const allocator, Trie self[static restrict 1], while (true) { size_t const k = prefix_length(len - prefix, key + prefix, self->nodes[idx].end - self->nodes[idx].start, self->strings + self->nodes[idx].start); - if (k == len - prefix) + if (k == len - prefix && k == self->nodes[idx].end - self->nodes[idx].start) { return; // duplicate found } // if @@ -62,7 +67,7 @@ trie_insert(GVA_Allocator const allocator, Trie self[static restrict 1], { if (self->nodes[idx].next == GVA_NULL) { - gva_uint const next = ARRAY_APPEND(allocator, self->nodes, ((TrieNode) {GVA_NULL, GVA_NULL, concat(allocator, self, len - prefix, key + prefix), len - prefix})) - 1; + gva_uint const next = ARRAY_APPEND(allocator, self->nodes, ((TrieNode) {GVA_NULL, GVA_NULL, concat(allocator, self, len - prefix, key + prefix), array_length(self->strings)})) - 1; self->nodes[idx].next = next; return; } // if @@ -73,7 +78,7 @@ trie_insert(GVA_Allocator const allocator, Trie self[static restrict 1], prefix += k; if (self->nodes[idx].link == GVA_NULL) { - gva_uint const link = ARRAY_APPEND(allocator, self->nodes, ((TrieNode) {GVA_NULL, GVA_NULL, concat(allocator, self, len - prefix, key + prefix), len - prefix})) - 1; + gva_uint const link = ARRAY_APPEND(allocator, self->nodes, ((TrieNode) {GVA_NULL, GVA_NULL, concat(allocator, self, len - prefix, key + prefix), array_length(self->strings)})) - 1; self->nodes[idx].link = link; return; } // if @@ -81,9 +86,12 @@ trie_insert(GVA_Allocator const allocator, Trie self[static restrict 1], } // if else { - fprintf(stderr, "split %u at %zu\n", idx, k); - prefix += k; - gva_uint const next = ARRAY_APPEND(allocator, self->nodes, ((TrieNode) {GVA_NULL, GVA_NULL, concat(allocator, self, len - prefix, key + prefix), array_length(self->strings)})) - 1; + gva_uint next = GVA_NULL; + if (k < len - prefix) + { + prefix += k; + next = ARRAY_APPEND(allocator, self->nodes, ((TrieNode) {GVA_NULL, GVA_NULL, concat(allocator, self, len - prefix, key + prefix), array_length(self->strings)})) - 1; + } // if gva_uint const link = ARRAY_APPEND(allocator, self->nodes, ((TrieNode) {self->nodes[idx].link, next, self->nodes[idx].start + k, self->nodes[idx].end})) - 1; self->nodes[idx].link = link; self->nodes[idx].end = self->nodes[idx].start + k; diff --git a/src/trie.h b/src/trie.h index 0339397..716cef8 100644 --- a/src/trie.h +++ b/src/trie.h @@ -29,4 +29,8 @@ trie_insert(GVA_Allocator const allocator, Trie self[static restrict 1], size_t const len, char const key[static restrict len]); +void +trie_destroy(GVA_Allocator const allocator, Trie self[static 1]); + + #endif // GVA_TRIE_H From dce8422c62b11f539881c65e8856842c2fe7a284 Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 23 Jul 2025 14:16:44 +0200 Subject: [PATCH 297/704] WIP: tries with full sequences --- src/main.c | 14 ++++++++++---- src/trie.c | 33 ++++++++++++++++++++------------- src/trie.h | 1 + 3 files changed, 31 insertions(+), 17 deletions(-) diff --git a/src/main.c b/src/main.c index 33159e7..4ed2f17 100644 --- a/src/main.c +++ b/src/main.c @@ -658,14 +658,17 @@ trie_dot(FILE* const stream, Trie const self) { for (gva_uint i = 0; i != GVA_NULL; i = self.nodes[i].next) { - fprintf(stream, "root->%u\n", i); + int const p_len = self.nodes[i].end - self.nodes[i].p_start; + fprintf(stream, "root->%u[label=\"%.*s\"]\n", i, p_len, self.strings + self.nodes[i].p_start); } // for for (size_t i = 0; i < array_length(self.nodes); ++i) { - fprintf(stream, "%zu[label=\"%.*s\"]\n", i, (int) (self.nodes[i].end - self.nodes[i].start), self.strings + self.nodes[i].start); + int const len = self.nodes[i].end - self.nodes[i].start; + fprintf(stream, "%zu[label=\"%.*s\"]\n", i, len, self.strings + self.nodes[i].start); for (gva_uint j = self.nodes[i].link; j != GVA_NULL; j = self.nodes[j].next) { - fprintf(stream, "%zu->%u\n", i, j); + int const p_len = self.nodes[j].end - self.nodes[j].p_start; + fprintf(stream, "%zu->%u[label=\"%.*s\"]\n", i, j, p_len, self.strings + self.nodes[j].p_start); } // for } // for } // if @@ -680,7 +683,7 @@ trie_raw(FILE* const stream, Trie const self) fprintf(stream, "nodes (%zu):\n", array_length(self.nodes)); for (size_t i = 0; i < array_length(self.nodes); ++i) { - fprintf(stream, "[%zu]\n .link: %2d\n .next: %2d\n .start: %2u\n .end: %2u\n", i, self.nodes[i].link, self.nodes[i].next, self.nodes[i].start, self.nodes[i].end); + fprintf(stream, "[%zu]\n .link: %2d\n .next: %2d\n .p_start: %2u\n .start: %2u\n .end: %2u\n", i, self.nodes[i].link, self.nodes[i].next, self.nodes[i].p_start, self.nodes[i].start, self.nodes[i].end); } // for } // trie_raw @@ -732,8 +735,11 @@ trie(int argc, char* argv[static argc + 1]) fprintf(stderr, "total: %zu\n", count); //trie_print(stderr, trie, 0); + //trie_raw(stderr, trie); trie_dot(stdout, trie); + fprintf(stderr, "str len: %zu\n", array_length(trie.strings)); + fprintf(stderr, "#nodes : %zu\n", array_length(trie.nodes)); //fprintf(stderr, "%p\n", (void*) trie_find(trie, 1, "AA")); diff --git a/src/trie.c b/src/trie.c index b67f70b..3218f20 100644 --- a/src/trie.c +++ b/src/trie.c @@ -49,7 +49,8 @@ trie_insert(GVA_Allocator const allocator, Trie self[static restrict 1], { if (self->nodes == NULL) { - ARRAY_APPEND(allocator, self->nodes, ((TrieNode) {GVA_NULL, GVA_NULL, concat(allocator, self, len, key), len})); + gva_uint const start = concat(allocator, self, len, key); + ARRAY_APPEND(allocator, self->nodes, ((TrieNode) {GVA_NULL, GVA_NULL, start, start, len})); return; } // if @@ -57,28 +58,33 @@ trie_insert(GVA_Allocator const allocator, Trie self[static restrict 1], gva_uint idx = 0; while (true) { - size_t const k = prefix_length(len - prefix, key + prefix, self->nodes[idx].end - self->nodes[idx].start, self->strings + self->nodes[idx].start); - if (k == len - prefix && k == self->nodes[idx].end - self->nodes[idx].start) + gva_uint const p_len = self->nodes[idx].end - self->nodes[idx].p_start; + size_t const k = prefix_length(len - prefix, key + prefix, p_len, self->strings + self->nodes[idx].p_start); + if (k == len - prefix && k == p_len) { - return; // duplicate found + return; // existing found } // if if (k == 0) { if (self->nodes[idx].next == GVA_NULL) { - gva_uint const next = ARRAY_APPEND(allocator, self->nodes, ((TrieNode) {GVA_NULL, GVA_NULL, concat(allocator, self, len - prefix, key + prefix), array_length(self->strings)})) - 1; + gva_uint const start = concat(allocator, self, len, key); + gva_uint const end = array_length(self->strings); + gva_uint const next = ARRAY_APPEND(allocator, self->nodes, ((TrieNode) {GVA_NULL, GVA_NULL, start + prefix, start, end})) - 1; self->nodes[idx].next = next; return; } // if idx = self->nodes[idx].next; } // if - else if (k == self->nodes[idx].end - self->nodes[idx].start) + else if (k == p_len) { prefix += k; if (self->nodes[idx].link == GVA_NULL) { - gva_uint const link = ARRAY_APPEND(allocator, self->nodes, ((TrieNode) {GVA_NULL, GVA_NULL, concat(allocator, self, len - prefix, key + prefix), array_length(self->strings)})) - 1; + gva_uint const start = concat(allocator, self, len, key); + gva_uint const end = array_length(self->strings); + gva_uint const link = ARRAY_APPEND(allocator, self->nodes, ((TrieNode) {GVA_NULL, GVA_NULL, start + prefix, start, end})) - 1; self->nodes[idx].link = link; return; } // if @@ -86,17 +92,18 @@ trie_insert(GVA_Allocator const allocator, Trie self[static restrict 1], } // if else { + prefix += k; gva_uint next = GVA_NULL; - if (k < len - prefix) + if (prefix < len) { - prefix += k; - next = ARRAY_APPEND(allocator, self->nodes, ((TrieNode) {GVA_NULL, GVA_NULL, concat(allocator, self, len - prefix, key + prefix), array_length(self->strings)})) - 1; + gva_uint const start = concat(allocator, self, len, key); + gva_uint const end = array_length(self->strings); + next = ARRAY_APPEND(allocator, self->nodes, ((TrieNode) {GVA_NULL, GVA_NULL, start + prefix, start, end})) - 1; } // if - gva_uint const link = ARRAY_APPEND(allocator, self->nodes, ((TrieNode) {self->nodes[idx].link, next, self->nodes[idx].start + k, self->nodes[idx].end})) - 1; + gva_uint const link = ARRAY_APPEND(allocator, self->nodes, ((TrieNode) {self->nodes[idx].link, next, self->nodes[idx].start + prefix, self->nodes[idx].start, self->nodes[idx].end})) - 1; self->nodes[idx].link = link; - self->nodes[idx].end = self->nodes[idx].start + k; + self->nodes[idx].end = self->nodes[idx].p_start + k; return; } // else } // while } // trie_insert - diff --git a/src/trie.h b/src/trie.h index 716cef8..8af9c59 100644 --- a/src/trie.h +++ b/src/trie.h @@ -12,6 +12,7 @@ typedef struct { gva_uint link; gva_uint next; + gva_uint p_start; gva_uint start; gva_uint end; } TrieNode; From fdd9af446fc53bc8d9e9b596beb3738b83a856bc Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 23 Jul 2025 19:02:18 +0200 Subject: [PATCH 298/704] WIP: stable node indices --- src/main.c | 11 ++++++----- src/trie.c | 50 ++++++++++++++++++++++++++++++++++++-------------- src/trie.h | 3 ++- 3 files changed, 44 insertions(+), 20 deletions(-) diff --git a/src/main.c b/src/main.c index 4ed2f17..0b14511 100644 --- a/src/main.c +++ b/src/main.c @@ -656,7 +656,7 @@ trie_dot(FILE* const stream, Trie const self) fprintf(stream, "strict digraph{\n\"root\"[label=\"\",shape=point]\n"); if (self.nodes != NULL) { - for (gva_uint i = 0; i != GVA_NULL; i = self.nodes[i].next) + for (gva_uint i = self.root; i != GVA_NULL; i = self.nodes[i].next) { int const p_len = self.nodes[i].end - self.nodes[i].p_start; fprintf(stream, "root->%u[label=\"%.*s\"]\n", i, p_len, self.strings + self.nodes[i].p_start); @@ -664,7 +664,7 @@ trie_dot(FILE* const stream, Trie const self) for (size_t i = 0; i < array_length(self.nodes); ++i) { int const len = self.nodes[i].end - self.nodes[i].start; - fprintf(stream, "%zu[label=\"%.*s\"]\n", i, len, self.strings + self.nodes[i].start); + fprintf(stream, "%zu[label=\"%zu\\n%.*s\"]\n", i, i, len, self.strings + self.nodes[i].start); for (gva_uint j = self.nodes[i].link; j != GVA_NULL; j = self.nodes[j].next) { int const p_len = self.nodes[j].end - self.nodes[j].p_start; @@ -705,7 +705,7 @@ trie(int argc, char* argv[static argc + 1]) return EXIT_FAILURE; } // if - Trie trie = {NULL, NULL}; + Trie trie = {NULL, NULL, GVA_NULL}; size_t count = 0; static char line[4096] = {0}; @@ -717,8 +717,9 @@ trie(int argc, char* argv[static argc + 1]) continue; } // if line[len] = '\0'; - //fprintf(stderr, "INSERT %.*s\n", (int) len, line); - trie_insert(gva_std_allocator, &trie, len, line); + fprintf(stderr, "INSERT %.*s\n", (int) len, line); + gva_uint const idx = trie_insert(gva_std_allocator, &trie, len, line); + fprintf(stderr, "%u\n", idx); count += 1; } // while diff --git a/src/trie.c b/src/trie.c index 3218f20..21a0cf0 100644 --- a/src/trie.c +++ b/src/trie.c @@ -3,7 +3,7 @@ #include // memcpy #include "../include/allocator.h" // GVA_Allocator -#include "../include/types.h" // GVA_NULL +#include "../include/types.h" // GVA_NULL, gva_uint #include "array.h" // ARRAY_*, array_* #include "trie.h" // Trie, TrieNode, trie_* @@ -43,26 +43,27 @@ concat(GVA_Allocator const allocator, Trie self[static restrict 1], } // concat -void +gva_uint trie_insert(GVA_Allocator const allocator, Trie self[static restrict 1], size_t const len, char const key[static restrict len]) { - if (self->nodes == NULL) + if (self->root == GVA_NULL) { gva_uint const start = concat(allocator, self, len, key); - ARRAY_APPEND(allocator, self->nodes, ((TrieNode) {GVA_NULL, GVA_NULL, start, start, len})); - return; + self->root = ARRAY_APPEND(allocator, self->nodes, ((TrieNode) {GVA_NULL, GVA_NULL, start, start, len})) - 1; + return self->root; } // if + gva_uint prev = GVA_NULL; size_t prefix = 0; - gva_uint idx = 0; + gva_uint idx = self->root; while (true) { gva_uint const p_len = self->nodes[idx].end - self->nodes[idx].p_start; size_t const k = prefix_length(len - prefix, key + prefix, p_len, self->strings + self->nodes[idx].p_start); if (k == len - prefix && k == p_len) { - return; // existing found + return idx; // existing found } // if if (k == 0) @@ -73,8 +74,9 @@ trie_insert(GVA_Allocator const allocator, Trie self[static restrict 1], gva_uint const end = array_length(self->strings); gva_uint const next = ARRAY_APPEND(allocator, self->nodes, ((TrieNode) {GVA_NULL, GVA_NULL, start + prefix, start, end})) - 1; self->nodes[idx].next = next; - return; + return next; } // if + prev = idx; idx = self->nodes[idx].next; } // if else if (k == p_len) @@ -86,8 +88,9 @@ trie_insert(GVA_Allocator const allocator, Trie self[static restrict 1], gva_uint const end = array_length(self->strings); gva_uint const link = ARRAY_APPEND(allocator, self->nodes, ((TrieNode) {GVA_NULL, GVA_NULL, start + prefix, start, end})) - 1; self->nodes[idx].link = link; - return; + return link; } // if + prev = idx; idx = self->nodes[idx].link; } // if else @@ -100,10 +103,29 @@ trie_insert(GVA_Allocator const allocator, Trie self[static restrict 1], gva_uint const end = array_length(self->strings); next = ARRAY_APPEND(allocator, self->nodes, ((TrieNode) {GVA_NULL, GVA_NULL, start + prefix, start, end})) - 1; } // if - gva_uint const link = ARRAY_APPEND(allocator, self->nodes, ((TrieNode) {self->nodes[idx].link, next, self->nodes[idx].start + prefix, self->nodes[idx].start, self->nodes[idx].end})) - 1; - self->nodes[idx].link = link; - self->nodes[idx].end = self->nodes[idx].p_start + k; - return; + gva_uint const link = ARRAY_APPEND(allocator, self->nodes, ((TrieNode) {idx, GVA_NULL, self->nodes[idx].p_start, self->nodes[idx].start, self->nodes[idx].p_start + k})) - 1; + self->nodes[idx].next = next; + self->nodes[idx].p_start += k; + if (prev != GVA_NULL) + { + if (self->nodes[prev].link == idx) + { + self->nodes[prev].link = link; + } // if + else + { + self->nodes[prev].next = link; + } // else + } // if + else + { + self->root = link; + } // else + if (next != GVA_NULL) + { + return next; + } // if + return link; } // else } // while -} // trie_insert +} // trie_insert \ No newline at end of file diff --git a/src/trie.h b/src/trie.h index 8af9c59..3c2b5ce 100644 --- a/src/trie.h +++ b/src/trie.h @@ -22,10 +22,11 @@ typedef struct { char* strings; TrieNode* nodes; + gva_uint root; } Trie; -void +gva_uint trie_insert(GVA_Allocator const allocator, Trie self[static restrict 1], size_t const len, char const key[static restrict len]); From 61067db4982b96a2c76a9e86f371c1328c0d8a87 Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 23 Jul 2025 19:51:15 +0200 Subject: [PATCH 299/704] FIX: next pointer for stable node indices --- src/main.c | 5 +++-- src/trie.c | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main.c b/src/main.c index 0b14511..1272461 100644 --- a/src/main.c +++ b/src/main.c @@ -679,6 +679,7 @@ trie_dot(FILE* const stream, Trie const self) static void trie_raw(FILE* const stream, Trie const self) { + fprintf(stream, "root: %u\n", self.root); fprintf(stream, "strings (%zu): %.*s\n", array_length(self.strings), (int) array_length(self.strings), self.strings); fprintf(stream, "nodes (%zu):\n", array_length(self.nodes)); for (size_t i = 0; i < array_length(self.nodes); ++i) @@ -717,9 +718,9 @@ trie(int argc, char* argv[static argc + 1]) continue; } // if line[len] = '\0'; - fprintf(stderr, "INSERT %.*s\n", (int) len, line); gva_uint const idx = trie_insert(gva_std_allocator, &trie, len, line); - fprintf(stderr, "%u\n", idx); + fprintf(stderr, "INSERT %.*s: %u\n", (int) len, line, idx); + //trie_raw(stderr, trie); count += 1; } // while diff --git a/src/trie.c b/src/trie.c index 21a0cf0..45fdd7d 100644 --- a/src/trie.c +++ b/src/trie.c @@ -103,7 +103,7 @@ trie_insert(GVA_Allocator const allocator, Trie self[static restrict 1], gva_uint const end = array_length(self->strings); next = ARRAY_APPEND(allocator, self->nodes, ((TrieNode) {GVA_NULL, GVA_NULL, start + prefix, start, end})) - 1; } // if - gva_uint const link = ARRAY_APPEND(allocator, self->nodes, ((TrieNode) {idx, GVA_NULL, self->nodes[idx].p_start, self->nodes[idx].start, self->nodes[idx].p_start + k})) - 1; + gva_uint const link = ARRAY_APPEND(allocator, self->nodes, ((TrieNode) {idx, self->nodes[idx].next, self->nodes[idx].p_start, self->nodes[idx].start, self->nodes[idx].p_start + k})) - 1; self->nodes[idx].next = next; self->nodes[idx].p_start += k; if (prev != GVA_NULL) From 18bc8c67a8c58a5900d97e75d025453c4d8c1e61 Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 28 Jul 2025 14:51:12 +0200 Subject: [PATCH 300/704] Snapshot --- include/allocator.h | 2 +- include/compare.h | 21 +- include/edit.h | 1 - include/stabbing.h | 17 +- include/std_alloc.h | 8 +- include/string.h | 30 +++ include/types.h | 10 +- include/utils.h | 10 +- include/variant.h | 16 +- src/align.c | 6 +- src/array.c | 1 - src/bitset.c | 5 +- src/bitset.h | 2 +- src/common.h | 3 - src/compare.c | 19 +- src/extract.c | 4 +- src/lcs_graph.c | 2 +- src/main.c | 575 ++++++++++++++++++-------------------------- src/stabbing.c | 110 ++------- src/string.c | 29 +++ src/trie.c | 41 ++-- src/trie.h | 15 +- src/utils.c | 5 +- src/variant.c | 39 ++- 24 files changed, 423 insertions(+), 548 deletions(-) create mode 100644 include/string.h create mode 100644 src/string.c diff --git a/include/allocator.h b/include/allocator.h index 4b9b365..21fcf91 100644 --- a/include/allocator.h +++ b/include/allocator.h @@ -18,7 +18,7 @@ // See `std_alloc.h` for a simple libc wrapper. typedef struct { - void* (*allocate)(void* const restrict context, void const* const restrict ptr, size_t const old_size, size_t const new_size); + void* (*allocate)(void* const restrict context, void* const restrict ptr, size_t const old_size, size_t const new_size); void* context; } GVA_Allocator; diff --git a/include/compare.h b/include/compare.h index ad95e0a..36465f9 100644 --- a/include/compare.h +++ b/include/compare.h @@ -2,18 +2,31 @@ #define GVA_COMPARE_H +#include // size_t + #include "allocator.h" // GVA_Allocator +#include "lcs_graph.h" // GVA_LCS_Graph #include "relations.h" // GVA_Relation +#include "types.h" // gva_uint #include "variant.h" // GVA_VARIANT -extern size_t disjoint_count; - - GVA_Relation -gva_compare(GVA_Allocator const allocator, +gva_compare_supremals(GVA_Allocator const allocator, size_t const len_ref, char const reference[static len_ref], GVA_Variant const lhs, GVA_Variant const rhs); +// FIXME: move to lcs_graph as `uniq_atomics`. +void +bitset_fill(GVA_LCS_Graph const graph, + gva_uint const offset, + gva_uint const start, gva_uint const end, + size_t dels[static restrict 1], + size_t as[static restrict 1], + size_t cs[static restrict 1], + size_t gs[static restrict 1], + size_t ts[static restrict 1]); + + #endif // GVA_COMPARE_H diff --git a/include/edit.h b/include/edit.h index 0e4fa8e..70f30ed 100644 --- a/include/edit.h +++ b/include/edit.h @@ -4,7 +4,6 @@ #include // size_t - #include "allocator.h" // GVA_Allocator diff --git a/include/stabbing.h b/include/stabbing.h index 45db9a3..fe8031f 100644 --- a/include/stabbing.h +++ b/include/stabbing.h @@ -13,13 +13,15 @@ typedef struct gva_uint parent; gva_uint leftsibling; gva_uint rightchild; - gva_uint start; gva_uint end; - // TODO: inserted seq, data + gva_uint inserted; + gva_uint distance; + size_t data; } GVA_Stabbing_Entry; +// FIXME: include trie as part of the index. typedef struct { size_t len_ref; @@ -32,19 +34,20 @@ GVA_Stabbing_Index gva_stabbing_index_init(GVA_Allocator const allocator, size_t const len_ref); +void +gva_stabbing_index_destroy(GVA_Allocator const allocator, GVA_Stabbing_Index index[static 1]); + + size_t gva_stabbing_index_add(GVA_Allocator const allocator, GVA_Stabbing_Index index[static 1], - size_t const start, size_t const end); + gva_uint const start, gva_uint const end, gva_uint const inserted, + gva_uint const distance, size_t const data); void gva_stabbing_index_build(GVA_Allocator const allocator, GVA_Stabbing_Index const index); -void -gva_stabbing_index_destroy(GVA_Allocator const allocator, GVA_Stabbing_Index index[static 1]); - - gva_uint* gva_stabbing_index_self_intersect(GVA_Allocator const allocator, GVA_Stabbing_Index const index); diff --git a/include/std_alloc.h b/include/std_alloc.h index 3d6d220..978c41e 100644 --- a/include/std_alloc.h +++ b/include/std_alloc.h @@ -12,21 +12,21 @@ // Provides a simple global allocation strategy based on `realloc` from // libc. static inline void* -gva_std_allocate(void* const restrict context, void const* const restrict ptr, size_t const old_size, size_t const new_size) +gva_std_allocate(void* const restrict context, void* const restrict ptr, size_t const old_size, size_t const new_size) { (void) context; (void) old_size; if (new_size == 0) { - free((void*) ptr); + free(ptr); return NULL; } // if - void* const new_ptr = realloc((void*) ptr, new_size); + void* const new_ptr = realloc(ptr, new_size); if (new_ptr == NULL) { - free((void*) ptr); + free(ptr); return NULL; // OOM } // if diff --git a/include/string.h b/include/string.h new file mode 100644 index 0000000..9cb65fa --- /dev/null +++ b/include/string.h @@ -0,0 +1,30 @@ +#ifndef GVA_STRING_H +#define GVA_STRING_H + + +#include // size_t + +#include "allocator.h" // GVA_Allocator + + +#define GVA_STRING_PRINT(string) (int) string.len, string.str +#define GVA_STRING_FMT "%.*s" + + +typedef struct +{ + size_t len; + char const* str; +} GVA_String; + + +void +gva_string_destroy(GVA_Allocator const allocator, GVA_String self); + + +GVA_String +gva_string_concat(GVA_Allocator const allocator, + GVA_String lhs, GVA_String const rhs); + + +#endif diff --git a/include/types.h b/include/types.h index 57b6d21..d14bd7f 100644 --- a/include/types.h +++ b/include/types.h @@ -3,11 +3,10 @@ #include // PRIu32 -#include // size_t #include // uint32_t, UINT32_MAX -#define GVA_UINT_FMT PRIu32 +#define GVA_UINT_FMT "%" PRIu32 // An unsigned integer type to store any position on a reference @@ -20,11 +19,4 @@ typedef uint32_t gva_uint; static gva_uint const GVA_NULL = UINT32_MAX; -typedef struct -{ - size_t len; - char const* str; -} GVA_String; - - #endif // GVA_TYPES_H diff --git a/include/utils.h b/include/utils.h index c337113..8b6d05c 100644 --- a/include/utils.h +++ b/include/utils.h @@ -6,13 +6,17 @@ #include // size_t #include // FILE - #include "allocator.h" // GVA_Allocator -#include "types.h" // GVA_String +#include "string.h" // GVA_String +// Reads the first sequence from a stream in FASTA format. A single header +// line (starting with '>') is expected after which the sequence is taken +// as is only omitting '\n' characters until EOF or the next '>' at the +// beginning of a line. +// The result must be deallocated by the caller (e.g. `gva_string_destroy`). GVA_String -gva_fasta_sequence(GVA_Allocator const allocator, FILE* const restrict stream); +gva_fasta_sequence(GVA_Allocator const allocator, FILE* const stream); #endif // GVA_UTILS_H diff --git a/include/variant.h b/include/variant.h index 73c47e4..bb58887 100644 --- a/include/variant.h +++ b/include/variant.h @@ -2,15 +2,19 @@ #define GVA_VARIANT_H +#include // bool #include // size_t - #include "allocator.h" // GVA_Allocator -#include "types.h" // GVA_UINT_FMT, gva_uint, GVA_String +#include "string.h" // GVA_STRING_*, GVA_String +#include "types.h" // GVA_UINT_FMT, gva_uint + +#define GVA_VARIANT_PRINT(variant) variant.start, variant.end, GVA_STRING_PRINT(variant.sequence) +#define GVA_VARIANT_FMT GVA_UINT_FMT ":" GVA_UINT_FMT "/" GVA_STRING_FMT -#define GVA_VARIANT_PRINT(variant) variant.start, variant.end, (int) variant.sequence.len, variant.sequence.str -#define GVA_VARIANT_FMT "%" GVA_UINT_FMT ":%" GVA_UINT_FMT "/%.*s" +#define GVA_VARIANT_PRINT_SPDI(ref_id, variant) ref_id, variant.start, (variant.end - variant.start), GVA_STRING_PRINT(variant.sequence) +#define GVA_VARIANT_FMT_SPDI "%s:" GVA_UINT_FMT ":" GVA_UINT_FMT ":" GVA_STRING_FMT typedef struct @@ -26,6 +30,10 @@ gva_parse_spdi(size_t const len, char const expression[static restrict len], GVA_Variant variants[static restrict 1]); +bool +gva_variant_eq(GVA_Variant const lhs, GVA_Variant const rhs); + + size_t gva_variant_length(GVA_Variant const variant); diff --git a/src/align.c b/src/align.c index 9c2b1dc..f35c476 100644 --- a/src/align.c +++ b/src/align.c @@ -3,11 +3,11 @@ #include // NULL, size_t #include // memset - #include "../include/allocator.h" // GVA_Allocator +#include "../include/types.h" // GVA_NULL, gva_uint #include "align.h" // LCS_Alignment, LCS_Node, lcs_align #include "array.h" // ARRAY_APPEND -#include "common.h" // GVA_NULL, ABS, MAX, MIN +#include "common.h" // ABS, MAX, MIN typedef struct @@ -203,4 +203,4 @@ lcs_align(GVA_Allocator const allocator, lcs.index = allocator.allocate(allocator.context, lcs.index, MIN(len_ref, len_obs) * sizeof(*lcs.index), lcs.length * sizeof(*lcs.index)); allocator.allocate(allocator.context, context.diagonals, size * sizeof(*context.diagonals), 0); return lcs; -} // align +} // lcs_align diff --git a/src/array.c b/src/array.c index ffcfdea..a8f032c 100644 --- a/src/array.c +++ b/src/array.c @@ -1,6 +1,5 @@ #include // NULL, size_t - #include "../include/allocator.h" // GVA_Allocator #include "array.h" // GVA_Array, gva_array_* diff --git a/src/bitset.c b/src/bitset.c index 3d75633..94c2867 100644 --- a/src/bitset.c +++ b/src/bitset.c @@ -6,6 +6,7 @@ #include "../include/allocator.h" // GVA_Allocator #include "array.h" // ARRAY_*, array_* #include "bitset.h" // bitset_* +#include "common.h" // MIN inline size_t* @@ -46,8 +47,8 @@ bitset_add(size_t self[static 1], size_t const start, size_t const end) inline size_t bitset_intersection_cnt(size_t const lhs[static 1], size_t const rhs[static 1]) { - size_t const len = array_length(lhs); size_t count = 0; + size_t const len = MIN(array_length(lhs), array_length(rhs)); for (size_t i = 0; i < len; ++i) { count += __builtin_popcountll(lhs[i] & rhs[i]); @@ -57,7 +58,7 @@ bitset_intersection_cnt(size_t const lhs[static 1], size_t const rhs[static 1]) inline size_t* -bitset_destroy(GVA_Allocator const allocator, size_t self[static 1]) +bitset_destroy(GVA_Allocator const allocator, size_t const* const self) { return ARRAY_DESTROY(allocator, self); } // bitset_destroy diff --git a/src/bitset.h b/src/bitset.h index bca57d1..3a61c1b 100644 --- a/src/bitset.h +++ b/src/bitset.h @@ -20,7 +20,7 @@ bitset_intersection_cnt(size_t const lhs[static 1], size_t const rhs[static 1]); size_t* -bitset_destroy(GVA_Allocator const allocator, size_t self[static 1]); +bitset_destroy(GVA_Allocator const allocator, size_t const* const self); #endif // GVA_BITSET_H diff --git a/src/common.h b/src/common.h index a4d8663..7889e6c 100644 --- a/src/common.h +++ b/src/common.h @@ -2,9 +2,6 @@ #define GVA_COMMON_H -#include "../include/types.h" // GVA_NULL, gva_uint - - // Generic abs function. Evaluates its parameters multiple times. #define ABS(x) (((x) >= 0) ? (x) : -(x)) diff --git a/src/compare.c b/src/compare.c index 37bbe6b..c88d3bc 100644 --- a/src/compare.c +++ b/src/compare.c @@ -2,15 +2,16 @@ #include // NULL, size_t #include // memcpy, strncmp - #include "../include/allocator.h" // GVA_Allocator +#include "../include/compare.h" // gva_compare_supremals #include "../include/edit.h" // gva_edit_distance #include "../include/lcs_graph.h" // GVA_LCS_Graph, gva_lcs_graph_*, gva_edges #include "../include/relations.h" // GVA_Relation, GVA_CONTAINS, GVA_DISJOINT, // GVA_EQUIVALENT GVA_IS_CONTAINED, GVA_OVERLAP +#include "../include/types.h" // GVA_NULL, gva_uint #include "../include/variant.h" // GVA_Variant #include "array.h" // ARRAY_DESTROY, array_length -#include "common.h" // GVA_NULL, gva_uint, MAX, MIN +#include "common.h" // MAX, MIN #include "bitset.h" // bitset_* @@ -20,7 +21,7 @@ static uint8_t const NUC_G = 0x4; static uint8_t const NUC_T = 0x8; -static inline uint8_t +inline static uint8_t nucleotides(size_t const len, char const sequence[static len]) { static uint8_t const MASK[256] = @@ -41,7 +42,7 @@ nucleotides(size_t const len, char const sequence[static len]) } // nucleotides -static size_t +void bitset_fill(GVA_LCS_Graph const graph, gva_uint const offset, gva_uint const start, gva_uint const end, @@ -51,7 +52,6 @@ bitset_fill(GVA_LCS_Graph const graph, size_t gs[static restrict 1], size_t ts[static restrict 1]) { - size_t counter = 0; for (size_t i = 0; i < array_length(graph.nodes); ++i) { if (graph.nodes[i].row > end) @@ -96,15 +96,11 @@ bitset_fill(GVA_LCS_Graph const graph, } // if } // for } // for - return counter; } // bitset_fill -size_t disjoint_count = 0; - - GVA_Relation -gva_compare(GVA_Allocator const allocator, +gva_compare_supremals(GVA_Allocator const allocator, size_t const len_ref, char const reference[static len_ref], GVA_Variant const lhs, GVA_Variant const rhs) { @@ -207,7 +203,6 @@ gva_compare(GVA_Allocator const allocator, else { relation = GVA_DISJOINT; - disjoint_count += 1; } // else lhs_ts = bitset_destroy(allocator, lhs_ts); @@ -227,4 +222,4 @@ gva_compare(GVA_Allocator const allocator, lhs_obs = allocator.allocate(allocator.context, lhs_obs, lhs_len, 0); return relation; -} // gva_compare +} // gva_compare_supremals diff --git a/src/extract.c b/src/extract.c index 98ae28b..6044723 100644 --- a/src/extract.c +++ b/src/extract.c @@ -1,9 +1,9 @@ #include // NULL, size_t - #include "../include/lcs_graph.h" // GVA_LCS_Graph, gva_edges +#include "../include/types.h" // GVA_NULL, gva_uint #include "array.h" // ARRAY_APPEND, array_length -#include "common.h" // GVA_NULL, MAX, MIN, GVA_String, gva_uint +#include "common.h" // MAX, MIN typedef struct diff --git a/src/lcs_graph.c b/src/lcs_graph.c index 87995d8..6830e9a 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -3,7 +3,6 @@ #include // NULL, size_t #include // memcpy - #include "../include/allocator.h" // GVA_Allocator #include "../include/lcs_graph.h" // GVA_LCS_Graph, gva_lcs_graph_* #include "../include/variant.h" // GVA_Variant, gva_variant_length @@ -339,4 +338,5 @@ gva_lcs_graph_destroy(GVA_Allocator const allocator, GVA_LCS_Graph self) self.nodes = ARRAY_DESTROY(allocator, self.nodes); self.edges = ARRAY_DESTROY(allocator, self.edges); self.local_supremal = ARRAY_DESTROY(allocator, self.local_supremal); + // FIXME: ownership of observed } // gva_lcs_graph_destroy diff --git a/src/main.c b/src/main.c index 1272461..41b54fc 100644 --- a/src/main.c +++ b/src/main.c @@ -1,29 +1,33 @@ -//#define _XOPEN_SOURCE -//#include #include // errno #include // CHAR_BIT #include // NULL, size_t #include // FILE, stderr, fclose, fopen, fprintf #include // EXIT_* -#include // strcmp, strerror, strlen -//#include // optarg +#include // strerror, strlen +#include // CLOCKS_PER_SEC, clock_t, clock - -#include "../include/compare.h" // gva_compare +#include "../include/compare.h" // bitset_fill #include "../include/edit.h" // gva_edit_distance #include "../include/extract.h" // gva_extract #include "../include/lcs_graph.h" // GVA_LCS_Graph, GVA_Variant, gva_lcs_graph_*, gva_edges -#include "../include/relations.h" // GVA_RELATION_LABELS #include "../include/stabbing.h" // GVA_Stabbing_*, gva_stabbing_* #include "../include/std_alloc.h" // gva_std_allocator -#include "../include/types.h" // GVA_NULL, GVA_String, gva_uint +#include "../include/string.h" // gva_string_destroy +#include "../include/types.h" // GVA_NULL, gva_uint #include "../include/utils.h" // gva_fasta_sequence #include "../include/variant.h" // GVA_VARIANT_*, GVA_Variant, gva_parse_spdi #include "array.h" // ARRAY_DESTROY, array_length #include "bitset.h" // bitset_* +#include "common.h" // MAX, MIN #include "trie.h" // Trie, trie_* +#define TIC(x) clock_t const x = clock() +#define TOC(x) fprintf(stderr, "Elapsed time: %s (seconds): %.2f\n", (#x), (double)(clock() - (x)) / CLOCKS_PER_SEC) + +#define LINE_SIZE 4096 + + static void lcs_graph_svg(FILE* const stream, GVA_LCS_Graph const graph) { @@ -282,142 +286,6 @@ lcs_graph_raw(FILE* const stream, GVA_LCS_Graph const graph) } // lcs_graph_raw -int -compare(int argc, char* argv[static argc + 1]) -{ - GVA_String reference = {0, NULL}; - errno = 0; - FILE* const restrict stream = fopen(argv[1], "r"); - if (stream == NULL) - { - fprintf(stderr, "error: %s\n", strerror(errno)); - return EXIT_FAILURE; - } // if - reference = gva_fasta_sequence(gva_std_allocator, stream); - fclose(stream); - - disjoint_count = 0; - - // NC_000001.11:169556314:6:TTTTTCTCT 3 NC_000001.11:169556314:8:TTTTTGTCTGGCTGC 7 4 is_contained - // NC_000001.10:g.103496806_103496807delAA NC_000001.10:103496805:13:AAAAAAAAAAA NC_000001.10:g.103496811A>C NC_000001.10:103496805:13:AAAAACAAAAAAA overlap - char lhs_hgvs[4096] = {0}; - char lhs_spdi[4096] = {0}; - //size_t lhs_dist = 0; - char rhs_hgvs[4096] = {0}; - char rhs_spdi[4096] = {0}; - //size_t rhs_dist = 0; - //size_t dist = 0; - //char python[32] = {0}; - char relation[32] = {0}; - size_t count = 0; - //while (fscanf(stdin, "%4096s %zu %4096s %zu %zu %32s\n", lhs_spdi, &lhs_dist, rhs_spdi, &rhs_dist, &dist, python) == 6) - while (fscanf(stdin, "%4095s %4095s %4095s %4095s %31s\n", lhs_hgvs, lhs_spdi, rhs_hgvs, rhs_spdi, relation) == 5) - { - GVA_Variant lhs; - if (!gva_parse_spdi(strlen(lhs_spdi), lhs_spdi, &lhs)) - { - fprintf(stderr, "PARSE ERROR: %s\n", lhs_spdi); - continue; - } // if - GVA_Variant rhs; - if (!gva_parse_spdi(strlen(rhs_spdi), rhs_spdi, &rhs)) - { - fprintf(stderr, "PARSE ERROR: %s\n", rhs_spdi); - continue; - } // if - - //fprintf(stderr, "%s %zu %s %zu %zu %s\n", lhs_spdi, lhs_dist, rhs_spdi, rhs_dist, dist, python); - size_t const relation = gva_compare(gva_std_allocator, reference.len, reference.str, lhs, rhs); - //if (strcmp(python, GVA_RELATION_LABELS[relation]) != 0) - { - //printf("%s %zu %s %zu %zu %s %s\n", lhs_spdi, lhs_dist, rhs_spdi, rhs_dist, dist, python, GVA_RELATION_LABELS[relation]); - printf("%s %s %s %s %s\n", lhs_hgvs, lhs_spdi, rhs_hgvs, rhs_spdi, GVA_RELATION_LABELS[relation]); - } // if - - count += 1; - } // while - fprintf(stderr, "total: %zu\n", count); - fprintf(stderr, "disjoint: %zu\n", disjoint_count); - reference.str = gva_std_allocator.allocate(gva_std_allocator.context, reference.str, reference.len, 0); - - return 0; -} // compare - - -int -all_graphs(void) -{ - GVA_String seq = {0, NULL}; - FILE* const restrict stream = fopen("data/NC_000001.11.fasta", "r"); - if (stream != NULL) - { - seq = gva_fasta_sequence(gva_std_allocator, stream); - fclose(stream); - } // if - - //bool check = false; - size_t rsid = 0; - char spdi[4096] = {0}; - char hgvs[4096] = {0}; - char python_sup[4096] = {0}; - //char c_sup[4096] = {0}; - size_t python_distance = 0; - size_t python_nodes = 0; - size_t python_edges = 0; - size_t count = 0; - size_t counter = 0; - while (fscanf(stdin, "%zu %4095s %4095s %4095s %zu %zu %zu\n", &rsid, spdi, hgvs, python_sup, &python_distance, &python_nodes, &python_edges) == 7) - { - GVA_Variant variant; - if (!gva_parse_spdi(strlen(spdi), spdi, &variant)) - { - fprintf(stderr, "PARSE ERROR: %zu %s %s %s %zu %zu %zu\n", rsid, spdi, hgvs, python_sup, python_distance, python_nodes, python_edges); - continue; - } // if - count += 1; - GVA_LCS_Graph graph = gva_lcs_graph_from_variant(gva_std_allocator, seq.len, seq.str, variant); - - //fprintf(stdout, "%zu %s %s %s %zu %zu %zu " GVA_VARIANT_FMT " %u %zu %zu\n", - // rsid, spdi, hgvs, python_sup, python_distance, python_nodes, python_edges, GVA_VARIANT_PRINT(graph.supremal), graph.distance, array_length(graph.nodes), array_length(graph.edges)); - //fprintf(stdout, "%zu %s %s %s %zu %zu %zu " GVA_VARIANT_FMT " %u %zu %zu\n", - // rsid, spdi, hgvs, python_sup, python_distance, python_nodes, python_edges, GVA_VARIANT_PRINT(graph.supremal), graph.distance, array_length(graph.nodes), array_length(graph.edges)); - //sprintf(c_sup, GVA_VARIANT_FMT, GVA_VARIANT_PRINT(graph.supremal)); - //fprintf(stderr, "%s %s\n", python_sup, c_sup); - //if (check && strcmp(python_sup, c_sup)) - //{ - // fprintf(stderr, "Different supremal!\n"); - //} - - //lcs_graph_raw(stderr, graph); - //lcs_graph_dot(stderr, graph); - - //gva_uint const sup_len = graph.supremal.end - graph.supremal.start; - //size_t* dels = bitset_init(gva_std_allocator, sup_len + 1); - //size_t* as = bitset_init(gva_std_allocator, sup_len + 1); - //size_t* cs = bitset_init(gva_std_allocator, sup_len + 1); - //size_t* gs = bitset_init(gva_std_allocator, sup_len + 1); - //size_t* ts = bitset_init(gva_std_allocator, sup_len + 1); - - //counter += bitset_fill(graph, graph.supremal.start, graph.supremal.start, graph.supremal.end, dels, as, cs, gs, ts); - - //ts = bitset_destroy(gva_std_allocator, ts); - //gs = bitset_destroy(gva_std_allocator, gs); - //cs = bitset_destroy(gva_std_allocator, cs); - //as = bitset_destroy(gva_std_allocator, as); - //dels = bitset_destroy(gva_std_allocator, dels); - - graph.observed.str = gva_std_allocator.allocate(gva_std_allocator.context, graph.observed.str, graph.observed.len, 0); - gva_lcs_graph_destroy(gva_std_allocator, graph); - } // while - - fprintf(stderr, "%zu %zu\n", count, counter); - - seq.str = gva_std_allocator.allocate(gva_std_allocator.context, seq.str, seq.len, 0); - - return EXIT_SUCCESS; -} // all_graphs - - int extract(int const argc, char* argv[static argc + 1]) { @@ -451,18 +319,13 @@ extract(int const argc, char* argv[static argc + 1]) } // for canonical = ARRAY_DESTROY(gva_std_allocator, canonical); - /* - size_t const distance = gva_edit_distance(gva_std_allocator, len_ref, reference, len_obs, observed); - fprintf(stderr, "distance only: %zu\n", distance); - */ - gva_lcs_graph_destroy(gva_std_allocator, graph); return EXIT_SUCCESS; } // extract -static void +void index_dot(FILE* const stream, GVA_Stabbing_Index const index) { fprintf(stream, "strict digraph{\nrankdir=BT\n"); @@ -478,14 +341,7 @@ index_dot(FILE* const stream, GVA_Stabbing_Index const index) } // index_dot -static inline bool -intersect(size_t const lhs_start, size_t const lhs_end, - size_t const rhs_start, size_t const rhs_end) -{ - return rhs_end >= lhs_start && rhs_start <= lhs_end; -} // intersect - - +// FIXME: see `match_number` in src/variant.c static inline size_t parse_number(char const buffer[static 1], size_t idx[static 1]) { @@ -499,18 +355,75 @@ parse_number(char const buffer[static 1], size_t idx[static 1]) } // parse_number -typedef struct +void +trie_dot(FILE* const stream, Trie const self) { - gva_uint start; - gva_uint end; -} Interval; + fprintf(stream, "strict digraph{\n\"root\"[label=\"\",shape=point]\n"); + if (self.nodes != NULL) + { + for (gva_uint i = self.root; i != GVA_NULL; i = self.nodes[i].next) + { + int const p_len = self.nodes[i].end - self.nodes[i].p_start; + fprintf(stream, "root->%u[label=\"%.*s\"]\n", i, p_len, self.strings.str + self.nodes[i].p_start); + } // for + for (size_t i = 0; i < array_length(self.nodes); ++i) + { + int const len = self.nodes[i].end - self.nodes[i].start; + fprintf(stream, "%zu[label=\"%zu\\n%.*s\"]\n", i, i, len, self.strings.str + self.nodes[i].start); + for (gva_uint j = self.nodes[i].link; j != GVA_NULL; j = self.nodes[j].next) + { + int const p_len = self.nodes[j].end - self.nodes[j].p_start; + fprintf(stream, "%zu->%u[label=\"%.*s\"]\n", i, j, p_len, self.strings.str + self.nodes[j].p_start); + } // for + } // for + } // if + fprintf(stream, "}\n"); +} // trie_dot + + +void +trie_raw(FILE* const stream, Trie const self) +{ + fprintf(stream, "root: %u\n", self.root); + fprintf(stream, "strings (%zu): %.*s\n", self.strings.len, (int) self.strings.len, self.strings.str); + fprintf(stream, "nodes (%zu):\n", array_length(self.nodes)); + for (size_t i = 0; i < array_length(self.nodes); ++i) + { + fprintf(stream, "[%zu]\n .link: %2d\n .next: %2d\n .p_start: %2u\n .start: %2u\n .end: %2u\n", i, self.nodes[i].link, self.nodes[i].next, self.nodes[i].p_start, self.nodes[i].start, self.nodes[i].end); + } // for +} // trie_raw + + +void +bitset_print(size_t const bitset[static 1], size_t const size) +{ + for (intmax_t i = array_length(bitset) * sizeof(*bitset) * CHAR_BIT - 1; i >= 0; --i) + { + if ((size_t) i > size) + { + fprintf(stderr, " "); + } // if + else + { + fprintf(stderr, "%zu", bitset[i / (sizeof(*bitset) * CHAR_BIT)] >> (i % (sizeof(*bitset) * CHAR_BIT)) & 0x1); + } // else + if (i % (sizeof(*bitset) * CHAR_BIT) == 0) + { + fprintf(stderr, "\n"); + } // if + else if (i % CHAR_BIT == 0) + { + fprintf(stderr, " "); + } // if + } // for +} // bitset_print static inline int -interval_cmp(void const* lhs, void const* rhs) +entry_cmp(void const* lhs, void const* rhs) { - Interval const* const lhs_interval = lhs; - Interval const* const rhs_interval = rhs; + GVA_Stabbing_Entry const* const lhs_interval = lhs; + GVA_Stabbing_Entry const* const rhs_interval = rhs; if (lhs_interval->start < rhs_interval->start) { @@ -529,15 +442,15 @@ interval_cmp(void const* lhs, void const* rhs) return 1; } // if return 0; -} // interval cmp +} // entry_cmp int -faststabber(int const argc, char* argv[static argc + 1]) +all(int argc, char* argv[static argc + 1]) { if (argc < 2) { - fprintf(stderr, "usage: %s path_to_variant_tsv\n", argv[0]); + fprintf(stderr, "usage: %s path_to_reference_fasta\n", argv[0]); return EXIT_FAILURE; } // if @@ -549,227 +462,197 @@ faststabber(int const argc, char* argv[static argc + 1]) return EXIT_FAILURE; } // if - //248956422 - //GVA_Stabbing_Index index = gva_stabbing_index_init(gva_std_allocator, 248956422); + GVA_String reference = {0, NULL}; + reference = gva_fasta_sequence(gva_std_allocator, stream); + fclose(stream); + + fprintf(stderr, "reference length: %zu\n", reference.len); - Interval* intervals = NULL; + TIC(perf_calculate_supremals); - size_t line_count = 0; - static char line[4096] = {0}; - while (fgets(line, sizeof(line), stream) != NULL) + GVA_Stabbing_Index index = gva_stabbing_index_init(gva_std_allocator, reference.len); + Trie trie = {{0, NULL}, NULL, GVA_NULL}; + + size_t count = 0; + static char line[LINE_SIZE] = {0}; + while (fgets(line, sizeof(line), stdin) != NULL) { size_t idx = 0; + size_t const rsid = parse_number(line, &idx); + idx += 1; // skip space or tab + int const len = (char*) memchr(line + idx, '\n', LINE_SIZE - idx) - (line + idx); + GVA_Variant variant; + if (gva_parse_spdi(len, line + idx, &variant) == 0) + { + fprintf(stderr, "error: SPDI parsing failed at line %zu: %s\n", count + 1, line); + continue; + } // if + + GVA_LCS_Graph graph = gva_lcs_graph_from_variant(gva_std_allocator, reference.len, reference.str, variant); + + gva_uint const inserted = trie_insert(gva_std_allocator, &trie, graph.supremal.sequence.len, graph.supremal.sequence.str); + gva_stabbing_index_add(gva_std_allocator, &index, graph.supremal.start, graph.supremal.end, inserted, graph.distance, rsid); + + gva_string_destroy(gva_std_allocator, graph.observed); + gva_lcs_graph_destroy(gva_std_allocator, graph); - // ignore rsid - parse_number(line, &idx); - idx += 1; - size_t const start = parse_number(line, &idx); - idx += 1; - size_t const end = parse_number(line, &idx); - // ignore remainder of the line - - //gva_stabbing_index_add(gva_std_allocator, &index, start, end); - ARRAY_APPEND(gva_std_allocator, intervals, ((Interval) {start, end})); - line_count += 1; + count += 1; } // while + fprintf(stderr, "number of variants: %zu\n", array_length(index.entries) - 1); - errno = 0; - if (feof(stream) == 0) - { - fprintf(stderr, "error: %s\n", strerror(errno)); - fclose(stream); - //gva_stabbing_index_destroy(gva_std_allocator, &index); - intervals = ARRAY_DESTROY(gva_std_allocator, intervals); - return EXIT_FAILURE; - } // if - fclose(stream); + TOC(perf_calculate_supremals); - fprintf(stderr, "line count: %zu\n", line_count); - if (intervals == NULL) - { - return EXIT_FAILURE; - } // if + TIC(perf_build_index); - //qsort(intervals, array_length(intervals), sizeof(*intervals), interval_cmp); - //fprintf(stderr, "entry count: %zu\n", array_length(index.entries) - 1); + qsort(index.entries, array_length(index.entries), sizeof(*index.entries), entry_cmp); + gva_stabbing_index_build(gva_std_allocator, index); - /* - for (size_t i = 0; i < array_length(intervals); ++i) - { - printf("%u %u\n", intervals[i].start, intervals[i].end); - } // for - */ + TOC(perf_build_index); - //gva_stabbing_index_build(gva_std_allocator, index); + TIC(perf_calculate_relations); - //index_dot(stderr, index); - //gva_uint* results = gva_stabbing_index_self_intersect(gva_std_allocator, index); - //fprintf(stderr, "total: %zu\n", array_length(results)); - //results = ARRAY_DESTROY(gva_std_allocator, results); -/* - size_t count = 0; + count = 0; for (size_t i = 1; i < array_length(index.entries); ++i) { - gva_uint* results = gva_stabbing_index_intersect(gva_std_allocator, index, index.entries[i].start, index.entries[i].end); - //count += array_length(results); - for (size_t j = 0; j < array_length(results); ++j) - { - if (i < results[j]) - { - //fprintf(stdout, "%2zu [%u, %u] %2u [%u, %u]\n", i, index.entries[i].start, index.entries[i].end, results[j], index.entries[results[j]].start, index.entries[results[j]].end); - count += 1; - } // if - } // for - results = ARRAY_DESTROY(gva_std_allocator, results); - } // for - fprintf(stderr, "total: %zu\n", count); -*/ + GVA_Variant const lhs = {index.entries[i].start, index.entries[i].end, {trie.nodes[index.entries[i].inserted].end - trie.nodes[index.entries[i].inserted].start, trie.strings.str + trie.nodes[index.entries[i].inserted].start}}; - size_t count = 0; - for (size_t i = 0; i < array_length(intervals); ++i) - { - for (size_t j = i + 1; j < array_length(intervals); ++j) + GVA_LCS_Graph lhs_graph = {.nodes = NULL}; + size_t* lhs_dels = NULL; + size_t* lhs_as = NULL; + size_t* lhs_cs = NULL; + size_t* lhs_gs = NULL; + size_t* lhs_ts = NULL; + + for (size_t j = i + 1; j < array_length(index.entries); ++j) { - if (intervals[i].end < intervals[j].start) + if (index.entries[i].end < index.entries[j].start) { break; } // if - if (intersect(intervals[i].start, intervals[i].end, intervals[j].start, intervals[j].end)) + if (index.entries[j].end >= index.entries[i].start && index.entries[j].start <= index.entries[i].end) { - //fprintf(stdout, "%2zu [%u, %u] %2zu [%u, %u]\n", i, index.entries[i].start, index.entries[i].end, j, index.entries[j].start, index.entries[j].end); count += 1; - } // if - } // for - } // for - fprintf(stderr, "total: %zu\n", count); - -// gva_stabbing_index_destroy(gva_std_allocator, &index); - intervals = ARRAY_DESTROY(gva_std_allocator, intervals); - - return EXIT_SUCCESS; -} // faststabber - - -static void -trie_dot(FILE* const stream, Trie const self) -{ - fprintf(stream, "strict digraph{\n\"root\"[label=\"\",shape=point]\n"); - if (self.nodes != NULL) - { - for (gva_uint i = self.root; i != GVA_NULL; i = self.nodes[i].next) - { - int const p_len = self.nodes[i].end - self.nodes[i].p_start; - fprintf(stream, "root->%u[label=\"%.*s\"]\n", i, p_len, self.strings + self.nodes[i].p_start); - } // for - for (size_t i = 0; i < array_length(self.nodes); ++i) - { - int const len = self.nodes[i].end - self.nodes[i].start; - fprintf(stream, "%zu[label=\"%zu\\n%.*s\"]\n", i, i, len, self.strings + self.nodes[i].start); - for (gva_uint j = self.nodes[i].link; j != GVA_NULL; j = self.nodes[j].next) - { - int const p_len = self.nodes[j].end - self.nodes[j].p_start; - fprintf(stream, "%zu->%u[label=\"%.*s\"]\n", i, j, p_len, self.strings + self.nodes[j].p_start); - } // for - } // for - } // if - fprintf(stream, "}\n"); -} // trie_dot + GVA_Variant const rhs = {index.entries[j].start, index.entries[j].end, {trie.nodes[index.entries[j].inserted].end - trie.nodes[index.entries[j].inserted].start, trie.strings.str + trie.nodes[index.entries[j].inserted].start}}; + if (index.entries[i].start == index.entries[j].start && index.entries[i].end == index.entries[j].end && index.entries[i].inserted == index.entries[j].inserted) + { + printf("%zu " GVA_VARIANT_FMT_SPDI " %zu " GVA_VARIANT_FMT_SPDI " equivalent\n", index.entries[i].data, GVA_VARIANT_PRINT_SPDI("NC_000001.11", lhs), index.entries[j].data, GVA_VARIANT_PRINT_SPDI("NC_000001.11", rhs)); + continue; + } // if -static void -trie_raw(FILE* const stream, Trie const self) -{ - fprintf(stream, "root: %u\n", self.root); - fprintf(stream, "strings (%zu): %.*s\n", array_length(self.strings), (int) array_length(self.strings), self.strings); - fprintf(stream, "nodes (%zu):\n", array_length(self.nodes)); - for (size_t i = 0; i < array_length(self.nodes); ++i) - { - fprintf(stream, "[%zu]\n .link: %2d\n .next: %2d\n .p_start: %2u\n .start: %2u\n .end: %2u\n", i, self.nodes[i].link, self.nodes[i].next, self.nodes[i].p_start, self.nodes[i].start, self.nodes[i].end); - } // for -} // trie_raw + size_t const start = MIN(lhs.start, rhs.start); + size_t const end = MAX(lhs.end, rhs.end); + size_t const lhs_len = (lhs.start - start) + lhs.sequence.len + (end - lhs.end); + char* lhs_obs = NULL; + if (lhs_len > 0) + { + lhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, NULL, 0, lhs_len); + if (lhs_obs != NULL) + { + memcpy(lhs_obs, reference.str + start, lhs.start - start); + memcpy(lhs_obs + lhs.start - start, lhs.sequence.str, lhs.sequence.len); + memcpy(lhs_obs + lhs.start - start + lhs.sequence.len, reference.str + lhs.end, end - lhs.end); + } // if + } // if -int -trie(int argc, char* argv[static argc + 1]) -{ - if (argc < 2) - { - fprintf(stderr, "usage %s path_to_strings\n", argv[0]); - return EXIT_FAILURE; - } // if + size_t const rhs_len = (rhs.start - start) + rhs.sequence.len + (end - rhs.end); + char* rhs_obs = NULL; + if (rhs_len > 0) + { + rhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, NULL, 0, rhs_len); + if (rhs_obs != NULL) + { + memcpy(rhs_obs, reference.str + start, rhs.start - start); + memcpy(rhs_obs + rhs.start - start, rhs.sequence.str, rhs.sequence.len); + memcpy(rhs_obs + rhs.start - start + rhs.sequence.len, reference.str + rhs.end, end - rhs.end); + } // if + } // if - errno = 0; - FILE* stream = fopen(argv[1], "r"); - if (stream == NULL) - { - fprintf(stderr, "error: %s\n", strerror(errno)); - return EXIT_FAILURE; - } // if + size_t const distance = gva_edit_distance(gva_std_allocator, lhs_len, lhs_obs, rhs_len, rhs_obs); - Trie trie = {NULL, NULL, GVA_NULL}; + rhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, rhs_obs, rhs_len, 0); + lhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, lhs_obs, lhs_len, 0); - size_t count = 0; - static char line[4096] = {0}; - while (fgets(line, sizeof(line), stream) != NULL) - { - size_t const len = strlen(line) - 1; - if (len == 1 && line[0] == '.') - { - continue; - } // if - line[len] = '\0'; - gva_uint const idx = trie_insert(gva_std_allocator, &trie, len, line); - fprintf(stderr, "INSERT %.*s: %u\n", (int) len, line, idx); - //trie_raw(stderr, trie); - count += 1; - } // while + if (index.entries[i].distance + index.entries[j].distance == distance) + { + continue; // disjoint + } // if - errno = 0; - if (feof(stream) == 0) - { - fprintf(stderr, "error: %s\n", strerror(errno)); - fclose(stream); - trie_destroy(gva_std_allocator, &trie); - return EXIT_FAILURE; - } // if - fclose(stream); + if (index.entries[i].distance - index.entries[j].distance == distance) + { + printf("%zu " GVA_VARIANT_FMT_SPDI " %zu " GVA_VARIANT_FMT_SPDI " contains\n", index.entries[i].data, GVA_VARIANT_PRINT_SPDI("NC_000001.11", lhs), index.entries[j].data, GVA_VARIANT_PRINT_SPDI("NC_000001.11", rhs)); + continue; + } // if - fprintf(stderr, "total: %zu\n", count); + if (index.entries[j].distance - index.entries[i].distance == distance) + { + printf("%zu " GVA_VARIANT_FMT_SPDI " %zu " GVA_VARIANT_FMT_SPDI " is_contained\n", index.entries[i].data, GVA_VARIANT_PRINT_SPDI("NC_000001.11", lhs), index.entries[j].data, GVA_VARIANT_PRINT_SPDI("NC_000001.11", rhs)); + continue; + } // if - //trie_print(stderr, trie, 0); - //trie_raw(stderr, trie); - trie_dot(stdout, trie); + if (lhs_graph.nodes == NULL) + { + lhs_graph = gva_lcs_graph_init(gva_std_allocator, lhs.end - lhs.start, reference.str + lhs.start, lhs.sequence.len, lhs.sequence.str, lhs.start); + size_t const len = lhs.end - lhs.start + 1; + lhs_dels = bitset_init(gva_std_allocator, len); // can be one shorter + lhs_as = bitset_init(gva_std_allocator, len); + lhs_cs = bitset_init(gva_std_allocator, len); + lhs_gs = bitset_init(gva_std_allocator, len); + lhs_ts = bitset_init(gva_std_allocator, len); + bitset_fill(lhs_graph, lhs.start, lhs.start, lhs.end, lhs_dels, lhs_as, lhs_cs, lhs_gs, lhs_ts); + } // if - fprintf(stderr, "str len: %zu\n", array_length(trie.strings)); - fprintf(stderr, "#nodes : %zu\n", array_length(trie.nodes)); - //fprintf(stderr, "%p\n", (void*) trie_find(trie, 1, "AA")); + GVA_LCS_Graph rhs_graph = gva_lcs_graph_init(gva_std_allocator, rhs.end - rhs.start, reference.str + rhs.start, rhs.sequence.len, rhs.sequence.str, rhs.start); + size_t const len = rhs.end - lhs.start + 1; + size_t* rhs_dels = bitset_init(gva_std_allocator, len); // can be one shorter + size_t* rhs_as = bitset_init(gva_std_allocator, len); + size_t* rhs_cs = bitset_init(gva_std_allocator, len); + size_t* rhs_gs = bitset_init(gva_std_allocator, len); + size_t* rhs_ts = bitset_init(gva_std_allocator, len); + bitset_fill(rhs_graph, lhs.start, rhs.start, rhs.end, rhs_dels, rhs_as, rhs_cs, rhs_gs, rhs_ts); + + if (bitset_intersection_cnt(lhs_dels, rhs_dels) > 0 || + bitset_intersection_cnt(lhs_as, rhs_as) > 0 || + bitset_intersection_cnt(lhs_cs, rhs_cs) > 0 || + bitset_intersection_cnt(lhs_gs, rhs_gs) > 0 || + bitset_intersection_cnt(lhs_ts, rhs_ts) > 0) + { + printf("%zu " GVA_VARIANT_FMT_SPDI " %zu " GVA_VARIANT_FMT_SPDI " overlap\n", index.entries[i].data, GVA_VARIANT_PRINT_SPDI("NC_000001.11", lhs), index.entries[j].data, GVA_VARIANT_PRINT_SPDI("NC_000001.11", rhs)); + } // if + rhs_ts = bitset_destroy(gva_std_allocator, rhs_ts); + rhs_gs = bitset_destroy(gva_std_allocator, rhs_gs); + rhs_cs = bitset_destroy(gva_std_allocator, rhs_cs); + rhs_as = bitset_destroy(gva_std_allocator, rhs_as); + rhs_dels = bitset_destroy(gva_std_allocator, rhs_dels); + gva_lcs_graph_destroy(gva_std_allocator, rhs_graph); + } // if + } // for + lhs_ts = bitset_destroy(gva_std_allocator, lhs_ts); + lhs_gs = bitset_destroy(gva_std_allocator, lhs_gs); + lhs_cs = bitset_destroy(gva_std_allocator, lhs_cs); + lhs_as = bitset_destroy(gva_std_allocator, lhs_as); + lhs_dels = bitset_destroy(gva_std_allocator, lhs_dels); + gva_lcs_graph_destroy(gva_std_allocator, lhs_graph); + } // for + fprintf(stderr, "number of pairs calculated: %zu\n", count); - trie.strings = ARRAY_DESTROY(gva_std_allocator, trie.strings); - trie.nodes = ARRAY_DESTROY(gva_std_allocator, trie.nodes); + TOC(perf_calculate_relations); + gva_stabbing_index_destroy(gva_std_allocator, &index); trie_destroy(gva_std_allocator, &trie); - + gva_string_destroy(gva_std_allocator, reference); return EXIT_SUCCESS; -} // trie +} // all int main(int argc, char* argv[static argc + 1]) { (void) argv; - - // check python relation output - //return compare(argc, argv); - - // calculate graphs for all inputs - //return all_graphs(); - - // extract single variant //return extract(argc, argv); - // faststabber - //return faststabber(argc, argv); - // trie - return trie(argc, argv); + // all + return all(argc, argv); } // main diff --git a/src/stabbing.c b/src/stabbing.c index a89ac33..78ca973 100644 --- a/src/stabbing.c +++ b/src/stabbing.c @@ -2,14 +2,11 @@ #include // NULL, size_t #include // memset - -#include // DEBUG - - #include "../include/allocator.h" // GVA_Allocator #include "../include/stabbing.h" // GVA_Stabbing_Entry, GVA_Stabbing_Index, gva_stabbing_index_* +#include "../include/types.h" // GVA_NULL, gva_uint #include "array.h" // ARRAY_*, array_* -#include "common.h" // GVA_NULL, gva_uint, MAX +#include "common.h" // MAX GVA_Stabbing_Index @@ -23,17 +20,27 @@ gva_stabbing_index_init(GVA_Allocator const allocator, size_t const len_ref) memset(start_table, 0, len_ref * sizeof(*start_table)); GVA_Stabbing_Entry* entries = NULL; - ARRAY_APPEND(allocator, entries, ((GVA_Stabbing_Entry) {GVA_NULL, GVA_NULL, GVA_NULL, 0, len_ref})); + ARRAY_APPEND(allocator, entries, ((GVA_Stabbing_Entry) {GVA_NULL, GVA_NULL, GVA_NULL, 0, len_ref, 0, 0, 0})); return (GVA_Stabbing_Index) {len_ref, start_table, entries}; } // gva_stabbing_index_init +void +gva_stabbing_index_destroy(GVA_Allocator const allocator, GVA_Stabbing_Index index[static 1]) +{ + index->entries = ARRAY_DESTROY(allocator, index->entries); + index->start_table = allocator.allocate(allocator.context, index->start_table, index->len_ref * sizeof(*index->start_table), 0); + index->len_ref = 0; +} // gva_stabbing_index_destroy + + inline size_t gva_stabbing_index_add(GVA_Allocator const allocator, GVA_Stabbing_Index index[static 1], - size_t const start, size_t const end) + gva_uint const start, gva_uint const end, gva_uint const inserted, + gva_uint const distance, size_t const data) { - return ARRAY_APPEND(allocator, index->entries, ((GVA_Stabbing_Entry) {GVA_NULL, GVA_NULL, GVA_NULL, start, end})); + return ARRAY_APPEND(allocator, index->entries, ((GVA_Stabbing_Entry) {GVA_NULL, GVA_NULL, GVA_NULL, start, end, inserted, distance, data})); } // gva_stabbing_index_add @@ -58,11 +65,8 @@ gva_stabbing_index_build(GVA_Allocator const allocator, GVA_Stabbing_Index const stack[top] = 0; for (gva_uint i = 0; i < index.len_ref; ++i) { - //fprintf(stderr, "index iteration: %u\n", i); - while (index.entries[stack[top]].end < i) { - //fprintf(stderr, "Popping [%u, %u] from stack\n", index.entries[stack[top]].start, index.entries[stack[top]].end); top -= 1; } // while @@ -71,7 +75,6 @@ gva_stabbing_index_build(GVA_Allocator const allocator, GVA_Stabbing_Index const { do { - //fprintf(stderr, "Pushing [%u, %u] on stack\n", index.entries[idx].start, index.entries[idx].end); top += 1; stack[top] = idx; @@ -88,7 +91,6 @@ gva_stabbing_index_build(GVA_Allocator const allocator, GVA_Stabbing_Index const } while (idx < len && index.entries[idx].start == index.entries[stack[top]].start && index.entries[idx].end == index.entries[stack[top]].end); } /// while - //fprintf(stderr, "start_table[%u] := [%u, %u]\n", i, index.entries[stack[top]].start, index.entries[stack[top]].end); index.start_table[i] = stack[top]; } // for @@ -96,85 +98,24 @@ gva_stabbing_index_build(GVA_Allocator const allocator, GVA_Stabbing_Index const } // gva_stabbing_index_init -void -gva_stabbing_index_destroy(GVA_Allocator const allocator, GVA_Stabbing_Index index[static 1]) -{ - index->entries = ARRAY_DESTROY(allocator, index->entries); - index->start_table = allocator.allocate(allocator.context, index->start_table, index->len_ref * sizeof(*index->start_table), 0); - index->len_ref = 0; -} // gva_stabbing_index_destroy - - gva_uint* gva_stabbing_index_self_intersect(GVA_Allocator const allocator, GVA_Stabbing_Index const index) { gva_uint* results = NULL; - gva_uint* stack = NULL; - - for (gva_uint i = 1; i < array_length(index.entries); ++i) + for (size_t i = 1; i < array_length(index.entries); ++i) { - //fprintf(stderr, "%2u: [%u, %u]\n", i, index.entries[i].start, index.entries[i].end); - if (index.entries[i].rightchild != GVA_NULL) + for (size_t j = i + 1; j < array_length(index.entries); ++j) { - ARRAY_APPEND(allocator, stack, index.entries[i].rightchild); - while (array_length(stack) > 0) + if (index.entries[i].end < index.entries[j].start) { - array_header(stack)->length -= 1; - gva_uint trav = stack[array_length(stack)]; - //fprintf(stderr, " Strav: %2u: [%u, %u]\n", trav, index.entries[trav].start, index.entries[trav].end); - //printf("%2u [%u, %u] %2u [%u, %u]\n", i, index.entries[i].start, index.entries[i].end, trav, index.entries[trav].start, index.entries[trav].end); - ARRAY_APPEND(allocator, results, trav); - - if (index.entries[trav].leftsibling != GVA_NULL) - { - ARRAY_APPEND(allocator, stack, index.entries[trav].leftsibling); - } // if - - if (index.entries[trav].rightchild != GVA_NULL) - { - ARRAY_APPEND(allocator, stack, index.entries[trav].rightchild); - } // if - } // while - } // if - - gva_uint stab = index.entries[i].parent; - while (stab != GVA_NULL) - { - if (index.entries[stab].rightchild != GVA_NULL) + break; + } // if + if (index.entries[j].end >= index.entries[i].start && index.entries[j].start <= index.entries[i].end) { - ARRAY_APPEND(allocator, stack, index.entries[stab].rightchild); - while (array_length(stack) > 0) - { - array_header(stack)->length -= 1; - gva_uint trav = stack[array_length(stack)]; - - //fprintf(stderr, " VISIT: %2u: [%u, %u]\n", trav, index.entries[trav].start, index.entries[trav].end); - - if (trav > i && index.entries[i].end >= index.entries[trav].start) - { - //fprintf(stderr, " Rtrav: %2u: [%u, %u]\n", trav, index.entries[trav].start, index.entries[trav].end); - //printf("%2u [%u, %u] %2u [%u, %u]\n", i, index.entries[i].start, index.entries[i].end, trav, index.entries[trav].start, index.entries[trav].end); - ARRAY_APPEND(allocator, results, trav); - - if (index.entries[trav].rightchild != GVA_NULL) - { - ARRAY_APPEND(allocator, stack, index.entries[trav].rightchild); - } // if - } // if - - if (index.entries[trav].leftsibling != GVA_NULL && index.entries[trav].leftsibling > i) - { - ARRAY_APPEND(allocator, stack, index.entries[trav].leftsibling); - } // if - } // while + ARRAY_APPEND(allocator, results, 0); } // if - - stab = index.entries[stab].parent; - } // while - + } // for } // for - stack = ARRAY_DESTROY(allocator, stack); - return results; } // gva_stabbing_index_self_intersect @@ -187,8 +128,6 @@ gva_stabbing_index_intersect(GVA_Allocator const allocator, GVA_Stabbing_Index c gva_uint* stack = NULL; gva_uint stab = index.start_table[end]; - //fprintf(stderr, "start_table: %2u\n", index.start_table[end]); - if (index.entries[stab].rightchild != GVA_NULL) { ARRAY_APPEND(allocator, stack, index.entries[stab].rightchild); @@ -198,7 +137,6 @@ gva_stabbing_index_intersect(GVA_Allocator const allocator, GVA_Stabbing_Index c gva_uint trav = stack[array_length(stack)]; if (end >= index.entries[trav].start) { - //fprintf(stderr, "Rtrav: %2u: [%2u, %2u]\n", trav, index.entries[trav].start, index.entries[trav].end); ARRAY_APPEND(allocator, results, trav); } // if @@ -218,7 +156,6 @@ gva_stabbing_index_intersect(GVA_Allocator const allocator, GVA_Stabbing_Index c { if (stab > 0) { - //fprintf(stderr, "stab: %2u: [%2u, %2u]\n", stab, index.entries[stab].start, index.entries[stab].end); ARRAY_APPEND(allocator, results, stab); } // if @@ -229,7 +166,6 @@ gva_stabbing_index_intersect(GVA_Allocator const allocator, GVA_Stabbing_Index c { array_header(stack)->length -= 1; gva_uint trav = stack[array_length(stack)]; - //fprintf(stderr, "trav: %2u: [%2u, %2u]\n", trav, index.entries[trav].start, index.entries[trav].end); ARRAY_APPEND(allocator, results, trav); if (index.entries[trav].leftsibling != GVA_NULL && start <= index.entries[index.entries[trav].leftsibling].end) diff --git a/src/string.c b/src/string.c new file mode 100644 index 0000000..c2b8629 --- /dev/null +++ b/src/string.c @@ -0,0 +1,29 @@ +#include // NULL, size_t +#include // memcpy + +#include "../include/allocator.h" // GVA_Allocator +#include "../include/string.h" // GVA_String, gva_string_* + + +inline void +gva_string_destroy(GVA_Allocator const allocator, GVA_String self) +{ + self.len = 0; + self.str = allocator.allocate(allocator.context, (char*) self.str, self.len, 0); +} // gva_string_destroy + + +inline GVA_String +gva_string_concat(GVA_Allocator const allocator, GVA_String lhs, GVA_String const rhs) +{ + size_t const len = lhs.len + rhs.len; + lhs.str = allocator.allocate(allocator.context, (char*) lhs.str, lhs.len, len); + if (lhs.str == NULL) + { + return (GVA_String) {0, NULL}; + } // if + + memcpy((char*) lhs.str + lhs.len, rhs.str, rhs.len); + lhs.len = len; + return lhs; +} // gva_string_concat diff --git a/src/trie.c b/src/trie.c index 45fdd7d..47896dd 100644 --- a/src/trie.c +++ b/src/trie.c @@ -1,18 +1,19 @@ #include // true #include // size_t -#include // memcpy #include "../include/allocator.h" // GVA_Allocator +#include "../include/string.h" // GVA_String, gva_string_* #include "../include/types.h" // GVA_NULL, gva_uint -#include "array.h" // ARRAY_*, array_* +#include "array.h" // ARRAY_* #include "trie.h" // Trie, TrieNode, trie_* inline void trie_destroy(GVA_Allocator const allocator, Trie self[static 1]) { - self->strings = ARRAY_DESTROY(allocator, self->strings); + gva_string_destroy(allocator, self->strings); self->nodes = ARRAY_DESTROY(allocator, self->nodes); + self->root = GVA_NULL; } // trie_destroy @@ -31,25 +32,14 @@ prefix_length(size_t const len_lhs, char const lhs[static restrict len_lhs], } // prefix_length -static inline size_t -concat(GVA_Allocator const allocator, Trie self[static restrict 1], - size_t const len, char const key[static restrict len]) -{ - size_t const start = array_length(self->strings); - self->strings = array_ensure(allocator, self->strings, sizeof(*self->strings), len); - memcpy(self->strings + start, key, len); - array_header(self->strings)->length += len; - return start; -} // concat - - gva_uint trie_insert(GVA_Allocator const allocator, Trie self[static restrict 1], size_t const len, char const key[static restrict len]) { if (self->root == GVA_NULL) { - gva_uint const start = concat(allocator, self, len, key); + gva_uint const start = 0; + self->strings = gva_string_concat(allocator, self->strings, (GVA_String) {len, key}); self->root = ARRAY_APPEND(allocator, self->nodes, ((TrieNode) {GVA_NULL, GVA_NULL, start, start, len})) - 1; return self->root; } // if @@ -60,7 +50,7 @@ trie_insert(GVA_Allocator const allocator, Trie self[static restrict 1], while (true) { gva_uint const p_len = self->nodes[idx].end - self->nodes[idx].p_start; - size_t const k = prefix_length(len - prefix, key + prefix, p_len, self->strings + self->nodes[idx].p_start); + size_t const k = prefix_length(len - prefix, key + prefix, p_len, self->strings.str + self->nodes[idx].p_start); if (k == len - prefix && k == p_len) { return idx; // existing found @@ -70,8 +60,9 @@ trie_insert(GVA_Allocator const allocator, Trie self[static restrict 1], { if (self->nodes[idx].next == GVA_NULL) { - gva_uint const start = concat(allocator, self, len, key); - gva_uint const end = array_length(self->strings); + gva_uint const start = self->strings.len; + self->strings = gva_string_concat(allocator, self->strings, (GVA_String) {len, key}); + gva_uint const end = self->strings.len; gva_uint const next = ARRAY_APPEND(allocator, self->nodes, ((TrieNode) {GVA_NULL, GVA_NULL, start + prefix, start, end})) - 1; self->nodes[idx].next = next; return next; @@ -84,8 +75,9 @@ trie_insert(GVA_Allocator const allocator, Trie self[static restrict 1], prefix += k; if (self->nodes[idx].link == GVA_NULL) { - gva_uint const start = concat(allocator, self, len, key); - gva_uint const end = array_length(self->strings); + gva_uint const start = self->strings.len; + self->strings = gva_string_concat(allocator, self->strings, (GVA_String) {len, key}); + gva_uint const end = self->strings.len; gva_uint const link = ARRAY_APPEND(allocator, self->nodes, ((TrieNode) {GVA_NULL, GVA_NULL, start + prefix, start, end})) - 1; self->nodes[idx].link = link; return link; @@ -99,8 +91,9 @@ trie_insert(GVA_Allocator const allocator, Trie self[static restrict 1], gva_uint next = GVA_NULL; if (prefix < len) { - gva_uint const start = concat(allocator, self, len, key); - gva_uint const end = array_length(self->strings); + gva_uint const start = self->strings.len; + self->strings = gva_string_concat(allocator, self->strings, (GVA_String) {len, key}); + gva_uint const end = self->strings.len; next = ARRAY_APPEND(allocator, self->nodes, ((TrieNode) {GVA_NULL, GVA_NULL, start + prefix, start, end})) - 1; } // if gva_uint const link = ARRAY_APPEND(allocator, self->nodes, ((TrieNode) {idx, self->nodes[idx].next, self->nodes[idx].p_start, self->nodes[idx].start, self->nodes[idx].p_start + k})) - 1; @@ -128,4 +121,4 @@ trie_insert(GVA_Allocator const allocator, Trie self[static restrict 1], return link; } // else } // while -} // trie_insert \ No newline at end of file +} // trie_insert diff --git a/src/trie.h b/src/trie.h index 3c2b5ce..107ebd6 100644 --- a/src/trie.h +++ b/src/trie.h @@ -5,6 +5,7 @@ #include // size_t #include "../include/allocator.h" // GVA_Allocator +#include "../include/string.h" // GVA_String #include "../include/types.h" // gva_uint @@ -20,19 +21,19 @@ typedef struct typedef struct { - char* strings; - TrieNode* nodes; - gva_uint root; + GVA_String strings; + TrieNode* nodes; + gva_uint root; } Trie; +void +trie_destroy(GVA_Allocator const allocator, Trie self[static 1]); + + gva_uint trie_insert(GVA_Allocator const allocator, Trie self[static restrict 1], size_t const len, char const key[static restrict len]); -void -trie_destroy(GVA_Allocator const allocator, Trie self[static 1]); - - #endif // GVA_TRIE_H diff --git a/src/utils.c b/src/utils.c index 296c064..d3b8c93 100644 --- a/src/utils.c +++ b/src/utils.c @@ -3,14 +3,13 @@ #include // FILE, fgets #include // strcspn - #include "../include/allocator.h" // GVA_Allocator -#include "../include/types.h" // GVA_String +#include "../include/string.h" // GVA_String #include "../include/utils.h" // gva_fasta_sequence GVA_String -gva_fasta_sequence(GVA_Allocator const allocator, FILE* const restrict stream) +gva_fasta_sequence(GVA_Allocator const allocator, FILE* const stream) { static size_t const FASTA_LINE_SIZE = 65536; size_t capacity = FASTA_LINE_SIZE; diff --git a/src/variant.c b/src/variant.c index 1a69808..e180121 100644 --- a/src/variant.c +++ b/src/variant.c @@ -1,11 +1,12 @@ #include // bool #include // NULL, size_t -#include // memcpy - +#include // memcmp #include "../include/allocator.h" // GVA_Allocator -#include "../include/types.h" // gva_uint, GVA_String +#include "../include/types.h" // gva_uint +#include "../include/string.h" // GVA_String, gva_string_concat #include "../include/variant.h" // gva_parse_spdi, gva_patch +#include "common.h" // MIN static inline bool @@ -60,23 +61,6 @@ match_until(size_t const len, char const expression[static len], char const deli } // match_until -static inline GVA_String -concat(GVA_Allocator const allocator, - GVA_String lhs, GVA_String const rhs) -{ - size_t const len = lhs.len + rhs.len; - lhs.str = allocator.allocate(allocator.context, lhs.str, lhs.len, len); - if (lhs.str == NULL) - { - return (GVA_String) {0, NULL}; - } // if - - memcpy((char*) lhs.str + lhs.len, rhs.str, rhs.len); - lhs.len = len; - return lhs; -} // concat - - size_t gva_parse_spdi(size_t const len, char const expression[static restrict len], GVA_Variant variants[static restrict 1]) @@ -127,6 +111,15 @@ gva_parse_spdi(size_t const len, char const expression[static restrict len], } // gva_parse_spdi +inline bool +gva_variant_eq(GVA_Variant const lhs, GVA_Variant const rhs) +{ + return lhs.start == rhs.start && lhs.end == rhs.end && + lhs.sequence.len == rhs.sequence.len && + memcmp(lhs.sequence.str, rhs.sequence.str, MIN(lhs.sequence.len, rhs.sequence.len)) == 0; +} // gva_variant_eq + + inline size_t gva_variant_length(GVA_Variant const variant) { @@ -143,14 +136,14 @@ gva_patch(GVA_Allocator const allocator, size_t start = 0; for (size_t i = 0; i < n; ++i) { - observed = concat(allocator, observed, (GVA_String) {variants[i].start - start, reference + start}); - observed = concat(allocator, observed, variants[i].sequence); + observed = gva_string_concat(allocator, observed, (GVA_String) {variants[i].start - start, reference + start}); + observed = gva_string_concat(allocator, observed, variants[i].sequence); start = variants[i].end; } // for if (start < len_ref) { - observed = concat(allocator, observed, (GVA_String) {len_ref - start, reference + start}); + observed = gva_string_concat(allocator, observed, (GVA_String) {len_ref - start, reference + start}); } // if return observed; From 0feef42396d5f4b9915241287eb640fbd6344950 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 29 Jul 2025 16:36:35 +0200 Subject: [PATCH 301/704] Clean up --- include/lcs_graph.h | 11 ++++---- src/lcs_graph.c | 66 ++++++++++++++++++++++----------------------- src/main.c | 2 +- 3 files changed, 40 insertions(+), 39 deletions(-) diff --git a/include/lcs_graph.h b/include/lcs_graph.h index dc3871f..1d27cf6 100644 --- a/include/lcs_graph.h +++ b/include/lcs_graph.h @@ -6,7 +6,8 @@ #include // size_t #include "allocator.h" // GVA_Allocator -#include "types.h" // GVA_String, gva_uint +#include "string.h" // GVA_String +#include "types.h" // gva_uint #include "variant.h" // GVA_Variant @@ -55,16 +56,16 @@ gva_lcs_graph_init(GVA_Allocator const allocator, size_t const shift); +void +gva_lcs_graph_destroy(GVA_Allocator const allocator, GVA_LCS_Graph self); + + GVA_LCS_Graph gva_lcs_graph_from_variant(GVA_Allocator const allocator, size_t const len_ref, char const reference[static len_ref], GVA_Variant const variant); -void -gva_lcs_graph_destroy(GVA_Allocator const allocator, GVA_LCS_Graph self); - - gva_uint gva_edges(char const observed[static restrict 1], GVA_Node const head, GVA_Node const tail, diff --git a/src/lcs_graph.c b/src/lcs_graph.c index 6830e9a..290c6c3 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -11,32 +11,6 @@ #include "common.h" // GVA_NULL, gva_uint, MAX, MIN -gva_uint -gva_edges(char const observed[static restrict 1], - GVA_Node const head, GVA_Node const tail, - bool const is_source, bool const is_sink, - GVA_Variant variant[static restrict 1]) -{ - intmax_t const row = (intmax_t) head.row - is_source; - intmax_t const col = (intmax_t) head.col - is_source; - gva_uint const head_length = head.length + is_source; - gva_uint const tail_length = tail.length + is_sink; - - intmax_t const offset = MIN((intmax_t) tail.row - row, (intmax_t) tail.col - col) - 1; - - gva_uint const head_offset = offset > 0 ? MIN(head_length, offset + 1) : 1; - gva_uint const tail_offset = offset < 0 ? MIN(tail_length, -offset) : 0; - - *variant = (GVA_Variant) { - row + head_offset, tail.row + tail_offset, { - (tail.col + tail_offset) - (col + head_offset), - observed + col + head_offset - } - }; - return MIN(head_length - head_offset, tail_length - tail_offset - 1) + 1; -} // gva_edges - - GVA_LCS_Graph gva_lcs_graph_init(GVA_Allocator const allocator, size_t const len_ref, char const reference[static restrict len_ref], @@ -290,6 +264,16 @@ gva_lcs_graph_init(GVA_Allocator const allocator, } // gva_lcs_graph_init +inline void +gva_lcs_graph_destroy(GVA_Allocator const allocator, GVA_LCS_Graph self) +{ + self.nodes = ARRAY_DESTROY(allocator, self.nodes); + self.edges = ARRAY_DESTROY(allocator, self.edges); + self.local_supremal = ARRAY_DESTROY(allocator, self.local_supremal); + // FIXME: ownership of observed +} // gva_lcs_graph_destroy + + GVA_LCS_Graph gva_lcs_graph_from_variant(GVA_Allocator const allocator, size_t const len_ref, char const reference[static len_ref], @@ -332,11 +316,27 @@ gva_lcs_graph_from_variant(GVA_Allocator const allocator, } // gva_lcs_graph_from_variant -inline void -gva_lcs_graph_destroy(GVA_Allocator const allocator, GVA_LCS_Graph self) +gva_uint +gva_edges(char const observed[static restrict 1], + GVA_Node const head, GVA_Node const tail, + bool const is_source, bool const is_sink, + GVA_Variant variant[static restrict 1]) { - self.nodes = ARRAY_DESTROY(allocator, self.nodes); - self.edges = ARRAY_DESTROY(allocator, self.edges); - self.local_supremal = ARRAY_DESTROY(allocator, self.local_supremal); - // FIXME: ownership of observed -} // gva_lcs_graph_destroy + intmax_t const row = (intmax_t) head.row - is_source; + intmax_t const col = (intmax_t) head.col - is_source; + gva_uint const head_length = head.length + is_source; + gva_uint const tail_length = tail.length + is_sink; + + intmax_t const offset = MIN((intmax_t) tail.row - row, (intmax_t) tail.col - col) - 1; + + gva_uint const head_offset = offset > 0 ? MIN(head_length, offset + 1) : 1; + gva_uint const tail_offset = offset < 0 ? MIN(tail_length, -offset) : 0; + + *variant = (GVA_Variant) { + row + head_offset, tail.row + tail_offset, { + (tail.col + tail_offset) - (col + head_offset), + observed + col + head_offset + } + }; + return MIN(head_length - head_offset, tail_length - tail_offset - 1) + 1; +} // gva_edges diff --git a/src/main.c b/src/main.c index 41b54fc..ddb8d9e 100644 --- a/src/main.c +++ b/src/main.c @@ -12,7 +12,7 @@ #include "../include/lcs_graph.h" // GVA_LCS_Graph, GVA_Variant, gva_lcs_graph_*, gva_edges #include "../include/stabbing.h" // GVA_Stabbing_*, gva_stabbing_* #include "../include/std_alloc.h" // gva_std_allocator -#include "../include/string.h" // gva_string_destroy +#include "../include/string.h" // GVA_String, gva_string_destroy #include "../include/types.h" // GVA_NULL, gva_uint #include "../include/utils.h" // gva_fasta_sequence #include "../include/variant.h" // GVA_VARIANT_*, GVA_Variant, gva_parse_spdi From dc05b89ff6ecf25172e8422f8ea133d35a268a77 Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 30 Jul 2025 15:07:29 +0200 Subject: [PATCH 302/704] Normalize containment --- src/main.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/main.c b/src/main.c index ddb8d9e..3468fea 100644 --- a/src/main.c +++ b/src/main.c @@ -422,22 +422,32 @@ bitset_print(size_t const bitset[static 1], size_t const size) static inline int entry_cmp(void const* lhs, void const* rhs) { - GVA_Stabbing_Entry const* const lhs_interval = lhs; - GVA_Stabbing_Entry const* const rhs_interval = rhs; + GVA_Stabbing_Entry const* const lhs_entry = lhs; + GVA_Stabbing_Entry const* const rhs_entry = rhs; - if (lhs_interval->start < rhs_interval->start) + if (lhs_entry->start < rhs_entry->start) { return -1; } // if - if (lhs_interval->start > rhs_interval->start) + if (lhs_entry->start > rhs_entry->start) { return 1; } // if - if (lhs_interval->end > rhs_interval->end) + /* + if (lhs_entry->end > rhs_entry->end) + { + return -1; + } // if + if (lhs_entry->end < rhs_entry->end) + { + return 1; + } // if + */ + if (lhs_entry->distance > rhs_entry->distance) { return -1; } // if - if (lhs_interval->end < rhs_interval->end) + if (lhs_entry->distance < rhs_entry->distance) { return 1; } // if @@ -585,12 +595,6 @@ all(int argc, char* argv[static argc + 1]) continue; } // if - if (index.entries[j].distance - index.entries[i].distance == distance) - { - printf("%zu " GVA_VARIANT_FMT_SPDI " %zu " GVA_VARIANT_FMT_SPDI " is_contained\n", index.entries[i].data, GVA_VARIANT_PRINT_SPDI("NC_000001.11", lhs), index.entries[j].data, GVA_VARIANT_PRINT_SPDI("NC_000001.11", rhs)); - continue; - } // if - if (lhs_graph.nodes == NULL) { lhs_graph = gva_lcs_graph_init(gva_std_allocator, lhs.end - lhs.start, reference.str + lhs.start, lhs.sequence.len, lhs.sequence.str, lhs.start); From eb20553ccec49fbcc4f69c39f583f92110d41474 Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 30 Jul 2025 16:08:20 +0200 Subject: [PATCH 303/704] Clean up --- src/main.c | 34 +++++++++++++--------------------- 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/src/main.c b/src/main.c index 3468fea..baa6763 100644 --- a/src/main.c +++ b/src/main.c @@ -433,7 +433,7 @@ entry_cmp(void const* lhs, void const* rhs) { return 1; } // if - /* + /* // FIXME: breaks faststabber order if (lhs_entry->end > rhs_entry->end) { return -1; @@ -554,29 +554,21 @@ all(int argc, char* argv[static argc + 1]) size_t const end = MAX(lhs.end, rhs.end); size_t const lhs_len = (lhs.start - start) + lhs.sequence.len + (end - lhs.end); - char* lhs_obs = NULL; - if (lhs_len > 0) + char* lhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, NULL, 0, lhs_len); + if (lhs_obs != NULL) { - lhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, NULL, 0, lhs_len); - if (lhs_obs != NULL) - { - memcpy(lhs_obs, reference.str + start, lhs.start - start); - memcpy(lhs_obs + lhs.start - start, lhs.sequence.str, lhs.sequence.len); - memcpy(lhs_obs + lhs.start - start + lhs.sequence.len, reference.str + lhs.end, end - lhs.end); - } // if + memcpy(lhs_obs, reference.str + start, lhs.start - start); + memcpy(lhs_obs + lhs.start - start, lhs.sequence.str, lhs.sequence.len); + memcpy(lhs_obs + lhs.start - start + lhs.sequence.len, reference.str + lhs.end, end - lhs.end); } // if size_t const rhs_len = (rhs.start - start) + rhs.sequence.len + (end - rhs.end); - char* rhs_obs = NULL; - if (rhs_len > 0) + char* rhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, NULL, 0, rhs_len); + if (rhs_obs != NULL) { - rhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, NULL, 0, rhs_len); - if (rhs_obs != NULL) - { - memcpy(rhs_obs, reference.str + start, rhs.start - start); - memcpy(rhs_obs + rhs.start - start, rhs.sequence.str, rhs.sequence.len); - memcpy(rhs_obs + rhs.start - start + rhs.sequence.len, reference.str + rhs.end, end - rhs.end); - } // if + memcpy(rhs_obs, reference.str + start, rhs.start - start); + memcpy(rhs_obs + rhs.start - start, rhs.sequence.str, rhs.sequence.len); + memcpy(rhs_obs + rhs.start - start + rhs.sequence.len, reference.str + rhs.end, end - rhs.end); } // if size_t const distance = gva_edit_distance(gva_std_allocator, lhs_len, lhs_obs, rhs_len, rhs_obs); @@ -599,7 +591,7 @@ all(int argc, char* argv[static argc + 1]) { lhs_graph = gva_lcs_graph_init(gva_std_allocator, lhs.end - lhs.start, reference.str + lhs.start, lhs.sequence.len, lhs.sequence.str, lhs.start); size_t const len = lhs.end - lhs.start + 1; - lhs_dels = bitset_init(gva_std_allocator, len); // can be one shorter + lhs_dels = bitset_init(gva_std_allocator, len); // can be one shorter lhs_as = bitset_init(gva_std_allocator, len); lhs_cs = bitset_init(gva_std_allocator, len); lhs_gs = bitset_init(gva_std_allocator, len); @@ -609,7 +601,7 @@ all(int argc, char* argv[static argc + 1]) GVA_LCS_Graph rhs_graph = gva_lcs_graph_init(gva_std_allocator, rhs.end - rhs.start, reference.str + rhs.start, rhs.sequence.len, rhs.sequence.str, rhs.start); size_t const len = rhs.end - lhs.start + 1; - size_t* rhs_dels = bitset_init(gva_std_allocator, len); // can be one shorter + size_t* rhs_dels = bitset_init(gva_std_allocator, len); // can be one shorter size_t* rhs_as = bitset_init(gva_std_allocator, len); size_t* rhs_cs = bitset_init(gva_std_allocator, len); size_t* rhs_gs = bitset_init(gva_std_allocator, len); From 471931602e9293d539f300e7107358d654c4be74 Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 4 Aug 2025 13:08:57 +0200 Subject: [PATCH 304/704] Guard memcpy --- src/main.c | 41 ++++++++++++++++++++++++++++------------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/src/main.c b/src/main.c index baa6763..12a8ad4 100644 --- a/src/main.c +++ b/src/main.c @@ -494,7 +494,7 @@ all(int argc, char* argv[static argc + 1]) GVA_Variant variant; if (gva_parse_spdi(len, line + idx, &variant) == 0) { - fprintf(stderr, "error: SPDI parsing failed at line %zu: %s\n", count + 1, line); + fprintf(stderr, "error: SPDI parsing failed at line %zu: %s", count + 1, line); continue; } // if @@ -554,27 +554,42 @@ all(int argc, char* argv[static argc + 1]) size_t const end = MAX(lhs.end, rhs.end); size_t const lhs_len = (lhs.start - start) + lhs.sequence.len + (end - lhs.end); - char* lhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, NULL, 0, lhs_len); - if (lhs_obs != NULL) + size_t const rhs_len = (rhs.start - start) + rhs.sequence.len + (end - rhs.end); + + size_t distance = 0; + if (lhs_len == 0) + { + distance = rhs_len; + } // if + else if (rhs_len == 0) { + distance = lhs_len; + } // if + else + { + char* lhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, NULL, 0, lhs_len); + if (lhs_obs == NULL) + { + continue; + } // if memcpy(lhs_obs, reference.str + start, lhs.start - start); memcpy(lhs_obs + lhs.start - start, lhs.sequence.str, lhs.sequence.len); memcpy(lhs_obs + lhs.start - start + lhs.sequence.len, reference.str + lhs.end, end - lhs.end); - } // if - size_t const rhs_len = (rhs.start - start) + rhs.sequence.len + (end - rhs.end); - char* rhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, NULL, 0, rhs_len); - if (rhs_obs != NULL) - { + char* rhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, NULL, 0, rhs_len); + if (rhs_obs == NULL) + { + lhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, lhs_obs, lhs_len, 0); + continue; + } // if memcpy(rhs_obs, reference.str + start, rhs.start - start); memcpy(rhs_obs + rhs.start - start, rhs.sequence.str, rhs.sequence.len); memcpy(rhs_obs + rhs.start - start + rhs.sequence.len, reference.str + rhs.end, end - rhs.end); - } // if - - size_t const distance = gva_edit_distance(gva_std_allocator, lhs_len, lhs_obs, rhs_len, rhs_obs); - rhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, rhs_obs, rhs_len, 0); - lhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, lhs_obs, lhs_len, 0); + distance = gva_edit_distance(gva_std_allocator, lhs_len, lhs_obs, rhs_len, rhs_obs); + rhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, rhs_obs, rhs_len, 0); + lhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, lhs_obs, lhs_len, 0); + } // else if (index.entries[i].distance + index.entries[j].distance == distance) { From e5503a20e80bf79abe96d5deb2fa92dc88b524be Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 7 Aug 2025 10:30:44 +0200 Subject: [PATCH 305/704] WIP: started on Python bindings --- include/utils.h | 5 ++ python/.gitignore | 4 ++ python/algebra/__init__.py | 11 +++ python/algebra/lcs/__init__.py | 9 +++ python/algebra/variants/__init__.py | 9 +++ python/ext/algebra_ext.c | 47 +++++++++++++ python/ext/lcsgraph.c | 103 ++++++++++++++++++++++++++++ python/ext/lcsgraph.h | 33 +++++++++ python/ext/variant.c | 49 +++++++++++++ python/ext/variant.h | 29 ++++++++ python/include | 1 + python/sandbox.py | 10 +++ python/setup.cfg | 25 +++++++ python/setup.py | 23 +++++++ python/src | 1 + src/utils.c | 30 ++++++++ 16 files changed, 389 insertions(+) create mode 100644 python/.gitignore create mode 100644 python/algebra/__init__.py create mode 100644 python/algebra/lcs/__init__.py create mode 100644 python/algebra/variants/__init__.py create mode 100644 python/ext/algebra_ext.c create mode 100644 python/ext/lcsgraph.c create mode 100644 python/ext/lcsgraph.h create mode 100644 python/ext/variant.c create mode 100644 python/ext/variant.h create mode 120000 python/include create mode 100644 python/sandbox.py create mode 100644 python/setup.cfg create mode 100644 python/setup.py create mode 120000 python/src diff --git a/include/utils.h b/include/utils.h index 8b6d05c..d355c15 100644 --- a/include/utils.h +++ b/include/utils.h @@ -19,4 +19,9 @@ GVA_String gva_fasta_sequence(GVA_Allocator const allocator, FILE* const stream); +GVA_String +gva_random_sequence(GVA_Allocator const allocator, + size_t const min_length, size_t const max_length); + + #endif // GVA_UTILS_H diff --git a/python/.gitignore b/python/.gitignore new file mode 100644 index 0000000..b0a3e26 --- /dev/null +++ b/python/.gitignore @@ -0,0 +1,4 @@ +build/ +*.egg-info/ +venv/ +**/__pycache__/ diff --git a/python/algebra/__init__.py b/python/algebra/__init__.py new file mode 100644 index 0000000..ecdc5e3 --- /dev/null +++ b/python/algebra/__init__.py @@ -0,0 +1,11 @@ +"""A Boolean Algebra for Genetic Variants.""" + + +from .lcs import LCSgraph +from .variants import Variant + + +__all__ = [ + "LCSgraph", + "Variant", +] diff --git a/python/algebra/lcs/__init__.py b/python/algebra/lcs/__init__.py new file mode 100644 index 0000000..65920fd --- /dev/null +++ b/python/algebra/lcs/__init__.py @@ -0,0 +1,9 @@ +"""Longest Common Subsequence (LCS) alignments.""" + + +from algebra_ext import LCSgraph + + +__all__ = [ + "LCSgraph", +] diff --git a/python/algebra/variants/__init__.py b/python/algebra/variants/__init__.py new file mode 100644 index 0000000..29508b6 --- /dev/null +++ b/python/algebra/variants/__init__.py @@ -0,0 +1,9 @@ +"""Variant model.""" + + +from algebra_ext import Variant + + +__all__ = [ + "Variant", +] diff --git a/python/ext/algebra_ext.c b/python/ext/algebra_ext.c new file mode 100644 index 0000000..2c0e270 --- /dev/null +++ b/python/ext/algebra_ext.c @@ -0,0 +1,47 @@ +#define PY_SSIZE_T_CLEAN +#include // Py* + +#include // NULL, size_t + +#include "lcsgraph.h" // LCSgraph, LCSgraph_* +#include "variant.h" // Variant, Variant_* + + +static PyModuleDef algebra_ext_module = +{ + PyModuleDef_HEAD_INIT, + .m_name = "algebra_ext", + .m_doc = PyDoc_STR("Algebra C extension"), + .m_size = -1, +}; + + +PyMODINIT_FUNC +PyInit_algebra_ext(void) +{ + PyObject* const module = PyModule_Create(&algebra_ext_module); + if (module == NULL) + { + return NULL; + } // if + + if (PyType_Ready(&LCSgraph_Type) < 0) + { + return NULL; + } // if + if (PyType_Ready(&Variant_Type) < 0) + { + return NULL; + } // if + + if (PyModule_AddObjectRef(module, "LCSgraph", (PyObject*) &LCSgraph_Type) < 0) + { + return NULL; + } // if + if (PyModule_AddObjectRef(module, "Variant", (PyObject*) &Variant_Type) < 0) + { + return NULL; + } // if + + return module; +} // PyInit_algebra_ext diff --git a/python/ext/lcsgraph.c b/python/ext/lcsgraph.c new file mode 100644 index 0000000..d31bffb --- /dev/null +++ b/python/ext/lcsgraph.c @@ -0,0 +1,103 @@ +#define PY_SSIZE_T_CLEAN +#include // Py* + +#include // NULL + +#include "lcsgraph.h" // LCSgraph, LCSgraph_* +#include "variant.h" // Variant, Variant_* + +#include "../include/lcs_graph.h" // GVA_LCS_Graph, gva_lcs_graph_from_variant +#include "../include/std_alloc.h" // gva_std_allocator + + +PyObject* +LCSgraph_new(PyTypeObject* type, PyObject* args, PyObject* kwargs) +{ + (void) args; + (void) kwargs; + + LCSgraph* const self = (LCSgraph*) type->tp_alloc(type, 0); + if (self == NULL) + { + return NULL; + } // if + + self->graph = (GVA_LCS_Graph) {0}; + return (PyObject*) self; +} // LCSgraph_new + + +inline void +LCSgraph_dealloc(LCSgraph* self) +{ + gva_lcs_graph_destroy(gva_std_allocator, self->graph); + Py_TYPE(self)->tp_free((PyObject*) self); +} // LCSgraph_dealloc + + +PyObject* +LCSgraph_from_variants(PyObject* cls, PyObject* args, PyObject* kwargs) +{ + char const* reference = NULL; + Py_ssize_t len_ref = 0; + PyObject* variant_list = NULL; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#O!|:from_variants", + (char* []) {"reference", "variants", NULL}, + &reference, &len_ref, &PyList_Type, &variant_list)) + { + return NULL; + } // if + + + GVA_Variant* variants = gva_std_allocator.allocate(gva_std_allocator.context, NULL, 0, PyList_GET_SIZE(variant_list) * sizeof(*variants)); + if (variants == NULL) + { + PyErr_SetString(PyExc_MemoryError, "OOM"); + return NULL; + } // if + + for (Py_ssize_t i = 0; i < PyList_GET_SIZE(variant_list); ++i) + { + Variant* item = NULL; + if (!PyArg_Parse(PyList_GET_ITEM(variant_list, i), "O!", &Variant_Type, &item)) + { + variants = gva_std_allocator.allocate(gva_std_allocator.context, variants, PyList_GET_SIZE(variant_list) * sizeof(*variants), 0); + return NULL; + } // if + } // for + + LCSgraph* self = (LCSgraph*) PyObject_CallNoArgs(cls); + if (self == NULL) + { + variants = gva_std_allocator.allocate(gva_std_allocator.context, variants, PyList_GET_SIZE(variant_list) * sizeof(*variants), 0); + return NULL; + } // if + + self->graph = gva_lcs_graph_from_variant(gva_std_allocator, len_ref, reference, variants[0]); + + PySys_FormatStderr("supremal: " GVA_VARIANT_FMT_SPDI "\n", GVA_VARIANT_PRINT_SPDI("reference", self->graph.supremal)); + + variants = gva_std_allocator.allocate(gva_std_allocator.context, variants, PyList_GET_SIZE(variant_list) * sizeof(*variants), 0); + return (PyObject*) self; +} // LCSgraph_from_variants + + +PyTypeObject LCSgraph_Type = +{ + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name = "algebra_ext.LCSgraph", + .tp_basicsize = sizeof(LCSgraph), + .tp_doc = PyDoc_STR("LCS graph class for storing all minimal alignments."), + .tp_new = LCSgraph_new, + .tp_dealloc = (destructor) LCSgraph_dealloc, + .tp_methods = (PyMethodDef[]) + { + { + "from_variants", + (PyCFunction) LCSgraph_from_variants, + METH_CLASS | METH_VARARGS | METH_KEYWORDS, + PyDoc_STR("Iteratively find the supremal LCS graph for an allele by repeatedly widening a range of influence."), + }, + {NULL} // sentinel + }, +}; diff --git a/python/ext/lcsgraph.h b/python/ext/lcsgraph.h new file mode 100644 index 0000000..e75a088 --- /dev/null +++ b/python/ext/lcsgraph.h @@ -0,0 +1,33 @@ +#ifndef EXT_LCSGRAPH_H +#define EXT_LCSGRAPH_H + + +#define PY_SSIZE_T_CLEAN +#include // Py* + +#include "../include/lcs_graph.h" // GVA_LCS_Graph + + +typedef struct +{ + PyObject_HEAD + GVA_LCS_Graph graph; +} LCSgraph; + + +PyObject* +LCSgraph_new(PyTypeObject* type, PyObject* args, PyObject* kwargs); + + +void +LCSgraph_dealloc(LCSgraph* self); + + +PyObject* +LCSgraph_from_variants(PyObject* cls, PyObject* args, PyObject* kwargs); + + +extern PyTypeObject LCSgraph_Type; + + +#endif // EXT_LCSGRAPH_H diff --git a/python/ext/variant.c b/python/ext/variant.c new file mode 100644 index 0000000..e41c0c1 --- /dev/null +++ b/python/ext/variant.c @@ -0,0 +1,49 @@ +#define PY_SSIZE_T_CLEAN +#include // Py* + +#include // NULL + +#include "variant.h" // Variant, Varaint_* + + +PyObject* +Variant_new(PyTypeObject* type, PyObject* args, PyObject* kwargs) +{ + Py_ssize_t start = 0; + Py_ssize_t end = 0; + char const* sequence = NULL; + Py_ssize_t len = 0; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "nns#:Variant", + (char* []) {"start", "end", "sequence", NULL}, + &start, &end, &sequence, &len)) + { + return NULL; + } // if + + Variant* const self = (Variant*) type->tp_alloc(type, 0); + if (self == NULL) + { + return NULL; + } // if + + self->variant = (GVA_Variant) {start, end, {len, sequence}}; + return (PyObject*) self; +} // Variant_new + + +inline void +Variant_dealloc(Variant* self) +{ + Py_TYPE(self)->tp_free((PyObject*) self); +} // Variant_dealloc + + +PyTypeObject Variant_Type = +{ + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name = "algebra_ext.Variant", + .tp_basicsize = sizeof(Variant), + .tp_doc = PyDoc_STR("Variant class for deletion/insertions."), + .tp_new = Variant_new, + .tp_dealloc = (destructor) Variant_dealloc, +}; diff --git a/python/ext/variant.h b/python/ext/variant.h new file mode 100644 index 0000000..fe9dbda --- /dev/null +++ b/python/ext/variant.h @@ -0,0 +1,29 @@ +#ifndef EXT_VARIANT_H +#define EXT_VARIANT_H + + +#define PY_SSIZE_T_CLEAN +#include // Py* + +#include "../include/variant.h" // GVA_Variant + + +typedef struct +{ + PyObject_HEAD + GVA_Variant variant; +} Variant; + + +PyObject* +Variant_new(PyTypeObject* type, PyObject* args, PyObject* kwargs); + + +void +Variant_dealloc(Variant* self); + + +extern PyTypeObject Variant_Type; + + +#endif // EXT_VARIANT_H diff --git a/python/include b/python/include new file mode 120000 index 0000000..f5030fe --- /dev/null +++ b/python/include @@ -0,0 +1 @@ +../include \ No newline at end of file diff --git a/python/sandbox.py b/python/sandbox.py new file mode 100644 index 0000000..317e3aa --- /dev/null +++ b/python/sandbox.py @@ -0,0 +1,10 @@ +from algebra import LCSgraph, Variant + + +def main(): + graph = LCSgraph.from_variants("AAAAAAA", [Variant(1, 1, "XXX")]) + print(graph) + + +if __name__ == "__main__": + main() diff --git a/python/setup.cfg b/python/setup.cfg new file mode 100644 index 0000000..762f2e0 --- /dev/null +++ b/python/setup.cfg @@ -0,0 +1,25 @@ +[metadata] +name = mutalyzer-algebra +version = 2.0.0 +description = A Boolean Algebra for Genetic Variants +long_description = file: README.md +long_description_content_type = text/markdown +author = Mark A. Santcroos, Jonathan K. Vis +author_email = m.a.santcroos@lumc.nl, j.k.vis@lumc.nl +url = https://github.com/mutalyzer/algebra +keywords = algebra, genomics, graph, string, genetics, edit-distance, alignment, compare, sequence, variants, lcs, relations, hgvs, extractor +license = MIT +classifiers = + Intended Audience :: Science/Research + Intended Audience :: Developers + Operating System :: OS Independent + Programming Language :: Python :: 3 + Topic :: Scientific/Engineering :: Bio-Informatics + +[options] +packages = find: + +[options.packages.find] +include = + algebra + algebra.* \ No newline at end of file diff --git a/python/setup.py b/python/setup.py new file mode 100644 index 0000000..985f0c8 --- /dev/null +++ b/python/setup.py @@ -0,0 +1,23 @@ +from setuptools import Extension, setup + + +setup( + ext_modules = [ + Extension("algebra_ext", + extra_compile_args=[ + "-Wextra", + "-Wpedantic", + "-std=c99", + ], + sources=[ + "ext/algebra_ext.c", + "ext/lcsgraph.c", + "ext/variant.c", + "../src/align.c", + "../src/array.c", + "../src/lcs_graph.c", + "../src/string.c", + "../src/variant.c", + ]), + ], +) diff --git a/python/src b/python/src new file mode 120000 index 0000000..5cd551c --- /dev/null +++ b/python/src @@ -0,0 +1 @@ +../src \ No newline at end of file diff --git a/src/utils.c b/src/utils.c index d3b8c93..4aca1cb 100644 --- a/src/utils.c +++ b/src/utils.c @@ -1,5 +1,6 @@ // NOT FREESTANDING #include // NULL, size_t +#include // rand #include // FILE, fgets #include // strcspn @@ -45,3 +46,32 @@ gva_fasta_sequence(GVA_Allocator const allocator, FILE* const stream) seq.str = allocator.allocate(allocator.context, (char*) seq.str, capacity, seq.len); return seq; } // gva_fasta_sequence + + +static inline void +random_sequence(size_t const len, char sequence[static len]) +{ + for (size_t i = 0; i < len; ++i) + { + sequence[i] = "AC"[rand() % 2]; + } // for +} // random_sequence + + +GVA_String +gva_random_sequence(GVA_Allocator const allocator, size_t const min_length, size_t const max_length) +{ + if (max_length < min_length) + { + return (GVA_String) {0, NULL}; + } // if + + size_t const len = rand() % (max_length - min_length + 1) + min_length; + GVA_String sequence = {len, allocator.allocate(allocator.context, NULL, 0, len)}; + if (sequence.str == NULL) + { + return (GVA_String) {0, NULL}; + } // if + random_sequence(len, (char*) sequence.str); + return sequence; +} // gva_random_sequence From 6e70126e0fa888d3e48acfa819e0cf4e9d091481 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 7 Aug 2025 11:09:16 +0200 Subject: [PATCH 306/704] WIP: LCSgraph from alleles --- include/lcs_graph.h | 6 +++--- include/variant.h | 3 ++- python/ext/lcsgraph.c | 7 ++++--- src/lcs_graph.c | 24 +++++++++++++++++------- src/main.c | 2 +- src/variant.c | 7 ++++--- 6 files changed, 31 insertions(+), 18 deletions(-) diff --git a/include/lcs_graph.h b/include/lcs_graph.h index 1d27cf6..dfd8759 100644 --- a/include/lcs_graph.h +++ b/include/lcs_graph.h @@ -61,9 +61,9 @@ gva_lcs_graph_destroy(GVA_Allocator const allocator, GVA_LCS_Graph self); GVA_LCS_Graph -gva_lcs_graph_from_variant(GVA_Allocator const allocator, - size_t const len_ref, char const reference[static len_ref], - GVA_Variant const variant); +gva_lcs_graph_from_variants(GVA_Allocator const allocator, + size_t const len_ref, char const reference[static restrict len_ref], + size_t const n, GVA_Variant const variants[static restrict n]); gva_uint diff --git a/include/variant.h b/include/variant.h index bb58887..cb5b447 100644 --- a/include/variant.h +++ b/include/variant.h @@ -41,7 +41,8 @@ gva_variant_length(GVA_Variant const variant); GVA_String gva_patch(GVA_Allocator const allocator, size_t const len_ref, char const reference[static restrict len_ref], - size_t const n, GVA_Variant const variants[static restrict n]); + size_t const n, GVA_Variant const variants[static restrict n], + size_t const shift); #endif // GVA_VARIANT_H diff --git a/python/ext/lcsgraph.c b/python/ext/lcsgraph.c index d31bffb..bc3cbe3 100644 --- a/python/ext/lcsgraph.c +++ b/python/ext/lcsgraph.c @@ -6,8 +6,9 @@ #include "lcsgraph.h" // LCSgraph, LCSgraph_* #include "variant.h" // Variant, Variant_* -#include "../include/lcs_graph.h" // GVA_LCS_Graph, gva_lcs_graph_from_variant +#include "../include/lcs_graph.h" // GVA_LCS_Graph, gva_lcs_graph_* #include "../include/std_alloc.h" // gva_std_allocator +#include "../include/types.h" // GVA_NULL PyObject* @@ -22,7 +23,7 @@ LCSgraph_new(PyTypeObject* type, PyObject* args, PyObject* kwargs) return NULL; } // if - self->graph = (GVA_LCS_Graph) {0}; + self->graph = (GVA_LCS_Graph) {NULL, NULL, NULL, {0, 0, {0, NULL}}, {0, NULL}, GVA_NULL, 0}; return (PyObject*) self; } // LCSgraph_new @@ -73,7 +74,7 @@ LCSgraph_from_variants(PyObject* cls, PyObject* args, PyObject* kwargs) return NULL; } // if - self->graph = gva_lcs_graph_from_variant(gva_std_allocator, len_ref, reference, variants[0]); + self->graph = gva_lcs_graph_from_variants(gva_std_allocator, len_ref, reference, PyList_GET_SIZE(variant_list), variants); PySys_FormatStderr("supremal: " GVA_VARIANT_FMT_SPDI "\n", GVA_VARIANT_PRINT_SPDI("reference", self->graph.supremal)); diff --git a/src/lcs_graph.c b/src/lcs_graph.c index 290c6c3..df89cff 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -5,10 +5,11 @@ #include "../include/allocator.h" // GVA_Allocator #include "../include/lcs_graph.h" // GVA_LCS_Graph, gva_lcs_graph_* -#include "../include/variant.h" // GVA_Variant, gva_variant_length +#include "../include/string.h" // GVA_String, gva_string_destroy +#include "../include/variant.h" // GVA_Variant, gva_patch, gva_variant_length #include "align.h" // LCS_Alignment, lcs_align #include "array.h" // ARRAY_*, array_length -#include "common.h" // GVA_NULL, gva_uint, MAX, MIN +#include "common.h" // GVA_NULL, MAX, MIN, gva_uint GVA_LCS_Graph @@ -275,14 +276,22 @@ gva_lcs_graph_destroy(GVA_Allocator const allocator, GVA_LCS_Graph self) GVA_LCS_Graph -gva_lcs_graph_from_variant(GVA_Allocator const allocator, - size_t const len_ref, char const reference[static len_ref], - GVA_Variant const variant) +gva_lcs_graph_from_variants(GVA_Allocator const allocator, + size_t const len_ref, char const reference[static restrict len_ref], + size_t const n, GVA_Variant const variants[static restrict n]) { + // FIXME: n == 0? + GVA_Variant variant = {variants[0].start, variants[0].end, {0, NULL}}; + for (size_t i = 1; i < n; ++i) + { + variant.start = MIN(variant.start, variants[i].start); + variant.end = MAX(variant.end, variants[i].end); + } // for + variant.sequence = gva_patch(allocator, variant.end - variant.start, reference + variant.start, n, variants, variant.start); + gva_uint offset = MAX(8, gva_variant_length(variant) / 2); size_t old_len = 0; char* observed = NULL; - while (true) { gva_uint const start = MAX(0, (intmax_t) variant.start - offset); @@ -313,7 +322,8 @@ gva_lcs_graph_from_variant(GVA_Allocator const allocator, old_len = len; offset *= 2; // OVERFLOW } // while -} // gva_lcs_graph_from_variant + gva_string_destroy(allocator, variant.sequence); +} // gva_lcs_graph_from_variants gva_uint diff --git a/src/main.c b/src/main.c index 12a8ad4..3f0ddf6 100644 --- a/src/main.c +++ b/src/main.c @@ -498,7 +498,7 @@ all(int argc, char* argv[static argc + 1]) continue; } // if - GVA_LCS_Graph graph = gva_lcs_graph_from_variant(gva_std_allocator, reference.len, reference.str, variant); + GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &variant); gva_uint const inserted = trie_insert(gva_std_allocator, &trie, graph.supremal.sequence.len, graph.supremal.sequence.str); gva_stabbing_index_add(gva_std_allocator, &index, graph.supremal.start, graph.supremal.end, inserted, graph.distance, rsid); diff --git a/src/variant.c b/src/variant.c index e180121..0f3fc79 100644 --- a/src/variant.c +++ b/src/variant.c @@ -130,15 +130,16 @@ gva_variant_length(GVA_Variant const variant) GVA_String gva_patch(GVA_Allocator const allocator, size_t const len_ref, char const reference[static restrict len_ref], - size_t const n, GVA_Variant const variants[static restrict n]) + size_t const n, GVA_Variant const variants[static restrict n], + size_t const shift) { GVA_String observed = {0, NULL}; size_t start = 0; for (size_t i = 0; i < n; ++i) { - observed = gva_string_concat(allocator, observed, (GVA_String) {variants[i].start - start, reference + start}); + observed = gva_string_concat(allocator, observed, (GVA_String) {variants[i].start - start - shift, reference + start}); observed = gva_string_concat(allocator, observed, variants[i].sequence); - start = variants[i].end; + start = variants[i].end - shift; } // for if (start < len_ref) From cdc05d2c4378ba296347c39a233f28bc8dafe3e9 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 7 Aug 2025 11:24:33 +0200 Subject: [PATCH 307/704] Added REAMDE for setup --- python/README.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 python/README.md diff --git a/python/README.md b/python/README.md new file mode 100644 index 0000000..e69de29 From 294babb88534800efe2ea25750db0f6e82c27ffd Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 7 Aug 2025 15:57:35 +0200 Subject: [PATCH 308/704] Snapshot --- python/ext/lcsgraph.c | 84 +++++++++++++++++++++++++++++++-------- python/ext/lcsgraph.h | 12 ------ python/ext/variant.c | 91 ++++++++++++++++++++++++++++++++++--------- python/ext/variant.h | 15 ++----- python/sandbox.py | 4 +- src/lcs_graph.c | 2 +- 6 files changed, 148 insertions(+), 60 deletions(-) diff --git a/python/ext/lcsgraph.c b/python/ext/lcsgraph.c index bc3cbe3..a31ad18 100644 --- a/python/ext/lcsgraph.c +++ b/python/ext/lcsgraph.c @@ -1,55 +1,60 @@ #define PY_SSIZE_T_CLEAN #include // Py* -#include // NULL +#include // NULL, size_t #include "lcsgraph.h" // LCSgraph, LCSgraph_* #include "variant.h" // Variant, Variant_* -#include "../include/lcs_graph.h" // GVA_LCS_Graph, gva_lcs_graph_* +#include "../include/lcs_graph.h" // GVA_LCS_Graph, gva_lcs_graph_*, gva_edges #include "../include/std_alloc.h" // gva_std_allocator +#include "../include/string.h" // gva_string_destroy #include "../include/types.h" // GVA_NULL +#include "../include/variant.h" // GVA_Variant +#include "../src/array.h" // array_length -PyObject* -LCSgraph_new(PyTypeObject* type, PyObject* args, PyObject* kwargs) +static PyObject* +LCSgraph_new(PyTypeObject* subtype, PyObject* args, PyObject* kwargs) { (void) args; (void) kwargs; - LCSgraph* const self = (LCSgraph*) type->tp_alloc(type, 0); + LCSgraph* const self = (LCSgraph*) subtype->tp_alloc(subtype, 0); if (self == NULL) { return NULL; } // if - self->graph = (GVA_LCS_Graph) {NULL, NULL, NULL, {0, 0, {0, NULL}}, {0, NULL}, GVA_NULL, 0}; + PySys_FormatStderr("LCSgraph_new() (%p)\n", (void*) self); return (PyObject*) self; } // LCSgraph_new -inline void +static inline void LCSgraph_dealloc(LCSgraph* self) { + PySys_FormatStderr("LCSgraph_dealloc() (%p)\n", (void*) self); + + gva_string_destroy(gva_std_allocator, self->graph.observed); gva_lcs_graph_destroy(gva_std_allocator, self->graph); Py_TYPE(self)->tp_free((PyObject*) self); } // LCSgraph_dealloc -PyObject* -LCSgraph_from_variants(PyObject* cls, PyObject* args, PyObject* kwargs) +static PyObject* +from_variants(PyObject* cls, PyObject* args, PyObject* kwargs) { char const* reference = NULL; Py_ssize_t len_ref = 0; PyObject* variant_list = NULL; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#O!|:from_variants", - (char* []) {"reference", "variants", NULL}, + (char*[]) {"reference", "variants", NULL}, &reference, &len_ref, &PyList_Type, &variant_list)) { return NULL; } // if - GVA_Variant* variants = gva_std_allocator.allocate(gva_std_allocator.context, NULL, 0, PyList_GET_SIZE(variant_list) * sizeof(*variants)); if (variants == NULL) { @@ -76,11 +81,46 @@ LCSgraph_from_variants(PyObject* cls, PyObject* args, PyObject* kwargs) self->graph = gva_lcs_graph_from_variants(gva_std_allocator, len_ref, reference, PyList_GET_SIZE(variant_list), variants); - PySys_FormatStderr("supremal: " GVA_VARIANT_FMT_SPDI "\n", GVA_VARIANT_PRINT_SPDI("reference", self->graph.supremal)); - variants = gva_std_allocator.allocate(gva_std_allocator.context, variants, PyList_GET_SIZE(variant_list) * sizeof(*variants), 0); return (PyObject*) self; -} // LCSgraph_from_variants +} // from_variants + + +static PyObject* +local_supremal(LCSgraph* self) +{ + PyObject* local = PyList_New(array_length(self->graph.local_supremal) - 1); + if (local == NULL) + { + return NULL; + } // if + + for (size_t i = 0; i < array_length(self->graph.local_supremal) - 1; ++i) + { + GVA_Variant variant; + gva_edges(self->graph.observed.str, + self->graph.local_supremal[i], self->graph.local_supremal[i + 1], + i == 0, i == array_length(self->graph.local_supremal) - 2, + &variant); + + PyObject* item = PyObject_CallFunction((PyObject*) &Variant_Type, "nnz", variant.start, variant.end, "test"); + if (item == NULL) + { + Py_DECREF(local); + return NULL; + } // if + PyList_SET_ITEM(local, i, item); + } // for + return local; +} // local_supremal + + +static PyObject* +supremal(LCSgraph* self) +{ + PySys_FormatStderr("supremal() (%p)\n", (void*) self); + return PyObject_CallFunction((PyObject*) &Variant_Type, "nns#", self->graph.supremal.start, self->graph.supremal.end, self->graph.supremal.sequence.str, self->graph.supremal.sequence.len); +} // supremal PyTypeObject LCSgraph_Type = @@ -89,16 +129,28 @@ PyTypeObject LCSgraph_Type = .tp_name = "algebra_ext.LCSgraph", .tp_basicsize = sizeof(LCSgraph), .tp_doc = PyDoc_STR("LCS graph class for storing all minimal alignments."), - .tp_new = LCSgraph_new, + .tp_new = (newfunc) LCSgraph_new, .tp_dealloc = (destructor) LCSgraph_dealloc, .tp_methods = (PyMethodDef[]) { { "from_variants", - (PyCFunction) LCSgraph_from_variants, + (PyCFunction) from_variants, METH_CLASS | METH_VARARGS | METH_KEYWORDS, PyDoc_STR("Iteratively find the supremal LCS graph for an allele by repeatedly widening a range of influence."), }, + { + "local_supremal", + (PyCFunction) local_supremal, + METH_NOARGS, + PyDoc_STR("The local supremal variant."), + }, + { + "supremal", + (PyCFunction) supremal, + METH_NOARGS, + PyDoc_STR("The supremal variant."), + }, {NULL} // sentinel }, }; diff --git a/python/ext/lcsgraph.h b/python/ext/lcsgraph.h index e75a088..7dd6e8f 100644 --- a/python/ext/lcsgraph.h +++ b/python/ext/lcsgraph.h @@ -15,18 +15,6 @@ typedef struct } LCSgraph; -PyObject* -LCSgraph_new(PyTypeObject* type, PyObject* args, PyObject* kwargs); - - -void -LCSgraph_dealloc(LCSgraph* self); - - -PyObject* -LCSgraph_from_variants(PyObject* cls, PyObject* args, PyObject* kwargs); - - extern PyTypeObject LCSgraph_Type; diff --git a/python/ext/variant.c b/python/ext/variant.c index e41c0c1..839d68a 100644 --- a/python/ext/variant.c +++ b/python/ext/variant.c @@ -1,49 +1,104 @@ #define PY_SSIZE_T_CLEAN #include // Py* -#include // NULL +#include // NULL, offsetof -#include "variant.h" // Variant, Varaint_* +#include "variant.h" // Variant, Variant_* +#include "../include/std_alloc.h" // gva_std_allocator -PyObject* -Variant_new(PyTypeObject* type, PyObject* args, PyObject* kwargs) + +static PyObject* +Variant_new(PyTypeObject* subtype, PyObject* args, PyObject* kwargs) { - Py_ssize_t start = 0; - Py_ssize_t end = 0; - char const* sequence = NULL; - Py_ssize_t len = 0; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "nns#:Variant", - (char* []) {"start", "end", "sequence", NULL}, - &start, &end, &sequence, &len)) - { - return NULL; - } // if + (void) args; + (void) kwargs; - Variant* const self = (Variant*) type->tp_alloc(type, 0); + Variant* const self = (Variant*) subtype->tp_alloc(subtype, 0); if (self == NULL) { return NULL; } // if - self->variant = (GVA_Variant) {start, end, {len, sequence}}; + PySys_FormatStderr("Variant_new() (%p)\n", (void*) self); return (PyObject*) self; } // Variant_new -inline void +static int +Variant_init(Variant* self, PyObject* args, PyObject* kwargs) +{ + PySys_FormatStderr("Variant_init() (%p)\n", (void*) self); + + Py_ssize_t start = 0; + Py_ssize_t end = 0; + char const* sequence = NULL; + Py_ssize_t len = 0; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "nns#|:Variant", + (char*[]) {"start", "end", "sequence", NULL}, + &start, &end, &sequence, &len)) + { + Py_DECREF(self); + return -1; + } // if + + self->start = start; + self->end = end; + self->len = len; + self->sequence = sequence; + return 0; +} // Variant_init + + +static inline void Variant_dealloc(Variant* self) { + PySys_FormatStderr("Variant_dealloc() (%p)\n", (void*) self); Py_TYPE(self)->tp_free((PyObject*) self); } // Variant_dealloc +static inline PyObject* +Variant_repr(Variant* self) +{ + PySys_FormatStderr("Variant_repr() (%p)\n", (void*) self); + return PyUnicode_FromFormat("%zu:%zu/%.*s", self->start, self->end, (int) self->len, self->sequence); +} // Variant_repr + + PyTypeObject Variant_Type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "algebra_ext.Variant", .tp_basicsize = sizeof(Variant), .tp_doc = PyDoc_STR("Variant class for deletion/insertions."), - .tp_new = Variant_new, + .tp_new = (newfunc) Variant_new, + .tp_init = (initproc) Variant_init, .tp_dealloc = (destructor) Variant_dealloc, + .tp_repr = (reprfunc) Variant_repr, + .tp_members = (PyMemberDef[]) + { + { + "start", + Py_T_PYSSIZET, + offsetof(Variant, start), + Py_READONLY, + PyDoc_STR("The start position (included) of the deleted part (zero-based)."), + }, + { + "end", + Py_T_PYSSIZET, + offsetof(Variant, end), + Py_READONLY, + PyDoc_STR("The end position (not included) of the deleted part."), + }, + { + "sequence", + Py_T_STRING, + offsetof(Variant, sequence), + Py_READONLY, + PyDoc_STR("The inserted sequence."), + }, + {NULL}, // sentinel + }, }; diff --git a/python/ext/variant.h b/python/ext/variant.h index fe9dbda..fedb311 100644 --- a/python/ext/variant.h +++ b/python/ext/variant.h @@ -5,24 +5,17 @@ #define PY_SSIZE_T_CLEAN #include // Py* -#include "../include/variant.h" // GVA_Variant - typedef struct { PyObject_HEAD - GVA_Variant variant; + Py_ssize_t start; + Py_ssize_t end; + Py_ssize_t len; + char const* sequence; } Variant; -PyObject* -Variant_new(PyTypeObject* type, PyObject* args, PyObject* kwargs); - - -void -Variant_dealloc(Variant* self); - - extern PyTypeObject Variant_Type; diff --git a/python/sandbox.py b/python/sandbox.py index 317e3aa..4348609 100644 --- a/python/sandbox.py +++ b/python/sandbox.py @@ -2,8 +2,8 @@ def main(): - graph = LCSgraph.from_variants("AAAAAAA", [Variant(1, 1, "XXX")]) - print(graph) + v = Variant(1, 1, "CCC") + print(v) if __name__ == "__main__": diff --git a/src/lcs_graph.c b/src/lcs_graph.c index df89cff..f723d67 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -314,6 +314,7 @@ gva_lcs_graph_from_variants(GVA_Allocator const allocator, if ((graph.supremal.start > start || graph.supremal.start == 0) && (graph.supremal.end < end || graph.supremal.end == len_ref)) { + gva_string_destroy(allocator, variant.sequence); return graph; } // if @@ -322,7 +323,6 @@ gva_lcs_graph_from_variants(GVA_Allocator const allocator, old_len = len; offset *= 2; // OVERFLOW } // while - gva_string_destroy(allocator, variant.sequence); } // gva_lcs_graph_from_variants From 4985f3fd20d3cbc10450d8f071c6c90ba877510d Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 7 Aug 2025 16:44:07 +0200 Subject: [PATCH 309/704] WIP: Python bindings LCSgraph creation from a single variant --- include/lcs_graph.h | 4 ++-- include/variant.h | 3 +-- python/ext/lcsgraph.c | 27 +++++++++++++++++++-------- python/ext/variant.c | 35 +++++++++-------------------------- python/sandbox.py | 9 +++++++-- src/lcs_graph.c | 19 +++++-------------- src/variant.c | 7 +++---- 7 files changed, 46 insertions(+), 58 deletions(-) diff --git a/include/lcs_graph.h b/include/lcs_graph.h index dfd8759..52158e7 100644 --- a/include/lcs_graph.h +++ b/include/lcs_graph.h @@ -61,9 +61,9 @@ gva_lcs_graph_destroy(GVA_Allocator const allocator, GVA_LCS_Graph self); GVA_LCS_Graph -gva_lcs_graph_from_variants(GVA_Allocator const allocator, +gva_lcs_graph_from_variant(GVA_Allocator const allocator, size_t const len_ref, char const reference[static restrict len_ref], - size_t const n, GVA_Variant const variants[static restrict n]); + GVA_Variant const variant); gva_uint diff --git a/include/variant.h b/include/variant.h index cb5b447..bb58887 100644 --- a/include/variant.h +++ b/include/variant.h @@ -41,8 +41,7 @@ gva_variant_length(GVA_Variant const variant); GVA_String gva_patch(GVA_Allocator const allocator, size_t const len_ref, char const reference[static restrict len_ref], - size_t const n, GVA_Variant const variants[static restrict n], - size_t const shift); + size_t const n, GVA_Variant const variants[static restrict n]); #endif // GVA_VARIANT_H diff --git a/python/ext/lcsgraph.c b/python/ext/lcsgraph.c index a31ad18..c3eb46c 100644 --- a/python/ext/lcsgraph.c +++ b/python/ext/lcsgraph.c @@ -14,6 +14,9 @@ #include "../src/array.h" // array_length +// DEBUG: PySys_FormatStderr + + static PyObject* LCSgraph_new(PyTypeObject* subtype, PyObject* args, PyObject* kwargs) { @@ -25,8 +28,6 @@ LCSgraph_new(PyTypeObject* subtype, PyObject* args, PyObject* kwargs) { return NULL; } // if - - PySys_FormatStderr("LCSgraph_new() (%p)\n", (void*) self); return (PyObject*) self; } // LCSgraph_new @@ -34,8 +35,6 @@ LCSgraph_new(PyTypeObject* subtype, PyObject* args, PyObject* kwargs) static inline void LCSgraph_dealloc(LCSgraph* self) { - PySys_FormatStderr("LCSgraph_dealloc() (%p)\n", (void*) self); - gva_string_destroy(gva_std_allocator, self->graph.observed); gva_lcs_graph_destroy(gva_std_allocator, self->graph); Py_TYPE(self)->tp_free((PyObject*) self); @@ -70,6 +69,7 @@ from_variants(PyObject* cls, PyObject* args, PyObject* kwargs) variants = gva_std_allocator.allocate(gva_std_allocator.context, variants, PyList_GET_SIZE(variant_list) * sizeof(*variants), 0); return NULL; } // if + variants[i] = (GVA_Variant) {item->start, item->end, {item->len, item->sequence}}; } // for LCSgraph* self = (LCSgraph*) PyObject_CallNoArgs(cls); @@ -79,7 +79,7 @@ from_variants(PyObject* cls, PyObject* args, PyObject* kwargs) return NULL; } // if - self->graph = gva_lcs_graph_from_variants(gva_std_allocator, len_ref, reference, PyList_GET_SIZE(variant_list), variants); + self->graph = gva_lcs_graph_from_variant(gva_std_allocator, len_ref, reference, variants[0]); variants = gva_std_allocator.allocate(gva_std_allocator.context, variants, PyList_GET_SIZE(variant_list) * sizeof(*variants), 0); return (PyObject*) self; @@ -103,9 +103,16 @@ local_supremal(LCSgraph* self) i == 0, i == array_length(self->graph.local_supremal) - 2, &variant); - PyObject* item = PyObject_CallFunction((PyObject*) &Variant_Type, "nnz", variant.start, variant.end, "test"); + PyObject* str = PyUnicode_FromFormat("%.*s", (int) variant.sequence.len, variant.sequence.str); + if (str == NULL) + { + Py_DECREF(local); + return NULL; + } // if + PyObject* item = PyObject_CallFunction((PyObject*) &Variant_Type, "nnO", variant.start, variant.end, str); if (item == NULL) { + Py_DECREF(str); Py_DECREF(local); return NULL; } // if @@ -118,8 +125,12 @@ local_supremal(LCSgraph* self) static PyObject* supremal(LCSgraph* self) { - PySys_FormatStderr("supremal() (%p)\n", (void*) self); - return PyObject_CallFunction((PyObject*) &Variant_Type, "nns#", self->graph.supremal.start, self->graph.supremal.end, self->graph.supremal.sequence.str, self->graph.supremal.sequence.len); + PyObject* str = PyUnicode_FromFormat("%.*s", (int) self->graph.supremal.sequence.len, self->graph.supremal.sequence.str); + if (str == NULL) + { + return NULL; + } // if + return PyObject_CallFunction((PyObject*) &Variant_Type, "nnO", self->graph.supremal.start, self->graph.supremal.end, str); } // supremal diff --git a/python/ext/variant.c b/python/ext/variant.c index 839d68a..4af8f49 100644 --- a/python/ext/variant.c +++ b/python/ext/variant.c @@ -11,25 +11,6 @@ static PyObject* Variant_new(PyTypeObject* subtype, PyObject* args, PyObject* kwargs) { - (void) args; - (void) kwargs; - - Variant* const self = (Variant*) subtype->tp_alloc(subtype, 0); - if (self == NULL) - { - return NULL; - } // if - - PySys_FormatStderr("Variant_new() (%p)\n", (void*) self); - return (PyObject*) self; -} // Variant_new - - -static int -Variant_init(Variant* self, PyObject* args, PyObject* kwargs) -{ - PySys_FormatStderr("Variant_init() (%p)\n", (void*) self); - Py_ssize_t start = 0; Py_ssize_t end = 0; char const* sequence = NULL; @@ -38,22 +19,26 @@ Variant_init(Variant* self, PyObject* args, PyObject* kwargs) (char*[]) {"start", "end", "sequence", NULL}, &start, &end, &sequence, &len)) { - Py_DECREF(self); - return -1; + return NULL; + } // if + + Variant* const self = (Variant*) subtype->tp_alloc(subtype, 0); + if (self == NULL) + { + return NULL; } // if self->start = start; self->end = end; self->len = len; self->sequence = sequence; - return 0; -} // Variant_init + return (PyObject*) self; +} // Variant_new static inline void Variant_dealloc(Variant* self) { - PySys_FormatStderr("Variant_dealloc() (%p)\n", (void*) self); Py_TYPE(self)->tp_free((PyObject*) self); } // Variant_dealloc @@ -61,7 +46,6 @@ Variant_dealloc(Variant* self) static inline PyObject* Variant_repr(Variant* self) { - PySys_FormatStderr("Variant_repr() (%p)\n", (void*) self); return PyUnicode_FromFormat("%zu:%zu/%.*s", self->start, self->end, (int) self->len, self->sequence); } // Variant_repr @@ -73,7 +57,6 @@ PyTypeObject Variant_Type = .tp_basicsize = sizeof(Variant), .tp_doc = PyDoc_STR("Variant class for deletion/insertions."), .tp_new = (newfunc) Variant_new, - .tp_init = (initproc) Variant_init, .tp_dealloc = (destructor) Variant_dealloc, .tp_repr = (reprfunc) Variant_repr, .tp_members = (PyMemberDef[]) diff --git a/python/sandbox.py b/python/sandbox.py index 4348609..5b895bb 100644 --- a/python/sandbox.py +++ b/python/sandbox.py @@ -2,8 +2,13 @@ def main(): - v = Variant(1, 1, "CCC") - print(v) + reference = "GTGTGTTTTTTTAACAGGGA" + variants = [Variant(8, 9, "")] + + graph = LCSgraph.from_variants(reference, variants) + + print(graph.supremal()) + print(graph.local_supremal()) if __name__ == "__main__": diff --git a/src/lcs_graph.c b/src/lcs_graph.c index f723d67..8d84426 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -276,22 +276,14 @@ gva_lcs_graph_destroy(GVA_Allocator const allocator, GVA_LCS_Graph self) GVA_LCS_Graph -gva_lcs_graph_from_variants(GVA_Allocator const allocator, - size_t const len_ref, char const reference[static restrict len_ref], - size_t const n, GVA_Variant const variants[static restrict n]) +gva_lcs_graph_from_variant(GVA_Allocator const allocator, + size_t const len_ref, char const reference[static len_ref], + GVA_Variant const variant) { - // FIXME: n == 0? - GVA_Variant variant = {variants[0].start, variants[0].end, {0, NULL}}; - for (size_t i = 1; i < n; ++i) - { - variant.start = MIN(variant.start, variants[i].start); - variant.end = MAX(variant.end, variants[i].end); - } // for - variant.sequence = gva_patch(allocator, variant.end - variant.start, reference + variant.start, n, variants, variant.start); - gva_uint offset = MAX(8, gva_variant_length(variant) / 2); size_t old_len = 0; char* observed = NULL; + while (true) { gva_uint const start = MAX(0, (intmax_t) variant.start - offset); @@ -314,7 +306,6 @@ gva_lcs_graph_from_variants(GVA_Allocator const allocator, if ((graph.supremal.start > start || graph.supremal.start == 0) && (graph.supremal.end < end || graph.supremal.end == len_ref)) { - gva_string_destroy(allocator, variant.sequence); return graph; } // if @@ -323,7 +314,7 @@ gva_lcs_graph_from_variants(GVA_Allocator const allocator, old_len = len; offset *= 2; // OVERFLOW } // while -} // gva_lcs_graph_from_variants +} // gva_lcs_graph_from_variant gva_uint diff --git a/src/variant.c b/src/variant.c index 0f3fc79..e180121 100644 --- a/src/variant.c +++ b/src/variant.c @@ -130,16 +130,15 @@ gva_variant_length(GVA_Variant const variant) GVA_String gva_patch(GVA_Allocator const allocator, size_t const len_ref, char const reference[static restrict len_ref], - size_t const n, GVA_Variant const variants[static restrict n], - size_t const shift) + size_t const n, GVA_Variant const variants[static restrict n]) { GVA_String observed = {0, NULL}; size_t start = 0; for (size_t i = 0; i < n; ++i) { - observed = gva_string_concat(allocator, observed, (GVA_String) {variants[i].start - start - shift, reference + start}); + observed = gva_string_concat(allocator, observed, (GVA_String) {variants[i].start - start, reference + start}); observed = gva_string_concat(allocator, observed, variants[i].sequence); - start = variants[i].end - shift; + start = variants[i].end; } // for if (start < len_ref) From 3aa8178d235f67ab049c2315d0518a65b6735afb Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 7 Aug 2025 19:21:17 +0200 Subject: [PATCH 310/704] WIP: from_variants for alleles with mulitple variants --- include/lcs_graph.h | 4 ++-- python/ext/lcsgraph.c | 2 +- python/sandbox.py | 2 +- src/lcs_graph.c | 24 +++++++++++++++++------- 4 files changed, 21 insertions(+), 11 deletions(-) diff --git a/include/lcs_graph.h b/include/lcs_graph.h index 52158e7..dfd8759 100644 --- a/include/lcs_graph.h +++ b/include/lcs_graph.h @@ -61,9 +61,9 @@ gva_lcs_graph_destroy(GVA_Allocator const allocator, GVA_LCS_Graph self); GVA_LCS_Graph -gva_lcs_graph_from_variant(GVA_Allocator const allocator, +gva_lcs_graph_from_variants(GVA_Allocator const allocator, size_t const len_ref, char const reference[static restrict len_ref], - GVA_Variant const variant); + size_t const n, GVA_Variant const variants[static restrict n]); gva_uint diff --git a/python/ext/lcsgraph.c b/python/ext/lcsgraph.c index c3eb46c..a5d764e 100644 --- a/python/ext/lcsgraph.c +++ b/python/ext/lcsgraph.c @@ -79,7 +79,7 @@ from_variants(PyObject* cls, PyObject* args, PyObject* kwargs) return NULL; } // if - self->graph = gva_lcs_graph_from_variant(gva_std_allocator, len_ref, reference, variants[0]); + self->graph = gva_lcs_graph_from_variants(gva_std_allocator, len_ref, reference, PyList_GET_SIZE(variant_list), variants); variants = gva_std_allocator.allocate(gva_std_allocator.context, variants, PyList_GET_SIZE(variant_list) * sizeof(*variants), 0); return (PyObject*) self; diff --git a/python/sandbox.py b/python/sandbox.py index 5b895bb..c7fcb92 100644 --- a/python/sandbox.py +++ b/python/sandbox.py @@ -3,7 +3,7 @@ def main(): reference = "GTGTGTTTTTTTAACAGGGA" - variants = [Variant(8, 9, "")] + variants = [Variant(4, 5, ""), Variant(12, 13, "")] graph = LCSgraph.from_variants(reference, variants) diff --git a/src/lcs_graph.c b/src/lcs_graph.c index 8d84426..07c780c 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -5,8 +5,8 @@ #include "../include/allocator.h" // GVA_Allocator #include "../include/lcs_graph.h" // GVA_LCS_Graph, gva_lcs_graph_* -#include "../include/string.h" // GVA_String, gva_string_destroy -#include "../include/variant.h" // GVA_Variant, gva_patch, gva_variant_length +#include "../include/string.h" // GVA_String, gva_string_* +#include "../include/variant.h" // GVA_Variant, gva_variant_length #include "align.h" // LCS_Alignment, lcs_align #include "array.h" // ARRAY_*, array_length #include "common.h" // GVA_NULL, MAX, MIN, gva_uint @@ -276,14 +276,21 @@ gva_lcs_graph_destroy(GVA_Allocator const allocator, GVA_LCS_Graph self) GVA_LCS_Graph -gva_lcs_graph_from_variant(GVA_Allocator const allocator, - size_t const len_ref, char const reference[static len_ref], - GVA_Variant const variant) +gva_lcs_graph_from_variants(GVA_Allocator const allocator, + size_t const len_ref, char const reference[static restrict len_ref], + size_t const n, GVA_Variant const variants[static restrict n]) { + GVA_Variant variant = {variants[0].start, variants[n - 1].end, {0, NULL}}; + variant.sequence = gva_string_concat(allocator, variant.sequence, variants[0].sequence); + for (size_t i = 1; i < n; ++i) + { + variant.sequence = gva_string_concat(allocator, variant.sequence, (GVA_String) {variants[i].start - variants[i - 1].end, reference + variants[i - 1].end}); + variant.sequence = gva_string_concat(allocator, variant.sequence, variants[i].sequence); + } // for + gva_uint offset = MAX(8, gva_variant_length(variant) / 2); size_t old_len = 0; char* observed = NULL; - while (true) { gva_uint const start = MAX(0, (intmax_t) variant.start - offset); @@ -294,6 +301,7 @@ gva_lcs_graph_from_variant(GVA_Allocator const allocator, observed = allocator.allocate(allocator.context, observed, old_len, len); if (observed == NULL) { + gva_string_destroy(allocator, variant.sequence); return (GVA_LCS_Graph) {NULL, NULL, NULL, {0, 0, {0, NULL}}, {0, NULL}, GVA_NULL, 0}; } // if @@ -306,6 +314,8 @@ gva_lcs_graph_from_variant(GVA_Allocator const allocator, if ((graph.supremal.start > start || graph.supremal.start == 0) && (graph.supremal.end < end || graph.supremal.end == len_ref)) { + // FIXME: observed is now owned by graph + gva_string_destroy(allocator, variant.sequence); return graph; } // if @@ -314,7 +324,7 @@ gva_lcs_graph_from_variant(GVA_Allocator const allocator, old_len = len; offset *= 2; // OVERFLOW } // while -} // gva_lcs_graph_from_variant +} // gva_lcs_graph_from_variants gva_uint From 0691d921aeba6fc732cdae874a1780f414054172 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 7 Aug 2025 22:28:07 +0200 Subject: [PATCH 311/704] WIP: extraction --- include/extract.h | 1 - python/algebra/extractor/__init__.py | 9 +++++ python/ext/algebra_ext.c | 60 ++++++++++++++++++++++++++++ python/ext/lcsgraph.c | 12 +++--- python/sandbox.py | 7 ++-- python/setup.py | 1 + 6 files changed, 80 insertions(+), 10 deletions(-) create mode 100644 python/algebra/extractor/__init__.py diff --git a/include/extract.h b/include/extract.h index 9f45780..9d4fd5c 100644 --- a/include/extract.h +++ b/include/extract.h @@ -4,7 +4,6 @@ #include "allocator.h" // GVA_Allocator #include "lcs_graph.h" // GVA_LCS_Graph -#include "variant.h" // GVA_Variant GVA_Variant* diff --git a/python/algebra/extractor/__init__.py b/python/algebra/extractor/__init__.py new file mode 100644 index 0000000..58dd718 --- /dev/null +++ b/python/algebra/extractor/__init__.py @@ -0,0 +1,9 @@ +"""Extract canonical variants.""" + + +from algebra_ext import LCSgraph, canonical + + +def extract(reference, variants): + graph = LCSgraph.from_variants(reference, variants) + return canonical(graph), graph diff --git a/python/ext/algebra_ext.c b/python/ext/algebra_ext.c index 2c0e270..afff152 100644 --- a/python/ext/algebra_ext.c +++ b/python/ext/algebra_ext.c @@ -6,6 +6,56 @@ #include "lcsgraph.h" // LCSgraph, LCSgraph_* #include "variant.h" // Variant, Variant_* +#include "../include/extract.h" // gva_extract +#include "../include/std_alloc.h" // gva_std_allocator +#include "../include/variant.h" // GVA_Variant +#include "../src/array.h" // ARRAY_DESTROY, array_length + + +static PyObject* +canonical(PyObject* self, PyObject* args, PyObject* kwargs) +{ + LCSgraph* graph = NULL; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!|:canonical", + (char*[]) {"graph", NULL}, + &LCSgraph_Type, &graph)) + { + return NULL; + } // if + + GVA_Variant* variants = gva_extract(gva_std_allocator, graph->graph); + + PyObject* result = PyList_New(array_length(variants)); + if (result == NULL) + { + variants = ARRAY_DESTROY(gva_std_allocator, variants); + return NULL; + } // if + + for (size_t i = 0; i < array_length(variants); ++i) + { + PyObject* str = PyUnicode_FromFormat("%.*s", (int) variants[i].sequence.len, variants[i].sequence.str); + if (str == NULL) + { + Py_DECREF(result); + variants = ARRAY_DESTROY(gva_std_allocator, variants); + return NULL; + } // if + PyObject* item = PyObject_CallFunction((PyObject*) &Variant_Type, "nnO", variants[i].start, variants[i].end, str); + if (item == NULL) + { + Py_DECREF(str); + Py_DECREF(result); + variants = ARRAY_DESTROY(gva_std_allocator, variants); + return NULL; + } // if + PyList_SET_ITEM(result, i, item); + } // for + variants = ARRAY_DESTROY(gva_std_allocator, variants); + + return result; +} // canonical + static PyModuleDef algebra_ext_module = { @@ -13,6 +63,16 @@ static PyModuleDef algebra_ext_module = .m_name = "algebra_ext", .m_doc = PyDoc_STR("Algebra C extension"), .m_size = -1, + .m_methods = (PyMethodDef[]) + { + { + "canonical", + (PyCFunction) canonical, + METH_VARARGS | METH_KEYWORDS, + PyDoc_STR("Extract the canonical variant representation together with its supremal representation for an allele."), + }, + {NULL}, // sentinel + }, }; diff --git a/python/ext/lcsgraph.c b/python/ext/lcsgraph.c index a5d764e..89f2bf3 100644 --- a/python/ext/lcsgraph.c +++ b/python/ext/lcsgraph.c @@ -89,8 +89,8 @@ from_variants(PyObject* cls, PyObject* args, PyObject* kwargs) static PyObject* local_supremal(LCSgraph* self) { - PyObject* local = PyList_New(array_length(self->graph.local_supremal) - 1); - if (local == NULL) + PyObject* result = PyList_New(array_length(self->graph.local_supremal) - 1); + if (result == NULL) { return NULL; } // if @@ -106,19 +106,19 @@ local_supremal(LCSgraph* self) PyObject* str = PyUnicode_FromFormat("%.*s", (int) variant.sequence.len, variant.sequence.str); if (str == NULL) { - Py_DECREF(local); + Py_DECREF(result); return NULL; } // if PyObject* item = PyObject_CallFunction((PyObject*) &Variant_Type, "nnO", variant.start, variant.end, str); if (item == NULL) { Py_DECREF(str); - Py_DECREF(local); + Py_DECREF(result); return NULL; } // if - PyList_SET_ITEM(local, i, item); + PyList_SET_ITEM(result, i, item); } // for - return local; + return result; } // local_supremal diff --git a/python/sandbox.py b/python/sandbox.py index c7fcb92..de1a532 100644 --- a/python/sandbox.py +++ b/python/sandbox.py @@ -1,12 +1,13 @@ -from algebra import LCSgraph, Variant +from algebra import Variant +from algebra.extractor import extract def main(): reference = "GTGTGTTTTTTTAACAGGGA" variants = [Variant(4, 5, ""), Variant(12, 13, "")] - graph = LCSgraph.from_variants(reference, variants) - + canonical, graph = extract(reference, variants) + print(canonical) print(graph.supremal()) print(graph.local_supremal()) diff --git a/python/setup.py b/python/setup.py index 985f0c8..4649a12 100644 --- a/python/setup.py +++ b/python/setup.py @@ -15,6 +15,7 @@ "ext/variant.c", "../src/align.c", "../src/array.c", + "../src/extract.c", "../src/lcs_graph.c", "../src/string.c", "../src/variant.c", From c6cabf153237014532ac0db543130eb6a864f809 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 7 Aug 2025 22:50:25 +0200 Subject: [PATCH 312/704] WIP: canonical as member function --- python/algebra/extractor/__init__.py | 9 ---- python/ext/algebra_ext.c | 62 +--------------------------- python/ext/lcsgraph.c | 46 ++++++++++++++++++++- python/sandbox.py | 9 ++-- 4 files changed, 50 insertions(+), 76 deletions(-) delete mode 100644 python/algebra/extractor/__init__.py diff --git a/python/algebra/extractor/__init__.py b/python/algebra/extractor/__init__.py deleted file mode 100644 index 58dd718..0000000 --- a/python/algebra/extractor/__init__.py +++ /dev/null @@ -1,9 +0,0 @@ -"""Extract canonical variants.""" - - -from algebra_ext import LCSgraph, canonical - - -def extract(reference, variants): - graph = LCSgraph.from_variants(reference, variants) - return canonical(graph), graph diff --git a/python/ext/algebra_ext.c b/python/ext/algebra_ext.c index afff152..100dbfa 100644 --- a/python/ext/algebra_ext.c +++ b/python/ext/algebra_ext.c @@ -1,61 +1,11 @@ #define PY_SSIZE_T_CLEAN #include // Py* -#include // NULL, size_t +#include // NULL #include "lcsgraph.h" // LCSgraph, LCSgraph_* #include "variant.h" // Variant, Variant_* -#include "../include/extract.h" // gva_extract -#include "../include/std_alloc.h" // gva_std_allocator -#include "../include/variant.h" // GVA_Variant -#include "../src/array.h" // ARRAY_DESTROY, array_length - - -static PyObject* -canonical(PyObject* self, PyObject* args, PyObject* kwargs) -{ - LCSgraph* graph = NULL; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!|:canonical", - (char*[]) {"graph", NULL}, - &LCSgraph_Type, &graph)) - { - return NULL; - } // if - - GVA_Variant* variants = gva_extract(gva_std_allocator, graph->graph); - - PyObject* result = PyList_New(array_length(variants)); - if (result == NULL) - { - variants = ARRAY_DESTROY(gva_std_allocator, variants); - return NULL; - } // if - - for (size_t i = 0; i < array_length(variants); ++i) - { - PyObject* str = PyUnicode_FromFormat("%.*s", (int) variants[i].sequence.len, variants[i].sequence.str); - if (str == NULL) - { - Py_DECREF(result); - variants = ARRAY_DESTROY(gva_std_allocator, variants); - return NULL; - } // if - PyObject* item = PyObject_CallFunction((PyObject*) &Variant_Type, "nnO", variants[i].start, variants[i].end, str); - if (item == NULL) - { - Py_DECREF(str); - Py_DECREF(result); - variants = ARRAY_DESTROY(gva_std_allocator, variants); - return NULL; - } // if - PyList_SET_ITEM(result, i, item); - } // for - variants = ARRAY_DESTROY(gva_std_allocator, variants); - - return result; -} // canonical - static PyModuleDef algebra_ext_module = { @@ -63,16 +13,6 @@ static PyModuleDef algebra_ext_module = .m_name = "algebra_ext", .m_doc = PyDoc_STR("Algebra C extension"), .m_size = -1, - .m_methods = (PyMethodDef[]) - { - { - "canonical", - (PyCFunction) canonical, - METH_VARARGS | METH_KEYWORDS, - PyDoc_STR("Extract the canonical variant representation together with its supremal representation for an allele."), - }, - {NULL}, // sentinel - }, }; diff --git a/python/ext/lcsgraph.c b/python/ext/lcsgraph.c index 89f2bf3..eeb08ad 100644 --- a/python/ext/lcsgraph.c +++ b/python/ext/lcsgraph.c @@ -6,12 +6,13 @@ #include "lcsgraph.h" // LCSgraph, LCSgraph_* #include "variant.h" // Variant, Variant_* +#include "../include/extract.h" // gva_extract #include "../include/lcs_graph.h" // GVA_LCS_Graph, gva_lcs_graph_*, gva_edges #include "../include/std_alloc.h" // gva_std_allocator #include "../include/string.h" // gva_string_destroy #include "../include/types.h" // GVA_NULL #include "../include/variant.h" // GVA_Variant -#include "../src/array.h" // array_length +#include "../src/array.h" // ARRAY_DESTROY, array_length // DEBUG: PySys_FormatStderr @@ -86,6 +87,43 @@ from_variants(PyObject* cls, PyObject* args, PyObject* kwargs) } // from_variants +static PyObject* +canonical(LCSgraph* self) +{ + GVA_Variant* variants = gva_extract(gva_std_allocator, self->graph); + + PyObject* result = PyList_New(array_length(variants)); + if (result == NULL) + { + variants = ARRAY_DESTROY(gva_std_allocator, variants); + return NULL; + } // if + + for (size_t i = 0; i < array_length(variants); ++i) + { + PyObject* str = PyUnicode_FromFormat("%.*s", (int) variants[i].sequence.len, variants[i].sequence.str); + if (str == NULL) + { + Py_DECREF(result); + variants = ARRAY_DESTROY(gva_std_allocator, variants); + return NULL; + } // if + PyObject* item = PyObject_CallFunction((PyObject*) &Variant_Type, "nnO", variants[i].start, variants[i].end, str); + if (item == NULL) + { + Py_DECREF(str); + Py_DECREF(result); + variants = ARRAY_DESTROY(gva_std_allocator, variants); + return NULL; + } // if + PyList_SET_ITEM(result, i, item); + } // for + variants = ARRAY_DESTROY(gva_std_allocator, variants); + + return result; +} // canonical + + static PyObject* local_supremal(LCSgraph* self) { @@ -150,6 +188,12 @@ PyTypeObject LCSgraph_Type = METH_CLASS | METH_VARARGS | METH_KEYWORDS, PyDoc_STR("Iteratively find the supremal LCS graph for an allele by repeatedly widening a range of influence."), }, + { + "canonical", + (PyCFunction) canonical, + METH_NOARGS, + PyDoc_STR("The canonical variant."), + }, { "local_supremal", (PyCFunction) local_supremal, diff --git a/python/sandbox.py b/python/sandbox.py index de1a532..5c3fd22 100644 --- a/python/sandbox.py +++ b/python/sandbox.py @@ -1,16 +1,15 @@ -from algebra import Variant -from algebra.extractor import extract +from algebra import LCSgraph, Variant def main(): reference = "GTGTGTTTTTTTAACAGGGA" variants = [Variant(4, 5, ""), Variant(12, 13, "")] - canonical, graph = extract(reference, variants) - print(canonical) + graph = LCSgraph.from_variants(reference, variants) + print(graph.supremal()) print(graph.local_supremal()) - + print(graph.canonical()) if __name__ == "__main__": main() From af51daffe7ad96bb7559d192fd80ab0c47cafeaa Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 7 Aug 2025 22:51:45 +0200 Subject: [PATCH 313/704] Style --- python/sandbox.py | 1 + 1 file changed, 1 insertion(+) diff --git a/python/sandbox.py b/python/sandbox.py index 5c3fd22..254ab53 100644 --- a/python/sandbox.py +++ b/python/sandbox.py @@ -11,5 +11,6 @@ def main(): print(graph.local_supremal()) print(graph.canonical()) + if __name__ == "__main__": main() From ccb4758c24a14db813a8f0c8c74e9631ac34ec7d Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 8 Aug 2025 09:11:16 +0200 Subject: [PATCH 314/704] Extractor --- include/{extract.h => extractor.h} | 2 +- python/ext/lcsgraph.c | 12 +++++++++--- python/setup.py | 5 ++++- src/{extract.c => extractor.c} | 5 +++-- src/main.c | 6 +++--- 5 files changed, 20 insertions(+), 10 deletions(-) rename include/{extract.h => extractor.h} (70%) rename src/{extract.c => extractor.c} (97%) diff --git a/include/extract.h b/include/extractor.h similarity index 70% rename from include/extract.h rename to include/extractor.h index 9d4fd5c..59c1a77 100644 --- a/include/extract.h +++ b/include/extractor.h @@ -7,7 +7,7 @@ GVA_Variant* -gva_extract(GVA_Allocator const allocator, GVA_LCS_Graph const graph); +gva_canonical(GVA_Allocator const allocator, GVA_LCS_Graph const graph); #endif // GVA_EXTRACT_H diff --git a/python/ext/lcsgraph.c b/python/ext/lcsgraph.c index eeb08ad..be353e1 100644 --- a/python/ext/lcsgraph.c +++ b/python/ext/lcsgraph.c @@ -6,7 +6,7 @@ #include "lcsgraph.h" // LCSgraph, LCSgraph_* #include "variant.h" // Variant, Variant_* -#include "../include/extract.h" // gva_extract +#include "../include/extractor.h" // gva_canonical #include "../include/lcs_graph.h" // GVA_LCS_Graph, gva_lcs_graph_*, gva_edges #include "../include/std_alloc.h" // gva_std_allocator #include "../include/string.h" // gva_string_destroy @@ -90,7 +90,7 @@ from_variants(PyObject* cls, PyObject* args, PyObject* kwargs) static PyObject* canonical(LCSgraph* self) { - GVA_Variant* variants = gva_extract(gva_std_allocator, self->graph); + GVA_Variant* variants = gva_canonical(gva_std_allocator, self->graph); PyObject* result = PyList_New(array_length(variants)); if (result == NULL) @@ -168,7 +168,13 @@ supremal(LCSgraph* self) { return NULL; } // if - return PyObject_CallFunction((PyObject*) &Variant_Type, "nnO", self->graph.supremal.start, self->graph.supremal.end, str); + PyObject* result = PyObject_CallFunction((PyObject*) &Variant_Type, "nnO", self->graph.supremal.start, self->graph.supremal.end, str); + if (result == NULL) + { + Py_DECREF(str); + return NULL; + } // if + return result; } // supremal diff --git a/python/setup.py b/python/setup.py index 4649a12..a2e6392 100644 --- a/python/setup.py +++ b/python/setup.py @@ -7,7 +7,10 @@ extra_compile_args=[ "-Wextra", "-Wpedantic", + "-Wno-cast-function-type", "-std=c99", + "-O3", + "-fanalyzer", ], sources=[ "ext/algebra_ext.c", @@ -15,7 +18,7 @@ "ext/variant.c", "../src/align.c", "../src/array.c", - "../src/extract.c", + "../src/extractor.c", "../src/lcs_graph.c", "../src/string.c", "../src/variant.c", diff --git a/src/extract.c b/src/extractor.c similarity index 97% rename from src/extract.c rename to src/extractor.c index 6044723..6783ed2 100644 --- a/src/extract.c +++ b/src/extractor.c @@ -1,5 +1,6 @@ #include // NULL, size_t +#include "../include/extractor.h" // gva_canonical #include "../include/lcs_graph.h" // GVA_LCS_Graph, gva_edges #include "../include/types.h" // GVA_NULL, gva_uint #include "array.h" // ARRAY_APPEND, array_length @@ -44,7 +45,7 @@ lca(gva_uint* const start, GVA_Variant* -gva_extract(GVA_Allocator const allocator, GVA_LCS_Graph const graph) +gva_canonical(GVA_Allocator const allocator, GVA_LCS_Graph const graph) { gva_uint const length = array_length(graph.nodes); LCA_Table* visited = allocator.allocate(allocator.context, NULL, 0, sizeof(*visited) * length); @@ -160,4 +161,4 @@ gva_extract(GVA_Allocator const allocator, GVA_LCS_Graph const graph) visited = allocator.allocate(allocator.context, visited, sizeof(*visited) * length, 0); return canonical; -} // gva_extract +} // gva_canonical diff --git a/src/main.c b/src/main.c index 3f0ddf6..c43f4e0 100644 --- a/src/main.c +++ b/src/main.c @@ -8,7 +8,7 @@ #include "../include/compare.h" // bitset_fill #include "../include/edit.h" // gva_edit_distance -#include "../include/extract.h" // gva_extract +#include "../include/extractor.h" // gva_canonical #include "../include/lcs_graph.h" // GVA_LCS_Graph, GVA_Variant, gva_lcs_graph_*, gva_edges #include "../include/stabbing.h" // GVA_Stabbing_*, gva_stabbing_* #include "../include/std_alloc.h" // gva_std_allocator @@ -225,7 +225,7 @@ lcs_graph_json(FILE* const stream, GVA_LCS_Graph const graph) } // if fprintf(stream, " ],\n \"supremal\": \"" GVA_VARIANT_FMT "\",\n", GVA_VARIANT_PRINT(graph.supremal)); fprintf(stream, " \"canonical\": [\n"); - GVA_Variant* canonical = gva_extract(gva_std_allocator, graph); + GVA_Variant* canonical = gva_canonical(gva_std_allocator, graph); for (size_t i = 0; i < array_length(canonical); ++i) { fprintf(stream, " \"" GVA_VARIANT_FMT "\"%s\n", GVA_VARIANT_PRINT(canonical[i]), i < array_length(canonical) - 1 ? "," : ""); @@ -312,7 +312,7 @@ extract(int const argc, char* argv[static argc + 1]) lcs_graph_json(stdout, graph); lcs_graph_svg(stderr, graph); - GVA_Variant* canonical = gva_extract(gva_std_allocator, graph); + GVA_Variant* canonical = gva_canonical(gva_std_allocator, graph); for (size_t i = 0; i < array_length(canonical); ++i) { fprintf(stderr, GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(canonical[i])); From 7e676dc7b3d8cb783dc00523172119a81fb7d4c9 Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 8 Aug 2025 11:00:11 +0200 Subject: [PATCH 315/704] WIP: added pytests --- python/ext/lcsgraph.c | 26 +++++++-------- python/ext/variant.c | 28 +++++++++++++++- python/setup.cfg | 6 +++- python/tests/__init__.py | 0 python/tests/test_lcs_graph.py | 27 +++++++++++++++ python/tests/test_variant.py | 61 ++++++++++++++++++++++++++++++++++ 6 files changed, 133 insertions(+), 15 deletions(-) create mode 100644 python/tests/__init__.py create mode 100644 python/tests/test_lcs_graph.py create mode 100644 python/tests/test_variant.py diff --git a/python/ext/lcsgraph.c b/python/ext/lcsgraph.c index be353e1..c258bf0 100644 --- a/python/ext/lcsgraph.c +++ b/python/ext/lcsgraph.c @@ -43,7 +43,7 @@ LCSgraph_dealloc(LCSgraph* self) static PyObject* -from_variants(PyObject* cls, PyObject* args, PyObject* kwargs) +LCSgraph_from_variants(PyObject* cls, PyObject* args, PyObject* kwargs) { char const* reference = NULL; Py_ssize_t len_ref = 0; @@ -84,11 +84,11 @@ from_variants(PyObject* cls, PyObject* args, PyObject* kwargs) variants = gva_std_allocator.allocate(gva_std_allocator.context, variants, PyList_GET_SIZE(variant_list) * sizeof(*variants), 0); return (PyObject*) self; -} // from_variants +} // LCSgraph_from_variants static PyObject* -canonical(LCSgraph* self) +LCSgraph_canonical(LCSgraph* self) { GVA_Variant* variants = gva_canonical(gva_std_allocator, self->graph); @@ -118,14 +118,14 @@ canonical(LCSgraph* self) } // if PyList_SET_ITEM(result, i, item); } // for - variants = ARRAY_DESTROY(gva_std_allocator, variants); + variants = ARRAY_DESTROY(gva_std_allocator, variants); return result; -} // canonical +} // LCSgraph_canonical static PyObject* -local_supremal(LCSgraph* self) +LCSgraph_local_supremal(LCSgraph* self) { PyObject* result = PyList_New(array_length(self->graph.local_supremal) - 1); if (result == NULL) @@ -157,11 +157,11 @@ local_supremal(LCSgraph* self) PyList_SET_ITEM(result, i, item); } // for return result; -} // local_supremal +} // LCSgraph_local_supremal static PyObject* -supremal(LCSgraph* self) +LCSgraph_supremal(LCSgraph* self) { PyObject* str = PyUnicode_FromFormat("%.*s", (int) self->graph.supremal.sequence.len, self->graph.supremal.sequence.str); if (str == NULL) @@ -175,7 +175,7 @@ supremal(LCSgraph* self) return NULL; } // if return result; -} // supremal +} // LCSgraph_supremal PyTypeObject LCSgraph_Type = @@ -190,25 +190,25 @@ PyTypeObject LCSgraph_Type = { { "from_variants", - (PyCFunction) from_variants, + (PyCFunction) LCSgraph_from_variants, METH_CLASS | METH_VARARGS | METH_KEYWORDS, PyDoc_STR("Iteratively find the supremal LCS graph for an allele by repeatedly widening a range of influence."), }, { "canonical", - (PyCFunction) canonical, + (PyCFunction) LCSgraph_canonical, METH_NOARGS, PyDoc_STR("The canonical variant."), }, { "local_supremal", - (PyCFunction) local_supremal, + (PyCFunction) LCSgraph_local_supremal, METH_NOARGS, PyDoc_STR("The local supremal variant."), }, { "supremal", - (PyCFunction) supremal, + (PyCFunction) LCSgraph_supremal, METH_NOARGS, PyDoc_STR("The supremal variant."), }, diff --git a/python/ext/variant.c b/python/ext/variant.c index 4af8f49..90c0c41 100644 --- a/python/ext/variant.c +++ b/python/ext/variant.c @@ -1,11 +1,12 @@ #define PY_SSIZE_T_CLEAN #include // Py* +#include // bool #include // NULL, offsetof #include "variant.h" // Variant, Variant_* -#include "../include/std_alloc.h" // gva_std_allocator +#include "../include/variant.h" // GVA_Variant, gva_variant_* static PyObject* @@ -50,6 +51,30 @@ Variant_repr(Variant* self) } // Variant_repr +static PyObject* +Variant_richcompare(Variant* self, Variant* other, int op) +{ + PyObject* result = Py_NotImplemented; + bool const equal = gva_variant_eq((GVA_Variant) {self->start, self->end, {self->len, self->sequence}}, + (GVA_Variant) {other->start, other->end, {other->len, other->sequence}}); + switch (op) + { + //case Py_LT: + //case Py_LE: + case Py_EQ: + result = equal ? Py_True : Py_False; + break; + case Py_NE: + result = equal ? Py_False : Py_True; + break; + //case Py_GT: + //case Py_GE: + } // switch + Py_XINCREF(result); + return result; +} // Variant_richcompare + + PyTypeObject Variant_Type = { PyVarObject_HEAD_INIT(NULL, 0) @@ -59,6 +84,7 @@ PyTypeObject Variant_Type = .tp_new = (newfunc) Variant_new, .tp_dealloc = (destructor) Variant_dealloc, .tp_repr = (reprfunc) Variant_repr, + .tp_richcompare = (richcmpfunc) Variant_richcompare, .tp_members = (PyMemberDef[]) { { diff --git a/python/setup.cfg b/python/setup.cfg index 762f2e0..e77b2d2 100644 --- a/python/setup.cfg +++ b/python/setup.cfg @@ -22,4 +22,8 @@ packages = find: [options.packages.find] include = algebra - algebra.* \ No newline at end of file + algebra.* + +[options.extras_require] +dev = + pytest diff --git a/python/tests/__init__.py b/python/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/python/tests/test_lcs_graph.py b/python/tests/test_lcs_graph.py new file mode 100644 index 0000000..d194087 --- /dev/null +++ b/python/tests/test_lcs_graph.py @@ -0,0 +1,27 @@ +import pytest +from algebra.lcs import LCSgraph +from algebra.variants import Variant + + +@pytest.mark.parametrize("args, expected", [ + (("GTGTGTTTTTTTAACAGGGA", [Variant(8, 9, "")]), [Variant(5, 12, "TTTTTT")]), +]) +def test_canonical(args, expected): + graph = LCSgraph.from_variants(*args) + assert graph.canonical() == expected + + +@pytest.mark.parametrize("args, expected", [ + (("GTGTGTTTTTTTAACAGGGA", [Variant(8, 9, "")]), [Variant(5, 12, "TTTTTT")]), +]) +def test_local_supremal(args, expected): + graph = LCSgraph.from_variants(*args) + assert graph.local_supremal() == expected + + +@pytest.mark.parametrize("args, expected", [ + (("GTGTGTTTTTTTAACAGGGA", [Variant(8, 9, "")]), Variant(5, 12, "TTTTTT")), +]) +def test_supremal(args, expected): + graph = LCSgraph.from_variants(*args) + assert graph.supremal() == expected diff --git a/python/tests/test_variant.py b/python/tests/test_variant.py new file mode 100644 index 0000000..5e9e89a --- /dev/null +++ b/python/tests/test_variant.py @@ -0,0 +1,61 @@ +import pytest +from algebra.variants import Variant + + +@pytest.mark.parametrize("args, expected", [ + ((0, 0, ""), {"start": 0, "end": 0, "sequence": ""}), + ((0, 0, "A"), {"start": 0, "end": 0, "sequence": "A"}), + ((0, 1, "A"), {"start": 0, "end": 1, "sequence": "A"}), +]) +def test_variant(args, expected): + variant = Variant(*args) + assert all((variant.start == expected["start"], + variant.end == expected["end"], + variant.sequence == expected["sequence"])) + + +@pytest.mark.parametrize("args, expected", [ + ((), "Variant() missing required argument 'start' (pos 1)"), + ((0,), "Variant() missing required argument 'end' (pos 2)"), + ((0, 0), "Variant() missing required argument 'sequence' (pos 3)"), + (("0", 0, ""), "'str' object cannot be interpreted as an integer"), + ((0, "0", ""), "'str' object cannot be interpreted as an integer"), + ((0, 0, 0), "a bytes-like object is required, not 'int'"), +]) +def test_variant_TypeError(args, expected): + with pytest.raises(TypeError) as exc: + Variant(*args) + assert str(exc.value) == expected + + +@pytest.mark.parametrize("args, expected", [ + ((0, 0, ""), "0:0/"), + ((0, 0, "A"), "0:0/A"), + ((0, 1, "A"), "0:1/A"), +]) +def test_variant_repr(args, expected): + assert str(Variant(*args)) == expected + + +def test_variant_immutable(): + variant = Variant(sequence="", start=0, end=0) + + with pytest.raises(AttributeError) as exc: + variant.start = 1 + assert str(exc.value) == "readonly attribute" + + with pytest.raises(AttributeError) as exc: + variant.end = 1 + assert str(exc.value) == "readonly attribute" + + with pytest.raises(AttributeError) as exc: + variant.sequence = "A" + assert str(exc.value) == "readonly attribute" + + +def test_variant_compare(): + assert Variant(0, 0, "") == Variant(0, 0, "") + assert Variant(0, 0, "A") == Variant(0, 0, "A") + assert Variant(0, 0, "") != Variant(0, 1, "") + assert Variant(0, 0, "") != Variant(1, 0, "") + assert Variant(0, 0, "") != Variant(0, 0, "A") From a52a445f14aeecb1a8ac3a2a0c4666eac090129f Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 8 Aug 2025 11:17:37 +0200 Subject: [PATCH 316/704] Better? alternative --- python/ext/lcsgraph.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/python/ext/lcsgraph.c b/python/ext/lcsgraph.c index c258bf0..5e7b575 100644 --- a/python/ext/lcsgraph.c +++ b/python/ext/lcsgraph.c @@ -101,7 +101,7 @@ LCSgraph_canonical(LCSgraph* self) for (size_t i = 0; i < array_length(variants); ++i) { - PyObject* str = PyUnicode_FromFormat("%.*s", (int) variants[i].sequence.len, variants[i].sequence.str); + PyObject* str = PyUnicode_FromStringAndSize(variants[i].sequence.str, variants[i].sequence.len); if (str == NULL) { Py_DECREF(result); @@ -141,7 +141,7 @@ LCSgraph_local_supremal(LCSgraph* self) i == 0, i == array_length(self->graph.local_supremal) - 2, &variant); - PyObject* str = PyUnicode_FromFormat("%.*s", (int) variant.sequence.len, variant.sequence.str); + PyObject* str = PyUnicode_FromStringAndSize(variant.sequence.str, variant.sequence.len); if (str == NULL) { Py_DECREF(result); @@ -163,7 +163,7 @@ LCSgraph_local_supremal(LCSgraph* self) static PyObject* LCSgraph_supremal(LCSgraph* self) { - PyObject* str = PyUnicode_FromFormat("%.*s", (int) self->graph.supremal.sequence.len, self->graph.supremal.sequence.str); + PyObject* str = PyUnicode_FromStringAndSize(self->graph.supremal.sequence.str, self->graph.supremal.sequence.len); if (str == NULL) { return NULL; From 005bb38ec782ab9623531d76629bc717acb2ac8c Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 8 Aug 2025 11:30:55 +0200 Subject: [PATCH 317/704] reUse C implementation --- python/ext/variant.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/python/ext/variant.c b/python/ext/variant.c index 90c0c41..318f39e 100644 --- a/python/ext/variant.c +++ b/python/ext/variant.c @@ -6,7 +6,7 @@ #include "variant.h" // Variant, Variant_* -#include "../include/variant.h" // GVA_Variant, gva_variant_* +#include "../include/variant.h" // GVA_VARIANT_*, GVA_Variant, gva_variant_* static PyObject* @@ -47,7 +47,7 @@ Variant_dealloc(Variant* self) static inline PyObject* Variant_repr(Variant* self) { - return PyUnicode_FromFormat("%zu:%zu/%.*s", self->start, self->end, (int) self->len, self->sequence); + return PyUnicode_FromFormat(GVA_VARIANT_FMT, GVA_VARIANT_PRINT(((GVA_Variant) {self->start, self->end, {self->len, self->sequence}}))); } // Variant_repr @@ -70,7 +70,7 @@ Variant_richcompare(Variant* self, Variant* other, int op) //case Py_GT: //case Py_GE: } // switch - Py_XINCREF(result); + Py_INCREF(result); return result; } // Variant_richcompare From ae232e72c90368925024023e2d774a0e54edfd91 Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 8 Aug 2025 11:46:31 +0200 Subject: [PATCH 318/704] More pytests --- python/sandbox.py | 16 ---------------- python/tests/test_lcs_graph.py | 30 +++++++++--------------------- python/tests/test_variant.py | 30 +++++++++++++++--------------- 3 files changed, 24 insertions(+), 52 deletions(-) delete mode 100644 python/sandbox.py diff --git a/python/sandbox.py b/python/sandbox.py deleted file mode 100644 index 254ab53..0000000 --- a/python/sandbox.py +++ /dev/null @@ -1,16 +0,0 @@ -from algebra import LCSgraph, Variant - - -def main(): - reference = "GTGTGTTTTTTTAACAGGGA" - variants = [Variant(4, 5, ""), Variant(12, 13, "")] - - graph = LCSgraph.from_variants(reference, variants) - - print(graph.supremal()) - print(graph.local_supremal()) - print(graph.canonical()) - - -if __name__ == "__main__": - main() diff --git a/python/tests/test_lcs_graph.py b/python/tests/test_lcs_graph.py index d194087..13247f8 100644 --- a/python/tests/test_lcs_graph.py +++ b/python/tests/test_lcs_graph.py @@ -3,25 +3,13 @@ from algebra.variants import Variant -@pytest.mark.parametrize("args, expected", [ - (("GTGTGTTTTTTTAACAGGGA", [Variant(8, 9, "")]), [Variant(5, 12, "TTTTTT")]), +@pytest.mark.parametrize("reference, variants, supremal, local_supremal, canonical", [ + ("GTGTGTTTTTTTAACAGGGA", [Variant(8, 9, "")], Variant(5, 12, "TTTTTT"), [Variant(5, 12, "TTTTTT")], [Variant(5, 12, "TTTTTT")]), + ("GTGTGTTTTTTTAACAGGGA", [Variant(4, 5, ""), Variant(12, 13, "")], Variant(4, 14, "TTTTTTTA"), [Variant(4, 5, ""), Variant(12, 14, "A")], [Variant(4, 5, ""), Variant(12, 14, "A")]), + ("GGGTCTTCGACTTTCCACGAAAATCGC", [Variant(11, 12, "")], Variant(11, 14, "TT"), [Variant(11, 14, "TT")], [Variant(11, 14, "TT")]), ]) -def test_canonical(args, expected): - graph = LCSgraph.from_variants(*args) - assert graph.canonical() == expected - - -@pytest.mark.parametrize("args, expected", [ - (("GTGTGTTTTTTTAACAGGGA", [Variant(8, 9, "")]), [Variant(5, 12, "TTTTTT")]), -]) -def test_local_supremal(args, expected): - graph = LCSgraph.from_variants(*args) - assert graph.local_supremal() == expected - - -@pytest.mark.parametrize("args, expected", [ - (("GTGTGTTTTTTTAACAGGGA", [Variant(8, 9, "")]), Variant(5, 12, "TTTTTT")), -]) -def test_supremal(args, expected): - graph = LCSgraph.from_variants(*args) - assert graph.supremal() == expected +def test_LCSgraph_from_variants(reference, variants, supremal, local_supremal, canonical): + graph = LCSgraph.from_variants(reference, variants) + assert all((graph.supremal() == supremal, + graph.local_supremal() == local_supremal, + graph.canonical() == canonical)) diff --git a/python/tests/test_variant.py b/python/tests/test_variant.py index 5e9e89a..9deda69 100644 --- a/python/tests/test_variant.py +++ b/python/tests/test_variant.py @@ -2,16 +2,16 @@ from algebra.variants import Variant -@pytest.mark.parametrize("args, expected", [ - ((0, 0, ""), {"start": 0, "end": 0, "sequence": ""}), - ((0, 0, "A"), {"start": 0, "end": 0, "sequence": "A"}), - ((0, 1, "A"), {"start": 0, "end": 1, "sequence": "A"}), +@pytest.mark.parametrize("start, end, sequence", [ + (0, 0, ""), + (0, 0, "A"), + (0, 1, "A"), ]) -def test_variant(args, expected): - variant = Variant(*args) - assert all((variant.start == expected["start"], - variant.end == expected["end"], - variant.sequence == expected["sequence"])) +def test_variant(start, end, sequence): + variant = Variant(start, end, sequence) + assert all((variant.start == start, + variant.end == end, + variant.sequence == sequence)) @pytest.mark.parametrize("args, expected", [ @@ -28,13 +28,13 @@ def test_variant_TypeError(args, expected): assert str(exc.value) == expected -@pytest.mark.parametrize("args, expected", [ - ((0, 0, ""), "0:0/"), - ((0, 0, "A"), "0:0/A"), - ((0, 1, "A"), "0:1/A"), +@pytest.mark.parametrize("variant, expected", [ + (Variant(0, 0, ""), "0:0/"), + (Variant(0, 0, "A"), "0:0/A"), + (Variant(0, 1, "A"), "0:1/A"), ]) -def test_variant_repr(args, expected): - assert str(Variant(*args)) == expected +def test_variant_repr(variant, expected): + assert str(variant) == expected def test_variant_immutable(): From ddb4edb148f2ec307f78e560312c3596bd685100 Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 8 Aug 2025 14:25:36 +0200 Subject: [PATCH 319/704] WIP: compare and relations --- include/compare.h | 18 ++-- python/algebra/__init__.py | 3 + python/algebra/relations/__init__.py | 7 ++ python/ext/algebra_ext.c | 79 ++++++++++++++++- python/ext/lcsgraph.c | 8 +- python/ext/variant.c | 2 +- python/setup.py | 3 + python/tests/test_compare.py | 9 ++ src/compare.c | 121 +++++++++++++++++++++++++-- 9 files changed, 229 insertions(+), 21 deletions(-) create mode 100644 python/algebra/relations/__init__.py create mode 100644 python/tests/test_compare.py diff --git a/include/compare.h b/include/compare.h index 36465f9..b4b97ff 100644 --- a/include/compare.h +++ b/include/compare.h @@ -11,12 +11,6 @@ #include "variant.h" // GVA_VARIANT -GVA_Relation -gva_compare_supremals(GVA_Allocator const allocator, - size_t const len_ref, char const reference[static len_ref], - GVA_Variant const lhs, GVA_Variant const rhs); - - // FIXME: move to lcs_graph as `uniq_atomics`. void bitset_fill(GVA_LCS_Graph const graph, @@ -29,4 +23,16 @@ bitset_fill(GVA_LCS_Graph const graph, size_t ts[static restrict 1]); +GVA_Relation +gva_compare_graphs(GVA_Allocator const allocator, + size_t const len_ref, char const reference[static len_ref], + GVA_LCS_Graph const lhs, GVA_LCS_Graph const rhs); + + +GVA_Relation +gva_compare_supremals(GVA_Allocator const allocator, + size_t const len_ref, char const reference[static len_ref], + GVA_Variant const lhs, GVA_Variant const rhs); + + #endif // GVA_COMPARE_H diff --git a/python/algebra/__init__.py b/python/algebra/__init__.py index ecdc5e3..1dd0f8c 100644 --- a/python/algebra/__init__.py +++ b/python/algebra/__init__.py @@ -2,10 +2,13 @@ from .lcs import LCSgraph +from .relations import Relation, compare from .variants import Variant __all__ = [ "LCSgraph", + "Relation", "Variant", + "compare", ] diff --git a/python/algebra/relations/__init__.py b/python/algebra/relations/__init__.py new file mode 100644 index 0000000..2f1ff69 --- /dev/null +++ b/python/algebra/relations/__init__.py @@ -0,0 +1,7 @@ +from algebra_ext import Relation, compare + + +__all__ = [ + "Relation", + "compare", +] diff --git a/python/ext/algebra_ext.c b/python/ext/algebra_ext.c index 100dbfa..cc903c5 100644 --- a/python/ext/algebra_ext.c +++ b/python/ext/algebra_ext.c @@ -3,8 +3,43 @@ #include // NULL -#include "lcsgraph.h" // LCSgraph, LCSgraph_* -#include "variant.h" // Variant, Variant_* +#include "lcsgraph.h" // LCSgraph, LCSgraph_* +#include "variant.h" // Variant, Variant_* + +#include "../include/compare.h" // gva_compare_graphs +#include "../include/relations.h" // GVA_RELATION_LABELS, GVA_Relation +#include "../include/std_alloc.h" // gva_std_allocator + + +// DEBUG: PySys_FormatStderr + + +static PyObject* +algebra_ext_compare(PyObject* self, PyObject* args, PyObject* kwargs) +{ + char const* reference = NULL; + Py_ssize_t len_ref = 0; + LCSgraph* lhs = NULL; + LCSgraph* rhs = NULL; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#O!O!|:compare", + (char*[]) {"reference", "lhs", "rhs", NULL}, + &reference, &len_ref, &LCSgraph_Type, &lhs, &LCSgraph_Type, &rhs)) + { + return NULL; + } // if + + GVA_Relation const relation = gva_compare_graphs(gva_std_allocator, len_ref, reference, lhs->graph, rhs->graph); + + PyObject* relations = PyObject_GetAttrString(self, "Relation"); + if (relations == NULL) + { + return NULL; + } // if + + PyObject* result = PyObject_GetAttrString(relations, GVA_RELATION_LABELS[relation]); + Py_DECREF(relations); + return result; +} // algebra_ext_compare static PyModuleDef algebra_ext_module = @@ -13,6 +48,16 @@ static PyModuleDef algebra_ext_module = .m_name = "algebra_ext", .m_doc = PyDoc_STR("Algebra C extension"), .m_size = -1, + .m_methods = (PyMethodDef[]) + { + { + "compare", + (PyCFunction) algebra_ext_compare, + METH_VARARGS | METH_KEYWORDS, + PyDoc_STR("Compare two LCS graphs."), + }, + {NULL} // sentinel + }, }; @@ -43,5 +88,35 @@ PyInit_algebra_ext(void) return NULL; } // if + PyObject* relations = PyDict_New(); + if (relations == NULL) + { + return NULL; + } // if + for (size_t i = 0; i < sizeof(GVA_RELATION_LABELS) / sizeof(*GVA_RELATION_LABELS); ++i) + { + PyDict_SetItemString(relations, GVA_RELATION_LABELS[i], PyUnicode_FromString(GVA_RELATION_LABELS[i])); + } // for + + PyObject* module_enum = PyImport_ImportModule("enum"); + if (module_enum == NULL) + { + return NULL; + } // if + + PyObject* enum_class = PyObject_CallMethod(module_enum, "Enum", "sO", "Relation", relations); + if (enum_class == NULL) + { + return NULL; + } // if + + Py_DECREF(module_enum); + Py_DECREF(relations); + + if (PyModule_AddObject(module, "Relation", enum_class) < 0) + { + return NULL; + } // if + return module; } // PyInit_algebra_ext diff --git a/python/ext/lcsgraph.c b/python/ext/lcsgraph.c index 5e7b575..f92f6d9 100644 --- a/python/ext/lcsgraph.c +++ b/python/ext/lcsgraph.c @@ -15,15 +15,9 @@ #include "../src/array.h" // ARRAY_DESTROY, array_length -// DEBUG: PySys_FormatStderr - - static PyObject* -LCSgraph_new(PyTypeObject* subtype, PyObject* args, PyObject* kwargs) +LCSgraph_new(PyTypeObject* subtype, PyObject* Py_UNUSED(args), PyObject* Py_UNUSED(kwargs)) { - (void) args; - (void) kwargs; - LCSgraph* const self = (LCSgraph*) subtype->tp_alloc(subtype, 0); if (self == NULL) { diff --git a/python/ext/variant.c b/python/ext/variant.c index 318f39e..c73d13b 100644 --- a/python/ext/variant.c +++ b/python/ext/variant.c @@ -108,6 +108,6 @@ PyTypeObject Variant_Type = Py_READONLY, PyDoc_STR("The inserted sequence."), }, - {NULL}, // sentinel + {NULL} // sentinel }, }; diff --git a/python/setup.py b/python/setup.py index a2e6392..7519e14 100644 --- a/python/setup.py +++ b/python/setup.py @@ -18,6 +18,9 @@ "ext/variant.c", "../src/align.c", "../src/array.c", + "../src/bitset.c", + "../src/compare.c", + "../src/edit.c", "../src/extractor.c", "../src/lcs_graph.c", "../src/string.c", diff --git a/python/tests/test_compare.py b/python/tests/test_compare.py new file mode 100644 index 0000000..6593441 --- /dev/null +++ b/python/tests/test_compare.py @@ -0,0 +1,9 @@ +import pytest +from algebra import LCSgraph, Relation, Variant, compare + + +def test_compare(): + reference = "AAAAA" + lhs = LCSgraph.from_variants(reference, [Variant(0, 0, "T")]) + rhs = LCSgraph.from_variants(reference, [Variant(0, 0, "TA")]) + assert compare(reference, lhs, rhs) == Relation.is_contained diff --git a/src/compare.c b/src/compare.c index c88d3bc..ce7d751 100644 --- a/src/compare.c +++ b/src/compare.c @@ -1,5 +1,6 @@ -#include // uint8_t +#include // bool #include // NULL, size_t +#include // uint8_t #include // memcpy, strncmp #include "../include/allocator.h" // GVA_Allocator @@ -9,7 +10,7 @@ #include "../include/relations.h" // GVA_Relation, GVA_CONTAINS, GVA_DISJOINT, // GVA_EQUIVALENT GVA_IS_CONTAINED, GVA_OVERLAP #include "../include/types.h" // GVA_NULL, gva_uint -#include "../include/variant.h" // GVA_Variant +#include "../include/variant.h" // GVA_Variant, gva_variant_eq #include "array.h" // ARRAY_DESTROY, array_length #include "common.h" // MAX, MIN #include "bitset.h" // bitset_* @@ -99,6 +100,118 @@ bitset_fill(GVA_LCS_Graph const graph, } // bitset_fill +GVA_Relation +gva_compare_graphs(GVA_Allocator const allocator, + size_t const len_ref, char const reference[static len_ref], + GVA_LCS_Graph const lhs, GVA_LCS_Graph const rhs) +{ + if (gva_variant_eq(lhs.supremal, rhs.supremal)) + { + return GVA_EQUIVALENT; + } // if + + if (lhs.supremal.start > rhs.supremal.end || rhs.supremal.start > lhs.supremal.end) + { + return GVA_DISJOINT; + } // if + + size_t const start = MIN(lhs.supremal.start, rhs.supremal.start); + size_t const end = MAX(lhs.supremal.end, rhs.supremal.end); + + size_t const lhs_len = (lhs.supremal.start - start) + lhs.supremal.sequence.len + (end - lhs.supremal.end); + size_t const rhs_len = (rhs.supremal.start - start) + rhs.supremal.sequence.len + (end - rhs.supremal.end); + + size_t distance = 0; + if (lhs_len == 0) + { + distance = rhs_len; + } // if + else if (rhs_len == 0) + { + distance = lhs_len; + } // if + else + { + char* lhs_obs = allocator.allocate(allocator.context, NULL, 0, lhs_len); + if (lhs_obs == NULL) + { + return GVA_DISJOINT; // FIXME: error + } // if + memcpy(lhs_obs, reference + start, lhs.supremal.start - start); + memcpy(lhs_obs + lhs.supremal.start - start, lhs.supremal.sequence.str, lhs.supremal.sequence.len); + memcpy(lhs_obs + lhs.supremal.start - start + lhs.supremal.sequence.len, reference + lhs.supremal.end, end - lhs.supremal.end); + + char* rhs_obs = allocator.allocate(allocator.context, NULL, 0, rhs_len); + if (rhs_obs == NULL) + { + lhs_obs = allocator.allocate(allocator.context, lhs_obs, lhs_len, 0); + return GVA_DISJOINT; // FIXME: error + } // if + memcpy(rhs_obs, reference + start, rhs.supremal.start - start); + memcpy(rhs_obs + rhs.supremal.start - start, rhs.supremal.sequence.str, rhs.supremal.sequence.len); + memcpy(rhs_obs + rhs.supremal.start - start + rhs.supremal.sequence.len, reference + rhs.supremal.end, end - rhs.supremal.end); + + distance = gva_edit_distance(allocator, lhs_len, lhs_obs, rhs_len, rhs_obs); + rhs_obs = allocator.allocate(allocator.context, rhs_obs, rhs_len, 0); + lhs_obs = allocator.allocate(allocator.context, lhs_obs, lhs_len, 0); + } // else + + if (lhs.distance + rhs.distance == distance) + { + return GVA_DISJOINT; + } // if + + if (lhs.distance - rhs.distance == distance) + { + return GVA_CONTAINS; + } // if + + if (rhs.distance - lhs.distance == distance) + { + return GVA_IS_CONTAINED; + } // if + + gva_uint const len = end - start + 1; + size_t* lhs_dels = bitset_init(allocator, len); // can be one shorter + size_t* lhs_as = bitset_init(allocator, len); + size_t* lhs_cs = bitset_init(allocator, len); + size_t* lhs_gs = bitset_init(allocator, len); + size_t* lhs_ts = bitset_init(allocator, len); + + size_t* rhs_dels = bitset_init(allocator, len); // can be one shorter + size_t* rhs_as = bitset_init(allocator, len); + size_t* rhs_cs = bitset_init(allocator, len); + size_t* rhs_gs = bitset_init(allocator, len); + size_t* rhs_ts = bitset_init(allocator, len); + + size_t const start_intersection = MAX(lhs.supremal.start, rhs.supremal.start); + size_t const end_intersection = MIN(lhs.supremal.end, rhs.supremal.end); + + bitset_fill(lhs, start, start_intersection, end_intersection, lhs_dels, lhs_as, lhs_cs, lhs_gs, lhs_ts); + bitset_fill(rhs, start, start_intersection, end_intersection, rhs_dels, rhs_as, rhs_cs, rhs_gs, rhs_ts); + + bool const overlap = bitset_intersection_cnt(lhs_dels, rhs_dels) > 0 || + bitset_intersection_cnt(lhs_as, rhs_as) > 0 || + bitset_intersection_cnt(lhs_cs, rhs_cs) > 0 || + bitset_intersection_cnt(lhs_gs, rhs_gs) > 0 || + bitset_intersection_cnt(lhs_ts, rhs_ts) > 0; + + rhs_ts = bitset_destroy(allocator, rhs_ts); + rhs_gs = bitset_destroy(allocator, rhs_gs); + rhs_cs = bitset_destroy(allocator, rhs_cs); + rhs_as = bitset_destroy(allocator, rhs_as); + rhs_dels = bitset_destroy(allocator, rhs_dels); + + lhs_ts = bitset_destroy(allocator, lhs_ts); + lhs_gs = bitset_destroy(allocator, lhs_gs); + lhs_cs = bitset_destroy(allocator, lhs_cs); + lhs_as = bitset_destroy(allocator, lhs_as); + lhs_dels = bitset_destroy(allocator, lhs_dels); + + return overlap ? GVA_OVERLAP : GVA_DISJOINT; +} // gva_compare_graphs + + GVA_Relation gva_compare_supremals(GVA_Allocator const allocator, size_t const len_ref, char const reference[static len_ref], @@ -106,9 +219,7 @@ gva_compare_supremals(GVA_Allocator const allocator, { GVA_Relation relation; - if (lhs.start == rhs.start && lhs.end == rhs.end && - lhs.sequence.len == rhs.sequence.len && - strncmp(lhs.sequence.str, rhs.sequence.str, MIN(lhs.sequence.len, rhs.sequence.len)) == 0) + if (gva_variant_eq(lhs, rhs)) { return GVA_EQUIVALENT; } // if From d3b045ac18ac2923c26c568a579594f9be7fe69c Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 8 Aug 2025 14:33:22 +0200 Subject: [PATCH 320/704] WIP: pytests for compare --- python/algebra/relations/__init__.py | 12 ++++++++++++ python/tests/test_compare.py | 17 ++++++++++++----- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/python/algebra/relations/__init__.py b/python/algebra/relations/__init__.py index 2f1ff69..fe76e0c 100644 --- a/python/algebra/relations/__init__.py +++ b/python/algebra/relations/__init__.py @@ -1,3 +1,15 @@ +"""Calculate the relation between two variants using the definitions +from [1]_. Variants are given as alleles, i.e., a list of variants +applied to some reference sequence. Both variants are subject to the same +reference sequence. + +References +---------- +[1] J.K. Vis, M.A. Santcroos, W.A. Kosters and J.F.J. Laros. +"A Boolean Algebra for Genetic Variants." In: Bioinformatics (2023). +""" + + from algebra_ext import Relation, compare diff --git a/python/tests/test_compare.py b/python/tests/test_compare.py index 6593441..68326f6 100644 --- a/python/tests/test_compare.py +++ b/python/tests/test_compare.py @@ -2,8 +2,15 @@ from algebra import LCSgraph, Relation, Variant, compare -def test_compare(): - reference = "AAAAA" - lhs = LCSgraph.from_variants(reference, [Variant(0, 0, "T")]) - rhs = LCSgraph.from_variants(reference, [Variant(0, 0, "TA")]) - assert compare(reference, lhs, rhs) == Relation.is_contained +@pytest.mark.parametrize("reference, lhs, rhs, expected", [ + ("CC", [Variant(0, 0, "C"), Variant(1, 2, "")], [Variant(0, 0, "C"), Variant(1, 1, "T")], Relation.disjoint), + ("CTCCG", [Variant(4, 4, "TCC")], [Variant(0, 0, "GT")], Relation.overlap), + ("CCCCC", [Variant(4, 5, "")], [Variant(0, 1, "")], Relation.equivalent), + ("AACCCCTTGTTC", [Variant(2, 2, "C")], [Variant(6, 7, "C")], Relation.is_contained), + ("AACATTTC", [Variant(1, 1, "AC")], [Variant(4, 5, "C")], Relation.overlap), + ("AAA", [Variant(1, 1, "T")], [Variant(1, 1, "C")], Relation.disjoint), +]) +def test_compare(reference, lhs, rhs, expected): + lhs_graph = LCSgraph.from_variants(reference, lhs) + rhs_graph = LCSgraph.from_variants(reference, rhs) + assert compare(reference, lhs_graph, rhs_graph) == expected From 2da15f0e07cd9428d78bc23dfe4edfc56884a611 Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 11 Aug 2025 09:07:44 +0200 Subject: [PATCH 321/704] Better? Python module --- python/algebra/__init__.py | 4 +- python/algebra/relations/__init__.py | 4 +- python/algebra_extmodule.c | 535 +++++++++++++++++++++++++++ python/ext/algebra_ext.c | 122 ------ python/ext/lcsgraph.c | 211 ----------- python/ext/lcsgraph.h | 21 -- python/ext/variant.c | 113 ------ python/ext/variant.h | 22 -- python/setup.py | 9 +- python/tests/test_compare.py | 14 +- 10 files changed, 548 insertions(+), 507 deletions(-) create mode 100644 python/algebra_extmodule.c delete mode 100644 python/ext/algebra_ext.c delete mode 100644 python/ext/lcsgraph.c delete mode 100644 python/ext/lcsgraph.h delete mode 100644 python/ext/variant.c delete mode 100644 python/ext/variant.h diff --git a/python/algebra/__init__.py b/python/algebra/__init__.py index 1dd0f8c..6a9bd6d 100644 --- a/python/algebra/__init__.py +++ b/python/algebra/__init__.py @@ -2,13 +2,13 @@ from .lcs import LCSgraph -from .relations import Relation, compare +from .relations import Relations, compare from .variants import Variant __all__ = [ "LCSgraph", - "Relation", + "Relations", "Variant", "compare", ] diff --git a/python/algebra/relations/__init__.py b/python/algebra/relations/__init__.py index fe76e0c..ac9632a 100644 --- a/python/algebra/relations/__init__.py +++ b/python/algebra/relations/__init__.py @@ -10,10 +10,10 @@ """ -from algebra_ext import Relation, compare +from algebra_ext import Relations, compare __all__ = [ - "Relation", + "Relations", "compare", ] diff --git a/python/algebra_extmodule.c b/python/algebra_extmodule.c new file mode 100644 index 0000000..d7bb759 --- /dev/null +++ b/python/algebra_extmodule.c @@ -0,0 +1,535 @@ +#define PY_SSIZE_T_CLEAN +#include // Py* + +#include // bool +#include // NULL, offsetof, size_t + +#include "../include/compare.h" // gva_compare_graphs +#include "../include/extractor.h" // gva_canonical +#include "../include/lcs_graph.h" // GVA_LCS_Graph, gva_lcs_graph_*, gva_edges +#include "../include/std_alloc.h" // gva_std_allocator +#include "../include/string.h" // gva_string_destroy +#include "../include/variant.h" // GVA_VARIANT_*, GVA_Variant, gva_variant_* +#include "../src/array.h" // ARRAY_DESTROY, array_length + + +// DEBUG: PySys_FormatStderr + + +typedef struct LCSgraph_Object +{ + PyObject_VAR_HEAD + GVA_LCS_Graph graph; +} LCSgraph_Object; + + +typedef struct Variant_Object +{ + PyObject_VAR_HEAD + Py_ssize_t start; + Py_ssize_t end; + Py_ssize_t len; + char const* sequence; +} Variant_Object; + + +typedef struct +{ + PyTypeObject* LCSgraph_Type; + PyTypeObject* Variant_Type; + PyObject* Relations; +} algebra_ext_state; + + +static inline algebra_ext_state* +get_algebra_ext_state(PyObject* module) +{ + return (algebra_ext_state*) PyModule_GetState(module); +} // get_algebra_ext_state + + +static inline PyObject* +LCSgraph_new(PyTypeObject* subtype, PyObject* Py_UNUSED(args), PyObject* Py_UNUSED(kwargs)) +{ + return subtype->tp_alloc(subtype, 0); +} // LCSgraph_new + + +static inline void +LCSgraph_dealloc(LCSgraph_Object* self) +{ + // FIXME: obeserved ownership + gva_string_destroy(gva_std_allocator, self->graph.observed); + gva_lcs_graph_destroy(gva_std_allocator, self->graph); + Py_TYPE(self)->tp_free((PyObject*) self); +} // LCSgraph_dealloc + + +static PyObject* +LCSgraph_from_variants(PyObject* cls, PyObject* args, PyObject* kwargs) +{ + algebra_ext_state* state = get_algebra_ext_state(PyType_GetModule((PyTypeObject*) cls)); + if (state == NULL) + { + return NULL; + } // if + + char const* reference = NULL; + Py_ssize_t len_ref = 0; + PyObject* variant_list = NULL; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#O!|", + (char*[]) {"reference", "variants", NULL}, + &reference, &len_ref, &PyList_Type, &variant_list)) + { + return NULL; + } // if + + size_t const n = PyList_GET_SIZE(variant_list); + GVA_Variant* variants = gva_std_allocator.allocate(gva_std_allocator.context, NULL, 0, n * sizeof(*variants)); + if (variants == NULL) + { + return PyErr_NoMemory(); + } // if + + for (Py_ssize_t i = 0; i < PyList_GET_SIZE(variant_list); ++i) + { + Variant_Object* item = NULL; + if (!PyArg_Parse(PyList_GET_ITEM(variant_list, i), "O!", state->Variant_Type, &item)) + { + variants = gva_std_allocator.allocate(gva_std_allocator.context, variants, n * sizeof(*variants), 0); + return NULL; + } // if + variants[i] = (GVA_Variant) {item->start, item->end, {item->len, item->sequence}}; + } // for + + LCSgraph_Object* self = (LCSgraph_Object*) PyObject_CallNoArgs(cls); + if (self == NULL) + { + variants = gva_std_allocator.allocate(gva_std_allocator.context, variants, n * sizeof(*variants), 0); + return NULL; + } // if + + self->graph = gva_lcs_graph_from_variants(gva_std_allocator, len_ref, reference, n, variants); + + variants = gva_std_allocator.allocate(gva_std_allocator.context, variants, n * sizeof(*variants), 0); + return (PyObject*) self; +} // LCSgraph_from_variants + + +static PyObject* +LCSgraph_canonical(LCSgraph_Object* self) +{ + algebra_ext_state* state = get_algebra_ext_state(PyType_GetModule(Py_TYPE(self))); + if (state == NULL) + { + return NULL; + } // if + + GVA_Variant* variants = gva_canonical(gva_std_allocator, self->graph); + + PyObject* result = PyList_New(array_length(variants)); + if (result == NULL) + { + variants = ARRAY_DESTROY(gva_std_allocator, variants); + return NULL; + } // if + + for (size_t i = 0; i < array_length(variants); ++i) + { + PyObject* str = PyUnicode_FromStringAndSize(variants[i].sequence.str, variants[i].sequence.len); + if (str == NULL) + { + Py_DECREF(result); + variants = ARRAY_DESTROY(gva_std_allocator, variants); + return NULL; + } // if + PyObject* item = PyObject_CallFunction((PyObject*) state->Variant_Type, "nnO", variants[i].start, variants[i].end, str); + Py_DECREF(str); + if (item == NULL) + { + Py_DECREF(result); + variants = ARRAY_DESTROY(gva_std_allocator, variants); + return NULL; + } // if + PyList_SET_ITEM(result, i, item); + } // for + + variants = ARRAY_DESTROY(gva_std_allocator, variants); + return result; +} // LCSgraph_canonical + + +static PyObject* +LCSgraph_local_supremal(LCSgraph_Object* self) +{ + algebra_ext_state* state = get_algebra_ext_state(PyType_GetModule(Py_TYPE(self))); + if (state == NULL) + { + return NULL; + } // if + + PyObject* result = PyList_New(array_length(self->graph.local_supremal) - 1); + if (result == NULL) + { + return NULL; + } // if + + for (size_t i = 0; i < array_length(self->graph.local_supremal) - 1; ++i) + { + GVA_Variant variant; + gva_edges(self->graph.observed.str, + self->graph.local_supremal[i], self->graph.local_supremal[i + 1], + i == 0, i == array_length(self->graph.local_supremal) - 2, + &variant); + + PyObject* str = PyUnicode_FromStringAndSize(variant.sequence.str, variant.sequence.len); + if (str == NULL) + { + Py_DECREF(result); + return NULL; + } // if + PyObject* item = PyObject_CallFunction((PyObject*) state->Variant_Type, "nnO", variant.start, variant.end, str); + Py_DECREF(str); + if (item == NULL) + { + Py_DECREF(result); + return NULL; + } // if + PyList_SET_ITEM(result, i, item); + } // for + return result; +} // LCSgraph_local_supremal + + +static PyObject* +LCSgraph_supremal(LCSgraph_Object* self) +{ + algebra_ext_state* state = get_algebra_ext_state(PyType_GetModule(Py_TYPE(self))); + if (state == NULL) + { + return NULL; + } // if + + PyObject* str = PyUnicode_FromStringAndSize(self->graph.supremal.sequence.str, self->graph.supremal.sequence.len); + if (str == NULL) + { + return NULL; + } // if + PyObject* result = PyObject_CallFunction((PyObject*) state->Variant_Type, "nnO", self->graph.supremal.start, self->graph.supremal.end, str); + Py_DECREF(str); + return result; +} // LCSgraph_supremal + + +static PyObject* +Variant_new(PyTypeObject* subtype, PyObject* args, PyObject* kwargs) +{ + Py_ssize_t start = 0; + Py_ssize_t end = 0; + char const* sequence = NULL; + Py_ssize_t len = 0; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "nns#|:Variant", + (char*[]) {"start", "end", "sequence", NULL}, + &start, &end, &sequence, &len)) + { + return NULL; + } // if + + Variant_Object* const self = (Variant_Object*) subtype->tp_alloc(subtype, 0); + if (self == NULL) + { + return NULL; + } // if + + self->start = start; + self->end = end; + self->len = len; + self->sequence = sequence; + return (PyObject*) self; +} // Variant_new + + +static inline void +Variant_dealloc(Variant_Object* self) +{ + Py_TYPE(self)->tp_free((PyObject*) self); +} // Variant_dealloc + + +static inline PyObject* +Variant_repr(Variant_Object* self) +{ + return PyUnicode_FromFormat(GVA_VARIANT_FMT, GVA_VARIANT_PRINT(((GVA_Variant) {self->start, self->end, {self->len, self->sequence}}))); +} // Variant_repr + + +static PyObject* +Variant_richcompare(Variant_Object* self, Variant_Object* other, int op) +{ + algebra_ext_state* state = get_algebra_ext_state(PyType_GetModule(Py_TYPE(self))); + if (state == NULL) + { + return NULL; + } // if + + if(Py_IS_TYPE(other, state->Variant_Type) == 0) + { + Py_RETURN_NOTIMPLEMENTED; + } // if + + bool const equal = self == other || + gva_variant_eq((GVA_Variant) {self->start, self->end, {self->len, self->sequence}}, + (GVA_Variant) {other->start, other->end, {other->len, other->sequence}}); + switch (op) + { + //case Py_LT: + //case Py_LE: + case Py_EQ: + if (equal) + { + Py_RETURN_TRUE; + } // if + Py_RETURN_FALSE; + case Py_NE: + if (equal) + { + Py_RETURN_FALSE; + } // if + Py_RETURN_TRUE; + //case Py_GT: + //case Py_GE: + } // switch + Py_RETURN_NOTIMPLEMENTED; +} // Variant_richcompare + + +static PyType_Spec LCSgraph_Spec = +{ + .name = "algebra_ext.LCSgraph", + .basicsize = sizeof(LCSgraph_Object), + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_IMMUTABLETYPE, + .slots = (PyType_Slot[]) + { + {Py_tp_doc, PyDoc_STR("LCS graph class for storing all minimal alignments.")}, + {Py_tp_new, LCSgraph_new}, + {Py_tp_dealloc, LCSgraph_dealloc}, + {Py_tp_methods, (PyMethodDef[]) + { + { + "from_variants", + (PyCFunction) LCSgraph_from_variants, + METH_CLASS | METH_VARARGS | METH_KEYWORDS, + PyDoc_STR("from_variants(reference, variants)\n\n Iteratively find the supremal LCS graph for an allele by repeatedly widening a range of influence."), + }, + { + "canonical", + (PyCFunction) LCSgraph_canonical, + METH_NOARGS, + PyDoc_STR("The canonical variant."), + }, + { + "local_supremal", + (PyCFunction) LCSgraph_local_supremal, + METH_NOARGS, + PyDoc_STR("The local supremal variant."), + }, + { + "supremal", + (PyCFunction) LCSgraph_supremal, + METH_NOARGS, + PyDoc_STR("The supremal variant."), + }, + {NULL, NULL, 0, NULL} // sentinel + }, + }, + {0, NULL} // sentinel + }, +}; + + +static PyType_Spec Variant_Spec = +{ + .name = "algebra_ext.Variant", + .basicsize = sizeof(Variant_Object), + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_IMMUTABLETYPE, + .slots = (PyType_Slot[]) + { + {Py_tp_doc, PyDoc_STR("Variant(start, end, inserted)\n\n Variant class for deletions/insertions.")}, + {Py_tp_new, Variant_new}, + {Py_tp_dealloc, Variant_dealloc}, + {Py_tp_repr, Variant_repr}, + {Py_tp_richcompare, Variant_richcompare}, + {Py_tp_members, (PyMemberDef[]) + { + {"end", Py_T_PYSSIZET, offsetof(Variant_Object, end), Py_READONLY, PyDoc_STR("The end position (not included) of the deleted part.")}, + {"sequence", Py_T_STRING, offsetof(Variant_Object, sequence), Py_READONLY, PyDoc_STR("The inserted sequence.")}, + {"start", Py_T_PYSSIZET, offsetof(Variant_Object, start), Py_READONLY, PyDoc_STR("The start position (included) of the deleted part (zero-based).")}, + {NULL} // sentinel + } + }, + {0, NULL} // sentinel + }, +}; + + +static int +algebra_ext_clear(PyObject* module) +{ + algebra_ext_state* state = get_algebra_ext_state(module); + Py_CLEAR(state->LCSgraph_Type); + Py_CLEAR(state->Variant_Type); + Py_CLEAR(state->Relations); + return 0; +} // algebra_ext_clear + + +static inline void +algebra_ext_free(void* module) +{ + algebra_ext_clear(module); +} // algebra_ext_free + + +static int +algebra_ext_mod_exec(PyObject* module) +{ + algebra_ext_state* state = get_algebra_ext_state(module); + + state->LCSgraph_Type = (PyTypeObject*) PyType_FromModuleAndSpec(module, &LCSgraph_Spec, NULL); + if (state->LCSgraph_Type == NULL) + { + Py_DECREF(module); + return -1; + } // if + + state->Variant_Type = (PyTypeObject*) PyType_FromModuleAndSpec(module, &Variant_Spec, NULL); + if (state->Variant_Type == NULL) + { + Py_DECREF(module); + return -1; + } // if + + if (PyModule_AddObjectRef(module, "LCSgraph", (PyObject*) state->LCSgraph_Type) < 0) + { + Py_DECREF(module); + return -1; + } // if + + if (PyModule_AddObjectRef(module, "Variant", (PyObject*) state->Variant_Type) < 0) + { + Py_DECREF(module); + return -1; + } // if + + PyObject* dict_relations = PyDict_New(); + if (dict_relations == NULL) + { + Py_DECREF(module); + return -1; + } // if + + for (size_t i = 0; i < sizeof(GVA_RELATION_LABELS) / sizeof(*GVA_RELATION_LABELS); ++i) + { + PyObject* value = PyUnicode_InternFromString(GVA_RELATION_LABELS[i]); + if (value == NULL) + { + Py_DECREF(dict_relations); + Py_DECREF(module); + return -1; + } // if + + if (PyDict_SetItemString(dict_relations, GVA_RELATION_LABELS[i], value) < 0) + { + Py_DECREF(value); + Py_DECREF(dict_relations); + Py_DECREF(module); + return -1; + } // if + Py_DECREF(value); + } // for + + PyObject* module_enum = PyImport_ImportModule("enum"); + if (module_enum == NULL) + { + Py_DECREF(dict_relations); + Py_DECREF(module); + return -1; + } // if + + state->Relations = PyObject_CallMethod(module_enum, "Enum", "sO", "Relations", dict_relations); + Py_DECREF(dict_relations); + Py_DECREF(module_enum); + + if (state->Relations == NULL) + { + Py_DECREF(module); + return -1; + } // if + + if (PyModule_AddObjectRef(module, "Relations", (PyObject*) state->Relations) < 0) + { + Py_DECREF(module); + return -1; + } // if + + return 0; +} // algebra_ext_mod_exec + + +static PyObject* +algebra_ext_compare(PyObject* self, PyObject* args, PyObject* kwargs) +{ + algebra_ext_state* state = get_algebra_ext_state(self); + if (state == NULL) + { + return NULL; + } // if + + char const* reference = NULL; + Py_ssize_t len_ref = 0; + LCSgraph_Object* lhs = NULL; + LCSgraph_Object* rhs = NULL; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#O!O!|", + (char*[]) {"reference", "lhs", "rhs", NULL}, + &reference, &len_ref, state->LCSgraph_Type, &lhs, state->LCSgraph_Type, &rhs)) + { + return NULL; + } // if + + GVA_Relation const relation = gva_compare_graphs(gva_std_allocator, len_ref, reference, lhs->graph, rhs->graph); + return PyObject_GetAttrString(state->Relations, GVA_RELATION_LABELS[relation]); +} // algebra_ext_compare + + +static struct PyModuleDef algebra_ext_module = +{ + PyModuleDef_HEAD_INIT, + .m_name = "algebra_ext", + .m_size = sizeof(algebra_ext_state), + .m_doc = PyDoc_STR("Genetic Variant Algebra C extension."), + .m_methods = (PyMethodDef[]) + { + { + "compare", + (PyCFunction) algebra_ext_compare, + METH_VARARGS | METH_KEYWORDS, + PyDoc_STR("compare(reference, lhs, rhs)\n\n Determine the relation between two LCS graphs."), + }, + {NULL, NULL, 0, NULL} // sentinel + }, + .m_slots = (PyModuleDef_Slot[]) + { + {Py_mod_exec, algebra_ext_mod_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, + {0, NULL} // sentinel + }, + .m_clear = algebra_ext_clear, + .m_free = algebra_ext_free, +}; + + +PyMODINIT_FUNC +PyInit_algebra_ext(void) +{ + return PyModuleDef_Init(&algebra_ext_module); +} // PyInit_algebra_ext diff --git a/python/ext/algebra_ext.c b/python/ext/algebra_ext.c deleted file mode 100644 index cc903c5..0000000 --- a/python/ext/algebra_ext.c +++ /dev/null @@ -1,122 +0,0 @@ -#define PY_SSIZE_T_CLEAN -#include // Py* - -#include // NULL - -#include "lcsgraph.h" // LCSgraph, LCSgraph_* -#include "variant.h" // Variant, Variant_* - -#include "../include/compare.h" // gva_compare_graphs -#include "../include/relations.h" // GVA_RELATION_LABELS, GVA_Relation -#include "../include/std_alloc.h" // gva_std_allocator - - -// DEBUG: PySys_FormatStderr - - -static PyObject* -algebra_ext_compare(PyObject* self, PyObject* args, PyObject* kwargs) -{ - char const* reference = NULL; - Py_ssize_t len_ref = 0; - LCSgraph* lhs = NULL; - LCSgraph* rhs = NULL; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#O!O!|:compare", - (char*[]) {"reference", "lhs", "rhs", NULL}, - &reference, &len_ref, &LCSgraph_Type, &lhs, &LCSgraph_Type, &rhs)) - { - return NULL; - } // if - - GVA_Relation const relation = gva_compare_graphs(gva_std_allocator, len_ref, reference, lhs->graph, rhs->graph); - - PyObject* relations = PyObject_GetAttrString(self, "Relation"); - if (relations == NULL) - { - return NULL; - } // if - - PyObject* result = PyObject_GetAttrString(relations, GVA_RELATION_LABELS[relation]); - Py_DECREF(relations); - return result; -} // algebra_ext_compare - - -static PyModuleDef algebra_ext_module = -{ - PyModuleDef_HEAD_INIT, - .m_name = "algebra_ext", - .m_doc = PyDoc_STR("Algebra C extension"), - .m_size = -1, - .m_methods = (PyMethodDef[]) - { - { - "compare", - (PyCFunction) algebra_ext_compare, - METH_VARARGS | METH_KEYWORDS, - PyDoc_STR("Compare two LCS graphs."), - }, - {NULL} // sentinel - }, -}; - - -PyMODINIT_FUNC -PyInit_algebra_ext(void) -{ - PyObject* const module = PyModule_Create(&algebra_ext_module); - if (module == NULL) - { - return NULL; - } // if - - if (PyType_Ready(&LCSgraph_Type) < 0) - { - return NULL; - } // if - if (PyType_Ready(&Variant_Type) < 0) - { - return NULL; - } // if - - if (PyModule_AddObjectRef(module, "LCSgraph", (PyObject*) &LCSgraph_Type) < 0) - { - return NULL; - } // if - if (PyModule_AddObjectRef(module, "Variant", (PyObject*) &Variant_Type) < 0) - { - return NULL; - } // if - - PyObject* relations = PyDict_New(); - if (relations == NULL) - { - return NULL; - } // if - for (size_t i = 0; i < sizeof(GVA_RELATION_LABELS) / sizeof(*GVA_RELATION_LABELS); ++i) - { - PyDict_SetItemString(relations, GVA_RELATION_LABELS[i], PyUnicode_FromString(GVA_RELATION_LABELS[i])); - } // for - - PyObject* module_enum = PyImport_ImportModule("enum"); - if (module_enum == NULL) - { - return NULL; - } // if - - PyObject* enum_class = PyObject_CallMethod(module_enum, "Enum", "sO", "Relation", relations); - if (enum_class == NULL) - { - return NULL; - } // if - - Py_DECREF(module_enum); - Py_DECREF(relations); - - if (PyModule_AddObject(module, "Relation", enum_class) < 0) - { - return NULL; - } // if - - return module; -} // PyInit_algebra_ext diff --git a/python/ext/lcsgraph.c b/python/ext/lcsgraph.c deleted file mode 100644 index f92f6d9..0000000 --- a/python/ext/lcsgraph.c +++ /dev/null @@ -1,211 +0,0 @@ -#define PY_SSIZE_T_CLEAN -#include // Py* - -#include // NULL, size_t - -#include "lcsgraph.h" // LCSgraph, LCSgraph_* -#include "variant.h" // Variant, Variant_* - -#include "../include/extractor.h" // gva_canonical -#include "../include/lcs_graph.h" // GVA_LCS_Graph, gva_lcs_graph_*, gva_edges -#include "../include/std_alloc.h" // gva_std_allocator -#include "../include/string.h" // gva_string_destroy -#include "../include/types.h" // GVA_NULL -#include "../include/variant.h" // GVA_Variant -#include "../src/array.h" // ARRAY_DESTROY, array_length - - -static PyObject* -LCSgraph_new(PyTypeObject* subtype, PyObject* Py_UNUSED(args), PyObject* Py_UNUSED(kwargs)) -{ - LCSgraph* const self = (LCSgraph*) subtype->tp_alloc(subtype, 0); - if (self == NULL) - { - return NULL; - } // if - return (PyObject*) self; -} // LCSgraph_new - - -static inline void -LCSgraph_dealloc(LCSgraph* self) -{ - gva_string_destroy(gva_std_allocator, self->graph.observed); - gva_lcs_graph_destroy(gva_std_allocator, self->graph); - Py_TYPE(self)->tp_free((PyObject*) self); -} // LCSgraph_dealloc - - -static PyObject* -LCSgraph_from_variants(PyObject* cls, PyObject* args, PyObject* kwargs) -{ - char const* reference = NULL; - Py_ssize_t len_ref = 0; - PyObject* variant_list = NULL; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#O!|:from_variants", - (char*[]) {"reference", "variants", NULL}, - &reference, &len_ref, &PyList_Type, &variant_list)) - { - return NULL; - } // if - - GVA_Variant* variants = gva_std_allocator.allocate(gva_std_allocator.context, NULL, 0, PyList_GET_SIZE(variant_list) * sizeof(*variants)); - if (variants == NULL) - { - PyErr_SetString(PyExc_MemoryError, "OOM"); - return NULL; - } // if - - for (Py_ssize_t i = 0; i < PyList_GET_SIZE(variant_list); ++i) - { - Variant* item = NULL; - if (!PyArg_Parse(PyList_GET_ITEM(variant_list, i), "O!", &Variant_Type, &item)) - { - variants = gva_std_allocator.allocate(gva_std_allocator.context, variants, PyList_GET_SIZE(variant_list) * sizeof(*variants), 0); - return NULL; - } // if - variants[i] = (GVA_Variant) {item->start, item->end, {item->len, item->sequence}}; - } // for - - LCSgraph* self = (LCSgraph*) PyObject_CallNoArgs(cls); - if (self == NULL) - { - variants = gva_std_allocator.allocate(gva_std_allocator.context, variants, PyList_GET_SIZE(variant_list) * sizeof(*variants), 0); - return NULL; - } // if - - self->graph = gva_lcs_graph_from_variants(gva_std_allocator, len_ref, reference, PyList_GET_SIZE(variant_list), variants); - - variants = gva_std_allocator.allocate(gva_std_allocator.context, variants, PyList_GET_SIZE(variant_list) * sizeof(*variants), 0); - return (PyObject*) self; -} // LCSgraph_from_variants - - -static PyObject* -LCSgraph_canonical(LCSgraph* self) -{ - GVA_Variant* variants = gva_canonical(gva_std_allocator, self->graph); - - PyObject* result = PyList_New(array_length(variants)); - if (result == NULL) - { - variants = ARRAY_DESTROY(gva_std_allocator, variants); - return NULL; - } // if - - for (size_t i = 0; i < array_length(variants); ++i) - { - PyObject* str = PyUnicode_FromStringAndSize(variants[i].sequence.str, variants[i].sequence.len); - if (str == NULL) - { - Py_DECREF(result); - variants = ARRAY_DESTROY(gva_std_allocator, variants); - return NULL; - } // if - PyObject* item = PyObject_CallFunction((PyObject*) &Variant_Type, "nnO", variants[i].start, variants[i].end, str); - if (item == NULL) - { - Py_DECREF(str); - Py_DECREF(result); - variants = ARRAY_DESTROY(gva_std_allocator, variants); - return NULL; - } // if - PyList_SET_ITEM(result, i, item); - } // for - - variants = ARRAY_DESTROY(gva_std_allocator, variants); - return result; -} // LCSgraph_canonical - - -static PyObject* -LCSgraph_local_supremal(LCSgraph* self) -{ - PyObject* result = PyList_New(array_length(self->graph.local_supremal) - 1); - if (result == NULL) - { - return NULL; - } // if - - for (size_t i = 0; i < array_length(self->graph.local_supremal) - 1; ++i) - { - GVA_Variant variant; - gva_edges(self->graph.observed.str, - self->graph.local_supremal[i], self->graph.local_supremal[i + 1], - i == 0, i == array_length(self->graph.local_supremal) - 2, - &variant); - - PyObject* str = PyUnicode_FromStringAndSize(variant.sequence.str, variant.sequence.len); - if (str == NULL) - { - Py_DECREF(result); - return NULL; - } // if - PyObject* item = PyObject_CallFunction((PyObject*) &Variant_Type, "nnO", variant.start, variant.end, str); - if (item == NULL) - { - Py_DECREF(str); - Py_DECREF(result); - return NULL; - } // if - PyList_SET_ITEM(result, i, item); - } // for - return result; -} // LCSgraph_local_supremal - - -static PyObject* -LCSgraph_supremal(LCSgraph* self) -{ - PyObject* str = PyUnicode_FromStringAndSize(self->graph.supremal.sequence.str, self->graph.supremal.sequence.len); - if (str == NULL) - { - return NULL; - } // if - PyObject* result = PyObject_CallFunction((PyObject*) &Variant_Type, "nnO", self->graph.supremal.start, self->graph.supremal.end, str); - if (result == NULL) - { - Py_DECREF(str); - return NULL; - } // if - return result; -} // LCSgraph_supremal - - -PyTypeObject LCSgraph_Type = -{ - PyVarObject_HEAD_INIT(NULL, 0) - .tp_name = "algebra_ext.LCSgraph", - .tp_basicsize = sizeof(LCSgraph), - .tp_doc = PyDoc_STR("LCS graph class for storing all minimal alignments."), - .tp_new = (newfunc) LCSgraph_new, - .tp_dealloc = (destructor) LCSgraph_dealloc, - .tp_methods = (PyMethodDef[]) - { - { - "from_variants", - (PyCFunction) LCSgraph_from_variants, - METH_CLASS | METH_VARARGS | METH_KEYWORDS, - PyDoc_STR("Iteratively find the supremal LCS graph for an allele by repeatedly widening a range of influence."), - }, - { - "canonical", - (PyCFunction) LCSgraph_canonical, - METH_NOARGS, - PyDoc_STR("The canonical variant."), - }, - { - "local_supremal", - (PyCFunction) LCSgraph_local_supremal, - METH_NOARGS, - PyDoc_STR("The local supremal variant."), - }, - { - "supremal", - (PyCFunction) LCSgraph_supremal, - METH_NOARGS, - PyDoc_STR("The supremal variant."), - }, - {NULL} // sentinel - }, -}; diff --git a/python/ext/lcsgraph.h b/python/ext/lcsgraph.h deleted file mode 100644 index 7dd6e8f..0000000 --- a/python/ext/lcsgraph.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef EXT_LCSGRAPH_H -#define EXT_LCSGRAPH_H - - -#define PY_SSIZE_T_CLEAN -#include // Py* - -#include "../include/lcs_graph.h" // GVA_LCS_Graph - - -typedef struct -{ - PyObject_HEAD - GVA_LCS_Graph graph; -} LCSgraph; - - -extern PyTypeObject LCSgraph_Type; - - -#endif // EXT_LCSGRAPH_H diff --git a/python/ext/variant.c b/python/ext/variant.c deleted file mode 100644 index c73d13b..0000000 --- a/python/ext/variant.c +++ /dev/null @@ -1,113 +0,0 @@ -#define PY_SSIZE_T_CLEAN -#include // Py* - -#include // bool -#include // NULL, offsetof - -#include "variant.h" // Variant, Variant_* - -#include "../include/variant.h" // GVA_VARIANT_*, GVA_Variant, gva_variant_* - - -static PyObject* -Variant_new(PyTypeObject* subtype, PyObject* args, PyObject* kwargs) -{ - Py_ssize_t start = 0; - Py_ssize_t end = 0; - char const* sequence = NULL; - Py_ssize_t len = 0; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "nns#|:Variant", - (char*[]) {"start", "end", "sequence", NULL}, - &start, &end, &sequence, &len)) - { - return NULL; - } // if - - Variant* const self = (Variant*) subtype->tp_alloc(subtype, 0); - if (self == NULL) - { - return NULL; - } // if - - self->start = start; - self->end = end; - self->len = len; - self->sequence = sequence; - return (PyObject*) self; -} // Variant_new - - -static inline void -Variant_dealloc(Variant* self) -{ - Py_TYPE(self)->tp_free((PyObject*) self); -} // Variant_dealloc - - -static inline PyObject* -Variant_repr(Variant* self) -{ - return PyUnicode_FromFormat(GVA_VARIANT_FMT, GVA_VARIANT_PRINT(((GVA_Variant) {self->start, self->end, {self->len, self->sequence}}))); -} // Variant_repr - - -static PyObject* -Variant_richcompare(Variant* self, Variant* other, int op) -{ - PyObject* result = Py_NotImplemented; - bool const equal = gva_variant_eq((GVA_Variant) {self->start, self->end, {self->len, self->sequence}}, - (GVA_Variant) {other->start, other->end, {other->len, other->sequence}}); - switch (op) - { - //case Py_LT: - //case Py_LE: - case Py_EQ: - result = equal ? Py_True : Py_False; - break; - case Py_NE: - result = equal ? Py_False : Py_True; - break; - //case Py_GT: - //case Py_GE: - } // switch - Py_INCREF(result); - return result; -} // Variant_richcompare - - -PyTypeObject Variant_Type = -{ - PyVarObject_HEAD_INIT(NULL, 0) - .tp_name = "algebra_ext.Variant", - .tp_basicsize = sizeof(Variant), - .tp_doc = PyDoc_STR("Variant class for deletion/insertions."), - .tp_new = (newfunc) Variant_new, - .tp_dealloc = (destructor) Variant_dealloc, - .tp_repr = (reprfunc) Variant_repr, - .tp_richcompare = (richcmpfunc) Variant_richcompare, - .tp_members = (PyMemberDef[]) - { - { - "start", - Py_T_PYSSIZET, - offsetof(Variant, start), - Py_READONLY, - PyDoc_STR("The start position (included) of the deleted part (zero-based)."), - }, - { - "end", - Py_T_PYSSIZET, - offsetof(Variant, end), - Py_READONLY, - PyDoc_STR("The end position (not included) of the deleted part."), - }, - { - "sequence", - Py_T_STRING, - offsetof(Variant, sequence), - Py_READONLY, - PyDoc_STR("The inserted sequence."), - }, - {NULL} // sentinel - }, -}; diff --git a/python/ext/variant.h b/python/ext/variant.h deleted file mode 100644 index fedb311..0000000 --- a/python/ext/variant.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef EXT_VARIANT_H -#define EXT_VARIANT_H - - -#define PY_SSIZE_T_CLEAN -#include // Py* - - -typedef struct -{ - PyObject_HEAD - Py_ssize_t start; - Py_ssize_t end; - Py_ssize_t len; - char const* sequence; -} Variant; - - -extern PyTypeObject Variant_Type; - - -#endif // EXT_VARIANT_H diff --git a/python/setup.py b/python/setup.py index 7519e14..f944d77 100644 --- a/python/setup.py +++ b/python/setup.py @@ -6,16 +6,11 @@ Extension("algebra_ext", extra_compile_args=[ "-Wextra", - "-Wpedantic", "-Wno-cast-function-type", "-std=c99", - "-O3", - "-fanalyzer", ], sources=[ - "ext/algebra_ext.c", - "ext/lcsgraph.c", - "ext/variant.c", + "algebra_extmodule.c", "../src/align.c", "../src/array.c", "../src/bitset.c", @@ -27,4 +22,4 @@ "../src/variant.c", ]), ], -) +) \ No newline at end of file diff --git a/python/tests/test_compare.py b/python/tests/test_compare.py index 68326f6..e76525c 100644 --- a/python/tests/test_compare.py +++ b/python/tests/test_compare.py @@ -1,14 +1,14 @@ import pytest -from algebra import LCSgraph, Relation, Variant, compare +from algebra import LCSgraph, Relations, Variant, compare @pytest.mark.parametrize("reference, lhs, rhs, expected", [ - ("CC", [Variant(0, 0, "C"), Variant(1, 2, "")], [Variant(0, 0, "C"), Variant(1, 1, "T")], Relation.disjoint), - ("CTCCG", [Variant(4, 4, "TCC")], [Variant(0, 0, "GT")], Relation.overlap), - ("CCCCC", [Variant(4, 5, "")], [Variant(0, 1, "")], Relation.equivalent), - ("AACCCCTTGTTC", [Variant(2, 2, "C")], [Variant(6, 7, "C")], Relation.is_contained), - ("AACATTTC", [Variant(1, 1, "AC")], [Variant(4, 5, "C")], Relation.overlap), - ("AAA", [Variant(1, 1, "T")], [Variant(1, 1, "C")], Relation.disjoint), + ("CC", [Variant(0, 0, "C"), Variant(1, 2, "")], [Variant(0, 0, "C"), Variant(1, 1, "T")], Relations.disjoint), + ("CTCCG", [Variant(4, 4, "TCC")], [Variant(0, 0, "GT")], Relations.overlap), + ("CCCCC", [Variant(4, 5, "")], [Variant(0, 1, "")], Relations.equivalent), + ("AACCCCTTGTTC", [Variant(2, 2, "C")], [Variant(6, 7, "C")], Relations.is_contained), + ("AACATTTC", [Variant(1, 1, "AC")], [Variant(4, 5, "C")], Relations.overlap), + ("AAA", [Variant(1, 1, "T")], [Variant(1, 1, "C")], Relations.disjoint), ]) def test_compare(reference, lhs, rhs, expected): lhs_graph = LCSgraph.from_variants(reference, lhs) From 0621daed159ddc6ee5acbddb488d7f32928adc43 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 12 Aug 2025 12:51:31 +0200 Subject: [PATCH 322/704] Distances for local supremal parts --- src/lcs_graph.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/lcs_graph.c b/src/lcs_graph.c index 07c780c..af1ff13 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -3,6 +3,10 @@ #include // NULL, size_t #include // memcpy + +//#include // DEBUG + + #include "../include/allocator.h" // GVA_Allocator #include "../include/lcs_graph.h" // GVA_LCS_Graph, gva_lcs_graph_* #include "../include/string.h" // GVA_String, gva_string_* @@ -202,22 +206,29 @@ gva_lcs_graph_init(GVA_Allocator const allocator, gva_uint len = 0; gva_uint prev = GVA_NULL; + gva_uint prev_distance = 0; for (gva_uint i = 0; i < lcs.length; ++i) { if (prev == GVA_NULL && lcs.nodes[lcs.index[i].tail].idx != source.idx) { + gva_uint const distance = graph.nodes[source.idx].row + graph.nodes[source.idx].col - 2 * i; ARRAY_APPEND(allocator, graph.local_supremal, ((GVA_Node) { - graph.nodes[source.idx].row, graph.nodes[source.idx].col, 0, GVA_NULL, source.idx + graph.nodes[source.idx].row, graph.nodes[source.idx].col, 0, distance - prev_distance, source.idx })); + //fprintf(stderr, "0.APPEND %u: (%u, %u, %u) @ %u\n", i, graph.nodes[source.idx].row, graph.nodes[source.idx].col, 0, distance); + prev_distance = distance; } // if if (len > 0 && (lcs.index[i].count > 1 || prev != lcs.index[i].tail)) { gva_uint const idx = lcs.nodes[prev].idx; gva_uint const offset = graph.nodes[idx].length - lcs.index[i - 1].offset - len; + gva_uint const distance = graph.nodes[idx].row + graph.nodes[idx].col + 2 * offset + 2 * len - 2 * i; ARRAY_APPEND(allocator, graph.local_supremal, ((GVA_Node) { - graph.nodes[idx].row + offset, graph.nodes[idx].col + offset, len, GVA_NULL, idx + graph.nodes[idx].row + offset, graph.nodes[idx].col + offset, len, distance - prev_distance, idx })); + //fprintf(stderr, "1.APPEND %u: (%u, %u, %u) @ %u\n", i, graph.nodes[idx].row + offset, graph.nodes[idx].col + offset, len, distance); len = 0; + prev_distance = distance; } // if if (lcs.index[i].count == 1) { @@ -231,16 +242,21 @@ gva_lcs_graph_init(GVA_Allocator const allocator, { gva_uint const idx = lcs.nodes[prev].idx; gva_uint const offset = graph.nodes[idx].length - lcs.index[lcs.length - 1].offset - len; + gva_uint const distance = graph.nodes[idx].row + graph.nodes[idx].col + 2 * offset + 2 * len - 2 * (lcs.length - len); ARRAY_APPEND(allocator, graph.local_supremal, ((GVA_Node) { - graph.nodes[idx].row + offset, graph.nodes[idx].col + offset, len, GVA_NULL, idx + graph.nodes[idx].row + offset, graph.nodes[idx].col + offset, len, distance - prev_distance, idx })); + //fprintf(stderr, "2.APPEND %u: (%u, %u, %u) @ %u\n", lcs.length - len, graph.nodes[idx].row + offset, graph.nodes[idx].col + offset, len, distance); len = 0; + prev_distance = distance; } // if if (graph.nodes != NULL) { + gva_uint const distance = graph.nodes[0].row + graph.nodes[0].length - len + graph.nodes[0].col + graph.nodes[0].length - len - 2 * (lcs.length - len); ARRAY_APPEND(allocator, graph.local_supremal, ((GVA_Node) { - graph.nodes[0].row + graph.nodes[0].length - len, graph.nodes[0].col + graph.nodes[0].length - len, 0, GVA_NULL, 0 + graph.nodes[0].row + graph.nodes[0].length - len, graph.nodes[0].col + graph.nodes[0].length - len, 0, distance - prev_distance, 0 })); + //fprintf(stderr, "3.APPEND %u: (%u, %u, %u) @ %u\n", lcs.length - len, graph.nodes[0].row + graph.nodes[0].length - len, graph.nodes[0].col + graph.nodes[0].length - len, 0, distance); } //if if (graph.local_supremal != NULL) From d714ed2acdff4b68c3edd51312944b0e40ff2e8a Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Tue, 12 Aug 2025 16:19:43 +0200 Subject: [PATCH 323/704] Local supremal based index build. --- include/stabbing.h | 27 +++- src/main.c | 311 ++++++++++++++++++++++++++------------------- src/stabbing.c | 28 ++-- 3 files changed, 222 insertions(+), 144 deletions(-) diff --git a/include/stabbing.h b/include/stabbing.h index fe8031f..39b10c2 100644 --- a/include/stabbing.h +++ b/include/stabbing.h @@ -17,16 +17,26 @@ typedef struct gva_uint end; gva_uint inserted; gva_uint distance; - size_t data; + gva_uint allele; + gva_uint next; } GVA_Stabbing_Entry; +typedef struct +{ + size_t data; + gva_uint distance; + gva_uint head; +} GVA_Stabbing_Allele; + + // FIXME: include trie as part of the index. typedef struct { - size_t len_ref; - gva_uint* start_table; - GVA_Stabbing_Entry* entries; + size_t len_ref; + gva_uint* start_table; + GVA_Stabbing_Entry* entries; + GVA_Stabbing_Allele* alleles; } GVA_Stabbing_Index; @@ -39,9 +49,14 @@ gva_stabbing_index_destroy(GVA_Allocator const allocator, GVA_Stabbing_Index ind size_t -gva_stabbing_index_add(GVA_Allocator const allocator, GVA_Stabbing_Index index[static 1], +gva_stabbing_index_add_allele(GVA_Allocator const allocator, GVA_Stabbing_Index index[static 1], + size_t const data, gva_uint const distance); + + +size_t +gva_stabbing_index_add_part(GVA_Allocator const allocator, GVA_Stabbing_Index index[static 1], gva_uint const start, gva_uint const end, gva_uint const inserted, - gva_uint const distance, size_t const data); + gva_uint const distance, gva_uint const allele); void diff --git a/src/main.c b/src/main.c index c43f4e0..24274d8 100644 --- a/src/main.c +++ b/src/main.c @@ -25,7 +25,7 @@ #define TIC(x) clock_t const x = clock() #define TOC(x) fprintf(stderr, "Elapsed time: %s (seconds): %.2f\n", (#x), (double)(clock() - (x)) / CLOCKS_PER_SEC) -#define LINE_SIZE 4096 +#define LINE_SIZE 8194 static void @@ -433,7 +433,6 @@ entry_cmp(void const* lhs, void const* rhs) { return 1; } // if - /* // FIXME: breaks faststabber order if (lhs_entry->end > rhs_entry->end) { return -1; @@ -442,7 +441,6 @@ entry_cmp(void const* lhs, void const* rhs) { return 1; } // if - */ if (lhs_entry->distance > rhs_entry->distance) { return -1; @@ -500,8 +498,39 @@ all(int argc, char* argv[static argc + 1]) GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &variant); - gva_uint const inserted = trie_insert(gva_std_allocator, &trie, graph.supremal.sequence.len, graph.supremal.sequence.str); - gva_stabbing_index_add(gva_std_allocator, &index, graph.supremal.start, graph.supremal.end, inserted, graph.distance, rsid); + if (array_length(graph.local_supremal) == 2) + { + // continue; + } + size_t const allele = gva_stabbing_index_add_allele(gva_std_allocator, &index, rsid, graph.distance) - 1; + fprintf(stderr, "%u\n", graph.distance); + size_t sum = 0; + for (size_t i = 0; i < array_length(graph.local_supremal) - 1; ++i) + { + GVA_Variant variant; + gva_edges(graph.observed.str, + graph.local_supremal[i], graph.local_supremal[i + 1], + i == 0, i == array_length(graph.local_supremal) - 2, + &variant); + fprintf(stderr, " (%u, %u, %u) -> (%u, %u, %u): " GVA_VARIANT_FMT " %u\n", + graph.local_supremal[i].row, graph.local_supremal[i].col, graph.local_supremal[i].length, + graph.local_supremal[i + 1].row, graph.local_supremal[i + 1].col, graph.local_supremal[i + 1].length, + GVA_VARIANT_PRINT(variant), graph.local_supremal[i + 1].edges); + + sum += graph.local_supremal[i + 1].edges; + + gva_uint const inserted = trie_insert(gva_std_allocator, &trie, variant.sequence.len, variant.sequence.str); + gva_stabbing_index_add_part(gva_std_allocator, &index, + variant.start, variant.end, inserted, graph.local_supremal[i + 1].edges, allele); + + } // for + fprintf(stderr, "\n"); + + if (graph.distance != sum) + { + fprintf(stderr, "%u != %zu\n", graph.distance, sum); + return -1; + } gva_string_destroy(gva_std_allocator, graph.observed); gva_lcs_graph_destroy(gva_std_allocator, graph); @@ -509,6 +538,7 @@ all(int argc, char* argv[static argc + 1]) count += 1; } // while fprintf(stderr, "number of variants: %zu\n", array_length(index.entries) - 1); + fprintf(stderr, "number of alleles: %zu\n", array_length(index.alleles)); TOC(perf_calculate_supremals); @@ -517,137 +547,158 @@ all(int argc, char* argv[static argc + 1]) qsort(index.entries, array_length(index.entries), sizeof(*index.entries), entry_cmp); gva_stabbing_index_build(gva_std_allocator, index); - TOC(perf_build_index); - - TIC(perf_calculate_relations); - - count = 0; - for (size_t i = 1; i < array_length(index.entries); ++i) + for (size_t i = array_length(index.entries) - 1; i > 0; --i) { - GVA_Variant const lhs = {index.entries[i].start, index.entries[i].end, {trie.nodes[index.entries[i].inserted].end - trie.nodes[index.entries[i].inserted].start, trie.strings.str + trie.nodes[index.entries[i].inserted].start}}; - - GVA_LCS_Graph lhs_graph = {.nodes = NULL}; - size_t* lhs_dels = NULL; - size_t* lhs_as = NULL; - size_t* lhs_cs = NULL; - size_t* lhs_gs = NULL; - size_t* lhs_ts = NULL; - - for (size_t j = i + 1; j < array_length(index.entries); ++j) - { - if (index.entries[i].end < index.entries[j].start) - { - break; - } // if - if (index.entries[j].end >= index.entries[i].start && index.entries[j].start <= index.entries[i].end) - { - count += 1; - GVA_Variant const rhs = {index.entries[j].start, index.entries[j].end, {trie.nodes[index.entries[j].inserted].end - trie.nodes[index.entries[j].inserted].start, trie.strings.str + trie.nodes[index.entries[j].inserted].start}}; - - if (index.entries[i].start == index.entries[j].start && index.entries[i].end == index.entries[j].end && index.entries[i].inserted == index.entries[j].inserted) - { - printf("%zu " GVA_VARIANT_FMT_SPDI " %zu " GVA_VARIANT_FMT_SPDI " equivalent\n", index.entries[i].data, GVA_VARIANT_PRINT_SPDI("NC_000001.11", lhs), index.entries[j].data, GVA_VARIANT_PRINT_SPDI("NC_000001.11", rhs)); - continue; - } // if + index.entries[i].next = index.alleles[index.entries[i].allele].head; + index.alleles[index.entries[i].allele].head = i; + } - size_t const start = MIN(lhs.start, rhs.start); - size_t const end = MAX(lhs.end, rhs.end); - size_t const lhs_len = (lhs.start - start) + lhs.sequence.len + (end - lhs.end); - size_t const rhs_len = (rhs.start - start) + rhs.sequence.len + (end - rhs.end); - - size_t distance = 0; - if (lhs_len == 0) - { - distance = rhs_len; - } // if - else if (rhs_len == 0) - { - distance = lhs_len; - } // if - else - { - char* lhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, NULL, 0, lhs_len); - if (lhs_obs == NULL) - { - continue; - } // if - memcpy(lhs_obs, reference.str + start, lhs.start - start); - memcpy(lhs_obs + lhs.start - start, lhs.sequence.str, lhs.sequence.len); - memcpy(lhs_obs + lhs.start - start + lhs.sequence.len, reference.str + lhs.end, end - lhs.end); - - char* rhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, NULL, 0, rhs_len); - if (rhs_obs == NULL) - { - lhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, lhs_obs, lhs_len, 0); - continue; - } // if - memcpy(rhs_obs, reference.str + start, rhs.start - start); - memcpy(rhs_obs + rhs.start - start, rhs.sequence.str, rhs.sequence.len); - memcpy(rhs_obs + rhs.start - start + rhs.sequence.len, reference.str + rhs.end, end - rhs.end); - - distance = gva_edit_distance(gva_std_allocator, lhs_len, lhs_obs, rhs_len, rhs_obs); - rhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, rhs_obs, rhs_len, 0); - lhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, lhs_obs, lhs_len, 0); - } // else - - if (index.entries[i].distance + index.entries[j].distance == distance) - { - continue; // disjoint - } // if - - if (index.entries[i].distance - index.entries[j].distance == distance) - { - printf("%zu " GVA_VARIANT_FMT_SPDI " %zu " GVA_VARIANT_FMT_SPDI " contains\n", index.entries[i].data, GVA_VARIANT_PRINT_SPDI("NC_000001.11", lhs), index.entries[j].data, GVA_VARIANT_PRINT_SPDI("NC_000001.11", rhs)); - continue; - } // if + TOC(perf_build_index); - if (lhs_graph.nodes == NULL) - { - lhs_graph = gva_lcs_graph_init(gva_std_allocator, lhs.end - lhs.start, reference.str + lhs.start, lhs.sequence.len, lhs.sequence.str, lhs.start); - size_t const len = lhs.end - lhs.start + 1; - lhs_dels = bitset_init(gva_std_allocator, len); // can be one shorter - lhs_as = bitset_init(gva_std_allocator, len); - lhs_cs = bitset_init(gva_std_allocator, len); - lhs_gs = bitset_init(gva_std_allocator, len); - lhs_ts = bitset_init(gva_std_allocator, len); - bitset_fill(lhs_graph, lhs.start, lhs.start, lhs.end, lhs_dels, lhs_as, lhs_cs, lhs_gs, lhs_ts); - } // if + for (size_t i = 0; i < array_length(index.alleles); ++i) + { + fprintf(stderr, "%zu\n", index.alleles[i].data); + for (gva_uint j = index.alleles[i].head; j != GVA_NULL; j = index.entries[j].next) + { + GVA_String inserted = {trie.nodes[index.entries[j].inserted].end - + trie.nodes[index.entries[j].inserted].start, + trie.strings.str + trie.nodes[index.entries[j].inserted].start}; + GVA_Variant variant = {index.entries[j].start, index.entries[j].end, inserted}; + fprintf(stderr, GVA_VARIANT_FMT " ", GVA_VARIANT_PRINT(variant)); + } + fprintf(stderr, "\n"); + } - GVA_LCS_Graph rhs_graph = gva_lcs_graph_init(gva_std_allocator, rhs.end - rhs.start, reference.str + rhs.start, rhs.sequence.len, rhs.sequence.str, rhs.start); - size_t const len = rhs.end - lhs.start + 1; - size_t* rhs_dels = bitset_init(gva_std_allocator, len); // can be one shorter - size_t* rhs_as = bitset_init(gva_std_allocator, len); - size_t* rhs_cs = bitset_init(gva_std_allocator, len); - size_t* rhs_gs = bitset_init(gva_std_allocator, len); - size_t* rhs_ts = bitset_init(gva_std_allocator, len); - bitset_fill(rhs_graph, lhs.start, rhs.start, rhs.end, rhs_dels, rhs_as, rhs_cs, rhs_gs, rhs_ts); - - if (bitset_intersection_cnt(lhs_dels, rhs_dels) > 0 || - bitset_intersection_cnt(lhs_as, rhs_as) > 0 || - bitset_intersection_cnt(lhs_cs, rhs_cs) > 0 || - bitset_intersection_cnt(lhs_gs, rhs_gs) > 0 || - bitset_intersection_cnt(lhs_ts, rhs_ts) > 0) - { - printf("%zu " GVA_VARIANT_FMT_SPDI " %zu " GVA_VARIANT_FMT_SPDI " overlap\n", index.entries[i].data, GVA_VARIANT_PRINT_SPDI("NC_000001.11", lhs), index.entries[j].data, GVA_VARIANT_PRINT_SPDI("NC_000001.11", rhs)); - } // if + TIC(perf_calculate_relations); - rhs_ts = bitset_destroy(gva_std_allocator, rhs_ts); - rhs_gs = bitset_destroy(gva_std_allocator, rhs_gs); - rhs_cs = bitset_destroy(gva_std_allocator, rhs_cs); - rhs_as = bitset_destroy(gva_std_allocator, rhs_as); - rhs_dels = bitset_destroy(gva_std_allocator, rhs_dels); - gva_lcs_graph_destroy(gva_std_allocator, rhs_graph); - } // if - } // for - lhs_ts = bitset_destroy(gva_std_allocator, lhs_ts); - lhs_gs = bitset_destroy(gva_std_allocator, lhs_gs); - lhs_cs = bitset_destroy(gva_std_allocator, lhs_cs); - lhs_as = bitset_destroy(gva_std_allocator, lhs_as); - lhs_dels = bitset_destroy(gva_std_allocator, lhs_dels); - gva_lcs_graph_destroy(gva_std_allocator, lhs_graph); - } // for - fprintf(stderr, "number of pairs calculated: %zu\n", count); + // count = 0; + // for (size_t i = 1; i < array_length(index.entries); ++i) + // { + // GVA_Variant const lhs = {index.entries[i].start, index.entries[i].end, {trie.nodes[index.entries[i].inserted].end - trie.nodes[index.entries[i].inserted].start, trie.strings.str + trie.nodes[index.entries[i].inserted].start}}; + + // GVA_LCS_Graph lhs_graph = {.nodes = NULL}; + // size_t* lhs_dels = NULL; + // size_t* lhs_as = NULL; + // size_t* lhs_cs = NULL; + // size_t* lhs_gs = NULL; + // size_t* lhs_ts = NULL; + + // for (size_t j = i + 1; j < array_length(index.entries); ++j) + // { + // if (index.entries[i].end < index.entries[j].start) + // { + // break; + // } // if + // if (index.entries[j].end >= index.entries[i].start && index.entries[j].start <= index.entries[i].end) + // { + // count += 1; + // GVA_Variant const rhs = {index.entries[j].start, index.entries[j].end, {trie.nodes[index.entries[j].inserted].end - trie.nodes[index.entries[j].inserted].start, trie.strings.str + trie.nodes[index.entries[j].inserted].start}}; + + // if (index.entries[i].start == index.entries[j].start && index.entries[i].end == index.entries[j].end && index.entries[i].inserted == index.entries[j].inserted) + // { + // printf("%zu " GVA_VARIANT_FMT_SPDI " %zu " GVA_VARIANT_FMT_SPDI " equivalent\n", index.entries[i].data, GVA_VARIANT_PRINT_SPDI("NC_000001.11", lhs), index.entries[j].data, GVA_VARIANT_PRINT_SPDI("NC_000001.11", rhs)); + // continue; + // } // if + + // size_t const start = MIN(lhs.start, rhs.start); + // size_t const end = MAX(lhs.end, rhs.end); + + // size_t const lhs_len = (lhs.start - start) + lhs.sequence.len + (end - lhs.end); + // size_t const rhs_len = (rhs.start - start) + rhs.sequence.len + (end - rhs.end); + + // size_t distance = 0; + // if (lhs_len == 0) + // { + // distance = rhs_len; + // } // if + // else if (rhs_len == 0) + // { + // distance = lhs_len; + // } // if + // else + // { + // char* lhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, NULL, 0, lhs_len); + // if (lhs_obs == NULL) + // { + // continue; + // } // if + // memcpy(lhs_obs, reference.str + start, lhs.start - start); + // memcpy(lhs_obs + lhs.start - start, lhs.sequence.str, lhs.sequence.len); + // memcpy(lhs_obs + lhs.start - start + lhs.sequence.len, reference.str + lhs.end, end - lhs.end); + + // char* rhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, NULL, 0, rhs_len); + // if (rhs_obs == NULL) + // { + // lhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, lhs_obs, lhs_len, 0); + // continue; + // } // if + // memcpy(rhs_obs, reference.str + start, rhs.start - start); + // memcpy(rhs_obs + rhs.start - start, rhs.sequence.str, rhs.sequence.len); + // memcpy(rhs_obs + rhs.start - start + rhs.sequence.len, reference.str + rhs.end, end - rhs.end); + + // distance = gva_edit_distance(gva_std_allocator, lhs_len, lhs_obs, rhs_len, rhs_obs); + // rhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, rhs_obs, rhs_len, 0); + // lhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, lhs_obs, lhs_len, 0); + // } // else + + // if (index.entries[i].distance + index.entries[j].distance == distance) + // { + // continue; // disjoint + // } // if + + // if (index.entries[i].distance - index.entries[j].distance == distance) + // { + // printf("%zu " GVA_VARIANT_FMT_SPDI " %zu " GVA_VARIANT_FMT_SPDI " contains\n", index.entries[i].data, GVA_VARIANT_PRINT_SPDI("NC_000001.11", lhs), index.entries[j].data, GVA_VARIANT_PRINT_SPDI("NC_000001.11", rhs)); + // continue; + // } // if + + // if (lhs_graph.nodes == NULL) + // { + // lhs_graph = gva_lcs_graph_init(gva_std_allocator, lhs.end - lhs.start, reference.str + lhs.start, lhs.sequence.len, lhs.sequence.str, lhs.start); + // size_t const len = lhs.end - lhs.start + 1; + // lhs_dels = bitset_init(gva_std_allocator, len); // can be one shorter + // lhs_as = bitset_init(gva_std_allocator, len); + // lhs_cs = bitset_init(gva_std_allocator, len); + // lhs_gs = bitset_init(gva_std_allocator, len); + // lhs_ts = bitset_init(gva_std_allocator, len); + // bitset_fill(lhs_graph, lhs.start, lhs.start, lhs.end, lhs_dels, lhs_as, lhs_cs, lhs_gs, lhs_ts); + // } // if + + // GVA_LCS_Graph rhs_graph = gva_lcs_graph_init(gva_std_allocator, rhs.end - rhs.start, reference.str + rhs.start, rhs.sequence.len, rhs.sequence.str, rhs.start); + // size_t const len = rhs.end - lhs.start + 1; + // size_t* rhs_dels = bitset_init(gva_std_allocator, len); // can be one shorter + // size_t* rhs_as = bitset_init(gva_std_allocator, len); + // size_t* rhs_cs = bitset_init(gva_std_allocator, len); + // size_t* rhs_gs = bitset_init(gva_std_allocator, len); + // size_t* rhs_ts = bitset_init(gva_std_allocator, len); + // bitset_fill(rhs_graph, lhs.start, rhs.start, rhs.end, rhs_dels, rhs_as, rhs_cs, rhs_gs, rhs_ts); + + // if (bitset_intersection_cnt(lhs_dels, rhs_dels) > 0 || + // bitset_intersection_cnt(lhs_as, rhs_as) > 0 || + // bitset_intersection_cnt(lhs_cs, rhs_cs) > 0 || + // bitset_intersection_cnt(lhs_gs, rhs_gs) > 0 || + // bitset_intersection_cnt(lhs_ts, rhs_ts) > 0) + // { + // printf("%zu " GVA_VARIANT_FMT_SPDI " %zu " GVA_VARIANT_FMT_SPDI " overlap\n", index.entries[i].data, GVA_VARIANT_PRINT_SPDI("NC_000001.11", lhs), index.entries[j].data, GVA_VARIANT_PRINT_SPDI("NC_000001.11", rhs)); + // } // if + + // rhs_ts = bitset_destroy(gva_std_allocator, rhs_ts); + // rhs_gs = bitset_destroy(gva_std_allocator, rhs_gs); + // rhs_cs = bitset_destroy(gva_std_allocator, rhs_cs); + // rhs_as = bitset_destroy(gva_std_allocator, rhs_as); + // rhs_dels = bitset_destroy(gva_std_allocator, rhs_dels); + // gva_lcs_graph_destroy(gva_std_allocator, rhs_graph); + // } // if + // } // for + // lhs_ts = bitset_destroy(gva_std_allocator, lhs_ts); + // lhs_gs = bitset_destroy(gva_std_allocator, lhs_gs); + // lhs_cs = bitset_destroy(gva_std_allocator, lhs_cs); + // lhs_as = bitset_destroy(gva_std_allocator, lhs_as); + // lhs_dels = bitset_destroy(gva_std_allocator, lhs_dels); + // gva_lcs_graph_destroy(gva_std_allocator, lhs_graph); + // } // for + // fprintf(stderr, "number of pairs calculated: %zu\n", count); TOC(perf_calculate_relations); diff --git a/src/stabbing.c b/src/stabbing.c index 78ca973..44f660e 100644 --- a/src/stabbing.c +++ b/src/stabbing.c @@ -15,20 +15,22 @@ gva_stabbing_index_init(GVA_Allocator const allocator, size_t const len_ref) gva_uint* start_table = allocator.allocate(allocator.context, NULL, 0, len_ref * sizeof(*start_table)); // OVERFLOW if (start_table == NULL) { - return (GVA_Stabbing_Index) {0, NULL, NULL}; + return (GVA_Stabbing_Index) {0, NULL, NULL, NULL}; } // if - memset(start_table, 0, len_ref * sizeof(*start_table)); + GVA_Stabbing_Entry* entries = NULL; - ARRAY_APPEND(allocator, entries, ((GVA_Stabbing_Entry) {GVA_NULL, GVA_NULL, GVA_NULL, 0, len_ref, 0, 0, 0})); + ARRAY_APPEND(allocator, entries, ((GVA_Stabbing_Entry) + {GVA_NULL, GVA_NULL, GVA_NULL, 0, len_ref, 0, 0, GVA_NULL, GVA_NULL})); - return (GVA_Stabbing_Index) {len_ref, start_table, entries}; + return (GVA_Stabbing_Index) {len_ref, start_table, entries, NULL}; } // gva_stabbing_index_init void gva_stabbing_index_destroy(GVA_Allocator const allocator, GVA_Stabbing_Index index[static 1]) { + index->alleles = ARRAY_DESTROY(allocator, index->alleles); index->entries = ARRAY_DESTROY(allocator, index->entries); index->start_table = allocator.allocate(allocator.context, index->start_table, index->len_ref * sizeof(*index->start_table), 0); index->len_ref = 0; @@ -36,12 +38,22 @@ gva_stabbing_index_destroy(GVA_Allocator const allocator, GVA_Stabbing_Index ind inline size_t -gva_stabbing_index_add(GVA_Allocator const allocator, GVA_Stabbing_Index index[static 1], +gva_stabbing_index_add_allele(GVA_Allocator const allocator, GVA_Stabbing_Index index[static 1], + size_t const data, gva_uint const distance) +{ + return ARRAY_APPEND(allocator, index->alleles, ((GVA_Stabbing_Allele) + {data, distance, GVA_NULL})); +} // gva_stabbing_index_add_allele + + +inline size_t +gva_stabbing_index_add_part(GVA_Allocator const allocator, GVA_Stabbing_Index index[static 1], gva_uint const start, gva_uint const end, gva_uint const inserted, - gva_uint const distance, size_t const data) + gva_uint const distance, gva_uint const allele) { - return ARRAY_APPEND(allocator, index->entries, ((GVA_Stabbing_Entry) {GVA_NULL, GVA_NULL, GVA_NULL, start, end, inserted, distance, data})); -} // gva_stabbing_index_add + return ARRAY_APPEND(allocator, index->entries, ((GVA_Stabbing_Entry) + {GVA_NULL, GVA_NULL, GVA_NULL, start, end, inserted, distance, allele, GVA_NULL})); +} // gva_stabbing_index_add_part void From 1f4f6edbb1a10cb064b88439cf70ce118f642902 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 12 Aug 2025 18:35:50 +0200 Subject: [PATCH 324/704] Retrieve string from trie index --- src/trie.c | 11 +++++++++++ src/trie.h | 4 ++++ 2 files changed, 15 insertions(+) diff --git a/src/trie.c b/src/trie.c index 47896dd..eeca9b5 100644 --- a/src/trie.c +++ b/src/trie.c @@ -122,3 +122,14 @@ trie_insert(GVA_Allocator const allocator, Trie self[static restrict 1], } // else } // while } // trie_insert + + +inline GVA_String +trie_string(Trie const self[static 1], size_t const idx) +{ + if (idx >= array_length(self->nodes)) + { + return (GVA_String) {0, NULL}; + } // if + return (GVA_String) {self->nodes[idx].end - self->nodes[idx].start, self->strings.str + self->nodes[idx].start}; +} //trie_string diff --git a/src/trie.h b/src/trie.h index 107ebd6..e62544f 100644 --- a/src/trie.h +++ b/src/trie.h @@ -36,4 +36,8 @@ trie_insert(GVA_Allocator const allocator, Trie self[static restrict 1], size_t const len, char const key[static restrict len]); +GVA_String +trie_string(Trie const self[static 1], size_t const idx); + + #endif // GVA_TRIE_H From 435e08e7ebf965914bddc25e35bc608b565063dd Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 12 Aug 2025 18:39:16 +0200 Subject: [PATCH 325/704] Trie string usage --- src/main.c | 12 ++++-------- src/trie.c | 6 +++--- src/trie.h | 2 +- 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/main.c b/src/main.c index 24274d8..1e17925 100644 --- a/src/main.c +++ b/src/main.c @@ -551,8 +551,7 @@ all(int argc, char* argv[static argc + 1]) { index.entries[i].next = index.alleles[index.entries[i].allele].head; index.alleles[index.entries[i].allele].head = i; - } - + } // for TOC(perf_build_index); @@ -561,14 +560,11 @@ all(int argc, char* argv[static argc + 1]) fprintf(stderr, "%zu\n", index.alleles[i].data); for (gva_uint j = index.alleles[i].head; j != GVA_NULL; j = index.entries[j].next) { - GVA_String inserted = {trie.nodes[index.entries[j].inserted].end - - trie.nodes[index.entries[j].inserted].start, - trie.strings.str + trie.nodes[index.entries[j].inserted].start}; - GVA_Variant variant = {index.entries[j].start, index.entries[j].end, inserted}; + GVA_Variant const variant = {index.entries[j].start, index.entries[j].end, trie_string(trie, index.entries[j].inserted)}; fprintf(stderr, GVA_VARIANT_FMT " ", GVA_VARIANT_PRINT(variant)); - } + } // for fprintf(stderr, "\n"); - } + } // for TIC(perf_calculate_relations); diff --git a/src/trie.c b/src/trie.c index eeca9b5..07d00be 100644 --- a/src/trie.c +++ b/src/trie.c @@ -125,11 +125,11 @@ trie_insert(GVA_Allocator const allocator, Trie self[static restrict 1], inline GVA_String -trie_string(Trie const self[static 1], size_t const idx) +trie_string(Trie const self, size_t const idx) { - if (idx >= array_length(self->nodes)) + if (idx >= array_length(self.nodes)) { return (GVA_String) {0, NULL}; } // if - return (GVA_String) {self->nodes[idx].end - self->nodes[idx].start, self->strings.str + self->nodes[idx].start}; + return (GVA_String) {self.nodes[idx].end - self.nodes[idx].start, self.strings.str + self.nodes[idx].start}; } //trie_string diff --git a/src/trie.h b/src/trie.h index e62544f..5807016 100644 --- a/src/trie.h +++ b/src/trie.h @@ -37,7 +37,7 @@ trie_insert(GVA_Allocator const allocator, Trie self[static restrict 1], GVA_String -trie_string(Trie const self[static 1], size_t const idx); +trie_string(Trie const self, size_t const idx); #endif // GVA_TRIE_H From 5e0ca703e329fd1948573c921bf0eaf38a7e2ab4 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Tue, 12 Aug 2025 22:40:34 +0200 Subject: [PATCH 326/704] Reenable modified version of compare. --- src/main.c | 263 +++++++++++++++++++++++++++-------------------------- 1 file changed, 136 insertions(+), 127 deletions(-) diff --git a/src/main.c b/src/main.c index 24274d8..3c1b4a1 100644 --- a/src/main.c +++ b/src/main.c @@ -572,133 +572,142 @@ all(int argc, char* argv[static argc + 1]) TIC(perf_calculate_relations); - // count = 0; - // for (size_t i = 1; i < array_length(index.entries); ++i) - // { - // GVA_Variant const lhs = {index.entries[i].start, index.entries[i].end, {trie.nodes[index.entries[i].inserted].end - trie.nodes[index.entries[i].inserted].start, trie.strings.str + trie.nodes[index.entries[i].inserted].start}}; - - // GVA_LCS_Graph lhs_graph = {.nodes = NULL}; - // size_t* lhs_dels = NULL; - // size_t* lhs_as = NULL; - // size_t* lhs_cs = NULL; - // size_t* lhs_gs = NULL; - // size_t* lhs_ts = NULL; - - // for (size_t j = i + 1; j < array_length(index.entries); ++j) - // { - // if (index.entries[i].end < index.entries[j].start) - // { - // break; - // } // if - // if (index.entries[j].end >= index.entries[i].start && index.entries[j].start <= index.entries[i].end) - // { - // count += 1; - // GVA_Variant const rhs = {index.entries[j].start, index.entries[j].end, {trie.nodes[index.entries[j].inserted].end - trie.nodes[index.entries[j].inserted].start, trie.strings.str + trie.nodes[index.entries[j].inserted].start}}; - - // if (index.entries[i].start == index.entries[j].start && index.entries[i].end == index.entries[j].end && index.entries[i].inserted == index.entries[j].inserted) - // { - // printf("%zu " GVA_VARIANT_FMT_SPDI " %zu " GVA_VARIANT_FMT_SPDI " equivalent\n", index.entries[i].data, GVA_VARIANT_PRINT_SPDI("NC_000001.11", lhs), index.entries[j].data, GVA_VARIANT_PRINT_SPDI("NC_000001.11", rhs)); - // continue; - // } // if - - // size_t const start = MIN(lhs.start, rhs.start); - // size_t const end = MAX(lhs.end, rhs.end); - - // size_t const lhs_len = (lhs.start - start) + lhs.sequence.len + (end - lhs.end); - // size_t const rhs_len = (rhs.start - start) + rhs.sequence.len + (end - rhs.end); - - // size_t distance = 0; - // if (lhs_len == 0) - // { - // distance = rhs_len; - // } // if - // else if (rhs_len == 0) - // { - // distance = lhs_len; - // } // if - // else - // { - // char* lhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, NULL, 0, lhs_len); - // if (lhs_obs == NULL) - // { - // continue; - // } // if - // memcpy(lhs_obs, reference.str + start, lhs.start - start); - // memcpy(lhs_obs + lhs.start - start, lhs.sequence.str, lhs.sequence.len); - // memcpy(lhs_obs + lhs.start - start + lhs.sequence.len, reference.str + lhs.end, end - lhs.end); - - // char* rhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, NULL, 0, rhs_len); - // if (rhs_obs == NULL) - // { - // lhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, lhs_obs, lhs_len, 0); - // continue; - // } // if - // memcpy(rhs_obs, reference.str + start, rhs.start - start); - // memcpy(rhs_obs + rhs.start - start, rhs.sequence.str, rhs.sequence.len); - // memcpy(rhs_obs + rhs.start - start + rhs.sequence.len, reference.str + rhs.end, end - rhs.end); - - // distance = gva_edit_distance(gva_std_allocator, lhs_len, lhs_obs, rhs_len, rhs_obs); - // rhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, rhs_obs, rhs_len, 0); - // lhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, lhs_obs, lhs_len, 0); - // } // else - - // if (index.entries[i].distance + index.entries[j].distance == distance) - // { - // continue; // disjoint - // } // if - - // if (index.entries[i].distance - index.entries[j].distance == distance) - // { - // printf("%zu " GVA_VARIANT_FMT_SPDI " %zu " GVA_VARIANT_FMT_SPDI " contains\n", index.entries[i].data, GVA_VARIANT_PRINT_SPDI("NC_000001.11", lhs), index.entries[j].data, GVA_VARIANT_PRINT_SPDI("NC_000001.11", rhs)); - // continue; - // } // if - - // if (lhs_graph.nodes == NULL) - // { - // lhs_graph = gva_lcs_graph_init(gva_std_allocator, lhs.end - lhs.start, reference.str + lhs.start, lhs.sequence.len, lhs.sequence.str, lhs.start); - // size_t const len = lhs.end - lhs.start + 1; - // lhs_dels = bitset_init(gva_std_allocator, len); // can be one shorter - // lhs_as = bitset_init(gva_std_allocator, len); - // lhs_cs = bitset_init(gva_std_allocator, len); - // lhs_gs = bitset_init(gva_std_allocator, len); - // lhs_ts = bitset_init(gva_std_allocator, len); - // bitset_fill(lhs_graph, lhs.start, lhs.start, lhs.end, lhs_dels, lhs_as, lhs_cs, lhs_gs, lhs_ts); - // } // if - - // GVA_LCS_Graph rhs_graph = gva_lcs_graph_init(gva_std_allocator, rhs.end - rhs.start, reference.str + rhs.start, rhs.sequence.len, rhs.sequence.str, rhs.start); - // size_t const len = rhs.end - lhs.start + 1; - // size_t* rhs_dels = bitset_init(gva_std_allocator, len); // can be one shorter - // size_t* rhs_as = bitset_init(gva_std_allocator, len); - // size_t* rhs_cs = bitset_init(gva_std_allocator, len); - // size_t* rhs_gs = bitset_init(gva_std_allocator, len); - // size_t* rhs_ts = bitset_init(gva_std_allocator, len); - // bitset_fill(rhs_graph, lhs.start, rhs.start, rhs.end, rhs_dels, rhs_as, rhs_cs, rhs_gs, rhs_ts); - - // if (bitset_intersection_cnt(lhs_dels, rhs_dels) > 0 || - // bitset_intersection_cnt(lhs_as, rhs_as) > 0 || - // bitset_intersection_cnt(lhs_cs, rhs_cs) > 0 || - // bitset_intersection_cnt(lhs_gs, rhs_gs) > 0 || - // bitset_intersection_cnt(lhs_ts, rhs_ts) > 0) - // { - // printf("%zu " GVA_VARIANT_FMT_SPDI " %zu " GVA_VARIANT_FMT_SPDI " overlap\n", index.entries[i].data, GVA_VARIANT_PRINT_SPDI("NC_000001.11", lhs), index.entries[j].data, GVA_VARIANT_PRINT_SPDI("NC_000001.11", rhs)); - // } // if - - // rhs_ts = bitset_destroy(gva_std_allocator, rhs_ts); - // rhs_gs = bitset_destroy(gva_std_allocator, rhs_gs); - // rhs_cs = bitset_destroy(gva_std_allocator, rhs_cs); - // rhs_as = bitset_destroy(gva_std_allocator, rhs_as); - // rhs_dels = bitset_destroy(gva_std_allocator, rhs_dels); - // gva_lcs_graph_destroy(gva_std_allocator, rhs_graph); - // } // if - // } // for - // lhs_ts = bitset_destroy(gva_std_allocator, lhs_ts); - // lhs_gs = bitset_destroy(gva_std_allocator, lhs_gs); - // lhs_cs = bitset_destroy(gva_std_allocator, lhs_cs); - // lhs_as = bitset_destroy(gva_std_allocator, lhs_as); - // lhs_dels = bitset_destroy(gva_std_allocator, lhs_dels); - // gva_lcs_graph_destroy(gva_std_allocator, lhs_graph); - // } // for - // fprintf(stderr, "number of pairs calculated: %zu\n", count); + count = 0; + for (size_t i = 1; i < array_length(index.entries); ++i) + { + GVA_Variant const lhs = {index.entries[i].start, index.entries[i].end, {trie.nodes[index.entries[i].inserted].end - trie.nodes[index.entries[i].inserted].start, trie.strings.str + trie.nodes[index.entries[i].inserted].start}}; + + GVA_LCS_Graph lhs_graph = {.nodes = NULL}; + size_t* lhs_dels = NULL; + size_t* lhs_as = NULL; + size_t* lhs_cs = NULL; + size_t* lhs_gs = NULL; + size_t* lhs_ts = NULL; + + for (size_t j = i + 1; j < array_length(index.entries); ++j) + { + if (index.entries[i].end < index.entries[j].start) + { + break; + } // if + if (index.entries[j].end >= index.entries[i].start && index.entries[j].start <= index.entries[i].end) + { + count += 1; + GVA_Variant const rhs = {index.entries[j].start, index.entries[j].end, {trie.nodes[index.entries[j].inserted].end - trie.nodes[index.entries[j].inserted].start, trie.strings.str + trie.nodes[index.entries[j].inserted].start}}; + + if (index.entries[i].start == index.entries[j].start && index.entries[i].end == index.entries[j].end && index.entries[i].inserted == index.entries[j].inserted) + { + printf("%zu " GVA_VARIANT_FMT_SPDI " %zu " GVA_VARIANT_FMT_SPDI " equivalent\n", + index.alleles[index.entries[i].allele].data, GVA_VARIANT_PRINT_SPDI("NG_008376.4", lhs), + index.alleles[index.entries[j].allele].data, GVA_VARIANT_PRINT_SPDI("NG_008376.4", rhs)); + continue; + } // if + + size_t const start = MIN(lhs.start, rhs.start); + size_t const end = MAX(lhs.end, rhs.end); + + size_t const lhs_len = (lhs.start - start) + lhs.sequence.len + (end - lhs.end); + size_t const rhs_len = (rhs.start - start) + rhs.sequence.len + (end - rhs.end); + + size_t distance = 0; + if (lhs_len == 0) + { + distance = rhs_len; + } // if + else if (rhs_len == 0) + { + distance = lhs_len; + } // if + else + { + char* lhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, NULL, 0, lhs_len); + if (lhs_obs == NULL) + { + continue; + } // if + memcpy(lhs_obs, reference.str + start, lhs.start - start); + memcpy(lhs_obs + lhs.start - start, lhs.sequence.str, lhs.sequence.len); + memcpy(lhs_obs + lhs.start - start + lhs.sequence.len, reference.str + lhs.end, end - lhs.end); + + char* rhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, NULL, 0, rhs_len); + if (rhs_obs == NULL) + { + lhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, lhs_obs, lhs_len, 0); + continue; + } // if + memcpy(rhs_obs, reference.str + start, rhs.start - start); + memcpy(rhs_obs + rhs.start - start, rhs.sequence.str, rhs.sequence.len); + memcpy(rhs_obs + rhs.start - start + rhs.sequence.len, reference.str + rhs.end, end - rhs.end); + + distance = gva_edit_distance(gva_std_allocator, lhs_len, lhs_obs, rhs_len, rhs_obs); + rhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, rhs_obs, rhs_len, 0); + lhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, lhs_obs, lhs_len, 0); + } // else + + if (index.entries[i].distance + index.entries[j].distance == distance) + { + printf("%zu " GVA_VARIANT_FMT_SPDI " %zu " GVA_VARIANT_FMT_SPDI " disjoint\n", + index.alleles[index.entries[i].allele].data, GVA_VARIANT_PRINT_SPDI("NG_008376.4", lhs), + index.alleles[index.entries[j].allele].data, GVA_VARIANT_PRINT_SPDI("NG_008376.4", rhs)); + continue; // disjoint + } // if + + if (index.entries[i].distance - index.entries[j].distance == distance) + { + printf("%zu " GVA_VARIANT_FMT_SPDI " %zu " GVA_VARIANT_FMT_SPDI " contains\n", + index.alleles[index.entries[i].allele].data, GVA_VARIANT_PRINT_SPDI("NG_008376.4", lhs), + index.alleles[index.entries[j].allele].data, GVA_VARIANT_PRINT_SPDI("NG_008376.4", rhs)); + continue; + } // if + + if (lhs_graph.nodes == NULL) + { + lhs_graph = gva_lcs_graph_init(gva_std_allocator, lhs.end - lhs.start, reference.str + lhs.start, lhs.sequence.len, lhs.sequence.str, lhs.start); + size_t const len = lhs.end - lhs.start + 1; + lhs_dels = bitset_init(gva_std_allocator, len); // can be one shorter + lhs_as = bitset_init(gva_std_allocator, len); + lhs_cs = bitset_init(gva_std_allocator, len); + lhs_gs = bitset_init(gva_std_allocator, len); + lhs_ts = bitset_init(gva_std_allocator, len); + bitset_fill(lhs_graph, lhs.start, lhs.start, lhs.end, lhs_dels, lhs_as, lhs_cs, lhs_gs, lhs_ts); + } // if + + GVA_LCS_Graph rhs_graph = gva_lcs_graph_init(gva_std_allocator, rhs.end - rhs.start, reference.str + rhs.start, rhs.sequence.len, rhs.sequence.str, rhs.start); + size_t const len = rhs.end - lhs.start + 1; + size_t* rhs_dels = bitset_init(gva_std_allocator, len); // can be one shorter + size_t* rhs_as = bitset_init(gva_std_allocator, len); + size_t* rhs_cs = bitset_init(gva_std_allocator, len); + size_t* rhs_gs = bitset_init(gva_std_allocator, len); + size_t* rhs_ts = bitset_init(gva_std_allocator, len); + bitset_fill(rhs_graph, lhs.start, rhs.start, rhs.end, rhs_dels, rhs_as, rhs_cs, rhs_gs, rhs_ts); + + if (bitset_intersection_cnt(lhs_dels, rhs_dels) > 0 || + bitset_intersection_cnt(lhs_as, rhs_as) > 0 || + bitset_intersection_cnt(lhs_cs, rhs_cs) > 0 || + bitset_intersection_cnt(lhs_gs, rhs_gs) > 0 || + bitset_intersection_cnt(lhs_ts, rhs_ts) > 0) + { + printf("%zu " GVA_VARIANT_FMT_SPDI " %zu " GVA_VARIANT_FMT_SPDI " overlap\n", + index.alleles[index.entries[i].allele].data, GVA_VARIANT_PRINT_SPDI("NG_008376.4", lhs), + index.alleles[index.entries[j].allele].data, GVA_VARIANT_PRINT_SPDI("NG_008376.4", rhs)); + } // if + + rhs_ts = bitset_destroy(gva_std_allocator, rhs_ts); + rhs_gs = bitset_destroy(gva_std_allocator, rhs_gs); + rhs_cs = bitset_destroy(gva_std_allocator, rhs_cs); + rhs_as = bitset_destroy(gva_std_allocator, rhs_as); + rhs_dels = bitset_destroy(gva_std_allocator, rhs_dels); + gva_lcs_graph_destroy(gva_std_allocator, rhs_graph); + } // if + } // for + lhs_ts = bitset_destroy(gva_std_allocator, lhs_ts); + lhs_gs = bitset_destroy(gva_std_allocator, lhs_gs); + lhs_cs = bitset_destroy(gva_std_allocator, lhs_cs); + lhs_as = bitset_destroy(gva_std_allocator, lhs_as); + lhs_dels = bitset_destroy(gva_std_allocator, lhs_dels); + gva_lcs_graph_destroy(gva_std_allocator, lhs_graph); + } // for + fprintf(stderr, "number of pairs calculated: %zu\n", count); TOC(perf_calculate_relations); From 59d4c60b32d7795e84edc1cc1cb21c24783db7e9 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Wed, 13 Aug 2025 12:10:14 +0200 Subject: [PATCH 327/704] Break out compare WIP. --- src/main.c | 239 +++++++++++++++++++++++++++-------------------------- 1 file changed, 121 insertions(+), 118 deletions(-) diff --git a/src/main.c b/src/main.c index 66049cb..85fffe7 100644 --- a/src/main.c +++ b/src/main.c @@ -453,6 +453,124 @@ entry_cmp(void const* lhs, void const* rhs) } // entry_cmp +GVA_Relation +compare_from_index(GVA_String const reference, + GVA_Variant const lhs, gva_uint const lhs_dist, + GVA_Variant const rhs, gva_uint const rhs_dist +) +{ + // TODO: possibly reuse lhs_graph again + + GVA_Relation relation; + + if (gva_variant_eq(lhs, rhs)) + { + return GVA_EQUIVALENT; + } // if + + size_t const start = MIN(lhs.start, rhs.start); + size_t const end = MAX(lhs.end, rhs.end); + + size_t const lhs_len = (lhs.start - start) + lhs.sequence.len + (end - lhs.end); + size_t const rhs_len = (rhs.start - start) + rhs.sequence.len + (end - rhs.end); + + size_t distance = 0; + if (lhs_len == 0) + { + distance = rhs_len; + } // if + else if (rhs_len == 0) + { + distance = lhs_len; + } // if + else + { + char* lhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, NULL, 0, lhs_len); + if (lhs_obs == NULL) + { + return -1; + } // if + memcpy(lhs_obs, reference.str + start, lhs.start - start); + memcpy(lhs_obs + lhs.start - start, lhs.sequence.str, lhs.sequence.len); + memcpy(lhs_obs + lhs.start - start + lhs.sequence.len, reference.str + lhs.end, end - lhs.end); + + char* rhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, NULL, 0, rhs_len); + if (rhs_obs == NULL) + { + lhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, lhs_obs, lhs_len, 0); + return -1; + } // if + memcpy(rhs_obs, reference.str + start, rhs.start - start); + memcpy(rhs_obs + rhs.start - start, rhs.sequence.str, rhs.sequence.len); + memcpy(rhs_obs + rhs.start - start + rhs.sequence.len, reference.str + rhs.end, end - rhs.end); + + distance = gva_edit_distance(gva_std_allocator, lhs_len, lhs_obs, rhs_len, rhs_obs); + rhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, rhs_obs, rhs_len, 0); + lhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, lhs_obs, lhs_len, 0); + } // else + + if (lhs_dist + rhs_dist == distance) + { + return GVA_DISJOINT; + } // if + + if (lhs_dist - rhs_dist == distance) + { + return GVA_CONTAINS; + } // if + + // CHECK + size_t const len = end - start + 1; + + GVA_LCS_Graph lhs_graph = gva_lcs_graph_init(gva_std_allocator, lhs.end - lhs.start, reference.str + lhs.start, lhs.sequence.len, lhs.sequence.str, lhs.start); + size_t* lhs_dels = bitset_init(gva_std_allocator, len); // can be one shorter + size_t* lhs_as = bitset_init(gva_std_allocator, len); + size_t* lhs_cs = bitset_init(gva_std_allocator, len); + size_t* lhs_gs = bitset_init(gva_std_allocator, len); + size_t* lhs_ts = bitset_init(gva_std_allocator, len); + bitset_fill(lhs_graph, lhs.start, lhs.start, lhs.end, lhs_dels, lhs_as, lhs_cs, lhs_gs, lhs_ts); + + GVA_LCS_Graph rhs_graph = gva_lcs_graph_init(gva_std_allocator, rhs.end - rhs.start, reference.str + rhs.start, rhs.sequence.len, rhs.sequence.str, rhs.start); + size_t* rhs_dels = bitset_init(gva_std_allocator, len); // can be one shorter + size_t* rhs_as = bitset_init(gva_std_allocator, len); + size_t* rhs_cs = bitset_init(gva_std_allocator, len); + size_t* rhs_gs = bitset_init(gva_std_allocator, len); + size_t* rhs_ts = bitset_init(gva_std_allocator, len); + bitset_fill(rhs_graph, lhs.start, rhs.start, rhs.end, rhs_dels, rhs_as, rhs_cs, rhs_gs, rhs_ts); + + if (bitset_intersection_cnt(lhs_dels, rhs_dels) > 0 || + bitset_intersection_cnt(lhs_as, rhs_as) > 0 || + bitset_intersection_cnt(lhs_cs, rhs_cs) > 0 || + bitset_intersection_cnt(lhs_gs, rhs_gs) > 0 || + bitset_intersection_cnt(lhs_ts, rhs_ts) > 0) + { + relation = GVA_OVERLAP; + } // if + else + { + relation = GVA_DISJOINT; + } // else + + lhs_ts = bitset_destroy(gva_std_allocator, lhs_ts); + lhs_gs = bitset_destroy(gva_std_allocator, lhs_gs); + lhs_cs = bitset_destroy(gva_std_allocator, lhs_cs); + lhs_as = bitset_destroy(gva_std_allocator, lhs_as); + lhs_dels = bitset_destroy(gva_std_allocator, lhs_dels); + gva_lcs_graph_destroy(gva_std_allocator, lhs_graph); + + rhs_ts = bitset_destroy(gva_std_allocator, rhs_ts); + rhs_gs = bitset_destroy(gva_std_allocator, rhs_gs); + rhs_cs = bitset_destroy(gva_std_allocator, rhs_cs); + rhs_as = bitset_destroy(gva_std_allocator, rhs_as); + rhs_dels = bitset_destroy(gva_std_allocator, rhs_dels); + gva_lcs_graph_destroy(gva_std_allocator, rhs_graph); + + return relation; +} + + + + int all(int argc, char* argv[static argc + 1]) { @@ -573,13 +691,6 @@ all(int argc, char* argv[static argc + 1]) { GVA_Variant const lhs = {index.entries[i].start, index.entries[i].end, {trie.nodes[index.entries[i].inserted].end - trie.nodes[index.entries[i].inserted].start, trie.strings.str + trie.nodes[index.entries[i].inserted].start}}; - GVA_LCS_Graph lhs_graph = {.nodes = NULL}; - size_t* lhs_dels = NULL; - size_t* lhs_as = NULL; - size_t* lhs_cs = NULL; - size_t* lhs_gs = NULL; - size_t* lhs_ts = NULL; - for (size_t j = i + 1; j < array_length(index.entries); ++j) { if (index.entries[i].end < index.entries[j].start) @@ -588,120 +699,12 @@ all(int argc, char* argv[static argc + 1]) } // if if (index.entries[j].end >= index.entries[i].start && index.entries[j].start <= index.entries[i].end) { - count += 1; GVA_Variant const rhs = {index.entries[j].start, index.entries[j].end, {trie.nodes[index.entries[j].inserted].end - trie.nodes[index.entries[j].inserted].start, trie.strings.str + trie.nodes[index.entries[j].inserted].start}}; - - if (index.entries[i].start == index.entries[j].start && index.entries[i].end == index.entries[j].end && index.entries[i].inserted == index.entries[j].inserted) - { - printf("%zu " GVA_VARIANT_FMT_SPDI " %zu " GVA_VARIANT_FMT_SPDI " equivalent\n", - index.alleles[index.entries[i].allele].data, GVA_VARIANT_PRINT_SPDI("NG_008376.4", lhs), - index.alleles[index.entries[j].allele].data, GVA_VARIANT_PRINT_SPDI("NG_008376.4", rhs)); - continue; - } // if - - size_t const start = MIN(lhs.start, rhs.start); - size_t const end = MAX(lhs.end, rhs.end); - - size_t const lhs_len = (lhs.start - start) + lhs.sequence.len + (end - lhs.end); - size_t const rhs_len = (rhs.start - start) + rhs.sequence.len + (end - rhs.end); - - size_t distance = 0; - if (lhs_len == 0) - { - distance = rhs_len; - } // if - else if (rhs_len == 0) - { - distance = lhs_len; - } // if - else - { - char* lhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, NULL, 0, lhs_len); - if (lhs_obs == NULL) - { - continue; - } // if - memcpy(lhs_obs, reference.str + start, lhs.start - start); - memcpy(lhs_obs + lhs.start - start, lhs.sequence.str, lhs.sequence.len); - memcpy(lhs_obs + lhs.start - start + lhs.sequence.len, reference.str + lhs.end, end - lhs.end); - - char* rhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, NULL, 0, rhs_len); - if (rhs_obs == NULL) - { - lhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, lhs_obs, lhs_len, 0); - continue; - } // if - memcpy(rhs_obs, reference.str + start, rhs.start - start); - memcpy(rhs_obs + rhs.start - start, rhs.sequence.str, rhs.sequence.len); - memcpy(rhs_obs + rhs.start - start + rhs.sequence.len, reference.str + rhs.end, end - rhs.end); - - distance = gva_edit_distance(gva_std_allocator, lhs_len, lhs_obs, rhs_len, rhs_obs); - rhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, rhs_obs, rhs_len, 0); - lhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, lhs_obs, lhs_len, 0); - } // else - - if (index.entries[i].distance + index.entries[j].distance == distance) - { - printf("%zu " GVA_VARIANT_FMT_SPDI " %zu " GVA_VARIANT_FMT_SPDI " disjoint\n", - index.alleles[index.entries[i].allele].data, GVA_VARIANT_PRINT_SPDI("NG_008376.4", lhs), - index.alleles[index.entries[j].allele].data, GVA_VARIANT_PRINT_SPDI("NG_008376.4", rhs)); - continue; // disjoint - } // if - - if (index.entries[i].distance - index.entries[j].distance == distance) - { - printf("%zu " GVA_VARIANT_FMT_SPDI " %zu " GVA_VARIANT_FMT_SPDI " contains\n", - index.alleles[index.entries[i].allele].data, GVA_VARIANT_PRINT_SPDI("NG_008376.4", lhs), - index.alleles[index.entries[j].allele].data, GVA_VARIANT_PRINT_SPDI("NG_008376.4", rhs)); - continue; - } // if - - if (lhs_graph.nodes == NULL) - { - lhs_graph = gva_lcs_graph_init(gva_std_allocator, lhs.end - lhs.start, reference.str + lhs.start, lhs.sequence.len, lhs.sequence.str, lhs.start); - size_t const len = lhs.end - lhs.start + 1; - lhs_dels = bitset_init(gva_std_allocator, len); // can be one shorter - lhs_as = bitset_init(gva_std_allocator, len); - lhs_cs = bitset_init(gva_std_allocator, len); - lhs_gs = bitset_init(gva_std_allocator, len); - lhs_ts = bitset_init(gva_std_allocator, len); - bitset_fill(lhs_graph, lhs.start, lhs.start, lhs.end, lhs_dels, lhs_as, lhs_cs, lhs_gs, lhs_ts); - } // if - - GVA_LCS_Graph rhs_graph = gva_lcs_graph_init(gva_std_allocator, rhs.end - rhs.start, reference.str + rhs.start, rhs.sequence.len, rhs.sequence.str, rhs.start); - size_t const len = rhs.end - lhs.start + 1; - size_t* rhs_dels = bitset_init(gva_std_allocator, len); // can be one shorter - size_t* rhs_as = bitset_init(gva_std_allocator, len); - size_t* rhs_cs = bitset_init(gva_std_allocator, len); - size_t* rhs_gs = bitset_init(gva_std_allocator, len); - size_t* rhs_ts = bitset_init(gva_std_allocator, len); - bitset_fill(rhs_graph, lhs.start, rhs.start, rhs.end, rhs_dels, rhs_as, rhs_cs, rhs_gs, rhs_ts); - - if (bitset_intersection_cnt(lhs_dels, rhs_dels) > 0 || - bitset_intersection_cnt(lhs_as, rhs_as) > 0 || - bitset_intersection_cnt(lhs_cs, rhs_cs) > 0 || - bitset_intersection_cnt(lhs_gs, rhs_gs) > 0 || - bitset_intersection_cnt(lhs_ts, rhs_ts) > 0) - { - printf("%zu " GVA_VARIANT_FMT_SPDI " %zu " GVA_VARIANT_FMT_SPDI " overlap\n", - index.alleles[index.entries[i].allele].data, GVA_VARIANT_PRINT_SPDI("NG_008376.4", lhs), - index.alleles[index.entries[j].allele].data, GVA_VARIANT_PRINT_SPDI("NG_008376.4", rhs)); - } // if - - rhs_ts = bitset_destroy(gva_std_allocator, rhs_ts); - rhs_gs = bitset_destroy(gva_std_allocator, rhs_gs); - rhs_cs = bitset_destroy(gva_std_allocator, rhs_cs); - rhs_as = bitset_destroy(gva_std_allocator, rhs_as); - rhs_dels = bitset_destroy(gva_std_allocator, rhs_dels); - gva_lcs_graph_destroy(gva_std_allocator, rhs_graph); + count += 1; + GVA_Relation const relation = compare_from_index(reference, lhs, index.entries[i].distance, rhs, index.entries[j].distance); + printf("%s\n", GVA_RELATION_LABELS[relation]); } // if } // for - lhs_ts = bitset_destroy(gva_std_allocator, lhs_ts); - lhs_gs = bitset_destroy(gva_std_allocator, lhs_gs); - lhs_cs = bitset_destroy(gva_std_allocator, lhs_cs); - lhs_as = bitset_destroy(gva_std_allocator, lhs_as); - lhs_dels = bitset_destroy(gva_std_allocator, lhs_dels); - gva_lcs_graph_destroy(gva_std_allocator, lhs_graph); } // for fprintf(stderr, "number of pairs calculated: %zu\n", count); From 2305c69d49d0ab13cb7d644a3401d1963397a985 Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 13 Aug 2025 13:58:41 +0200 Subject: [PATCH 328/704] Don't decref string objects? --- python/algebra_extmodule.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/python/algebra_extmodule.c b/python/algebra_extmodule.c index d7bb759..5839dfa 100644 --- a/python/algebra_extmodule.c +++ b/python/algebra_extmodule.c @@ -77,7 +77,7 @@ LCSgraph_from_variants(PyObject* cls, PyObject* args, PyObject* kwargs) char const* reference = NULL; Py_ssize_t len_ref = 0; PyObject* variant_list = NULL; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#O!|", + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#O!|from_variants", (char*[]) {"reference", "variants", NULL}, &reference, &len_ref, &PyList_Type, &variant_list)) { @@ -144,7 +144,7 @@ LCSgraph_canonical(LCSgraph_Object* self) return NULL; } // if PyObject* item = PyObject_CallFunction((PyObject*) state->Variant_Type, "nnO", variants[i].start, variants[i].end, str); - Py_DECREF(str); + // FIXME: Py_DECREF(str); if (item == NULL) { Py_DECREF(result); @@ -189,7 +189,7 @@ LCSgraph_local_supremal(LCSgraph_Object* self) return NULL; } // if PyObject* item = PyObject_CallFunction((PyObject*) state->Variant_Type, "nnO", variant.start, variant.end, str); - Py_DECREF(str); + // FIXME: Py_DECREF(str); if (item == NULL) { Py_DECREF(result); @@ -216,7 +216,7 @@ LCSgraph_supremal(LCSgraph_Object* self) return NULL; } // if PyObject* result = PyObject_CallFunction((PyObject*) state->Variant_Type, "nnO", self->graph.supremal.start, self->graph.supremal.end, str); - Py_DECREF(str); + // FIXME: Py_DECREF(str); return result; } // LCSgraph_supremal From 88d7a3c4e0c0cc2ebba01f6d8052dbe11824c4ae Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 13 Aug 2025 13:59:49 +0200 Subject: [PATCH 329/704] Binary search --- src/main.c | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/src/main.c b/src/main.c index 1e17925..ccb572c 100644 --- a/src/main.c +++ b/src/main.c @@ -453,6 +453,32 @@ entry_cmp(void const* lhs, void const* rhs) } // entry_cmp +static size_t +binary_search(size_t const n, GVA_Stabbing_Entry const entries[static n], + GVA_Stabbing_Entry const key, size_t low) +{ + size_t high = n; + while (low <= high) + { + size_t const mid = low + (high - low) / 2; + int const cmp = entry_cmp(&entries[mid], &key); + if (cmp < 0) + { + low = mid + 1; + } // if + else if (cmp > 0 && mid > 0) + { + high = mid - 1; + } // if + else + { + return mid; + } // else + } // while + return low; +} // binary_search + + int all(int argc, char* argv[static argc + 1]) { @@ -498,10 +524,6 @@ all(int argc, char* argv[static argc + 1]) GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &variant); - if (array_length(graph.local_supremal) == 2) - { - // continue; - } size_t const allele = gva_stabbing_index_add_allele(gva_std_allocator, &index, rsid, graph.distance) - 1; fprintf(stderr, "%u\n", graph.distance); size_t sum = 0; @@ -530,7 +552,7 @@ all(int argc, char* argv[static argc + 1]) { fprintf(stderr, "%u != %zu\n", graph.distance, sum); return -1; - } + } // if gva_string_destroy(gva_std_allocator, graph.observed); gva_lcs_graph_destroy(gva_std_allocator, graph); From b5d1804184c5c9d373a660a8cc164a9dbfca5a78 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Wed, 13 Aug 2025 15:23:20 +0200 Subject: [PATCH 330/704] WIP first logic query single loc sup part. --- src/main.c | 85 +++++++++++++++++++++++++++++------------------------- 1 file changed, 46 insertions(+), 39 deletions(-) diff --git a/src/main.c b/src/main.c index 85fffe7..29bac90 100644 --- a/src/main.c +++ b/src/main.c @@ -474,7 +474,7 @@ compare_from_index(GVA_String const reference, size_t const lhs_len = (lhs.start - start) + lhs.sequence.len + (end - lhs.end); size_t const rhs_len = (rhs.start - start) + rhs.sequence.len + (end - rhs.end); - size_t distance = 0; + gva_uint distance = 0; if (lhs_len == 0) { distance = rhs_len; @@ -519,8 +519,14 @@ compare_from_index(GVA_String const reference, return GVA_CONTAINS; } // if - // CHECK + if (rhs_dist - lhs_dist == distance) + { + return GVA_IS_CONTAINED; + } // if + size_t const len = end - start + 1; + size_t const start_intersection = MAX(lhs.start, rhs.start); + size_t const end_intersection = MIN(lhs.end, rhs.end); GVA_LCS_Graph lhs_graph = gva_lcs_graph_init(gva_std_allocator, lhs.end - lhs.start, reference.str + lhs.start, lhs.sequence.len, lhs.sequence.str, lhs.start); size_t* lhs_dels = bitset_init(gva_std_allocator, len); // can be one shorter @@ -528,7 +534,7 @@ compare_from_index(GVA_String const reference, size_t* lhs_cs = bitset_init(gva_std_allocator, len); size_t* lhs_gs = bitset_init(gva_std_allocator, len); size_t* lhs_ts = bitset_init(gva_std_allocator, len); - bitset_fill(lhs_graph, lhs.start, lhs.start, lhs.end, lhs_dels, lhs_as, lhs_cs, lhs_gs, lhs_ts); + bitset_fill(lhs_graph, start, start_intersection, end_intersection, lhs_dels, lhs_as, lhs_cs, lhs_gs, lhs_ts); GVA_LCS_Graph rhs_graph = gva_lcs_graph_init(gva_std_allocator, rhs.end - rhs.start, reference.str + rhs.start, rhs.sequence.len, rhs.sequence.str, rhs.start); size_t* rhs_dels = bitset_init(gva_std_allocator, len); // can be one shorter @@ -536,7 +542,7 @@ compare_from_index(GVA_String const reference, size_t* rhs_cs = bitset_init(gva_std_allocator, len); size_t* rhs_gs = bitset_init(gva_std_allocator, len); size_t* rhs_ts = bitset_init(gva_std_allocator, len); - bitset_fill(rhs_graph, lhs.start, rhs.start, rhs.end, rhs_dels, rhs_as, rhs_cs, rhs_gs, rhs_ts); + bitset_fill(rhs_graph, start, start_intersection, end_intersection, rhs_dels, rhs_as, rhs_cs, rhs_gs, rhs_ts); if (bitset_intersection_cnt(lhs_dels, rhs_dels) > 0 || bitset_intersection_cnt(lhs_as, rhs_as) > 0 || @@ -616,13 +622,7 @@ all(int argc, char* argv[static argc + 1]) GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &variant); - if (array_length(graph.local_supremal) == 2) - { - // continue; - } size_t const allele = gva_stabbing_index_add_allele(gva_std_allocator, &index, rsid, graph.distance) - 1; - fprintf(stderr, "%u\n", graph.distance); - size_t sum = 0; for (size_t i = 0; i < array_length(graph.local_supremal) - 1; ++i) { GVA_Variant variant; @@ -630,25 +630,13 @@ all(int argc, char* argv[static argc + 1]) graph.local_supremal[i], graph.local_supremal[i + 1], i == 0, i == array_length(graph.local_supremal) - 2, &variant); - fprintf(stderr, " (%u, %u, %u) -> (%u, %u, %u): " GVA_VARIANT_FMT " %u\n", - graph.local_supremal[i].row, graph.local_supremal[i].col, graph.local_supremal[i].length, - graph.local_supremal[i + 1].row, graph.local_supremal[i + 1].col, graph.local_supremal[i + 1].length, - GVA_VARIANT_PRINT(variant), graph.local_supremal[i + 1].edges); - - sum += graph.local_supremal[i + 1].edges; gva_uint const inserted = trie_insert(gva_std_allocator, &trie, variant.sequence.len, variant.sequence.str); gva_stabbing_index_add_part(gva_std_allocator, &index, variant.start, variant.end, inserted, graph.local_supremal[i + 1].edges, allele); } // for - fprintf(stderr, "\n"); - if (graph.distance != sum) - { - fprintf(stderr, "%u != %zu\n", graph.distance, sum); - return -1; - } gva_string_destroy(gva_std_allocator, graph.observed); gva_lcs_graph_destroy(gva_std_allocator, graph); @@ -675,7 +663,7 @@ all(int argc, char* argv[static argc + 1]) for (size_t i = 0; i < array_length(index.alleles); ++i) { - fprintf(stderr, "%zu\n", index.alleles[i].data); + // fprintf(stderr, "%zu\n", index.alleles[i].data); for (gva_uint j = index.alleles[i].head; j != GVA_NULL; j = index.entries[j].next) { GVA_Variant const variant = {index.entries[j].start, index.entries[j].end, trie_string(trie, index.entries[j].inserted)}; @@ -686,27 +674,46 @@ all(int argc, char* argv[static argc + 1]) TIC(perf_calculate_relations); - count = 0; - for (size_t i = 1; i < array_length(index.entries); ++i) + // NG_008376.4:9199:5:CCCCG + // GVA_Variant rhs = {9199, 9203, {4, "CCCC"}}; + GVA_Variant rhs = {9199, 9204, {5, "CCCCG"}}; + gva_uint rhs_dist = 4; + gva_uint* results = gva_stabbing_index_intersect(gva_std_allocator, index, rhs.start, rhs.end); + + for (size_t i = 0; i < array_length(results); ++i) { - GVA_Variant const lhs = {index.entries[i].start, index.entries[i].end, {trie.nodes[index.entries[i].inserted].end - trie.nodes[index.entries[i].inserted].start, trie.strings.str + trie.nodes[index.entries[i].inserted].start}}; + if (results[i] != 3858) + { + //continue; + } + GVA_Variant const lhs = {index.entries[results[i]].start, index.entries[results[i]].end, trie_string(trie, index.entries[results[i]].inserted)}; + GVA_Relation relation = compare_from_index(reference, lhs, index.entries[results[i]].distance, rhs, rhs_dist); - for (size_t j = i + 1; j < array_length(index.entries); ++j) + // fprintf(stderr, GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(lhs)); + // fprintf(stderr, GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(rhs)); + + // fprintf(stderr, "%u %u\n", index.entries[results[i]].distance, rhs_dist); + if (relation == GVA_EQUIVALENT) { - if (index.entries[i].end < index.entries[j].start) + if (index.alleles[index.entries[results[i]].allele].distance > rhs_dist) { - break; - } // if - if (index.entries[j].end >= index.entries[i].start && index.entries[j].start <= index.entries[i].end) + relation = GVA_CONTAINS; + } + } + else if (relation == GVA_IS_CONTAINED) + { + if (index.alleles[index.entries[results[i]].allele].distance > index.entries[results[i]].distance) { - GVA_Variant const rhs = {index.entries[j].start, index.entries[j].end, {trie.nodes[index.entries[j].inserted].end - trie.nodes[index.entries[j].inserted].start, trie.strings.str + trie.nodes[index.entries[j].inserted].start}}; - count += 1; - GVA_Relation const relation = compare_from_index(reference, lhs, index.entries[i].distance, rhs, index.entries[j].distance); - printf("%s\n", GVA_RELATION_LABELS[relation]); - } // if - } // for - } // for - fprintf(stderr, "number of pairs calculated: %zu\n", count); + relation = GVA_OVERLAP; + } + } + + printf("%u %zu %s\n", results[i], index.alleles[index.entries[results[i]].allele].data, GVA_RELATION_LABELS[relation]); + } + + // printf("%s\n", GVA_RELATION_LABELS[relation]); + + results = ARRAY_DESTROY(gva_std_allocator, results); TOC(perf_calculate_relations); From 91968425398dbf45bd9a9ac9df04385d8f4a4684 Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 13 Aug 2025 17:19:44 +0200 Subject: [PATCH 331/704] WIP: arguments to Python objects --- python/algebra_extmodule.c | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/python/algebra_extmodule.c b/python/algebra_extmodule.c index 5839dfa..7b6394f 100644 --- a/python/algebra_extmodule.c +++ b/python/algebra_extmodule.c @@ -143,8 +143,16 @@ LCSgraph_canonical(LCSgraph_Object* self) variants = ARRAY_DESTROY(gva_std_allocator, variants); return NULL; } // if - PyObject* item = PyObject_CallFunction((PyObject*) state->Variant_Type, "nnO", variants[i].start, variants[i].end, str); - // FIXME: Py_DECREF(str); + PyObject* args = Py_BuildValue("nnO", variants[i].start, variants[i].end, str); + if (args == NULL) + { + Py_DECREF(str); + Py_DECREF(result); + variants = ARRAY_DESTROY(gva_std_allocator, variants); + return NULL; + } // if + PyObject* item = PyObject_CallObject((PyObject*) state->Variant_Type, args); + Py_DECREF(args); if (item == NULL) { Py_DECREF(result); @@ -188,8 +196,15 @@ LCSgraph_local_supremal(LCSgraph_Object* self) Py_DECREF(result); return NULL; } // if - PyObject* item = PyObject_CallFunction((PyObject*) state->Variant_Type, "nnO", variant.start, variant.end, str); - // FIXME: Py_DECREF(str); + PyObject* args = Py_BuildValue("nnO", variant.start, variant.end, str); + if (args == NULL) + { + Py_DECREF(str); + Py_DECREF(result); + return NULL; + } // if + PyObject* item = PyObject_CallObject((PyObject*) state->Variant_Type, args); + Py_DECREF(args); if (item == NULL) { Py_DECREF(result); @@ -215,8 +230,14 @@ LCSgraph_supremal(LCSgraph_Object* self) { return NULL; } // if - PyObject* result = PyObject_CallFunction((PyObject*) state->Variant_Type, "nnO", self->graph.supremal.start, self->graph.supremal.end, str); - // FIXME: Py_DECREF(str); + PyObject* args = Py_BuildValue("nnO", self->graph.supremal.start, self->graph.supremal.end, str); + if (args == NULL) + { + Py_DECREF(str); + return NULL; + } // if + PyObject* result = PyObject_CallObject((PyObject*) state->Variant_Type, args); + Py_DECREF(args); return result; } // LCSgraph_supremal From 73d2dfa844ef9b0db6cca1de55fbe30d4a505f7c Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Wed, 13 Aug 2025 20:49:52 +0200 Subject: [PATCH 332/704] LCSgraph for rhs. --- src/main.c | 73 +++++++++++++++++++++++++++++++++--------------------- 1 file changed, 45 insertions(+), 28 deletions(-) diff --git a/src/main.c b/src/main.c index b9e2456..3366881 100644 --- a/src/main.c +++ b/src/main.c @@ -689,53 +689,70 @@ all(int argc, char* argv[static argc + 1]) for (gva_uint j = index.alleles[i].head; j != GVA_NULL; j = index.entries[j].next) { GVA_Variant const variant = {index.entries[j].start, index.entries[j].end, trie_string(trie, index.entries[j].inserted)}; - fprintf(stderr, GVA_VARIANT_FMT " ", GVA_VARIANT_PRINT(variant)); + // fprintf(stderr, GVA_VARIANT_FMT " ", GVA_VARIANT_PRINT(variant)); } // for - fprintf(stderr, "\n"); + // fprintf(stderr, "\n"); } // for TIC(perf_calculate_relations); // NG_008376.4:9199:5:CCCCG // GVA_Variant rhs = {9199, 9203, {4, "CCCC"}}; - GVA_Variant rhs = {9199, 9204, {5, "CCCCG"}}; - gva_uint rhs_dist = 4; - gva_uint* results = gva_stabbing_index_intersect(gva_std_allocator, index, rhs.start, rhs.end); + // GVA_Variant rhs = {9199, 9204, {5, "CCCCG"}}; + // gva_uint rhs_dist = 4; - for (size_t i = 0; i < array_length(results); ++i) + GVA_LCS_Graph rhs_graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, + 2, (GVA_Variant[]) {(GVA_Variant) {7869, 7870, {1, "T"}}, (GVA_Variant) {9199, 9200, {1, "C"}}}); + + for (size_t i = 0; i < array_length(rhs_graph.local_supremal) - 1; ++i) { - if (results[i] != 3858) - { - //continue; - } - GVA_Variant const lhs = {index.entries[results[i]].start, index.entries[results[i]].end, trie_string(trie, index.entries[results[i]].inserted)}; - GVA_Relation relation = compare_from_index(reference, lhs, index.entries[results[i]].distance, rhs, rhs_dist); + GVA_Variant rhs; + gva_edges(rhs_graph.observed.str, + rhs_graph.local_supremal[i], rhs_graph.local_supremal[i + 1], + i == 0, i == array_length(rhs_graph.local_supremal) - 2, + &rhs); - // fprintf(stderr, GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(lhs)); - // fprintf(stderr, GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(rhs)); + gva_uint rhs_dist = rhs_graph.local_supremal[i + 1].edges; + fprintf(stderr, GVA_VARIANT_FMT " %u\n", GVA_VARIANT_PRINT(rhs), rhs_graph.local_supremal[i + 1].edges); - // fprintf(stderr, "%u %u\n", index.entries[results[i]].distance, rhs_dist); - if (relation == GVA_EQUIVALENT) + gva_uint* results = gva_stabbing_index_intersect(gva_std_allocator, index, rhs.start, rhs.end); + + for (size_t i = 0; i < array_length(results); ++i) { - if (index.alleles[index.entries[results[i]].allele].distance > rhs_dist) + if (results[i] != 3858) { - relation = GVA_CONTAINS; + //continue; } - } - else if (relation == GVA_IS_CONTAINED) - { - if (index.alleles[index.entries[results[i]].allele].distance > index.entries[results[i]].distance) + GVA_Variant const lhs = {index.entries[results[i]].start, index.entries[results[i]].end, trie_string(trie, index.entries[results[i]].inserted)}; + GVA_Relation relation = compare_from_index(reference, lhs, index.entries[results[i]].distance, rhs, rhs_dist); + + // fprintf(stderr, GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(lhs)); + // fprintf(stderr, GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(rhs)); + + // fprintf(stderr, "%u %u\n", index.entries[results[i]].distance, rhs_dist); + if (relation == GVA_EQUIVALENT) { - relation = GVA_OVERLAP; + if (index.alleles[index.entries[results[i]].allele].distance > rhs_dist) + { + relation = GVA_CONTAINS; + } + } + else if (relation == GVA_IS_CONTAINED) + { + if (index.alleles[index.entries[results[i]].allele].distance > index.entries[results[i]].distance) + { + relation = GVA_OVERLAP; + } } - } - printf("%u %zu %s\n", results[i], index.alleles[index.entries[results[i]].allele].data, GVA_RELATION_LABELS[relation]); - } + fprintf(stderr, "%u %zu %s\n", results[i], index.alleles[index.entries[results[i]].allele].data, GVA_RELATION_LABELS[relation]); + + } - // printf("%s\n", GVA_RELATION_LABELS[relation]); + // printf("%s\n", GVA_RELATION_LABELS[relation]); - results = ARRAY_DESTROY(gva_std_allocator, results); + results = ARRAY_DESTROY(gva_std_allocator, results); + } TOC(perf_calculate_relations); From f8c63c962646e6f1ce301ee862825f763d3d4d61 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Thu, 14 Aug 2025 14:40:17 +0200 Subject: [PATCH 333/704] Local supremal based query. --- src/main.c | 91 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 53 insertions(+), 38 deletions(-) diff --git a/src/main.c b/src/main.c index 3366881..f556afd 100644 --- a/src/main.c +++ b/src/main.c @@ -683,27 +683,21 @@ all(int argc, char* argv[static argc + 1]) TOC(perf_build_index); - for (size_t i = 0; i < array_length(index.alleles); ++i) - { - // fprintf(stderr, "%zu\n", index.alleles[i].data); - for (gva_uint j = index.alleles[i].head; j != GVA_NULL; j = index.entries[j].next) - { - GVA_Variant const variant = {index.entries[j].start, index.entries[j].end, trie_string(trie, index.entries[j].inserted)}; - // fprintf(stderr, GVA_VARIANT_FMT " ", GVA_VARIANT_PRINT(variant)); - } // for - // fprintf(stderr, "\n"); - } // for - TIC(perf_calculate_relations); - // NG_008376.4:9199:5:CCCCG - // GVA_Variant rhs = {9199, 9203, {4, "CCCC"}}; - // GVA_Variant rhs = {9199, 9204, {5, "CCCCG"}}; - // gva_uint rhs_dist = 4; - GVA_LCS_Graph rhs_graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 2, (GVA_Variant[]) {(GVA_Variant) {7869, 7870, {1, "T"}}, (GVA_Variant) {9199, 9200, {1, "C"}}}); + struct { + gva_uint included; + gva_uint excluded; + }* result_map = gva_std_allocator.allocate(gva_std_allocator.context, NULL, 0, 1024 * sizeof(*result_map)); + if (result_map == NULL) + { + return -1; + } + memset(result_map, 0, 1024 * sizeof(*result_map)); + for (size_t i = 0; i < array_length(rhs_graph.local_supremal) - 1; ++i) { GVA_Variant rhs; @@ -717,42 +711,63 @@ all(int argc, char* argv[static argc + 1]) gva_uint* results = gva_stabbing_index_intersect(gva_std_allocator, index, rhs.start, rhs.end); - for (size_t i = 0; i < array_length(results); ++i) - { - if (results[i] != 3858) + for (size_t i = 0; i < array_length(results); ++i) { + GVA_Variant const lhs = {index.entries[results[i]].start, index.entries[results[i]].end, + trie_string(trie, index.entries[results[i]].inserted)}; + GVA_Relation relation = compare_from_index(reference, lhs, index.entries[results[i]].distance, rhs, + rhs_dist); + + if (relation == GVA_EQUIVALENT || relation == GVA_CONTAINS) + { + result_map[index.entries[results[i]].allele].included += rhs_dist; + } + else if (relation == GVA_IS_CONTAINED) + { + result_map[index.entries[results[i]].allele].included += index.entries[results[i]].distance; + result_map[index.entries[results[i]].allele].excluded += rhs_dist - index.entries[results[i]].distance; + } + else if (relation == GVA_OVERLAP) { - //continue; + result_map[index.entries[results[i]].allele].included += 1; + result_map[index.entries[results[i]].allele].excluded += 1; } - GVA_Variant const lhs = {index.entries[results[i]].start, index.entries[results[i]].end, trie_string(trie, index.entries[results[i]].inserted)}; - GVA_Relation relation = compare_from_index(reference, lhs, index.entries[results[i]].distance, rhs, rhs_dist); + } - // fprintf(stderr, GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(lhs)); - // fprintf(stderr, GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(rhs)); + results = ARRAY_DESTROY(gva_std_allocator, results); + } - // fprintf(stderr, "%u %u\n", index.entries[results[i]].distance, rhs_dist); - if (relation == GVA_EQUIVALENT) + for (size_t i = 0; i < 1024; ++i) + { + if (result_map[i].included > 0 || result_map[i].excluded > 0) + { + result_map[i].excluded = rhs_graph.distance - result_map[i].included; + + GVA_Relation relation = GVA_OVERLAP; + if (result_map[i].excluded == 0) { - if (index.alleles[index.entries[results[i]].allele].distance > rhs_dist) + if (result_map[i].included == index.alleles[i].distance) + { + relation = GVA_EQUIVALENT; + } + else { relation = GVA_CONTAINS; } } - else if (relation == GVA_IS_CONTAINED) + else if (result_map[i].included == index.alleles[i].distance) { - if (index.alleles[index.entries[results[i]].allele].distance > index.entries[results[i]].distance) - { - relation = GVA_OVERLAP; - } + relation = GVA_IS_CONTAINED; } - fprintf(stderr, "%u %zu %s\n", results[i], index.alleles[index.entries[results[i]].allele].data, GVA_RELATION_LABELS[relation]); - + fprintf(stderr, "%zu(%u): %u %u -> %s\n", + index.alleles[i].data, index.alleles[i].distance, + result_map[i].included, result_map[i].excluded, GVA_RELATION_LABELS[relation]); } - - // printf("%s\n", GVA_RELATION_LABELS[relation]); - - results = ARRAY_DESTROY(gva_std_allocator, results); } + result_map = gva_std_allocator.allocate(gva_std_allocator.context, result_map, 1024 * sizeof(*result_map), 0); + + gva_string_destroy(gva_std_allocator, rhs_graph.observed); + gva_lcs_graph_destroy(gva_std_allocator, rhs_graph); TOC(perf_calculate_relations); From f8d1abdc61b8e407e7b191d9292f943796efe1af Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Thu, 14 Aug 2025 16:24:53 +0200 Subject: [PATCH 334/704] Shelf union calculation for later debugging purposes. --- src/compare.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/compare.c b/src/compare.c index ce7d751..94c1514 100644 --- a/src/compare.c +++ b/src/compare.c @@ -307,6 +307,21 @@ gva_compare_supremals(GVA_Allocator const allocator, bitset_intersection_cnt(lhs_gs, rhs_gs) + bitset_intersection_cnt(lhs_ts, rhs_ts); + // Also calculate the union + // Note: bitset_fill needs to use "plain" start and end. + // + // size_t const union1 = + // bitset_intersection_cnt(lhs_dels, lhs_dels) + + // bitset_intersection_cnt(lhs_as, lhs_as) + + // bitset_intersection_cnt(lhs_cs, lhs_cs) + + // bitset_intersection_cnt(lhs_gs, lhs_gs) + + // bitset_intersection_cnt(lhs_ts, lhs_ts) + + // bitset_intersection_cnt(rhs_dels, rhs_dels) + + // bitset_intersection_cnt(rhs_as, rhs_as) + + // bitset_intersection_cnt(rhs_cs, rhs_cs) + + // bitset_intersection_cnt(rhs_gs, rhs_gs) + + // bitset_intersection_cnt(rhs_ts, rhs_ts) - common; + if (common > 0) { relation = GVA_OVERLAP; From f9b69bbd342c6551ff1fe7230e45ebd42951d2f5 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Thu, 14 Aug 2025 16:27:01 +0200 Subject: [PATCH 335/704] Validate non-distance based relations with python output from compare_all2.txt. --- src/main.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/src/main.c b/src/main.c index f556afd..86c6ab5 100644 --- a/src/main.c +++ b/src/main.c @@ -778,12 +778,69 @@ all(int argc, char* argv[static argc + 1]) } // all +int +compare(int argc, char* argv[static argc + 1]) +{ + GVA_String reference = {0, NULL}; + errno = 0; + FILE* const restrict stream = fopen(argv[1], "r"); + if (stream == NULL) + { + fprintf(stderr, "error: %s\n", strerror(errno)); + return EXIT_FAILURE; + } // if + reference = gva_fasta_sequence(gva_std_allocator, stream); + fclose(stream); + + char lhs_hgvs[4096]; + char lhs_spdi[4096]; + size_t lhs_dist; + char rhs_hgvs[4096]; + char rhs_spdi[4096]; + size_t rhs_dist; + size_t dist; + char python[32]; + size_t common_count; + size_t union_count; + size_t count = 0; + // NC_000001.11:6100897:2:CC 2 NC_000001.11:6100895:3:GGG 2 2 overlap 1 8 + while (fscanf(stdin, "%4096s %zu %4096s %zu %zu %32s %zu %zu\n", lhs_spdi, &lhs_dist, rhs_spdi, &rhs_dist, &dist, python, &common_count, &union_count) == 8) + { + GVA_Variant lhs; + if (!gva_parse_spdi(strlen(lhs_spdi), lhs_spdi, &lhs)) + { + fprintf(stderr, "PARSE ERROR: %s\n", lhs_spdi); + continue; + } // if + GVA_Variant rhs; + if (!gva_parse_spdi(strlen(rhs_spdi), rhs_spdi, &rhs)) + { + fprintf(stderr, "PARSE ERROR: %s\n", rhs_spdi); + continue; + } // if + + size_t const relation = gva_compare_supremals(gva_std_allocator, reference.len, reference.str, lhs, rhs); + if (strcmp(python, GVA_RELATION_LABELS[relation]) != 0) + { + printf("%s %s %s %s %s\n", lhs_hgvs, lhs_spdi, rhs_hgvs, rhs_spdi, GVA_RELATION_LABELS[relation]); + } // if + + count += 1; + } // while + fprintf(stderr, "total: %zu\n", count); + gva_string_destroy(gva_std_allocator, reference); + + return 0; +} // compare + int main(int argc, char* argv[static argc + 1]) { - (void) argv; //return extract(argc, argv); // all return all(argc, argv); + + // compare + // return compare(argc, argv); } // main From 48f6e10c855c77f271b1e0a7ba367344aabccc73 Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 15 Aug 2025 23:04:11 +0200 Subject: [PATCH 336/704] WIP: interval tree --- include/index.h | 36 +++++++ src/index.c | 271 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 307 insertions(+) create mode 100644 include/index.h create mode 100644 src/index.c diff --git a/include/index.h b/include/index.h new file mode 100644 index 0000000..cec3699 --- /dev/null +++ b/include/index.h @@ -0,0 +1,36 @@ +#ifndef GVA_INDEX_H +#define GVA_INDEX_H + + +#include // size_t + +#include "allocator.h" // GVA_Allocator +#include "types.h" // gva_uint +#include "variant.h" // GVA_Variant + + +typedef struct +{ + GVA_Allocator allocator; + gva_uint root; + struct Allele* alleles; + struct Node* nodes; + struct Next_Allele* next_alleles; +} GVA_Index; + + +GVA_Index +gva_index_init(GVA_Allocator const allocator); + + +void +gva_index_destroy(GVA_Index self); + + +void +gva_index_add(GVA_Index self, size_t const data, + size_t const n, GVA_Variant const variants[static n]); + + +#endif // GVA_INDEX_H + diff --git a/src/index.c b/src/index.c new file mode 100644 index 0000000..d7c8679 --- /dev/null +++ b/src/index.c @@ -0,0 +1,271 @@ +#include // uint64_t +#include // NULL, size_t + +#include "../include/allocator.h" // GVA_Allocator +#include "../include/index.h" // GVA_Index +#include "../include/types.h" // GVA_NULL, gva_uint +#include "array.h" // ARRAY_APPEND, ARRAY_DESTROY, array_length +#include "common.h" // MAX + + +typedef struct Allele +{ + size_t data; + gva_uint start; + gva_uint end; +} Allele; + + +typedef struct Node +{ + gva_uint child[2]; + gva_uint start; + gva_uint end; + gva_uint max; + gva_uint allele; + // FIXME: we assume gva_uint is 32bits + gva_uint balance : 3; + gva_uint inserted : 29; +} Node; + + +typedef struct Next_Allele +{ + gva_uint allele; + gva_uint next; +} Next_Allele; + + +inline GVA_Index +gva_index_init(GVA_Allocator const allocator) +{ + return (GVA_Index) {allocator, GVA_NULL, NULL, NULL, NULL}; +} // gva_index_init + + +inline void +gva_index_destroy(GVA_Index self) +{ + self.root = GVA_NULL; + self.alleles = ARRAY_DESTROY(self.allocator, self.alleles); + self.nodes = ARRAY_DESTROY(self.allocator, self.nodes); + self.next_alleles = ARRAY_DESTROY(self.allocator, self.next_alleles); +} // gva_index_destroy + + +enum +{ + LEFT = 0, + RIGHT = 1 +}; + + +static inline gva_uint +update_max(GVA_Index const self, gva_uint const idx) +{ + gva_uint result = self.nodes[idx].end; + if (self.nodes[idx].child[LEFT] != GVA_NULL) + { + result = MAX(result, self.nodes[self.nodes[idx].child[LEFT]].max); + } // if + if (self.nodes[idx].child[RIGHT] != GVA_NULL) + { + result = MAX(result, self.nodes[self.nodes[idx].child[RIGHT]].max); + } // if + return result; +} // update_max + + +static gva_uint +insert(GVA_Index self, gva_uint const idx) +{ + if (self.root == GVA_NULL) + { + self.root = idx; + return idx; + } // if + + // limiting to height 64 becomes a problem after allocating 413 TiB + // at the earliest; it allows for a minimum of + // 27,777,890,035,287 nodes + uint64_t path = 0; // bit-path to first unbalanced ancestor + int len = 0; // length of the path + int dir = 0; + + gva_uint tmp = self.root; + gva_uint tmp_par = self.root; // parent of tmp + + gva_uint unbal = self.root; // first unbalanced ancestor of tmp + gva_uint unbal_par = self.root; // parent of unbalanced + + // Insert a new node at the BST position + while (tmp != GVA_NULL) + { + self.nodes[tmp].max = MAX(self.nodes[tmp].max, self.nodes[idx].end); + + if (self.nodes[tmp].balance != 0) + { + // this is now the first unbalanced ancestor of tmp + unbal_par = tmp_par; + unbal = tmp; + path = 0; + len = 0; + } // if + + dir = self.nodes[idx].start > self.nodes[tmp].start; + if (dir == RIGHT) + { + path |= (uint64_t) RIGHT << len; + } // if + len += 1; + + tmp_par = tmp; + tmp = self.nodes[tmp].child[dir]; + } // while + + // TODO: early return if found + + self.nodes[tmp_par].child[dir] = idx; + + // Update the balance factors along the path from the first + // unbalanced ancestor to the new node + tmp = unbal; + while (tmp != idx) + { + if ((path & RIGHT) == RIGHT) + { + self.nodes[tmp].balance += 1; + } // if + else + { + self.nodes[tmp].balance -= 1; + } // else + + tmp = self.nodes[tmp].child[path & RIGHT]; + path >>= 1; + } // while + + // Do the rotations if necessary + gva_uint root = 0; + if (self.nodes[unbal].balance == -2) + { + gva_uint const child = self.nodes[unbal].child[LEFT]; + if (self.nodes[child].balance == -1) + { + root = child; + self.nodes[unbal].child[LEFT] = self.nodes[child].child[RIGHT]; + self.nodes[child].child[RIGHT] = unbal; + self.nodes[child].balance = 0; + self.nodes[unbal].balance = 0; + self.nodes[child].max = update_max(self, child); + self.nodes[unbal].max = update_max(self, unbal); + } // if + else + { + root = self.nodes[child].child[RIGHT]; + self.nodes[child].child[RIGHT] = self.nodes[root].child[LEFT]; + self.nodes[root].child[LEFT] = child; + self.nodes[unbal].child[LEFT] = self.nodes[root].child[RIGHT]; + self.nodes[root].child[RIGHT] = unbal; + if (self.nodes[root].balance == -1) + { + self.nodes[child].balance = 0; + self.nodes[unbal].balance = 1; + } // if + else if (self.nodes[root].balance == 0) + { + self.nodes[child].balance = 0; + self.nodes[unbal].balance = 0; + } // if + else + { + self.nodes[child].balance = -1; + self.nodes[unbal].balance = 0; + } // else + self.nodes[root].balance = 0; + + self.nodes[root].max = update_max(self, root); + self.nodes[child].max = update_max(self, child); + self.nodes[unbal].max = update_max(self, unbal); + } // else + } // if + else if (self.nodes[unbal].balance == 2) + { + gva_uint const child = self.nodes[unbal].child[RIGHT]; + if (self.nodes[child].balance == 1) + { + root = child; + self.nodes[unbal].child[RIGHT] = self.nodes[child].child[LEFT]; + self.nodes[child].child[LEFT] = unbal; + self.nodes[child].balance = 0; + self.nodes[unbal].balance = 0; + + self.nodes[child].max = update_max(self, child); + self.nodes[unbal].max = update_max(self, unbal); + } // if + else + { + root = self.nodes[child].child[LEFT]; + self.nodes[child].child[LEFT] = self.nodes[root].child[RIGHT]; + self.nodes[root].child[RIGHT] = child; + self.nodes[unbal].child[RIGHT] = self.nodes[root].child[LEFT]; + self.nodes[root].child[LEFT] = unbal; + if (self.nodes[root].balance == 1) + { + self.nodes[child].balance = 0; + self.nodes[unbal].balance = -1; + } // if + else if(self.nodes[root].balance == 0) + { + self.nodes[child].balance = 0; + self.nodes[unbal].balance = 0; + } // if + else + { + self.nodes[child].balance = 1; + self.nodes[unbal].balance = 0; + } // else + self.nodes[root].balance = 0; + + self.nodes[root].max = update_max(self, root); + self.nodes[child].max = update_max(self, child); + self.nodes[unbal].max = update_max(self, unbal); + } // else + } // if + else + { + return idx; + } // else + + if (self.root == unbal) + { + self.root = root; + return idx; + } // if + + self.nodes[unbal_par].child[unbal != self.nodes[unbal_par].child[LEFT]] = root; + return idx; +} // insert + + +void +gva_index_add(GVA_Index self, size_t const data, + size_t const n, GVA_Variant const variants[static n]) +{ + gva_uint const allele = ARRAY_APPEND(self.allocator, self.alleles, ((Allele) {data, array_length(self.next_alleles) - 1, array_length(self.next_alleles) + n - 1})) - 1; + for (size_t i = 0; i < n; ++i) + { + gva_uint const idx = ARRAY_APPEND(self.allocator, self.next_alleles, ((Next_Allele) {allele, GVA_NULL})) - 1; + if (1 /* not found */) + { + gva_uint const inserted = 0; /* insert in trie */ + gva_uint const node = ARRAY_APPEND(self.allocator, self.nodes, ((Node) {{GVA_NULL, GVA_NULL}, variants[i].start, variants[i].end, variants[i].end, idx, 0, inserted})) - 1; + insert(self, node); + } // if + else + { + self.next_alleles[idx].next = 0; /* found node */ + self.nodes[0 /* found node */].allele = idx; + } // else + } // for +} // gva_index_add From 2bbce977140833b0d0f28937fe3e9bfcb71f0c46 Mon Sep 17 00:00:00 2001 From: jkvis Date: Sat, 16 Aug 2025 10:40:12 +0200 Subject: [PATCH 337/704] WIP: interval tree with duplicates --- include/index.h | 36 ------ src/index.c | 271 -------------------------------------------- src/interval_tree.c | 217 +++++++++++++++++++++++++++++++++++ src/interval_tree.h | 42 +++++++ src/main.c | 135 ++++++++++++++++++---- src/trie.c | 9 +- src/trie.h | 4 + 7 files changed, 386 insertions(+), 328 deletions(-) delete mode 100644 include/index.h delete mode 100644 src/index.c create mode 100644 src/interval_tree.c create mode 100644 src/interval_tree.h diff --git a/include/index.h b/include/index.h deleted file mode 100644 index cec3699..0000000 --- a/include/index.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef GVA_INDEX_H -#define GVA_INDEX_H - - -#include // size_t - -#include "allocator.h" // GVA_Allocator -#include "types.h" // gva_uint -#include "variant.h" // GVA_Variant - - -typedef struct -{ - GVA_Allocator allocator; - gva_uint root; - struct Allele* alleles; - struct Node* nodes; - struct Next_Allele* next_alleles; -} GVA_Index; - - -GVA_Index -gva_index_init(GVA_Allocator const allocator); - - -void -gva_index_destroy(GVA_Index self); - - -void -gva_index_add(GVA_Index self, size_t const data, - size_t const n, GVA_Variant const variants[static n]); - - -#endif // GVA_INDEX_H - diff --git a/src/index.c b/src/index.c deleted file mode 100644 index d7c8679..0000000 --- a/src/index.c +++ /dev/null @@ -1,271 +0,0 @@ -#include // uint64_t -#include // NULL, size_t - -#include "../include/allocator.h" // GVA_Allocator -#include "../include/index.h" // GVA_Index -#include "../include/types.h" // GVA_NULL, gva_uint -#include "array.h" // ARRAY_APPEND, ARRAY_DESTROY, array_length -#include "common.h" // MAX - - -typedef struct Allele -{ - size_t data; - gva_uint start; - gva_uint end; -} Allele; - - -typedef struct Node -{ - gva_uint child[2]; - gva_uint start; - gva_uint end; - gva_uint max; - gva_uint allele; - // FIXME: we assume gva_uint is 32bits - gva_uint balance : 3; - gva_uint inserted : 29; -} Node; - - -typedef struct Next_Allele -{ - gva_uint allele; - gva_uint next; -} Next_Allele; - - -inline GVA_Index -gva_index_init(GVA_Allocator const allocator) -{ - return (GVA_Index) {allocator, GVA_NULL, NULL, NULL, NULL}; -} // gva_index_init - - -inline void -gva_index_destroy(GVA_Index self) -{ - self.root = GVA_NULL; - self.alleles = ARRAY_DESTROY(self.allocator, self.alleles); - self.nodes = ARRAY_DESTROY(self.allocator, self.nodes); - self.next_alleles = ARRAY_DESTROY(self.allocator, self.next_alleles); -} // gva_index_destroy - - -enum -{ - LEFT = 0, - RIGHT = 1 -}; - - -static inline gva_uint -update_max(GVA_Index const self, gva_uint const idx) -{ - gva_uint result = self.nodes[idx].end; - if (self.nodes[idx].child[LEFT] != GVA_NULL) - { - result = MAX(result, self.nodes[self.nodes[idx].child[LEFT]].max); - } // if - if (self.nodes[idx].child[RIGHT] != GVA_NULL) - { - result = MAX(result, self.nodes[self.nodes[idx].child[RIGHT]].max); - } // if - return result; -} // update_max - - -static gva_uint -insert(GVA_Index self, gva_uint const idx) -{ - if (self.root == GVA_NULL) - { - self.root = idx; - return idx; - } // if - - // limiting to height 64 becomes a problem after allocating 413 TiB - // at the earliest; it allows for a minimum of - // 27,777,890,035,287 nodes - uint64_t path = 0; // bit-path to first unbalanced ancestor - int len = 0; // length of the path - int dir = 0; - - gva_uint tmp = self.root; - gva_uint tmp_par = self.root; // parent of tmp - - gva_uint unbal = self.root; // first unbalanced ancestor of tmp - gva_uint unbal_par = self.root; // parent of unbalanced - - // Insert a new node at the BST position - while (tmp != GVA_NULL) - { - self.nodes[tmp].max = MAX(self.nodes[tmp].max, self.nodes[idx].end); - - if (self.nodes[tmp].balance != 0) - { - // this is now the first unbalanced ancestor of tmp - unbal_par = tmp_par; - unbal = tmp; - path = 0; - len = 0; - } // if - - dir = self.nodes[idx].start > self.nodes[tmp].start; - if (dir == RIGHT) - { - path |= (uint64_t) RIGHT << len; - } // if - len += 1; - - tmp_par = tmp; - tmp = self.nodes[tmp].child[dir]; - } // while - - // TODO: early return if found - - self.nodes[tmp_par].child[dir] = idx; - - // Update the balance factors along the path from the first - // unbalanced ancestor to the new node - tmp = unbal; - while (tmp != idx) - { - if ((path & RIGHT) == RIGHT) - { - self.nodes[tmp].balance += 1; - } // if - else - { - self.nodes[tmp].balance -= 1; - } // else - - tmp = self.nodes[tmp].child[path & RIGHT]; - path >>= 1; - } // while - - // Do the rotations if necessary - gva_uint root = 0; - if (self.nodes[unbal].balance == -2) - { - gva_uint const child = self.nodes[unbal].child[LEFT]; - if (self.nodes[child].balance == -1) - { - root = child; - self.nodes[unbal].child[LEFT] = self.nodes[child].child[RIGHT]; - self.nodes[child].child[RIGHT] = unbal; - self.nodes[child].balance = 0; - self.nodes[unbal].balance = 0; - self.nodes[child].max = update_max(self, child); - self.nodes[unbal].max = update_max(self, unbal); - } // if - else - { - root = self.nodes[child].child[RIGHT]; - self.nodes[child].child[RIGHT] = self.nodes[root].child[LEFT]; - self.nodes[root].child[LEFT] = child; - self.nodes[unbal].child[LEFT] = self.nodes[root].child[RIGHT]; - self.nodes[root].child[RIGHT] = unbal; - if (self.nodes[root].balance == -1) - { - self.nodes[child].balance = 0; - self.nodes[unbal].balance = 1; - } // if - else if (self.nodes[root].balance == 0) - { - self.nodes[child].balance = 0; - self.nodes[unbal].balance = 0; - } // if - else - { - self.nodes[child].balance = -1; - self.nodes[unbal].balance = 0; - } // else - self.nodes[root].balance = 0; - - self.nodes[root].max = update_max(self, root); - self.nodes[child].max = update_max(self, child); - self.nodes[unbal].max = update_max(self, unbal); - } // else - } // if - else if (self.nodes[unbal].balance == 2) - { - gva_uint const child = self.nodes[unbal].child[RIGHT]; - if (self.nodes[child].balance == 1) - { - root = child; - self.nodes[unbal].child[RIGHT] = self.nodes[child].child[LEFT]; - self.nodes[child].child[LEFT] = unbal; - self.nodes[child].balance = 0; - self.nodes[unbal].balance = 0; - - self.nodes[child].max = update_max(self, child); - self.nodes[unbal].max = update_max(self, unbal); - } // if - else - { - root = self.nodes[child].child[LEFT]; - self.nodes[child].child[LEFT] = self.nodes[root].child[RIGHT]; - self.nodes[root].child[RIGHT] = child; - self.nodes[unbal].child[RIGHT] = self.nodes[root].child[LEFT]; - self.nodes[root].child[LEFT] = unbal; - if (self.nodes[root].balance == 1) - { - self.nodes[child].balance = 0; - self.nodes[unbal].balance = -1; - } // if - else if(self.nodes[root].balance == 0) - { - self.nodes[child].balance = 0; - self.nodes[unbal].balance = 0; - } // if - else - { - self.nodes[child].balance = 1; - self.nodes[unbal].balance = 0; - } // else - self.nodes[root].balance = 0; - - self.nodes[root].max = update_max(self, root); - self.nodes[child].max = update_max(self, child); - self.nodes[unbal].max = update_max(self, unbal); - } // else - } // if - else - { - return idx; - } // else - - if (self.root == unbal) - { - self.root = root; - return idx; - } // if - - self.nodes[unbal_par].child[unbal != self.nodes[unbal_par].child[LEFT]] = root; - return idx; -} // insert - - -void -gva_index_add(GVA_Index self, size_t const data, - size_t const n, GVA_Variant const variants[static n]) -{ - gva_uint const allele = ARRAY_APPEND(self.allocator, self.alleles, ((Allele) {data, array_length(self.next_alleles) - 1, array_length(self.next_alleles) + n - 1})) - 1; - for (size_t i = 0; i < n; ++i) - { - gva_uint const idx = ARRAY_APPEND(self.allocator, self.next_alleles, ((Next_Allele) {allele, GVA_NULL})) - 1; - if (1 /* not found */) - { - gva_uint const inserted = 0; /* insert in trie */ - gva_uint const node = ARRAY_APPEND(self.allocator, self.nodes, ((Node) {{GVA_NULL, GVA_NULL}, variants[i].start, variants[i].end, variants[i].end, idx, 0, inserted})) - 1; - insert(self, node); - } // if - else - { - self.next_alleles[idx].next = 0; /* found node */ - self.nodes[0 /* found node */].allele = idx; - } // else - } // for -} // gva_index_add diff --git a/src/interval_tree.c b/src/interval_tree.c new file mode 100644 index 0000000..551d3d5 --- /dev/null +++ b/src/interval_tree.c @@ -0,0 +1,217 @@ +#include // NULL +#include // uint64_t + +#include "../include/allocator.h" // GVA_Allocator +#include "../include/types.h" // GVA_NULL +#include "array.h" // ARRAY_DESTROY +#include "common.h" // MAX +#include "interval_tree.h" // Interval_Tree, interval_tree_* + + +inline Interval_Tree +interval_tree_init(void) +{ + return (Interval_Tree) {NULL, GVA_NULL}; +} // interval_tree_init + + +inline void +interval_tree_destroy(GVA_Allocator const allocator, Interval_Tree self[static 1]) +{ + self->nodes = ARRAY_DESTROY(allocator, self->nodes); + self->root = GVA_NULL; +} // interval_tree_destroy + + +enum +{ + LEFT = 0, + RIGHT = 1 +}; + + +static inline gva_uint +calculate_max(Interval_Tree_Node const nodes[static 1], gva_uint const idx) +{ + gva_uint result = nodes[idx].end; + if (nodes[idx].child[LEFT] != GVA_NULL) + { + result = MAX(result, nodes[nodes[idx].child[LEFT]].max); + } // if + if (nodes[idx].child[RIGHT] != GVA_NULL) + { + result = MAX(result, nodes[nodes[idx].child[RIGHT]].max); + } // if + return result; +} // calculate_max + + +gva_uint +interval_tree_insert(Interval_Tree self[static 1], gva_uint const idx) +{ + if (self->root == GVA_NULL) + { + self->root = idx; + return idx; + } // if + + // limiting to height 64 allows for a minimum of + // 27,777,890,035,287 nodes + uint64_t path = 0; // bit-path to first unbalanced ancestor + int len = 0; // length of the path + int dir = LEFT; + + gva_uint tmp = self->root; + gva_uint tmp_par = self->root; // parent of tmp + + gva_uint unbal = self->root; // first unbalanced ancestor of tmp + gva_uint unbal_par = self->root; // parent of unbalanced + + // Insert a new node at the BST position + while (tmp != GVA_NULL) + { + self->nodes[tmp].max = MAX(self->nodes[tmp].max, self->nodes[idx].end); + + if (self->nodes[tmp].balance != 0) + { + // this is now the first unbalanced ancestor of tmp + unbal_par = tmp_par; + unbal = tmp; + path = 0; + len = 0; + } // if + + dir = self->nodes[idx].start > self->nodes[tmp].start; + if (dir == RIGHT) + { + path |= (uint64_t) RIGHT << len; + } // if + len += 1; + + tmp_par = tmp; + tmp = self->nodes[tmp].child[dir]; + } // while + + // TODO: early return if found + + self->nodes[tmp_par].child[dir] = idx; + + // Update the balance factors along the path from the first + // unbalanced ancestor to the new node + tmp = unbal; + while (tmp != idx) + { + if ((path & RIGHT) == RIGHT) + { + self->nodes[tmp].balance += 1; + } // if + else + { + self->nodes[tmp].balance -= 1; + } // else + + tmp = self->nodes[tmp].child[path & RIGHT]; + path >>= 1; + } // while + + // Do the rotations if necessary + gva_uint root = 0; + if (self->nodes[unbal].balance == -2) + { + gva_uint const child = self->nodes[unbal].child[LEFT]; + if (self->nodes[child].balance == -1) + { + root = child; + self->nodes[unbal].child[LEFT] = self->nodes[child].child[RIGHT]; + self->nodes[child].child[RIGHT] = unbal; + self->nodes[child].balance = 0; + self->nodes[unbal].balance = 0; + self->nodes[child].max = calculate_max(self->nodes, child); + self->nodes[unbal].max = calculate_max(self->nodes, unbal); + } // if + else + { + root = self->nodes[child].child[RIGHT]; + self->nodes[child].child[RIGHT] = self->nodes[root].child[LEFT]; + self->nodes[root].child[LEFT] = child; + self->nodes[unbal].child[LEFT] = self->nodes[root].child[RIGHT]; + self->nodes[root].child[RIGHT] = unbal; + if (self->nodes[root].balance == -1) + { + self->nodes[child].balance = 0; + self->nodes[unbal].balance = 1; + } // if + else if (self->nodes[root].balance == 0) + { + self->nodes[child].balance = 0; + self->nodes[unbal].balance = 0; + } // if + else + { + self->nodes[child].balance = -1; + self->nodes[unbal].balance = 0; + } // else + self->nodes[root].balance = 0; + + self->nodes[root].max = calculate_max(self->nodes, root); + self->nodes[child].max = calculate_max(self->nodes, child); + self->nodes[unbal].max = calculate_max(self->nodes, unbal); + } // else + } // if + else if (self->nodes[unbal].balance == 2) + { + gva_uint const child = self->nodes[unbal].child[RIGHT]; + if (self->nodes[child].balance == 1) + { + root = child; + self->nodes[unbal].child[RIGHT] = self->nodes[child].child[LEFT]; + self->nodes[child].child[LEFT] = unbal; + self->nodes[child].balance = 0; + self->nodes[unbal].balance = 0; + + self->nodes[child].max = calculate_max(self->nodes, child); + self->nodes[unbal].max = calculate_max(self->nodes, unbal); + } // if + else + { + root = self->nodes[child].child[LEFT]; + self->nodes[child].child[LEFT] = self->nodes[root].child[RIGHT]; + self->nodes[root].child[RIGHT] = child; + self->nodes[unbal].child[RIGHT] = self->nodes[root].child[LEFT]; + self->nodes[root].child[LEFT] = unbal; + if (self->nodes[root].balance == 1) + { + self->nodes[child].balance = 0; + self->nodes[unbal].balance = -1; + } // if + else if(self->nodes[root].balance == 0) + { + self->nodes[child].balance = 0; + self->nodes[unbal].balance = 0; + } // if + else + { + self->nodes[child].balance = 1; + self->nodes[unbal].balance = 0; + } // else + self->nodes[root].balance = 0; + + self->nodes[root].max = calculate_max(self->nodes, root); + self->nodes[child].max = calculate_max(self->nodes, child); + self->nodes[unbal].max = calculate_max(self->nodes, unbal); + } // else + } // if + else + { + return idx; + } // else + + if (self->root == unbal) + { + self->root = root; + return idx; + } // if + + self->nodes[unbal_par].child[unbal != self->nodes[unbal_par].child[LEFT]] = root; + return idx; +} // interval_tree_insert diff --git a/src/interval_tree.h b/src/interval_tree.h new file mode 100644 index 0000000..3192da5 --- /dev/null +++ b/src/interval_tree.h @@ -0,0 +1,42 @@ +#ifndef GVA_INTERVAL_TREE_H +#define GVA_INTERVAL_TREE_H + + +#include "../include/allocator.h" // GVA_Allocator +#include "../include/types.h" // gva_uint + + +typedef struct +{ + gva_uint child[2]; + gva_uint start; + gva_uint end; + gva_uint max; + // FIXME: we assume gva_uint is 32bits + gva_uint balance : 3; + gva_uint inserted : 29; + gva_uint allele; + gva_uint distance; +} Interval_Tree_Node; + + +typedef struct +{ + Interval_Tree_Node* nodes; + gva_uint root; +} Interval_Tree; + + +Interval_Tree +interval_tree_init(void); + + +void +interval_tree_destroy(GVA_Allocator const allocator, Interval_Tree self[static 1]); + + +gva_uint +interval_tree_insert(Interval_Tree self[static 1], gva_uint const idx); + + +#endif // GVA_INTERVAL_TREE_H diff --git a/src/main.c b/src/main.c index 86c6ab5..528647f 100644 --- a/src/main.c +++ b/src/main.c @@ -16,10 +16,11 @@ #include "../include/types.h" // GVA_NULL, gva_uint #include "../include/utils.h" // gva_fasta_sequence #include "../include/variant.h" // GVA_VARIANT_*, GVA_Variant, gva_parse_spdi -#include "array.h" // ARRAY_DESTROY, array_length -#include "bitset.h" // bitset_* -#include "common.h" // MAX, MIN -#include "trie.h" // Trie, trie_* +#include "array.h" // ARRAY_DESTROY, array_length +#include "bitset.h" // bitset_* +#include "common.h" // MAX, MIN +#include "interval_tree.h" // Interval_Tree, interval_tree_* +#include "trie.h" // Trie, trie_* #define TIC(x) clock_t const x = clock() @@ -394,6 +395,32 @@ trie_raw(FILE* const stream, Trie const self) } // trie_raw +static void +interval_tree_dot_node(FILE* const stream, Interval_Tree const self, gva_uint const idx) +{ + fprintf(stream, "%u[label=\"[%u, %u) %u\"]\n", idx, self.nodes[idx].start, self.nodes[idx].end, self.nodes[idx].max); + if (self.nodes[idx].child[0] != GVA_NULL) + { + fprintf(stream, "%u->%u\n", idx, self.nodes[idx].child[0]); + interval_tree_dot_node(stream, self, self.nodes[idx].child[0]); + } // if + if (self.nodes[idx].child[1] != GVA_NULL) + { + fprintf(stream, "%u->%u\n", idx, self.nodes[idx].child[1]); + interval_tree_dot_node(stream, self, self.nodes[idx].child[1]); + } // if +} // interval_tree_dot_node + + +void +interval_tree_dot(FILE* const stream, Interval_Tree const self) +{ + fprintf(stream, "strict digraph{\n"); + interval_tree_dot_node(stream, self, self.root); + fprintf(stream, "}\n"); +} // interval_tree_dot + + void bitset_print(size_t const bitset[static 1], size_t const size) { @@ -453,7 +480,7 @@ entry_cmp(void const* lhs, void const* rhs) } // entry_cmp -static size_t +size_t binary_search(size_t const n, GVA_Stabbing_Entry const entries[static n], GVA_Stabbing_Entry const key, size_t low) { @@ -597,7 +624,7 @@ compare_from_index(GVA_String const reference, gva_lcs_graph_destroy(gva_std_allocator, rhs_graph); return relation; -} +} // compare_from_index int @@ -657,7 +684,6 @@ all(int argc, char* argv[static argc + 1]) gva_uint const inserted = trie_insert(gva_std_allocator, &trie, variant.sequence.len, variant.sequence.str); gva_stabbing_index_add_part(gva_std_allocator, &index, variant.start, variant.end, inserted, graph.local_supremal[i + 1].edges, allele); - } // for gva_string_destroy(gva_std_allocator, graph.observed); @@ -695,7 +721,7 @@ all(int argc, char* argv[static argc + 1]) if (result_map == NULL) { return -1; - } + } // if memset(result_map, 0, 1024 * sizeof(*result_map)); for (size_t i = 0; i < array_length(rhs_graph.local_supremal) - 1; ++i) @@ -720,21 +746,21 @@ all(int argc, char* argv[static argc + 1]) if (relation == GVA_EQUIVALENT || relation == GVA_CONTAINS) { result_map[index.entries[results[i]].allele].included += rhs_dist; - } + } // if else if (relation == GVA_IS_CONTAINED) { result_map[index.entries[results[i]].allele].included += index.entries[results[i]].distance; result_map[index.entries[results[i]].allele].excluded += rhs_dist - index.entries[results[i]].distance; - } + } // if else if (relation == GVA_OVERLAP) { result_map[index.entries[results[i]].allele].included += 1; result_map[index.entries[results[i]].allele].excluded += 1; - } - } + } // if + } // for results = ARRAY_DESTROY(gva_std_allocator, results); - } + } // for for (size_t i = 0; i < 1024; ++i) { @@ -748,22 +774,22 @@ all(int argc, char* argv[static argc + 1]) if (result_map[i].included == index.alleles[i].distance) { relation = GVA_EQUIVALENT; - } + } // if else { relation = GVA_CONTAINS; - } + } // else } else if (result_map[i].included == index.alleles[i].distance) { relation = GVA_IS_CONTAINED; - } + } // if fprintf(stderr, "%zu(%u): %u %u -> %s\n", index.alleles[i].data, index.alleles[i].distance, result_map[i].included, result_map[i].excluded, GVA_RELATION_LABELS[relation]); - } - } + } // if + } // for result_map = gva_std_allocator.allocate(gva_std_allocator.context, result_map, 1024 * sizeof(*result_map), 0); gva_string_destroy(gva_std_allocator, rhs_graph.observed); @@ -830,16 +856,85 @@ compare(int argc, char* argv[static argc + 1]) fprintf(stderr, "total: %zu\n", count); gva_string_destroy(gva_std_allocator, reference); - return 0; + return EXIT_SUCCESS; } // compare + int main(int argc, char* argv[static argc + 1]) { + errno = 0; + FILE* stream = fopen(argv[1], "r"); + if (stream == NULL) + { + fprintf(stderr, "error: %s\n", strerror(errno)); + return EXIT_FAILURE; + } // if + + GVA_String reference = {0, NULL}; + reference = gva_fasta_sequence(gva_std_allocator, stream); + fclose(stream); + + fprintf(stderr, "reference length: %zu\n", reference.len); + + Trie trie = trie_init(); + Interval_Tree tree = interval_tree_init(); + + size_t count = 0; + static char line[LINE_SIZE] = {0}; + while (fgets(line, sizeof(line), stdin) != NULL) + { + size_t idx = 0; + size_t const id = parse_number(line, &idx); + idx += 1; // skip space or tab + int const len = (char*) memchr(line + idx, '\n', LINE_SIZE - idx) - (line + idx); + GVA_Variant variant; + if (gva_parse_spdi(len, line + idx, &variant) == 0) + { + fprintf(stderr, "error: SPDI parsing failed at line %zu: %s", count + 1, line); + continue; + } // if + + GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &variant); + for (size_t i = 0; i < array_length(graph.local_supremal) - 1; ++i) + { + GVA_Variant variant; + gva_edges(graph.observed.str, + graph.local_supremal[i], graph.local_supremal[i + 1], + i == 0, i == array_length(graph.local_supremal) - 2, + &variant); + + gva_uint const inserted = trie_insert(gva_std_allocator, &trie, variant.sequence.len, variant.sequence.str); + gva_uint const node = ARRAY_APPEND(gva_std_allocator, tree.nodes, ((Interval_Tree_Node) {{GVA_NULL, GVA_NULL}, variant.start, variant.end, variant.end, 0, inserted, id, graph.local_supremal[i + 1].edges})) - 1; + + if (interval_tree_insert(&tree, node) != node) + { + fprintf(stderr, "ERROR\n"); + } // if + } // for + + gva_string_destroy(gva_std_allocator, graph.observed); + gva_lcs_graph_destroy(gva_std_allocator, graph); + + count += 1; + } // while + fprintf(stderr, "count: %zu\n", count); + + fprintf(stderr, "tree nodes: %zu\n", array_length(tree.nodes)); + fprintf(stderr, "trie nodes: %zu\n", array_length(trie.nodes)); + + interval_tree_dot(stdout, tree); + + interval_tree_destroy(gva_std_allocator, &tree); + trie_destroy(gva_std_allocator, &trie); + + gva_string_destroy(gva_std_allocator, reference); + return EXIT_SUCCESS; + //return extract(argc, argv); // all - return all(argc, argv); + //return all(argc, argv); // compare // return compare(argc, argv); diff --git a/src/trie.c b/src/trie.c index 07d00be..cd10acf 100644 --- a/src/trie.c +++ b/src/trie.c @@ -1,5 +1,5 @@ #include // true -#include // size_t +#include // NULL, size_t #include "../include/allocator.h" // GVA_Allocator #include "../include/string.h" // GVA_String, gva_string_* @@ -8,6 +8,13 @@ #include "trie.h" // Trie, TrieNode, trie_* +inline Trie +trie_init(void) +{ + return (Trie) {{0, NULL}, NULL, GVA_NULL}; +} // trie_init + + inline void trie_destroy(GVA_Allocator const allocator, Trie self[static 1]) { diff --git a/src/trie.h b/src/trie.h index 5807016..5523050 100644 --- a/src/trie.h +++ b/src/trie.h @@ -27,6 +27,10 @@ typedef struct } Trie; +Trie +trie_init(void); + + void trie_destroy(GVA_Allocator const allocator, Trie self[static 1]); From 1d00908e2dc353be194d8442eea5811c2bacc86c Mon Sep 17 00:00:00 2001 From: jkvis Date: Sat, 16 Aug 2025 11:09:36 +0200 Subject: [PATCH 338/704] WIP: avoiding duplicates --- src/interval_tree.c | 8 +++++++- src/main.c | 5 +++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/interval_tree.c b/src/interval_tree.c index 551d3d5..3a7d4b9 100644 --- a/src/interval_tree.c +++ b/src/interval_tree.c @@ -88,11 +88,17 @@ interval_tree_insert(Interval_Tree self[static 1], gva_uint const idx) } // if len += 1; + if (self->nodes[tmp_par].start == self->nodes[idx].start && + self->nodes[tmp_par].end == self->nodes[idx].end && + self->nodes[tmp_par].inserted == self->nodes[idx].inserted) + { + return tmp_par; + } // if + tmp_par = tmp; tmp = self->nodes[tmp].child[dir]; } // while - // TODO: early return if found self->nodes[tmp_par].child[dir] = idx; diff --git a/src/main.c b/src/main.c index 528647f..06e1d9b 100644 --- a/src/main.c +++ b/src/main.c @@ -398,7 +398,7 @@ trie_raw(FILE* const stream, Trie const self) static void interval_tree_dot_node(FILE* const stream, Interval_Tree const self, gva_uint const idx) { - fprintf(stream, "%u[label=\"[%u, %u) %u\"]\n", idx, self.nodes[idx].start, self.nodes[idx].end, self.nodes[idx].max); + fprintf(stream, "%u[label=\"{[%u, %u), %u} %u\"]\n", idx, self.nodes[idx].start, self.nodes[idx].end, self.nodes[idx].inserted, self.nodes[idx].max); if (self.nodes[idx].child[0] != GVA_NULL) { fprintf(stream, "%u->%u\n", idx, self.nodes[idx].child[0]); @@ -909,7 +909,8 @@ main(int argc, char* argv[static argc + 1]) if (interval_tree_insert(&tree, node) != node) { - fprintf(stderr, "ERROR\n"); + fprintf(stderr, "FOUND\n"); + array_header(tree.nodes)->length -= 1; } // if } // for From 864ebe4fd1a1eeeb8f07fe6ead8633581ba08982 Mon Sep 17 00:00:00 2001 From: jkvis Date: Sat, 16 Aug 2025 13:44:47 +0200 Subject: [PATCH 339/704] WIP: Pharmvar uniq --- src/interval_tree.c | 8 ++++---- src/main.c | 2 -- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/interval_tree.c b/src/interval_tree.c index 3a7d4b9..b588612 100644 --- a/src/interval_tree.c +++ b/src/interval_tree.c @@ -88,11 +88,11 @@ interval_tree_insert(Interval_Tree self[static 1], gva_uint const idx) } // if len += 1; - if (self->nodes[tmp_par].start == self->nodes[idx].start && - self->nodes[tmp_par].end == self->nodes[idx].end && - self->nodes[tmp_par].inserted == self->nodes[idx].inserted) + if (self->nodes[tmp].start == self->nodes[idx].start && + self->nodes[tmp].end == self->nodes[idx].end && + self->nodes[tmp].inserted == self->nodes[idx].inserted) { - return tmp_par; + return tmp; } // if tmp_par = tmp; diff --git a/src/main.c b/src/main.c index 06e1d9b..15f41dd 100644 --- a/src/main.c +++ b/src/main.c @@ -906,10 +906,8 @@ main(int argc, char* argv[static argc + 1]) gva_uint const inserted = trie_insert(gva_std_allocator, &trie, variant.sequence.len, variant.sequence.str); gva_uint const node = ARRAY_APPEND(gva_std_allocator, tree.nodes, ((Interval_Tree_Node) {{GVA_NULL, GVA_NULL}, variant.start, variant.end, variant.end, 0, inserted, id, graph.local_supremal[i + 1].edges})) - 1; - if (interval_tree_insert(&tree, node) != node) { - fprintf(stderr, "FOUND\n"); array_header(tree.nodes)->length -= 1; } // if } // for From e4310f7f096289247eb2d7865bcd9d9eddd60e50 Mon Sep 17 00:00:00 2001 From: jkvis Date: Sat, 16 Aug 2025 15:37:37 +0200 Subject: [PATCH 340/704] WIP: index with join table --- src/interval_tree.c | 2 +- src/interval_tree.h | 2 +- src/main.c | 65 ++++++++++++++++++++++++++++++--------------- 3 files changed, 45 insertions(+), 24 deletions(-) diff --git a/src/interval_tree.c b/src/interval_tree.c index b588612..8a43296 100644 --- a/src/interval_tree.c +++ b/src/interval_tree.c @@ -88,6 +88,7 @@ interval_tree_insert(Interval_Tree self[static 1], gva_uint const idx) } // if len += 1; + // Disallow duplicates if (self->nodes[tmp].start == self->nodes[idx].start && self->nodes[tmp].end == self->nodes[idx].end && self->nodes[tmp].inserted == self->nodes[idx].inserted) @@ -99,7 +100,6 @@ interval_tree_insert(Interval_Tree self[static 1], gva_uint const idx) tmp = self->nodes[tmp].child[dir]; } // while - self->nodes[tmp_par].child[dir] = idx; // Update the balance factors along the path from the first diff --git a/src/interval_tree.h b/src/interval_tree.h index 3192da5..69f4562 100644 --- a/src/interval_tree.h +++ b/src/interval_tree.h @@ -15,7 +15,7 @@ typedef struct // FIXME: we assume gva_uint is 32bits gva_uint balance : 3; gva_uint inserted : 29; - gva_uint allele; + gva_uint alleles; gva_uint distance; } Interval_Tree_Node; diff --git a/src/main.c b/src/main.c index 15f41dd..2ebe06e 100644 --- a/src/main.c +++ b/src/main.c @@ -395,28 +395,22 @@ trie_raw(FILE* const stream, Trie const self) } // trie_raw -static void -interval_tree_dot_node(FILE* const stream, Interval_Tree const self, gva_uint const idx) -{ - fprintf(stream, "%u[label=\"{[%u, %u), %u} %u\"]\n", idx, self.nodes[idx].start, self.nodes[idx].end, self.nodes[idx].inserted, self.nodes[idx].max); - if (self.nodes[idx].child[0] != GVA_NULL) - { - fprintf(stream, "%u->%u\n", idx, self.nodes[idx].child[0]); - interval_tree_dot_node(stream, self, self.nodes[idx].child[0]); - } // if - if (self.nodes[idx].child[1] != GVA_NULL) - { - fprintf(stream, "%u->%u\n", idx, self.nodes[idx].child[1]); - interval_tree_dot_node(stream, self, self.nodes[idx].child[1]); - } // if -} // interval_tree_dot_node - - void interval_tree_dot(FILE* const stream, Interval_Tree const self) { fprintf(stream, "strict digraph{\n"); - interval_tree_dot_node(stream, self, self.root); + for (size_t i = 0; i < array_length(self.nodes); ++i) + { + fprintf(stream, "%zu[label=\"{[%u, %u), %u} %u %d\"]\n", i, self.nodes[i].start, self.nodes[i].end, self.nodes[i].inserted, self.nodes[i].max, self.nodes[i].alleles); + if (self.nodes[i].child[0] != GVA_NULL) + { + fprintf(stream, "%zu->%u\n", i, self.nodes[i].child[0]); + } // if + if (self.nodes[i].child[1] != GVA_NULL) + { + fprintf(stream, "%zu->%u\n", i, self.nodes[i].child[1]); + } // if + } // if fprintf(stream, "}\n"); } // interval_tree_dot @@ -879,6 +873,18 @@ main(int argc, char* argv[static argc + 1]) Trie trie = trie_init(); Interval_Tree tree = interval_tree_init(); + struct Node_Allele + { + gva_uint node; + gva_uint allele; + gva_uint next; + }* node_allele_join = NULL; + struct Allele + { + size_t data; + gva_uint start; + gva_uint distance; + }* alleles = NULL; size_t count = 0; static char line[LINE_SIZE] = {0}; @@ -896,6 +902,7 @@ main(int argc, char* argv[static argc + 1]) } // if GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &variant); + gva_uint const allele = ARRAY_APPEND(gva_std_allocator, alleles, ((struct Allele) {id, array_length(node_allele_join), graph.distance})) - 1; for (size_t i = 0; i < array_length(graph.local_supremal) - 1; ++i) { GVA_Variant variant; @@ -905,11 +912,13 @@ main(int argc, char* argv[static argc + 1]) &variant); gva_uint const inserted = trie_insert(gva_std_allocator, &trie, variant.sequence.len, variant.sequence.str); - gva_uint const node = ARRAY_APPEND(gva_std_allocator, tree.nodes, ((Interval_Tree_Node) {{GVA_NULL, GVA_NULL}, variant.start, variant.end, variant.end, 0, inserted, id, graph.local_supremal[i + 1].edges})) - 1; - if (interval_tree_insert(&tree, node) != node) + gva_uint const node = ARRAY_APPEND(gva_std_allocator, tree.nodes, ((Interval_Tree_Node) {{GVA_NULL, GVA_NULL}, variant.start, variant.end, variant.end, 0, inserted, GVA_NULL, graph.local_supremal[i + 1].edges})) - 1; + gva_uint const here = interval_tree_insert(&tree, node); + if (here != node) { - array_header(tree.nodes)->length -= 1; + array_header(tree.nodes)->length -= 1; // delete; already in the tree } // if + tree.nodes[here].alleles = ARRAY_APPEND(gva_std_allocator, node_allele_join, ((struct Node_Allele) {here, allele, tree.nodes[here].alleles})) - 1; } // for gva_string_destroy(gva_std_allocator, graph.observed); @@ -922,8 +931,20 @@ main(int argc, char* argv[static argc + 1]) fprintf(stderr, "tree nodes: %zu\n", array_length(tree.nodes)); fprintf(stderr, "trie nodes: %zu\n", array_length(trie.nodes)); - interval_tree_dot(stdout, tree); + //interval_tree_dot(stdout, tree); + for (size_t i = 0; i < array_length(alleles); ++i) + { + gva_uint const end = i < array_length(alleles) - 1 ? alleles[i + 1].start : array_length(node_allele_join); + fprintf(stderr, "Allele[%zu]: {%zu, [%u, %u), %u}\n", i, alleles[i].data, alleles[i].start, end, alleles[i].distance); + } // for + + for (size_t i = 0; i < array_length(node_allele_join); ++i) + { + fprintf(stderr, "%zu: {%u, %u, %d}\n", i, node_allele_join[i].node, node_allele_join[i].allele, node_allele_join[i].next); + } // for + alleles = ARRAY_DESTROY(gva_std_allocator, alleles); + node_allele_join = ARRAY_DESTROY(gva_std_allocator, node_allele_join); interval_tree_destroy(gva_std_allocator, &tree); trie_destroy(gva_std_allocator, &trie); From cf62ad9c6b34ebc64f24d3985a1f76d77eb211ed Mon Sep 17 00:00:00 2001 From: jkvis Date: Sat, 16 Aug 2025 19:16:07 +0200 Subject: [PATCH 341/704] WIP: Interval tree intersection --- src/interval_tree.c | 35 +++++++++++++++++++++++++++++++++++ src/interval_tree.h | 5 +++++ src/main.c | 14 ++++++++++++++ 3 files changed, 54 insertions(+) diff --git a/src/interval_tree.c b/src/interval_tree.c index 8a43296..45ad4f0 100644 --- a/src/interval_tree.c +++ b/src/interval_tree.c @@ -221,3 +221,38 @@ interval_tree_insert(Interval_Tree self[static 1], gva_uint const idx) self->nodes[unbal_par].child[unbal != self->nodes[unbal_par].child[LEFT]] = root; return idx; } // interval_tree_insert + + +// FIXME: recursion! +static gva_uint* +intersect(GVA_Allocator const allocator, Interval_Tree_Node const nodes[static 1], + gva_uint const idx, gva_uint const start, gva_uint const end, gva_uint* results) +{ + if (idx == GVA_NULL || nodes[idx].max < start) + { + return results; + } // if + + if (nodes[idx].start > end) + { + return intersect(allocator, nodes, nodes[idx].child[LEFT], start, end, results); + } // if + + results = intersect(allocator, nodes, nodes[idx].child[LEFT], start, end, results); + + // FIXME: endpoints? + if (start < nodes[idx].end && end >= nodes[idx].start) + { + ARRAY_APPEND(allocator, results, idx); + } // if + + return intersect(allocator, nodes, nodes[idx].child[RIGHT], start, end, results); +} // intersect + + +inline gva_uint* +interval_tree_intersection(GVA_Allocator const allocator, Interval_Tree const self, + gva_uint const start, gva_uint const end) +{ + return intersect(allocator, self.nodes, self.root, start, end, NULL); +} // interval_tree_intersection diff --git a/src/interval_tree.h b/src/interval_tree.h index 69f4562..2411ba6 100644 --- a/src/interval_tree.h +++ b/src/interval_tree.h @@ -39,4 +39,9 @@ gva_uint interval_tree_insert(Interval_Tree self[static 1], gva_uint const idx); +gva_uint* +interval_tree_intersection(GVA_Allocator const allocator, Interval_Tree const self, + gva_uint const start, gva_uint const end); + + #endif // GVA_INTERVAL_TREE_H diff --git a/src/main.c b/src/main.c index 2ebe06e..10a3207 100644 --- a/src/main.c +++ b/src/main.c @@ -931,7 +931,10 @@ main(int argc, char* argv[static argc + 1]) fprintf(stderr, "tree nodes: %zu\n", array_length(tree.nodes)); fprintf(stderr, "trie nodes: %zu\n", array_length(trie.nodes)); + fprintf(stderr, "#alleles: %zu\n", array_length(alleles)); + fprintf(stderr, "#join: %zu\n", array_length(node_allele_join)); //interval_tree_dot(stdout, tree); + /* for (size_t i = 0; i < array_length(alleles); ++i) { gva_uint const end = i < array_length(alleles) - 1 ? alleles[i + 1].start : array_length(node_allele_join); @@ -942,6 +945,17 @@ main(int argc, char* argv[static argc + 1]) { fprintf(stderr, "%zu: {%u, %u, %d}\n", i, node_allele_join[i].node, node_allele_join[i].allele, node_allele_join[i].next); } // for + */ + + gva_uint* results = interval_tree_intersection(gva_std_allocator, tree, 6000, 6250); + + for (size_t i = 0; i < array_length(results); ++i) + { + fprintf(stderr, "[%u, %u)\n", tree.nodes[results[i]].start, tree.nodes[results[i]].end); + } // for + fprintf(stderr, "results: %zu\n", array_length(results)); + + results = ARRAY_DESTROY(gva_std_allocator, results); alleles = ARRAY_DESTROY(gva_std_allocator, alleles); node_allele_join = ARRAY_DESTROY(gva_std_allocator, node_allele_join); From 9c7ce11323d734afd3b39e73ff879fed9d65d480 Mon Sep 17 00:00:00 2001 From: jkvis Date: Sun, 17 Aug 2025 10:51:35 +0200 Subject: [PATCH 342/704] WIP: simple hash --- src/hash_table.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++ src/hash_table.h | 39 +++++++++++++++++++++++++ src/main.c | 19 ++++++++++++ 3 files changed, 134 insertions(+) create mode 100644 src/hash_table.c create mode 100644 src/hash_table.h diff --git a/src/hash_table.c b/src/hash_table.c new file mode 100644 index 0000000..fc12be5 --- /dev/null +++ b/src/hash_table.c @@ -0,0 +1,76 @@ +#include // true +#include // NULL, size_t +#include // uint32_t, uintmax_t +#include // memcpy + +#include "array.h" // ARRAY_DESTROY, Array, array_* +#include "hash_table.h" // hash_table_* + + +void* +hash_table_init(GVA_Allocator const allocator, size_t const capacity, size_t const item_size) +{ + void* hash_table = array_init(allocator, capacity, item_size); + for (size_t i = 0; i < capacity; ++i) + { + *(uint32_t*) ((uintmax_t) hash_table + i * item_size) = -1; + } // if + return hash_table; +} // hash_table_init + + +// Jenkins hash +static inline uint32_t +hash(uint32_t key) +{ + key = (key + 0x7ed55d16) + (key << 12); + key = (key ^ 0xc761c23c) ^ (key >> 19); + key = (key + 0x165667b1) + (key << 5); + key = (key + 0xd3a2646c) ^ (key << 9); + key = (key + 0xfd7046c5) + (key << 3); + key = (key ^ 0xb55a4f09) ^ (key >> 16); + return key; +} // hash + + +size_t +hash_table_index(void* const self, size_t const item_size, uint32_t const key) +{ + size_t probe = 0; + while (true) + { + // Quadratic probing with c1 and c2 1/2. + size_t const idx = (hash(key) + (probe + probe * probe) / 2) % array_header(self)->capacity; + if (*(uint32_t*) ((uintmax_t) self + idx * item_size) == (uint32_t) -1 || + *(uint32_t*) ((uintmax_t) self + idx * item_size) == key) + { + return idx; + } // if + probe += 1; + } // while +} // hash_table_index + + +void* +hash_table_ensure(GVA_Allocator const allocator, void* const self, size_t const item_size) +{ + size_t const old_capacity = array_header(self)->capacity; + if (array_length(self) < old_capacity / 2) + { + return self; + } // if + void* new_table = hash_table_init(allocator, old_capacity * 2, item_size); // OVERFLOW + if (new_table == NULL) + { + return self; // OOM + } // if + for (size_t i = 0; i < old_capacity; ++i) + { + array_header(new_table)->length += 1; + void* const src = (void*) ((uintmax_t) self + i * item_size); + void* const dest = (void*) ((uintmax_t) new_table + hash_table_index(new_table, item_size, *(uint32_t*) src) * item_size); + memcpy(dest, src, item_size); + } // for + ARRAY_DESTROY(allocator, (Array*) self); + return new_table; +} // hash_table_ensure diff --git a/src/hash_table.h b/src/hash_table.h new file mode 100644 index 0000000..7592b2f --- /dev/null +++ b/src/hash_table.h @@ -0,0 +1,39 @@ +#ifndef GVA_HASH_TABLE_H +#define GVA_HASH_TABLE_H + + +#include // size_t +#include // uint32_t + +#include "../include/allocator.h" // GVA_Allocator +#include "array.h" // ARRAY_DESTROY, array_header + + +#define HASH_TABLE_KEY uint32_t gva_key + + +void* +hash_table_init(GVA_Allocator const allocator, size_t const capacity, size_t const item_size); + + +size_t +hash_table_index(void* const self, size_t const item_size, uint32_t const key); + + +void* +hash_table_ensure(GVA_Allocator const allocator, void* const self, size_t const item_size); + + +#define HASH_TABLE_DESTROY(allocator, self) ARRAY_DESTROY(allocator, self) + + +#define HASH_TABLE_INDEX(self, key) hash_table_index(self, sizeof(*self), key) + + +#define HASH_TABLE_SET(allocator, self, key, value) \ + (self) = hash_table_ensure(allocator, self, (sizeof(*(self)))), \ + array_header(self)->length += 1, \ + self[hash_table_index(self, sizeof(*(self)), key)] = (value) + + +#endif // GVA_HASH_TABLE_H diff --git a/src/main.c b/src/main.c index 10a3207..cd79d9b 100644 --- a/src/main.c +++ b/src/main.c @@ -19,6 +19,7 @@ #include "array.h" // ARRAY_DESTROY, array_length #include "bitset.h" // bitset_* #include "common.h" // MAX, MIN +#include "hash_table.h" // HASH_TABLE_KEY, hash_table_* #include "interval_tree.h" // Interval_Tree, interval_tree_* #include "trie.h" // Trie, trie_* @@ -857,6 +858,24 @@ compare(int argc, char* argv[static argc + 1]) int main(int argc, char* argv[static argc + 1]) { + struct IN_EX + { + HASH_TABLE_KEY; + gva_uint included; + gva_uint excluded; + }* table = hash_table_init(gva_std_allocator, 1024, sizeof(*table)); + + HASH_TABLE_SET(gva_std_allocator, table, 42, ((struct IN_EX) {42, 1, 2})); + + if (table[HASH_TABLE_INDEX(table, 42)].gva_key == 42) + { + fprintf(stderr, "FOUND at %zu\n", HASH_TABLE_INDEX(table, 42)); + } // if + + table = HASH_TABLE_DESTROY(gva_std_allocator, table); + + return EXIT_SUCCESS; + errno = 0; FILE* stream = fopen(argv[1], "r"); if (stream == NULL) From 3f6540c783d9cf41647db096f45a245f07bd041f Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 18 Aug 2025 08:56:23 +0200 Subject: [PATCH 343/704] WIP: only rehash actual buckets --- src/hash_table.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/hash_table.c b/src/hash_table.c index fc12be5..45e02b9 100644 --- a/src/hash_table.c +++ b/src/hash_table.c @@ -66,10 +66,14 @@ hash_table_ensure(GVA_Allocator const allocator, void* const self, size_t const } // if for (size_t i = 0; i < old_capacity; ++i) { - array_header(new_table)->length += 1; - void* const src = (void*) ((uintmax_t) self + i * item_size); - void* const dest = (void*) ((uintmax_t) new_table + hash_table_index(new_table, item_size, *(uint32_t*) src) * item_size); - memcpy(dest, src, item_size); + void const* const src = (void*) ((uintmax_t) self + i * item_size); + if (*(uint32_t*) src != (uint32_t) -1) + { + array_header(new_table)->length += 1; + memcpy( + (void*) ((uintmax_t) new_table + hash_table_index(new_table, item_size, *(uint32_t*) src) * item_size), + src, item_size); + } // if } // for ARRAY_DESTROY(allocator, (Array*) self); return new_table; From b52a69a39a5ab2e5d6f68f5da8d2da7e028f0232 Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 18 Aug 2025 14:20:01 +0200 Subject: [PATCH 344/704] WIP: allele query? --- src/main.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 100 insertions(+), 2 deletions(-) diff --git a/src/main.c b/src/main.c index cd79d9b..a7d4a1e 100644 --- a/src/main.c +++ b/src/main.c @@ -858,6 +858,7 @@ compare(int argc, char* argv[static argc + 1]) int main(int argc, char* argv[static argc + 1]) { +/* struct IN_EX { HASH_TABLE_KEY; @@ -875,6 +876,7 @@ main(int argc, char* argv[static argc + 1]) table = HASH_TABLE_DESTROY(gva_std_allocator, table); return EXIT_SUCCESS; +*/ errno = 0; FILE* stream = fopen(argv[1], "r"); @@ -966,15 +968,111 @@ main(int argc, char* argv[static argc + 1]) } // for */ + /* gva_uint* results = interval_tree_intersection(gva_std_allocator, tree, 6000, 6250); - for (size_t i = 0; i < array_length(results); ++i) { fprintf(stderr, "[%u, %u)\n", tree.nodes[results[i]].start, tree.nodes[results[i]].end); } // for fprintf(stderr, "results: %zu\n", array_length(results)); + */ + + if (alleles == NULL || node_allele_join == NULL) + { + return -1; + } // if + + GVA_LCS_Graph rhs_graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, + 2, (GVA_Variant[]) {(GVA_Variant) {7869, 7870, {1, "T"}}, (GVA_Variant) {9199, 9200, {1, "C"}}}); + + struct { + gva_uint included; + gva_uint excluded; + }* result_map = gva_std_allocator.allocate(gva_std_allocator.context, NULL, 0, 1024 * sizeof(*result_map)); + if (result_map == NULL) + { + return -1; + } // if + memset(result_map, 0, 1024 * sizeof(*result_map)); + + for (size_t i = 0; i < array_length(rhs_graph.local_supremal) - 1; ++i) + { + GVA_Variant rhs; + gva_edges(rhs_graph.observed.str, + rhs_graph.local_supremal[i], rhs_graph.local_supremal[i + 1], + i == 0, i == array_length(rhs_graph.local_supremal) - 2, + &rhs); + + gva_uint rhs_dist = rhs_graph.local_supremal[i + 1].edges; + fprintf(stderr, GVA_VARIANT_FMT " %u\n", GVA_VARIANT_PRINT(rhs), rhs_graph.local_supremal[i + 1].edges); + + gva_uint* results = interval_tree_intersection(gva_std_allocator, tree, rhs.start, rhs.end); + for (size_t i = 0; i < array_length(results); ++i) { + GVA_Variant const lhs = {tree.nodes[results[i]].start, tree.nodes[results[i]].end, + trie_string(trie, tree.nodes[results[i]].inserted)}; + GVA_Relation relation = compare_from_index(reference, lhs, tree.nodes[results[i]].distance, rhs, rhs_dist); + + if (relation == GVA_EQUIVALENT || relation == GVA_CONTAINS) + { + for (gva_uint j = tree.nodes[results[i]].alleles; j != GVA_NULL; j = node_allele_join[j].next) + { + result_map[node_allele_join[j].allele].included += rhs_dist; + } // for + } // if + else if (relation == GVA_IS_CONTAINED) + { + for (gva_uint j = tree.nodes[results[i]].alleles; j != GVA_NULL; j = node_allele_join[j].next) + { + result_map[node_allele_join[j].allele].included += tree.nodes[results[i]].distance; + result_map[node_allele_join[j].allele].excluded += rhs_dist - tree.nodes[results[i]].distance; + } // for + } // if + else if (relation == GVA_OVERLAP) + { + for (gva_uint j = tree.nodes[results[i]].alleles; j != GVA_NULL; j = node_allele_join[j].next) + { + result_map[node_allele_join[j].allele].included += 1; + result_map[node_allele_join[j].allele].excluded += 1; + } // for + } // if + } // for + + results = ARRAY_DESTROY(gva_std_allocator, results); + } // for + + for (size_t i = 0; i < 1024; ++i) + { + if (result_map[i].included > 0 || result_map[i].excluded > 0) + { + result_map[i].excluded = rhs_graph.distance - result_map[i].included; + + GVA_Relation relation = GVA_OVERLAP; + if (result_map[i].excluded == 0) + { + if (result_map[i].included == alleles[i].distance) + { + relation = GVA_EQUIVALENT; + } // if + else + { + relation = GVA_CONTAINS; + } // else + } + else if (result_map[i].included == alleles[i].distance) + { + relation = GVA_IS_CONTAINED; + } // if + + fprintf(stderr, "%zu(%u): %u %u -> %s\n", + alleles[i].data, alleles[i].distance, + result_map[i].included, result_map[i].excluded, GVA_RELATION_LABELS[relation]); + } // if + } // for + result_map = gva_std_allocator.allocate(gva_std_allocator.context, result_map, 1024 * sizeof(*result_map), 0); + + gva_string_destroy(gva_std_allocator, rhs_graph.observed); + gva_lcs_graph_destroy(gva_std_allocator, rhs_graph); - results = ARRAY_DESTROY(gva_std_allocator, results); alleles = ARRAY_DESTROY(gva_std_allocator, alleles); node_allele_join = ARRAY_DESTROY(gva_std_allocator, node_allele_join); From 96fb986f814f7122196eadf6311a4016de907cf3 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 19 Aug 2025 16:06:15 +0200 Subject: [PATCH 345/704] Testing AVL and augmented interval tree --- src/interval_tree.c | 248 ++++++++++++++++++++++++-------------------- src/interval_tree.h | 12 ++- 2 files changed, 143 insertions(+), 117 deletions(-) diff --git a/src/interval_tree.c b/src/interval_tree.c index 45ad4f0..c1a45f8 100644 --- a/src/interval_tree.c +++ b/src/interval_tree.c @@ -1,5 +1,5 @@ #include // NULL -#include // uint64_t +#include // uint8_t #include "../include/allocator.h" // GVA_Allocator #include "../include/types.h" // GVA_NULL @@ -31,19 +31,51 @@ enum static inline gva_uint -calculate_max(Interval_Tree_Node const nodes[static 1], gva_uint const idx) +update_max(Interval_Tree const self[static 1], gva_uint const idx) { - gva_uint result = nodes[idx].end; - if (nodes[idx].child[LEFT] != GVA_NULL) + gva_uint result = self->nodes[idx].end; + if (self->nodes[idx].child[LEFT] != GVA_NULL) { - result = MAX(result, nodes[nodes[idx].child[LEFT]].max); + result = MAX(result, self->nodes[self->nodes[idx].child[LEFT]].max); } // if - if (nodes[idx].child[RIGHT] != GVA_NULL) + if (self->nodes[idx].child[RIGHT] != GVA_NULL) { - result = MAX(result, nodes[nodes[idx].child[RIGHT]].max); + result = MAX(result, self->nodes[self->nodes[idx].child[RIGHT]].max); } // if return result; -} // calculate_max +} // update_max + + +static int +interval_cmp(gva_uint const lhs_start, gva_uint const lhs_end, gva_uint const lhs_inserted, + gva_uint const rhs_start, gva_uint const rhs_end, gva_uint const rhs_inserted) +{ + if (lhs_start < rhs_start) + { + return LEFT; + } // if + if (rhs_start < lhs_start) + { + return RIGHT; + } // if + if (lhs_end < rhs_end) + { + return LEFT; + } // if + if (rhs_end < lhs_end) + { + return RIGHT; + } // if + if (lhs_inserted < rhs_inserted) + { + return LEFT; + } // if + if (rhs_inserted < lhs_inserted) + { + return RIGHT; + } // if + return -1; // identity +} // interval_cmp gva_uint @@ -55,156 +87,144 @@ interval_tree_insert(Interval_Tree self[static 1], gva_uint const idx) return idx; } // if - // limiting to height 64 allows for a minimum of - // 27,777,890,035,287 nodes - uint64_t path = 0; // bit-path to first unbalanced ancestor - int len = 0; // length of the path - int dir = LEFT; - - gva_uint tmp = self->root; - gva_uint tmp_par = self->root; // parent of tmp + gva_uint y = self->root; // Top node to update balance factor, + gva_uint z = self->root; // and parent. - gva_uint unbal = self->root; // first unbalanced ancestor of tmp - gva_uint unbal_par = self->root; // parent of unbalanced + uint8_t path[64]; // Cached comparison results. + int k = 0; // Number of cached results. + int dir = LEFT; // Direction to descend. - // Insert a new node at the BST position - while (tmp != GVA_NULL) + gva_uint p = y; // Iterator, + gva_uint q = z; // and parent. + while (p != GVA_NULL) { - self->nodes[tmp].max = MAX(self->nodes[tmp].max, self->nodes[idx].end); - - if (self->nodes[tmp].balance != 0) + dir = interval_cmp(self->nodes[idx].start, self->nodes[idx].end, self->nodes[idx].inserted, + self->nodes[p].start, self->nodes[p].end, self->nodes[p].inserted); + if (dir == -1) { - // this is now the first unbalanced ancestor of tmp - unbal_par = tmp_par; - unbal = tmp; - path = 0; - len = 0; + return p; // found } // if - dir = self->nodes[idx].start > self->nodes[tmp].start; - if (dir == RIGHT) - { - path |= (uint64_t) RIGHT << len; - } // if - len += 1; + self->nodes[p].max = MAX(self->nodes[p].max, self->nodes[idx].end); - // Disallow duplicates - if (self->nodes[tmp].start == self->nodes[idx].start && - self->nodes[tmp].end == self->nodes[idx].end && - self->nodes[tmp].inserted == self->nodes[idx].inserted) + if (self->nodes[p].balance != 0) { - return tmp; + z = q; + y = p; + k = 0; } // if - - tmp_par = tmp; - tmp = self->nodes[tmp].child[dir]; + path[k] = dir; + k += 1; + q = p; + p = self->nodes[p].child[dir]; } // while - self->nodes[tmp_par].child[dir] = idx; + // add + self->nodes[q].child[dir] = idx; - // Update the balance factors along the path from the first - // unbalanced ancestor to the new node - tmp = unbal; - while (tmp != idx) + // update balance factors + p = y; + k = 0; + while (p != idx) { - if ((path & RIGHT) == RIGHT) + if (path[k] == LEFT) { - self->nodes[tmp].balance += 1; + self->nodes[p].balance -= 1; } // if else { - self->nodes[tmp].balance -= 1; + self->nodes[p].balance += 1; } // else + p = self->nodes[p].child[path[k]]; + k += 1; + } // for - tmp = self->nodes[tmp].child[path & RIGHT]; - path >>= 1; - } // while - - // Do the rotations if necessary - gva_uint root = 0; - if (self->nodes[unbal].balance == -2) + // rotations + gva_uint w; // New root of rebalanced subtree. + if (self->nodes[y].balance == -2) { - gva_uint const child = self->nodes[unbal].child[LEFT]; - if (self->nodes[child].balance == -1) + gva_uint const x = self->nodes[y].child[LEFT]; + if (self->nodes[x].balance == -1) { - root = child; - self->nodes[unbal].child[LEFT] = self->nodes[child].child[RIGHT]; - self->nodes[child].child[RIGHT] = unbal; - self->nodes[child].balance = 0; - self->nodes[unbal].balance = 0; - self->nodes[child].max = calculate_max(self->nodes, child); - self->nodes[unbal].max = calculate_max(self->nodes, unbal); + w = x; + self->nodes[y].child[LEFT] = self->nodes[x].child[RIGHT]; + self->nodes[x].child[RIGHT] = y; + self->nodes[x].balance = 0; + self->nodes[y].balance = 0; + + self->nodes[x].max = update_max(self, x); + self->nodes[y].max = update_max(self, y); } // if else { - root = self->nodes[child].child[RIGHT]; - self->nodes[child].child[RIGHT] = self->nodes[root].child[LEFT]; - self->nodes[root].child[LEFT] = child; - self->nodes[unbal].child[LEFT] = self->nodes[root].child[RIGHT]; - self->nodes[root].child[RIGHT] = unbal; - if (self->nodes[root].balance == -1) + w = self->nodes[x].child[RIGHT]; + self->nodes[x].child[RIGHT] = self->nodes[w].child[LEFT]; + self->nodes[w].child[LEFT] = x; + self->nodes[y].child[LEFT] = self->nodes[w].child[RIGHT]; + self->nodes[w].child[RIGHT] = y; + if (self->nodes[w].balance == -1) { - self->nodes[child].balance = 0; - self->nodes[unbal].balance = 1; + self->nodes[x].balance = 0; + self->nodes[y].balance = +1; } // if - else if (self->nodes[root].balance == 0) + else if (self->nodes[w].balance == 0) { - self->nodes[child].balance = 0; - self->nodes[unbal].balance = 0; + self->nodes[x].balance = 0; + self->nodes[y].balance = 0; } // if else { - self->nodes[child].balance = -1; - self->nodes[unbal].balance = 0; + self->nodes[x].balance = -1; + self->nodes[y].balance = 0; } // else - self->nodes[root].balance = 0; + self->nodes[w].balance = 0; - self->nodes[root].max = calculate_max(self->nodes, root); - self->nodes[child].max = calculate_max(self->nodes, child); - self->nodes[unbal].max = calculate_max(self->nodes, unbal); + self->nodes[x].max = update_max(self, x); + self->nodes[y].max = update_max(self, y); + self->nodes[w].max = update_max(self, w); } // else } // if - else if (self->nodes[unbal].balance == 2) + else if (self->nodes[y].balance == +2) { - gva_uint const child = self->nodes[unbal].child[RIGHT]; - if (self->nodes[child].balance == 1) + gva_uint const x = self->nodes[y].child[RIGHT]; + if (self->nodes[x].balance == +1) { - root = child; - self->nodes[unbal].child[RIGHT] = self->nodes[child].child[LEFT]; - self->nodes[child].child[LEFT] = unbal; - self->nodes[child].balance = 0; - self->nodes[unbal].balance = 0; - - self->nodes[child].max = calculate_max(self->nodes, child); - self->nodes[unbal].max = calculate_max(self->nodes, unbal); + w = x; + self->nodes[y].child[RIGHT] = self->nodes[x].child[LEFT]; + self->nodes[x].child[LEFT] = y; + self->nodes[x].balance = 0; + self->nodes[y].balance = 0; + + self->nodes[x].max = update_max(self, x); + self->nodes[y].max = update_max(self, y); } // if else { - root = self->nodes[child].child[LEFT]; - self->nodes[child].child[LEFT] = self->nodes[root].child[RIGHT]; - self->nodes[root].child[RIGHT] = child; - self->nodes[unbal].child[RIGHT] = self->nodes[root].child[LEFT]; - self->nodes[root].child[LEFT] = unbal; - if (self->nodes[root].balance == 1) + w = self->nodes[x].child[LEFT]; + self->nodes[x].child[LEFT] = self->nodes[w].child[RIGHT]; + self->nodes[w].child[RIGHT] = x; + self->nodes[y].child[RIGHT] = self->nodes[w].child[LEFT]; + self->nodes[w].child[LEFT] = y; + if (self->nodes[w].balance == +1) { - self->nodes[child].balance = 0; - self->nodes[unbal].balance = -1; + self->nodes[x].balance = 0; + self->nodes[y].balance = -1; } // if - else if(self->nodes[root].balance == 0) + else if (self->nodes[w].balance == 0) { - self->nodes[child].balance = 0; - self->nodes[unbal].balance = 0; + self->nodes[x].balance = 0; + self->nodes[y].balance = 0; } // if else { - self->nodes[child].balance = 1; - self->nodes[unbal].balance = 0; + self->nodes[x].balance = +1; + self->nodes[y].balance = 0; } // else - self->nodes[root].balance = 0; + self->nodes[w].balance = 0; - self->nodes[root].max = calculate_max(self->nodes, root); - self->nodes[child].max = calculate_max(self->nodes, child); - self->nodes[unbal].max = calculate_max(self->nodes, unbal); + self->nodes[x].max = update_max(self, x); + self->nodes[y].max = update_max(self, y); + self->nodes[w].max = update_max(self, w); } // else } // if else @@ -212,13 +232,13 @@ interval_tree_insert(Interval_Tree self[static 1], gva_uint const idx) return idx; } // else - if (self->root == unbal) + if (self->root == y) { - self->root = root; + self->root = w; return idx; } // if - self->nodes[unbal_par].child[unbal != self->nodes[unbal_par].child[LEFT]] = root; + self->nodes[z].child[y != self->nodes[z].child[LEFT]] = w; return idx; } // interval_tree_insert diff --git a/src/interval_tree.h b/src/interval_tree.h index 2411ba6..0b6a1f8 100644 --- a/src/interval_tree.h +++ b/src/interval_tree.h @@ -2,19 +2,25 @@ #define GVA_INTERVAL_TREE_H +#include // CHAR_BIT +#include // int8_t + #include "../include/allocator.h" // GVA_Allocator #include "../include/types.h" // gva_uint +// [-4, ..., 3], we use [-2, ..., 2] +#define BALANCE_BITS 3 + + typedef struct { gva_uint child[2]; gva_uint start; gva_uint end; gva_uint max; - // FIXME: we assume gva_uint is 32bits - gva_uint balance : 3; - gva_uint inserted : 29; + int8_t balance : BALANCE_BITS; + gva_uint inserted : sizeof(gva_uint) * CHAR_BIT - BALANCE_BITS; gva_uint alleles; gva_uint distance; } Interval_Tree_Node; From 9c2c44f2a795b6cb890a951a91918a4f6543f858 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Wed, 20 Aug 2025 02:04:36 +0200 Subject: [PATCH 346/704] Iterate on endpoint selection. Satisfies PV all2all. --- src/interval_tree.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/interval_tree.c b/src/interval_tree.c index c1a45f8..3306927 100644 --- a/src/interval_tree.c +++ b/src/interval_tree.c @@ -261,7 +261,7 @@ intersect(GVA_Allocator const allocator, Interval_Tree_Node const nodes[static 1 results = intersect(allocator, nodes, nodes[idx].child[LEFT], start, end, results); // FIXME: endpoints? - if (start < nodes[idx].end && end >= nodes[idx].start) + if (start < nodes[idx].end + 1) // && end >= nodes[idx].start) { ARRAY_APPEND(allocator, results, idx); } // if From daf7be279832af9f5dcf5f03b72e428ad78f9362 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Wed, 20 Aug 2025 02:07:06 +0200 Subject: [PATCH 347/704] Query batch of alleles to allele index. --- src/main.c | 187 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 116 insertions(+), 71 deletions(-) diff --git a/src/main.c b/src/main.c index a7d4a1e..57c00af 100644 --- a/src/main.c +++ b/src/main.c @@ -982,97 +982,142 @@ main(int argc, char* argv[static argc + 1]) return -1; } // if - GVA_LCS_Graph rhs_graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, - 2, (GVA_Variant[]) {(GVA_Variant) {7869, 7870, {1, "T"}}, (GVA_Variant) {9199, 9200, {1, "C"}}}); - - struct { - gva_uint included; - gva_uint excluded; - }* result_map = gva_std_allocator.allocate(gva_std_allocator.context, NULL, 0, 1024 * sizeof(*result_map)); - if (result_map == NULL) + errno = 0; + stream = fopen(argv[2], "r"); + if (stream == NULL) { - return -1; + fprintf(stderr, "error: %s\n", strerror(errno)); + return EXIT_FAILURE; } // if - memset(result_map, 0, 1024 * sizeof(*result_map)); - for (size_t i = 0; i < array_length(rhs_graph.local_supremal) - 1; ++i) + while (fgets(line, sizeof(line), stream) != NULL) { - GVA_Variant rhs; - gva_edges(rhs_graph.observed.str, - rhs_graph.local_supremal[i], rhs_graph.local_supremal[i + 1], - i == 0, i == array_length(rhs_graph.local_supremal) - 2, - &rhs); + size_t idx = 0; + size_t const id = parse_number(line, &idx); + idx += 1; // skip space or tab + int const len = (char*) memchr(line + idx, '\n', LINE_SIZE - idx) - (line + idx); + GVA_Variant sup; + if (gva_parse_spdi(len, line + idx, &sup) == 0) + { + fprintf(stderr, "error: SPDI parsing failed at line %zu: %s", count + 1, line); + continue; + } // if - gva_uint rhs_dist = rhs_graph.local_supremal[i + 1].edges; - fprintf(stderr, GVA_VARIANT_FMT " %u\n", GVA_VARIANT_PRINT(rhs), rhs_graph.local_supremal[i + 1].edges); + // fprintf(stderr, "%zu %u %u %s\n", id, sup.start, sup.end, sup.sequence.str); - gva_uint* results = interval_tree_intersection(gva_std_allocator, tree, rhs.start, rhs.end); - for (size_t i = 0; i < array_length(results); ++i) { - GVA_Variant const lhs = {tree.nodes[results[i]].start, tree.nodes[results[i]].end, - trie_string(trie, tree.nodes[results[i]].inserted)}; - GVA_Relation relation = compare_from_index(reference, lhs, tree.nodes[results[i]].distance, rhs, rhs_dist); + // fprintf(stderr, GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(sup)); - if (relation == GVA_EQUIVALENT || relation == GVA_CONTAINS) - { - for (gva_uint j = tree.nodes[results[i]].alleles; j != GVA_NULL; j = node_allele_join[j].next) + struct { + gva_uint included; + gva_uint excluded; + }* result_map = gva_std_allocator.allocate(gva_std_allocator.context, NULL, 0, 1024 * sizeof(*result_map)); + if (result_map == NULL) + { + return -1; + } // if + memset(result_map, 0, 1024 * sizeof(*result_map)); + + GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &sup); + for (size_t i = 0; i < array_length(graph.local_supremal) - 1; ++i) { + GVA_Variant part; + gva_edges(graph.observed.str, + graph.local_supremal[i], graph.local_supremal[i + 1], + i == 0, i == array_length(graph.local_supremal) - 2, + &part); + + gva_uint dist = graph.local_supremal[i + 1].edges; + // fprintf(stderr, "part: " GVA_VARIANT_FMT " %u\n", GVA_VARIANT_PRINT(part), graph.local_supremal[i + 1].edges); + + gva_uint* results = interval_tree_intersection(gva_std_allocator, tree, part.start, part.end); + for (size_t i = 0; i < array_length(results); ++i) { + // fprintf(stderr, "result loop: %zu %zu %u\n", id, i, results[i]); + GVA_Variant const lhs = {tree.nodes[results[i]].start, tree.nodes[results[i]].end, + trie_string(trie, tree.nodes[results[i]].inserted)}; + GVA_Relation relation = compare_from_index(reference, lhs, tree.nodes[results[i]].distance, part, dist); + + if (relation == GVA_EQUIVALENT || relation == GVA_CONTAINS) { - result_map[node_allele_join[j].allele].included += rhs_dist; - } // for - } // if - else if (relation == GVA_IS_CONTAINED) - { - for (gva_uint j = tree.nodes[results[i]].alleles; j != GVA_NULL; j = node_allele_join[j].next) + for (gva_uint j = tree.nodes[results[i]].alleles; j != GVA_NULL; j = node_allele_join[j].next) + { + // fprintf(stderr, "%u %u %zu\n", j, node_allele_join[j].allele, alleles[node_allele_join[j].allele].data); + // if (alleles[node_allele_join[j].allele].data == 231) + { + // fprintf(stderr, "equiv/contains dist: %u\n", dist); + result_map[node_allele_join[j].allele].included += dist; + // fprintf(stderr, "included: %u\n", result_map[node_allele_join[j].allele].included); + } + } // for + } // if + else if (relation == GVA_IS_CONTAINED) { - result_map[node_allele_join[j].allele].included += tree.nodes[results[i]].distance; - result_map[node_allele_join[j].allele].excluded += rhs_dist - tree.nodes[results[i]].distance; - } // for - } // if - else if (relation == GVA_OVERLAP) - { - for (gva_uint j = tree.nodes[results[i]].alleles; j != GVA_NULL; j = node_allele_join[j].next) + for (gva_uint j = tree.nodes[results[i]].alleles; j != GVA_NULL; j = node_allele_join[j].next) + { + // if (alleles[node_allele_join[j].allele].data == 231) + { + // fprintf(stderr, "is_contained\n"); + result_map[node_allele_join[j].allele].included += tree.nodes[results[i]].distance; + result_map[node_allele_join[j].allele].excluded += dist - tree.nodes[results[i]].distance; + } + } // for + } // if + else if (relation == GVA_OVERLAP) { - result_map[node_allele_join[j].allele].included += 1; - result_map[node_allele_join[j].allele].excluded += 1; - } // for - } // if + for (gva_uint j = tree.nodes[results[i]].alleles; j != GVA_NULL; j = node_allele_join[j].next) + { + // if (alleles[node_allele_join[j].allele].data == 231) + { + // fprintf(stderr, "overlap\n"); + result_map[node_allele_join[j].allele].included += 1; + result_map[node_allele_join[j].allele].excluded += 1; + } + } // for + } // if + } // for + + results = ARRAY_DESTROY(gva_std_allocator, results); } // for - results = ARRAY_DESTROY(gva_std_allocator, results); - } // for + gva_string_destroy(gva_std_allocator, graph.observed); + gva_lcs_graph_destroy(gva_std_allocator, graph); - for (size_t i = 0; i < 1024; ++i) - { - if (result_map[i].included > 0 || result_map[i].excluded > 0) + for (size_t i = 0; i < 1024; ++i) { - result_map[i].excluded = rhs_graph.distance - result_map[i].included; - - GVA_Relation relation = GVA_OVERLAP; - if (result_map[i].excluded == 0) + if (result_map[i].included > 0 || result_map[i].excluded > 0) { - if (result_map[i].included == alleles[i].distance) + result_map[i].excluded = graph.distance - result_map[i].included; + // fprintf(stderr, "%zu graph dist: %u included: %u excluded: %u\n", i, graph.distance, result_map[i].included, result_map[i].excluded); + + GVA_Relation relation = GVA_OVERLAP; + if (result_map[i].excluded == 0) { - relation = GVA_EQUIVALENT; + if (result_map[i].included == alleles[i].distance) + { + relation = GVA_EQUIVALENT; + } // if + else + { + relation = GVA_CONTAINS; + } // else + } + else if (result_map[i].included == alleles[i].distance) + { + relation = GVA_IS_CONTAINED; } // if - else + + // fprintf(stderr, "%zu(%u): %u %u -> %s\n", + // alleles[i].data, alleles[i].distance, + // result_map[i].included, result_map[i].excluded, GVA_RELATION_LABELS[relation]); + // if (alleles[i].data == 231) + if (alleles[i].data < id) { - relation = GVA_CONTAINS; - } // else - } - else if (result_map[i].included == alleles[i].distance) - { - relation = GVA_IS_CONTAINED; + fprintf(stdout, "%zu %zu %s\n", alleles[i].data, id, GVA_RELATION_LABELS[relation]); + } } // if + } // for + result_map = gva_std_allocator.allocate(gva_std_allocator.context, result_map, 1024 * sizeof(*result_map), 0); - fprintf(stderr, "%zu(%u): %u %u -> %s\n", - alleles[i].data, alleles[i].distance, - result_map[i].included, result_map[i].excluded, GVA_RELATION_LABELS[relation]); - } // if - } // for - result_map = gva_std_allocator.allocate(gva_std_allocator.context, result_map, 1024 * sizeof(*result_map), 0); - - gva_string_destroy(gva_std_allocator, rhs_graph.observed); - gva_lcs_graph_destroy(gva_std_allocator, rhs_graph); - + } + fclose(stream); alleles = ARRAY_DESTROY(gva_std_allocator, alleles); node_allele_join = ARRAY_DESTROY(gva_std_allocator, node_allele_join); From de06b64c2b4d3d9cca2be8ad866b2ed1db265d4c Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Wed, 20 Aug 2025 12:00:15 +0200 Subject: [PATCH 348/704] Streamline intersection logic. --- src/interval_tree.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/interval_tree.c b/src/interval_tree.c index 3306927..da73e36 100644 --- a/src/interval_tree.c +++ b/src/interval_tree.c @@ -248,20 +248,19 @@ static gva_uint* intersect(GVA_Allocator const allocator, Interval_Tree_Node const nodes[static 1], gva_uint const idx, gva_uint const start, gva_uint const end, gva_uint* results) { - if (idx == GVA_NULL || nodes[idx].max < start) + if (idx == GVA_NULL || start > nodes[idx].max) { return results; } // if - if (nodes[idx].start > end) + results = intersect(allocator, nodes, nodes[idx].child[LEFT], start, end, results); + + if (end < nodes[idx].start) { - return intersect(allocator, nodes, nodes[idx].child[LEFT], start, end, results); + return results; } // if - results = intersect(allocator, nodes, nodes[idx].child[LEFT], start, end, results); - - // FIXME: endpoints? - if (start < nodes[idx].end + 1) // && end >= nodes[idx].start) + if (start <= nodes[idx].end) // already satisfied above: && end >= nodes[idx].start) { ARRAY_APPEND(allocator, results, idx); } // if From 83971112b6181c21a715d32547074c5605bc5d72 Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 20 Aug 2025 12:11:32 +0200 Subject: [PATCH 349/704] Attribution --- src/interval_tree.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/interval_tree.c b/src/interval_tree.c index c1a45f8..1a5fa18 100644 --- a/src/interval_tree.c +++ b/src/interval_tree.c @@ -78,6 +78,8 @@ interval_cmp(gva_uint const lhs_start, gva_uint const lhs_end, gva_uint const lh } // interval_cmp +// Adapted from: +// http://adtinfo.org/libavl.html/Inserting-into-an-AVL-Tree.html gva_uint interval_tree_insert(Interval_Tree self[static 1], gva_uint const idx) { From 51d55b0b79dedde4a0b23491c4a27c4ba3b76c5d Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Wed, 20 Aug 2025 21:41:58 +0200 Subject: [PATCH 350/704] Cleanup. --- src/main.c | 66 +++++++++--------------------------------------------- 1 file changed, 10 insertions(+), 56 deletions(-) diff --git a/src/main.c b/src/main.c index 57c00af..31a8355 100644 --- a/src/main.c +++ b/src/main.c @@ -954,28 +954,6 @@ main(int argc, char* argv[static argc + 1]) fprintf(stderr, "#alleles: %zu\n", array_length(alleles)); fprintf(stderr, "#join: %zu\n", array_length(node_allele_join)); - //interval_tree_dot(stdout, tree); - /* - for (size_t i = 0; i < array_length(alleles); ++i) - { - gva_uint const end = i < array_length(alleles) - 1 ? alleles[i + 1].start : array_length(node_allele_join); - fprintf(stderr, "Allele[%zu]: {%zu, [%u, %u), %u}\n", i, alleles[i].data, alleles[i].start, end, alleles[i].distance); - } // for - - for (size_t i = 0; i < array_length(node_allele_join); ++i) - { - fprintf(stderr, "%zu: {%u, %u, %d}\n", i, node_allele_join[i].node, node_allele_join[i].allele, node_allele_join[i].next); - } // for - */ - - /* - gva_uint* results = interval_tree_intersection(gva_std_allocator, tree, 6000, 6250); - for (size_t i = 0; i < array_length(results); ++i) - { - fprintf(stderr, "[%u, %u)\n", tree.nodes[results[i]].start, tree.nodes[results[i]].end); - } // for - fprintf(stderr, "results: %zu\n", array_length(results)); - */ if (alleles == NULL || node_allele_join == NULL) { @@ -1003,10 +981,6 @@ main(int argc, char* argv[static argc + 1]) continue; } // if - // fprintf(stderr, "%zu %u %u %s\n", id, sup.start, sup.end, sup.sequence.str); - - // fprintf(stderr, GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(sup)); - struct { gva_uint included; gva_uint excluded; @@ -1018,7 +992,8 @@ main(int argc, char* argv[static argc + 1]) memset(result_map, 0, 1024 * sizeof(*result_map)); GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &sup); - for (size_t i = 0; i < array_length(graph.local_supremal) - 1; ++i) { + for (size_t i = 0; i < array_length(graph.local_supremal) - 1; ++i) + { GVA_Variant part; gva_edges(graph.observed.str, graph.local_supremal[i], graph.local_supremal[i + 1], @@ -1026,11 +1001,9 @@ main(int argc, char* argv[static argc + 1]) &part); gva_uint dist = graph.local_supremal[i + 1].edges; - // fprintf(stderr, "part: " GVA_VARIANT_FMT " %u\n", GVA_VARIANT_PRINT(part), graph.local_supremal[i + 1].edges); gva_uint* results = interval_tree_intersection(gva_std_allocator, tree, part.start, part.end); for (size_t i = 0; i < array_length(results); ++i) { - // fprintf(stderr, "result loop: %zu %zu %u\n", id, i, results[i]); GVA_Variant const lhs = {tree.nodes[results[i]].start, tree.nodes[results[i]].end, trie_string(trie, tree.nodes[results[i]].inserted)}; GVA_Relation relation = compare_from_index(reference, lhs, tree.nodes[results[i]].distance, part, dist); @@ -1039,37 +1012,23 @@ main(int argc, char* argv[static argc + 1]) { for (gva_uint j = tree.nodes[results[i]].alleles; j != GVA_NULL; j = node_allele_join[j].next) { - // fprintf(stderr, "%u %u %zu\n", j, node_allele_join[j].allele, alleles[node_allele_join[j].allele].data); - // if (alleles[node_allele_join[j].allele].data == 231) - { - // fprintf(stderr, "equiv/contains dist: %u\n", dist); - result_map[node_allele_join[j].allele].included += dist; - // fprintf(stderr, "included: %u\n", result_map[node_allele_join[j].allele].included); - } + result_map[node_allele_join[j].allele].included += dist; } // for } // if else if (relation == GVA_IS_CONTAINED) { for (gva_uint j = tree.nodes[results[i]].alleles; j != GVA_NULL; j = node_allele_join[j].next) { - // if (alleles[node_allele_join[j].allele].data == 231) - { - // fprintf(stderr, "is_contained\n"); - result_map[node_allele_join[j].allele].included += tree.nodes[results[i]].distance; - result_map[node_allele_join[j].allele].excluded += dist - tree.nodes[results[i]].distance; - } + result_map[node_allele_join[j].allele].included += tree.nodes[results[i]].distance; + result_map[node_allele_join[j].allele].excluded += dist - tree.nodes[results[i]].distance; } // for } // if else if (relation == GVA_OVERLAP) { for (gva_uint j = tree.nodes[results[i]].alleles; j != GVA_NULL; j = node_allele_join[j].next) { - // if (alleles[node_allele_join[j].allele].data == 231) - { - // fprintf(stderr, "overlap\n"); - result_map[node_allele_join[j].allele].included += 1; - result_map[node_allele_join[j].allele].excluded += 1; - } + result_map[node_allele_join[j].allele].included += 1; + result_map[node_allele_join[j].allele].excluded += 1; } // for } // if } // for @@ -1085,7 +1044,6 @@ main(int argc, char* argv[static argc + 1]) if (result_map[i].included > 0 || result_map[i].excluded > 0) { result_map[i].excluded = graph.distance - result_map[i].included; - // fprintf(stderr, "%zu graph dist: %u included: %u excluded: %u\n", i, graph.distance, result_map[i].included, result_map[i].excluded); GVA_Relation relation = GVA_OVERLAP; if (result_map[i].excluded == 0) @@ -1098,25 +1056,21 @@ main(int argc, char* argv[static argc + 1]) { relation = GVA_CONTAINS; } // else - } + } // if else if (result_map[i].included == alleles[i].distance) { relation = GVA_IS_CONTAINED; } // if - // fprintf(stderr, "%zu(%u): %u %u -> %s\n", - // alleles[i].data, alleles[i].distance, - // result_map[i].included, result_map[i].excluded, GVA_RELATION_LABELS[relation]); - // if (alleles[i].data == 231) if (alleles[i].data < id) { fprintf(stdout, "%zu %zu %s\n", alleles[i].data, id, GVA_RELATION_LABELS[relation]); - } + } // if } // if } // for result_map = gva_std_allocator.allocate(gva_std_allocator.context, result_map, 1024 * sizeof(*result_map), 0); - } + } // while fclose(stream); alleles = ARRAY_DESTROY(gva_std_allocator, alleles); From 41439a0937dacf1004c82bad18582682496d60ce Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 27 Aug 2025 17:05:31 +0200 Subject: [PATCH 351/704] WIP: inserted sequences are now owned by the Python objects --- python/algebra_extmodule.c | 19 ++++++++++++++----- python/tests/test_variant.py | 7 +++++++ 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/python/algebra_extmodule.c b/python/algebra_extmodule.c index 7b6394f..0e4ef81 100644 --- a/python/algebra_extmodule.c +++ b/python/algebra_extmodule.c @@ -3,6 +3,7 @@ #include // bool #include // NULL, offsetof, size_t +#include // memcpy #include "../include/compare.h" // gva_compare_graphs #include "../include/extractor.h" // gva_canonical @@ -26,10 +27,10 @@ typedef struct LCSgraph_Object typedef struct Variant_Object { PyObject_VAR_HEAD - Py_ssize_t start; - Py_ssize_t end; - Py_ssize_t len; - char const* sequence; + Py_ssize_t start; + Py_ssize_t end; + Py_ssize_t len; + char* sequence; } Variant_Object; @@ -262,10 +263,17 @@ Variant_new(PyTypeObject* subtype, PyObject* args, PyObject* kwargs) return NULL; } // if + self->sequence = PyMem_Malloc(len + 1); + if (self->sequence == NULL) + { + return PyErr_NoMemory(); + } // if + self->start = start; self->end = end; self->len = len; - self->sequence = sequence; + memcpy(self->sequence, sequence, len); + self->sequence[len] = '\0'; return (PyObject*) self; } // Variant_new @@ -273,6 +281,7 @@ Variant_new(PyTypeObject* subtype, PyObject* args, PyObject* kwargs) static inline void Variant_dealloc(Variant_Object* self) { + PyMem_Free(self->sequence); Py_TYPE(self)->tp_free((PyObject*) self); } // Variant_dealloc diff --git a/python/tests/test_variant.py b/python/tests/test_variant.py index 9deda69..6f466bf 100644 --- a/python/tests/test_variant.py +++ b/python/tests/test_variant.py @@ -59,3 +59,10 @@ def test_variant_compare(): assert Variant(0, 0, "") != Variant(0, 1, "") assert Variant(0, 0, "") != Variant(1, 0, "") assert Variant(0, 0, "") != Variant(0, 0, "A") + + +def test_variant_from_slice(): + reference = "GTTCGCGGGGAAAGGAAAAAAGCCGCCGGGCAGGAAA" + variants = [Variant(1, 5, reference[7:34])] + del reference + assert variants == [Variant(1, 5, "GGGAAAGGAAAAAAGCCGCCGGGCAGG")] From 7c2bd8e8feccccdf67cb7da8c71929d5e8489af9 Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 27 Aug 2025 17:07:37 +0200 Subject: [PATCH 352/704] DECREF on failure --- python/algebra_extmodule.c | 1 + 1 file changed, 1 insertion(+) diff --git a/python/algebra_extmodule.c b/python/algebra_extmodule.c index 0e4ef81..7e7eee0 100644 --- a/python/algebra_extmodule.c +++ b/python/algebra_extmodule.c @@ -266,6 +266,7 @@ Variant_new(PyTypeObject* subtype, PyObject* args, PyObject* kwargs) self->sequence = PyMem_Malloc(len + 1); if (self->sequence == NULL) { + Py_DECREF(self); return PyErr_NoMemory(); } // if From 6fe7a17cf1b5edf47fd003c2bd4da329ad8fb291 Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 27 Aug 2025 21:58:22 +0200 Subject: [PATCH 353/704] LCSgraph Edge Iterator --- python/algebra_extmodule.c | 211 ++++++++++++++++++++++++++++----- python/tests/test_lcs_graph.py | 14 +++ 2 files changed, 198 insertions(+), 27 deletions(-) diff --git a/python/algebra_extmodule.c b/python/algebra_extmodule.c index 7e7eee0..4bda9e0 100644 --- a/python/algebra_extmodule.c +++ b/python/algebra_extmodule.c @@ -7,9 +7,10 @@ #include "../include/compare.h" // gva_compare_graphs #include "../include/extractor.h" // gva_canonical -#include "../include/lcs_graph.h" // GVA_LCS_Graph, gva_lcs_graph_*, gva_edges +#include "../include/lcs_graph.h" // GVA_LCS_Graph, GVA_Node, gva_lcs_graph_*, gva_edges #include "../include/std_alloc.h" // gva_std_allocator #include "../include/string.h" // gva_string_destroy +#include "../include/types.h" // GVA_NULL, gva_uint #include "../include/variant.h" // GVA_VARIANT_*, GVA_Variant, gva_variant_* #include "../src/array.h" // ARRAY_DESTROY, array_length @@ -17,14 +18,23 @@ // DEBUG: PySys_FormatStderr -typedef struct LCSgraph_Object +typedef struct { PyObject_VAR_HEAD GVA_LCS_Graph graph; } LCSgraph_Object; -typedef struct Variant_Object +typedef struct +{ + PyObject_VAR_HEAD + size_t node; + gva_uint edge; + LCSgraph_Object* graph; +} LCSgraph_Edge_Iterator; + + +typedef struct { PyObject_VAR_HEAD Py_ssize_t start; @@ -37,8 +47,9 @@ typedef struct Variant_Object typedef struct { PyTypeObject* LCSgraph_Type; + PyTypeObject* LCSgraph_Edge_Iterator_Type; PyTypeObject* Variant_Type; - PyObject* Relations; + PyObject* Relations; } algebra_ext_state; @@ -69,7 +80,7 @@ LCSgraph_dealloc(LCSgraph_Object* self) static PyObject* LCSgraph_from_variants(PyObject* cls, PyObject* args, PyObject* kwargs) { - algebra_ext_state* state = get_algebra_ext_state(PyType_GetModule((PyTypeObject*) cls)); + algebra_ext_state* const state = get_algebra_ext_state(PyType_GetModule((PyTypeObject*) cls)); if (state == NULL) { return NULL; @@ -103,7 +114,7 @@ LCSgraph_from_variants(PyObject* cls, PyObject* args, PyObject* kwargs) variants[i] = (GVA_Variant) {item->start, item->end, {item->len, item->sequence}}; } // for - LCSgraph_Object* self = (LCSgraph_Object*) PyObject_CallNoArgs(cls); + LCSgraph_Object* const self = (LCSgraph_Object*) PyObject_CallNoArgs(cls); if (self == NULL) { variants = gva_std_allocator.allocate(gva_std_allocator.context, variants, n * sizeof(*variants), 0); @@ -120,7 +131,7 @@ LCSgraph_from_variants(PyObject* cls, PyObject* args, PyObject* kwargs) static PyObject* LCSgraph_canonical(LCSgraph_Object* self) { - algebra_ext_state* state = get_algebra_ext_state(PyType_GetModule(Py_TYPE(self))); + algebra_ext_state* const state = get_algebra_ext_state(PyType_GetModule(Py_TYPE(self))); if (state == NULL) { return NULL; @@ -128,7 +139,7 @@ LCSgraph_canonical(LCSgraph_Object* self) GVA_Variant* variants = gva_canonical(gva_std_allocator, self->graph); - PyObject* result = PyList_New(array_length(variants)); + PyObject* const result = PyList_New(array_length(variants)); if (result == NULL) { variants = ARRAY_DESTROY(gva_std_allocator, variants); @@ -137,14 +148,14 @@ LCSgraph_canonical(LCSgraph_Object* self) for (size_t i = 0; i < array_length(variants); ++i) { - PyObject* str = PyUnicode_FromStringAndSize(variants[i].sequence.str, variants[i].sequence.len); + PyObject* const str = PyUnicode_FromStringAndSize(variants[i].sequence.str, variants[i].sequence.len); if (str == NULL) { Py_DECREF(result); variants = ARRAY_DESTROY(gva_std_allocator, variants); return NULL; } // if - PyObject* args = Py_BuildValue("nnO", variants[i].start, variants[i].end, str); + PyObject* const args = Py_BuildValue("nnO", variants[i].start, variants[i].end, str); if (args == NULL) { Py_DECREF(str); @@ -152,7 +163,7 @@ LCSgraph_canonical(LCSgraph_Object* self) variants = ARRAY_DESTROY(gva_std_allocator, variants); return NULL; } // if - PyObject* item = PyObject_CallObject((PyObject*) state->Variant_Type, args); + PyObject* const item = PyObject_CallObject((PyObject*) state->Variant_Type, args); Py_DECREF(args); if (item == NULL) { @@ -171,13 +182,13 @@ LCSgraph_canonical(LCSgraph_Object* self) static PyObject* LCSgraph_local_supremal(LCSgraph_Object* self) { - algebra_ext_state* state = get_algebra_ext_state(PyType_GetModule(Py_TYPE(self))); + algebra_ext_state* const state = get_algebra_ext_state(PyType_GetModule(Py_TYPE(self))); if (state == NULL) { return NULL; } // if - PyObject* result = PyList_New(array_length(self->graph.local_supremal) - 1); + PyObject* const result = PyList_New(array_length(self->graph.local_supremal) - 1); if (result == NULL) { return NULL; @@ -191,20 +202,20 @@ LCSgraph_local_supremal(LCSgraph_Object* self) i == 0, i == array_length(self->graph.local_supremal) - 2, &variant); - PyObject* str = PyUnicode_FromStringAndSize(variant.sequence.str, variant.sequence.len); + PyObject* const str = PyUnicode_FromStringAndSize(variant.sequence.str, variant.sequence.len); if (str == NULL) { Py_DECREF(result); return NULL; } // if - PyObject* args = Py_BuildValue("nnO", variant.start, variant.end, str); + PyObject* const args = Py_BuildValue("nnO", variant.start, variant.end, str); if (args == NULL) { Py_DECREF(str); Py_DECREF(result); return NULL; } // if - PyObject* item = PyObject_CallObject((PyObject*) state->Variant_Type, args); + PyObject* const item = PyObject_CallObject((PyObject*) state->Variant_Type, args); Py_DECREF(args); if (item == NULL) { @@ -220,29 +231,138 @@ LCSgraph_local_supremal(LCSgraph_Object* self) static PyObject* LCSgraph_supremal(LCSgraph_Object* self) { - algebra_ext_state* state = get_algebra_ext_state(PyType_GetModule(Py_TYPE(self))); + algebra_ext_state* const state = get_algebra_ext_state(PyType_GetModule(Py_TYPE(self))); if (state == NULL) { return NULL; } // if - PyObject* str = PyUnicode_FromStringAndSize(self->graph.supremal.sequence.str, self->graph.supremal.sequence.len); + PyObject* const str = PyUnicode_FromStringAndSize(self->graph.supremal.sequence.str, self->graph.supremal.sequence.len); if (str == NULL) { return NULL; } // if - PyObject* args = Py_BuildValue("nnO", self->graph.supremal.start, self->graph.supremal.end, str); + PyObject* const args = Py_BuildValue("nnO", self->graph.supremal.start, self->graph.supremal.end, str); if (args == NULL) { Py_DECREF(str); return NULL; } // if - PyObject* result = PyObject_CallObject((PyObject*) state->Variant_Type, args); + PyObject* const result = PyObject_CallObject((PyObject*) state->Variant_Type, args); Py_DECREF(args); return result; } // LCSgraph_supremal +static PyObject* +LCSgraph_edges(LCSgraph_Object* self) +{ + algebra_ext_state* const state = get_algebra_ext_state(PyType_GetModule(Py_TYPE(self))); + if (state == NULL) + { + return NULL; + } // if + return PyObject_CallOneArg((PyObject*) state->LCSgraph_Edge_Iterator_Type, (PyObject*) self); +} // LCSgraph_edges + + +static PyObject* +LCSgraph_Edge_Iterator_new(PyTypeObject* subtype, PyObject* args, PyObject* kwargs) +{ + algebra_ext_state* const state = get_algebra_ext_state(PyType_GetModule(subtype)); + if (state == NULL) + { + return NULL; + } // if + + LCSgraph_Object* graph = NULL; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!|:LCSgraph_Edge_Iterator", + (char*[]) {"LCSgraph", NULL}, + state->LCSgraph_Type, &graph)) + { + return NULL; + } // if + + LCSgraph_Edge_Iterator* const self = (LCSgraph_Edge_Iterator*) subtype->tp_alloc(subtype, 0); + if (self == NULL) + { + return NULL; + } // if + + Py_INCREF(graph); + self->graph = graph; + self->node = 0; + self->edge = graph->graph.nodes[self->node].edges; + return (PyObject*) self; +} // LCSgraph_Edge_Iterator_new + + +inline static void +LCSgraph_Edge_Iterator_dealloc(LCSgraph_Edge_Iterator* self) +{ + Py_XDECREF(self->graph); + Py_TYPE(self)->tp_free((PyObject*) self); +} // LCSgraph_Edge_Iterator_dealloc + + +static PyObject* +LCSgraph_Edge_Iterator_next(LCSgraph_Edge_Iterator* self) +{ + if (self->edge == GVA_NULL) + { + self->node += 1; + if (self->node >= array_length(self->graph->graph.nodes)) + { + Py_CLEAR(self->graph); + return NULL; + } // if + self->edge = self->graph->graph.nodes[self->node].edges; + } // if + + algebra_ext_state* const state = get_algebra_ext_state(PyType_GetModule(Py_TYPE(self))); + if (state == NULL) + { + return NULL; + } // if + + GVA_Node const head = self->graph->graph.nodes[self->node]; + GVA_Node const tail = self->graph->graph.nodes[self->graph->graph.edges[self->edge].tail]; + GVA_Variant variant; + gva_uint const count = gva_edges(self->graph->graph.observed.str, + head, tail, + self->node == self->graph->graph.source, self->graph->graph.nodes[self->graph->graph.edges[self->edge].tail].edges == GVA_NULL, + &variant); + + self->edge = self->graph->graph.edges[self->edge].next; + + PyObject* const str = PyUnicode_FromStringAndSize(variant.sequence.str, variant.sequence.len); + if (str == NULL) + { + return NULL; + } // if + PyObject* const args = Py_BuildValue("nnO", variant.start, variant.end, str); + if (args == NULL) + { + Py_DECREF(str); + return NULL; + } // if + PyObject* const var = PyObject_CallObject((PyObject*) state->Variant_Type, args); + Py_DECREF(args); + if (var == NULL) + { + Py_DECREF(str); + return NULL; + } // if + + return Py_BuildValue("{s: (i, i, i), s: (i, i, i), s: O, s: i}", + "head", head.row, head.col, head.length, + "tail", tail.row, tail.col, tail.length, + "variant", var, + "count", count + ); +} // LCSgraph_Edge_Iterator_next + + static PyObject* Variant_new(PyTypeObject* subtype, PyObject* args, PyObject* kwargs) { @@ -297,7 +417,7 @@ Variant_repr(Variant_Object* self) static PyObject* Variant_richcompare(Variant_Object* self, Variant_Object* other, int op) { - algebra_ext_state* state = get_algebra_ext_state(PyType_GetModule(Py_TYPE(self))); + algebra_ext_state* const state = get_algebra_ext_state(PyType_GetModule(Py_TYPE(self))); if (state == NULL) { return NULL; @@ -370,6 +490,12 @@ static PyType_Spec LCSgraph_Spec = METH_NOARGS, PyDoc_STR("The supremal variant."), }, + { + "edges", + (PyCFunction) LCSgraph_edges, + METH_NOARGS, + PyDoc_STR("Edges iterator."), + }, {NULL, NULL, 0, NULL} // sentinel }, }, @@ -378,6 +504,23 @@ static PyType_Spec LCSgraph_Spec = }; +static PyType_Spec LCSgraph_Edge_Iterator_Spec = +{ + .name = "algebra_ext.LCSgraphEdgeIterator", + .basicsize = sizeof(LCSgraph_Edge_Iterator), + .flags = Py_TPFLAGS_DEFAULT, + .slots = (PyType_Slot[]) + { + {Py_tp_doc, PyDoc_STR("LCS graph edge iterator.")}, + {Py_tp_new, LCSgraph_Edge_Iterator_new}, + {Py_tp_dealloc, LCSgraph_Edge_Iterator_dealloc}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, LCSgraph_Edge_Iterator_next}, + {0, NULL} // sentinel + }, +}; + + static PyType_Spec Variant_Spec = { .name = "algebra_ext.Variant", @@ -406,8 +549,9 @@ static PyType_Spec Variant_Spec = static int algebra_ext_clear(PyObject* module) { - algebra_ext_state* state = get_algebra_ext_state(module); + algebra_ext_state* const state = get_algebra_ext_state(module); Py_CLEAR(state->LCSgraph_Type); + Py_CLEAR(state->LCSgraph_Edge_Iterator_Type); Py_CLEAR(state->Variant_Type); Py_CLEAR(state->Relations); return 0; @@ -424,7 +568,7 @@ algebra_ext_free(void* module) static int algebra_ext_mod_exec(PyObject* module) { - algebra_ext_state* state = get_algebra_ext_state(module); + algebra_ext_state* const state = get_algebra_ext_state(module); state->LCSgraph_Type = (PyTypeObject*) PyType_FromModuleAndSpec(module, &LCSgraph_Spec, NULL); if (state->LCSgraph_Type == NULL) @@ -433,6 +577,13 @@ algebra_ext_mod_exec(PyObject* module) return -1; } // if + state->LCSgraph_Edge_Iterator_Type = (PyTypeObject*) PyType_FromModuleAndSpec(module, &LCSgraph_Edge_Iterator_Spec, NULL); + if (state->LCSgraph_Edge_Iterator_Type == NULL) + { + Py_DECREF(module); + return -1; + } // if + state->Variant_Type = (PyTypeObject*) PyType_FromModuleAndSpec(module, &Variant_Spec, NULL); if (state->Variant_Type == NULL) { @@ -446,13 +597,19 @@ algebra_ext_mod_exec(PyObject* module) return -1; } // if + if (PyModule_AddObjectRef(module, "LCSgraphEdgeIterator", (PyObject*) state->LCSgraph_Edge_Iterator_Type) < 0) + { + Py_DECREF(module); + return -1; + } // if + if (PyModule_AddObjectRef(module, "Variant", (PyObject*) state->Variant_Type) < 0) { Py_DECREF(module); return -1; } // if - PyObject* dict_relations = PyDict_New(); + PyObject* const dict_relations = PyDict_New(); if (dict_relations == NULL) { Py_DECREF(module); @@ -461,7 +618,7 @@ algebra_ext_mod_exec(PyObject* module) for (size_t i = 0; i < sizeof(GVA_RELATION_LABELS) / sizeof(*GVA_RELATION_LABELS); ++i) { - PyObject* value = PyUnicode_InternFromString(GVA_RELATION_LABELS[i]); + PyObject* const value = PyUnicode_InternFromString(GVA_RELATION_LABELS[i]); if (value == NULL) { Py_DECREF(dict_relations); @@ -479,7 +636,7 @@ algebra_ext_mod_exec(PyObject* module) Py_DECREF(value); } // for - PyObject* module_enum = PyImport_ImportModule("enum"); + PyObject* const module_enum = PyImport_ImportModule("enum"); if (module_enum == NULL) { Py_DECREF(dict_relations); @@ -510,7 +667,7 @@ algebra_ext_mod_exec(PyObject* module) static PyObject* algebra_ext_compare(PyObject* self, PyObject* args, PyObject* kwargs) { - algebra_ext_state* state = get_algebra_ext_state(self); + algebra_ext_state* const state = get_algebra_ext_state(self); if (state == NULL) { return NULL; diff --git a/python/tests/test_lcs_graph.py b/python/tests/test_lcs_graph.py index 13247f8..45fbdf5 100644 --- a/python/tests/test_lcs_graph.py +++ b/python/tests/test_lcs_graph.py @@ -13,3 +13,17 @@ def test_LCSgraph_from_variants(reference, variants, supremal, local_supremal, c assert all((graph.supremal() == supremal, graph.local_supremal() == local_supremal, graph.canonical() == canonical)) + + +def test_LCSgraph_edges(): + graph = LCSgraph.from_variants("ACCTGACT", [Variant(1, 2, "T"), Variant(4, 5, "T"), Variant(7, 8, "TT")]) + assert list(graph.edges()) == [ + {"head": (5, 5, 3), "tail": (7, 8, 1), "variant": Variant(7, 7, "T"), "count": 2}, + {"head": (3, 3, 1), "tail": (5, 5, 3), "variant": Variant(4, 5, "T"), "count": 1}, + {"head": (3, 4, 1), "tail": (5, 5, 3), "variant": Variant(4, 5, ""), "count": 1}, + {"head": (1, 2, 1), "tail": (3, 4, 1), "variant": Variant(2, 3, "T"), "count": 1}, + {"head": (1, 2, 1), "tail": (3, 3, 1), "variant": Variant(2, 3, ""), "count": 1}, + {"head": (2, 2, 1), "tail": (3, 4, 1), "variant": Variant(3, 3, "T"), "count": 1}, + {"head": (1, 1, 0), "tail": (2, 2, 1), "variant": Variant(1, 2, "T"), "count": 1}, + {"head": (1, 1, 0), "tail": (1, 2, 1), "variant": Variant(1, 1, "T"), "count": 1} + ] From 31bc79633fcd7ea497fd161032ec5758542e44d2 Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 27 Aug 2025 22:27:50 +0200 Subject: [PATCH 354/704] Clean up and some docs --- python/algebra_extmodule.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/python/algebra_extmodule.c b/python/algebra_extmodule.c index 4bda9e0..d9880e6 100644 --- a/python/algebra_extmodule.c +++ b/python/algebra_extmodule.c @@ -314,7 +314,7 @@ LCSgraph_Edge_Iterator_next(LCSgraph_Edge_Iterator* self) if (self->node >= array_length(self->graph->graph.nodes)) { Py_CLEAR(self->graph); - return NULL; + return NULL; // raises StopIteration } // if self->edge = self->graph->graph.nodes[self->node].edges; } // if @@ -346,9 +346,9 @@ LCSgraph_Edge_Iterator_next(LCSgraph_Edge_Iterator* self) Py_DECREF(str); return NULL; } // if - PyObject* const var = PyObject_CallObject((PyObject*) state->Variant_Type, args); + PyObject* const object = PyObject_CallObject((PyObject*) state->Variant_Type, args); Py_DECREF(args); - if (var == NULL) + if (object == NULL) { Py_DECREF(str); return NULL; @@ -357,7 +357,7 @@ LCSgraph_Edge_Iterator_next(LCSgraph_Edge_Iterator* self) return Py_BuildValue("{s: (i, i, i), s: (i, i, i), s: O, s: i}", "head", head.row, head.col, head.length, "tail", tail.row, tail.col, tail.length, - "variant", var, + "variant", object, "count", count ); } // LCSgraph_Edge_Iterator_next @@ -383,6 +383,8 @@ Variant_new(PyTypeObject* subtype, PyObject* args, PyObject* kwargs) return NULL; } // if + // FIXME: The Variant object owns a copy of the inserted sequence string + // and must append a NULL character for the sequence getter. self->sequence = PyMem_Malloc(len + 1); if (self->sequence == NULL) { @@ -402,6 +404,7 @@ Variant_new(PyTypeObject* subtype, PyObject* args, PyObject* kwargs) static inline void Variant_dealloc(Variant_Object* self) { + // FIXME: ownership of sequence PyMem_Free(self->sequence); Py_TYPE(self)->tp_free((PyObject*) self); } // Variant_dealloc @@ -494,7 +497,7 @@ static PyType_Spec LCSgraph_Spec = "edges", (PyCFunction) LCSgraph_edges, METH_NOARGS, - PyDoc_STR("Edges iterator."), + PyDoc_STR("An iterator over the edges in the LCS graph."), }, {NULL, NULL, 0, NULL} // sentinel }, @@ -511,7 +514,7 @@ static PyType_Spec LCSgraph_Edge_Iterator_Spec = .flags = Py_TPFLAGS_DEFAULT, .slots = (PyType_Slot[]) { - {Py_tp_doc, PyDoc_STR("LCS graph edge iterator.")}, + {Py_tp_doc, PyDoc_STR("Iterator over edges in an LCS graph.")}, {Py_tp_new, LCSgraph_Edge_Iterator_new}, {Py_tp_dealloc, LCSgraph_Edge_Iterator_dealloc}, {Py_tp_iter, PyObject_SelfIter}, From d400a77f2d84ca5f7a1e7ae8ffa5d224c73ec767 Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 29 Aug 2025 13:38:06 +0200 Subject: [PATCH 355/704] Also iterate over the lambda edges --- python/algebra_extmodule.c | 18 +++++++++++++++++- python/tests/test_lcs_graph.py | 1 + 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/python/algebra_extmodule.c b/python/algebra_extmodule.c index d9880e6..f200b20 100644 --- a/python/algebra_extmodule.c +++ b/python/algebra_extmodule.c @@ -1,7 +1,7 @@ #define PY_SSIZE_T_CLEAN #include // Py* -#include // bool +#include // bool, false, true #include // NULL, offsetof, size_t #include // memcpy @@ -28,6 +28,7 @@ typedef struct typedef struct { PyObject_VAR_HEAD + bool lambda; size_t node; gva_uint edge; LCSgraph_Object* graph; @@ -291,6 +292,7 @@ LCSgraph_Edge_Iterator_new(PyTypeObject* subtype, PyObject* args, PyObject* kwar Py_INCREF(graph); self->graph = graph; + self->lambda = false; self->node = 0; self->edge = graph->graph.nodes[self->node].edges; return (PyObject*) self; @@ -316,6 +318,7 @@ LCSgraph_Edge_Iterator_next(LCSgraph_Edge_Iterator* self) Py_CLEAR(self->graph); return NULL; // raises StopIteration } // if + self->lambda = false; self->edge = self->graph->graph.nodes[self->node].edges; } // if @@ -326,6 +329,19 @@ LCSgraph_Edge_Iterator_next(LCSgraph_Edge_Iterator* self) } // if GVA_Node const head = self->graph->graph.nodes[self->node]; + + if (!self->lambda && self->graph->graph.nodes[self->node].lambda != GVA_NULL) + { + GVA_Node const tail = self->graph->graph.nodes[self->graph->graph.nodes[self->node].lambda]; + self->lambda = true; + return Py_BuildValue("{s: (i, i, i), s: (i, i, i), s: O, s: i}", + "head", head.row, head.col, head.length, + "tail", tail.row, tail.col, tail.length, + "variant", Py_None, + "count", 0 + ); + } // if + GVA_Node const tail = self->graph->graph.nodes[self->graph->graph.edges[self->edge].tail]; GVA_Variant variant; gva_uint const count = gva_edges(self->graph->graph.observed.str, diff --git a/python/tests/test_lcs_graph.py b/python/tests/test_lcs_graph.py index 45fbdf5..f9355fa 100644 --- a/python/tests/test_lcs_graph.py +++ b/python/tests/test_lcs_graph.py @@ -23,6 +23,7 @@ def test_LCSgraph_edges(): {"head": (3, 4, 1), "tail": (5, 5, 3), "variant": Variant(4, 5, ""), "count": 1}, {"head": (1, 2, 1), "tail": (3, 4, 1), "variant": Variant(2, 3, "T"), "count": 1}, {"head": (1, 2, 1), "tail": (3, 3, 1), "variant": Variant(2, 3, ""), "count": 1}, + {"head": (2, 2, 1), "tail": (3, 3, 1), "variant": None, "count": 0}, {"head": (2, 2, 1), "tail": (3, 4, 1), "variant": Variant(3, 3, "T"), "count": 1}, {"head": (1, 1, 0), "tail": (2, 2, 1), "variant": Variant(1, 2, "T"), "count": 1}, {"head": (1, 1, 0), "tail": (1, 2, 1), "variant": Variant(1, 1, "T"), "count": 1} From 62de0ec50673ebf586db313a4a91cf2f77ee9d7c Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 29 Aug 2025 13:43:15 +0200 Subject: [PATCH 356/704] Added INCREF for Py_None --- python/algebra_extmodule.c | 1 + 1 file changed, 1 insertion(+) diff --git a/python/algebra_extmodule.c b/python/algebra_extmodule.c index f200b20..acbf252 100644 --- a/python/algebra_extmodule.c +++ b/python/algebra_extmodule.c @@ -334,6 +334,7 @@ LCSgraph_Edge_Iterator_next(LCSgraph_Edge_Iterator* self) { GVA_Node const tail = self->graph->graph.nodes[self->graph->graph.nodes[self->node].lambda]; self->lambda = true; + Py_INCREF(Py_None); return Py_BuildValue("{s: (i, i, i), s: (i, i, i), s: O, s: i}", "head", head.row, head.col, head.length, "tail", tail.row, tail.col, tail.length, From 0cb76a7655d131fc6a7905baa63deddeee1996ba Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Thu, 4 Sep 2025 01:49:45 +0200 Subject: [PATCH 357/704] WIP: Hash table integration. --- src/main.c | 106 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 66 insertions(+), 40 deletions(-) diff --git a/src/main.c b/src/main.c index 31a8355..1787c06 100644 --- a/src/main.c +++ b/src/main.c @@ -858,26 +858,6 @@ compare(int argc, char* argv[static argc + 1]) int main(int argc, char* argv[static argc + 1]) { -/* - struct IN_EX - { - HASH_TABLE_KEY; - gva_uint included; - gva_uint excluded; - }* table = hash_table_init(gva_std_allocator, 1024, sizeof(*table)); - - HASH_TABLE_SET(gva_std_allocator, table, 42, ((struct IN_EX) {42, 1, 2})); - - if (table[HASH_TABLE_INDEX(table, 42)].gva_key == 42) - { - fprintf(stderr, "FOUND at %zu\n", HASH_TABLE_INDEX(table, 42)); - } // if - - table = HASH_TABLE_DESTROY(gva_std_allocator, table); - - return EXIT_SUCCESS; -*/ - errno = 0; FILE* stream = fopen(argv[1], "r"); if (stream == NULL) @@ -981,15 +961,12 @@ main(int argc, char* argv[static argc + 1]) continue; } // if - struct { + struct IN_EX + { + HASH_TABLE_KEY; gva_uint included; gva_uint excluded; - }* result_map = gva_std_allocator.allocate(gva_std_allocator.context, NULL, 0, 1024 * sizeof(*result_map)); - if (result_map == NULL) - { - return -1; - } // if - memset(result_map, 0, 1024 * sizeof(*result_map)); + }* table = hash_table_init(gva_std_allocator, 1024, sizeof(*table)); GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &sup); for (size_t i = 0; i < array_length(graph.local_supremal) - 1; ++i) @@ -1012,23 +989,67 @@ main(int argc, char* argv[static argc + 1]) { for (gva_uint j = tree.nodes[results[i]].alleles; j != GVA_NULL; j = node_allele_join[j].next) { - result_map[node_allele_join[j].allele].included += dist; + size_t allele = node_allele_join[j].allele; + size_t hash_idx = HASH_TABLE_INDEX(table, allele); + fprintf(stderr, "equiv/contains allele_idx: %zu pv_id: %zu\n", allele, alleles[allele].data); + if (table[hash_idx].gva_key != allele) + { + fprintf(stderr, "NOT FOUND YET\n"); + HASH_TABLE_SET(gva_std_allocator, table, allele, ((struct IN_EX) {allele, 0, 0})); + hash_idx = HASH_TABLE_INDEX(table, allele); + } // if + else + { + fprintf(stderr, "FOUND %zu @ %zu\n", allele, hash_idx); + } // else + fprintf(stderr, "MODIFYING allele_idx: %zu @ hash_idx: %zu\n", allele, hash_idx); + table[hash_idx].included += dist; } // for } // if else if (relation == GVA_IS_CONTAINED) { for (gva_uint j = tree.nodes[results[i]].alleles; j != GVA_NULL; j = node_allele_join[j].next) { - result_map[node_allele_join[j].allele].included += tree.nodes[results[i]].distance; - result_map[node_allele_join[j].allele].excluded += dist - tree.nodes[results[i]].distance; + size_t allele = node_allele_join[j].allele; + size_t hash_idx = HASH_TABLE_INDEX(table, allele); + fprintf(stderr, "is_contained allele_idx: %zu pv_id: %zu\n", allele, alleles[allele].data); + if (table[hash_idx].gva_key != allele) + { + fprintf(stderr, "NOT FOUND YET\n"); + HASH_TABLE_SET(gva_std_allocator, table, allele, ((struct IN_EX) {allele, 0, 0})); + hash_idx = HASH_TABLE_INDEX(table, allele); + } // if + else + { + fprintf(stderr, "FOUND %zu @ %zu\n", allele, hash_idx); + + } // else + fprintf(stderr, "MODIFYING allele_idx: %zu @ hash_idx: %zu\n", allele, hash_idx); + table[hash_idx].included += tree.nodes[results[i]].distance; + table[hash_idx].excluded += dist - tree.nodes[results[i]].distance; } // for } // if else if (relation == GVA_OVERLAP) { for (gva_uint j = tree.nodes[results[i]].alleles; j != GVA_NULL; j = node_allele_join[j].next) { - result_map[node_allele_join[j].allele].included += 1; - result_map[node_allele_join[j].allele].excluded += 1; + size_t allele = node_allele_join[j].allele; + size_t hash_idx = HASH_TABLE_INDEX(table, allele); + fprintf(stderr, "is_contained allele_idx: %zu pv_id: %zu\n", allele, alleles[allele].data); + if (table[hash_idx].gva_key != allele) + { + fprintf(stderr, "NOT FOUND YET\n"); + HASH_TABLE_SET(gva_std_allocator, table, allele, ((struct IN_EX) {allele, 0, 0})); + hash_idx = HASH_TABLE_INDEX(table, allele); + } // if + else + { + fprintf(stderr, "FOUND %zu @ %zu\n", allele, hash_idx); + + } // else + fprintf(stderr, "MODIFYING allele_idx: %zu @ hash_idx: %zu\n", allele, hash_idx); + table[hash_idx].included += 1; + table[hash_idx].excluded += 1; } // for } // if } // for @@ -1041,14 +1062,19 @@ main(int argc, char* argv[static argc + 1]) for (size_t i = 0; i < 1024; ++i) { - if (result_map[i].included > 0 || result_map[i].excluded > 0) + if (table[i].gva_key == (uint32_t) -1) + { + continue; + } + size_t allele = table[i].gva_key; + if (table[i].included > 0 || table[i].excluded > 0) { - result_map[i].excluded = graph.distance - result_map[i].included; + table[i].excluded = graph.distance - table[i].included; GVA_Relation relation = GVA_OVERLAP; - if (result_map[i].excluded == 0) + if (table[i].excluded == 0) { - if (result_map[i].included == alleles[i].distance) + if (table[i].included == alleles[allele].distance) { relation = GVA_EQUIVALENT; } // if @@ -1057,18 +1083,18 @@ main(int argc, char* argv[static argc + 1]) relation = GVA_CONTAINS; } // else } // if - else if (result_map[i].included == alleles[i].distance) + else if (table[i].included == alleles[allele].distance) { relation = GVA_IS_CONTAINED; } // if - if (alleles[i].data < id) + if (alleles[allele].data < id) { - fprintf(stdout, "%zu %zu %s\n", alleles[i].data, id, GVA_RELATION_LABELS[relation]); + fprintf(stdout, "%zu %zu %s\n", alleles[allele].data, id, GVA_RELATION_LABELS[relation]); } // if } // if } // for - result_map = gva_std_allocator.allocate(gva_std_allocator.context, result_map, 1024 * sizeof(*result_map), 0); + table = HASH_TABLE_DESTROY(gva_std_allocator, table); } // while fclose(stream); From c1572a0c1f642ab13177cd9504c668c6279c48a6 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Thu, 25 Sep 2025 10:15:58 +0200 Subject: [PATCH 358/704] WIP while debugging non-combining inclusion. --- src/main.c | 225 +++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 183 insertions(+), 42 deletions(-) diff --git a/src/main.c b/src/main.c index 1787c06..ee9bde4 100644 --- a/src/main.c +++ b/src/main.c @@ -1,8 +1,10 @@ +#define _POSIX_C_SOURCE 200809L #include // errno #include // CHAR_BIT #include // NULL, size_t #include // FILE, stderr, fclose, fopen, fprintf #include // EXIT_* + #include // strerror, strlen #include // CLOCKS_PER_SEC, clock_t, clock @@ -29,6 +31,8 @@ #define LINE_SIZE 8194 +#define REFERENCE_ID "NC_000001.11" + static void lcs_graph_svg(FILE* const stream, GVA_LCS_Graph const graph) @@ -883,6 +887,7 @@ main(int argc, char* argv[static argc + 1]) struct Allele { size_t data; + GVA_Variant supremal; gva_uint start; gva_uint distance; }* alleles = NULL; @@ -903,7 +908,16 @@ main(int argc, char* argv[static argc + 1]) } // if GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &variant); - gva_uint const allele = ARRAY_APPEND(gva_std_allocator, alleles, ((struct Allele) {id, array_length(node_allele_join), graph.distance})) - 1; + // return (f"{reference_id}:{self.start}:{self.end - self.start}:" f"{self.sequence}") + // char spdi_str[42 + graph.supremal.sequence.len]; + // printf(GVA_VARIANT_FMT_SPDI "\n", GVA_VARIANT_PRINT_SPDI("NC_000001.11", graph.supremal)); + // sprintf(spdi_str, GVA_VARIANT_FMT_SPDI, GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, graph.supremal)); + //gva_uint const allele = ARRAY_APPEND(gva_std_allocator, alleles, ((struct Allele) {id, strdup(spdi_str), array_length(node_allele_join), graph.distance})) - 1; + gva_uint const allele = ARRAY_APPEND(gva_std_allocator, alleles, ((struct Allele) {id, + (GVA_Variant) {graph.supremal.start, graph.supremal.end, (GVA_String) {graph.supremal.sequence.len, strndup(graph.supremal.sequence.str, graph.supremal.sequence.len)}}, + + array_length(node_allele_join), graph.distance})) - 1; + //gva_uint const allele = ARRAY_APPEND(gva_std_allocator, alleles, ((struct Allele) {id, strndup(line + idx, len), array_length(node_allele_join), graph.distance})) - 1; for (size_t i = 0; i < array_length(graph.local_supremal) - 1; ++i) { GVA_Variant variant; @@ -948,6 +962,7 @@ main(int argc, char* argv[static argc + 1]) return EXIT_FAILURE; } // if + // for every query while (fgets(line, sizeof(line), stream) != NULL) { size_t idx = 0; @@ -966,11 +981,16 @@ main(int argc, char* argv[static argc + 1]) HASH_TABLE_KEY; gva_uint included; gva_uint excluded; + gva_uint hits; + bool overlap; + bool disjoint; }* table = hash_table_init(gva_std_allocator, 1024, sizeof(*table)); + // query graph GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &sup); for (size_t i = 0; i < array_length(graph.local_supremal) - 1; ++i) { + // query local supremal part GVA_Variant part; gva_edges(graph.observed.str, graph.local_supremal[i], graph.local_supremal[i + 1], @@ -978,32 +998,39 @@ main(int argc, char* argv[static argc + 1]) &part); gva_uint dist = graph.local_supremal[i + 1].edges; + fprintf(stderr, "query part %zu (%d): " GVA_VARIANT_FMT "\n", i, dist, GVA_VARIANT_PRINT(part)); + // find candites for this local supremal part gva_uint* results = interval_tree_intersection(gva_std_allocator, tree, part.start, part.end); for (size_t i = 0; i < array_length(results); ++i) { GVA_Variant const lhs = {tree.nodes[results[i]].start, tree.nodes[results[i]].end, trie_string(trie, tree.nodes[results[i]].inserted)}; GVA_Relation relation = compare_from_index(reference, lhs, tree.nodes[results[i]].distance, part, dist); - + fprintf(stderr, "db hit %zu (%d): " GVA_VARIANT_FMT " %s\n", i, tree.nodes[results[i]].distance, GVA_VARIANT_PRINT(lhs), GVA_RELATION_LABELS[relation]); + continue; if (relation == GVA_EQUIVALENT || relation == GVA_CONTAINS) { for (gva_uint j = tree.nodes[results[i]].alleles; j != GVA_NULL; j = node_allele_join[j].next) { size_t allele = node_allele_join[j].allele; size_t hash_idx = HASH_TABLE_INDEX(table, allele); - fprintf(stderr, "equiv/contains allele_idx: %zu pv_id: %zu\n", allele, alleles[allele].data); + // fprintf(stderr, "equiv/contains allele_idx: %zu pv_id: %zu\n", allele, alleles[allele].data); if (table[hash_idx].gva_key != allele) { - fprintf(stderr, "NOT FOUND YET\n"); - HASH_TABLE_SET(gva_std_allocator, table, allele, ((struct IN_EX) {allele, 0, 0})); + // fprintf(stderr, "NOT FOUND YET\n"); + HASH_TABLE_SET(gva_std_allocator, table, allele, ((struct IN_EX) {allele, 0, 0, 0, false, false})); hash_idx = HASH_TABLE_INDEX(table, allele); } // if else { - fprintf(stderr, "FOUND %zu @ %zu\n", allele, hash_idx); + // fprintf(stderr, "FOUND %zu @ %zu\n", allele, hash_idx); } // else - fprintf(stderr, "MODIFYING allele_idx: %zu @ hash_idx: %zu\n", allele, hash_idx); + // fprintf(stderr, "MODIFYING allele_idx: %zu @ hash_idx: %zu\n", allele, hash_idx); + table[hash_idx].hits += 1; table[hash_idx].included += dist; + table[hash_idx].excluded += tree.nodes[results[i]].distance - dist; + fprintf(stderr, "I have included %zu %u\n", hash_idx, table[hash_idx].included); + fprintf(stderr, "I have excluded %zu %u\n", hash_idx, table[hash_idx].excluded); } // for } // if else if (relation == GVA_IS_CONTAINED) @@ -1012,21 +1039,24 @@ main(int argc, char* argv[static argc + 1]) { size_t allele = node_allele_join[j].allele; size_t hash_idx = HASH_TABLE_INDEX(table, allele); - fprintf(stderr, "is_contained allele_idx: %zu pv_id: %zu\n", allele, alleles[allele].data); + // fprintf(stderr, "is_contained allele_idx: %zu pv_id: %zu\n", allele, alleles[allele].data); if (table[hash_idx].gva_key != allele) { - fprintf(stderr, "NOT FOUND YET\n"); - HASH_TABLE_SET(gva_std_allocator, table, allele, ((struct IN_EX) {allele, 0, 0})); + // fprintf(stderr, "NOT FOUND YET\n"); + HASH_TABLE_SET(gva_std_allocator, table, allele, ((struct IN_EX) {allele, 0, 0, 0, false, false})); hash_idx = HASH_TABLE_INDEX(table, allele); } // if - else + // else { - fprintf(stderr, "FOUND %zu @ %zu\n", allele, hash_idx); + // fprintf(stderr, "FOUND %zu @ %zu\n", allele, hash_idx); } // else - fprintf(stderr, "MODIFYING allele_idx: %zu @ hash_idx: %zu\n", allele, hash_idx); + // fprintf(stderr, "MODIFYING allele_idx: %zu @ hash_idx: %zu\n", allele, hash_idx); + table[hash_idx].hits += 1; table[hash_idx].included += tree.nodes[results[i]].distance; table[hash_idx].excluded += dist - tree.nodes[results[i]].distance; + fprintf(stderr, "I have included %zu %u\n", hash_idx, table[hash_idx].included); + fprintf(stderr, "I have excluded %zu %u\n", hash_idx, table[hash_idx].excluded); } // for } // if else if (relation == GVA_OVERLAP) @@ -1035,67 +1065,178 @@ main(int argc, char* argv[static argc + 1]) { size_t allele = node_allele_join[j].allele; size_t hash_idx = HASH_TABLE_INDEX(table, allele); - fprintf(stderr, "is_contained allele_idx: %zu pv_id: %zu\n", allele, alleles[allele].data); + // fprintf(stderr, "is_contained allele_idx: %zu pv_id: %zu\n", allele, alleles[allele].data); if (table[hash_idx].gva_key != allele) { - fprintf(stderr, "NOT FOUND YET\n"); - HASH_TABLE_SET(gva_std_allocator, table, allele, ((struct IN_EX) {allele, 0, 0})); + // fprintf(stderr, "NOT FOUND YET\n"); + HASH_TABLE_SET(gva_std_allocator, table, allele, ((struct IN_EX) {allele, 0, 0, 0, false, false})); hash_idx = HASH_TABLE_INDEX(table, allele); } // if else { - fprintf(stderr, "FOUND %zu @ %zu\n", allele, hash_idx); + // fprintf(stderr, "FOUND %zu @ %zu\n", allele, hash_idx); } // else - fprintf(stderr, "MODIFYING allele_idx: %zu @ hash_idx: %zu\n", allele, hash_idx); + // fprintf(stderr, "MODIFYING allele_idx: %zu @ hash_idx: %zu\n", allele, hash_idx); + table[hash_idx].hits += 1; + table[hash_idx].overlap = true; table[hash_idx].included += 1; table[hash_idx].excluded += 1; + fprintf(stderr, "I have included %zu %u\n", hash_idx, table[hash_idx].included); + fprintf(stderr, "I have excluded %zu %u\n", hash_idx, table[hash_idx].excluded); } // for } // if + else if (relation == GVA_DISJOINT) + { + for (gva_uint j = tree.nodes[results[i]].alleles; j != GVA_NULL; j = node_allele_join[j].next) + { + size_t allele = node_allele_join[j].allele; + size_t hash_idx = HASH_TABLE_INDEX(table, allele); + // fprintf(stderr, "equiv/contains allele_idx: %zu pv_id: %zu\n", allele, alleles[allele].data); + if (table[hash_idx].gva_key != allele) + { + // fprintf(stderr, "NOT FOUND YET\n"); + HASH_TABLE_SET(gva_std_allocator, table, allele, ((struct IN_EX) {allele, 0, 0, 0, false, false})); + hash_idx = HASH_TABLE_INDEX(table, allele); + } // if + else + { + // fprintf(stderr, "FOUND %zu @ %zu\n", allele, hash_idx); + } // else + // fprintf(stderr, "MODIFYING allele_idx: %zu @ hash_idx: %zu\n", allele, hash_idx); + table[hash_idx].hits += 1; + table[hash_idx].disjoint = true; + table[hash_idx].excluded += dist; + fprintf(stderr, "I have excluded %zu %u\n", hash_idx, table[hash_idx].excluded); + } // for + } + } // for results = ARRAY_DESTROY(gva_std_allocator, results); } // for - gva_string_destroy(gva_std_allocator, graph.observed); - gva_lcs_graph_destroy(gva_std_allocator, graph); - - for (size_t i = 0; i < 1024; ++i) + // FIXME: Use real size?! + // for (size_t i = 0; i < 1024; ++i) + size_t x = array_header(table)->capacity; + // fprintf(stderr, "table size: %zu\n", x); + for (size_t i = 0; i < x; ++i) { + // fprintf(stderr, "table i: %zu\n", i); if (table[i].gva_key == (uint32_t) -1) { continue; } - size_t allele = table[i].gva_key; - if (table[i].included > 0 || table[i].excluded > 0) + if (table[i].included == 0 && table[i].excluded == 0) { - table[i].excluded = graph.distance - table[i].included; + fprintf(stderr, "deze disjoint?!\n"); + continue; + } - GVA_Relation relation = GVA_OVERLAP; - if (table[i].excluded == 0) + size_t allele = table[i].gva_key; + fprintf(stderr, "table incl: %u\n", table[i].included); + fprintf(stderr, "table excl: %u\n", table[i].excluded); + fprintf(stderr, "query distance: %u\n", graph.distance); + fprintf(stderr, "db allele distance: %u\n", alleles[allele].distance); + // table[i].excluded = graph.distance - table[i].included; + fprintf(stderr, "table new excl: %u\n", table[i].excluded); + + GVA_Relation relation = GVA_DISJOINT; + if (table[i].excluded == 0 && alleles[allele].distance == graph.distance) { + fprintf(stderr, "deze equiv?!\n"); + relation = GVA_EQUIVALENT; + } + else if (table[i].included > 0 && alleles[allele].distance > graph.distance) + { + if (array_length(graph.local_supremal) - 1 <= table[i].hits && !table[i].overlap && table[i].included == graph.distance + // && table[i].excluded == 0 + ) { - if (table[i].included == alleles[allele].distance) - { - relation = GVA_EQUIVALENT; - } // if - else + fprintf(stderr, "deze contains?!\n"); + relation = GVA_CONTAINS; + } + else + { + fprintf(stderr, "deze 2 overlap?!\n"); + relation = GVA_OVERLAP; + } + } + else if (table[i].included == alleles[allele].distance && + alleles[allele].distance < graph.distance) + { + fprintf(stderr, "local supremals: %zu hits: %d\n", array_length(graph.local_supremal), table[i].hits); + if (array_length(graph.local_supremal) - 1 == table[i].hits) + { + fprintf(stderr, "Seen all parts\n"); + if (table[i].overlap) { - relation = GVA_CONTAINS; - } // else - } // if - else if (table[i].included == alleles[allele].distance) + fprintf(stderr, "there was overlap?!\n"); + relation = GVA_OVERLAP; + } + else { + fprintf(stderr, "deze is_contained?!\n"); + relation = GVA_IS_CONTAINED; + } + } + else if (table[i].disjoint) { + fprintf(stderr, "there was disjoint?!\n"); + relation = GVA_OVERLAP; + } + else if (!table[i].overlap) + { + fprintf(stderr, "there was no overlap?!\n"); relation = GVA_IS_CONTAINED; - } // if - - if (alleles[allele].data < id) + } + else { - fprintf(stdout, "%zu %zu %s\n", alleles[allele].data, id, GVA_RELATION_LABELS[relation]); - } // if - } // if + fprintf(stderr, "Not seen all parts\n"); + fprintf(stderr, "deze is_contained?!\n"); + relation = GVA_OVERLAP; + } + } + // } // if + // else + // { + // fprintf(stderr, "deze contains?!\n"); + // relation = GVA_CONTAINS; + // } // else + // } // if + // // else if (table[i].included == alleles[allele].distance) + // // else if (table[i].included == graph.distance) + // else if (table[i].included == graph.distance && graph.distance > alleles[allele].distance) + // { + // relation = GVA_IS_CONTAINED; + // fprintf(stderr, "deze is_contained?!\n"); + // } // if + else if (table[i].included > 0) + { + fprintf(stderr, "deze overlap?!\n"); + relation = GVA_OVERLAP; + } + + if (relation == GVA_EQUIVALENT || relation == GVA_DISJOINT) + { + continue; + } + + // fprintf(stderr, "distances: %u %u\n", alleles[allele].distance, graph.distance); + + fprintf(stdout, "%zu " GVA_VARIANT_FMT_SPDI " %zu " GVA_VARIANT_FMT_SPDI " %s\n", + alleles[allele].data, GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, alleles[allele].supremal), + id, GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, graph.supremal), + GVA_RELATION_LABELS[relation]); + // fprintf(stdout, "%zu " GVA_VARIANT_FMT_SPDI " %zu " GVA_VARIANT_FMT_SPDI " %s\n", + // id, GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, graph.supremal), + // alleles[allele].data, GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, alleles[allele].supremal), + // GVA_RELATION_LABELS[relation]); + } // for table = HASH_TABLE_DESTROY(gva_std_allocator, table); + gva_string_destroy(gva_std_allocator, graph.observed); + gva_lcs_graph_destroy(gva_std_allocator, graph); + } // while fclose(stream); From 2c60cedd7a0870e4d98d9519cc2a3e56005c9dc5 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Mon, 29 Sep 2025 13:32:54 +0200 Subject: [PATCH 359/704] WIP: before removal of disjoint bookkeeping. --- include/relations.h | 2 +- src/main.c | 507 ++++++++++++++++++++++---------------------- 2 files changed, 260 insertions(+), 249 deletions(-) diff --git a/include/relations.h b/include/relations.h index 5bb0c4a..d4f1fe7 100644 --- a/include/relations.h +++ b/include/relations.h @@ -4,7 +4,7 @@ typedef enum { - GVA_DISJOINT, + GVA_DISJOINT = 0, GVA_OVERLAP, GVA_CONTAINS, GVA_IS_CONTAINED, diff --git a/src/main.c b/src/main.c index ee9bde4..6fd4c69 100644 --- a/src/main.c +++ b/src/main.c @@ -887,61 +887,59 @@ main(int argc, char* argv[static argc + 1]) struct Allele { size_t data; - GVA_Variant supremal; - gva_uint start; + gva_uint join_start; // offset into node_allele_join gva_uint distance; }* alleles = NULL; - size_t count = 0; + size_t line_count = 0; static char line[LINE_SIZE] = {0}; while (fgets(line, sizeof(line), stdin) != NULL) { size_t idx = 0; - size_t const id = parse_number(line, &idx); + size_t const rsid = parse_number(line, &idx); idx += 1; // skip space or tab int const len = (char*) memchr(line + idx, '\n', LINE_SIZE - idx) - (line + idx); GVA_Variant variant; if (gva_parse_spdi(len, line + idx, &variant) == 0) { - fprintf(stderr, "error: SPDI parsing failed at line %zu: %s", count + 1, line); + fprintf(stderr, "error: SPDI parsing failed at line %zu: %s", line_count + 1, line); continue; } // if GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &variant); - // return (f"{reference_id}:{self.start}:{self.end - self.start}:" f"{self.sequence}") - // char spdi_str[42 + graph.supremal.sequence.len]; - // printf(GVA_VARIANT_FMT_SPDI "\n", GVA_VARIANT_PRINT_SPDI("NC_000001.11", graph.supremal)); - // sprintf(spdi_str, GVA_VARIANT_FMT_SPDI, GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, graph.supremal)); - //gva_uint const allele = ARRAY_APPEND(gva_std_allocator, alleles, ((struct Allele) {id, strdup(spdi_str), array_length(node_allele_join), graph.distance})) - 1; - gva_uint const allele = ARRAY_APPEND(gva_std_allocator, alleles, ((struct Allele) {id, - (GVA_Variant) {graph.supremal.start, graph.supremal.end, (GVA_String) {graph.supremal.sequence.len, strndup(graph.supremal.sequence.str, graph.supremal.sequence.len)}}, - - array_length(node_allele_join), graph.distance})) - 1; - //gva_uint const allele = ARRAY_APPEND(gva_std_allocator, alleles, ((struct Allele) {id, strndup(line + idx, len), array_length(node_allele_join), graph.distance})) - 1; + gva_uint const allele_idx = ARRAY_APPEND( + gva_std_allocator, alleles, + ((struct Allele) {rsid, array_length(node_allele_join), graph.distance}) + ) - 1; + fprintf(stderr, "input allele %zu: " GVA_VARIANT_FMT " stored at: %d\n", rsid, GVA_VARIANT_PRINT(variant), allele_idx); + for (size_t i = 0; i < array_length(graph.local_supremal) - 1; ++i) { - GVA_Variant variant; + GVA_Variant part; gva_edges(graph.observed.str, graph.local_supremal[i], graph.local_supremal[i + 1], i == 0, i == array_length(graph.local_supremal) - 2, - &variant); + &part); - gva_uint const inserted = trie_insert(gva_std_allocator, &trie, variant.sequence.len, variant.sequence.str); - gva_uint const node = ARRAY_APPEND(gva_std_allocator, tree.nodes, ((Interval_Tree_Node) {{GVA_NULL, GVA_NULL}, variant.start, variant.end, variant.end, 0, inserted, GVA_NULL, graph.local_supremal[i + 1].edges})) - 1; - gva_uint const here = interval_tree_insert(&tree, node); - if (here != node) + gva_uint const inserted_idx = trie_insert(gva_std_allocator, &trie, part.sequence.len, part.sequence.str); + gva_uint const tmp_idx = ARRAY_APPEND(gva_std_allocator, tree.nodes, ((Interval_Tree_Node) {{GVA_NULL, GVA_NULL}, part.start, part.end, part.end, 0, inserted_idx, GVA_NULL, graph.local_supremal[i + 1].edges})) - 1; + gva_uint const node_idx = interval_tree_insert(&tree, tmp_idx); + if (node_idx != tmp_idx) { - array_header(tree.nodes)->length -= 1; // delete; already in the tree + fprintf(stderr, " part %zu already in the tree\n", i); + array_header(tree.nodes)->length -= 1; // reverse; node already in the tree } // if - tree.nodes[here].alleles = ARRAY_APPEND(gva_std_allocator, node_allele_join, ((struct Node_Allele) {here, allele, tree.nodes[here].alleles})) - 1; + tree.nodes[node_idx].alleles = ARRAY_APPEND(gva_std_allocator, node_allele_join, ((struct Node_Allele) {node_idx, allele_idx, tree.nodes[node_idx].alleles})) - 1; + fprintf(stderr, " input part %zu (allele %d): " GVA_VARIANT_FMT " stored at: %d\n", i, allele_idx, GVA_VARIANT_PRINT(part), node_idx); + } // for gva_string_destroy(gva_std_allocator, graph.observed); gva_lcs_graph_destroy(gva_std_allocator, graph); - count += 1; + line_count += 1; } // while - fprintf(stderr, "count: %zu\n", count); + fprintf(stderr, "line count: %zu\n", line_count); fprintf(stderr, "tree nodes: %zu\n", array_length(tree.nodes)); fprintf(stderr, "trie nodes: %zu\n", array_length(trie.nodes)); @@ -963,281 +961,294 @@ main(int argc, char* argv[static argc + 1]) } // if // for every query + line_count = 0; while (fgets(line, sizeof(line), stream) != NULL) { size_t idx = 0; - size_t const id = parse_number(line, &idx); + size_t const query_id = parse_number(line, &idx); idx += 1; // skip space or tab int const len = (char*) memchr(line + idx, '\n', LINE_SIZE - idx) - (line + idx); - GVA_Variant sup; - if (gva_parse_spdi(len, line + idx, &sup) == 0) + GVA_Variant query_var; + if (gva_parse_spdi(len, line + idx, &query_var) == 0) { - fprintf(stderr, "error: SPDI parsing failed at line %zu: %s", count + 1, line); + fprintf(stderr, "error: SPDI parsing failed at line %zu: %s", line_count + 1, line); continue; } // if + fprintf(stderr, "query allele %zu: " GVA_VARIANT_FMT "\n", query_id, GVA_VARIANT_PRINT(query_var)); + // Link query to alleles struct IN_EX { HASH_TABLE_KEY; gva_uint included; gva_uint excluded; - gva_uint hits; - bool overlap; - bool disjoint; - }* table = hash_table_init(gva_std_allocator, 1024, sizeof(*table)); + // // gva_uint hits; + // // bool overlap; + // // bool disjoint; + // // bool contains; + // // bool is_contained; + // // bool equivalent; + }* in_ex_table = hash_table_init(gva_std_allocator, 1024, sizeof(*in_ex_table)); + + // Join nodes in the index to parts in the query + struct NODE_PARTS + { + HASH_TABLE_KEY; + gva_uint relation; + gva_uint start; + gva_uint end; + }* node_parts_table = hash_table_init(gva_std_allocator, 1024, sizeof(*node_parts_table)); // query graph - GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &sup); - for (size_t i = 0; i < array_length(graph.local_supremal) - 1; ++i) + GVA_LCS_Graph query_graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &query_var); + for (size_t part_idx = 0; part_idx < array_length(query_graph.local_supremal) - 1; ++part_idx) { + // Join query part with nodes in the same index allele + struct ALLELE_NODES + { + HASH_TABLE_KEY; + gva_uint* nodes; + }* allele_nodes_table = hash_table_init(gva_std_allocator, 1024, sizeof(*allele_nodes_table)); + // query local supremal part - GVA_Variant part; - gva_edges(graph.observed.str, - graph.local_supremal[i], graph.local_supremal[i + 1], - i == 0, i == array_length(graph.local_supremal) - 2, - &part); - - gva_uint dist = graph.local_supremal[i + 1].edges; - fprintf(stderr, "query part %zu (%d): " GVA_VARIANT_FMT "\n", i, dist, GVA_VARIANT_PRINT(part)); - - // find candites for this local supremal part - gva_uint* results = interval_tree_intersection(gva_std_allocator, tree, part.start, part.end); - for (size_t i = 0; i < array_length(results); ++i) { - GVA_Variant const lhs = {tree.nodes[results[i]].start, tree.nodes[results[i]].end, - trie_string(trie, tree.nodes[results[i]].inserted)}; - GVA_Relation relation = compare_from_index(reference, lhs, tree.nodes[results[i]].distance, part, dist); - fprintf(stderr, "db hit %zu (%d): " GVA_VARIANT_FMT " %s\n", i, tree.nodes[results[i]].distance, GVA_VARIANT_PRINT(lhs), GVA_RELATION_LABELS[relation]); - continue; - if (relation == GVA_EQUIVALENT || relation == GVA_CONTAINS) + GVA_Variant query_part; + gva_edges(query_graph.observed.str, + query_graph.local_supremal[part_idx], query_graph.local_supremal[part_idx + 1], + part_idx == 0, part_idx == array_length(query_graph.local_supremal) - 2, + &query_part); + + gva_uint query_dist = query_graph.local_supremal[part_idx + 1].edges; + fprintf(stderr, " query part %zu (dist: %d): " GVA_VARIANT_FMT "\n", part_idx, query_dist, GVA_VARIANT_PRINT(query_part)); + + // find candidates for this local supremal part + gva_uint* candidates = interval_tree_intersection(gva_std_allocator, tree, query_part.start, query_part.end); + for (size_t can_idx = 0; can_idx < array_length(candidates); ++can_idx) { + gva_uint node_idx = candidates[can_idx]; + GVA_Variant const db_var = {tree.nodes[node_idx].start, tree.nodes[node_idx].end, + trie_string(trie, tree.nodes[node_idx].inserted)}; + GVA_Relation relation = compare_from_index(reference, db_var, tree.nodes[node_idx].distance, query_part, query_dist); + fprintf(stderr, " db candidate node_idx: %d (dist: %d): " GVA_VARIANT_FMT " %s\n", node_idx, tree.nodes[node_idx].distance, GVA_VARIANT_PRINT(db_var), GVA_RELATION_LABELS[relation]); + + // link nodes to parts + size_t hash_idx = HASH_TABLE_INDEX(node_parts_table, node_idx); + if (node_parts_table[hash_idx].gva_key != node_idx) { - for (gva_uint j = tree.nodes[results[i]].alleles; j != GVA_NULL; j = node_allele_join[j].next) - { - size_t allele = node_allele_join[j].allele; - size_t hash_idx = HASH_TABLE_INDEX(table, allele); - // fprintf(stderr, "equiv/contains allele_idx: %zu pv_id: %zu\n", allele, alleles[allele].data); - if (table[hash_idx].gva_key != allele) - { - // fprintf(stderr, "NOT FOUND YET\n"); - HASH_TABLE_SET(gva_std_allocator, table, allele, ((struct IN_EX) {allele, 0, 0, 0, false, false})); - hash_idx = HASH_TABLE_INDEX(table, allele); - } // if - else - { - // fprintf(stderr, "FOUND %zu @ %zu\n", allele, hash_idx); - } // else - // fprintf(stderr, "MODIFYING allele_idx: %zu @ hash_idx: %zu\n", allele, hash_idx); - table[hash_idx].hits += 1; - table[hash_idx].included += dist; - table[hash_idx].excluded += tree.nodes[results[i]].distance - dist; - fprintf(stderr, "I have included %zu %u\n", hash_idx, table[hash_idx].included); - fprintf(stderr, "I have excluded %zu %u\n", hash_idx, table[hash_idx].excluded); - } // for + HASH_TABLE_SET(gva_std_allocator, node_parts_table, node_idx, ((struct NODE_PARTS) {node_idx, GVA_NULL, -1, -1})); + hash_idx = HASH_TABLE_INDEX(node_parts_table, node_idx); } // if - else if (relation == GVA_IS_CONTAINED) + if (relation == GVA_DISJOINT) { - for (gva_uint j = tree.nodes[results[i]].alleles; j != GVA_NULL; j = node_allele_join[j].next) + if (node_parts_table[hash_idx].relation == GVA_NULL || + node_parts_table[hash_idx].relation == GVA_DISJOINT) { - size_t allele = node_allele_join[j].allele; - size_t hash_idx = HASH_TABLE_INDEX(table, allele); - // fprintf(stderr, "is_contained allele_idx: %zu pv_id: %zu\n", allele, alleles[allele].data); - if (table[hash_idx].gva_key != allele) - { - // fprintf(stderr, "NOT FOUND YET\n"); - HASH_TABLE_SET(gva_std_allocator, table, allele, ((struct IN_EX) {allele, 0, 0, 0, false, false})); - hash_idx = HASH_TABLE_INDEX(table, allele); - } // if - // else - { - // fprintf(stderr, "FOUND %zu @ %zu\n", allele, hash_idx); - - } // else - // fprintf(stderr, "MODIFYING allele_idx: %zu @ hash_idx: %zu\n", allele, hash_idx); - table[hash_idx].hits += 1; - table[hash_idx].included += tree.nodes[results[i]].distance; - table[hash_idx].excluded += dist - tree.nodes[results[i]].distance; - fprintf(stderr, "I have included %zu %u\n", hash_idx, table[hash_idx].included); - fprintf(stderr, "I have excluded %zu %u\n", hash_idx, table[hash_idx].excluded); - } // for - } // if + node_parts_table[hash_idx].relation = GVA_DISJOINT; + } + else + { + node_parts_table[hash_idx].relation = GVA_OVERLAP; + } + } + else if (relation == GVA_EQUIVALENT) + { + node_parts_table[hash_idx].relation = GVA_EQUIVALENT; + } else if (relation == GVA_OVERLAP) { - for (gva_uint j = tree.nodes[results[i]].alleles; j != GVA_NULL; j = node_allele_join[j].next) - { - size_t allele = node_allele_join[j].allele; - size_t hash_idx = HASH_TABLE_INDEX(table, allele); - // fprintf(stderr, "is_contained allele_idx: %zu pv_id: %zu\n", allele, alleles[allele].data); - if (table[hash_idx].gva_key != allele) - { - // fprintf(stderr, "NOT FOUND YET\n"); - HASH_TABLE_SET(gva_std_allocator, table, allele, ((struct IN_EX) {allele, 0, 0, 0, false, false})); - hash_idx = HASH_TABLE_INDEX(table, allele); - } // if - else - { - // fprintf(stderr, "FOUND %zu @ %zu\n", allele, hash_idx); - - } // else - // fprintf(stderr, "MODIFYING allele_idx: %zu @ hash_idx: %zu\n", allele, hash_idx); - table[hash_idx].hits += 1; - table[hash_idx].overlap = true; - table[hash_idx].included += 1; - table[hash_idx].excluded += 1; - fprintf(stderr, "I have included %zu %u\n", hash_idx, table[hash_idx].included); - fprintf(stderr, "I have excluded %zu %u\n", hash_idx, table[hash_idx].excluded); - } // for - } // if - else if (relation == GVA_DISJOINT) + node_parts_table[hash_idx].relation = GVA_OVERLAP; + } + else if (relation == GVA_IS_CONTAINED) + { + node_parts_table[hash_idx].relation = GVA_IS_CONTAINED; + } + else if (relation == GVA_CONTAINS) { - for (gva_uint j = tree.nodes[results[i]].alleles; j != GVA_NULL; j = node_allele_join[j].next) + if (node_parts_table[hash_idx].relation == GVA_NULL) { - size_t allele = node_allele_join[j].allele; - size_t hash_idx = HASH_TABLE_INDEX(table, allele); - // fprintf(stderr, "equiv/contains allele_idx: %zu pv_id: %zu\n", allele, alleles[allele].data); - if (table[hash_idx].gva_key != allele) - { - // fprintf(stderr, "NOT FOUND YET\n"); - HASH_TABLE_SET(gva_std_allocator, table, allele, ((struct IN_EX) {allele, 0, 0, 0, false, false})); - hash_idx = HASH_TABLE_INDEX(table, allele); - } // if - else - { - // fprintf(stderr, "FOUND %zu @ %zu\n", allele, hash_idx); - } // else - // fprintf(stderr, "MODIFYING allele_idx: %zu @ hash_idx: %zu\n", allele, hash_idx); - table[hash_idx].hits += 1; - table[hash_idx].disjoint = true; - table[hash_idx].excluded += dist; - fprintf(stderr, "I have excluded %zu %u\n", hash_idx, table[hash_idx].excluded); - } // for + node_parts_table[hash_idx].relation = GVA_CONTAINS; + node_parts_table[hash_idx].start = part_idx; + node_parts_table[hash_idx].end = part_idx + 1; + } + else if (node_parts_table[hash_idx].relation == GVA_CONTAINS) + { + node_parts_table[hash_idx].end = part_idx + 1; + } + else + { + node_parts_table[hash_idx].relation = GVA_OVERLAP; + } } - } // for + for (gva_uint join_idx = tree.nodes[node_idx].alleles; join_idx != GVA_NULL; join_idx = node_allele_join[join_idx].next) + { + gva_uint allele_idx = node_allele_join[join_idx].allele; + fprintf(stderr, " join_idx: %d allele_idx: %d rs_id: %zu\n", join_idx, allele_idx, alleles[allele_idx].data); - results = ARRAY_DESTROY(gva_std_allocator, results); - } // for + // link all alleles impacted for this node + size_t hash_idx = HASH_TABLE_INDEX(allele_nodes_table, allele_idx); + if (allele_nodes_table[hash_idx].gva_key != allele_idx) + { + HASH_TABLE_SET(gva_std_allocator, allele_nodes_table, allele_idx, ((struct ALLELE_NODES) {allele_idx, NULL})); + hash_idx = HASH_TABLE_INDEX(allele_nodes_table, allele_idx); + } // if + ARRAY_APPEND(gva_std_allocator, allele_nodes_table[hash_idx].nodes, node_idx); - // FIXME: Use real size?! - // for (size_t i = 0; i < 1024; ++i) - size_t x = array_header(table)->capacity; - // fprintf(stderr, "table size: %zu\n", x); - for (size_t i = 0; i < x; ++i) - { - // fprintf(stderr, "table i: %zu\n", i); - if (table[i].gva_key == (uint32_t) -1) - { - continue; - } - if (table[i].included == 0 && table[i].excluded == 0) - { - fprintf(stderr, "deze disjoint?!\n"); - continue; - } + // link query to alleles + hash_idx = HASH_TABLE_INDEX(in_ex_table, allele_idx); + if (in_ex_table[hash_idx].gva_key != allele_idx) + { + HASH_TABLE_SET(gva_std_allocator, in_ex_table, allele_idx, ((struct IN_EX) {allele_idx, 0, 0})); + hash_idx = HASH_TABLE_INDEX(in_ex_table, allele_idx); + } // if - size_t allele = table[i].gva_key; - fprintf(stderr, "table incl: %u\n", table[i].included); - fprintf(stderr, "table excl: %u\n", table[i].excluded); - fprintf(stderr, "query distance: %u\n", graph.distance); - fprintf(stderr, "db allele distance: %u\n", alleles[allele].distance); - // table[i].excluded = graph.distance - table[i].included; - fprintf(stderr, "table new excl: %u\n", table[i].excluded); - - GVA_Relation relation = GVA_DISJOINT; - if (table[i].excluded == 0 && alleles[allele].distance == graph.distance) { - fprintf(stderr, "deze equiv?!\n"); - relation = GVA_EQUIVALENT; - } - else if (table[i].included > 0 && alleles[allele].distance > graph.distance) + if (relation == GVA_EQUIVALENT || relation == GVA_CONTAINS) + { + in_ex_table[hash_idx].included += query_dist; + } + else if (relation == GVA_IS_CONTAINED) + { + in_ex_table[hash_idx].included += tree.nodes[node_idx].distance; + in_ex_table[hash_idx].excluded += query_dist - tree.nodes[node_idx].distance; + } + else if (relation == GVA_OVERLAP) + { + in_ex_table[hash_idx].included += 1; + in_ex_table[hash_idx].excluded += 1; + } + else // (relation == GVA_DISJOINT) + { + in_ex_table[hash_idx].excluded += query_dist; + } + + fprintf(stderr, "\n"); + } // for alleles + + } // for every candidate + + for (size_t x = 0; x < array_header(allele_nodes_table)->capacity; ++x) { - if (array_length(graph.local_supremal) - 1 <= table[i].hits && !table[i].overlap && table[i].included == graph.distance - // && table[i].excluded == 0 - ) + if (allele_nodes_table[x].gva_key == (uint32_t) - 1) { - fprintf(stderr, "deze contains?!\n"); - relation = GVA_CONTAINS; + continue; } - else + fprintf(stderr, " allele_idx: %d\n", allele_nodes_table[x].gva_key); + for (size_t y = 0; y < array_length(allele_nodes_table[x].nodes); ++y) { - fprintf(stderr, "deze 2 overlap?!\n"); - relation = GVA_OVERLAP; + fprintf(stderr, " node: %d\n", allele_nodes_table[x].nodes[y]); } } - else if (table[i].included == alleles[allele].distance && - alleles[allele].distance < graph.distance) + + allele_nodes_table = HASH_TABLE_DESTROY(gva_std_allocator, allele_nodes_table); + candidates = ARRAY_DESTROY(gva_std_allocator, candidates); + fprintf(stderr, "\n"); + } // for query allele parts + + // TODO: dont store disjoint and accept an extra distance calculation now and then?! + + for (size_t i = 0; i < array_header(node_parts_table)->capacity; ++i) + { + size_t node_idx = node_parts_table[i].gva_key; + if (node_idx == (uint32_t) - 1) { - fprintf(stderr, "local supremals: %zu hits: %d\n", array_length(graph.local_supremal), table[i].hits); - if (array_length(graph.local_supremal) - 1 == table[i].hits) + continue; + } + fprintf(stderr, " node_idx: %zu " GVA_VARIANT_FMT " %s (%d, %d)\n", node_idx, + GVA_VARIANT_PRINT(((GVA_Variant) { + tree.nodes[node_idx].start, tree.nodes[node_idx].end, + trie_string(trie, tree.nodes[node_idx].inserted) + })), + GVA_RELATION_LABELS[node_parts_table[i].relation], + node_parts_table[i].start, node_parts_table[i].end); + + if (node_parts_table[i].relation == GVA_CONTAINS && node_parts_table[i].end - node_parts_table[i].start > 1) + { + fprintf(stderr, "Perform extra comparison\n"); + size_t slice_dist = 0; + for (size_t j = node_parts_table[i].start; j < node_parts_table[i].end; ++j) { - fprintf(stderr, "Seen all parts\n"); - if (table[i].overlap) - { - fprintf(stderr, "there was overlap?!\n"); - relation = GVA_OVERLAP; - } - else { - fprintf(stderr, "deze is_contained?!\n"); - relation = GVA_IS_CONTAINED; - } + slice_dist += query_graph.local_supremal[j + 1].edges; } - else if (table[i].disjoint) + fprintf(stderr, "distances: %zu %u\n", slice_dist, tree.nodes[node_idx].distance); + if (slice_dist >= tree.nodes[node_idx].distance) { - fprintf(stderr, "there was disjoint?!\n"); - relation = GVA_OVERLAP; + node_parts_table[i].relation = GVA_OVERLAP; + fprintf(stderr, "NOT REACHED?!\n"); + continue; } - else if (!table[i].overlap) + + GVA_Variant rhs; + gva_edges(query_graph.observed.str, + query_graph.local_supremal[node_parts_table[i].start], + query_graph.local_supremal[node_parts_table[i].end], + node_parts_table[i].start == 0, + node_parts_table[i].end == array_length(query_graph.local_supremal) - 1, + &rhs); + fprintf(stderr, GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(rhs)); + + GVA_Variant const lhs = {tree.nodes[node_idx].start, + tree.nodes[node_idx].end, + trie_string(trie, tree.nodes[node_idx].inserted)}; + + size_t const start = MIN(lhs.start, rhs.start); + size_t const end = MAX(lhs.end, rhs.end); + + size_t const lhs_len = (lhs.start - start) + lhs.sequence.len + (end - lhs.end); + size_t const rhs_len = (rhs.start - start) + rhs.sequence.len + (end - rhs.end); + + char* lhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, NULL, 0, lhs_len); + if (lhs_obs == NULL) { - fprintf(stderr, "there was no overlap?!\n"); - relation = GVA_IS_CONTAINED; - } - else + return -1; + } // if + memcpy(lhs_obs, reference.str + start, lhs.start - start); + memcpy(lhs_obs + lhs.start - start, lhs.sequence.str, lhs.sequence.len); + memcpy(lhs_obs + lhs.start - start + lhs.sequence.len, reference.str + lhs.end, end - lhs.end); + + char* rhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, NULL, 0, rhs_len); + if (rhs_obs == NULL) + { + lhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, lhs_obs, lhs_len, 0); + return -1; + } // if + memcpy(rhs_obs, reference.str + start, rhs.start - start); + memcpy(rhs_obs + rhs.start - start, rhs.sequence.str, rhs.sequence.len); + memcpy(rhs_obs + rhs.start - start + rhs.sequence.len, reference.str + rhs.end, end - rhs.end); + + size_t const op_distance = gva_edit_distance(gva_std_allocator, lhs_len, lhs_obs, rhs_len, rhs_obs); + fprintf(stderr, "op_distance: %zu\n", op_distance); + rhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, rhs_obs, rhs_len, 0); + lhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, lhs_obs, lhs_len, 0); + + if (tree.nodes[node_idx].distance - op_distance != slice_dist) { - fprintf(stderr, "Not seen all parts\n"); - fprintf(stderr, "deze is_contained?!\n"); - relation = GVA_OVERLAP; + node_parts_table[i].relation = GVA_OVERLAP; + fprintf(stderr, "OVERLAP!!\n"); } + + // GVA_Relation relation = compare_from_index(reference, db_var, tree.nodes[node_idx].distance, query_part, query_dist); + // fprintf(stderr, " db candidate node_idx: %d (dist: %d): " GVA_VARIANT_FMT " %s\n", node_idx, tree.nodes[node_idx].distance, GVA_VARIANT_PRINT(db_var), GVA_RELATION_LABELS[relation]); } - // } // if - // else - // { - // fprintf(stderr, "deze contains?!\n"); - // relation = GVA_CONTAINS; - // } // else - // } // if - // // else if (table[i].included == alleles[allele].distance) - // // else if (table[i].included == graph.distance) - // else if (table[i].included == graph.distance && graph.distance > alleles[allele].distance) + // for (size_t j = 0; j < array_length(node_parts_table[i].parts); ++j) // { - // relation = GVA_IS_CONTAINED; - // fprintf(stderr, "deze is_contained?!\n"); - // } // if - else if (table[i].included > 0) - { - fprintf(stderr, "deze overlap?!\n"); - relation = GVA_OVERLAP; - } + // fprintf(stderr, " local part: %d\n", node_parts_table[i].parts[j]); + // } + } // for + node_parts_table = HASH_TABLE_DESTROY(gva_std_allocator, node_parts_table); - if (relation == GVA_EQUIVALENT || relation == GVA_DISJOINT) - { + for (size_t i = 0; i < array_header(in_ex_table)->capacity; ++i) { + size_t node_idx = in_ex_table[i].gva_key; + if (node_idx == (uint32_t) - 1) { continue; } + fprintf(stderr, "allele_idx: %d incl: %d excl: %d\n", in_ex_table[i].gva_key, in_ex_table[i].included, in_ex_table[i].excluded); + } + in_ex_table = HASH_TABLE_DESTROY(gva_std_allocator, in_ex_table); - // fprintf(stderr, "distances: %u %u\n", alleles[allele].distance, graph.distance); - - fprintf(stdout, "%zu " GVA_VARIANT_FMT_SPDI " %zu " GVA_VARIANT_FMT_SPDI " %s\n", - alleles[allele].data, GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, alleles[allele].supremal), - id, GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, graph.supremal), - GVA_RELATION_LABELS[relation]); - // fprintf(stdout, "%zu " GVA_VARIANT_FMT_SPDI " %zu " GVA_VARIANT_FMT_SPDI " %s\n", - // id, GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, graph.supremal), - // alleles[allele].data, GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, alleles[allele].supremal), - // GVA_RELATION_LABELS[relation]); + gva_string_destroy(gva_std_allocator, query_graph.observed); + gva_lcs_graph_destroy(gva_std_allocator, query_graph); - } // for - table = HASH_TABLE_DESTROY(gva_std_allocator, table); - - gva_string_destroy(gva_std_allocator, graph.observed); - gva_lcs_graph_destroy(gva_std_allocator, graph); - - } // while + fprintf(stderr, "\n"); + line_count += 1; + } // while fgets fclose(stream); alleles = ARRAY_DESTROY(gva_std_allocator, alleles); From 29e07a55d10c51ad87900506b153e467a17bc73a Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 30 Sep 2025 08:45:24 +0200 Subject: [PATCH 360/704] Strdup --- include/string.h | 4 ++++ src/string.c | 7 +++++++ 2 files changed, 11 insertions(+) diff --git a/include/string.h b/include/string.h index 9cb65fa..d839d1b 100644 --- a/include/string.h +++ b/include/string.h @@ -27,4 +27,8 @@ gva_string_concat(GVA_Allocator const allocator, GVA_String lhs, GVA_String const rhs); +GVA_String +gva_string_dup(GVA_Allocator const allocator, GVA_String const self); + + #endif diff --git a/src/string.c b/src/string.c index c2b8629..951c3c9 100644 --- a/src/string.c +++ b/src/string.c @@ -27,3 +27,10 @@ gva_string_concat(GVA_Allocator const allocator, GVA_String lhs, GVA_String cons lhs.len = len; return lhs; } // gva_string_concat + + +inline GVA_String +gva_string_dup(GVA_Allocator const allocator, GVA_String const self) +{ + return gva_string_concat(allocator, (GVA_String) {0, NULL}, self); +} // gva_string_dup From f8241dc9b0ea738852a29171224ee0403b7925f9 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 30 Sep 2025 08:46:00 +0200 Subject: [PATCH 361/704] WIP: reading phased data --- src/main.c | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 117 insertions(+), 7 deletions(-) diff --git a/src/main.c b/src/main.c index 31a8355..ffb2232 100644 --- a/src/main.c +++ b/src/main.c @@ -309,17 +309,19 @@ extract(int const argc, char* argv[static argc + 1]) GVA_LCS_Graph graph = gva_lcs_graph_init(gva_std_allocator, len_ref, reference, len_obs, observed, 0); - lcs_graph_raw(stderr, graph); + //lcs_graph_raw(stderr, graph); lcs_graph_dot(stderr, graph); - lcs_graph_json(stdout, graph); - lcs_graph_svg(stderr, graph); + //lcs_graph_json(stdout, graph); + //lcs_graph_svg(stderr, graph); + /* GVA_Variant* canonical = gva_canonical(gva_std_allocator, graph); for (size_t i = 0; i < array_length(canonical); ++i) { fprintf(stderr, GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(canonical[i])); } // for canonical = ARRAY_DESTROY(gva_std_allocator, canonical); + */ gva_lcs_graph_destroy(gva_std_allocator, graph); @@ -728,7 +730,7 @@ all(int argc, char* argv[static argc + 1]) &rhs); gva_uint rhs_dist = rhs_graph.local_supremal[i + 1].edges; - fprintf(stderr, GVA_VARIANT_FMT " %u\n", GVA_VARIANT_PRINT(rhs), rhs_graph.local_supremal[i + 1].edges); + fprintf(stderr, GVA_VARIANT_FMT " %u\n", GVA_VARIANT_PRINT(rhs), rhs_dist); gva_uint* results = gva_stabbing_index_intersect(gva_std_allocator, index, rhs.start, rhs.end); @@ -855,10 +857,117 @@ compare(int argc, char* argv[static argc + 1]) } // compare +static inline size_t +prefix_length(size_t const len_lhs, char const lhs[static restrict len_lhs], + size_t const len_rhs, char const rhs[static restrict len_rhs]) +{ + size_t idx = 0; + while (idx < len_lhs && idx < len_rhs && lhs[idx] == rhs[idx]) + { + idx += 1; + } // while + return idx; +} // prefix_length + + +static inline size_t +suffix_length(size_t const len_lhs, char const lhs[static restrict len_lhs], + size_t const len_rhs, char const rhs[static restrict len_rhs]) +{ + size_t idx_lhs = len_lhs; + size_t idx_rhs = len_rhs; + while (idx_lhs > 0 && idx_rhs > 0 && lhs[idx_lhs - 1] == rhs[idx_rhs - 1]) + { + idx_lhs -= 1; + idx_rhs -= 1; + } // while + return len_lhs - idx_lhs; +} // suffix_length + + +static inline GVA_Variant +prefix_trimmed(size_t const len_ref, char const reference[static len_ref], + GVA_Variant const variant) +{ + size_t const len = prefix_length((variant.end - variant.start), reference + variant.start, variant.sequence.len, variant.sequence.str); + return (GVA_Variant) {variant.start + len, variant.end, {variant.sequence.len - len, variant.sequence.str + len}}; +} // prefix_trimmed + + +static inline GVA_Variant +suffix_trimmed(size_t const len_ref, char const reference[static len_ref], + GVA_Variant const variant) +{ + size_t const len = suffix_length((variant.end - variant.start), reference + variant.start, variant.sequence.len, variant.sequence.str); + return (GVA_Variant) {variant.start, variant.end - len, {variant.sequence.len - len, variant.sequence.str}}; +} // suffix_trimmed + + int main(int argc, char* argv[static argc + 1]) { /* + errno = 0; + FILE* stream = fopen(argv[1], "r"); + if (stream == NULL) + { + fprintf(stderr, "error: %s\n", strerror(errno)); + return EXIT_FAILURE; + } // if + + GVA_String reference = {0, NULL}; + reference = gva_fasta_sequence(gva_std_allocator, stream); + fclose(stream); + + GVA_Variant variants[2]; + size_t count = 0; + static char line[LINE_SIZE] = {0}; + while (fgets(line, sizeof(line), stdin) != NULL) + { + int const len = (char*) memchr(line, '\n', LINE_SIZE) - line; + if (gva_parse_spdi(len, line, &variants[count > 0]) == 0) + { + fprintf(stderr, "error: SPDI parsing failed at line %zu: %s", count + 1, line); + continue; + } // if + + variants[count > 0] = prefix_trimmed(reference.len, reference.str, variants[count > 0]); + + for (size_t i = 0; i <= (count > 0); ++i) + { + fprintf(stderr, GVA_VARIANT_FMT " ", GVA_VARIANT_PRINT(variants[i])); + } // for + fprintf(stderr, "\n"); + + GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1 + (count > 0), variants); + GVA_Variant local; + for (size_t i = 0; i < array_length(graph.local_supremal) - 1; ++i) + { + gva_edges(graph.observed.str, + graph.local_supremal[i], graph.local_supremal[i + 1], + i == 0, i == array_length(graph.local_supremal) - 2, + &local); + if (i < array_length(graph.local_supremal) - 2) + { + fprintf(stderr, "OUT: " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(local)); + } // if + } // for + gva_lcs_graph_destroy(gva_std_allocator, graph); + + if (count > 0) + { + gva_string_destroy(gva_std_allocator, variants[0].sequence); + } // if + variants[0] = (GVA_Variant) {local.start, local.end, gva_string_dup(gva_std_allocator, local.sequence)}; + variants[0] = suffix_trimmed(reference.len, reference.str, variants[0]); + + count += 1; + } // while + + gva_string_destroy(gva_std_allocator, reference); + return EXIT_SUCCESS; + + struct IN_EX { HASH_TABLE_KEY; @@ -876,7 +985,7 @@ main(int argc, char* argv[static argc + 1]) table = HASH_TABLE_DESTROY(gva_std_allocator, table); return EXIT_SUCCESS; -*/ + errno = 0; FILE* stream = fopen(argv[1], "r"); @@ -1080,12 +1189,13 @@ main(int argc, char* argv[static argc + 1]) gva_string_destroy(gva_std_allocator, reference); return EXIT_SUCCESS; - - //return extract(argc, argv); +*/ + return extract(argc, argv); // all //return all(argc, argv); // compare // return compare(argc, argv); + } // main From 78c74a5e22119d29488902ec18d27e4a94040298 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 30 Sep 2025 09:02:51 +0200 Subject: [PATCH 362/704] Removed stray comment close --- src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.c b/src/main.c index 968a6f4..0d6b308 100644 --- a/src/main.c +++ b/src/main.c @@ -1235,7 +1235,7 @@ main(int argc, char* argv[static argc + 1]) gva_string_destroy(gva_std_allocator, reference); return EXIT_SUCCESS; -*/ + return extract(argc, argv); // all From 5861f7058d512d376c3ddbfb447994b77d34aaaa Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Wed, 1 Oct 2025 23:09:27 +0200 Subject: [PATCH 363/704] WIP. First 100k dbsnp entries are okay! --- src/main.c | 504 +++++++++++++++++++++++++++++++++++------------------ 1 file changed, 338 insertions(+), 166 deletions(-) diff --git a/src/main.c b/src/main.c index 6fd4c69..0cbb31c 100644 --- a/src/main.c +++ b/src/main.c @@ -859,6 +859,114 @@ compare(int argc, char* argv[static argc + 1]) } // compare +size_t +variants_distance(GVA_Allocator const allocator, size_t const len_ref, char const reference[static len_ref], GVA_Variant const lhs, GVA_Variant const rhs) +{ + size_t const start = MIN(lhs.start, rhs.start); + size_t const end = MAX(lhs.end, rhs.end); + + size_t const lhs_len = (lhs.start - start) + lhs.sequence.len + (end - lhs.end); + size_t const rhs_len = (rhs.start - start) + rhs.sequence.len + (end - rhs.end); + + char* lhs_obs = allocator.allocate(allocator.context, NULL, 0, lhs_len); + if (lhs_obs == NULL) + { + return -1; + } // if + memcpy(lhs_obs, reference + start, lhs.start - start); + memcpy(lhs_obs + lhs.start - start, lhs.sequence.str, lhs.sequence.len); + memcpy(lhs_obs + lhs.start - start + lhs.sequence.len, reference + lhs.end, end - lhs.end); + + char* rhs_obs = allocator.allocate(allocator.context, NULL, 0, rhs_len); + if (rhs_obs == NULL) + { + lhs_obs = allocator.allocate(allocator.context, lhs_obs, lhs_len, 0); + return -1; + } // if + memcpy(rhs_obs, reference + start, rhs.start - start); + memcpy(rhs_obs + rhs.start - start, rhs.sequence.str, rhs.sequence.len); + memcpy(rhs_obs + rhs.start - start + rhs.sequence.len, reference + rhs.end, end - rhs.end); + + size_t const distance = gva_edit_distance(allocator, lhs_len, lhs_obs, rhs_len, rhs_obs); + rhs_obs = allocator.allocate(allocator.context, rhs_obs, rhs_len, 0); + lhs_obs = allocator.allocate(allocator.context, lhs_obs, lhs_len, 0); + + return distance; +} + + +GVA_Variant +construct_variant(GVA_Allocator const allocator, size_t const len_ref, char const reference[static len_ref], Interval_Tree const tree, Trie const trie, gva_uint* const nodes) +{ + size_t const n = array_length(nodes); + GVA_Variant* variants = allocator.allocate(allocator.context, NULL, 0, n * sizeof(*variants)); + for (size_t i = 0; i < n; ++i) + { + variants[i] = (GVA_Variant) { + tree.nodes[nodes[i]].start, + tree.nodes[nodes[i]].end, + trie_string(trie, tree.nodes[nodes[i]].inserted) + }; + } + + GVA_Variant lhs = { + tree.nodes[nodes[0]].start, + tree.nodes[nodes[n - 1]].end, + {0, NULL} + }; + lhs.sequence = gva_string_concat(allocator, lhs.sequence, variants[0].sequence); + for (size_t i = 1; i < n; ++i) + { + lhs.sequence = gva_string_concat(allocator, lhs.sequence, (GVA_String) {variants[i].start - variants[i - 1].end, reference + variants[i - 1].end}); + lhs.sequence = gva_string_concat(allocator, lhs.sequence, variants[i].sequence); + } // for + fprintf(stderr, GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(lhs)); + + // deallocate + variants = allocator.allocate(allocator.context, variants, n * sizeof(*variants), 0); + + return lhs; +} + +GVA_Relation +multiple_is_contained(GVA_Allocator const allocator, size_t const len_ref, char const reference[static len_ref], GVA_LCS_Graph const graph, size_t const part_idx, Interval_Tree const tree, Trie const trie, gva_uint* const nodes, size_t* const slice_dist) +{ + size_t const n = array_length(nodes); + *slice_dist = 0; + for (size_t i = 0; i < n; ++i) + { + *slice_dist += tree.nodes[nodes[i]].distance; + } // for + + size_t const part_dist = graph.local_supremal[part_idx + 1].edges; + if (*slice_dist >= part_dist) + { + fprintf(stderr, "Can conclude based on distance only\n"); + return GVA_OVERLAP; + } + + // construct allele + GVA_Variant rhs; + gva_edges(graph.observed.str, + graph.local_supremal[part_idx], graph.local_supremal[part_idx + 1], + part_idx == 0, part_idx == array_length(graph.local_supremal) - 2, + &rhs); + fprintf(stderr, GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(rhs)); + + GVA_Variant const lhs = construct_variant(allocator, len_ref, reference, tree, trie, nodes); + + size_t const op_distance = variants_distance(allocator, len_ref, reference, rhs, lhs); + gva_string_destroy(allocator, lhs.sequence); + + fprintf(stderr, "part_dist: %zu op_distance: %zu slice_dist: %zu\n", part_dist, op_distance, *slice_dist); + if (part_dist - op_distance != *slice_dist) + { + return GVA_OVERLAP; + } + return GVA_IS_CONTAINED; +} + + int main(int argc, char* argv[static argc + 1]) { @@ -887,9 +995,10 @@ main(int argc, char* argv[static argc + 1]) struct Allele { size_t data; + char* spdi; gva_uint join_start; // offset into node_allele_join gva_uint distance; - }* alleles = NULL; + }* db_alleles = NULL; size_t line_count = 0; static char line[LINE_SIZE] = {0}; @@ -907,9 +1016,17 @@ main(int argc, char* argv[static argc + 1]) } // if GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &variant); + size_t const spdi_len = snprintf(NULL, 0, GVA_VARIANT_FMT_SPDI, GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, graph.supremal)) + 1; + char* const spdi = malloc(spdi_len); + if (NULL == spdi) { + (void) fprintf(stderr, "spdi malloc() failed\n"); + return EXIT_FAILURE; + } + snprintf(spdi, spdi_len, GVA_VARIANT_FMT_SPDI, GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, graph.supremal)); + gva_uint const allele_idx = ARRAY_APPEND( - gva_std_allocator, alleles, - ((struct Allele) {rsid, array_length(node_allele_join), graph.distance}) + gva_std_allocator, db_alleles, + ((struct Allele) {rsid, spdi, array_length(node_allele_join), graph.distance}) ) - 1; fprintf(stderr, "input allele %zu: " GVA_VARIANT_FMT " stored at: %d\n", rsid, GVA_VARIANT_PRINT(variant), allele_idx); @@ -944,10 +1061,10 @@ main(int argc, char* argv[static argc + 1]) fprintf(stderr, "tree nodes: %zu\n", array_length(tree.nodes)); fprintf(stderr, "trie nodes: %zu\n", array_length(trie.nodes)); - fprintf(stderr, "#alleles: %zu\n", array_length(alleles)); + fprintf(stderr, "#db_alleles: %zu\n", array_length(db_alleles)); fprintf(stderr, "#join: %zu\n", array_length(node_allele_join)); - if (alleles == NULL || node_allele_join == NULL) + if (db_alleles == NULL || node_allele_join == NULL) { return -1; } // if @@ -976,40 +1093,30 @@ main(int argc, char* argv[static argc + 1]) } // if fprintf(stderr, "query allele %zu: " GVA_VARIANT_FMT "\n", query_id, GVA_VARIANT_PRINT(query_var)); - // Link query to alleles - struct IN_EX - { - HASH_TABLE_KEY; - gva_uint included; - gva_uint excluded; - // // gva_uint hits; - // // bool overlap; - // // bool disjoint; - // // bool contains; - // // bool is_contained; - // // bool equivalent; - }* in_ex_table = hash_table_init(gva_std_allocator, 1024, sizeof(*in_ex_table)); - // Join nodes in the index to parts in the query struct NODE_PARTS { HASH_TABLE_KEY; - gva_uint relation; + GVA_Relation relation; gva_uint start; gva_uint end; + gva_uint part_idx; + gva_uint included; }* node_parts_table = hash_table_init(gva_std_allocator, 1024, sizeof(*node_parts_table)); // query graph GVA_LCS_Graph query_graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &query_var); + + size_t const spdi_len = snprintf(NULL, 0, GVA_VARIANT_FMT_SPDI, GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, query_graph.supremal)) + 1; + char* const query_spdi = malloc(spdi_len); + if (NULL == query_spdi) { + (void) fprintf(stderr, "spdi malloc() failed\n"); + return EXIT_FAILURE; + } + snprintf(query_spdi, spdi_len, GVA_VARIANT_FMT_SPDI, GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, query_graph.supremal)); + for (size_t part_idx = 0; part_idx < array_length(query_graph.local_supremal) - 1; ++part_idx) { - // Join query part with nodes in the same index allele - struct ALLELE_NODES - { - HASH_TABLE_KEY; - gva_uint* nodes; - }* allele_nodes_table = hash_table_init(gva_std_allocator, 1024, sizeof(*allele_nodes_table)); - // query local supremal part GVA_Variant query_part; gva_edges(query_graph.observed.str, @@ -1029,151 +1136,94 @@ main(int argc, char* argv[static argc + 1]) GVA_Relation relation = compare_from_index(reference, db_var, tree.nodes[node_idx].distance, query_part, query_dist); fprintf(stderr, " db candidate node_idx: %d (dist: %d): " GVA_VARIANT_FMT " %s\n", node_idx, tree.nodes[node_idx].distance, GVA_VARIANT_PRINT(db_var), GVA_RELATION_LABELS[relation]); + if (relation == GVA_DISJOINT) + { + continue; + } // link nodes to parts size_t hash_idx = HASH_TABLE_INDEX(node_parts_table, node_idx); + // fprintf(stderr, "initial hash_idx: %zu\n", hash_idx); if (node_parts_table[hash_idx].gva_key != node_idx) { - HASH_TABLE_SET(gva_std_allocator, node_parts_table, node_idx, ((struct NODE_PARTS) {node_idx, GVA_NULL, -1, -1})); + // TODO: set correct initial relation + HASH_TABLE_SET(gva_std_allocator, node_parts_table, node_idx, ((struct NODE_PARTS) {node_idx, GVA_DISJOINT, -1, -1, -1, 0})); hash_idx = HASH_TABLE_INDEX(node_parts_table, node_idx); + // fprintf(stderr, "inside if hash_idx: %zu\n", hash_idx); } // if - if (relation == GVA_DISJOINT) - { - if (node_parts_table[hash_idx].relation == GVA_NULL || - node_parts_table[hash_idx].relation == GVA_DISJOINT) - { - node_parts_table[hash_idx].relation = GVA_DISJOINT; - } - else - { - node_parts_table[hash_idx].relation = GVA_OVERLAP; - } - } - else if (relation == GVA_EQUIVALENT) + + node_parts_table[hash_idx].part_idx = part_idx; + + if (relation == GVA_EQUIVALENT) { node_parts_table[hash_idx].relation = GVA_EQUIVALENT; - } + node_parts_table[hash_idx].included = tree.nodes[node_idx].distance; + } // if else if (relation == GVA_OVERLAP) { node_parts_table[hash_idx].relation = GVA_OVERLAP; - } + node_parts_table[hash_idx].included = 1; + } // if else if (relation == GVA_IS_CONTAINED) { node_parts_table[hash_idx].relation = GVA_IS_CONTAINED; - } + node_parts_table[hash_idx].included = tree.nodes[node_idx].distance; + } // if else if (relation == GVA_CONTAINS) { - if (node_parts_table[hash_idx].relation == GVA_NULL) + if (node_parts_table[hash_idx].relation == GVA_DISJOINT) { node_parts_table[hash_idx].relation = GVA_CONTAINS; node_parts_table[hash_idx].start = part_idx; - node_parts_table[hash_idx].end = part_idx + 1; - } - else if (node_parts_table[hash_idx].relation == GVA_CONTAINS) - { - node_parts_table[hash_idx].end = part_idx + 1; - } - else - { - node_parts_table[hash_idx].relation = GVA_OVERLAP; - } - } - - for (gva_uint join_idx = tree.nodes[node_idx].alleles; join_idx != GVA_NULL; join_idx = node_allele_join[join_idx].next) - { - gva_uint allele_idx = node_allele_join[join_idx].allele; - fprintf(stderr, " join_idx: %d allele_idx: %d rs_id: %zu\n", join_idx, allele_idx, alleles[allele_idx].data); - - // link all alleles impacted for this node - size_t hash_idx = HASH_TABLE_INDEX(allele_nodes_table, allele_idx); - if (allele_nodes_table[hash_idx].gva_key != allele_idx) - { - HASH_TABLE_SET(gva_std_allocator, allele_nodes_table, allele_idx, ((struct ALLELE_NODES) {allele_idx, NULL})); - hash_idx = HASH_TABLE_INDEX(allele_nodes_table, allele_idx); - } // if - ARRAY_APPEND(gva_std_allocator, allele_nodes_table[hash_idx].nodes, node_idx); - - // link query to alleles - hash_idx = HASH_TABLE_INDEX(in_ex_table, allele_idx); - if (in_ex_table[hash_idx].gva_key != allele_idx) - { - HASH_TABLE_SET(gva_std_allocator, in_ex_table, allele_idx, ((struct IN_EX) {allele_idx, 0, 0})); - hash_idx = HASH_TABLE_INDEX(in_ex_table, allele_idx); - } // if - - if (relation == GVA_EQUIVALENT || relation == GVA_CONTAINS) - { - in_ex_table[hash_idx].included += query_dist; - } - else if (relation == GVA_IS_CONTAINED) - { - in_ex_table[hash_idx].included += tree.nodes[node_idx].distance; - in_ex_table[hash_idx].excluded += query_dist - tree.nodes[node_idx].distance; - } - else if (relation == GVA_OVERLAP) - { - in_ex_table[hash_idx].included += 1; - in_ex_table[hash_idx].excluded += 1; - } - else // (relation == GVA_DISJOINT) - { - in_ex_table[hash_idx].excluded += query_dist; + node_parts_table[hash_idx].included = query_dist; } - - fprintf(stderr, "\n"); - } // for alleles - + node_parts_table[hash_idx].end = part_idx + 1; + } // if } // for every candidate - for (size_t x = 0; x < array_header(allele_nodes_table)->capacity; ++x) - { - if (allele_nodes_table[x].gva_key == (uint32_t) - 1) - { - continue; - } - fprintf(stderr, " allele_idx: %d\n", allele_nodes_table[x].gva_key); - for (size_t y = 0; y < array_length(allele_nodes_table[x].nodes); ++y) - { - fprintf(stderr, " node: %d\n", allele_nodes_table[x].nodes[y]); - } - } - - allele_nodes_table = HASH_TABLE_DESTROY(gva_std_allocator, allele_nodes_table); candidates = ARRAY_DESTROY(gva_std_allocator, candidates); fprintf(stderr, "\n"); } // for query allele parts - // TODO: dont store disjoint and accept an extra distance calculation now and then?! - + // fix containment for multiple parts in single node for (size_t i = 0; i < array_header(node_parts_table)->capacity; ++i) { size_t node_idx = node_parts_table[i].gva_key; if (node_idx == (uint32_t) - 1) { continue; - } - fprintf(stderr, " node_idx: %zu " GVA_VARIANT_FMT " %s (%d, %d)\n", node_idx, + } // if + fprintf(stderr, " node_idx: %zu " GVA_VARIANT_FMT " %s (%d, %d, %d) in:%d\n", node_idx, GVA_VARIANT_PRINT(((GVA_Variant) { tree.nodes[node_idx].start, tree.nodes[node_idx].end, trie_string(trie, tree.nodes[node_idx].inserted) })), GVA_RELATION_LABELS[node_parts_table[i].relation], - node_parts_table[i].start, node_parts_table[i].end); + node_parts_table[i].start, node_parts_table[i].end, node_parts_table[i].part_idx, + node_parts_table[i].included); if (node_parts_table[i].relation == GVA_CONTAINS && node_parts_table[i].end - node_parts_table[i].start > 1) { - fprintf(stderr, "Perform extra comparison\n"); + fprintf(stderr, " Perform extra comparison\n"); size_t slice_dist = 0; for (size_t j = node_parts_table[i].start; j < node_parts_table[i].end; ++j) { slice_dist += query_graph.local_supremal[j + 1].edges; - } - fprintf(stderr, "distances: %zu %u\n", slice_dist, tree.nodes[node_idx].distance); + } // for + fprintf(stderr, " Distances: %zu %u\n", slice_dist, tree.nodes[node_idx].distance); if (slice_dist >= tree.nodes[node_idx].distance) { node_parts_table[i].relation = GVA_OVERLAP; - fprintf(stderr, "NOT REACHED?!\n"); + node_parts_table[i].included = 1; + fprintf(stderr, " REPAIRED DISTANCE node_idx: %zu " GVA_VARIANT_FMT " %s (%d, %d, %d) in:%d\n", node_idx, + GVA_VARIANT_PRINT(((GVA_Variant) { + tree.nodes[node_idx].start, tree.nodes[node_idx].end, + trie_string(trie, tree.nodes[node_idx].inserted) + })), + GVA_RELATION_LABELS[node_parts_table[i].relation], + node_parts_table[i].start, node_parts_table[i].end, node_parts_table[i].part_idx, + node_parts_table[i].included); continue; - } + } // if GVA_Variant rhs; gva_edges(query_graph.observed.str, @@ -1188,60 +1238,178 @@ main(int argc, char* argv[static argc + 1]) tree.nodes[node_idx].end, trie_string(trie, tree.nodes[node_idx].inserted)}; - size_t const start = MIN(lhs.start, rhs.start); - size_t const end = MAX(lhs.end, rhs.end); + size_t const op_distance = variants_distance(gva_std_allocator, reference.len, reference.str, lhs, rhs); + fprintf(stderr, "op_distance: %zu\n", op_distance); - size_t const lhs_len = (lhs.start - start) + lhs.sequence.len + (end - lhs.end); - size_t const rhs_len = (rhs.start - start) + rhs.sequence.len + (end - rhs.end); + node_parts_table[i].included = slice_dist; - char* lhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, NULL, 0, lhs_len); - if (lhs_obs == NULL) + if (tree.nodes[node_idx].distance - op_distance != slice_dist) { - return -1; + node_parts_table[i].relation = GVA_OVERLAP; + node_parts_table[i].included = 1; + fprintf(stderr, "OVERLAP!!\n"); } // if - memcpy(lhs_obs, reference.str + start, lhs.start - start); - memcpy(lhs_obs + lhs.start - start, lhs.sequence.str, lhs.sequence.len); - memcpy(lhs_obs + lhs.start - start + lhs.sequence.len, reference.str + lhs.end, end - lhs.end); - char* rhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, NULL, 0, rhs_len); - if (rhs_obs == NULL) + fprintf(stderr, " REPAIRED node_idx: %zu " GVA_VARIANT_FMT " %s (%d, %d, %d) in:%d\n", node_idx, + GVA_VARIANT_PRINT(((GVA_Variant) { + tree.nodes[node_idx].start, tree.nodes[node_idx].end, + trie_string(trie, tree.nodes[node_idx].inserted) + })), + GVA_RELATION_LABELS[node_parts_table[i].relation], + node_parts_table[i].start, node_parts_table[i].end, node_parts_table[i].part_idx, + node_parts_table[i].included); + + } // if + } // for node_parts_table + + // build result vector + fprintf(stderr, "Loop over all alleles:\n"); + for (size_t allele_idx = 0; allele_idx < array_length(db_alleles); ++allele_idx) + { + GVA_Relation relation = GVA_DISJOINT; + size_t included = 0; + + gva_uint* is_contained_nodes = NULL; + gva_uint is_contained_part_idx = -1; + for (size_t join_idx = db_alleles[allele_idx].join_start; node_allele_join[join_idx].allele == allele_idx; ++join_idx) + { + size_t hash_idx = HASH_TABLE_INDEX(node_parts_table, node_allele_join[join_idx].node); + if (node_allele_join[join_idx].node != node_parts_table[hash_idx].gva_key) { - lhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, lhs_obs, lhs_len, 0); - return -1; + continue; } // if - memcpy(rhs_obs, reference.str + start, rhs.start - start); - memcpy(rhs_obs + rhs.start - start, rhs.sequence.str, rhs.sequence.len); - memcpy(rhs_obs + rhs.start - start + rhs.sequence.len, reference.str + rhs.end, end - rhs.end); - - size_t const op_distance = gva_edit_distance(gva_std_allocator, lhs_len, lhs_obs, rhs_len, rhs_obs); - fprintf(stderr, "op_distance: %zu\n", op_distance); - rhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, rhs_obs, rhs_len, 0); - lhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, lhs_obs, lhs_len, 0); + size_t part_idx = node_parts_table[hash_idx].part_idx; + if (node_parts_table[hash_idx].relation == GVA_EQUIVALENT) + { + included += tree.nodes[node_allele_join[join_idx].node].distance; - if (tree.nodes[node_idx].distance - op_distance != slice_dist) + // TODO: need this guard? + // if (relation == GVA_EQUIVALENT || relation == GVA_DISJOINT) + { + relation = GVA_EQUIVALENT; + } + } // if + else if (node_parts_table[hash_idx].relation == GVA_CONTAINS) { - node_parts_table[i].relation = GVA_OVERLAP; - fprintf(stderr, "OVERLAP!!\n"); + included += query_graph.local_supremal[part_idx + 1].edges; + + if (relation == GVA_IS_CONTAINED) + { + // included = 1; can it be an overestimate ?!? + relation = GVA_OVERLAP; + break; + } + relation = GVA_CONTAINS; } + else if (node_parts_table[hash_idx].relation == GVA_IS_CONTAINED) + { + fprintf(stderr, "here %s\n", GVA_RELATION_LABELS[relation]); + if (relation == GVA_CONTAINS) + { + included += tree.nodes[node_allele_join[join_idx].node].distance; + // included = 1; ??? + relation = GVA_OVERLAP; + break; + } // if - // GVA_Relation relation = compare_from_index(reference, db_var, tree.nodes[node_idx].distance, query_part, query_dist); - // fprintf(stderr, " db candidate node_idx: %d (dist: %d): " GVA_VARIANT_FMT " %s\n", node_idx, tree.nodes[node_idx].distance, GVA_VARIANT_PRINT(db_var), GVA_RELATION_LABELS[relation]); - } - // for (size_t j = 0; j < array_length(node_parts_table[i].parts); ++j) - // { - // fprintf(stderr, " local part: %d\n", node_parts_table[i].parts[j]); - // } - } // for - node_parts_table = HASH_TABLE_DESTROY(gva_std_allocator, node_parts_table); + if (part_idx != is_contained_part_idx) + { + fprintf(stderr, "here2 %s\n", GVA_RELATION_LABELS[relation]); + + // close old window + if (array_length(is_contained_nodes) > 1) + { + fprintf(stderr, "Found multiple is_containeds for the same part\n"); + size_t slice_dist = 0; + relation = multiple_is_contained(gva_std_allocator, reference.len, reference.str, query_graph, part_idx, tree, trie, is_contained_nodes, &slice_dist); + if (relation == GVA_OVERLAP) + { + fprintf(stderr, "overlap shortcut in loop\n"); + included = 1; + break; + } // if + included += slice_dist; + } // if + + // open new window + is_contained_part_idx = part_idx; + is_contained_nodes = ARRAY_DESTROY(gva_std_allocator, is_contained_nodes); + } // if - for (size_t i = 0; i < array_header(in_ex_table)->capacity; ++i) { - size_t node_idx = in_ex_table[i].gva_key; - if (node_idx == (uint32_t) - 1) { - continue; + ARRAY_APPEND(gva_std_allocator, is_contained_nodes, node_allele_join[join_idx].node); + relation = GVA_IS_CONTAINED; + } // if + else if (node_parts_table[hash_idx].relation == GVA_OVERLAP) + { + fprintf(stderr, "this overlap is reached\n"); + included = 1; + relation = GVA_OVERLAP; + break; + } // if + + } // for allele nodes + + // close old window + size_t const n = array_length(is_contained_nodes); + if (relation == GVA_IS_CONTAINED && n == 1) + { + fprintf(stderr, "found single is_contained\n"); + included += tree.nodes[is_contained_nodes[0]].distance; } - fprintf(stderr, "allele_idx: %d incl: %d excl: %d\n", in_ex_table[i].gva_key, in_ex_table[i].included, in_ex_table[i].excluded); - } - in_ex_table = HASH_TABLE_DESTROY(gva_std_allocator, in_ex_table); + else if (relation == GVA_IS_CONTAINED && n > 1) + { + fprintf(stderr, "Found multiple is_containeds for the same part at the end\n"); + size_t slice_dist = 0; + relation = multiple_is_contained(gva_std_allocator, reference.len, reference.str, query_graph, is_contained_part_idx, tree, trie, is_contained_nodes, &slice_dist); + if (relation == GVA_OVERLAP) + { + included = 1; + } // if + else + { + included += slice_dist; + } // else + + } // if is_contained repair + is_contained_nodes = ARRAY_DESTROY(gva_std_allocator, is_contained_nodes); + + if (included > 0) + { + fprintf(stderr, "allele dist: %u query dist: %u\n", db_alleles[allele_idx].distance, query_graph.distance); + + size_t const allele_excluded = db_alleles[allele_idx].distance - included; + size_t const query_excluded = query_graph.distance - included; + + if (allele_excluded > 0 && query_excluded > 0) + { + relation = GVA_OVERLAP; + } + else if (allele_excluded > 0) + { + relation = GVA_CONTAINS; + } + else if (query_excluded > 0) + { + relation = GVA_IS_CONTAINED; + } + fprintf(stderr, "allele_idx: %zu relation: %s in: %zu\n", allele_idx, GVA_RELATION_LABELS[relation], included); + + if (relation != GVA_EQUIVALENT) + { + printf("%zu %s %zu %s %s\n", + db_alleles[allele_idx].data, + db_alleles[allele_idx].spdi, + query_id, + query_spdi, + GVA_RELATION_LABELS[relation]); + } + } // if + } // for all alleles + + + fprintf(stderr, "\n"); + + node_parts_table = HASH_TABLE_DESTROY(gva_std_allocator, node_parts_table); gva_string_destroy(gva_std_allocator, query_graph.observed); gva_lcs_graph_destroy(gva_std_allocator, query_graph); @@ -1251,7 +1419,11 @@ main(int argc, char* argv[static argc + 1]) } // while fgets fclose(stream); - alleles = ARRAY_DESTROY(gva_std_allocator, alleles); + for (size_t allele_idx = 0; allele_idx < array_length(db_alleles); ++allele_idx) + { + free(db_alleles[allele_idx].spdi); + } + db_alleles = ARRAY_DESTROY(gva_std_allocator, db_alleles); node_allele_join = ARRAY_DESTROY(gva_std_allocator, node_allele_join); interval_tree_destroy(gva_std_allocator, &tree); trie_destroy(gva_std_allocator, &trie); From 9baf194e15a2a495bec0bd227b19a59b2ef3d5ca Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Thu, 2 Oct 2025 14:09:40 +0200 Subject: [PATCH 364/704] Fix loop to stop at the end of the list. --- src/main.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main.c b/src/main.c index 0cbb31c..8178e40 100644 --- a/src/main.c +++ b/src/main.c @@ -1271,7 +1271,12 @@ main(int argc, char* argv[static argc + 1]) gva_uint* is_contained_nodes = NULL; gva_uint is_contained_part_idx = -1; - for (size_t join_idx = db_alleles[allele_idx].join_start; node_allele_join[join_idx].allele == allele_idx; ++join_idx) + + // loop over all nodes for this allele + // fprintf(stderr, "Loop over nodes for this allele:\n"); + for (size_t join_idx = db_alleles[allele_idx].join_start; + node_allele_join[join_idx].allele == allele_idx && join_idx < array_length(node_allele_join); + ++join_idx) { size_t hash_idx = HASH_TABLE_INDEX(node_parts_table, node_allele_join[join_idx].node); if (node_allele_join[join_idx].node != node_parts_table[hash_idx].gva_key) From e9aea1810181e93976fb7d3028dbe06be8647da8 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Thu, 2 Oct 2025 14:12:01 +0200 Subject: [PATCH 365/704] Dump tables. --- src/main.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/src/main.c b/src/main.c index 8178e40..bf5984a 100644 --- a/src/main.c +++ b/src/main.c @@ -1262,8 +1262,31 @@ main(int argc, char* argv[static argc + 1]) } // if } // for node_parts_table - // build result vector - fprintf(stderr, "Loop over all alleles:\n"); + // fprintf(stderr, "db_allele table:\n"); + // for (size_t i = 0; i < array_length(db_alleles); ++i) + // { + // fprintf(stderr, "entry: %zu %s %zu %zu\n", + // db_alleles[i].data, + // db_alleles[i].spdi, + // db_alleles[i].join_start, + // db_alleles[i].distance + // ); + // } + // fprintf(stderr, "\n"); + // + // fprintf(stderr, "node_allele_join table:\n"); + // for (size_t i = 0; i < array_length(node_allele_join); ++i) + // { + // fprintf(stderr, "entry: %zu %zu %d\n", + // node_allele_join[i].node, + // node_allele_join[i].allele, + // node_allele_join[i].next + // ); + // } + // fprintf(stderr, "\n"); + + // build result vector for every query + // fprintf(stderr, "Loop over all alleles for every query:\n"); for (size_t allele_idx = 0; allele_idx < array_length(db_alleles); ++allele_idx) { GVA_Relation relation = GVA_DISJOINT; From 09bd44c1a7301a7cbfa94ac4c5fcada45361fdaa Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Thu, 2 Oct 2025 14:20:17 +0200 Subject: [PATCH 366/704] WIP in attempt to fix 1mln^2. But before performance fixes to test that. Does 100k^2 correctly. --- src/main.c | 182 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 104 insertions(+), 78 deletions(-) diff --git a/src/main.c b/src/main.c index bf5984a..ff38355 100644 --- a/src/main.c +++ b/src/main.c @@ -920,7 +920,7 @@ construct_variant(GVA_Allocator const allocator, size_t const len_ref, char cons lhs.sequence = gva_string_concat(allocator, lhs.sequence, (GVA_String) {variants[i].start - variants[i - 1].end, reference + variants[i - 1].end}); lhs.sequence = gva_string_concat(allocator, lhs.sequence, variants[i].sequence); } // for - fprintf(stderr, GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(lhs)); + // fprintf(stderr, GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(lhs)); // deallocate variants = allocator.allocate(allocator.context, variants, n * sizeof(*variants), 0); @@ -941,7 +941,7 @@ multiple_is_contained(GVA_Allocator const allocator, size_t const len_ref, char size_t const part_dist = graph.local_supremal[part_idx + 1].edges; if (*slice_dist >= part_dist) { - fprintf(stderr, "Can conclude based on distance only\n"); + // fprintf(stderr, "Can conclude based on distance only\n"); return GVA_OVERLAP; } @@ -951,14 +951,14 @@ multiple_is_contained(GVA_Allocator const allocator, size_t const len_ref, char graph.local_supremal[part_idx], graph.local_supremal[part_idx + 1], part_idx == 0, part_idx == array_length(graph.local_supremal) - 2, &rhs); - fprintf(stderr, GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(rhs)); + // fprintf(stderr, GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(rhs)); GVA_Variant const lhs = construct_variant(allocator, len_ref, reference, tree, trie, nodes); size_t const op_distance = variants_distance(allocator, len_ref, reference, rhs, lhs); gva_string_destroy(allocator, lhs.sequence); - fprintf(stderr, "part_dist: %zu op_distance: %zu slice_dist: %zu\n", part_dist, op_distance, *slice_dist); + // fprintf(stderr, "part_dist: %zu op_distance: %zu slice_dist: %zu\n", part_dist, op_distance, *slice_dist); if (part_dist - op_distance != *slice_dist) { return GVA_OVERLAP; @@ -1028,7 +1028,7 @@ main(int argc, char* argv[static argc + 1]) gva_std_allocator, db_alleles, ((struct Allele) {rsid, spdi, array_length(node_allele_join), graph.distance}) ) - 1; - fprintf(stderr, "input allele %zu: " GVA_VARIANT_FMT " stored at: %d\n", rsid, GVA_VARIANT_PRINT(variant), allele_idx); + // fprintf(stderr, "input allele %zu: " GVA_VARIANT_FMT " (dist: %d) stored at: %d\n", rsid, GVA_VARIANT_PRINT(variant), graph.distance, allele_idx); for (size_t i = 0; i < array_length(graph.local_supremal) - 1; ++i) { @@ -1043,11 +1043,11 @@ main(int argc, char* argv[static argc + 1]) gva_uint const node_idx = interval_tree_insert(&tree, tmp_idx); if (node_idx != tmp_idx) { - fprintf(stderr, " part %zu already in the tree\n", i); + // fprintf(stderr, " part %zu already in the tree\n", i); array_header(tree.nodes)->length -= 1; // reverse; node already in the tree } // if tree.nodes[node_idx].alleles = ARRAY_APPEND(gva_std_allocator, node_allele_join, ((struct Node_Allele) {node_idx, allele_idx, tree.nodes[node_idx].alleles})) - 1; - fprintf(stderr, " input part %zu (allele %d): " GVA_VARIANT_FMT " stored at: %d\n", i, allele_idx, GVA_VARIANT_PRINT(part), node_idx); + // fprintf(stderr, " input part %zu (allele %d): " GVA_VARIANT_FMT " stored at: %d\n", i, allele_idx, GVA_VARIANT_PRINT(part), node_idx); } // for @@ -1091,7 +1091,7 @@ main(int argc, char* argv[static argc + 1]) fprintf(stderr, "error: SPDI parsing failed at line %zu: %s", line_count + 1, line); continue; } // if - fprintf(stderr, "query allele %zu: " GVA_VARIANT_FMT "\n", query_id, GVA_VARIANT_PRINT(query_var)); + // fprintf(stderr, "query allele %zu: " GVA_VARIANT_FMT "\n", query_id, GVA_VARIANT_PRINT(query_var)); // Join nodes in the index to parts in the query struct NODE_PARTS @@ -1125,7 +1125,7 @@ main(int argc, char* argv[static argc + 1]) &query_part); gva_uint query_dist = query_graph.local_supremal[part_idx + 1].edges; - fprintf(stderr, " query part %zu (dist: %d): " GVA_VARIANT_FMT "\n", part_idx, query_dist, GVA_VARIANT_PRINT(query_part)); + // fprintf(stderr, " query part %zu (dist: %d): " GVA_VARIANT_FMT "\n", part_idx, query_dist, GVA_VARIANT_PRINT(query_part)); // find candidates for this local supremal part gva_uint* candidates = interval_tree_intersection(gva_std_allocator, tree, query_part.start, query_part.end); @@ -1134,7 +1134,7 @@ main(int argc, char* argv[static argc + 1]) GVA_Variant const db_var = {tree.nodes[node_idx].start, tree.nodes[node_idx].end, trie_string(trie, tree.nodes[node_idx].inserted)}; GVA_Relation relation = compare_from_index(reference, db_var, tree.nodes[node_idx].distance, query_part, query_dist); - fprintf(stderr, " db candidate node_idx: %d (dist: %d): " GVA_VARIANT_FMT " %s\n", node_idx, tree.nodes[node_idx].distance, GVA_VARIANT_PRINT(db_var), GVA_RELATION_LABELS[relation]); + // fprintf(stderr, " db candidate node_idx: %d (dist: %d): " GVA_VARIANT_FMT " %s\n", node_idx, tree.nodes[node_idx].distance, GVA_VARIANT_PRINT(db_var), GVA_RELATION_LABELS[relation]); if (relation == GVA_DISJOINT) { @@ -1146,13 +1146,12 @@ main(int argc, char* argv[static argc + 1]) if (node_parts_table[hash_idx].gva_key != node_idx) { // TODO: set correct initial relation - HASH_TABLE_SET(gva_std_allocator, node_parts_table, node_idx, ((struct NODE_PARTS) {node_idx, GVA_DISJOINT, -1, -1, -1, 0})); + HASH_TABLE_SET(gva_std_allocator, node_parts_table, node_idx, + ((struct NODE_PARTS) {node_idx, GVA_DISJOINT, -1, -1, -1, 0})); hash_idx = HASH_TABLE_INDEX(node_parts_table, node_idx); // fprintf(stderr, "inside if hash_idx: %zu\n", hash_idx); } // if - node_parts_table[hash_idx].part_idx = part_idx; - if (relation == GVA_EQUIVALENT) { node_parts_table[hash_idx].relation = GVA_EQUIVALENT; @@ -1165,6 +1164,7 @@ main(int argc, char* argv[static argc + 1]) } // if else if (relation == GVA_IS_CONTAINED) { + node_parts_table[hash_idx].part_idx = part_idx; node_parts_table[hash_idx].relation = GVA_IS_CONTAINED; node_parts_table[hash_idx].included = tree.nodes[node_idx].distance; } // if @@ -1181,83 +1181,90 @@ main(int argc, char* argv[static argc + 1]) } // for every candidate candidates = ARRAY_DESTROY(gva_std_allocator, candidates); - fprintf(stderr, "\n"); + // fprintf(stderr, "\n"); } // for query allele parts - // fix containment for multiple parts in single node - for (size_t i = 0; i < array_header(node_parts_table)->capacity; ++i) + // We have now compared all query parts to the index + + // fix containment for multiple parts in single node for every query + for (size_t npt_index = 0; npt_index < array_header(node_parts_table)->capacity; ++npt_index) { - size_t node_idx = node_parts_table[i].gva_key; + size_t node_idx = node_parts_table[npt_index].gva_key; if (node_idx == (uint32_t) - 1) { continue; } // if - fprintf(stderr, " node_idx: %zu " GVA_VARIANT_FMT " %s (%d, %d, %d) in:%d\n", node_idx, - GVA_VARIANT_PRINT(((GVA_Variant) { - tree.nodes[node_idx].start, tree.nodes[node_idx].end, - trie_string(trie, tree.nodes[node_idx].inserted) - })), - GVA_RELATION_LABELS[node_parts_table[i].relation], - node_parts_table[i].start, node_parts_table[i].end, node_parts_table[i].part_idx, - node_parts_table[i].included); - - if (node_parts_table[i].relation == GVA_CONTAINS && node_parts_table[i].end - node_parts_table[i].start > 1) + // fprintf(stderr, " node_idx: %zu " GVA_VARIANT_FMT " %s (%d, %d) in:%d\n", + // node_idx, + // GVA_VARIANT_PRINT(((GVA_Variant) { + // tree.nodes[node_idx].start, tree.nodes[node_idx].end, + // trie_string(trie, tree.nodes[node_idx].inserted) + // })), + // GVA_RELATION_LABELS[node_parts_table[npt_index].relation], + // node_parts_table[npt_index].start, node_parts_table[npt_index].end, + // node_parts_table[npt_index].included); + + if (node_parts_table[npt_index].relation == GVA_CONTAINS && + node_parts_table[npt_index].end - node_parts_table[npt_index].start > 1) { - fprintf(stderr, " Perform extra comparison\n"); + // fprintf(stderr, " Perform extra comparison\n"); size_t slice_dist = 0; - for (size_t j = node_parts_table[i].start; j < node_parts_table[i].end; ++j) + for (size_t i = node_parts_table[npt_index].start; i < node_parts_table[npt_index].end; ++i) { - slice_dist += query_graph.local_supremal[j + 1].edges; + slice_dist += query_graph.local_supremal[i + 1].edges; } // for - fprintf(stderr, " Distances: %zu %u\n", slice_dist, tree.nodes[node_idx].distance); + // fprintf(stderr, " slice dist: %zu node dist: %u\n", slice_dist, tree.nodes[node_idx].distance); if (slice_dist >= tree.nodes[node_idx].distance) { - node_parts_table[i].relation = GVA_OVERLAP; - node_parts_table[i].included = 1; - fprintf(stderr, " REPAIRED DISTANCE node_idx: %zu " GVA_VARIANT_FMT " %s (%d, %d, %d) in:%d\n", node_idx, - GVA_VARIANT_PRINT(((GVA_Variant) { - tree.nodes[node_idx].start, tree.nodes[node_idx].end, - trie_string(trie, tree.nodes[node_idx].inserted) - })), - GVA_RELATION_LABELS[node_parts_table[i].relation], - node_parts_table[i].start, node_parts_table[i].end, node_parts_table[i].part_idx, - node_parts_table[i].included); + // fprintf(stderr, "here A\n"); + node_parts_table[npt_index].relation = GVA_OVERLAP; + node_parts_table[npt_index].included = 1; + // fprintf(stderr, " REPAIRED DISTANCE node_idx: %zu " GVA_VARIANT_FMT " %s (%d, %d, %d) in:%d\n", node_idx, + // GVA_VARIANT_PRINT(((GVA_Variant) { + // tree.nodes[node_idx].start, tree.nodes[node_idx].end, + // trie_string(trie, tree.nodes[node_idx].inserted) + // })), + // GVA_RELATION_LABELS[node_parts_table[i].relation], + // node_parts_table[npt_index].start, node_parts_table[npt_index].end, node_parts_table[npt_index].part_idx, + // node_parts_table[npt_index].included); continue; } // if GVA_Variant rhs; gva_edges(query_graph.observed.str, - query_graph.local_supremal[node_parts_table[i].start], - query_graph.local_supremal[node_parts_table[i].end], - node_parts_table[i].start == 0, - node_parts_table[i].end == array_length(query_graph.local_supremal) - 1, + query_graph.local_supremal[node_parts_table[npt_index].start], + query_graph.local_supremal[node_parts_table[npt_index].end], + node_parts_table[npt_index].start == 0, + node_parts_table[npt_index].end == array_length(query_graph.local_supremal) - 1, &rhs); - fprintf(stderr, GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(rhs)); + // fprintf(stderr, GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(rhs)); GVA_Variant const lhs = {tree.nodes[node_idx].start, tree.nodes[node_idx].end, trie_string(trie, tree.nodes[node_idx].inserted)}; size_t const op_distance = variants_distance(gva_std_allocator, reference.len, reference.str, lhs, rhs); - fprintf(stderr, "op_distance: %zu\n", op_distance); + // fprintf(stderr, "op_distance: %zu\n", op_distance); - node_parts_table[i].included = slice_dist; + node_parts_table[npt_index].included = slice_dist; if (tree.nodes[node_idx].distance - op_distance != slice_dist) { - node_parts_table[i].relation = GVA_OVERLAP; - node_parts_table[i].included = 1; - fprintf(stderr, "OVERLAP!!\n"); + // fprintf(stderr, "here B\n"); + node_parts_table[npt_index].relation = GVA_OVERLAP; + node_parts_table[npt_index].included = 1; + // fprintf(stderr, "OVERLAP!!\n"); } // if + // fprintf(stderr, "here C\n"); - fprintf(stderr, " REPAIRED node_idx: %zu " GVA_VARIANT_FMT " %s (%d, %d, %d) in:%d\n", node_idx, - GVA_VARIANT_PRINT(((GVA_Variant) { - tree.nodes[node_idx].start, tree.nodes[node_idx].end, - trie_string(trie, tree.nodes[node_idx].inserted) - })), - GVA_RELATION_LABELS[node_parts_table[i].relation], - node_parts_table[i].start, node_parts_table[i].end, node_parts_table[i].part_idx, - node_parts_table[i].included); + // fprintf(stderr, " REPAIRED node_idx: %zu " GVA_VARIANT_FMT " %s (%d, %d, %d) in:%d\n", node_idx, + // GVA_VARIANT_PRINT(((GVA_Variant) { + // tree.nodes[node_idx].start, tree.nodes[node_idx].end, + // trie_string(trie, tree.nodes[node_idx].inserted) + // })), + // GVA_RELATION_LABELS[node_parts_table[npt_index].relation], + // node_parts_table[npt_index].start, node_parts_table[npt_index].end, node_parts_table[npt_index].part_idx, + // node_parts_table[npt_index].included); } // if } // for node_parts_table @@ -1291,6 +1298,7 @@ main(int argc, char* argv[static argc + 1]) { GVA_Relation relation = GVA_DISJOINT; size_t included = 0; + // fprintf(stderr, "allele_idx: %zu\n", allele_idx); gva_uint* is_contained_nodes = NULL; gva_uint is_contained_part_idx = -1; @@ -1301,15 +1309,23 @@ main(int argc, char* argv[static argc + 1]) node_allele_join[join_idx].allele == allele_idx && join_idx < array_length(node_allele_join); ++join_idx) { - size_t hash_idx = HASH_TABLE_INDEX(node_parts_table, node_allele_join[join_idx].node); - if (node_allele_join[join_idx].node != node_parts_table[hash_idx].gva_key) + // fprintf(stderr, "join_idx: %zu\n", join_idx); + size_t node_idx = node_allele_join[join_idx].node; + size_t hash_idx = HASH_TABLE_INDEX(node_parts_table, node_idx); + if (node_idx != node_parts_table[hash_idx].gva_key) { + // fprintf(stderr, "when?!?\n"); continue; } // if + // fprintf(stderr, "node_idx: %zu\n", node_idx); + // continue; + size_t part_idx = node_parts_table[hash_idx].part_idx; + // size_t part_idx = 0; if (node_parts_table[hash_idx].relation == GVA_EQUIVALENT) { - included += tree.nodes[node_allele_join[join_idx].node].distance; + // included += tree.nodes[node_idx].distance; + included += node_parts_table[hash_idx].included; // TODO: need this guard? // if (relation == GVA_EQUIVALENT || relation == GVA_DISJOINT) @@ -1319,7 +1335,9 @@ main(int argc, char* argv[static argc + 1]) } // if else if (node_parts_table[hash_idx].relation == GVA_CONTAINS) { - included += query_graph.local_supremal[part_idx + 1].edges; + // fprintf(stderr, "here D\n"); + // included += query_graph.local_supremal[part_idx + 1].edges; + included += node_parts_table[hash_idx].included; if (relation == GVA_IS_CONTAINED) { @@ -1331,10 +1349,11 @@ main(int argc, char* argv[static argc + 1]) } else if (node_parts_table[hash_idx].relation == GVA_IS_CONTAINED) { - fprintf(stderr, "here %s\n", GVA_RELATION_LABELS[relation]); + // fprintf(stderr, "here %s\n", GVA_RELATION_LABELS[relation]); if (relation == GVA_CONTAINS) { - included += tree.nodes[node_allele_join[join_idx].node].distance; + // included += tree.nodes[node_idx].distance; + included += node_parts_table[hash_idx].included; // included = 1; ??? relation = GVA_OVERLAP; break; @@ -1342,17 +1361,18 @@ main(int argc, char* argv[static argc + 1]) if (part_idx != is_contained_part_idx) { - fprintf(stderr, "here2 %s\n", GVA_RELATION_LABELS[relation]); + // fprintf(stderr, "here2 %s\n", GVA_RELATION_LABELS[relation]); // close old window if (array_length(is_contained_nodes) > 1) { - fprintf(stderr, "Found multiple is_containeds for the same part\n"); + // fprintf(stderr, "Found multiple is_containeds for the same part\n"); size_t slice_dist = 0; - relation = multiple_is_contained(gva_std_allocator, reference.len, reference.str, query_graph, part_idx, tree, trie, is_contained_nodes, &slice_dist); + relation = multiple_is_contained(gva_std_allocator, reference.len, reference.str, + query_graph, part_idx, tree, trie, is_contained_nodes, &slice_dist); if (relation == GVA_OVERLAP) { - fprintf(stderr, "overlap shortcut in loop\n"); + // fprintf(stderr, "overlap shortcut in loop\n"); included = 1; break; } // if @@ -1364,31 +1384,35 @@ main(int argc, char* argv[static argc + 1]) is_contained_nodes = ARRAY_DESTROY(gva_std_allocator, is_contained_nodes); } // if - ARRAY_APPEND(gva_std_allocator, is_contained_nodes, node_allele_join[join_idx].node); + ARRAY_APPEND(gva_std_allocator, is_contained_nodes, node_idx); relation = GVA_IS_CONTAINED; } // if else if (node_parts_table[hash_idx].relation == GVA_OVERLAP) { - fprintf(stderr, "this overlap is reached\n"); + // fprintf(stderr, "this overlap is reached\n"); included = 1; relation = GVA_OVERLAP; break; } // if + // fprintf(stderr, "here F\n"); } // for allele nodes + // fprintf(stderr, "here G\n"); + // close old window size_t const n = array_length(is_contained_nodes); if (relation == GVA_IS_CONTAINED && n == 1) { - fprintf(stderr, "found single is_contained\n"); + // fprintf(stderr, "found single is_contained\n"); included += tree.nodes[is_contained_nodes[0]].distance; } else if (relation == GVA_IS_CONTAINED && n > 1) { - fprintf(stderr, "Found multiple is_containeds for the same part at the end\n"); + // fprintf(stderr, "Found multiple is_containeds for the same part at the end\n"); size_t slice_dist = 0; - relation = multiple_is_contained(gva_std_allocator, reference.len, reference.str, query_graph, is_contained_part_idx, tree, trie, is_contained_nodes, &slice_dist); + relation = multiple_is_contained(gva_std_allocator, reference.len, reference.str, + query_graph, is_contained_part_idx, tree, trie, is_contained_nodes, &slice_dist); if (relation == GVA_OVERLAP) { included = 1; @@ -1403,11 +1427,13 @@ main(int argc, char* argv[static argc + 1]) if (included > 0) { - fprintf(stderr, "allele dist: %u query dist: %u\n", db_alleles[allele_idx].distance, query_graph.distance); + // fprintf(stderr, "allele dist: %u query dist: %u\n", db_alleles[allele_idx].distance, query_graph.distance); size_t const allele_excluded = db_alleles[allele_idx].distance - included; size_t const query_excluded = query_graph.distance - included; + // fprintf(stderr, "included: %zu, allele_excluded: %zu query_excluded: %zu\n", + // included, allele_excluded, query_excluded); if (allele_excluded > 0 && query_excluded > 0) { relation = GVA_OVERLAP; @@ -1420,7 +1446,7 @@ main(int argc, char* argv[static argc + 1]) { relation = GVA_IS_CONTAINED; } - fprintf(stderr, "allele_idx: %zu relation: %s in: %zu\n", allele_idx, GVA_RELATION_LABELS[relation], included); + // fprintf(stderr, "allele_idx: %zu relation: %s in: %zu\n", allele_idx, GVA_RELATION_LABELS[relation], included); if (relation != GVA_EQUIVALENT) { @@ -1435,14 +1461,14 @@ main(int argc, char* argv[static argc + 1]) } // for all alleles - fprintf(stderr, "\n"); + // fprintf(stderr, "\n"); node_parts_table = HASH_TABLE_DESTROY(gva_std_allocator, node_parts_table); gva_string_destroy(gva_std_allocator, query_graph.observed); gva_lcs_graph_destroy(gva_std_allocator, query_graph); - fprintf(stderr, "\n"); + // fprintf(stderr, "\n"); line_count += 1; } // while fgets fclose(stream); From 5a9717b9bdeea7aa53c3b9cb4fb535fcf792aa3b Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Fri, 3 Oct 2025 00:06:57 +0200 Subject: [PATCH 367/704] Loop over the alleles that were actually part of a result. --- src/main.c | 41 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/src/main.c b/src/main.c index ff38355..e1634c5 100644 --- a/src/main.c +++ b/src/main.c @@ -1292,13 +1292,46 @@ main(int argc, char* argv[static argc + 1]) // } // fprintf(stderr, "\n"); + struct RESULT_ALLELES + { + HASH_TABLE_KEY; + }* results_table = hash_table_init(gva_std_allocator, 1024, sizeof(*results_table)); + + // fprintf(stderr, "Loop over all node parts for every query:\n"); + for (size_t npt_index = 0; npt_index < array_header(node_parts_table)->capacity; ++npt_index) + { + size_t const node_idx = node_parts_table[npt_index].gva_key; + if (node_idx == (uint32_t) - 1) + { + continue; + } // if + + for (size_t naj_table_idx = tree.nodes[node_idx].alleles; + naj_table_idx != GVA_NULL; + naj_table_idx = node_allele_join[naj_table_idx].next) + { + size_t const allele_idx = node_allele_join[naj_table_idx].allele; + size_t hash_idx = HASH_TABLE_INDEX(results_table, allele_idx); + if (results_table[hash_idx].gva_key != allele_idx) + { + HASH_TABLE_SET(gva_std_allocator, results_table, allele_idx, ((struct RESULT_ALLELES) {allele_idx})); + } // if + + } // for alleles + } // for node_parts_table + // build result vector for every query - // fprintf(stderr, "Loop over all alleles for every query:\n"); - for (size_t allele_idx = 0; allele_idx < array_length(db_alleles); ++allele_idx) + for (size_t results_index = 0; results_index < array_header(results_table)->capacity; ++results_index) { + size_t allele_idx = results_table[results_index].gva_key; + if (allele_idx == (uint32_t) - 1) + { + continue; + } // if + // fprintf(stderr, "allele_idx: %zu\n", allele_idx); + GVA_Relation relation = GVA_DISJOINT; size_t included = 0; - // fprintf(stderr, "allele_idx: %zu\n", allele_idx); gva_uint* is_contained_nodes = NULL; gva_uint is_contained_part_idx = -1; @@ -1318,7 +1351,6 @@ main(int argc, char* argv[static argc + 1]) continue; } // if // fprintf(stderr, "node_idx: %zu\n", node_idx); - // continue; size_t part_idx = node_parts_table[hash_idx].part_idx; // size_t part_idx = 0; @@ -1464,6 +1496,7 @@ main(int argc, char* argv[static argc + 1]) // fprintf(stderr, "\n"); node_parts_table = HASH_TABLE_DESTROY(gva_std_allocator, node_parts_table); + results_table = HASH_TABLE_DESTROY(gva_std_allocator, results_table); gva_string_destroy(gva_std_allocator, query_graph.observed); gva_lcs_graph_destroy(gva_std_allocator, query_graph); From 964be9bef91532980c6ca4a2a3f8a3880fac78cb Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Fri, 3 Oct 2025 08:27:29 +0200 Subject: [PATCH 368/704] Only update if it was not inclusion already. --- src/main.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main.c b/src/main.c index e1634c5..ec1db67 100644 --- a/src/main.c +++ b/src/main.c @@ -1359,8 +1359,7 @@ main(int argc, char* argv[static argc + 1]) // included += tree.nodes[node_idx].distance; included += node_parts_table[hash_idx].included; - // TODO: need this guard? - // if (relation == GVA_EQUIVALENT || relation == GVA_DISJOINT) + if (relation == GVA_EQUIVALENT || relation == GVA_DISJOINT) { relation = GVA_EQUIVALENT; } From a8d678d82d01ca08f2c3f3c761c9d700d9485242 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Fri, 3 Oct 2025 08:28:01 +0200 Subject: [PATCH 369/704] Explicitly add equivalent. --- src/main.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main.c b/src/main.c index ec1db67..5f88824 100644 --- a/src/main.c +++ b/src/main.c @@ -1477,6 +1477,10 @@ main(int argc, char* argv[static argc + 1]) { relation = GVA_IS_CONTAINED; } + else if (allele_excluded == 0 && query_excluded == 0) + { + relation = GVA_EQUIVALENT; + } // fprintf(stderr, "allele_idx: %zu relation: %s in: %zu\n", allele_idx, GVA_RELATION_LABELS[relation], included); if (relation != GVA_EQUIVALENT) From eede9d53accc74d17928fead87fc519d21128284 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Fri, 3 Oct 2025 08:28:11 +0200 Subject: [PATCH 370/704] Only show equivalent if rsid's dont match. --- src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.c b/src/main.c index 5f88824..ca0b5f5 100644 --- a/src/main.c +++ b/src/main.c @@ -1483,7 +1483,7 @@ main(int argc, char* argv[static argc + 1]) } // fprintf(stderr, "allele_idx: %zu relation: %s in: %zu\n", allele_idx, GVA_RELATION_LABELS[relation], included); - if (relation != GVA_EQUIVALENT) + if (relation != GVA_EQUIVALENT || db_alleles[allele_idx].data < query_id) { printf("%zu %s %zu %s %s\n", db_alleles[allele_idx].data, From 826dabe851254cad49002e1390bccbfe0f70c4be Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Sat, 4 Oct 2025 00:07:13 +0200 Subject: [PATCH 371/704] Deal with len==0. --- src/main.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/main.c b/src/main.c index ca0b5f5..901ba98 100644 --- a/src/main.c +++ b/src/main.c @@ -869,23 +869,29 @@ variants_distance(GVA_Allocator const allocator, size_t const len_ref, char cons size_t const rhs_len = (rhs.start - start) + rhs.sequence.len + (end - rhs.end); char* lhs_obs = allocator.allocate(allocator.context, NULL, 0, lhs_len); - if (lhs_obs == NULL) + if (lhs_len > 0) { - return -1; - } // if - memcpy(lhs_obs, reference + start, lhs.start - start); - memcpy(lhs_obs + lhs.start - start, lhs.sequence.str, lhs.sequence.len); - memcpy(lhs_obs + lhs.start - start + lhs.sequence.len, reference + lhs.end, end - lhs.end); + if (lhs_obs == NULL) + { + return -1; + } // if + memcpy(lhs_obs, reference + start, lhs.start - start); + memcpy(lhs_obs + lhs.start - start, lhs.sequence.str, lhs.sequence.len); + memcpy(lhs_obs + lhs.start - start + lhs.sequence.len, reference + lhs.end, end - lhs.end); + } char* rhs_obs = allocator.allocate(allocator.context, NULL, 0, rhs_len); - if (rhs_obs == NULL) + if (rhs_len > 0) { - lhs_obs = allocator.allocate(allocator.context, lhs_obs, lhs_len, 0); - return -1; - } // if - memcpy(rhs_obs, reference + start, rhs.start - start); - memcpy(rhs_obs + rhs.start - start, rhs.sequence.str, rhs.sequence.len); - memcpy(rhs_obs + rhs.start - start + rhs.sequence.len, reference + rhs.end, end - rhs.end); + if (rhs_obs == NULL && rhs_len > 0) + { + lhs_obs = allocator.allocate(allocator.context, lhs_obs, lhs_len, 0); + return -1; + } // if + memcpy(rhs_obs, reference + start, rhs.start - start); + memcpy(rhs_obs + rhs.start - start, rhs.sequence.str, rhs.sequence.len); + memcpy(rhs_obs + rhs.start - start + rhs.sequence.len, reference + rhs.end, end - rhs.end); + } size_t const distance = gva_edit_distance(allocator, lhs_len, lhs_obs, rhs_len, rhs_obs); rhs_obs = allocator.allocate(allocator.context, rhs_obs, rhs_len, 0); From 91a4b73d68eb08765e966105f8f0230bcdb21b55 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Sat, 4 Oct 2025 00:07:51 +0200 Subject: [PATCH 372/704] Put guard in front. --- src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.c b/src/main.c index 901ba98..b94c63b 100644 --- a/src/main.c +++ b/src/main.c @@ -1345,7 +1345,7 @@ main(int argc, char* argv[static argc + 1]) // loop over all nodes for this allele // fprintf(stderr, "Loop over nodes for this allele:\n"); for (size_t join_idx = db_alleles[allele_idx].join_start; - node_allele_join[join_idx].allele == allele_idx && join_idx < array_length(node_allele_join); + join_idx < array_length(node_allele_join) && node_allele_join[join_idx].allele == allele_idx; ++join_idx) { // fprintf(stderr, "join_idx: %zu\n", join_idx); From fe8f0292fc033c1a27ed156925c9a0bbe707b09e Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Mon, 6 Oct 2025 08:50:54 +0200 Subject: [PATCH 373/704] parts_idx only needed for is_contained. --- src/main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main.c b/src/main.c index b94c63b..1c057d8 100644 --- a/src/main.c +++ b/src/main.c @@ -1358,8 +1358,6 @@ main(int argc, char* argv[static argc + 1]) } // if // fprintf(stderr, "node_idx: %zu\n", node_idx); - size_t part_idx = node_parts_table[hash_idx].part_idx; - // size_t part_idx = 0; if (node_parts_table[hash_idx].relation == GVA_EQUIVALENT) { // included += tree.nodes[node_idx].distance; @@ -1386,7 +1384,9 @@ main(int argc, char* argv[static argc + 1]) } else if (node_parts_table[hash_idx].relation == GVA_IS_CONTAINED) { - // fprintf(stderr, "here %s\n", GVA_RELATION_LABELS[relation]); + size_t part_idx = node_parts_table[hash_idx].part_idx; + // fprintf(stderr, "part_idx: %zu\n", part_idx); + // fprintf(stderr, "if containment current: %s\n", GVA_RELATION_LABELS[relation]); if (relation == GVA_CONTAINS) { // included += tree.nodes[node_idx].distance; From 7500f6ad468459a827f95dcca5a1add110f4b36b Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Mon, 6 Oct 2025 08:52:05 +0200 Subject: [PATCH 374/704] Leave note. --- src/main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main.c b/src/main.c index 1c057d8..dccca47 100644 --- a/src/main.c +++ b/src/main.c @@ -1176,6 +1176,8 @@ main(int argc, char* argv[static argc + 1]) } // if else if (relation == GVA_CONTAINS) { + // fprintf(stderr, "yo\n"); + // TODO: extend conditional with EQUIVALENT?! if (node_parts_table[hash_idx].relation == GVA_DISJOINT) { node_parts_table[hash_idx].relation = GVA_CONTAINS; From 8aefab1aad6b9aca4223c28372cb400c2f35d21d Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Mon, 6 Oct 2025 08:53:03 +0200 Subject: [PATCH 375/704] Cleanup. --- src/main.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/main.c b/src/main.c index dccca47..e07f88d 100644 --- a/src/main.c +++ b/src/main.c @@ -1362,7 +1362,6 @@ main(int argc, char* argv[static argc + 1]) if (node_parts_table[hash_idx].relation == GVA_EQUIVALENT) { - // included += tree.nodes[node_idx].distance; included += node_parts_table[hash_idx].included; if (relation == GVA_EQUIVALENT || relation == GVA_DISJOINT) @@ -1373,7 +1372,6 @@ main(int argc, char* argv[static argc + 1]) else if (node_parts_table[hash_idx].relation == GVA_CONTAINS) { // fprintf(stderr, "here D\n"); - // included += query_graph.local_supremal[part_idx + 1].edges; included += node_parts_table[hash_idx].included; if (relation == GVA_IS_CONTAINED) @@ -1391,9 +1389,7 @@ main(int argc, char* argv[static argc + 1]) // fprintf(stderr, "if containment current: %s\n", GVA_RELATION_LABELS[relation]); if (relation == GVA_CONTAINS) { - // included += tree.nodes[node_idx].distance; - included += node_parts_table[hash_idx].included; - // included = 1; ??? + included += node_parts_table[hash_idx].included; // TODO: included = 1; ??? relation = GVA_OVERLAP; break; } // if From d801a7987b245787e149623fe33760e6d6af0152 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Mon, 6 Oct 2025 08:53:50 +0200 Subject: [PATCH 376/704] Debugging fprintfs. --- src/main.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/main.c b/src/main.c index e07f88d..0e24ec2 100644 --- a/src/main.c +++ b/src/main.c @@ -1097,7 +1097,6 @@ main(int argc, char* argv[static argc + 1]) fprintf(stderr, "error: SPDI parsing failed at line %zu: %s", line_count + 1, line); continue; } // if - // fprintf(stderr, "query allele %zu: " GVA_VARIANT_FMT "\n", query_id, GVA_VARIANT_PRINT(query_var)); // Join nodes in the index to parts in the query struct NODE_PARTS @@ -1112,6 +1111,7 @@ main(int argc, char* argv[static argc + 1]) // query graph GVA_LCS_Graph query_graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &query_var); + // fprintf(stderr, "query allele %zu: " GVA_VARIANT_FMT " (dist: %u)\n", query_id, GVA_VARIANT_PRINT(query_var), query_graph.distance); size_t const spdi_len = snprintf(NULL, 0, GVA_VARIANT_FMT_SPDI, GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, query_graph.supremal)) + 1; char* const query_spdi = malloc(spdi_len); @@ -1252,7 +1252,7 @@ main(int argc, char* argv[static argc + 1]) trie_string(trie, tree.nodes[node_idx].inserted)}; size_t const op_distance = variants_distance(gva_std_allocator, reference.len, reference.str, lhs, rhs); - // fprintf(stderr, "op_distance: %zu\n", op_distance); + // fprintf(stderr, "op_distance: %d\n", op_distance); node_parts_table[npt_index].included = slice_dist; @@ -1396,8 +1396,8 @@ main(int argc, char* argv[static argc + 1]) if (part_idx != is_contained_part_idx) { - // fprintf(stderr, "here2 %s\n", GVA_RELATION_LABELS[relation]); - + // fprintf(stderr, "close window upper %s\n", GVA_RELATION_LABELS[relation]); + // fprintf(stderr, "#is_contained_nodes: %zu\n", array_length(is_contained_nodes)); // close old window if (array_length(is_contained_nodes) > 1) { @@ -1407,7 +1407,6 @@ main(int argc, char* argv[static argc + 1]) query_graph, part_idx, tree, trie, is_contained_nodes, &slice_dist); if (relation == GVA_OVERLAP) { - // fprintf(stderr, "overlap shortcut in loop\n"); included = 1; break; } // if @@ -1415,6 +1414,7 @@ main(int argc, char* argv[static argc + 1]) } // if // open new window + // fprintf(stderr, "open new window\n"); is_contained_part_idx = part_idx; is_contained_nodes = ARRAY_DESTROY(gva_std_allocator, is_contained_nodes); } // if @@ -1435,12 +1435,15 @@ main(int argc, char* argv[static argc + 1]) // fprintf(stderr, "here G\n"); + // fprintf(stderr, "included: %zu\n", included); + // close old window size_t const n = array_length(is_contained_nodes); if (relation == GVA_IS_CONTAINED && n == 1) { // fprintf(stderr, "found single is_contained\n"); included += tree.nodes[is_contained_nodes[0]].distance; + // fprintf(stderr, "increase included with %u to %zu\n", tree.nodes[is_contained_nodes[0]].distance, included); } else if (relation == GVA_IS_CONTAINED && n > 1) { @@ -1455,6 +1458,7 @@ main(int argc, char* argv[static argc + 1]) else { included += slice_dist; + // fprintf(stderr, "increase included with %zu to %zu\n", slice_dist, included); } // else } // if is_contained repair @@ -1463,11 +1467,12 @@ main(int argc, char* argv[static argc + 1]) if (included > 0) { // fprintf(stderr, "allele dist: %u query dist: %u\n", db_alleles[allele_idx].distance, query_graph.distance); + // fprintf(stderr, "relation: %s\n", GVA_RELATION_LABELS[relation]); size_t const allele_excluded = db_alleles[allele_idx].distance - included; size_t const query_excluded = query_graph.distance - included; - // fprintf(stderr, "included: %zu, allele_excluded: %zu query_excluded: %zu\n", + // fprintf(stderr, "included: %zu, allele_excluded: %d query_excluded: %zu\n", // included, allele_excluded, query_excluded); if (allele_excluded > 0 && query_excluded > 0) { From 392dc4a713d99a2feff2d584fa8340727df74051 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Mon, 6 Oct 2025 08:54:19 +0200 Subject: [PATCH 377/704] Comments. --- src/main.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main.c b/src/main.c index 0e24ec2..28faad1 100644 --- a/src/main.c +++ b/src/main.c @@ -1417,11 +1417,10 @@ main(int argc, char* argv[static argc + 1]) // fprintf(stderr, "open new window\n"); is_contained_part_idx = part_idx; is_contained_nodes = ARRAY_DESTROY(gva_std_allocator, is_contained_nodes); - } // if - + } // if part_idx != is_contained_part_idx ARRAY_APPEND(gva_std_allocator, is_contained_nodes, node_idx); relation = GVA_IS_CONTAINED; - } // if + } // if relation == GVA_IS_CONTAINED else if (node_parts_table[hash_idx].relation == GVA_OVERLAP) { // fprintf(stderr, "this overlap is reached\n"); @@ -1431,7 +1430,7 @@ main(int argc, char* argv[static argc + 1]) } // if // fprintf(stderr, "here F\n"); - } // for allele nodes + } // for all nodes for this allele // fprintf(stderr, "here G\n"); From b7a9d7f88567e21049528ee7a06335de2912e4f1 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Mon, 6 Oct 2025 08:55:39 +0200 Subject: [PATCH 378/704] Also close window when there is only a single element. --- src/main.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main.c b/src/main.c index 28faad1..b3efb96 100644 --- a/src/main.c +++ b/src/main.c @@ -1412,6 +1412,11 @@ main(int argc, char* argv[static argc + 1]) } // if included += slice_dist; } // if + else if (array_length(is_contained_nodes) == 1) + { + // fprintf(stderr, "Now should add previous node\n"); + included += tree.nodes[is_contained_nodes[0]].distance; + } // open new window // fprintf(stderr, "open new window\n"); From 359513cde69beb63396d138e35c08ac69a09361d Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Mon, 6 Oct 2025 09:09:41 +0200 Subject: [PATCH 379/704] Drop space. --- src/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.c b/src/main.c index b3efb96..beb23d1 100644 --- a/src/main.c +++ b/src/main.c @@ -1197,8 +1197,8 @@ main(int argc, char* argv[static argc + 1]) // fix containment for multiple parts in single node for every query for (size_t npt_index = 0; npt_index < array_header(node_parts_table)->capacity; ++npt_index) { - size_t node_idx = node_parts_table[npt_index].gva_key; - if (node_idx == (uint32_t) - 1) + size_t const node_idx = node_parts_table[npt_index].gva_key; + if (node_idx == (uint32_t) -1) { continue; } // if From 532e396f1839993151d75b8e10d73a1ec0442875 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Mon, 6 Oct 2025 09:09:51 +0200 Subject: [PATCH 380/704] Leave note. --- src/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main.c b/src/main.c index beb23d1..b18ffd6 100644 --- a/src/main.c +++ b/src/main.c @@ -1300,6 +1300,7 @@ main(int argc, char* argv[static argc + 1]) // } // fprintf(stderr, "\n"); + // TODO: best datastructure if there is only a key?! struct RESULT_ALLELES { HASH_TABLE_KEY; From e749d426a61b113af5ba55cb8a1856e2ecd8ff96 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Mon, 6 Oct 2025 09:10:09 +0200 Subject: [PATCH 381/704] Const. --- src/main.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main.c b/src/main.c index b18ffd6..1285583 100644 --- a/src/main.c +++ b/src/main.c @@ -1021,7 +1021,7 @@ main(int argc, char* argv[static argc + 1]) continue; } // if - GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &variant); + GVA_LCS_Graph const graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &variant); size_t const spdi_len = snprintf(NULL, 0, GVA_VARIANT_FMT_SPDI, GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, graph.supremal)) + 1; char* const spdi = malloc(spdi_len); if (NULL == spdi) { @@ -1110,7 +1110,7 @@ main(int argc, char* argv[static argc + 1]) }* node_parts_table = hash_table_init(gva_std_allocator, 1024, sizeof(*node_parts_table)); // query graph - GVA_LCS_Graph query_graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &query_var); + GVA_LCS_Graph const query_graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &query_var); // fprintf(stderr, "query allele %zu: " GVA_VARIANT_FMT " (dist: %u)\n", query_id, GVA_VARIANT_PRINT(query_var), query_graph.distance); size_t const spdi_len = snprintf(NULL, 0, GVA_VARIANT_FMT_SPDI, GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, query_graph.supremal)) + 1; @@ -1130,16 +1130,16 @@ main(int argc, char* argv[static argc + 1]) part_idx == 0, part_idx == array_length(query_graph.local_supremal) - 2, &query_part); - gva_uint query_dist = query_graph.local_supremal[part_idx + 1].edges; + gva_uint const query_dist = query_graph.local_supremal[part_idx + 1].edges; // fprintf(stderr, " query part %zu (dist: %d): " GVA_VARIANT_FMT "\n", part_idx, query_dist, GVA_VARIANT_PRINT(query_part)); // find candidates for this local supremal part gva_uint* candidates = interval_tree_intersection(gva_std_allocator, tree, query_part.start, query_part.end); for (size_t can_idx = 0; can_idx < array_length(candidates); ++can_idx) { - gva_uint node_idx = candidates[can_idx]; + gva_uint const node_idx = candidates[can_idx]; GVA_Variant const db_var = {tree.nodes[node_idx].start, tree.nodes[node_idx].end, trie_string(trie, tree.nodes[node_idx].inserted)}; - GVA_Relation relation = compare_from_index(reference, db_var, tree.nodes[node_idx].distance, query_part, query_dist); + GVA_Relation const relation = compare_from_index(reference, db_var, tree.nodes[node_idx].distance, query_part, query_dist); // fprintf(stderr, " db candidate node_idx: %d (dist: %d): " GVA_VARIANT_FMT " %s\n", node_idx, tree.nodes[node_idx].distance, GVA_VARIANT_PRINT(db_var), GVA_RELATION_LABELS[relation]); if (relation == GVA_DISJOINT) From aef961f9e3b20c107949f8b04068c70f90793d2c Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Mon, 6 Oct 2025 09:10:17 +0200 Subject: [PATCH 382/704] Consistent types for included and excluded. --- src/main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main.c b/src/main.c index 1285583..dbffe3c 100644 --- a/src/main.c +++ b/src/main.c @@ -1340,7 +1340,7 @@ main(int argc, char* argv[static argc + 1]) // fprintf(stderr, "allele_idx: %zu\n", allele_idx); GVA_Relation relation = GVA_DISJOINT; - size_t included = 0; + gva_uint included = 0; gva_uint* is_contained_nodes = NULL; gva_uint is_contained_part_idx = -1; @@ -1474,8 +1474,8 @@ main(int argc, char* argv[static argc + 1]) // fprintf(stderr, "allele dist: %u query dist: %u\n", db_alleles[allele_idx].distance, query_graph.distance); // fprintf(stderr, "relation: %s\n", GVA_RELATION_LABELS[relation]); - size_t const allele_excluded = db_alleles[allele_idx].distance - included; - size_t const query_excluded = query_graph.distance - included; + gva_uint const allele_excluded = db_alleles[allele_idx].distance - included; + gva_uint const query_excluded = query_graph.distance - included; // fprintf(stderr, "included: %zu, allele_excluded: %d query_excluded: %zu\n", // included, allele_excluded, query_excluded); From b2a131a4850bcab730d6ae81ae748d2109dadc54 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Mon, 6 Oct 2025 13:15:27 +0200 Subject: [PATCH 383/704] Output length of trie strings. --- src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.c b/src/main.c index dbffe3c..436a393 100644 --- a/src/main.c +++ b/src/main.c @@ -1065,7 +1065,7 @@ main(int argc, char* argv[static argc + 1]) fprintf(stderr, "line count: %zu\n", line_count); fprintf(stderr, "tree nodes: %zu\n", array_length(tree.nodes)); - fprintf(stderr, "trie nodes: %zu\n", array_length(trie.nodes)); + fprintf(stderr, "trie nodes: %zu (%zu)\n", array_length(trie.nodes), trie.strings.len); fprintf(stderr, "#db_alleles: %zu\n", array_length(db_alleles)); fprintf(stderr, "#join: %zu\n", array_length(node_allele_join)); From d43c6572681a0186efd7cc54ef11830c5ade3a0b Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Mon, 6 Oct 2025 13:33:51 +0200 Subject: [PATCH 384/704] Remove all things stabbing. --- include/stabbing.h | 75 ------------- src/main.c | 254 --------------------------------------------- src/stabbing.c | 200 ----------------------------------- 3 files changed, 529 deletions(-) delete mode 100644 include/stabbing.h delete mode 100644 src/stabbing.c diff --git a/include/stabbing.h b/include/stabbing.h deleted file mode 100644 index 39b10c2..0000000 --- a/include/stabbing.h +++ /dev/null @@ -1,75 +0,0 @@ -#ifndef GVA_STABBING_H -#define GVA_STABBING_H - - -#include // size_t - -#include "allocator.h" // GVA_Allocator -#include "types.h" // gva_uint - - -typedef struct -{ - gva_uint parent; - gva_uint leftsibling; - gva_uint rightchild; - gva_uint start; - gva_uint end; - gva_uint inserted; - gva_uint distance; - gva_uint allele; - gva_uint next; -} GVA_Stabbing_Entry; - - -typedef struct -{ - size_t data; - gva_uint distance; - gva_uint head; -} GVA_Stabbing_Allele; - - -// FIXME: include trie as part of the index. -typedef struct -{ - size_t len_ref; - gva_uint* start_table; - GVA_Stabbing_Entry* entries; - GVA_Stabbing_Allele* alleles; -} GVA_Stabbing_Index; - - -GVA_Stabbing_Index -gva_stabbing_index_init(GVA_Allocator const allocator, size_t const len_ref); - - -void -gva_stabbing_index_destroy(GVA_Allocator const allocator, GVA_Stabbing_Index index[static 1]); - - -size_t -gva_stabbing_index_add_allele(GVA_Allocator const allocator, GVA_Stabbing_Index index[static 1], - size_t const data, gva_uint const distance); - - -size_t -gva_stabbing_index_add_part(GVA_Allocator const allocator, GVA_Stabbing_Index index[static 1], - gva_uint const start, gva_uint const end, gva_uint const inserted, - gva_uint const distance, gva_uint const allele); - - -void -gva_stabbing_index_build(GVA_Allocator const allocator, GVA_Stabbing_Index const index); - - -gva_uint* -gva_stabbing_index_self_intersect(GVA_Allocator const allocator, GVA_Stabbing_Index const index); - - -gva_uint* -gva_stabbing_index_intersect(GVA_Allocator const allocator, GVA_Stabbing_Index const index, - gva_uint const start, gva_uint const end); - - -#endif // GVA_STABBING_H diff --git a/src/main.c b/src/main.c index f6837b6..44bc7fc 100644 --- a/src/main.c +++ b/src/main.c @@ -12,7 +12,6 @@ #include "../include/edit.h" // gva_edit_distance #include "../include/extractor.h" // gva_canonical #include "../include/lcs_graph.h" // GVA_LCS_Graph, GVA_Variant, gva_lcs_graph_*, gva_edges -#include "../include/stabbing.h" // GVA_Stabbing_*, gva_stabbing_* #include "../include/std_alloc.h" // gva_std_allocator #include "../include/string.h" // GVA_String, gva_string_destroy #include "../include/types.h" // GVA_NULL, gva_uint @@ -333,22 +332,6 @@ extract(int const argc, char* argv[static argc + 1]) } // extract -void -index_dot(FILE* const stream, GVA_Stabbing_Index const index) -{ - fprintf(stream, "strict digraph{\nrankdir=BT\n"); - for (gva_uint i = 0; i < array_length(index.entries); ++i) - { - fprintf(stream, "%u[label=\"%u\\n[%u, %u]\"]\n", i, i, index.entries[i].start, index.entries[i].end); - if (index.entries[i].parent != GVA_NULL) - { - fprintf(stream, "%u->%u\n", i, index.entries[i].parent); - } // if - } // for - fprintf(stream, "}\n"); -} // index_dot - - // FIXME: see `match_number` in src/variant.c static inline size_t parse_number(char const buffer[static 1], size_t idx[static 1]) @@ -447,66 +430,6 @@ bitset_print(size_t const bitset[static 1], size_t const size) } // bitset_print -static inline int -entry_cmp(void const* lhs, void const* rhs) -{ - GVA_Stabbing_Entry const* const lhs_entry = lhs; - GVA_Stabbing_Entry const* const rhs_entry = rhs; - - if (lhs_entry->start < rhs_entry->start) - { - return -1; - } // if - if (lhs_entry->start > rhs_entry->start) - { - return 1; - } // if - if (lhs_entry->end > rhs_entry->end) - { - return -1; - } // if - if (lhs_entry->end < rhs_entry->end) - { - return 1; - } // if - if (lhs_entry->distance > rhs_entry->distance) - { - return -1; - } // if - if (lhs_entry->distance < rhs_entry->distance) - { - return 1; - } // if - return 0; -} // entry_cmp - - -size_t -binary_search(size_t const n, GVA_Stabbing_Entry const entries[static n], - GVA_Stabbing_Entry const key, size_t low) -{ - size_t high = n; - while (low <= high) - { - size_t const mid = low + (high - low) / 2; - int const cmp = entry_cmp(&entries[mid], &key); - if (cmp < 0) - { - low = mid + 1; - } // if - else if (cmp > 0 && mid > 0) - { - high = mid - 1; - } // if - else - { - return mid; - } // else - } // while - return low; -} // binary_search - - GVA_Relation compare_from_index(GVA_String const reference, GVA_Variant const lhs, gva_uint const lhs_dist, @@ -628,183 +551,6 @@ compare_from_index(GVA_String const reference, } // compare_from_index -int -all(int argc, char* argv[static argc + 1]) -{ - if (argc < 2) - { - fprintf(stderr, "usage: %s path_to_reference_fasta\n", argv[0]); - return EXIT_FAILURE; - } // if - - errno = 0; - FILE* stream = fopen(argv[1], "r"); - if (stream == NULL) - { - fprintf(stderr, "error: %s\n", strerror(errno)); - return EXIT_FAILURE; - } // if - - GVA_String reference = {0, NULL}; - reference = gva_fasta_sequence(gva_std_allocator, stream); - fclose(stream); - - fprintf(stderr, "reference length: %zu\n", reference.len); - - TIC(perf_calculate_supremals); - - GVA_Stabbing_Index index = gva_stabbing_index_init(gva_std_allocator, reference.len); - Trie trie = {{0, NULL}, NULL, GVA_NULL}; - - size_t count = 0; - static char line[LINE_SIZE] = {0}; - while (fgets(line, sizeof(line), stdin) != NULL) - { - size_t idx = 0; - size_t const rsid = parse_number(line, &idx); - idx += 1; // skip space or tab - int const len = (char*) memchr(line + idx, '\n', LINE_SIZE - idx) - (line + idx); - GVA_Variant variant; - if (gva_parse_spdi(len, line + idx, &variant) == 0) - { - fprintf(stderr, "error: SPDI parsing failed at line %zu: %s", count + 1, line); - continue; - } // if - - GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &variant); - - size_t const allele = gva_stabbing_index_add_allele(gva_std_allocator, &index, rsid, graph.distance) - 1; - for (size_t i = 0; i < array_length(graph.local_supremal) - 1; ++i) - { - GVA_Variant variant; - gva_edges(graph.observed.str, - graph.local_supremal[i], graph.local_supremal[i + 1], - i == 0, i == array_length(graph.local_supremal) - 2, - &variant); - - gva_uint const inserted = trie_insert(gva_std_allocator, &trie, variant.sequence.len, variant.sequence.str); - gva_stabbing_index_add_part(gva_std_allocator, &index, - variant.start, variant.end, inserted, graph.local_supremal[i + 1].edges, allele); - } // for - - gva_string_destroy(gva_std_allocator, graph.observed); - gva_lcs_graph_destroy(gva_std_allocator, graph); - - count += 1; - } // while - fprintf(stderr, "number of variants: %zu\n", array_length(index.entries) - 1); - fprintf(stderr, "number of alleles: %zu\n", array_length(index.alleles)); - - TOC(perf_calculate_supremals); - - TIC(perf_build_index); - - qsort(index.entries, array_length(index.entries), sizeof(*index.entries), entry_cmp); - gva_stabbing_index_build(gva_std_allocator, index); - - for (size_t i = array_length(index.entries) - 1; i > 0; --i) - { - index.entries[i].next = index.alleles[index.entries[i].allele].head; - index.alleles[index.entries[i].allele].head = i; - } // for - - TOC(perf_build_index); - - TIC(perf_calculate_relations); - - GVA_LCS_Graph rhs_graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, - 2, (GVA_Variant[]) {(GVA_Variant) {7869, 7870, {1, "T"}}, (GVA_Variant) {9199, 9200, {1, "C"}}}); - - struct { - gva_uint included; - gva_uint excluded; - }* result_map = gva_std_allocator.allocate(gva_std_allocator.context, NULL, 0, 1024 * sizeof(*result_map)); - if (result_map == NULL) - { - return -1; - } // if - memset(result_map, 0, 1024 * sizeof(*result_map)); - - for (size_t i = 0; i < array_length(rhs_graph.local_supremal) - 1; ++i) - { - GVA_Variant rhs; - gva_edges(rhs_graph.observed.str, - rhs_graph.local_supremal[i], rhs_graph.local_supremal[i + 1], - i == 0, i == array_length(rhs_graph.local_supremal) - 2, - &rhs); - - gva_uint rhs_dist = rhs_graph.local_supremal[i + 1].edges; - fprintf(stderr, GVA_VARIANT_FMT " %u\n", GVA_VARIANT_PRINT(rhs), rhs_dist); - - gva_uint* results = gva_stabbing_index_intersect(gva_std_allocator, index, rhs.start, rhs.end); - - for (size_t i = 0; i < array_length(results); ++i) { - GVA_Variant const lhs = {index.entries[results[i]].start, index.entries[results[i]].end, - trie_string(trie, index.entries[results[i]].inserted)}; - GVA_Relation relation = compare_from_index(reference, lhs, index.entries[results[i]].distance, rhs, - rhs_dist); - - if (relation == GVA_EQUIVALENT || relation == GVA_CONTAINS) - { - result_map[index.entries[results[i]].allele].included += rhs_dist; - } // if - else if (relation == GVA_IS_CONTAINED) - { - result_map[index.entries[results[i]].allele].included += index.entries[results[i]].distance; - result_map[index.entries[results[i]].allele].excluded += rhs_dist - index.entries[results[i]].distance; - } // if - else if (relation == GVA_OVERLAP) - { - result_map[index.entries[results[i]].allele].included += 1; - result_map[index.entries[results[i]].allele].excluded += 1; - } // if - } // for - - results = ARRAY_DESTROY(gva_std_allocator, results); - } // for - - for (size_t i = 0; i < 1024; ++i) - { - if (result_map[i].included > 0 || result_map[i].excluded > 0) - { - result_map[i].excluded = rhs_graph.distance - result_map[i].included; - - GVA_Relation relation = GVA_OVERLAP; - if (result_map[i].excluded == 0) - { - if (result_map[i].included == index.alleles[i].distance) - { - relation = GVA_EQUIVALENT; - } // if - else - { - relation = GVA_CONTAINS; - } // else - } - else if (result_map[i].included == index.alleles[i].distance) - { - relation = GVA_IS_CONTAINED; - } // if - - fprintf(stderr, "%zu(%u): %u %u -> %s\n", - index.alleles[i].data, index.alleles[i].distance, - result_map[i].included, result_map[i].excluded, GVA_RELATION_LABELS[relation]); - } // if - } // for - result_map = gva_std_allocator.allocate(gva_std_allocator.context, result_map, 1024 * sizeof(*result_map), 0); - - gva_string_destroy(gva_std_allocator, rhs_graph.observed); - gva_lcs_graph_destroy(gva_std_allocator, rhs_graph); - - TOC(perf_calculate_relations); - - gva_stabbing_index_destroy(gva_std_allocator, &index); - trie_destroy(gva_std_allocator, &trie); - gva_string_destroy(gva_std_allocator, reference); - return EXIT_SUCCESS; -} // all - - int compare(int argc, char* argv[static argc + 1]) { diff --git a/src/stabbing.c b/src/stabbing.c deleted file mode 100644 index 44f660e..0000000 --- a/src/stabbing.c +++ /dev/null @@ -1,200 +0,0 @@ -#include // bool, false, true -#include // NULL, size_t -#include // memset - -#include "../include/allocator.h" // GVA_Allocator -#include "../include/stabbing.h" // GVA_Stabbing_Entry, GVA_Stabbing_Index, gva_stabbing_index_* -#include "../include/types.h" // GVA_NULL, gva_uint -#include "array.h" // ARRAY_*, array_* -#include "common.h" // MAX - - -GVA_Stabbing_Index -gva_stabbing_index_init(GVA_Allocator const allocator, size_t const len_ref) -{ - gva_uint* start_table = allocator.allocate(allocator.context, NULL, 0, len_ref * sizeof(*start_table)); // OVERFLOW - if (start_table == NULL) - { - return (GVA_Stabbing_Index) {0, NULL, NULL, NULL}; - } // if - memset(start_table, 0, len_ref * sizeof(*start_table)); - - GVA_Stabbing_Entry* entries = NULL; - ARRAY_APPEND(allocator, entries, ((GVA_Stabbing_Entry) - {GVA_NULL, GVA_NULL, GVA_NULL, 0, len_ref, 0, 0, GVA_NULL, GVA_NULL})); - - return (GVA_Stabbing_Index) {len_ref, start_table, entries, NULL}; -} // gva_stabbing_index_init - - -void -gva_stabbing_index_destroy(GVA_Allocator const allocator, GVA_Stabbing_Index index[static 1]) -{ - index->alleles = ARRAY_DESTROY(allocator, index->alleles); - index->entries = ARRAY_DESTROY(allocator, index->entries); - index->start_table = allocator.allocate(allocator.context, index->start_table, index->len_ref * sizeof(*index->start_table), 0); - index->len_ref = 0; -} // gva_stabbing_index_destroy - - -inline size_t -gva_stabbing_index_add_allele(GVA_Allocator const allocator, GVA_Stabbing_Index index[static 1], - size_t const data, gva_uint const distance) -{ - return ARRAY_APPEND(allocator, index->alleles, ((GVA_Stabbing_Allele) - {data, distance, GVA_NULL})); -} // gva_stabbing_index_add_allele - - -inline size_t -gva_stabbing_index_add_part(GVA_Allocator const allocator, GVA_Stabbing_Index index[static 1], - gva_uint const start, gva_uint const end, gva_uint const inserted, - gva_uint const distance, gva_uint const allele) -{ - return ARRAY_APPEND(allocator, index->entries, ((GVA_Stabbing_Entry) - {GVA_NULL, GVA_NULL, GVA_NULL, start, end, inserted, distance, allele, GVA_NULL})); -} // gva_stabbing_index_add_part - - -void -gva_stabbing_index_build(GVA_Allocator const allocator, GVA_Stabbing_Index const index) -{ - gva_uint const len = array_length(index.entries); - if (len <= 1) - { - return; - } // if - - gva_uint* stack = allocator.allocate(allocator.context, NULL, 0, index.len_ref * sizeof(*stack)); - if (stack == NULL) - { - return; - } // if - - gva_uint prev = 0; - gva_uint idx = 1; - gva_uint top = 0; - stack[top] = 0; - for (gva_uint i = 0; i < index.len_ref; ++i) - { - while (index.entries[stack[top]].end < i) - { - top -= 1; - } // while - - while (idx < len && i >= index.entries[idx].start && i <= index.entries[idx].end && - !(index.entries[idx].start == index.entries[stack[top]].start && index.entries[idx].end == index.entries[stack[top]].end)) - { - do - { - top += 1; - stack[top] = idx; - - index.entries[idx].parent = prev; - while (index.entries[idx].parent != GVA_NULL && index.entries[index.entries[idx].parent].end < index.entries[idx].end) - { - index.entries[idx].parent = index.entries[index.entries[idx].parent].parent; - } // while - index.entries[idx].leftsibling = index.entries[index.entries[idx].parent].rightchild; - index.entries[index.entries[idx].parent].rightchild = idx; - prev = idx; - - idx += 1; - } while (idx < len && index.entries[idx].start == index.entries[stack[top]].start && index.entries[idx].end == index.entries[stack[top]].end); - } /// while - - index.start_table[i] = stack[top]; - } // for - - stack = allocator.allocate(allocator.context, stack, index.len_ref * sizeof(*stack), 0); -} // gva_stabbing_index_init - - -gva_uint* -gva_stabbing_index_self_intersect(GVA_Allocator const allocator, GVA_Stabbing_Index const index) -{ - gva_uint* results = NULL; - for (size_t i = 1; i < array_length(index.entries); ++i) - { - for (size_t j = i + 1; j < array_length(index.entries); ++j) - { - if (index.entries[i].end < index.entries[j].start) - { - break; - } // if - if (index.entries[j].end >= index.entries[i].start && index.entries[j].start <= index.entries[i].end) - { - ARRAY_APPEND(allocator, results, 0); - } // if - } // for - } // for - return results; -} // gva_stabbing_index_self_intersect - - -gva_uint* -gva_stabbing_index_intersect(GVA_Allocator const allocator, GVA_Stabbing_Index const index, - gva_uint const start, gva_uint const end) -{ - gva_uint* results = NULL; - gva_uint* stack = NULL; - gva_uint stab = index.start_table[end]; - - if (index.entries[stab].rightchild != GVA_NULL) - { - ARRAY_APPEND(allocator, stack, index.entries[stab].rightchild); - while (array_length(stack) > 0) - { - array_header(stack)->length -= 1; - gva_uint trav = stack[array_length(stack)]; - if (end >= index.entries[trav].start) - { - ARRAY_APPEND(allocator, results, trav); - } // if - - if (index.entries[trav].leftsibling != GVA_NULL) - { - ARRAY_APPEND(allocator, stack, index.entries[trav].leftsibling); - } // if - - if (index.entries[trav].rightchild != GVA_NULL && end >= index.entries[index.entries[trav].rightchild].start) - { - ARRAY_APPEND(allocator, stack, index.entries[trav].rightchild); - } // if - } // while - } // if - - while (stab != GVA_NULL) - { - if (stab > 0) - { - ARRAY_APPEND(allocator, results, stab); - } // if - - if (index.entries[stab].leftsibling != GVA_NULL && start <= index.entries[index.entries[stab].leftsibling].end) - { - ARRAY_APPEND(allocator, stack, index.entries[stab].leftsibling); - while (array_length(stack) > 0) - { - array_header(stack)->length -= 1; - gva_uint trav = stack[array_length(stack)]; - ARRAY_APPEND(allocator, results, trav); - - if (index.entries[trav].leftsibling != GVA_NULL && start <= index.entries[index.entries[trav].leftsibling].end) - { - ARRAY_APPEND(allocator, stack, index.entries[trav].leftsibling); - } // if - - if (index.entries[trav].rightchild != GVA_NULL) - { - ARRAY_APPEND(allocator, stack, index.entries[trav].rightchild); - } // if - } // while - } // if - - stab = index.entries[stab].parent; - } // while - stack = ARRAY_DESTROY(allocator, stack); - - return results; -} // gva_stabbing_index_intersect From 39d1f32acddd1448c8a7e46ca4912e280e38c4a8 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Mon, 6 Oct 2025 13:37:33 +0200 Subject: [PATCH 385/704] Breakout vcf processor in seperate function. --- src/main.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main.c b/src/main.c index 44bc7fc..80aea11 100644 --- a/src/main.c +++ b/src/main.c @@ -768,9 +768,8 @@ suffix_trimmed(size_t const len_ref, char const reference[static len_ref], int -main(int argc, char* argv[static argc + 1]) +vcfallele(int argc, char* argv[static argc + 1]) { -/* errno = 0; FILE* stream = fopen(argv[1], "r"); if (stream == NULL) @@ -848,9 +847,12 @@ main(int argc, char* argv[static argc + 1]) table = HASH_TABLE_DESTROY(gva_std_allocator, table); return EXIT_SUCCESS; -*/ +} +int +main(int argc, char* argv[static argc + 1]) +{ errno = 0; FILE* stream = fopen(argv[1], "r"); if (stream == NULL) From dbcb665f59f9eb0548e7ddc5d4bdfe175fa4d68a Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Mon, 6 Oct 2025 13:50:42 +0200 Subject: [PATCH 386/704] Cleanup. --- src/lcs_graph.c | 8 - src/main.c | 451 +----------------------------------------------- 2 files changed, 2 insertions(+), 457 deletions(-) diff --git a/src/lcs_graph.c b/src/lcs_graph.c index af1ff13..539b93f 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -3,10 +3,6 @@ #include // NULL, size_t #include // memcpy - -//#include // DEBUG - - #include "../include/allocator.h" // GVA_Allocator #include "../include/lcs_graph.h" // GVA_LCS_Graph, gva_lcs_graph_* #include "../include/string.h" // GVA_String, gva_string_* @@ -215,7 +211,6 @@ gva_lcs_graph_init(GVA_Allocator const allocator, ARRAY_APPEND(allocator, graph.local_supremal, ((GVA_Node) { graph.nodes[source.idx].row, graph.nodes[source.idx].col, 0, distance - prev_distance, source.idx })); - //fprintf(stderr, "0.APPEND %u: (%u, %u, %u) @ %u\n", i, graph.nodes[source.idx].row, graph.nodes[source.idx].col, 0, distance); prev_distance = distance; } // if if (len > 0 && (lcs.index[i].count > 1 || prev != lcs.index[i].tail)) @@ -226,7 +221,6 @@ gva_lcs_graph_init(GVA_Allocator const allocator, ARRAY_APPEND(allocator, graph.local_supremal, ((GVA_Node) { graph.nodes[idx].row + offset, graph.nodes[idx].col + offset, len, distance - prev_distance, idx })); - //fprintf(stderr, "1.APPEND %u: (%u, %u, %u) @ %u\n", i, graph.nodes[idx].row + offset, graph.nodes[idx].col + offset, len, distance); len = 0; prev_distance = distance; } // if @@ -246,7 +240,6 @@ gva_lcs_graph_init(GVA_Allocator const allocator, ARRAY_APPEND(allocator, graph.local_supremal, ((GVA_Node) { graph.nodes[idx].row + offset, graph.nodes[idx].col + offset, len, distance - prev_distance, idx })); - //fprintf(stderr, "2.APPEND %u: (%u, %u, %u) @ %u\n", lcs.length - len, graph.nodes[idx].row + offset, graph.nodes[idx].col + offset, len, distance); len = 0; prev_distance = distance; } // if @@ -256,7 +249,6 @@ gva_lcs_graph_init(GVA_Allocator const allocator, ARRAY_APPEND(allocator, graph.local_supremal, ((GVA_Node) { graph.nodes[0].row + graph.nodes[0].length - len, graph.nodes[0].col + graph.nodes[0].length - len, 0, distance - prev_distance, 0 })); - //fprintf(stderr, "3.APPEND %u: (%u, %u, %u) @ %u\n", lcs.length - len, graph.nodes[0].row + graph.nodes[0].length - len, graph.nodes[0].col + graph.nodes[0].length - len, 0, distance); } //if if (graph.local_supremal != NULL) diff --git a/src/main.c b/src/main.c index 80aea11..6efba9e 100644 --- a/src/main.c +++ b/src/main.c @@ -33,305 +33,6 @@ #define REFERENCE_ID "NC_000001.11" -static void -lcs_graph_svg(FILE* const stream, GVA_LCS_Graph const graph) -{ - gva_uint const offset = graph.nodes[graph.source].row; - gva_uint const scale = 30; - fprintf(stream, "\n", (graph.nodes[0].col + graph.nodes[0].length) * scale + 2 * scale, (graph.nodes[0].row + graph.nodes[0].length - offset) * scale + 2 * scale); - - fprintf(stream, "\n"); - for (size_t i = 0; i < array_length(graph.nodes); ++i) - { - if (graph.nodes[i].lambda != GVA_NULL) - { - gva_uint const row = (graph.nodes[i].row - offset) * scale + scale; - gva_uint const col = graph.nodes[i].col * scale + scale; - gva_uint const to_row = (graph.nodes[graph.nodes[i].lambda].row - offset) * scale + scale; - gva_uint const to_col = graph.nodes[graph.nodes[i].lambda].col * scale + scale; - fprintf(stream, "\n", col, row, to_col, to_row); - } // if - - for (gva_uint j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) - { - GVA_Variant variant; - gva_uint const count = gva_edges(graph.observed.str, - graph.nodes[i], graph.nodes[graph.edges[j].tail], - i == graph.source, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, - &variant); - - gva_uint const row = (variant.start - (variant.start > 0) - offset); // * scale + scale; - gva_uint const col = (variant.sequence.str - graph.observed.str - (variant.start > 0)); // * scale + scale; - gva_uint const to_row = (variant.end + count - 1 - offset); // * scale + scale; - gva_uint const to_col = (col + count - (variant.start == 0) + variant.sequence.len); // * scale + scale; - - fprintf(stream, "\n", col * scale + scale, row * scale + scale, to_col * scale + scale, to_row * scale + scale, (double) count / 2.0); - } // for - } // for - fprintf(stream, "\n"); - - for (size_t i = 0; i < array_length(graph.nodes); ++i) - { - gva_uint const row = (graph.nodes[i].row - offset) * scale + scale; - gva_uint const col = graph.nodes[i].col * scale + scale; - if (graph.nodes[i].length < 2) - { - fprintf(stream, "\n", col, row); - } // if - else - { - gva_uint const to_row = (graph.nodes[i].row - offset + graph.nodes[i].length) * scale + scale; - gva_uint const to_col = (graph.nodes[i].col + graph.nodes[i].length) * scale + scale; - fprintf(stream, "\n", col, row, to_col, to_row); - fprintf(stream, "\n", col, row, to_col, to_row); - } // else - fprintf(stream, "(%u, %u, %u)\n", col, row + 1, graph.nodes[i].row - offset, graph.nodes[i].col, graph.nodes[i].length); - if (graph.nodes[i].lambda != GVA_NULL) - { - gva_uint const row = (graph.nodes[graph.nodes[i].lambda].row - offset) * scale + scale; - gva_uint const col = graph.nodes[graph.nodes[i].lambda].col * scale + scale; - fprintf(stream, "(%u, %u, %u)\n", col, row + 1, graph.nodes[graph.nodes[i].lambda].row - offset, graph.nodes[graph.nodes[i].lambda].col, graph.nodes[graph.nodes[i].lambda].length); - } // ifr - } // for - fprintf(stream, "\n"); -} // lcs_graph_svg - - -static void -lcs_graph_dot(FILE* const stream, GVA_LCS_Graph const graph) -{ - fprintf(stream, "strict digraph{\nrankdir=LR\nedge[fontname=monospace]\nnode[fixedsize=true,fontname=serif,shape=circle,width=1]\ni[label=\"\",shape=none,width=0]\ni->%u\n", graph.source); - for (size_t i = 0; i < array_length(graph.nodes); ++i) - { - fprintf(stream, "%zu[label=\"(%u, %u, %u)\"%s]\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, graph.nodes[i].edges == GVA_NULL ? ",peripheries=2" : ""); - if (graph.nodes[i].lambda != GVA_NULL) - { - fprintf(stream, "%zu->%u[label=\"λ\",style=dashed]\n", i, graph.nodes[i].lambda); - } // if - for (gva_uint j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) - { - GVA_Variant variant; - gva_uint const count = gva_edges(graph.observed.str, - graph.nodes[i], graph.nodes[graph.edges[j].tail], - i == graph.source, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, - &variant); - if (count > 1) - { - fprintf(stream, "%zu->%u[label=\"" GVA_VARIANT_FMT " x %u\",penwidth=2]\n", i, graph.edges[j].tail, GVA_VARIANT_PRINT(variant), count); - } // if - else - { - fprintf(stream, "%zu->%u[label=\"" GVA_VARIANT_FMT "\"]\n", i, graph.edges[j].tail, GVA_VARIANT_PRINT(variant)); - } // else - } // for - } // for - for (size_t i = 0; i < array_length(graph.local_supremal); ++i) - { - fprintf(stream, "%u[penwidth=2]\n", graph.local_supremal[i].lambda); - } // for - fprintf(stream, "}\n"); -} // lcs_graph_dot - - -static void -bfs_traversal(FILE* const stream, GVA_LCS_Graph const graph) -{ - struct - { - gva_uint depth; - gva_uint next; - }* table = gva_std_allocator.allocate(gva_std_allocator.context, NULL, 0, sizeof(*table) * array_length(graph.nodes)); - if (table == NULL) - { - return; - } // if - - for (size_t i = 0; i < array_length(graph.nodes); ++i) - { - table[i].depth = 0; - table[i].next = GVA_NULL; - } // for - gva_uint head = graph.source; - gva_uint tail = graph.source; - - bool first = true; - fprintf(stream, " \"edges\": [\n"); - while (head != GVA_NULL) - { - gva_uint len = graph.nodes[head].length; - for (gva_uint i = head; i != GVA_NULL; i = graph.nodes[i].lambda) - { - if (i != head) - { - len += graph.nodes[i].length; - } // if - for (gva_uint j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) - { - GVA_Variant variant; - gva_uint const count = gva_edges(graph.observed.str, - graph.nodes[i], graph.nodes[graph.edges[j].tail], - i == graph.source, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, - &variant); - - for (gva_uint k = 0; k < count; ++k) - { - if (!first) - { - printf(",\n"); - } // if - first = false; - fprintf(stream, " {\"head\": \"s%u\", \"tail\": \"s%u\", \"variant\": \"" GVA_VARIANT_FMT "\"}", head, graph.edges[j].tail, GVA_VARIANT_PRINT(variant)); - variant.start += 1; - variant.end += 1; - variant.sequence.str += 1; - } // for - - if (table[graph.edges[j].tail].depth > 0) - { - continue; - } // if - - table[graph.edges[j].tail].depth = table[i].depth + 1; - table[tail].next = graph.edges[j].tail; - tail = graph.edges[j].tail; - } // for - } // for - head = table[head].next; - } // while - - fprintf(stream, "\n ],\n"); - - table = gva_std_allocator.allocate(gva_std_allocator.context, table, sizeof(*table) * array_length(graph.nodes), 0); -} // bfs_traversal - - -static void -lcs_graph_json(FILE* const stream, GVA_LCS_Graph const graph) -{ - fprintf(stream, "{\n \"source\": \"s%u\",\n \"nodes\": {\n", graph.source); - for (gva_uint i = 0; i < array_length(graph.nodes); ++i) - { - fprintf(stream, " \"s%u\": {\"row\": %u, \"col\": %u, \"length\": %u}%s\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, i < array_length(graph.nodes) - 1 ? "," : ""); - } // for - fprintf(stream, " },\n"); - bfs_traversal(stream, graph); - fprintf(stream, " \"local_supremal\": [\n"); - if (array_length(graph.local_supremal) > 1) - { - for (size_t i = 0; i < array_length(graph.local_supremal) - 1; ++i) - { - GVA_Variant variant; - gva_edges(graph.observed.str, - graph.local_supremal[i], graph.local_supremal[i + 1], - i == 0, i == array_length(graph.local_supremal) - 2, - &variant); - fprintf(stream, " \"" GVA_VARIANT_FMT "\"%s\n", GVA_VARIANT_PRINT(variant), i < array_length(graph.local_supremal) - 2 ? "," : ""); - } // for - } // if - fprintf(stream, " ],\n \"supremal\": \"" GVA_VARIANT_FMT "\",\n", GVA_VARIANT_PRINT(graph.supremal)); - fprintf(stream, " \"canonical\": [\n"); - GVA_Variant* canonical = gva_canonical(gva_std_allocator, graph); - for (size_t i = 0; i < array_length(canonical); ++i) - { - fprintf(stream, " \"" GVA_VARIANT_FMT "\"%s\n", GVA_VARIANT_PRINT(canonical[i]), i < array_length(canonical) - 1 ? "," : ""); - } // for - canonical = ARRAY_DESTROY(gva_std_allocator, canonical); - - fprintf(stream, " ],\n \"distance\": %u\n", graph.distance); - fprintf(stream, "}\n"); -} // lcs_graph_json - - -static void -lcs_graph_raw(FILE* const stream, GVA_LCS_Graph const graph) -{ - fprintf(stream, "#nodes: %zu\n#edges: %zu\n", array_length(graph.nodes), array_length(graph.edges)); - fprintf(stream, "distance: %u\n", graph.distance); - fprintf(stream, "source: %u\n", graph.source); - fprintf(stream, "local supremal:\n"); - if (array_length(graph.local_supremal) > 1) - { - for (size_t i = 0; i < array_length(graph.local_supremal) - 1; ++i) - { - GVA_Variant variant; - gva_edges(graph.observed.str, - graph.local_supremal[i], graph.local_supremal[i + 1], - i == 0, i == array_length(graph.local_supremal) - 2, - &variant); - fprintf(stream, " (%u, %u, %u) -> (%u, %u, %u): " GVA_VARIANT_FMT "\n", - graph.local_supremal[i].row, graph.local_supremal[i].col, graph.local_supremal[i].length, - graph.local_supremal[i + 1].row, graph.local_supremal[i + 1].col, graph.local_supremal[i + 1].length, - GVA_VARIANT_PRINT(variant)); - } // for - } // if - - if (graph.nodes == NULL) - { - return; - } // if - - for (size_t i = 0; i < array_length(graph.nodes); ++i) - { - fprintf(stream, "%zu: (%u, %u, %u):\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length); - if (graph.nodes[i].lambda != GVA_NULL) - { - fprintf(stream, " lambda: (%u, %u, %u)\n", graph.nodes[graph.nodes[i].lambda].row, graph.nodes[graph.nodes[i].lambda].col, graph.nodes[graph.nodes[i].lambda].length); - } // if - for (gva_uint j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) - { - fprintf(stream, " %u: (%u, %u, %u): ", graph.edges[j].tail, graph.nodes[graph.edges[j].tail].row, graph.nodes[graph.edges[j].tail].col, graph.nodes[graph.edges[j].tail].length); - GVA_Variant variant; - gva_uint const count = gva_edges(graph.observed.str, - graph.nodes[i], graph.nodes[graph.edges[j].tail], - i == graph.source, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, - &variant); - fprintf(stream, GVA_VARIANT_FMT " x %u\n", GVA_VARIANT_PRINT(variant), count); - } // for - } // for -} // lcs_graph_raw - - -int -extract(int const argc, char* argv[static argc + 1]) -{ - if (argc != 3) - { - fprintf(stderr, "usage %s reference observed\n", argv[0]); - return EXIT_FAILURE; - } // if - - /* - char const* const restrict reference = "ATTCTATCTTCTGTCTACATAAGATGTCATACTAGAGGGCATATCTGCAATGTATACATATTATCTTTTCCAGCATGCATTCAGTTGTGTTGGAATAATTTATGTACACCTTTATAAACGCTGAGCCTCACAAGAGCCATGTGCCACGTATTGTTTTCTTACTACTTTTTGGGATACCTGGCACGTAATAGACACTCATTGAAAGTTTCCTAATGAATGAAGTACAAAGATAAAACAAGTTATAGACTGATTCTTTTGAGCTGTCAAGGTTGTAAATAGACTTTTGCTCAATCAATTCAAATGGTGGCAGGTAGTGGGGGTAGAGGGATTGGTATGAAAAACATAAGCTTTCAGAACTCCTGTGTTTATTTTTAGAATGTCAACTGCTTGAGTGTTTTTAACTCTGTGGTATCTGAACTATCTTCTCTAACTGCAGGTTGGGCTCAGATCTGTGATAGAACAGTTTCCTGGGAAGCTTGACTTTGTCCTTGTGGATGGGGGCTGTGTCCTAAGCCATGGCCACAAGCAGTTGATGTGCTTGGCTAGATCTGTTCTCAGTAAGGCGAAGATCTTGCTGCTTGATGAACCCAGTGCTCATTTGGATCCAGTGTGAGTTTCAGATGTTCTGTTACTTAATAGCACAGTGGGAACAGAATCATTATGCCTGCTTCATGGTGACACATATTTCTATTAGGCTGTCATGTCTGCGTGTGGGGGTCTCCCCCAAGATATGAAATAATTGCCCAGTGGAAATGAGCATAAATGCATATTTCCTTGCTAAGAGTCTTGTGTTTTCTTCCGAAGATAGTTTTTAGTTTCATACAAACTCTTCCCCCTTGTCAACACATGATGAAGCTTTTAAATACATGGGCCTAATCTGATCCTTATGATTTGCCTTTGTATCCCATTTATACCATAAGCATGTTTATAGCCCCAAATAAAGAAGTACTGGTGATTCTACATAATGAAAAATGTACTCATTTATTAAAGTTTCTTTGAAATATTTGTCCTGTTTATTTATGGATACTTAGAGTCTACCCCATGGTTGAAAAGCTGATTGTGGCTAACGCTATATCAACATTATGTGAAAAGAACTTAAAGAAATAAGTAATTTAAAGAGATAATAGAACAATAGACATATTATCAAGGTAAATACAGATCATTACTGTTCTGTGATATTATGTGTGGTATTTTCTTTCTTTTCTAGAACATACCAAATAATTAGAAGAACTCTAAAACAAGCATTTGCTGATTGCACAGTAATTCTCTGTGAACACAGGATAGAAGCAATGCTGGAATGCCAACAATTTTTGGTGAGTCTTTATAACTTTACTTAAGATCTCATTGCCCTTGTAATTCTTGATAACAATCTCACATGTGATAGTTCCTGCAAATTGCAACAATGTACAAGTTCTTTTCAAAAATATGTATCATACAGCCATCCAGCTTTACTCAAAATAGCTGCACAAGTTTTTCACTTTGATCTGAGCCATGTGGTGAGGTTGAAATATAGTAAATCTAAAATGGCAGCATATTACTAAGTTATGTTTATAAATAGGATATATATACTTTTTGAGCCCTTTATTTGGGGACCAAGTCATACAAAATACTCTACTGTTTAAGATTTTAAAAAAGGTCCCTGTGATTCTTTCAATAACTAAATGTCCCATGGATGTGGTCTGGGACAGGCCTAGTTGTCTTACAGTCTGATTTATGGTATTAATGACAAAGTTGAGAGGCACATTTCATTTTT"; - char const* const restrict observed = "ATTCTATCTTCTGTCTACATAAGATGTCATACTAGAGGGCATATCTGCAATGTATACATATTATCTTTTCCAGCATGCATTCAGTTGTGTTGGAATAATTTATGTACACCTTTATAAACGCTGAGCCTCACAAGAGCCATGTGCCACGTATTGTTTTCTTACTACTTTTTGGGATACCTGGCACGTAATAGACACTCATTGAAAGTTTCCTAATGAATGAAGTACAAAGATAAAACAAGTTATAGACTGATTCTTTTGAGCTGTCAAGGTTGTAAATAGACTTTTGCTCAATCAATTCAAATGGTGGCAGGTAGTGGGGGTAGAGGGATTGGTATGAAAAACATAAGCTTTCAGAACTCCTGTGTTTATTTTTAGAATGTCAACTGCTTGAGTGTTTTTAACTCTGTGGTATCTGAACTATCTTCTCTAACTGCAGGTGAGTCTTTATAACTTTACTTAAGATCTCATTGCCCTTGTAATTCTTGATAACAATCTCACATGTGATAGTTCCTGCAAATTGCAACAATGTACAAGTTCTTTTCAAAAATATGTATCATACAGCCATCCAGCTTTACTCAAAATAGCTGCACAAGTTTTTCACTTTGATCTGAGCCATGTGGTGAGGTTGAAATATAGTAAATCTAAAATGGCAGCATATTACTAAGTTATGTTTATAAATAGGATATATATACTTTTTGAGCCCTTTATTTGGGGACCAAGTCATACAAAATACTCTACTGTTTAAGATTTTAAAAAAGGTCCCTGTGATTCTTTCAATAACTAAATGTCCCATGGATGTGGTCTGGGACAGGCCTAGTTGTCTTACAGTCTGATTTATGGTATTAATGACAAAGTTGAGAGGCACATTTCATTTTT"; - */ - char const* const restrict reference = argv[1]; - char const* const restrict observed = argv[2]; - - size_t const len_ref = strlen(reference); - size_t const len_obs = strlen(observed); - - GVA_LCS_Graph graph = gva_lcs_graph_init(gva_std_allocator, len_ref, reference, len_obs, observed, 0); - - //lcs_graph_raw(stderr, graph); - lcs_graph_dot(stderr, graph); - //lcs_graph_json(stdout, graph); - //lcs_graph_svg(stderr, graph); - - /* - GVA_Variant* canonical = gva_canonical(gva_std_allocator, graph); - for (size_t i = 0; i < array_length(canonical); ++i) - { - fprintf(stderr, GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(canonical[i])); - } // for - canonical = ARRAY_DESTROY(gva_std_allocator, canonical); - */ - - gva_lcs_graph_destroy(gva_std_allocator, graph); - - return EXIT_SUCCESS; -} // extract - - // FIXME: see `match_number` in src/variant.c static inline size_t parse_number(char const buffer[static 1], size_t idx[static 1]) @@ -346,90 +47,6 @@ parse_number(char const buffer[static 1], size_t idx[static 1]) } // parse_number -void -trie_dot(FILE* const stream, Trie const self) -{ - fprintf(stream, "strict digraph{\n\"root\"[label=\"\",shape=point]\n"); - if (self.nodes != NULL) - { - for (gva_uint i = self.root; i != GVA_NULL; i = self.nodes[i].next) - { - int const p_len = self.nodes[i].end - self.nodes[i].p_start; - fprintf(stream, "root->%u[label=\"%.*s\"]\n", i, p_len, self.strings.str + self.nodes[i].p_start); - } // for - for (size_t i = 0; i < array_length(self.nodes); ++i) - { - int const len = self.nodes[i].end - self.nodes[i].start; - fprintf(stream, "%zu[label=\"%zu\\n%.*s\"]\n", i, i, len, self.strings.str + self.nodes[i].start); - for (gva_uint j = self.nodes[i].link; j != GVA_NULL; j = self.nodes[j].next) - { - int const p_len = self.nodes[j].end - self.nodes[j].p_start; - fprintf(stream, "%zu->%u[label=\"%.*s\"]\n", i, j, p_len, self.strings.str + self.nodes[j].p_start); - } // for - } // for - } // if - fprintf(stream, "}\n"); -} // trie_dot - - -void -trie_raw(FILE* const stream, Trie const self) -{ - fprintf(stream, "root: %u\n", self.root); - fprintf(stream, "strings (%zu): %.*s\n", self.strings.len, (int) self.strings.len, self.strings.str); - fprintf(stream, "nodes (%zu):\n", array_length(self.nodes)); - for (size_t i = 0; i < array_length(self.nodes); ++i) - { - fprintf(stream, "[%zu]\n .link: %2d\n .next: %2d\n .p_start: %2u\n .start: %2u\n .end: %2u\n", i, self.nodes[i].link, self.nodes[i].next, self.nodes[i].p_start, self.nodes[i].start, self.nodes[i].end); - } // for -} // trie_raw - - -void -interval_tree_dot(FILE* const stream, Interval_Tree const self) -{ - fprintf(stream, "strict digraph{\n"); - for (size_t i = 0; i < array_length(self.nodes); ++i) - { - fprintf(stream, "%zu[label=\"{[%u, %u), %u} %u %d\"]\n", i, self.nodes[i].start, self.nodes[i].end, self.nodes[i].inserted, self.nodes[i].max, self.nodes[i].alleles); - if (self.nodes[i].child[0] != GVA_NULL) - { - fprintf(stream, "%zu->%u\n", i, self.nodes[i].child[0]); - } // if - if (self.nodes[i].child[1] != GVA_NULL) - { - fprintf(stream, "%zu->%u\n", i, self.nodes[i].child[1]); - } // if - } // if - fprintf(stream, "}\n"); -} // interval_tree_dot - - -void -bitset_print(size_t const bitset[static 1], size_t const size) -{ - for (intmax_t i = array_length(bitset) * sizeof(*bitset) * CHAR_BIT - 1; i >= 0; --i) - { - if ((size_t) i > size) - { - fprintf(stderr, " "); - } // if - else - { - fprintf(stderr, "%zu", bitset[i / (sizeof(*bitset) * CHAR_BIT)] >> (i % (sizeof(*bitset) * CHAR_BIT)) & 0x1); - } // else - if (i % (sizeof(*bitset) * CHAR_BIT) == 0) - { - fprintf(stderr, "\n"); - } // if - else if (i % CHAR_BIT == 0) - { - fprintf(stderr, " "); - } // if - } // for -} // bitset_print - - GVA_Relation compare_from_index(GVA_String const reference, GVA_Variant const lhs, gva_uint const lhs_dist, @@ -551,62 +168,6 @@ compare_from_index(GVA_String const reference, } // compare_from_index -int -compare(int argc, char* argv[static argc + 1]) -{ - GVA_String reference = {0, NULL}; - errno = 0; - FILE* const restrict stream = fopen(argv[1], "r"); - if (stream == NULL) - { - fprintf(stderr, "error: %s\n", strerror(errno)); - return EXIT_FAILURE; - } // if - reference = gva_fasta_sequence(gva_std_allocator, stream); - fclose(stream); - - char lhs_hgvs[4096]; - char lhs_spdi[4096]; - size_t lhs_dist; - char rhs_hgvs[4096]; - char rhs_spdi[4096]; - size_t rhs_dist; - size_t dist; - char python[32]; - size_t common_count; - size_t union_count; - size_t count = 0; - // NC_000001.11:6100897:2:CC 2 NC_000001.11:6100895:3:GGG 2 2 overlap 1 8 - while (fscanf(stdin, "%4096s %zu %4096s %zu %zu %32s %zu %zu\n", lhs_spdi, &lhs_dist, rhs_spdi, &rhs_dist, &dist, python, &common_count, &union_count) == 8) - { - GVA_Variant lhs; - if (!gva_parse_spdi(strlen(lhs_spdi), lhs_spdi, &lhs)) - { - fprintf(stderr, "PARSE ERROR: %s\n", lhs_spdi); - continue; - } // if - GVA_Variant rhs; - if (!gva_parse_spdi(strlen(rhs_spdi), rhs_spdi, &rhs)) - { - fprintf(stderr, "PARSE ERROR: %s\n", rhs_spdi); - continue; - } // if - - size_t const relation = gva_compare_supremals(gva_std_allocator, reference.len, reference.str, lhs, rhs); - if (strcmp(python, GVA_RELATION_LABELS[relation]) != 0) - { - printf("%s %s %s %s %s\n", lhs_hgvs, lhs_spdi, rhs_hgvs, rhs_spdi, GVA_RELATION_LABELS[relation]); - } // if - - count += 1; - } // while - fprintf(stderr, "total: %zu\n", count); - gva_string_destroy(gva_std_allocator, reference); - - return EXIT_SUCCESS; -} // compare - - size_t variants_distance(GVA_Allocator const allocator, size_t const len_ref, char const reference[static len_ref], GVA_Variant const lhs, GVA_Variant const rhs) { @@ -768,7 +329,7 @@ suffix_trimmed(size_t const len_ref, char const reference[static len_ref], int -vcfallele(int argc, char* argv[static argc + 1]) +vcf_main(int argc, char* argv[static argc + 1]) { errno = 0; FILE* stream = fopen(argv[1], "r"); @@ -1410,14 +971,6 @@ main(int argc, char* argv[static argc + 1]) trie_destroy(gva_std_allocator, &trie); gva_string_destroy(gva_std_allocator, reference); - return EXIT_SUCCESS; - - // return extract(argc, argv); - - // all - //return all(argc, argv); - - // compare - // return compare(argc, argv); + return EXIT_SUCCESS; } // main From d6a72a89e8a5d2d5b10c50ece5887255e962ca91 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Mon, 6 Oct 2025 13:56:48 +0200 Subject: [PATCH 387/704] New regres set in progress. --- test_alleles.txt | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 test_alleles.txt diff --git a/test_alleles.txt b/test_alleles.txt new file mode 100644 index 0000000..8b91ba8 --- /dev/null +++ b/test_alleles.txt @@ -0,0 +1,41 @@ +769288 NC_000001.11:85456095:12:AAAAAAAAAA +769288 NC_000001.11:85456095:12:AAAAAAAAAAA +769288 NC_000001.11:85456095:12:AAAAAAAAAAAAA +769288 NC_000001.11:85456095:12:AAAAAAAAAAAAAA +1045609 NC_000001.11:85456095:12:AAAAGAAAAAAA +538 NC_000001.11:6100897:1:T +538 NC_000001.11:6100897:2:CC +538 NC_000001.11:6100895:3:GGG +549 NC_000001.11:15220327:2:CC +549 NC_000001.11:15220328:1:G +549 NC_000001.11:15220328:2:TT +2062 NC_000001.11:236991590:3:CCT +2063 NC_000001.11:236991589:2:CC +367303 NC_000001.11:52722559:21:TTTTTTTTTCTTTTTTTTTTT +367307 NC_000001.11:52722559:21:TTTTTCTTTTTTTTTTTTTTT +481173 NC_000001.11:74278135:3:TTT +33986771 NC_000001.11:74278137:1:TTTTT +2236904 NC_000001.11:209714022:2:AA +372241832 NC_000001.11:209714023:2:GTCATT +2090782046 NC_000001.11:149733075:4:GGTT +3029678 NC_000001.11:149733077:2:TGTTTT +3220523 NC_000001.11:154309540:45:CACACACACACACACACACACACACACACACACACACACACACA +5006305 NC_000001.11:154309583:3:AAA +5006305 NC_000001.11:154309584:1:C +5006305 NC_000001.11:154309584:1:G +597939 NC_000001.11:58651436:3:TGT +3222756 NC_000001.11:58651407:35:TGTGTGTGTGTGTGTGTGTGTGTGTGTGTGTGTGTGTG +2861166 NC_000001.11:175225135:1:A +3220119 NC_000001.11:175225135:4:ACACA +3831929 NC_000001.11:147276340:5:CACCAGCCC +3831929 NC_000001.11:147276342:2:GCCA +71498946 NC_000001.11:248280509:2:AC +386641973 NC_000001.11:248280507:4:GTAC +4071802 NC_000001.11:144735932:18:GGAGAGAGAGAGAGAGAGAGAGA +4071802 NC_000001.11:144735947:2:GAGAG +57438612 NC_000001.11:148271316:3:ACTAAGATT +57438612 NC_000001.11:148271316:3:TACTAAGATTT +113010908 NC_000001.11:143535768:9:TTTTTTTTTTT +202102073 NC_000001.11:143535768:9:TTTTTTTTTTT +879278532 NC_000001.11:164871874:5:AC +746240940 NC_000001.11:164871870:9: From ced80f83c12d5e74b914517fe9979e7f93c507e3 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Mon, 6 Oct 2025 13:57:02 +0200 Subject: [PATCH 388/704] Cleanup. --- regres.sh | 67 ---------------------- test.py | 169 ------------------------------------------------------ 2 files changed, 236 deletions(-) delete mode 100755 regres.sh delete mode 100644 test.py diff --git a/regres.sh b/regres.sh deleted file mode 100755 index fbaba9b..0000000 --- a/regres.sh +++ /dev/null @@ -1,67 +0,0 @@ -set -o errexit - -TESTS=( -TATCCGTCCG GAAAAATCCG -GCCTGCCTAT GCCTAAAAAG -TGCCTTA TAGCAGCCC -CCC CACCCACA -TTGGGAA CCGAATA -GACAT ACACTCCCAT -GAG AGGATAAGT -CACGCTCGT ACACT -GTTTA TCTTTCTGC -TCAACAAAGG CAA -CTTATAAT CCTACCG -GG GGTCA -"" AAT -CGATGT TGTGA -AGTGG TGGGGTAGT -CGAG CGAG -GGCGAA GGACCA -CTCCTCGGA ACCTCGTCTG -TTTCCAG TTGTTCA -CGGGGGC CCGGCCG -CTATATAAAC CTCGTAA -TTAATTAGTT GACGTTAATT -TAAG TAAGACCGC -GGCGA GGTTTTA -GGCTGC GCTCCAA -CTGGGGAG CCACCTGGGC -CATTTCACGA TCGCCC -GCC CGACGAGCCC -AGAGAAAAA AAAA -# Python algebra -"" "" -"" C -C "" -C G -CATC GATG -AGAATTGCTTGAA AGGGTTAAA -CTCTAGAGACTTTATTTTCCAC GTCTCAGACTTTCTTTATCCCC -ATATACCTTTTA CTATAGCCTTTTTC -CAGGGGAAGTG GCAGGGGCCTA -TCGTGGT CTAACAT -TGCATTAGGGCAAGGGTCTTCGACTTTCCACGAAAATCGCGTCGGTTTGAC TGCATTAGGGCAAGGGTCTTCGACTTCCACGAAAATCGCGTCGGTTTGAC -TGCATTAGGGCAAGGGTCTTCGACTTTCCACGAAAATCGCGTCGGTTTGAC TGCATTAGGGCAAGGGTCTTCGACTTCCACGAAAATCGCGTCGGTTGAC -CTCGGCATTA GGCTGGCTGT -TTT TTTTAT -TTTTAT TTT -TTAATTGACA CTACTGAGTT -TCTCTATCGTA TCTA -AAAATA GAAAAGAAA -CATATATCG CTTATAGCAT -TCTC TC -TTGTA TTTGTGTT -AA ACA -ACA AA -AGGCCG CGCAGCCTC -ACAGGA CAAGGCG -TAATTGGTAG CTATTCAG -TTAAG TAACA -# paper -ACCTGACT ATCTTACTT -) - -for ((i=0; i<${#TESTS[@]}; i+=2)); do - python test.py "${TESTS[i]}" "${TESTS[i+1]}" -done diff --git a/test.py b/test.py deleted file mode 100644 index 57708cf..0000000 --- a/test.py +++ /dev/null @@ -1,169 +0,0 @@ -import json -# import random -import signal -import subprocess -import sys - -from itertools import chain -#import networkx as nx - -from algebra import LCSgraph -from algebra.extractor import local_supremal -from algebra.extractor.extractor import canonical -from algebra.utils import random_sequence, to_dot -from algebra.variants import Variant - - -def handler(signum, frame): - raise KeyboardInterrupt - - -def nx_extract(reference, observed): - # Create graph in C - stdout = subprocess.run(["./a.out", reference, observed, "true"], check=True, stdout=subprocess.PIPE).stdout.decode("utf-8") - try: - cgraph = json.loads(stdout) - except json.decoder.JSONDecodeError as exc: - print(f'\"{stdout}\"') - raise exc - - # Set source and guess sink - source = cgraph["source"] - i = iter(cgraph["nodes"]) - while True: - try: - sink = next(i) - except StopIteration: - break - if sink != source: - break - - # Convert C string variant into Variant object - def str2var(desc): - if desc == "lambda": - return None - - start, remainder = desc.split(":") - end, inserted = remainder.split("/") - return Variant(int(start), int(end), inserted) - - # Convert C graph to NetworkX - mdg = nx.MultiDiGraph() - mdg.add_nodes_from([(k, cgraph["nodes"][k]) for k in cgraph["nodes"]]) - mdg.add_edges_from([(e['head'], e['tail'], {'variant': str2var(e['variant']), 'weight': 0 if str(e['variant']) == 'lambda' else 1}) for e in cgraph["edges"]]) - - # Find all shortest paths and create a new subgraph with only those nodes - all_paths = nx.all_shortest_paths(mdg, source, sink, weight="weight") - mdg = mdg.subgraph(set(chain(*all_paths))) - - # Calculate the dominators on the reversed graph - postdoms = nx.immediate_dominators(mdg.reverse(), sink) - - # Extract local supremals from reduced graph - local_supremal = [] - lhs = source - while lhs != postdoms[lhs]: - rhs = postdoms[lhs] - if not (mdg.nodes[lhs]["row"] + mdg.nodes[lhs]["length"] == mdg.nodes[rhs]["row"] + mdg.nodes[rhs]["length"] and - mdg.nodes[lhs]["col"] + mdg.nodes[lhs]["length"] == mdg.nodes[rhs]["col"] + mdg.nodes[rhs]["length"]): - del_start = min([e[2].start for e in filter(lambda e: e[2], mdg.out_edges(lhs, data="variant"))]) - del_end = max([e[2].end for e in filter(lambda e: e[2], mdg.in_edges(rhs, data="variant"))]) - ins_start = mdg.nodes[lhs]["col"] + del_start - mdg.nodes[lhs]["row"] - ins_end = mdg.nodes[rhs]["col"] + del_end - mdg.nodes[rhs]["row"] - v = Variant(del_start, del_end, observed[ins_start: ins_end]) - local_supremal.append(v) - lhs = rhs - - # Validate against original Python implementation - for lhs, rhs in zip(reversed(cgraph["canonical"]), local_supremal): - assert lhs == str(rhs), f'canonical elements differ: {lhs} vs {rhs}' - - -def check(reference, observed, debug=False, timeout=2): - #graph = LCSgraph.from_sequence(reference, observed) - graph = LCSgraph(reference, observed) - valgrind = [] - if debug: - print("\n".join(to_dot(reference, graph, labels=False, hgvs=False))) - print(canonical(graph)) - valgrind = ["valgrind", "--leak-check=full", "--error-exitcode=1"] - - stdout = subprocess.run([*valgrind, "./a.out", reference, observed], check=True, stderr=subprocess.DEVNULL, stdout=subprocess.PIPE, timeout=timeout).stdout.decode("utf-8") - - try: - cgraph = json.loads(stdout) - except json.decoder.JSONDecodeError as exc: - print(f'\"{stdout}\"') - raise exc - - assert cgraph["distance"] == graph.distance, f'disances differ: {cgraph["distance"]} vs {graph.distance}' - assert cgraph["supremal"] == str(graph.supremal), f'supremals differ: {cgraph["supremal"]} vs {graph.supremal}' - - nodes = list(graph.nodes()) - edges = list(graph.bfs_traversal()) - - assert len(cgraph["nodes"]) == len(nodes), f'# cgraph nodes {len(cgraph["nodes"])} vs # graph nodes {len(nodes)}' - assert len(cgraph["edges"]) == len(edges), f'# cgraph edges {len(cgraph["edges"])} vs # graph edges {len(edges)}' - - for cnode in cgraph["nodes"].values(): - try: - cnode["node"] = next(node for node in nodes if node.row == cnode["row"] and node.col == cnode["col"]) - except StopIteration: - raise ValueError(f'{cnode} not in graph nodes') from None - - for cedge in cgraph["edges"]: - head = cgraph["nodes"][cedge["head"]]["node"] - tail = cgraph["nodes"][cedge["tail"]]["node"] - try: - next((t, v) for t, v in head.edges if t == tail and str(v) == cedge["variant"]) - except StopIteration: - raise ValueError(f'{cedge} not in edges of {head}') from None - - assert len(cgraph["local_supremal"]) == len(local_supremal(reference, graph)), f'local supremal length' - - for lhs, rhs in zip(cgraph["local_supremal"], local_supremal(reference, graph)): - assert lhs == str(rhs), f'local supremal elements differ: {lhs} vs {rhs}' - - assert len(cgraph["canonical"]) == len(canonical(graph)), f'canonical length' - - for lhs, rhs in zip(cgraph["canonical"], canonical(graph)): - assert lhs == str(rhs), f'canonical elements differ: {lhs} vs {rhs}' - - -def main(): - if len(sys.argv) == 3: - print(sys.argv[1], sys.argv[2]) - return check(sys.argv[1], sys.argv[2], debug=False) - - signal.signal(signal.SIGINT, handler) - - failed = [] - n = 0 - while True: - prefix = "" - suffix = "" - #if random.random() > 0.5: - # prefix = random_sequence(1000) - # suffix = random_sequence(1000) - reference = prefix + random_sequence(142) + suffix - observed = prefix + random_sequence(142) + suffix - - if n % 1_000 == 0: - print(n) - - try: - check(reference, observed) - # nx_extract(reference, observed) - n += 1 - except KeyboardInterrupt: - break - except Exception as exc: - failed.append({"reference": reference, "observed": observed, "exception": exc}) - break - - print() - print(n, failed) - - -if __name__ == "__main__": - main() From 593b1f3d4e75c68684c94fb86e59c5f794ca9725 Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 6 Oct 2025 15:33:32 +0200 Subject: [PATCH 389/704] Some random 'improvements' --- src/main.c | 144 +++++++++++++++++++++++++++++------------------------ 1 file changed, 78 insertions(+), 66 deletions(-) diff --git a/src/main.c b/src/main.c index 6efba9e..513a230 100644 --- a/src/main.c +++ b/src/main.c @@ -168,8 +168,10 @@ compare_from_index(GVA_String const reference, } // compare_from_index -size_t -variants_distance(GVA_Allocator const allocator, size_t const len_ref, char const reference[static len_ref], GVA_Variant const lhs, GVA_Variant const rhs) +static size_t +variants_distance(GVA_Allocator const allocator, + size_t const len_ref, char const reference[static len_ref], + GVA_Variant const lhs, GVA_Variant const rhs) { size_t const start = MIN(lhs.start, rhs.start); size_t const end = MAX(lhs.end, rhs.end); @@ -177,41 +179,45 @@ variants_distance(GVA_Allocator const allocator, size_t const len_ref, char cons size_t const lhs_len = (lhs.start - start) + lhs.sequence.len + (end - lhs.end); size_t const rhs_len = (rhs.start - start) + rhs.sequence.len + (end - rhs.end); - char* lhs_obs = allocator.allocate(allocator.context, NULL, 0, lhs_len); - if (lhs_len > 0) + if (lhs_len == 0) { - if (lhs_obs == NULL) - { - return -1; - } // if - memcpy(lhs_obs, reference + start, lhs.start - start); - memcpy(lhs_obs + lhs.start - start, lhs.sequence.str, lhs.sequence.len); - memcpy(lhs_obs + lhs.start - start + lhs.sequence.len, reference + lhs.end, end - lhs.end); - } + return rhs_len; + } // if + if (rhs_len == 0) + { + return lhs_len; + } // if + char* lhs_obs = allocator.allocate(allocator.context, NULL, 0, lhs_len); char* rhs_obs = allocator.allocate(allocator.context, NULL, 0, rhs_len); - if (rhs_len > 0) + if (lhs_obs == NULL || rhs_obs == NULL) { - if (rhs_obs == NULL && rhs_len > 0) - { - lhs_obs = allocator.allocate(allocator.context, lhs_obs, lhs_len, 0); - return -1; - } // if - memcpy(rhs_obs, reference + start, rhs.start - start); - memcpy(rhs_obs + rhs.start - start, rhs.sequence.str, rhs.sequence.len); - memcpy(rhs_obs + rhs.start - start + rhs.sequence.len, reference + rhs.end, end - rhs.end); - } + lhs_obs = allocator.allocate(allocator.context, lhs_obs, lhs_len, 0); + rhs_obs = allocator.allocate(allocator.context, rhs_obs, rhs_len, 0); + return -1; + } // if + + memcpy(lhs_obs, reference + start, lhs.start - start); + memcpy(lhs_obs + lhs.start - start, lhs.sequence.str, lhs.sequence.len); + memcpy(lhs_obs + lhs.start - start + lhs.sequence.len, reference + lhs.end, end - lhs.end); + + memcpy(rhs_obs, reference + start, rhs.start - start); + memcpy(rhs_obs + rhs.start - start, rhs.sequence.str, rhs.sequence.len); + memcpy(rhs_obs + rhs.start - start + rhs.sequence.len, reference + rhs.end, end - rhs.end); size_t const distance = gva_edit_distance(allocator, lhs_len, lhs_obs, rhs_len, rhs_obs); + rhs_obs = allocator.allocate(allocator.context, rhs_obs, rhs_len, 0); lhs_obs = allocator.allocate(allocator.context, lhs_obs, lhs_len, 0); return distance; -} +} // variants_distance -GVA_Variant -construct_variant(GVA_Allocator const allocator, size_t const len_ref, char const reference[static len_ref], Interval_Tree const tree, Trie const trie, gva_uint* const nodes) +static GVA_Variant +construct_variant(GVA_Allocator const allocator, + size_t const len_ref, char const reference[static len_ref], + Interval_Tree const tree, Trie const trie, gva_uint* const nodes) { size_t const n = array_length(nodes); GVA_Variant* variants = allocator.allocate(allocator.context, NULL, 0, n * sizeof(*variants)); @@ -222,7 +228,7 @@ construct_variant(GVA_Allocator const allocator, size_t const len_ref, char cons tree.nodes[nodes[i]].end, trie_string(trie, tree.nodes[nodes[i]].inserted) }; - } + } // for GVA_Variant lhs = { tree.nodes[nodes[0]].start, @@ -241,45 +247,45 @@ construct_variant(GVA_Allocator const allocator, size_t const len_ref, char cons variants = allocator.allocate(allocator.context, variants, n * sizeof(*variants), 0); return lhs; -} +} // construct_variant -GVA_Relation -multiple_is_contained(GVA_Allocator const allocator, size_t const len_ref, char const reference[static len_ref], GVA_LCS_Graph const graph, size_t const part_idx, Interval_Tree const tree, Trie const trie, gva_uint* const nodes, size_t* const slice_dist) + +static size_t +multiple_is_contained_distance(GVA_Allocator const allocator, + size_t const len_ref, char const reference[static len_ref], + GVA_LCS_Graph const graph, + size_t const part_idx, Interval_Tree const tree, Trie const trie, gva_uint* const nodes) { size_t const n = array_length(nodes); - *slice_dist = 0; + size_t lhs_distance = 0; for (size_t i = 0; i < n; ++i) { - *slice_dist += tree.nodes[nodes[i]].distance; + lhs_distance += tree.nodes[nodes[i]].distance; } // for - size_t const part_dist = graph.local_supremal[part_idx + 1].edges; - if (*slice_dist >= part_dist) + size_t const rhs_distance = graph.local_supremal[part_idx + 1].edges; + if (lhs_distance >= rhs_distance) { - // fprintf(stderr, "Can conclude based on distance only\n"); - return GVA_OVERLAP; - } + return 1; // overlap + } // if + + GVA_Variant const lhs = construct_variant(allocator, len_ref, reference, tree, trie, nodes); - // construct allele GVA_Variant rhs; gva_edges(graph.observed.str, graph.local_supremal[part_idx], graph.local_supremal[part_idx + 1], part_idx == 0, part_idx == array_length(graph.local_supremal) - 2, &rhs); - // fprintf(stderr, GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(rhs)); - - GVA_Variant const lhs = construct_variant(allocator, len_ref, reference, tree, trie, nodes); - size_t const op_distance = variants_distance(allocator, len_ref, reference, rhs, lhs); + size_t const distance = variants_distance(allocator, len_ref, reference, rhs, lhs); gva_string_destroy(allocator, lhs.sequence); - // fprintf(stderr, "part_dist: %zu op_distance: %zu slice_dist: %zu\n", part_dist, op_distance, *slice_dist); - if (part_dist - op_distance != *slice_dist) + if (rhs_distance - distance != lhs_distance) { - return GVA_OVERLAP; - } - return GVA_IS_CONTAINED; -} + return 1; // overlap + } // if + return lhs_distance; +} // multiple_is_contained_distance static inline size_t @@ -439,7 +445,7 @@ main(int argc, char* argv[static argc + 1]) struct Allele { size_t data; - char* spdi; + char* spdi; // FIXME gva_uint join_start; // offset into node_allele_join gva_uint distance; }* db_alleles = NULL; @@ -460,13 +466,17 @@ main(int argc, char* argv[static argc + 1]) } // if GVA_LCS_Graph const graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &variant); + + // FIXME size_t const spdi_len = snprintf(NULL, 0, GVA_VARIANT_FMT_SPDI, GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, graph.supremal)) + 1; char* const spdi = malloc(spdi_len); - if (NULL == spdi) { - (void) fprintf(stderr, "spdi malloc() failed\n"); + if (spdi == NULL) + { + fprintf(stderr, "spdi malloc() failed\n"); return EXIT_FAILURE; } snprintf(spdi, spdi_len, GVA_VARIANT_FMT_SPDI, GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, graph.supremal)); + // end FIXME gva_uint const allele_idx = ARRAY_APPEND( gva_std_allocator, db_alleles, @@ -492,7 +502,6 @@ main(int argc, char* argv[static argc + 1]) } // if tree.nodes[node_idx].alleles = ARRAY_APPEND(gva_std_allocator, node_allele_join, ((struct Node_Allele) {node_idx, allele_idx, tree.nodes[node_idx].alleles})) - 1; // fprintf(stderr, " input part %zu (allele %d): " GVA_VARIANT_FMT " stored at: %d\n", i, allele_idx, GVA_VARIANT_PRINT(part), node_idx); - } // for gva_string_destroy(gva_std_allocator, graph.observed); @@ -573,7 +582,8 @@ main(int argc, char* argv[static argc + 1]) // find candidates for this local supremal part gva_uint* candidates = interval_tree_intersection(gva_std_allocator, tree, query_part.start, query_part.end); - for (size_t can_idx = 0; can_idx < array_length(candidates); ++can_idx) { + for (size_t can_idx = 0; can_idx < array_length(candidates); ++can_idx) + { gva_uint const node_idx = candidates[can_idx]; GVA_Variant const db_var = {tree.nodes[node_idx].start, tree.nodes[node_idx].end, trie_string(trie, tree.nodes[node_idx].inserted)}; @@ -612,7 +622,7 @@ main(int argc, char* argv[static argc + 1]) node_parts_table[hash_idx].relation = GVA_IS_CONTAINED; node_parts_table[hash_idx].included = tree.nodes[node_idx].distance; } // if - else if (relation == GVA_CONTAINS) + else // if (relation == GVA_CONTAINS) { // fprintf(stderr, "yo\n"); // TODO: extend conditional with EQUIVALENT?! @@ -758,6 +768,7 @@ main(int argc, char* argv[static argc + 1]) naj_table_idx = node_allele_join[naj_table_idx].next) { size_t const allele_idx = node_allele_join[naj_table_idx].allele; + // TODO: direct SET size_t hash_idx = HASH_TABLE_INDEX(results_table, allele_idx); if (results_table[hash_idx].gva_key != allele_idx) { @@ -790,8 +801,8 @@ main(int argc, char* argv[static argc + 1]) ++join_idx) { // fprintf(stderr, "join_idx: %zu\n", join_idx); - size_t node_idx = node_allele_join[join_idx].node; - size_t hash_idx = HASH_TABLE_INDEX(node_parts_table, node_idx); + size_t const node_idx = node_allele_join[join_idx].node; + size_t const hash_idx = HASH_TABLE_INDEX(node_parts_table, node_idx); if (node_idx != node_parts_table[hash_idx].gva_key) { // fprintf(stderr, "when?!?\n"); @@ -823,7 +834,7 @@ main(int argc, char* argv[static argc + 1]) } else if (node_parts_table[hash_idx].relation == GVA_IS_CONTAINED) { - size_t part_idx = node_parts_table[hash_idx].part_idx; + size_t const part_idx = node_parts_table[hash_idx].part_idx; // fprintf(stderr, "part_idx: %zu\n", part_idx); // fprintf(stderr, "if containment current: %s\n", GVA_RELATION_LABELS[relation]); if (relation == GVA_CONTAINS) @@ -841,12 +852,12 @@ main(int argc, char* argv[static argc + 1]) if (array_length(is_contained_nodes) > 1) { // fprintf(stderr, "Found multiple is_containeds for the same part\n"); - size_t slice_dist = 0; - relation = multiple_is_contained(gva_std_allocator, reference.len, reference.str, - query_graph, part_idx, tree, trie, is_contained_nodes, &slice_dist); - if (relation == GVA_OVERLAP) + size_t const slice_dist = multiple_is_contained_distance(gva_std_allocator, reference.len, reference.str, + query_graph, part_idx, tree, trie, is_contained_nodes); + if (slice_dist == 1) { included = 1; + relation = GVA_OVERLAP; break; } // if included += slice_dist; @@ -891,12 +902,12 @@ main(int argc, char* argv[static argc + 1]) else if (relation == GVA_IS_CONTAINED && n > 1) { // fprintf(stderr, "Found multiple is_containeds for the same part at the end\n"); - size_t slice_dist = 0; - relation = multiple_is_contained(gva_std_allocator, reference.len, reference.str, - query_graph, is_contained_part_idx, tree, trie, is_contained_nodes, &slice_dist); - if (relation == GVA_OVERLAP) + size_t const slice_dist = multiple_is_contained_distance(gva_std_allocator, reference.len, reference.str, + query_graph, is_contained_part_idx, tree, trie, is_contained_nodes); + if (slice_dist == 1) { included = 1; + relation = GVA_OVERLAP; } // if else { @@ -929,12 +940,13 @@ main(int argc, char* argv[static argc + 1]) { relation = GVA_IS_CONTAINED; } - else if (allele_excluded == 0 && query_excluded == 0) + else // if (allele_excluded == 0 && query_excluded == 0) { relation = GVA_EQUIVALENT; } // fprintf(stderr, "allele_idx: %zu relation: %s in: %zu\n", allele_idx, GVA_RELATION_LABELS[relation], included); + // only for testing if (relation != GVA_EQUIVALENT || db_alleles[allele_idx].data < query_id) { printf("%zu %s %zu %s %s\n", @@ -950,8 +962,8 @@ main(int argc, char* argv[static argc + 1]) // fprintf(stderr, "\n"); - node_parts_table = HASH_TABLE_DESTROY(gva_std_allocator, node_parts_table); results_table = HASH_TABLE_DESTROY(gva_std_allocator, results_table); + node_parts_table = HASH_TABLE_DESTROY(gva_std_allocator, node_parts_table); gva_string_destroy(gva_std_allocator, query_graph.observed); gva_lcs_graph_destroy(gva_std_allocator, query_graph); From bb1521450190b30742764341f6288edb8f90cabe Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Mon, 6 Oct 2025 16:38:47 +0200 Subject: [PATCH 390/704] For the query we don't need to save the spdi. --- src/main.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/main.c b/src/main.c index 513a230..7e8ffd7 100644 --- a/src/main.c +++ b/src/main.c @@ -560,14 +560,6 @@ main(int argc, char* argv[static argc + 1]) GVA_LCS_Graph const query_graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &query_var); // fprintf(stderr, "query allele %zu: " GVA_VARIANT_FMT " (dist: %u)\n", query_id, GVA_VARIANT_PRINT(query_var), query_graph.distance); - size_t const spdi_len = snprintf(NULL, 0, GVA_VARIANT_FMT_SPDI, GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, query_graph.supremal)) + 1; - char* const query_spdi = malloc(spdi_len); - if (NULL == query_spdi) { - (void) fprintf(stderr, "spdi malloc() failed\n"); - return EXIT_FAILURE; - } - snprintf(query_spdi, spdi_len, GVA_VARIANT_FMT_SPDI, GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, query_graph.supremal)); - for (size_t part_idx = 0; part_idx < array_length(query_graph.local_supremal) - 1; ++part_idx) { // query local supremal part @@ -949,11 +941,11 @@ main(int argc, char* argv[static argc + 1]) // only for testing if (relation != GVA_EQUIVALENT || db_alleles[allele_idx].data < query_id) { - printf("%zu %s %zu %s %s\n", + printf("%zu %s %zu " GVA_VARIANT_FMT_SPDI " %s\n", db_alleles[allele_idx].data, db_alleles[allele_idx].spdi, query_id, - query_spdi, + GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, query_graph.supremal), GVA_RELATION_LABELS[relation]); } } // if From ce86c6930579b4ed0ac778365c6730cf9e042581 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Tue, 7 Oct 2025 08:57:49 +0200 Subject: [PATCH 391/704] Properly instantiate relation in node_parts_table. --- src/main.c | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/src/main.c b/src/main.c index 7e8ffd7..9f3f10e 100644 --- a/src/main.c +++ b/src/main.c @@ -586,50 +586,40 @@ main(int argc, char* argv[static argc + 1]) { continue; } - // link nodes to parts + + // link nodes to query parts size_t hash_idx = HASH_TABLE_INDEX(node_parts_table, node_idx); - // fprintf(stderr, "initial hash_idx: %zu\n", hash_idx); if (node_parts_table[hash_idx].gva_key != node_idx) { - // TODO: set correct initial relation HASH_TABLE_SET(gva_std_allocator, node_parts_table, node_idx, - ((struct NODE_PARTS) {node_idx, GVA_DISJOINT, -1, -1, -1, 0})); + ((struct NODE_PARTS) {node_idx, relation, -1, -1, -1, 0})); hash_idx = HASH_TABLE_INDEX(node_parts_table, node_idx); - // fprintf(stderr, "inside if hash_idx: %zu\n", hash_idx); } // if if (relation == GVA_EQUIVALENT) { - node_parts_table[hash_idx].relation = GVA_EQUIVALENT; node_parts_table[hash_idx].included = tree.nodes[node_idx].distance; } // if else if (relation == GVA_OVERLAP) { - node_parts_table[hash_idx].relation = GVA_OVERLAP; node_parts_table[hash_idx].included = 1; } // if else if (relation == GVA_IS_CONTAINED) { node_parts_table[hash_idx].part_idx = part_idx; - node_parts_table[hash_idx].relation = GVA_IS_CONTAINED; node_parts_table[hash_idx].included = tree.nodes[node_idx].distance; } // if - else // if (relation == GVA_CONTAINS) + else { - // fprintf(stderr, "yo\n"); - // TODO: extend conditional with EQUIVALENT?! - if (node_parts_table[hash_idx].relation == GVA_DISJOINT) + if (node_parts_table[hash_idx].included == 0) { - node_parts_table[hash_idx].relation = GVA_CONTAINS; node_parts_table[hash_idx].start = part_idx; node_parts_table[hash_idx].included = query_dist; - } + } // if node_parts_table[hash_idx].end = part_idx + 1; - } // if + } // else } // for every candidate - candidates = ARRAY_DESTROY(gva_std_allocator, candidates); - // fprintf(stderr, "\n"); } // for query allele parts // We have now compared all query parts to the index From 8ae7a60388e51322f8e24f5192d26c8f5b5fa4ad Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Tue, 7 Oct 2025 09:13:25 +0200 Subject: [PATCH 392/704] Rename variable. --- src/main.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main.c b/src/main.c index 9f3f10e..d3fe594 100644 --- a/src/main.c +++ b/src/main.c @@ -230,23 +230,23 @@ construct_variant(GVA_Allocator const allocator, }; } // for - GVA_Variant lhs = { + GVA_Variant variant = { tree.nodes[nodes[0]].start, tree.nodes[nodes[n - 1]].end, {0, NULL} }; - lhs.sequence = gva_string_concat(allocator, lhs.sequence, variants[0].sequence); + variant.sequence = gva_string_concat(allocator, variant.sequence, variants[0].sequence); for (size_t i = 1; i < n; ++i) { - lhs.sequence = gva_string_concat(allocator, lhs.sequence, (GVA_String) {variants[i].start - variants[i - 1].end, reference + variants[i - 1].end}); - lhs.sequence = gva_string_concat(allocator, lhs.sequence, variants[i].sequence); + variant.sequence = gva_string_concat(allocator, variant.sequence, (GVA_String) {variants[i].start - variants[i - 1].end, reference + variants[i - 1].end}); + variant.sequence = gva_string_concat(allocator, variant.sequence, variants[i].sequence); } // for - // fprintf(stderr, GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(lhs)); + // fprintf(stderr, GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(variant)); // deallocate variants = allocator.allocate(allocator.context, variants, n * sizeof(*variants), 0); - return lhs; + return variant; } // construct_variant From 45af9ab50f704ea803c79dc8139306df55e7793f Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Tue, 7 Oct 2025 09:13:35 +0200 Subject: [PATCH 393/704] Reorder lhs and rhs. --- src/main.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main.c b/src/main.c index d3fe594..1996aa9 100644 --- a/src/main.c +++ b/src/main.c @@ -668,6 +668,10 @@ main(int argc, char* argv[static argc + 1]) continue; } // if + GVA_Variant const lhs = {tree.nodes[node_idx].start, + tree.nodes[node_idx].end, + trie_string(trie, tree.nodes[node_idx].inserted)}; + GVA_Variant rhs; gva_edges(query_graph.observed.str, query_graph.local_supremal[node_parts_table[npt_index].start], @@ -677,10 +681,6 @@ main(int argc, char* argv[static argc + 1]) &rhs); // fprintf(stderr, GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(rhs)); - GVA_Variant const lhs = {tree.nodes[node_idx].start, - tree.nodes[node_idx].end, - trie_string(trie, tree.nodes[node_idx].inserted)}; - size_t const op_distance = variants_distance(gva_std_allocator, reference.len, reference.str, lhs, rhs); // fprintf(stderr, "op_distance: %d\n", op_distance); From e7e32bc5246e01a25f250c7564a9e24fac39342c Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Tue, 7 Oct 2025 09:13:44 +0200 Subject: [PATCH 394/704] Notes. --- src/main.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main.c b/src/main.c index 1996aa9..56f1f9f 100644 --- a/src/main.c +++ b/src/main.c @@ -730,7 +730,6 @@ main(int argc, char* argv[static argc + 1]) // } // fprintf(stderr, "\n"); - // TODO: best datastructure if there is only a key?! struct RESULT_ALLELES { HASH_TABLE_KEY; @@ -756,7 +755,7 @@ main(int argc, char* argv[static argc + 1]) { HASH_TABLE_SET(gva_std_allocator, results_table, allele_idx, ((struct RESULT_ALLELES) {allele_idx})); } // if - + // TODO: construct allele distance here?! } // for alleles } // for node_parts_table From a960cf5ac287b8696fba9e6476464687698ed4d1 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Tue, 7 Oct 2025 10:51:10 +0200 Subject: [PATCH 395/704] Reuse start for part_idx and simplify logic with use of default values. --- src/main.c | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/src/main.c b/src/main.c index 56f1f9f..5ce8c68 100644 --- a/src/main.c +++ b/src/main.c @@ -552,7 +552,6 @@ main(int argc, char* argv[static argc + 1]) GVA_Relation relation; gva_uint start; gva_uint end; - gva_uint part_idx; gva_uint included; }* node_parts_table = hash_table_init(gva_std_allocator, 1024, sizeof(*node_parts_table)); @@ -592,31 +591,21 @@ main(int argc, char* argv[static argc + 1]) if (node_parts_table[hash_idx].gva_key != node_idx) { HASH_TABLE_SET(gva_std_allocator, node_parts_table, node_idx, - ((struct NODE_PARTS) {node_idx, relation, -1, -1, -1, 0})); + ((struct NODE_PARTS) {node_idx, relation, part_idx, part_idx + 1, query_dist})); hash_idx = HASH_TABLE_INDEX(node_parts_table, node_idx); } // if - if (relation == GVA_EQUIVALENT) + if (relation == GVA_EQUIVALENT || relation == GVA_IS_CONTAINED) { node_parts_table[hash_idx].included = tree.nodes[node_idx].distance; } // if - else if (relation == GVA_OVERLAP) + else if (relation == GVA_CONTAINS) { - node_parts_table[hash_idx].included = 1; - } // if - else if (relation == GVA_IS_CONTAINED) - { - node_parts_table[hash_idx].part_idx = part_idx; - node_parts_table[hash_idx].included = tree.nodes[node_idx].distance; + node_parts_table[hash_idx].end = part_idx + 1; } // if - else + else // GVA_OVERLAP { - if (node_parts_table[hash_idx].included == 0) - { - node_parts_table[hash_idx].start = part_idx; - node_parts_table[hash_idx].included = query_dist; - } // if - node_parts_table[hash_idx].end = part_idx + 1; + node_parts_table[hash_idx].included = 1; } // else } // for every candidate candidates = ARRAY_DESTROY(gva_std_allocator, candidates); @@ -815,7 +804,7 @@ main(int argc, char* argv[static argc + 1]) } else if (node_parts_table[hash_idx].relation == GVA_IS_CONTAINED) { - size_t const part_idx = node_parts_table[hash_idx].part_idx; + size_t const part_idx = node_parts_table[hash_idx].start; // fprintf(stderr, "part_idx: %zu\n", part_idx); // fprintf(stderr, "if containment current: %s\n", GVA_RELATION_LABELS[relation]); if (relation == GVA_CONTAINS) From 25bac818f9c76b008851fbbb12bc9507a5aaf435 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Tue, 7 Oct 2025 11:18:27 +0200 Subject: [PATCH 396/704] Use union for edges/distance. --- Makefile | 2 +- include/lcs_graph.h | 6 +++++- src/lcs_graph.c | 26 +++++++++++++------------- src/main.c | 8 ++++---- 4 files changed, 23 insertions(+), 19 deletions(-) diff --git a/Makefile b/Makefile index 6f13e6e..c3545b2 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ TEST_COVS = $(TESTS:.c=.c.gcov) TARGET = a.out CC = gcc -CFLAGS = -std=c99 -march=native -Wall -Wextra -Wpedantic -fanalyzer +CFLAGS = -std=c11 -march=native -Wall -Wextra -Wpedantic -fanalyzer MEMCHECK = valgrind -q --leak-check=full --error-exitcode=1 diff --git a/include/lcs_graph.h b/include/lcs_graph.h index dfd8759..4ff4da8 100644 --- a/include/lcs_graph.h +++ b/include/lcs_graph.h @@ -30,7 +30,11 @@ typedef struct gva_uint row; gva_uint col; gva_uint length; - gva_uint edges; + union + { + gva_uint edges; + gva_uint distance; + }; gva_uint lambda; } GVA_Node; diff --git a/src/lcs_graph.c b/src/lcs_graph.c index 539b93f..9bf14a2 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -25,7 +25,7 @@ gva_lcs_graph_init(GVA_Allocator const allocator, if (lcs.nodes == NULL || graph.distance == 0) { gva_uint const sink = ARRAY_APPEND(allocator, graph.nodes, ((GVA_Node) { - len_ref + shift, len_obs, 0, GVA_NULL, GVA_NULL + len_ref + shift, len_obs, 0, {GVA_NULL}, GVA_NULL })) - 1; if ((len_ref == 0 && len_obs == 0) || graph.distance == 0) { @@ -34,7 +34,7 @@ gva_lcs_graph_init(GVA_Allocator const allocator, graph.nodes[sink].col = 0; graph.nodes[sink].length = 0; ARRAY_APPEND(allocator, graph.local_supremal, ((GVA_Node) { - shift, 0, 0, GVA_NULL, graph.source + shift, 0, 0, {GVA_NULL}, graph.source })); lcs.index = allocator.allocate(allocator.context, lcs.index, lcs.length * sizeof(*lcs.index), 0); @@ -44,7 +44,7 @@ gva_lcs_graph_init(GVA_Allocator const allocator, graph.source = ARRAY_APPEND(allocator, graph.nodes, ((GVA_Node) { shift, 0, 0, - ARRAY_APPEND(allocator, graph.edges, ((GVA_Edge) {sink, GVA_NULL})) - 1, + {ARRAY_APPEND(allocator, graph.edges, ((GVA_Edge) {sink, GVA_NULL})) - 1}, GVA_NULL })) - 1; @@ -63,7 +63,7 @@ gva_lcs_graph_init(GVA_Allocator const allocator, if (sink.row + sink.length == len_ref + shift && sink.col + sink.length == len_obs) { lcs.nodes[tail_idx].idx = ARRAY_APPEND(allocator, graph.nodes, ((GVA_Node) { - sink.row, sink.col, sink.length, GVA_NULL, GVA_NULL + sink.row, sink.col, sink.length, {GVA_NULL}, GVA_NULL })) - 1; lcs.nodes[tail_idx].moved = true; sink = lcs.nodes[tail_idx]; @@ -72,7 +72,7 @@ gva_lcs_graph_init(GVA_Allocator const allocator, { sink = (LCS_Node) {.row = len_ref + shift, .col = len_obs, .length = 0}; sink.idx = ARRAY_APPEND(allocator, graph.nodes, ((GVA_Node) { - sink.row, sink.col, sink.length, GVA_NULL, GVA_NULL + sink.row, sink.col, sink.length, {GVA_NULL}, GVA_NULL })) - 1; tail_idx = GVA_NULL; } // else @@ -80,7 +80,7 @@ gva_lcs_graph_init(GVA_Allocator const allocator, { lcs.nodes[i].idx = ARRAY_APPEND(allocator, graph.nodes, ((GVA_Node) { lcs.nodes[i].row, lcs.nodes[i].col, lcs.nodes[i].length, - ARRAY_APPEND(allocator, graph.edges, ((GVA_Edge) {sink.idx, GVA_NULL})) - 1, + {ARRAY_APPEND(allocator, graph.edges, ((GVA_Edge) {sink.idx, GVA_NULL})) - 1}, GVA_NULL })) - 1; } // for @@ -119,7 +119,7 @@ gva_lcs_graph_init(GVA_Allocator const allocator, gva_uint const split_idx = head->idx; head->idx = ARRAY_APPEND(allocator, graph.nodes, ((GVA_Node) { head->row, head->col, head->length, - ARRAY_APPEND(allocator, graph.edges, ((GVA_Edge) {tail->idx, GVA_NULL})) - 1, + {ARRAY_APPEND(allocator, graph.edges, ((GVA_Edge) {tail->idx, GVA_NULL})) - 1}, split_idx })) - 1; head->moved = false; @@ -133,7 +133,7 @@ gva_lcs_graph_init(GVA_Allocator const allocator, { head->idx = ARRAY_APPEND(allocator, graph.nodes, ((GVA_Node) { head->row, head->col, head->length, - ARRAY_APPEND(allocator, graph.edges, ((GVA_Edge) {tail->idx, GVA_NULL})) - 1, + {ARRAY_APPEND(allocator, graph.edges, ((GVA_Edge) {tail->idx, GVA_NULL})) - 1}, GVA_NULL })) - 1; } // if @@ -178,7 +178,7 @@ gva_lcs_graph_init(GVA_Allocator const allocator, { source = (LCS_Node) {.row = shift, .col = 0, .length = 0}; source.idx = ARRAY_APPEND(allocator, graph.nodes, ((GVA_Node) { - source.row, source.col, source.length, GVA_NULL, GVA_NULL + source.row, source.col, source.length, {GVA_NULL}, GVA_NULL })) - 1; } // else for (gva_uint i = head_idx; i != GVA_NULL; i = lcs.nodes[i].next) @@ -209,7 +209,7 @@ gva_lcs_graph_init(GVA_Allocator const allocator, { gva_uint const distance = graph.nodes[source.idx].row + graph.nodes[source.idx].col - 2 * i; ARRAY_APPEND(allocator, graph.local_supremal, ((GVA_Node) { - graph.nodes[source.idx].row, graph.nodes[source.idx].col, 0, distance - prev_distance, source.idx + graph.nodes[source.idx].row, graph.nodes[source.idx].col, 0, {distance - prev_distance}, source.idx })); prev_distance = distance; } // if @@ -219,7 +219,7 @@ gva_lcs_graph_init(GVA_Allocator const allocator, gva_uint const offset = graph.nodes[idx].length - lcs.index[i - 1].offset - len; gva_uint const distance = graph.nodes[idx].row + graph.nodes[idx].col + 2 * offset + 2 * len - 2 * i; ARRAY_APPEND(allocator, graph.local_supremal, ((GVA_Node) { - graph.nodes[idx].row + offset, graph.nodes[idx].col + offset, len, distance - prev_distance, idx + graph.nodes[idx].row + offset, graph.nodes[idx].col + offset, len, {distance - prev_distance}, idx })); len = 0; prev_distance = distance; @@ -238,7 +238,7 @@ gva_lcs_graph_init(GVA_Allocator const allocator, gva_uint const offset = graph.nodes[idx].length - lcs.index[lcs.length - 1].offset - len; gva_uint const distance = graph.nodes[idx].row + graph.nodes[idx].col + 2 * offset + 2 * len - 2 * (lcs.length - len); ARRAY_APPEND(allocator, graph.local_supremal, ((GVA_Node) { - graph.nodes[idx].row + offset, graph.nodes[idx].col + offset, len, distance - prev_distance, idx + graph.nodes[idx].row + offset, graph.nodes[idx].col + offset, len, {distance - prev_distance}, idx })); len = 0; prev_distance = distance; @@ -247,7 +247,7 @@ gva_lcs_graph_init(GVA_Allocator const allocator, { gva_uint const distance = graph.nodes[0].row + graph.nodes[0].length - len + graph.nodes[0].col + graph.nodes[0].length - len - 2 * (lcs.length - len); ARRAY_APPEND(allocator, graph.local_supremal, ((GVA_Node) { - graph.nodes[0].row + graph.nodes[0].length - len, graph.nodes[0].col + graph.nodes[0].length - len, 0, distance - prev_distance, 0 + graph.nodes[0].row + graph.nodes[0].length - len, graph.nodes[0].col + graph.nodes[0].length - len, 0, {distance - prev_distance}, 0 })); } //if diff --git a/src/main.c b/src/main.c index 5ce8c68..a8949e5 100644 --- a/src/main.c +++ b/src/main.c @@ -263,7 +263,7 @@ multiple_is_contained_distance(GVA_Allocator const allocator, lhs_distance += tree.nodes[nodes[i]].distance; } // for - size_t const rhs_distance = graph.local_supremal[part_idx + 1].edges; + size_t const rhs_distance = graph.local_supremal[part_idx + 1].distance; if (lhs_distance >= rhs_distance) { return 1; // overlap @@ -493,7 +493,7 @@ main(int argc, char* argv[static argc + 1]) &part); gva_uint const inserted_idx = trie_insert(gva_std_allocator, &trie, part.sequence.len, part.sequence.str); - gva_uint const tmp_idx = ARRAY_APPEND(gva_std_allocator, tree.nodes, ((Interval_Tree_Node) {{GVA_NULL, GVA_NULL}, part.start, part.end, part.end, 0, inserted_idx, GVA_NULL, graph.local_supremal[i + 1].edges})) - 1; + gva_uint const tmp_idx = ARRAY_APPEND(gva_std_allocator, tree.nodes, ((Interval_Tree_Node) {{GVA_NULL, GVA_NULL}, part.start, part.end, part.end, 0, inserted_idx, GVA_NULL, graph.local_supremal[i + 1].distance})) - 1; gva_uint const node_idx = interval_tree_insert(&tree, tmp_idx); if (node_idx != tmp_idx) { @@ -568,7 +568,7 @@ main(int argc, char* argv[static argc + 1]) part_idx == 0, part_idx == array_length(query_graph.local_supremal) - 2, &query_part); - gva_uint const query_dist = query_graph.local_supremal[part_idx + 1].edges; + gva_uint const query_dist = query_graph.local_supremal[part_idx + 1].distance; // fprintf(stderr, " query part %zu (dist: %d): " GVA_VARIANT_FMT "\n", part_idx, query_dist, GVA_VARIANT_PRINT(query_part)); // find candidates for this local supremal part @@ -638,7 +638,7 @@ main(int argc, char* argv[static argc + 1]) size_t slice_dist = 0; for (size_t i = node_parts_table[npt_index].start; i < node_parts_table[npt_index].end; ++i) { - slice_dist += query_graph.local_supremal[i + 1].edges; + sum_distance += query_graph.local_supremal[i + 1].distance; } // for // fprintf(stderr, " slice dist: %zu node dist: %u\n", slice_dist, tree.nodes[node_idx].distance); if (slice_dist >= tree.nodes[node_idx].distance) From bda06af0ac3099d5e3e990bd5f26d83a90cea54e Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Tue, 7 Oct 2025 11:19:41 +0200 Subject: [PATCH 397/704] Distance instantation in nodes for local supremals from NULL to 0. --- src/lcs_graph.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lcs_graph.c b/src/lcs_graph.c index 9bf14a2..65da6c7 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -49,10 +49,10 @@ gva_lcs_graph_init(GVA_Allocator const allocator, })) - 1; ARRAY_APPEND(allocator, graph.local_supremal, ((GVA_Node) { - shift, 0, 0, GVA_NULL, GVA_NULL + shift, 0, 0, {0}, GVA_NULL })); ARRAY_APPEND(allocator, graph.local_supremal, ((GVA_Node) { - len_ref + shift, len_obs, 0, GVA_NULL, GVA_NULL + len_ref + shift, len_obs, 0, {0}, GVA_NULL })); graph.supremal = (GVA_Variant) {shift, len_ref + shift, {len_obs, observed}}; return graph; From 7d64e416ac1e215bacb967d48101a5d72f819f76 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Tue, 7 Oct 2025 11:40:14 +0200 Subject: [PATCH 398/704] Cleanup. --- src/main.c | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/src/main.c b/src/main.c index a8949e5..ff7508d 100644 --- a/src/main.c +++ b/src/main.c @@ -621,15 +621,6 @@ main(int argc, char* argv[static argc + 1]) { continue; } // if - // fprintf(stderr, " node_idx: %zu " GVA_VARIANT_FMT " %s (%d, %d) in:%d\n", - // node_idx, - // GVA_VARIANT_PRINT(((GVA_Variant) { - // tree.nodes[node_idx].start, tree.nodes[node_idx].end, - // trie_string(trie, tree.nodes[node_idx].inserted) - // })), - // GVA_RELATION_LABELS[node_parts_table[npt_index].relation], - // node_parts_table[npt_index].start, node_parts_table[npt_index].end, - // node_parts_table[npt_index].included); if (node_parts_table[npt_index].relation == GVA_CONTAINS && node_parts_table[npt_index].end - node_parts_table[npt_index].start > 1) @@ -646,14 +637,6 @@ main(int argc, char* argv[static argc + 1]) // fprintf(stderr, "here A\n"); node_parts_table[npt_index].relation = GVA_OVERLAP; node_parts_table[npt_index].included = 1; - // fprintf(stderr, " REPAIRED DISTANCE node_idx: %zu " GVA_VARIANT_FMT " %s (%d, %d, %d) in:%d\n", node_idx, - // GVA_VARIANT_PRINT(((GVA_Variant) { - // tree.nodes[node_idx].start, tree.nodes[node_idx].end, - // trie_string(trie, tree.nodes[node_idx].inserted) - // })), - // GVA_RELATION_LABELS[node_parts_table[i].relation], - // node_parts_table[npt_index].start, node_parts_table[npt_index].end, node_parts_table[npt_index].part_idx, - // node_parts_table[npt_index].included); continue; } // if @@ -682,17 +665,6 @@ main(int argc, char* argv[static argc + 1]) node_parts_table[npt_index].included = 1; // fprintf(stderr, "OVERLAP!!\n"); } // if - // fprintf(stderr, "here C\n"); - - // fprintf(stderr, " REPAIRED node_idx: %zu " GVA_VARIANT_FMT " %s (%d, %d, %d) in:%d\n", node_idx, - // GVA_VARIANT_PRINT(((GVA_Variant) { - // tree.nodes[node_idx].start, tree.nodes[node_idx].end, - // trie_string(trie, tree.nodes[node_idx].inserted) - // })), - // GVA_RELATION_LABELS[node_parts_table[npt_index].relation], - // node_parts_table[npt_index].start, node_parts_table[npt_index].end, node_parts_table[npt_index].part_idx, - // node_parts_table[npt_index].included); - } // if } // for node_parts_table From 1e12bec853f6a0d30580eefd3df4e32cbe9e4449 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Tue, 7 Oct 2025 11:40:32 +0200 Subject: [PATCH 399/704] Improve symmetry. --- src/main.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/main.c b/src/main.c index ff7508d..2c21883 100644 --- a/src/main.c +++ b/src/main.c @@ -626,15 +626,16 @@ main(int argc, char* argv[static argc + 1]) node_parts_table[npt_index].end - node_parts_table[npt_index].start > 1) { // fprintf(stderr, " Perform extra comparison\n"); - size_t slice_dist = 0; + size_t const lhs_distance = tree.nodes[node_idx].distance; + + size_t rhs_distance = 0; for (size_t i = node_parts_table[npt_index].start; i < node_parts_table[npt_index].end; ++i) { - sum_distance += query_graph.local_supremal[i + 1].distance; + rhs_distance += query_graph.local_supremal[i + 1].distance; } // for - // fprintf(stderr, " slice dist: %zu node dist: %u\n", slice_dist, tree.nodes[node_idx].distance); - if (slice_dist >= tree.nodes[node_idx].distance) + // fprintf(stderr, " slice dist: %zu node dist: %u\n", rhs_distance, lhs_distance); + if (rhs_distance >= lhs_distance) { - // fprintf(stderr, "here A\n"); node_parts_table[npt_index].relation = GVA_OVERLAP; node_parts_table[npt_index].included = 1; continue; @@ -653,12 +654,12 @@ main(int argc, char* argv[static argc + 1]) &rhs); // fprintf(stderr, GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(rhs)); - size_t const op_distance = variants_distance(gva_std_allocator, reference.len, reference.str, lhs, rhs); - // fprintf(stderr, "op_distance: %d\n", op_distance); + size_t const distance = variants_distance(gva_std_allocator, reference.len, reference.str, lhs, rhs); + // fprintf(stderr, "distance: %d\n", distance); - node_parts_table[npt_index].included = slice_dist; + node_parts_table[npt_index].included = rhs_distance; - if (tree.nodes[node_idx].distance - op_distance != slice_dist) + if (lhs_distance - distance != rhs_distance) { // fprintf(stderr, "here B\n"); node_parts_table[npt_index].relation = GVA_OVERLAP; From 6e140aaece72c9bf78ad41bdf4741a6c951f0b0b Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Tue, 7 Oct 2025 12:24:18 +0200 Subject: [PATCH 400/704] Move variable declaration. --- src/main.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/main.c b/src/main.c index 2c21883..7b8e59a 100644 --- a/src/main.c +++ b/src/main.c @@ -52,9 +52,7 @@ compare_from_index(GVA_String const reference, GVA_Variant const lhs, gva_uint const lhs_dist, GVA_Variant const rhs, gva_uint const rhs_dist) { - // TODO: possibly reuse lhs_graph again - - GVA_Relation relation; + // TODO: possibly reuse rhs_graph if (gva_variant_eq(lhs, rhs)) { @@ -137,6 +135,7 @@ compare_from_index(GVA_String const reference, size_t* rhs_ts = bitset_init(gva_std_allocator, len); bitset_fill(rhs_graph, start, start_intersection, end_intersection, rhs_dels, rhs_as, rhs_cs, rhs_gs, rhs_ts); + GVA_Relation relation = GVA_DISJOINT; if (bitset_intersection_cnt(lhs_dels, rhs_dels) > 0 || bitset_intersection_cnt(lhs_as, rhs_as) > 0 || bitset_intersection_cnt(lhs_cs, rhs_cs) > 0 || @@ -145,10 +144,6 @@ compare_from_index(GVA_String const reference, { relation = GVA_OVERLAP; } // if - else - { - relation = GVA_DISJOINT; - } // else lhs_ts = bitset_destroy(gva_std_allocator, lhs_ts); lhs_gs = bitset_destroy(gva_std_allocator, lhs_gs); From 145fe87fd164722ff5e81303f008d6b70fcd8342 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Tue, 7 Oct 2025 12:26:05 +0200 Subject: [PATCH 401/704] Consistent naming. --- src/main.c | 78 +++++++++++++++++++++++++++--------------------------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/src/main.c b/src/main.c index 7b8e59a..532e37b 100644 --- a/src/main.c +++ b/src/main.c @@ -49,8 +49,8 @@ parse_number(char const buffer[static 1], size_t idx[static 1]) GVA_Relation compare_from_index(GVA_String const reference, - GVA_Variant const lhs, gva_uint const lhs_dist, - GVA_Variant const rhs, gva_uint const rhs_dist) + GVA_Variant const lhs, gva_uint const lhs_distance, + GVA_Variant const rhs, gva_uint const rhs_distance) { // TODO: possibly reuse rhs_graph @@ -100,17 +100,17 @@ compare_from_index(GVA_String const reference, lhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, lhs_obs, lhs_len, 0); } // else - if (lhs_dist + rhs_dist == distance) + if (lhs_distance + rhs_distance == distance) { return GVA_DISJOINT; } // if - if (lhs_dist - rhs_dist == distance) + if (lhs_distance - rhs_distance == distance) { return GVA_CONTAINS; } // if - if (rhs_dist - lhs_dist == distance) + if (rhs_distance - lhs_distance == distance) { return GVA_IS_CONTAINED; } // if @@ -533,8 +533,8 @@ main(int argc, char* argv[static argc + 1]) size_t const query_id = parse_number(line, &idx); idx += 1; // skip space or tab int const len = (char*) memchr(line + idx, '\n', LINE_SIZE - idx) - (line + idx); - GVA_Variant query_var; - if (gva_parse_spdi(len, line + idx, &query_var) == 0) + GVA_Variant rhs_var; + if (gva_parse_spdi(len, line + idx, &rhs_var) == 0) { fprintf(stderr, "error: SPDI parsing failed at line %zu: %s", line_count + 1, line); continue; @@ -551,29 +551,29 @@ main(int argc, char* argv[static argc + 1]) }* node_parts_table = hash_table_init(gva_std_allocator, 1024, sizeof(*node_parts_table)); // query graph - GVA_LCS_Graph const query_graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &query_var); - // fprintf(stderr, "query allele %zu: " GVA_VARIANT_FMT " (dist: %u)\n", query_id, GVA_VARIANT_PRINT(query_var), query_graph.distance); + GVA_LCS_Graph const rhs_graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &rhs_var); + // fprintf(stderr, "query allele %zu: " GVA_VARIANT_FMT " (dist: %u)\n", rhs_id, GVA_VARIANT_PRINT(rhs_var), rhs_graph.distance); - for (size_t part_idx = 0; part_idx < array_length(query_graph.local_supremal) - 1; ++part_idx) + for (size_t part_idx = 0; part_idx < array_length(rhs_graph.local_supremal) - 1; ++part_idx) { // query local supremal part - GVA_Variant query_part; - gva_edges(query_graph.observed.str, - query_graph.local_supremal[part_idx], query_graph.local_supremal[part_idx + 1], - part_idx == 0, part_idx == array_length(query_graph.local_supremal) - 2, - &query_part); + GVA_Variant rhs_part; + gva_edges(rhs_graph.observed.str, + rhs_graph.local_supremal[part_idx], rhs_graph.local_supremal[part_idx + 1], + part_idx == 0, part_idx == array_length(rhs_graph.local_supremal) - 2, + &rhs_part); - gva_uint const query_dist = query_graph.local_supremal[part_idx + 1].distance; - // fprintf(stderr, " query part %zu (dist: %d): " GVA_VARIANT_FMT "\n", part_idx, query_dist, GVA_VARIANT_PRINT(query_part)); + gva_uint const rhs_distance = rhs_graph.local_supremal[part_idx + 1].distance; + // fprintf(stderr, " query part %zu (dist: %d): " GVA_VARIANT_FMT "\n", part_idx, rhs_distance, GVA_VARIANT_PRINT(rhs_part)); // find candidates for this local supremal part - gva_uint* candidates = interval_tree_intersection(gva_std_allocator, tree, query_part.start, query_part.end); + gva_uint* candidates = interval_tree_intersection(gva_std_allocator, tree, rhs_part.start, rhs_part.end); for (size_t can_idx = 0; can_idx < array_length(candidates); ++can_idx) { gva_uint const node_idx = candidates[can_idx]; GVA_Variant const db_var = {tree.nodes[node_idx].start, tree.nodes[node_idx].end, trie_string(trie, tree.nodes[node_idx].inserted)}; - GVA_Relation const relation = compare_from_index(reference, db_var, tree.nodes[node_idx].distance, query_part, query_dist); + GVA_Relation const relation = compare_from_index(reference, db_var, tree.nodes[node_idx].distance, rhs_part, rhs_distance); // fprintf(stderr, " db candidate node_idx: %d (dist: %d): " GVA_VARIANT_FMT " %s\n", node_idx, tree.nodes[node_idx].distance, GVA_VARIANT_PRINT(db_var), GVA_RELATION_LABELS[relation]); if (relation == GVA_DISJOINT) @@ -586,7 +586,7 @@ main(int argc, char* argv[static argc + 1]) if (node_parts_table[hash_idx].gva_key != node_idx) { HASH_TABLE_SET(gva_std_allocator, node_parts_table, node_idx, - ((struct NODE_PARTS) {node_idx, relation, part_idx, part_idx + 1, query_dist})); + ((struct NODE_PARTS) {node_idx, relation, part_idx, part_idx + 1, rhs_distance})); hash_idx = HASH_TABLE_INDEX(node_parts_table, node_idx); } // if @@ -626,7 +626,7 @@ main(int argc, char* argv[static argc + 1]) size_t rhs_distance = 0; for (size_t i = node_parts_table[npt_index].start; i < node_parts_table[npt_index].end; ++i) { - rhs_distance += query_graph.local_supremal[i + 1].distance; + rhs_distance += rhs_graph.local_supremal[i + 1].distance; } // for // fprintf(stderr, " slice dist: %zu node dist: %u\n", rhs_distance, lhs_distance); if (rhs_distance >= lhs_distance) @@ -641,11 +641,11 @@ main(int argc, char* argv[static argc + 1]) trie_string(trie, tree.nodes[node_idx].inserted)}; GVA_Variant rhs; - gva_edges(query_graph.observed.str, - query_graph.local_supremal[node_parts_table[npt_index].start], - query_graph.local_supremal[node_parts_table[npt_index].end], + gva_edges(rhs_graph.observed.str, + rhs_graph.local_supremal[node_parts_table[npt_index].start], + rhs_graph.local_supremal[node_parts_table[npt_index].end], node_parts_table[npt_index].start == 0, - node_parts_table[npt_index].end == array_length(query_graph.local_supremal) - 1, + node_parts_table[npt_index].end == array_length(rhs_graph.local_supremal) - 1, &rhs); // fprintf(stderr, GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(rhs)); @@ -791,7 +791,7 @@ main(int argc, char* argv[static argc + 1]) { // fprintf(stderr, "Found multiple is_containeds for the same part\n"); size_t const slice_dist = multiple_is_contained_distance(gva_std_allocator, reference.len, reference.str, - query_graph, part_idx, tree, trie, is_contained_nodes); + rhs_graph, part_idx, tree, trie, is_contained_nodes); if (slice_dist == 1) { included = 1; @@ -841,7 +841,7 @@ main(int argc, char* argv[static argc + 1]) { // fprintf(stderr, "Found multiple is_containeds for the same part at the end\n"); size_t const slice_dist = multiple_is_contained_distance(gva_std_allocator, reference.len, reference.str, - query_graph, is_contained_part_idx, tree, trie, is_contained_nodes); + rhs_graph, is_contained_part_idx, tree, trie, is_contained_nodes); if (slice_dist == 1) { included = 1; @@ -858,27 +858,27 @@ main(int argc, char* argv[static argc + 1]) if (included > 0) { - // fprintf(stderr, "allele dist: %u query dist: %u\n", db_alleles[allele_idx].distance, query_graph.distance); + // fprintf(stderr, "allele dist: %u query dist: %u\n", db_alleles[allele_idx].distance, rhs_graph.distance); // fprintf(stderr, "relation: %s\n", GVA_RELATION_LABELS[relation]); - gva_uint const allele_excluded = db_alleles[allele_idx].distance - included; - gva_uint const query_excluded = query_graph.distance - included; + gva_uint const lhs_excluded = db_alleles[allele_idx].distance - included; + gva_uint const rhs_excluded = rhs_graph.distance - included; - // fprintf(stderr, "included: %zu, allele_excluded: %d query_excluded: %zu\n", - // included, allele_excluded, query_excluded); - if (allele_excluded > 0 && query_excluded > 0) + // fprintf(stderr, "included: %zu, lhs_excluded: %d rhs_excluded: %zu\n", + // included, lhs_excluded, rhs_excluded); + if (lhs_excluded > 0 && rhs_excluded > 0) { relation = GVA_OVERLAP; } - else if (allele_excluded > 0) + else if (lhs_excluded > 0) { relation = GVA_CONTAINS; } - else if (query_excluded > 0) + else if (rhs_excluded > 0) { relation = GVA_IS_CONTAINED; } - else // if (allele_excluded == 0 && query_excluded == 0) + else // if (lhs_excluded == 0 && rhs_excluded == 0) { relation = GVA_EQUIVALENT; } @@ -891,7 +891,7 @@ main(int argc, char* argv[static argc + 1]) db_alleles[allele_idx].data, db_alleles[allele_idx].spdi, query_id, - GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, query_graph.supremal), + GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, rhs_graph.supremal), GVA_RELATION_LABELS[relation]); } } // if @@ -903,8 +903,8 @@ main(int argc, char* argv[static argc + 1]) results_table = HASH_TABLE_DESTROY(gva_std_allocator, results_table); node_parts_table = HASH_TABLE_DESTROY(gva_std_allocator, node_parts_table); - gva_string_destroy(gva_std_allocator, query_graph.observed); - gva_lcs_graph_destroy(gva_std_allocator, query_graph); + gva_string_destroy(gva_std_allocator, rhs_graph.observed); + gva_lcs_graph_destroy(gva_std_allocator, rhs_graph); // fprintf(stderr, "\n"); line_count += 1; From b3397f7e2e27ada4e554ef76654e309c990b37fd Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Tue, 7 Oct 2025 15:41:35 +0200 Subject: [PATCH 402/704] Rename. --- src/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.c b/src/main.c index 532e37b..3501b54 100644 --- a/src/main.c +++ b/src/main.c @@ -717,9 +717,9 @@ main(int argc, char* argv[static argc + 1]) } // for node_parts_table // build result vector for every query - for (size_t results_index = 0; results_index < array_header(results_table)->capacity; ++results_index) + for (size_t results_idx = 0; results_idx < array_header(results_table)->capacity; ++results_idx) { - size_t allele_idx = results_table[results_index].gva_key; + size_t allele_idx = results_table[results_idx].gva_key; if (allele_idx == (uint32_t) - 1) { continue; From 84437f954836bc9046e17c3ab5416c473ff30543 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Tue, 7 Oct 2025 15:41:54 +0200 Subject: [PATCH 403/704] Recalculate allele distance and only store for results. --- src/main.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/main.c b/src/main.c index 3501b54..50c8748 100644 --- a/src/main.c +++ b/src/main.c @@ -442,7 +442,6 @@ main(int argc, char* argv[static argc + 1]) size_t data; char* spdi; // FIXME gva_uint join_start; // offset into node_allele_join - gva_uint distance; }* db_alleles = NULL; size_t line_count = 0; @@ -475,7 +474,7 @@ main(int argc, char* argv[static argc + 1]) gva_uint const allele_idx = ARRAY_APPEND( gva_std_allocator, db_alleles, - ((struct Allele) {rsid, spdi, array_length(node_allele_join), graph.distance}) + ((struct Allele) {rsid, spdi, array_length(node_allele_join)}) ) - 1; // fprintf(stderr, "input allele %zu: " GVA_VARIANT_FMT " (dist: %d) stored at: %d\n", rsid, GVA_VARIANT_PRINT(variant), graph.distance, allele_idx); @@ -690,6 +689,7 @@ main(int argc, char* argv[static argc + 1]) struct RESULT_ALLELES { HASH_TABLE_KEY; + gva_uint distance; }* results_table = hash_table_init(gva_std_allocator, 1024, sizeof(*results_table)); // fprintf(stderr, "Loop over all node parts for every query:\n"); @@ -710,9 +710,8 @@ main(int argc, char* argv[static argc + 1]) size_t hash_idx = HASH_TABLE_INDEX(results_table, allele_idx); if (results_table[hash_idx].gva_key != allele_idx) { - HASH_TABLE_SET(gva_std_allocator, results_table, allele_idx, ((struct RESULT_ALLELES) {allele_idx})); + HASH_TABLE_SET(gva_std_allocator, results_table, allele_idx, ((struct RESULT_ALLELES) {allele_idx, 0})); } // if - // TODO: construct allele distance here?! } // for alleles } // for node_parts_table @@ -740,6 +739,10 @@ main(int argc, char* argv[static argc + 1]) { // fprintf(stderr, "join_idx: %zu\n", join_idx); size_t const node_idx = node_allele_join[join_idx].node; + + // (re)calculate allele distance from nodes + results_table[results_idx].distance += tree.nodes[node_idx].distance; + size_t const hash_idx = HASH_TABLE_INDEX(node_parts_table, node_idx); if (node_idx != node_parts_table[hash_idx].gva_key) { @@ -861,7 +864,7 @@ main(int argc, char* argv[static argc + 1]) // fprintf(stderr, "allele dist: %u query dist: %u\n", db_alleles[allele_idx].distance, rhs_graph.distance); // fprintf(stderr, "relation: %s\n", GVA_RELATION_LABELS[relation]); - gva_uint const lhs_excluded = db_alleles[allele_idx].distance - included; + gva_uint const lhs_excluded = results_table[results_idx].distance - included; gva_uint const rhs_excluded = rhs_graph.distance - included; // fprintf(stderr, "included: %zu, lhs_excluded: %d rhs_excluded: %zu\n", From eb19c127fa45795ee946d67f276c2127f386ced3 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Tue, 7 Oct 2025 15:45:13 +0200 Subject: [PATCH 404/704] Naming. --- src/main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main.c b/src/main.c index 50c8748..92b646f 100644 --- a/src/main.c +++ b/src/main.c @@ -692,10 +692,10 @@ main(int argc, char* argv[static argc + 1]) gva_uint distance; }* results_table = hash_table_init(gva_std_allocator, 1024, sizeof(*results_table)); - // fprintf(stderr, "Loop over all node parts for every query:\n"); - for (size_t npt_index = 0; npt_index < array_header(node_parts_table)->capacity; ++npt_index) + // find all alleles that were part of a non-disjoint relation + for (size_t npt_idx = 0; npt_idx < array_header(node_parts_table)->capacity; ++npt_idx) { - size_t const node_idx = node_parts_table[npt_index].gva_key; + size_t const node_idx = node_parts_table[npt_idx].gva_key; if (node_idx == (uint32_t) - 1) { continue; From 5477a9af5e762a092aa4bde2b5b1a9a458d43895 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Tue, 7 Oct 2025 15:45:42 +0200 Subject: [PATCH 405/704] Direct set can be used here. --- src/main.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/main.c b/src/main.c index 92b646f..3c6c8f1 100644 --- a/src/main.c +++ b/src/main.c @@ -706,12 +706,7 @@ main(int argc, char* argv[static argc + 1]) naj_table_idx = node_allele_join[naj_table_idx].next) { size_t const allele_idx = node_allele_join[naj_table_idx].allele; - // TODO: direct SET - size_t hash_idx = HASH_TABLE_INDEX(results_table, allele_idx); - if (results_table[hash_idx].gva_key != allele_idx) - { - HASH_TABLE_SET(gva_std_allocator, results_table, allele_idx, ((struct RESULT_ALLELES) {allele_idx, 0})); - } // if + HASH_TABLE_SET(gva_std_allocator, results_table, allele_idx, ((struct RESULT_ALLELES) {allele_idx, 0})); } // for alleles } // for node_parts_table From 9a4015bb7426c93ad041f7951127d2c15539d7d7 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Tue, 7 Oct 2025 16:40:45 +0200 Subject: [PATCH 406/704] Union for start/part_index. --- src/main.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/main.c b/src/main.c index 3c6c8f1..1cb8ffc 100644 --- a/src/main.c +++ b/src/main.c @@ -544,7 +544,10 @@ main(int argc, char* argv[static argc + 1]) { HASH_TABLE_KEY; GVA_Relation relation; - gva_uint start; + union { + gva_uint start; + gva_uint part_idx; + }; gva_uint end; gva_uint included; }* node_parts_table = hash_table_init(gva_std_allocator, 1024, sizeof(*node_parts_table)); @@ -585,7 +588,7 @@ main(int argc, char* argv[static argc + 1]) if (node_parts_table[hash_idx].gva_key != node_idx) { HASH_TABLE_SET(gva_std_allocator, node_parts_table, node_idx, - ((struct NODE_PARTS) {node_idx, relation, part_idx, part_idx + 1, rhs_distance})); + ((struct NODE_PARTS) { node_idx, relation, {part_idx}, part_idx + 1, rhs_distance})); hash_idx = HASH_TABLE_INDEX(node_parts_table, node_idx); } // if @@ -706,7 +709,7 @@ main(int argc, char* argv[static argc + 1]) naj_table_idx = node_allele_join[naj_table_idx].next) { size_t const allele_idx = node_allele_join[naj_table_idx].allele; - HASH_TABLE_SET(gva_std_allocator, results_table, allele_idx, ((struct RESULT_ALLELES) {allele_idx, 0})); + HASH_TABLE_SET(gva_std_allocator, results_table, allele_idx, ((struct RESULT_ALLELES) { allele_idx, 0})); } // for alleles } // for node_parts_table @@ -770,7 +773,7 @@ main(int argc, char* argv[static argc + 1]) } else if (node_parts_table[hash_idx].relation == GVA_IS_CONTAINED) { - size_t const part_idx = node_parts_table[hash_idx].start; + size_t const part_idx = node_parts_table[hash_idx].part_idx; // fprintf(stderr, "part_idx: %zu\n", part_idx); // fprintf(stderr, "if containment current: %s\n", GVA_RELATION_LABELS[relation]); if (relation == GVA_CONTAINS) From dea4fff0dd4733bf84d28d006dafd65218f246c3 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Tue, 7 Oct 2025 16:58:10 +0200 Subject: [PATCH 407/704] Undo union. --- src/main.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/main.c b/src/main.c index 1cb8ffc..3c6c8f1 100644 --- a/src/main.c +++ b/src/main.c @@ -544,10 +544,7 @@ main(int argc, char* argv[static argc + 1]) { HASH_TABLE_KEY; GVA_Relation relation; - union { - gva_uint start; - gva_uint part_idx; - }; + gva_uint start; gva_uint end; gva_uint included; }* node_parts_table = hash_table_init(gva_std_allocator, 1024, sizeof(*node_parts_table)); @@ -588,7 +585,7 @@ main(int argc, char* argv[static argc + 1]) if (node_parts_table[hash_idx].gva_key != node_idx) { HASH_TABLE_SET(gva_std_allocator, node_parts_table, node_idx, - ((struct NODE_PARTS) { node_idx, relation, {part_idx}, part_idx + 1, rhs_distance})); + ((struct NODE_PARTS) {node_idx, relation, part_idx, part_idx + 1, rhs_distance})); hash_idx = HASH_TABLE_INDEX(node_parts_table, node_idx); } // if @@ -709,7 +706,7 @@ main(int argc, char* argv[static argc + 1]) naj_table_idx = node_allele_join[naj_table_idx].next) { size_t const allele_idx = node_allele_join[naj_table_idx].allele; - HASH_TABLE_SET(gva_std_allocator, results_table, allele_idx, ((struct RESULT_ALLELES) { allele_idx, 0})); + HASH_TABLE_SET(gva_std_allocator, results_table, allele_idx, ((struct RESULT_ALLELES) {allele_idx, 0})); } // for alleles } // for node_parts_table @@ -773,7 +770,7 @@ main(int argc, char* argv[static argc + 1]) } else if (node_parts_table[hash_idx].relation == GVA_IS_CONTAINED) { - size_t const part_idx = node_parts_table[hash_idx].part_idx; + size_t const part_idx = node_parts_table[hash_idx].start; // fprintf(stderr, "part_idx: %zu\n", part_idx); // fprintf(stderr, "if containment current: %s\n", GVA_RELATION_LABELS[relation]); if (relation == GVA_CONTAINS) From 51afe5acb1df825f38961449a48f0089c06a4978 Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 8 Oct 2025 11:27:22 +0200 Subject: [PATCH 408/704] Remove extra parens --- src/hash_table.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hash_table.h b/src/hash_table.h index 7592b2f..9ab1fc2 100644 --- a/src/hash_table.h +++ b/src/hash_table.h @@ -31,7 +31,7 @@ hash_table_ensure(GVA_Allocator const allocator, void* const self, size_t const #define HASH_TABLE_SET(allocator, self, key, value) \ - (self) = hash_table_ensure(allocator, self, (sizeof(*(self)))), \ + (self) = hash_table_ensure(allocator, self, sizeof(*(self))), \ array_header(self)->length += 1, \ self[hash_table_index(self, sizeof(*(self)), key)] = (value) From e5fe7111bfeb2f23a9e3f929629b9c3b7a478e99 Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 8 Oct 2025 11:28:00 +0200 Subject: [PATCH 409/704] Construct local supremal from vcf-wide alleles --- src/main.c | 55 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 32 insertions(+), 23 deletions(-) diff --git a/src/main.c b/src/main.c index 3c6c8f1..5e960bd 100644 --- a/src/main.c +++ b/src/main.c @@ -346,6 +346,8 @@ vcf_main(int argc, char* argv[static argc + 1]) GVA_Variant variants[2]; size_t count = 0; + size_t out_count = 0; + size_t drop_count = 0; static char line[LINE_SIZE] = {0}; while (fgets(line, sizeof(line), stdin) != NULL) { @@ -358,11 +360,12 @@ vcf_main(int argc, char* argv[static argc + 1]) variants[count > 0] = prefix_trimmed(reference.len, reference.str, variants[count > 0]); - for (size_t i = 0; i <= (count > 0); ++i) + if (count > 0 && variants[0].end > variants[1].start) { - fprintf(stderr, GVA_VARIANT_FMT " ", GVA_VARIANT_PRINT(variants[i])); - } // for - fprintf(stderr, "\n"); + fprintf(stderr, "drop: " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(variants[1])); + drop_count += 1; + continue; + } // if GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1 + (count > 0), variants); GVA_Variant local; @@ -374,11 +377,10 @@ vcf_main(int argc, char* argv[static argc + 1]) &local); if (i < array_length(graph.local_supremal) - 2) { - fprintf(stderr, "OUT: " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(local)); + //fprintf(stderr, "OUT: " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(local)); + out_count += 1; } // if } // for - gva_lcs_graph_destroy(gva_std_allocator, graph); - if (count > 0) { gva_string_destroy(gva_std_allocator, variants[0].sequence); @@ -386,35 +388,42 @@ vcf_main(int argc, char* argv[static argc + 1]) variants[0] = (GVA_Variant) {local.start, local.end, gva_string_dup(gva_std_allocator, local.sequence)}; variants[0] = suffix_trimmed(reference.len, reference.str, variants[0]); + gva_string_destroy(gva_std_allocator, graph.observed); + gva_lcs_graph_destroy(gva_std_allocator, graph); + count += 1; } // while - - gva_string_destroy(gva_std_allocator, reference); - return EXIT_SUCCESS; - - struct IN_EX + GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, variants); + GVA_Variant local; + for (size_t i = 0; i < array_length(graph.local_supremal) - 1; ++i) { - HASH_TABLE_KEY; - gva_uint included; - gva_uint excluded; - }* table = hash_table_init(gva_std_allocator, 1024, sizeof(*table)); - - HASH_TABLE_SET(gva_std_allocator, table, 42, ((struct IN_EX) {42, 1, 2})); - - if (table[HASH_TABLE_INDEX(table, 42)].gva_key == 42) + gva_edges(graph.observed.str, + graph.local_supremal[i], graph.local_supremal[i + 1], + i == 0, i == array_length(graph.local_supremal) - 2, + &local); + //fprintf(stderr, "OUT: " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(local)); + out_count += 1; + } // for + if (count > 0) { - fprintf(stderr, "FOUND at %zu\n", HASH_TABLE_INDEX(table, 42)); + gva_string_destroy(gva_std_allocator, variants[0].sequence); } // if + gva_string_destroy(gva_std_allocator, graph.observed); + gva_lcs_graph_destroy(gva_std_allocator, graph); - table = HASH_TABLE_DESTROY(gva_std_allocator, table); + printf("#local supremal parts: %zu\n", out_count); + printf("#dropped variants: %zu\n", drop_count); + gva_string_destroy(gva_std_allocator, reference); return EXIT_SUCCESS; -} +} // vcf_main int main(int argc, char* argv[static argc + 1]) { + // return vcf_main(argc, argv); + errno = 0; FILE* stream = fopen(argv[1], "r"); if (stream == NULL) From ebb97bcda647f6dba2f8f2b839ec37bc15afe9e6 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Wed, 8 Oct 2025 12:11:58 +0200 Subject: [PATCH 410/704] Only store/output linenr and no spdi and rsid. --- src/main.c | 36 +++++++----------------------------- 1 file changed, 7 insertions(+), 29 deletions(-) diff --git a/src/main.c b/src/main.c index 3c6c8f1..a5b9ef3 100644 --- a/src/main.c +++ b/src/main.c @@ -439,8 +439,7 @@ main(int argc, char* argv[static argc + 1]) }* node_allele_join = NULL; struct Allele { - size_t data; - char* spdi; // FIXME + gva_uint line; gva_uint join_start; // offset into node_allele_join }* db_alleles = NULL; @@ -449,7 +448,7 @@ main(int argc, char* argv[static argc + 1]) while (fgets(line, sizeof(line), stdin) != NULL) { size_t idx = 0; - size_t const rsid = parse_number(line, &idx); + parse_number(line, &idx); idx += 1; // skip space or tab int const len = (char*) memchr(line + idx, '\n', LINE_SIZE - idx) - (line + idx); GVA_Variant variant; @@ -461,20 +460,9 @@ main(int argc, char* argv[static argc + 1]) GVA_LCS_Graph const graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &variant); - // FIXME - size_t const spdi_len = snprintf(NULL, 0, GVA_VARIANT_FMT_SPDI, GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, graph.supremal)) + 1; - char* const spdi = malloc(spdi_len); - if (spdi == NULL) - { - fprintf(stderr, "spdi malloc() failed\n"); - return EXIT_FAILURE; - } - snprintf(spdi, spdi_len, GVA_VARIANT_FMT_SPDI, GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, graph.supremal)); - // end FIXME - gva_uint const allele_idx = ARRAY_APPEND( gva_std_allocator, db_alleles, - ((struct Allele) {rsid, spdi, array_length(node_allele_join)}) + ((struct Allele) {line_count, array_length(node_allele_join)}) ) - 1; // fprintf(stderr, "input allele %zu: " GVA_VARIANT_FMT " (dist: %d) stored at: %d\n", rsid, GVA_VARIANT_PRINT(variant), graph.distance, allele_idx); @@ -529,7 +517,7 @@ main(int argc, char* argv[static argc + 1]) while (fgets(line, sizeof(line), stream) != NULL) { size_t idx = 0; - size_t const query_id = parse_number(line, &idx); + parse_number(line, &idx); idx += 1; // skip space or tab int const len = (char*) memchr(line + idx, '\n', LINE_SIZE - idx) - (line + idx); GVA_Variant rhs_var; @@ -883,14 +871,9 @@ main(int argc, char* argv[static argc + 1]) // fprintf(stderr, "allele_idx: %zu relation: %s in: %zu\n", allele_idx, GVA_RELATION_LABELS[relation], included); // only for testing - if (relation != GVA_EQUIVALENT || db_alleles[allele_idx].data < query_id) + if (relation != GVA_EQUIVALENT || db_alleles[allele_idx].line != line_count) { - printf("%zu %s %zu " GVA_VARIANT_FMT_SPDI " %s\n", - db_alleles[allele_idx].data, - db_alleles[allele_idx].spdi, - query_id, - GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, rhs_graph.supremal), - GVA_RELATION_LABELS[relation]); + printf("%u %zu %s\n", db_alleles[allele_idx].line, line_count, GVA_RELATION_LABELS[relation]); } } // if } // for all alleles @@ -909,16 +892,11 @@ main(int argc, char* argv[static argc + 1]) } // while fgets fclose(stream); - for (size_t allele_idx = 0; allele_idx < array_length(db_alleles); ++allele_idx) - { - free(db_alleles[allele_idx].spdi); - } db_alleles = ARRAY_DESTROY(gva_std_allocator, db_alleles); node_allele_join = ARRAY_DESTROY(gva_std_allocator, node_allele_join); interval_tree_destroy(gva_std_allocator, &tree); trie_destroy(gva_std_allocator, &trie); - gva_string_destroy(gva_std_allocator, reference); return EXIT_SUCCESS; -} // main +} // main \ No newline at end of file From b5ded07b10925372a4d8f2cad83ef9aa2d11b9ca Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Wed, 8 Oct 2025 14:59:30 +0200 Subject: [PATCH 411/704] Cleanup. --- src/main.c | 95 ++++++------------------------------------------------ 1 file changed, 10 insertions(+), 85 deletions(-) diff --git a/src/main.c b/src/main.c index def6ec1..de8ae58 100644 --- a/src/main.c +++ b/src/main.c @@ -473,7 +473,6 @@ main(int argc, char* argv[static argc + 1]) gva_std_allocator, db_alleles, ((struct Allele) {line_count, array_length(node_allele_join)}) ) - 1; - // fprintf(stderr, "input allele %zu: " GVA_VARIANT_FMT " (dist: %d) stored at: %d\n", rsid, GVA_VARIANT_PRINT(variant), graph.distance, allele_idx); for (size_t i = 0; i < array_length(graph.local_supremal) - 1; ++i) { @@ -488,11 +487,9 @@ main(int argc, char* argv[static argc + 1]) gva_uint const node_idx = interval_tree_insert(&tree, tmp_idx); if (node_idx != tmp_idx) { - // fprintf(stderr, " part %zu already in the tree\n", i); array_header(tree.nodes)->length -= 1; // reverse; node already in the tree } // if tree.nodes[node_idx].alleles = ARRAY_APPEND(gva_std_allocator, node_allele_join, ((struct Node_Allele) {node_idx, allele_idx, tree.nodes[node_idx].alleles})) - 1; - // fprintf(stderr, " input part %zu (allele %d): " GVA_VARIANT_FMT " stored at: %d\n", i, allele_idx, GVA_VARIANT_PRINT(part), node_idx); } // for gva_string_destroy(gva_std_allocator, graph.observed); @@ -546,13 +543,10 @@ main(int argc, char* argv[static argc + 1]) gva_uint included; }* node_parts_table = hash_table_init(gva_std_allocator, 1024, sizeof(*node_parts_table)); - // query graph GVA_LCS_Graph const rhs_graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &rhs_var); - // fprintf(stderr, "query allele %zu: " GVA_VARIANT_FMT " (dist: %u)\n", rhs_id, GVA_VARIANT_PRINT(rhs_var), rhs_graph.distance); for (size_t part_idx = 0; part_idx < array_length(rhs_graph.local_supremal) - 1; ++part_idx) { - // query local supremal part GVA_Variant rhs_part; gva_edges(rhs_graph.observed.str, rhs_graph.local_supremal[part_idx], rhs_graph.local_supremal[part_idx + 1], @@ -560,9 +554,7 @@ main(int argc, char* argv[static argc + 1]) &rhs_part); gva_uint const rhs_distance = rhs_graph.local_supremal[part_idx + 1].distance; - // fprintf(stderr, " query part %zu (dist: %d): " GVA_VARIANT_FMT "\n", part_idx, rhs_distance, GVA_VARIANT_PRINT(rhs_part)); - // find candidates for this local supremal part gva_uint* candidates = interval_tree_intersection(gva_std_allocator, tree, rhs_part.start, rhs_part.end); for (size_t can_idx = 0; can_idx < array_length(candidates); ++can_idx) { @@ -570,12 +562,10 @@ main(int argc, char* argv[static argc + 1]) GVA_Variant const db_var = {tree.nodes[node_idx].start, tree.nodes[node_idx].end, trie_string(trie, tree.nodes[node_idx].inserted)}; GVA_Relation const relation = compare_from_index(reference, db_var, tree.nodes[node_idx].distance, rhs_part, rhs_distance); - // fprintf(stderr, " db candidate node_idx: %d (dist: %d): " GVA_VARIANT_FMT " %s\n", node_idx, tree.nodes[node_idx].distance, GVA_VARIANT_PRINT(db_var), GVA_RELATION_LABELS[relation]); - if (relation == GVA_DISJOINT) { continue; - } + } // if // link nodes to query parts size_t hash_idx = HASH_TABLE_INDEX(node_parts_table, node_idx); @@ -616,15 +606,12 @@ main(int argc, char* argv[static argc + 1]) if (node_parts_table[npt_index].relation == GVA_CONTAINS && node_parts_table[npt_index].end - node_parts_table[npt_index].start > 1) { - // fprintf(stderr, " Perform extra comparison\n"); size_t const lhs_distance = tree.nodes[node_idx].distance; - size_t rhs_distance = 0; for (size_t i = node_parts_table[npt_index].start; i < node_parts_table[npt_index].end; ++i) { rhs_distance += rhs_graph.local_supremal[i + 1].distance; } // for - // fprintf(stderr, " slice dist: %zu node dist: %u\n", rhs_distance, lhs_distance); if (rhs_distance >= lhs_distance) { node_parts_table[npt_index].relation = GVA_OVERLAP; @@ -643,7 +630,6 @@ main(int argc, char* argv[static argc + 1]) node_parts_table[npt_index].start == 0, node_parts_table[npt_index].end == array_length(rhs_graph.local_supremal) - 1, &rhs); - // fprintf(stderr, GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(rhs)); size_t const distance = variants_distance(gva_std_allocator, reference.len, reference.str, lhs, rhs); // fprintf(stderr, "distance: %d\n", distance); @@ -652,37 +638,12 @@ main(int argc, char* argv[static argc + 1]) if (lhs_distance - distance != rhs_distance) { - // fprintf(stderr, "here B\n"); node_parts_table[npt_index].relation = GVA_OVERLAP; node_parts_table[npt_index].included = 1; - // fprintf(stderr, "OVERLAP!!\n"); } // if } // if } // for node_parts_table - // fprintf(stderr, "db_allele table:\n"); - // for (size_t i = 0; i < array_length(db_alleles); ++i) - // { - // fprintf(stderr, "entry: %zu %s %zu %zu\n", - // db_alleles[i].data, - // db_alleles[i].spdi, - // db_alleles[i].join_start, - // db_alleles[i].distance - // ); - // } - // fprintf(stderr, "\n"); - // - // fprintf(stderr, "node_allele_join table:\n"); - // for (size_t i = 0; i < array_length(node_allele_join); ++i) - // { - // fprintf(stderr, "entry: %zu %zu %d\n", - // node_allele_join[i].node, - // node_allele_join[i].allele, - // node_allele_join[i].next - // ); - // } - // fprintf(stderr, "\n"); - struct RESULT_ALLELES { HASH_TABLE_KEY; @@ -715,7 +676,6 @@ main(int argc, char* argv[static argc + 1]) { continue; } // if - // fprintf(stderr, "allele_idx: %zu\n", allele_idx); GVA_Relation relation = GVA_DISJOINT; gva_uint included = 0; @@ -724,12 +684,10 @@ main(int argc, char* argv[static argc + 1]) gva_uint is_contained_part_idx = -1; // loop over all nodes for this allele - // fprintf(stderr, "Loop over nodes for this allele:\n"); for (size_t join_idx = db_alleles[allele_idx].join_start; join_idx < array_length(node_allele_join) && node_allele_join[join_idx].allele == allele_idx; ++join_idx) { - // fprintf(stderr, "join_idx: %zu\n", join_idx); size_t const node_idx = node_allele_join[join_idx].node; // (re)calculate allele distance from nodes @@ -738,15 +696,12 @@ main(int argc, char* argv[static argc + 1]) size_t const hash_idx = HASH_TABLE_INDEX(node_parts_table, node_idx); if (node_idx != node_parts_table[hash_idx].gva_key) { - // fprintf(stderr, "when?!?\n"); continue; } // if - // fprintf(stderr, "node_idx: %zu\n", node_idx); if (node_parts_table[hash_idx].relation == GVA_EQUIVALENT) { included += node_parts_table[hash_idx].included; - if (relation == GVA_EQUIVALENT || relation == GVA_DISJOINT) { relation = GVA_EQUIVALENT; @@ -754,22 +709,17 @@ main(int argc, char* argv[static argc + 1]) } // if else if (node_parts_table[hash_idx].relation == GVA_CONTAINS) { - // fprintf(stderr, "here D\n"); included += node_parts_table[hash_idx].included; - if (relation == GVA_IS_CONTAINED) { - // included = 1; can it be an overestimate ?!? - relation = GVA_OVERLAP; + relation = GVA_OVERLAP; // TODO: included = 1; ??? break; - } + } // if relation = GVA_CONTAINS; - } + } // if else if (node_parts_table[hash_idx].relation == GVA_IS_CONTAINED) { size_t const part_idx = node_parts_table[hash_idx].start; - // fprintf(stderr, "part_idx: %zu\n", part_idx); - // fprintf(stderr, "if containment current: %s\n", GVA_RELATION_LABELS[relation]); if (relation == GVA_CONTAINS) { included += node_parts_table[hash_idx].included; // TODO: included = 1; ??? @@ -779,12 +729,9 @@ main(int argc, char* argv[static argc + 1]) if (part_idx != is_contained_part_idx) { - // fprintf(stderr, "close window upper %s\n", GVA_RELATION_LABELS[relation]); - // fprintf(stderr, "#is_contained_nodes: %zu\n", array_length(is_contained_nodes)); // close old window if (array_length(is_contained_nodes) > 1) { - // fprintf(stderr, "Found multiple is_containeds for the same part\n"); size_t const slice_dist = multiple_is_contained_distance(gva_std_allocator, reference.len, reference.str, rhs_graph, part_idx, tree, trie, is_contained_nodes); if (slice_dist == 1) @@ -797,12 +744,10 @@ main(int argc, char* argv[static argc + 1]) } // if else if (array_length(is_contained_nodes) == 1) { - // fprintf(stderr, "Now should add previous node\n"); included += tree.nodes[is_contained_nodes[0]].distance; - } + } // if // open new window - // fprintf(stderr, "open new window\n"); is_contained_part_idx = part_idx; is_contained_nodes = ARRAY_DESTROY(gva_std_allocator, is_contained_nodes); } // if part_idx != is_contained_part_idx @@ -811,30 +756,21 @@ main(int argc, char* argv[static argc + 1]) } // if relation == GVA_IS_CONTAINED else if (node_parts_table[hash_idx].relation == GVA_OVERLAP) { - // fprintf(stderr, "this overlap is reached\n"); included = 1; relation = GVA_OVERLAP; break; } // if - // fprintf(stderr, "here F\n"); } // for all nodes for this allele - // fprintf(stderr, "here G\n"); - - // fprintf(stderr, "included: %zu\n", included); - // close old window size_t const n = array_length(is_contained_nodes); if (relation == GVA_IS_CONTAINED && n == 1) { - // fprintf(stderr, "found single is_contained\n"); included += tree.nodes[is_contained_nodes[0]].distance; - // fprintf(stderr, "increase included with %u to %zu\n", tree.nodes[is_contained_nodes[0]].distance, included); } else if (relation == GVA_IS_CONTAINED && n > 1) { - // fprintf(stderr, "Found multiple is_containeds for the same part at the end\n"); size_t const slice_dist = multiple_is_contained_distance(gva_std_allocator, reference.len, reference.str, rhs_graph, is_contained_part_idx, tree, trie, is_contained_nodes); if (slice_dist == 1) @@ -845,7 +781,6 @@ main(int argc, char* argv[static argc + 1]) else { included += slice_dist; - // fprintf(stderr, "increase included with %zu to %zu\n", slice_dist, included); } // else } // if is_contained repair @@ -853,50 +788,40 @@ main(int argc, char* argv[static argc + 1]) if (included > 0) { - // fprintf(stderr, "allele dist: %u query dist: %u\n", db_alleles[allele_idx].distance, rhs_graph.distance); - // fprintf(stderr, "relation: %s\n", GVA_RELATION_LABELS[relation]); - gva_uint const lhs_excluded = results_table[results_idx].distance - included; gva_uint const rhs_excluded = rhs_graph.distance - included; - // fprintf(stderr, "included: %zu, lhs_excluded: %d rhs_excluded: %zu\n", - // included, lhs_excluded, rhs_excluded); if (lhs_excluded > 0 && rhs_excluded > 0) { relation = GVA_OVERLAP; - } + } // if else if (lhs_excluded > 0) { relation = GVA_CONTAINS; - } + } // if else if (rhs_excluded > 0) { relation = GVA_IS_CONTAINED; - } + } // if else // if (lhs_excluded == 0 && rhs_excluded == 0) { relation = GVA_EQUIVALENT; - } - // fprintf(stderr, "allele_idx: %zu relation: %s in: %zu\n", allele_idx, GVA_RELATION_LABELS[relation], included); + } // else // only for testing if (relation != GVA_EQUIVALENT || db_alleles[allele_idx].line != line_count) { printf("%u %zu %s\n", db_alleles[allele_idx].line, line_count, GVA_RELATION_LABELS[relation]); - } + } // if } // if } // for all alleles - - // fprintf(stderr, "\n"); - results_table = HASH_TABLE_DESTROY(gva_std_allocator, results_table); node_parts_table = HASH_TABLE_DESTROY(gva_std_allocator, node_parts_table); gva_string_destroy(gva_std_allocator, rhs_graph.observed); gva_lcs_graph_destroy(gva_std_allocator, rhs_graph); - // fprintf(stderr, "\n"); line_count += 1; } // while fgets fclose(stream); From 9879ba75fc03567314dd613f1343af14e8f2459c Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Wed, 8 Oct 2025 14:59:52 +0200 Subject: [PATCH 412/704] Inverse logic. --- src/main.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main.c b/src/main.c index de8ae58..d471078 100644 --- a/src/main.c +++ b/src/main.c @@ -632,11 +632,11 @@ main(int argc, char* argv[static argc + 1]) &rhs); size_t const distance = variants_distance(gva_std_allocator, reference.len, reference.str, lhs, rhs); - // fprintf(stderr, "distance: %d\n", distance); - - node_parts_table[npt_index].included = rhs_distance; - - if (lhs_distance - distance != rhs_distance) + if (lhs_distance - distance == rhs_distance) + { + node_parts_table[npt_index].included = rhs_distance; + } // if + else { node_parts_table[npt_index].relation = GVA_OVERLAP; node_parts_table[npt_index].included = 1; From 45f5003bc736103da98efa8c2994af77e77c7ecc Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Wed, 8 Oct 2025 15:04:34 +0200 Subject: [PATCH 413/704] Store allele distance in array. --- src/main.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/main.c b/src/main.c index d471078..eb6b8db 100644 --- a/src/main.c +++ b/src/main.c @@ -450,6 +450,7 @@ main(int argc, char* argv[static argc + 1]) { gva_uint line; gva_uint join_start; // offset into node_allele_join + gva_uint distance; }* db_alleles = NULL; size_t line_count = 0; @@ -471,7 +472,7 @@ main(int argc, char* argv[static argc + 1]) gva_uint const allele_idx = ARRAY_APPEND( gva_std_allocator, db_alleles, - ((struct Allele) {line_count, array_length(node_allele_join)}) + ((struct Allele) {line_count, array_length(node_allele_join), graph.distance}) ) - 1; for (size_t i = 0; i < array_length(graph.local_supremal) - 1; ++i) @@ -647,7 +648,6 @@ main(int argc, char* argv[static argc + 1]) struct RESULT_ALLELES { HASH_TABLE_KEY; - gva_uint distance; }* results_table = hash_table_init(gva_std_allocator, 1024, sizeof(*results_table)); // find all alleles that were part of a non-disjoint relation @@ -664,7 +664,7 @@ main(int argc, char* argv[static argc + 1]) naj_table_idx = node_allele_join[naj_table_idx].next) { size_t const allele_idx = node_allele_join[naj_table_idx].allele; - HASH_TABLE_SET(gva_std_allocator, results_table, allele_idx, ((struct RESULT_ALLELES) {allele_idx, 0})); + HASH_TABLE_SET(gva_std_allocator, results_table, allele_idx, ((struct RESULT_ALLELES) {allele_idx})); } // for alleles } // for node_parts_table @@ -690,9 +690,6 @@ main(int argc, char* argv[static argc + 1]) { size_t const node_idx = node_allele_join[join_idx].node; - // (re)calculate allele distance from nodes - results_table[results_idx].distance += tree.nodes[node_idx].distance; - size_t const hash_idx = HASH_TABLE_INDEX(node_parts_table, node_idx); if (node_idx != node_parts_table[hash_idx].gva_key) { @@ -788,7 +785,7 @@ main(int argc, char* argv[static argc + 1]) if (included > 0) { - gva_uint const lhs_excluded = results_table[results_idx].distance - included; + gva_uint const lhs_excluded = db_alleles[allele_idx].distance - included; gva_uint const rhs_excluded = rhs_graph.distance - included; if (lhs_excluded > 0 && rhs_excluded > 0) From 5c32e22a7f018691453cfda5b8540527e0be061e Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 8 Oct 2025 16:22:57 +0200 Subject: [PATCH 414/704] Expose entry not found in hash table --- src/hash_table.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/hash_table.h b/src/hash_table.h index 9ab1fc2..f8c603d 100644 --- a/src/hash_table.h +++ b/src/hash_table.h @@ -3,7 +3,7 @@ #include // size_t -#include // uint32_t +#include // UINT32_MAX, uint32_t #include "../include/allocator.h" // GVA_Allocator #include "array.h" // ARRAY_DESTROY, array_header @@ -12,6 +12,9 @@ #define HASH_TABLE_KEY uint32_t gva_key +static uint32_t const GVA_NOT_FOUND = UINT32_MAX; + + void* hash_table_init(GVA_Allocator const allocator, size_t const capacity, size_t const item_size); From 08eb77d6bd1b260cdfc4064078968da5e6d17940 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Thu, 9 Oct 2025 10:01:37 +0200 Subject: [PATCH 415/704] Cover the n > 1 path for is_contained correction within the loop. --- test_alleles.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test_alleles.txt b/test_alleles.txt index 8b91ba8..d18ebcd 100644 --- a/test_alleles.txt +++ b/test_alleles.txt @@ -39,3 +39,5 @@ 202102073 NC_000001.11:143535768:9:TTTTTTTTTTT 879278532 NC_000001.11:164871874:5:AC 746240940 NC_000001.11:164871870:9: +1553151551 NC_000001.11:2656571:CCACACCCCCAGGTGAGCATCCGACAGCCTGGAGCAGCACCCACACCCCCAGGTGAGCATGTGACAGCCTGGAAG:ACCCACACCACCAGGCGATCATCCGC +878949278 NC_000001.11:2656570:CCCACACCCCCAGGTGAGCATCCGACAGCCTGGAGCAGCACCCACACCCCCAGGTGAGCATGTGACAGCCTGGAAG:AACCCACACCCCCAGGCGAGCATCTGA From 48292a857d18db58aaf78989b9b577b6a70a751a Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Thu, 9 Oct 2025 10:08:18 +0200 Subject: [PATCH 416/704] More explicit. --- src/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.c b/src/main.c index eb6b8db..c290757 100644 --- a/src/main.c +++ b/src/main.c @@ -20,7 +20,7 @@ #include "array.h" // ARRAY_DESTROY, array_length #include "bitset.h" // bitset_* #include "common.h" // MAX, MIN -#include "hash_table.h" // HASH_TABLE_KEY, hash_table_* +#include "hash_table.h" // GVA_NOT_FOUND, HASH_TABLE_KEY, hash_table_* #include "interval_tree.h" // Interval_Tree, interval_tree_* #include "trie.h" // Trie, trie_* @@ -599,7 +599,7 @@ main(int argc, char* argv[static argc + 1]) for (size_t npt_index = 0; npt_index < array_header(node_parts_table)->capacity; ++npt_index) { size_t const node_idx = node_parts_table[npt_index].gva_key; - if (node_idx == (uint32_t) -1) + if (node_idx == GVA_NOT_FOUND) { continue; } // if From 5e98031e024627b84914a54c13b3b2774dd630d2 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Thu, 9 Oct 2025 10:10:45 +0200 Subject: [PATCH 417/704] Consistent order. --- src/main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main.c b/src/main.c index c290757..df65a80 100644 --- a/src/main.c +++ b/src/main.c @@ -615,8 +615,8 @@ main(int argc, char* argv[static argc + 1]) } // for if (rhs_distance >= lhs_distance) { - node_parts_table[npt_index].relation = GVA_OVERLAP; node_parts_table[npt_index].included = 1; + node_parts_table[npt_index].relation = GVA_OVERLAP; continue; } // if @@ -639,8 +639,8 @@ main(int argc, char* argv[static argc + 1]) } // if else { - node_parts_table[npt_index].relation = GVA_OVERLAP; node_parts_table[npt_index].included = 1; + node_parts_table[npt_index].relation = GVA_OVERLAP; } // if } // if } // for node_parts_table @@ -677,8 +677,8 @@ main(int argc, char* argv[static argc + 1]) continue; } // if - GVA_Relation relation = GVA_DISJOINT; gva_uint included = 0; + GVA_Relation relation = GVA_DISJOINT; gva_uint* is_contained_nodes = NULL; gva_uint is_contained_part_idx = -1; From 36e66d57c57a2b44ada71f501de7ef74d37a05c9 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Thu, 9 Oct 2025 11:29:51 +0200 Subject: [PATCH 418/704] Equiv in one direction only. --- src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.c b/src/main.c index df65a80..83ebdb7 100644 --- a/src/main.c +++ b/src/main.c @@ -806,7 +806,7 @@ main(int argc, char* argv[static argc + 1]) } // else // only for testing - if (relation != GVA_EQUIVALENT || db_alleles[allele_idx].line != line_count) + if (relation != GVA_EQUIVALENT || db_alleles[allele_idx].line < line_count) { printf("%u %zu %s\n", db_alleles[allele_idx].line, line_count, GVA_RELATION_LABELS[relation]); } // if From e7aa6a837a1db396889275c1f44b7d00b1a9eb0d Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Thu, 9 Oct 2025 11:30:08 +0200 Subject: [PATCH 419/704] Repair is_contained in function. --- src/main.c | 78 ++++++++++++++++++++++-------------------------------- 1 file changed, 32 insertions(+), 46 deletions(-) diff --git a/src/main.c b/src/main.c index 83ebdb7..2d581aa 100644 --- a/src/main.c +++ b/src/main.c @@ -419,6 +419,32 @@ vcf_main(int argc, char* argv[static argc + 1]) } // vcf_main +void +repair_is_contained(GVA_Allocator const allocator, GVA_String const reference, GVA_LCS_Graph const graph, Interval_Tree const tree, Trie const trie, + gva_uint** nodes, gva_uint const part_idx, gva_uint* const included, GVA_Relation* const relation) +{ + size_t const nodes_len = array_length(*nodes); + if (*relation == GVA_IS_CONTAINED && nodes_len == 1) + { + *included += tree.nodes[*nodes[0]].distance; + } // if + else if (*relation == GVA_IS_CONTAINED && nodes_len > 1) + { + size_t const slice_dist = multiple_is_contained_distance(allocator, reference.len, reference.str, + graph, part_idx, tree, trie, *nodes); + if (slice_dist == 1) + { + *included = 1; + *relation = GVA_OVERLAP; + } // if + else + { + *included += slice_dist; + } // else + } // if + *nodes = ARRAY_DESTROY(gva_std_allocator, *nodes); +} + int main(int argc, char* argv[static argc + 1]) { @@ -726,62 +752,22 @@ main(int argc, char* argv[static argc + 1]) if (part_idx != is_contained_part_idx) { - // close old window - if (array_length(is_contained_nodes) > 1) - { - size_t const slice_dist = multiple_is_contained_distance(gva_std_allocator, reference.len, reference.str, - rhs_graph, part_idx, tree, trie, is_contained_nodes); - if (slice_dist == 1) - { - included = 1; - relation = GVA_OVERLAP; - break; - } // if - included += slice_dist; - } // if - else if (array_length(is_contained_nodes) == 1) - { - included += tree.nodes[is_contained_nodes[0]].distance; - } // if - - // open new window + repair_is_contained(gva_std_allocator, reference, rhs_graph, tree, trie, + &is_contained_nodes, is_contained_part_idx, &included, &relation); is_contained_part_idx = part_idx; - is_contained_nodes = ARRAY_DESTROY(gva_std_allocator, is_contained_nodes); - } // if part_idx != is_contained_part_idx + } // if ARRAY_APPEND(gva_std_allocator, is_contained_nodes, node_idx); relation = GVA_IS_CONTAINED; - } // if relation == GVA_IS_CONTAINED + } // if else if (node_parts_table[hash_idx].relation == GVA_OVERLAP) { included = 1; relation = GVA_OVERLAP; break; } // if - } // for all nodes for this allele - - // close old window - size_t const n = array_length(is_contained_nodes); - if (relation == GVA_IS_CONTAINED && n == 1) - { - included += tree.nodes[is_contained_nodes[0]].distance; - } - else if (relation == GVA_IS_CONTAINED && n > 1) - { - size_t const slice_dist = multiple_is_contained_distance(gva_std_allocator, reference.len, reference.str, - rhs_graph, is_contained_part_idx, tree, trie, is_contained_nodes); - if (slice_dist == 1) - { - included = 1; - relation = GVA_OVERLAP; - } // if - else - { - included += slice_dist; - } // else - - } // if is_contained repair - is_contained_nodes = ARRAY_DESTROY(gva_std_allocator, is_contained_nodes); + repair_is_contained(gva_std_allocator, reference, rhs_graph, tree, trie, + &is_contained_nodes, is_contained_part_idx, &included, &relation); if (included > 0) { From c482d6f610cb5f5ef52a636b7e43efd16dd81847 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Thu, 9 Oct 2025 13:14:35 +0200 Subject: [PATCH 420/704] More GVA_NOT_FOUND. --- src/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.c b/src/main.c index 2d581aa..d633c4c 100644 --- a/src/main.c +++ b/src/main.c @@ -680,7 +680,7 @@ main(int argc, char* argv[static argc + 1]) for (size_t npt_idx = 0; npt_idx < array_header(node_parts_table)->capacity; ++npt_idx) { size_t const node_idx = node_parts_table[npt_idx].gva_key; - if (node_idx == (uint32_t) - 1) + if (node_idx == GVA_NOT_FOUND) { continue; } // if @@ -698,7 +698,7 @@ main(int argc, char* argv[static argc + 1]) for (size_t results_idx = 0; results_idx < array_header(results_table)->capacity; ++results_idx) { size_t allele_idx = results_table[results_idx].gva_key; - if (allele_idx == (uint32_t) - 1) + if (allele_idx == GVA_NOT_FOUND) { continue; } // if From 4753fac6a2f78c4acd5e2a1ff4eabcb96239f7f2 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Fri, 10 Oct 2025 14:14:53 +0200 Subject: [PATCH 421/704] A new day, a new main. --- src/main.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/main.c b/src/main.c index d633c4c..bf23c7d 100644 --- a/src/main.c +++ b/src/main.c @@ -445,11 +445,10 @@ repair_is_contained(GVA_Allocator const allocator, GVA_String const reference, G *nodes = ARRAY_DESTROY(gva_std_allocator, *nodes); } + int -main(int argc, char* argv[static argc + 1]) +dbsnp_main(int argc, char* argv[static argc + 1]) { - // return vcf_main(argc, argv); - errno = 0; FILE* stream = fopen(argv[1], "r"); if (stream == NULL) @@ -816,4 +815,12 @@ main(int argc, char* argv[static argc + 1]) gva_string_destroy(gva_std_allocator, reference); return EXIT_SUCCESS; -} // main \ No newline at end of file +} // dbsnp_main + + +int +main(int argc, char* argv[static argc + 1]) +{ +// return vcf_main(argc, argv); + return dbsnp_main(argc, argv); +} \ No newline at end of file From 0ddfa8a6c13b7bfac279f70526d472d94847dc55 Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 13 Oct 2025 10:27:02 +0200 Subject: [PATCH 422/704] Macro like array --- src/hash_table.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/hash_table.h b/src/hash_table.h index f8c603d..4014b0f 100644 --- a/src/hash_table.h +++ b/src/hash_table.h @@ -33,10 +33,11 @@ hash_table_ensure(GVA_Allocator const allocator, void* const self, size_t const #define HASH_TABLE_INDEX(self, key) hash_table_index(self, sizeof(*self), key) -#define HASH_TABLE_SET(allocator, self, key, value) \ +#define HASH_TABLE_SET(allocator, self, key, value) ( \ (self) = hash_table_ensure(allocator, self, sizeof(*(self))), \ array_header(self)->length += 1, \ - self[hash_table_index(self, sizeof(*(self)), key)] = (value) + self[hash_table_index(self, sizeof(*(self)), key)] = (value) \ +) #endif // GVA_HASH_TABLE_H From 2b88602ded2fcd0dccc0bae5f45d50b1db426d38 Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 13 Oct 2025 10:27:21 +0200 Subject: [PATCH 423/704] Allele reader --- src/main.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/main.c b/src/main.c index eb6b8db..4f5508c 100644 --- a/src/main.c +++ b/src/main.c @@ -214,6 +214,7 @@ construct_variant(GVA_Allocator const allocator, size_t const len_ref, char const reference[static len_ref], Interval_Tree const tree, Trie const trie, gva_uint* const nodes) { + // FIXME: in 1 loop size_t const n = array_length(nodes); GVA_Variant* variants = allocator.allocate(allocator.context, NULL, 0, n * sizeof(*variants)); for (size_t i = 0; i < n; ++i) @@ -377,7 +378,7 @@ vcf_main(int argc, char* argv[static argc + 1]) &local); if (i < array_length(graph.local_supremal) - 2) { - //fprintf(stderr, "OUT: " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(local)); + printf(GVA_VARIANT_FMT_SPDI "\n", GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, local)); out_count += 1; } // if } // for @@ -394,14 +395,14 @@ vcf_main(int argc, char* argv[static argc + 1]) count += 1; } // while GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, variants); - GVA_Variant local; for (size_t i = 0; i < array_length(graph.local_supremal) - 1; ++i) { + GVA_Variant local; gva_edges(graph.observed.str, graph.local_supremal[i], graph.local_supremal[i + 1], i == 0, i == array_length(graph.local_supremal) - 2, &local); - //fprintf(stderr, "OUT: " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(local)); + printf(GVA_VARIANT_FMT_SPDI "\n", GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, local)); out_count += 1; } // for if (count > 0) @@ -411,8 +412,8 @@ vcf_main(int argc, char* argv[static argc + 1]) gva_string_destroy(gva_std_allocator, graph.observed); gva_lcs_graph_destroy(gva_std_allocator, graph); - printf("#local supremal parts: %zu\n", out_count); - printf("#dropped variants: %zu\n", drop_count); + fprintf(stderr, "#local supremal parts: %zu\n", out_count); + fprintf(stderr, "#dropped variants: %zu\n", drop_count); gva_string_destroy(gva_std_allocator, reference); return EXIT_SUCCESS; @@ -702,7 +703,7 @@ main(int argc, char* argv[static argc + 1]) if (relation == GVA_EQUIVALENT || relation == GVA_DISJOINT) { relation = GVA_EQUIVALENT; - } + } // if } // if else if (node_parts_table[hash_idx].relation == GVA_CONTAINS) { @@ -830,4 +831,4 @@ main(int argc, char* argv[static argc + 1]) gva_string_destroy(gva_std_allocator, reference); return EXIT_SUCCESS; -} // main \ No newline at end of file +} // main From a219af7d7b99d7d75f0fe195e40a926d94ab8075 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Tue, 14 Oct 2025 14:33:54 +0200 Subject: [PATCH 424/704] Also print/store distance per local supremal part. --- src/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.c b/src/main.c index c72464d..0710048 100644 --- a/src/main.c +++ b/src/main.c @@ -378,7 +378,7 @@ vcf_main(int argc, char* argv[static argc + 1]) &local); if (i < array_length(graph.local_supremal) - 2) { - printf(GVA_VARIANT_FMT_SPDI "\n", GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, local)); + printf("%u " GVA_VARIANT_FMT_SPDI "\n", graph.local_supremal[i + 1].distance, GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, local)); out_count += 1; } // if } // for @@ -402,7 +402,7 @@ vcf_main(int argc, char* argv[static argc + 1]) graph.local_supremal[i], graph.local_supremal[i + 1], i == 0, i == array_length(graph.local_supremal) - 2, &local); - printf(GVA_VARIANT_FMT_SPDI "\n", GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, local)); + printf("%u " GVA_VARIANT_FMT_SPDI "\n", graph.local_supremal[i + 1].distance, GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, local)); out_count += 1; } // for if (count > 0) From f6c7450886f59fbcd603ed55b24faac9368b0562 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Thu, 16 Oct 2025 15:11:56 +0200 Subject: [PATCH 425/704] Fasta blob write. Valgrind in 2s for chr1. --- src/main.c | 341 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 338 insertions(+), 3 deletions(-) diff --git a/src/main.c b/src/main.c index 0710048..f846446 100644 --- a/src/main.c +++ b/src/main.c @@ -2,7 +2,7 @@ #include // errno #include // CHAR_BIT #include // NULL, size_t -#include // FILE, stderr, fclose, fopen, fprintf +#include // FILE, stderr, stdout, fclose, fopen, fprintf #include // EXIT_* #include // strerror, strlen @@ -47,6 +47,88 @@ parse_number(char const buffer[static 1], size_t idx[static 1]) } // parse_number +GVA_String +gva_fasta_sequence_blob(GVA_Allocator const allocator, FILE* const stream) +{ + GVA_String reference = {0, NULL}; + + static char line[42] = {0}; + if (fgets(line, sizeof(line), stream) == NULL) + { + fprintf(stderr, "error: %s\n", strerror(errno)); + return reference; + } // if + size_t idx = 0; + size_t length = parse_number(line, &idx); + + reference.str = allocator.allocate(allocator.context, NULL, 0, length); + if (reference.str == NULL) + { + fprintf(stderr, "allocate error: %s\n", strerror(errno)); + return reference; + } // if + + if (fgets((char *)reference.str, length, stream) == NULL) + { + fprintf(stderr, "read error: %s\n", strerror(errno)); + gva_string_destroy(gva_std_allocator, reference); + return reference; + } // + reference.len = length; + + return reference; +} // gva_fasta_sequence_blob + + +int +fasta_blob_write(int argc, char* argv[static argc + 1]) +{ + errno = 0; + FILE* stream = fopen(argv[1], "r"); + if (stream == NULL) + { + fprintf(stderr, "error: %s\n", strerror(errno)); + return EXIT_FAILURE; + } // if + + GVA_String reference = {0, NULL}; + reference = gva_fasta_sequence(gva_std_allocator, stream); + fclose(stream); + + fprintf(stderr, "reference length: %zu\n", reference.len); + + fprintf(stdout, "%zu\n", reference.len); + size_t const ret = fwrite(reference.str, 1, reference.len, stdout); + if (ret != reference.len) + { + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} // fasta_blob_write + + +int +fasta_blob_read(int argc, char* argv[static argc + 1]) +{ + errno = 0; + FILE* stream = fopen(argv[1], "r"); + if (stream == NULL) + { + fprintf(stderr, "error: %s\n", strerror(errno)); + return EXIT_FAILURE; + } // if + + GVA_String reference = gva_fasta_sequence_blob(gva_std_allocator, stream); + fclose(stream); + + fprintf(stderr, "reference length: %zu\n", reference.len); + gva_string_destroy(gva_std_allocator, reference); + + return EXIT_SUCCESS; +} // fasta_blob_read + + GVA_Relation compare_from_index(GVA_String const reference, GVA_Variant const lhs, gva_uint const lhs_distance, @@ -819,9 +901,262 @@ dbsnp_main(int argc, char* argv[static argc + 1]) } // dbsnp_main +int +locals_main(int argc, char* argv[static argc + 1]) +{ + errno = 0; + FILE* stream = fopen(argv[1], "r"); + if (stream == NULL) + { + fprintf(stderr, "error: %s\n", strerror(errno)); + return EXIT_FAILURE; + } // if + + GVA_String reference = {0, NULL}; + reference = gva_fasta_sequence(gva_std_allocator, stream); + fclose(stream); + + fprintf(stderr, "reference length: %zu\n", reference.len); + + Trie trie = trie_init(); + Interval_Tree tree = interval_tree_init(); + + struct Node_Allele + { + gva_uint node; + gva_uint allele; + gva_uint next; + }* node_allele_join = NULL; + struct Allele + { + gva_uint data; + gva_uint join_start; // offset into node_allele_join + gva_uint distance; + }* db_alleles = NULL; + + errno = 0; + stream = fopen(argv[2], "r"); + if (stream == NULL) + { + fprintf(stderr, "error: %s\n", strerror(errno)); + return EXIT_FAILURE; + } // if + + static char line[LINE_SIZE] = {0}; + size_t line_count = 0; + size_t parts = 0; + while (fgets(line, sizeof(line), stream) != NULL) + { + size_t idx = 0; + size_t data = parse_number(line, &idx); // glob index + idx += 1; // skip space or tab + size_t allele_entries = parse_number(line, &idx); + parts += allele_entries; + + size_t const allele_idx = ARRAY_APPEND(gva_std_allocator, db_alleles, ((struct Allele) {data, array_length(node_allele_join), 0})) - 1; + fprintf(stderr, "allele: %zu (%zu) length: %zu\n", data, allele_idx, allele_entries); + + size_t allele_distance = 0; + line_count += 1; + for (size_t i = 0; i < allele_entries; ++i) + { + fgets(line, sizeof(line), stream); + idx = 0; + size_t const distance = parse_number(line, &idx); + allele_distance += distance; + idx += 1; + int const len = (char*) memchr(line + idx, '\n', LINE_SIZE - idx) - (line + idx); + GVA_Variant variant; + if (gva_parse_spdi(len, line + idx, &variant) == 0) { + fprintf(stderr, "error: SPDI parsing failed at line %zu: %s", line_count + 1, line); + continue; + } // + // fprintf(stderr, GVA_VARIANT_FMT " %zu\n", GVA_VARIANT_PRINT(variant), distance); + + gva_uint const inserted_idx = trie_insert(gva_std_allocator, &trie, variant.sequence.len, variant.sequence.str); + gva_uint const tmp_idx = ARRAY_APPEND(gva_std_allocator, tree.nodes, + ((Interval_Tree_Node) {{GVA_NULL, GVA_NULL}, + variant.start, variant.end, variant.end, 0, inserted_idx, GVA_NULL, distance})) - 1; + gva_uint const node_idx = interval_tree_insert(&tree, tmp_idx); + if (node_idx != tmp_idx) + { + array_header(tree.nodes)->length -= 1; // reverse; node already in the tree + } // if + tree.nodes[node_idx].alleles = ARRAY_APPEND(gva_std_allocator, node_allele_join, ((struct Node_Allele) {node_idx, allele_idx, tree.nodes[node_idx].alleles})) - 1; + + line_count += 1; + } // for + } // while + fprintf(stderr, "line count: %zu\n", line_count); + + fprintf(stderr, "parts: %zu\n", parts); + fprintf(stderr, "tree nodes: %zu\n", array_length(tree.nodes)); + fprintf(stderr, "trie nodes: %zu (%zu)\n", array_length(trie.nodes), trie.strings.len); + + fprintf(stderr, "#db_alleles: %zu\n", array_length(db_alleles)); + fprintf(stderr, "#join: %zu\n", array_length(node_allele_join)); + + // line_count = 0; + // parts = 0; + // while (fgets(line, sizeof(line), stdin) != NULL) { + // size_t idx = 0; + // size_t data = parse_number(line, &idx); // glob index + // idx += 1; // skip space or tab + // size_t allele_entries = parse_number(line, &idx); + // parts += allele_entries; + // + // size_t const allele_idx = ARRAY_APPEND(gva_std_allocator, db_alleles, + // ((struct Allele) {data, array_length(node_allele_join), 0})) - 1; + // fprintf(stderr, "allele: %zu (%zu) length: %zu\n", data, allele_idx, allele_entries); + // + // // Join nodes in the index to parts in the query + // struct NODE_PARTS + // { + // HASH_TABLE_KEY; + // GVA_Relation relation; + // gva_uint start; + // gva_uint end; + // gva_uint included; + // }* node_parts_table = hash_table_init(gva_std_allocator, 1024, sizeof(*node_parts_table)); + // + // gva_uint part_distances[allele_entries]; + // gva_uint part_starts[allele_entries]; + // gva_uint part_ends[allele_entries]; + // + // size_t allele_distance = 0; + // line_count += 1; + // for (size_t part_idx = 0; part_idx < allele_entries; ++part_idx) { + // fgets(line, sizeof(line), stdin); + // idx = 0; + // size_t const rhs_distance = parse_number(line, &idx); + // allele_distance += rhs_distance; + // idx += 1; + // int const len = (char *) memchr(line + idx, '\n', LINE_SIZE - idx) - (line + idx); + // GVA_Variant rhs_part; + // if (gva_parse_spdi(len, line + idx, &rhs_part) == 0) { + // fprintf(stderr, "error: SPDI parsing failed at line %zu: %s", line_count + 1, line); + // continue; + // } // + // // fprintf(stderr, GVA_VARIANT_FMT " %zu\n", GVA_VARIANT_PRINT(rhs_part), distance); + // part_distances[part_idx] = rhs_distance; + // part_starts[part_idx] = rhs_part.start; + // part_ends[part_idx] = rhs_part.end; + // + // gva_uint* candidates = interval_tree_intersection(gva_std_allocator, tree, rhs_part.start, rhs_part.end); + // for (size_t can_idx = 0; can_idx < array_length(candidates); ++can_idx) + // { + // gva_uint const node_idx = candidates[can_idx]; + // GVA_Variant const db_var = {tree.nodes[node_idx].start, tree.nodes[node_idx].end, + // trie_string(trie, tree.nodes[node_idx].inserted)}; + // GVA_Relation const relation = compare_from_index(reference, db_var, tree.nodes[node_idx].distance, rhs_part, rhs_distance); + // if (relation == GVA_DISJOINT) + // { + // continue; + // } // if + // + // // link nodes to query parts + // size_t hash_idx = HASH_TABLE_INDEX(node_parts_table, node_idx); + // if (node_parts_table[hash_idx].gva_key != node_idx) + // { + // HASH_TABLE_SET(gva_std_allocator, node_parts_table, node_idx, + // ((struct NODE_PARTS) {node_idx, relation, part_idx, part_idx + 1, rhs_distance})); + // hash_idx = HASH_TABLE_INDEX(node_parts_table, node_idx); + // } // if + // + // if (relation == GVA_EQUIVALENT || relation == GVA_IS_CONTAINED) + // { + // node_parts_table[hash_idx].included = tree.nodes[node_idx].distance; + // } // if + // else if (relation == GVA_CONTAINS) + // { + // node_parts_table[hash_idx].end = part_idx + 1; + // } // if + // else // GVA_OVERLAP + // { + // node_parts_table[hash_idx].included = 1; + // } // else + // } // for every candidate + // candidates = ARRAY_DESTROY(gva_std_allocator, candidates); + // + // } // for + // + // // fix containment for multiple parts in single node for every query + // for (size_t npt_index = 0; npt_index < array_header(node_parts_table)->capacity; ++npt_index) + // { + // size_t const node_idx = node_parts_table[npt_index].gva_key; + // if (node_idx == GVA_NOT_FOUND) + // { + // continue; + // } // if + // + // if (node_parts_table[npt_index].relation == GVA_CONTAINS && + // node_parts_table[npt_index].end - node_parts_table[npt_index].start > 1) + // { + // size_t const lhs_distance = tree.nodes[node_idx].distance; + // size_t rhs_distance = 0; + // for (size_t i = node_parts_table[npt_index].start; i < node_parts_table[npt_index].end; ++i) + // { + // // TODO: which distance?! + // // rhs_distance += rhs_graph.local_supremal[i + 1].distance; + // rhs_distance += part_distances[i]; + // + // } // for + // if (rhs_distance >= lhs_distance) + // { + // node_parts_table[npt_index].included = 1; + // node_parts_table[npt_index].relation = GVA_OVERLAP; + // continue; + // } // if + // + // GVA_Variant const lhs = {tree.nodes[node_idx].start, + // tree.nodes[node_idx].end, + // trie_string(trie, tree.nodes[node_idx].inserted)}; + // + // GVA_Variant rhs; + // gva_edges(rhs_graph.observed.str, + // // rhs_graph.local_supremal[node_parts_table[npt_index].start], + // // rhs_graph.local_supremal[node_parts_table[npt_index].end], + // rhs_graph.local_supremal[node_parts_table[npt_index].start], + // rhs_graph.local_supremal[node_parts_table[npt_index].end], + // node_parts_table[npt_index].start == 0, + // node_parts_table[npt_index].end == array_length(rhs_graph.local_supremal) - 1, + // &rhs); + // + // size_t const distance = variants_distance(gva_std_allocator, reference.len, reference.str, lhs, rhs); + // if (lhs_distance - distance == rhs_distance) + // { + // node_parts_table[npt_index].included = rhs_distance; + // } // if + // else + // { + // node_parts_table[npt_index].included = 1; + // node_parts_table[npt_index].relation = GVA_OVERLAP; + // } // if + // } // if + // } // for node_parts_table + // + // node_parts_table = HASH_TABLE_DESTROY(gva_std_allocator, node_parts_table); + // } // while + + + + + db_alleles = ARRAY_DESTROY(gva_std_allocator, db_alleles); + node_allele_join = ARRAY_DESTROY(gva_std_allocator, node_allele_join); + interval_tree_destroy(gva_std_allocator, &tree); + trie_destroy(gva_std_allocator, &trie); + gva_string_destroy(gva_std_allocator, reference); + + return EXIT_SUCCESS; +} // dbsnp_main + + int main(int argc, char* argv[static argc + 1]) { - // return vcf_main(argc, argv); - return dbsnp_main(argc, argv); + // return fasta_blob_read(argc, argv); + // return fasta_blob_write(argc, argv); + return vcf_main(argc, argv); + // return dbsnp_main(argc, argv); + // return locals_main(argc, argv); } // main From 5829ebb8b346dccf6484302c761eefb0a4b19bb9 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Mon, 3 Nov 2025 15:07:57 +0100 Subject: [PATCH 426/704] WIP drop cancelling variants. --- src/main.c | 61 ++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 45 insertions(+), 16 deletions(-) diff --git a/src/main.c b/src/main.c index f846446..a689789 100644 --- a/src/main.c +++ b/src/main.c @@ -423,17 +423,19 @@ vcf_main(int argc, char* argv[static argc + 1]) return EXIT_FAILURE; } // if - GVA_String reference = {0, NULL}; - reference = gva_fasta_sequence(gva_std_allocator, stream); + GVA_String reference = gva_fasta_sequence(gva_std_allocator, stream); fclose(stream); + fprintf(stderr, "reference length: %zu\n", reference.len); GVA_Variant variants[2]; size_t count = 0; size_t out_count = 0; size_t drop_count = 0; static char line[LINE_SIZE] = {0}; + // read line while (fgets(line, sizeof(line), stdin) != NULL) { + // fprintf(stderr, "count: %zu\n", count); int const len = (char*) memchr(line, '\n', LINE_SIZE) - line; if (gva_parse_spdi(len, line, &variants[count > 0]) == 0) { @@ -442,6 +444,7 @@ vcf_main(int argc, char* argv[static argc + 1]) } // if variants[count > 0] = prefix_trimmed(reference.len, reference.str, variants[count > 0]); + // fprintf(stderr, "variant: " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(variants[count > 0])); if (count > 0 && variants[0].end > variants[1].start) { @@ -450,10 +453,25 @@ vcf_main(int argc, char* argv[static argc + 1]) continue; } // if + // TODO: memory allocated here GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1 + (count > 0), variants); + // fprintf(stderr, "graph distance: %u\n", graph.distance); + + if (graph.distance == 0) + { + fprintf(stderr, "drop0: " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(variants[0])); + fprintf(stderr, "drop1: " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(variants[1])); + count = 0; + gva_string_destroy(gva_std_allocator, variants[0].sequence); + gva_string_destroy(gva_std_allocator, graph.observed); + gva_lcs_graph_destroy(gva_std_allocator, graph); + continue; + } + GVA_Variant local; for (size_t i = 0; i < array_length(graph.local_supremal) - 1; ++i) { + // fprintf(stderr, "i: %zu\n", i); gva_edges(graph.observed.str, graph.local_supremal[i], graph.local_supremal[i + 1], i == 0, i == array_length(graph.local_supremal) - 2, @@ -468,31 +486,42 @@ vcf_main(int argc, char* argv[static argc + 1]) { gva_string_destroy(gva_std_allocator, variants[0].sequence); } // if + // TODO: memory accessed here + // fprintf(stderr, "before\n"); + // fprintf(stderr, "%u_%u:%.*s(%zu)\n", local.start, local.end, (int)local.sequence.len, local.sequence.str, local.sequence.len); variants[0] = (GVA_Variant) {local.start, local.end, gva_string_dup(gva_std_allocator, local.sequence)}; + // fprintf(stderr, "after\n"); variants[0] = suffix_trimmed(reference.len, reference.str, variants[0]); + count += 1; + + // TODO: memory freed here + // fprintf(stderr, "string destroy %zu\n", graph.observed.len); gva_string_destroy(gva_std_allocator, graph.observed); gva_lcs_graph_destroy(gva_std_allocator, graph); - count += 1; } // while - GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, variants); - for (size_t i = 0; i < array_length(graph.local_supremal) - 1; ++i) - { - GVA_Variant local; - gva_edges(graph.observed.str, - graph.local_supremal[i], graph.local_supremal[i + 1], - i == 0, i == array_length(graph.local_supremal) - 2, - &local); - printf("%u " GVA_VARIANT_FMT_SPDI "\n", graph.local_supremal[i + 1].distance, GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, local)); - out_count += 1; - } // for + // fprintf(stderr, "count: %zu\n", count); if (count > 0) { + GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, variants); + // fprintf(stderr, "bottom graph distance: %u\n", graph.distance); + + for (size_t i = 0; i < array_length(graph.local_supremal) - 1; ++i) + { + GVA_Variant local; + gva_edges(graph.observed.str, + graph.local_supremal[i], graph.local_supremal[i + 1], + i == 0, i == array_length(graph.local_supremal) - 2, + &local); + printf("%u " GVA_VARIANT_FMT_SPDI "\n", graph.local_supremal[i + 1].distance, GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, local)); + out_count += 1; + } // for gva_string_destroy(gva_std_allocator, variants[0].sequence); + gva_string_destroy(gva_std_allocator, graph.observed); + gva_lcs_graph_destroy(gva_std_allocator, graph); } // if - gva_string_destroy(gva_std_allocator, graph.observed); - gva_lcs_graph_destroy(gva_std_allocator, graph); + fprintf(stderr, "#local supremal parts: %zu\n", out_count); fprintf(stderr, "#dropped variants: %zu\n", drop_count); From 09dc3984a55d0fe61cb403b2934c10d9e40864e8 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Tue, 4 Nov 2025 12:39:03 +0100 Subject: [PATCH 427/704] WIP. --- src/main.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) diff --git a/src/main.c b/src/main.c index a689789..412acc4 100644 --- a/src/main.c +++ b/src/main.c @@ -412,6 +412,66 @@ suffix_trimmed(size_t const len_ref, char const reference[static len_ref], } // suffix_trimmed +int +vcf_main2(int argc, char* argv[static argc + 1]) { + errno = 0; + FILE *stream = fopen(argv[1], "r"); + if (stream == NULL) { + fprintf(stderr, "error: %s\n", strerror(errno)); + return EXIT_FAILURE; + } // if + + GVA_String reference = gva_fasta_sequence_blob(gva_std_allocator, stream); + fclose(stream); + fprintf(stderr, "reference length: %zu\n", reference.len); + + GVA_Variant* variants = NULL; + size_t count = 0; + static char line[LINE_SIZE] = {0}; + + size_t start = 0; + + // read line + while (fgets(line, sizeof(line), stdin) != NULL) { + GVA_Variant variant; + int const len = (char*) memchr(line, '\n', LINE_SIZE) - line; + if (gva_parse_spdi(len, line, &variant) == 0) + { + fprintf(stderr, "error: SPDI parsing failed at line %zu: %s", count + 1, line); + continue; + } // if + fprintf(stderr, "variant: " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(variant)); + + ARRAY_APPEND(gva_std_allocator, variants, prefix_trimmed(reference.len, reference.str, variant)); + + GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, + array_length(variants) - start, variants + start); + size_t const extra = array_length(graph.local_supremal) == 0 ? 0 : array_length(graph.local_supremal) - 2; + variants = array_ensure(gva_std_allocator, variants, sizeof(*variants), extra); + + for (size_t i = 0; i < array_length(graph.local_supremal) - 1; ++i) + { + fprintf(stderr, "loop\n"); + GVA_Variant variant; + gva_edges(graph.observed.str, + graph.local_supremal[i], graph.local_supremal[i + 1], + i == 0, i == array_length(graph.local_supremal) - 2, + &variant); + + fprintf(stderr, "part: " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(variant)); + + variants[start] = (GVA_Variant) {variant.start, variant.end, gva_string_dup(gva_std_allocator, variant.sequence)}; + start += 1; + fprintf(stderr, "end loop\n"); + + } // for + + count += 1; + } + return EXIT_SUCCESS; +} + + int vcf_main(int argc, char* argv[static argc + 1]) { @@ -1185,7 +1245,8 @@ main(int argc, char* argv[static argc + 1]) { // return fasta_blob_read(argc, argv); // return fasta_blob_write(argc, argv); - return vcf_main(argc, argv); + return vcf_main2(argc, argv); + // return vcf_main(argc, argv); // return dbsnp_main(argc, argv); // return locals_main(argc, argv); } // main From c3126da9016836fbddf7623d6d48a7a21515b574 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 4 Nov 2025 16:56:21 +0100 Subject: [PATCH 428/704] WIP: snapshot allele reader --- src/main.c | 138 ++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 109 insertions(+), 29 deletions(-) diff --git a/src/main.c b/src/main.c index 412acc4..2c87086 100644 --- a/src/main.c +++ b/src/main.c @@ -73,7 +73,7 @@ gva_fasta_sequence_blob(GVA_Allocator const allocator, FILE* const stream) fprintf(stderr, "read error: %s\n", strerror(errno)); gva_string_destroy(gva_std_allocator, reference); return reference; - } // + } // if reference.len = length; return reference; @@ -102,7 +102,7 @@ fasta_blob_write(int argc, char* argv[static argc + 1]) if (ret != reference.len) { return EXIT_FAILURE; - } + } // if return EXIT_SUCCESS; } // fasta_blob_write @@ -413,7 +413,8 @@ suffix_trimmed(size_t const len_ref, char const reference[static len_ref], int -vcf_main2(int argc, char* argv[static argc + 1]) { +vcf_main2(int argc, char* argv[static argc + 1]) +{ errno = 0; FILE *stream = fopen(argv[1], "r"); if (stream == NULL) { @@ -426,50 +427,130 @@ vcf_main2(int argc, char* argv[static argc + 1]) { fprintf(stderr, "reference length: %zu\n", reference.len); GVA_Variant* variants = NULL; - size_t count = 0; - static char line[LINE_SIZE] = {0}; - size_t start = 0; - // read line - while (fgets(line, sizeof(line), stdin) != NULL) { + size_t count = 0; + static char line[LINE_SIZE] = {0}; + while (fgets(line, sizeof(line), stdin) != NULL) + { + count += 1; GVA_Variant variant; int const len = (char*) memchr(line, '\n', LINE_SIZE) - line; if (gva_parse_spdi(len, line, &variant) == 0) { - fprintf(stderr, "error: SPDI parsing failed at line %zu: %s", count + 1, line); + fprintf(stderr, "error: SPDI parsing failed at line %zu: %s", count, line); continue; } // if - fprintf(stderr, "variant: " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(variant)); - ARRAY_APPEND(gva_std_allocator, variants, prefix_trimmed(reference.len, reference.str, variant)); + fprintf(stderr, "input: " GVA_VARIANT_FMT " at line %zu\n", GVA_VARIANT_PRINT(variant), count); + + size_t const idx = ARRAY_APPEND(gva_std_allocator, variants, prefix_trimmed(reference.len, reference.str, variant)) - 1; + + fprintf(stderr, "trimmed: " GVA_VARIANT_FMT " @ %zu\n", GVA_VARIANT_PRINT(variants[idx]), idx); + + fprintf(stderr, "from: [%zu, %zu)\n", start, array_length(variants)); GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, array_length(variants) - start, variants + start); - size_t const extra = array_length(graph.local_supremal) == 0 ? 0 : array_length(graph.local_supremal) - 2; - variants = array_ensure(gva_std_allocator, variants, sizeof(*variants), extra); + size_t const length = array_length(graph.local_supremal); - for (size_t i = 0; i < array_length(graph.local_supremal) - 1; ++i) + if (length == 0) { - fprintf(stderr, "loop\n"); - GVA_Variant variant; - gva_edges(graph.observed.str, - graph.local_supremal[i], graph.local_supremal[i + 1], - i == 0, i == array_length(graph.local_supremal) - 2, - &variant); + fprintf(stderr, "Cancelling variants\n"); + array_header(variants)->length = start; + if (start > 0) + { + start -= 1; + } // if + gva_string_destroy(gva_std_allocator, graph.observed); + gva_lcs_graph_destroy(gva_std_allocator, graph); + continue; + } // if - fprintf(stderr, "part: " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(variant)); + if (array_length(variants) - start == 1) + { + fprintf(stderr, "First variant\n"); + for (size_t i = 0; i < length - 1; ++i) + { + gva_edges(graph.observed.str, graph.local_supremal[i], graph.local_supremal[i + 1], i == 0, i == length - 2, &variant); + if (i == 0) + { + variants[start] = (GVA_Variant) {variant.start, variant.end, gva_string_dup(gva_std_allocator, variant.sequence)}; + } // if + else + { + ARRAY_APPEND(gva_std_allocator, variants, ((GVA_Variant) {variant.start, variant.end, gva_string_dup(gva_std_allocator, variant.sequence)})); + } // else + } // for + start += length - 2; + gva_string_destroy(gva_std_allocator, graph.observed); + gva_lcs_graph_destroy(gva_std_allocator, graph); + continue; + } // if + + gva_edges(graph.observed.str, graph.local_supremal[0], graph.local_supremal[1], true, 1 == length - 2, &variant); + if (gva_variant_eq(variants[start], variant)) + { + fprintf(stderr, "Nicely separated\n"); + for (size_t i = 1; i < length - 1; ++i) + { + gva_edges(graph.observed.str, graph.local_supremal[i], graph.local_supremal[i + 1], false, i == length - 2, &variant); + if (i == 1) + { + variants[start + 1] = (GVA_Variant) {variant.start, variant.end, gva_string_dup(gva_std_allocator, variant.sequence)}; + } // if + else + { + ARRAY_APPEND(gva_std_allocator, variants, ((GVA_Variant) {variant.start, variant.end, gva_string_dup(gva_std_allocator, variant.sequence)})); + } // else + } // for + start += length - 2; + gva_string_destroy(gva_std_allocator, graph.observed); + gva_lcs_graph_destroy(gva_std_allocator, graph); + continue; + } // if + fprintf(stderr, "Difficult\n"); + fprintf(stderr, " " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(variant)); + while (start > 0) + { + gva_string_destroy(gva_std_allocator, variants[start].sequence); variants[start] = (GVA_Variant) {variant.start, variant.end, gva_string_dup(gva_std_allocator, variant.sequence)}; - start += 1; - fprintf(stderr, "end loop\n"); + start -= 1; + array_header(variants)->length -= 1; + gva_string_destroy(gva_std_allocator, graph.observed); + gva_lcs_graph_destroy(gva_std_allocator, graph); + + fprintf(stderr, "from: [%zu, %zu)\n", start, array_length(variants)); + graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, array_length(variants) - start, variants + start); + + gva_edges(graph.observed.str, graph.local_supremal[0], graph.local_supremal[1], true, 1 == length - 2, &variant); + if (gva_variant_eq(variants[start], variant)) + { + gva_string_destroy(gva_std_allocator, graph.observed); + gva_lcs_graph_destroy(gva_std_allocator, graph); + break; + } // if + } // while + start += 1; + } // while + + if (variants != NULL) + { + fprintf(stderr, "======\nlength: %zu\n", array_length(variants)); + for (size_t i = 0; i < array_length(variants); ++i) + { + fprintf(stderr, "%3zu: " GVA_VARIANT_FMT "\n", i, GVA_VARIANT_PRINT(variants[i])); + gva_string_destroy(gva_std_allocator, variants[i].sequence); } // for + variants = ARRAY_DESTROY(gva_std_allocator, variants); + } // if + + gva_string_destroy(gva_std_allocator, reference); - count += 1; - } return EXIT_SUCCESS; -} +} // vcf_main2 int @@ -526,7 +607,7 @@ vcf_main(int argc, char* argv[static argc + 1]) gva_string_destroy(gva_std_allocator, graph.observed); gva_lcs_graph_destroy(gva_std_allocator, graph); continue; - } + } // if GVA_Variant local; for (size_t i = 0; i < array_length(graph.local_supremal) - 1; ++i) @@ -582,7 +663,6 @@ vcf_main(int argc, char* argv[static argc + 1]) gva_lcs_graph_destroy(gva_std_allocator, graph); } // if - fprintf(stderr, "#local supremal parts: %zu\n", out_count); fprintf(stderr, "#dropped variants: %zu\n", drop_count); @@ -615,7 +695,7 @@ repair_is_contained(GVA_Allocator const allocator, GVA_String const reference, G } // else } // if *nodes = ARRAY_DESTROY(gva_std_allocator, *nodes); -} +} // repair_is_contained int From 0549ab9aedb91ec83241d590d1b1ff803e38d508 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 11 Nov 2025 11:39:26 +0100 Subject: [PATCH 429/704] WIP: allele reader --- include/variant.h | 4 ++ src/main.c | 115 ++++++++++++++++------------------------------ src/variant.c | 9 +++- 3 files changed, 52 insertions(+), 76 deletions(-) diff --git a/include/variant.h b/include/variant.h index bb58887..1f7d78e 100644 --- a/include/variant.h +++ b/include/variant.h @@ -34,6 +34,10 @@ bool gva_variant_eq(GVA_Variant const lhs, GVA_Variant const rhs); +GVA_Variant +gva_variant_dup(GVA_Allocator const allocator, GVA_Variant const variant); + + size_t gva_variant_length(GVA_Variant const variant); diff --git a/src/main.c b/src/main.c index 2c87086..8d7b6ee 100644 --- a/src/main.c +++ b/src/main.c @@ -427,118 +427,83 @@ vcf_main2(int argc, char* argv[static argc + 1]) fprintf(stderr, "reference length: %zu\n", reference.len); GVA_Variant* variants = NULL; - size_t start = 0; size_t count = 0; static char line[LINE_SIZE] = {0}; while (fgets(line, sizeof(line), stdin) != NULL) { - count += 1; GVA_Variant variant; - int const len = (char*) memchr(line, '\n', LINE_SIZE) - line; - if (gva_parse_spdi(len, line, &variant) == 0) + if (gva_parse_spdi(strlen(line) - 1, line, &variant) == 0) { - fprintf(stderr, "error: SPDI parsing failed at line %zu: %s", count, line); + fprintf(stderr, "error: SPDI parsing failed at line %zu: %s", count + 1, line); continue; } // if + count += 1; fprintf(stderr, "input: " GVA_VARIANT_FMT " at line %zu\n", GVA_VARIANT_PRINT(variant), count); + variant = prefix_trimmed(reference.len, reference.str, variant); + size_t const idx = ARRAY_APPEND(gva_std_allocator, variants, variant) - 1; + fprintf(stderr, "trimmed: " GVA_VARIANT_FMT " @ %zu\n", GVA_VARIANT_PRINT(variant), idx); - size_t const idx = ARRAY_APPEND(gva_std_allocator, variants, prefix_trimmed(reference.len, reference.str, variant)) - 1; - - fprintf(stderr, "trimmed: " GVA_VARIANT_FMT " @ %zu\n", GVA_VARIANT_PRINT(variants[idx]), idx); + size_t start = 0; + if (array_length(variants) > 1) + { + start = array_length(variants) - 2; + variant = variants[start]; + variants[start] = suffix_trimmed(reference.len, reference.str, variants[start]); + fprintf(stderr, "last part: " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(variant)); + fprintf(stderr, "suffix trimmed: " GVA_VARIANT_FMT " @ %zu\n", GVA_VARIANT_PRINT(variants[start]), start); + } // if - fprintf(stderr, "from: [%zu, %zu)\n", start, array_length(variants)); + fprintf(stderr, "[%zu, %zu)\n", start, array_length(variants)); - GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, - array_length(variants) - start, variants + start); - size_t const length = array_length(graph.local_supremal); + GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, array_length(variants) - start, variants + start); + size_t const length = array_length(graph.local_supremal) - 1; + fprintf(stderr, "#local supremal parts: %zu\n", length); if (length == 0) { - fprintf(stderr, "Cancelling variants\n"); - array_header(variants)->length = start; - if (start > 0) - { - start -= 1; - } // if + fprintf(stderr, "Cancelling and NIL-variants\n"); + array_header(variants)->length -= 1; gva_string_destroy(gva_std_allocator, graph.observed); gva_lcs_graph_destroy(gva_std_allocator, graph); continue; } // if - if (array_length(variants) - start == 1) + variants[start] = variant; + fprintf(stderr, "restore: " GVA_VARIANT_FMT " @ %zu\n", GVA_VARIANT_PRINT(variants[start]), start); + + gva_edges(graph.observed.str, + graph.local_supremal[0], graph.local_supremal[1], + true, 1 == length - 1, &variant); + + if (array_length(variants) == 1) { fprintf(stderr, "First variant\n"); - for (size_t i = 0; i < length - 1; ++i) + variants[0] = gva_variant_dup(gva_std_allocator, variant); + fprintf(stderr, "store: " GVA_VARIANT_FMT " @ %zu\n", GVA_VARIANT_PRINT(variants[0]), 0UL); + for (size_t i = 1; i < length; ++i) { - gva_edges(graph.observed.str, graph.local_supremal[i], graph.local_supremal[i + 1], i == 0, i == length - 2, &variant); - if (i == 0) - { - variants[start] = (GVA_Variant) {variant.start, variant.end, gva_string_dup(gva_std_allocator, variant.sequence)}; - } // if - else - { - ARRAY_APPEND(gva_std_allocator, variants, ((GVA_Variant) {variant.start, variant.end, gva_string_dup(gva_std_allocator, variant.sequence)})); - } // else + gva_edges(graph.observed.str, + graph.local_supremal[i], graph.local_supremal[i + 1], + false, i == length - 1, &variant); + size_t const idx = ARRAY_APPEND(gva_std_allocator, variants, gva_variant_dup(gva_std_allocator, variant)) - 1; + fprintf(stderr, "add: " GVA_VARIANT_FMT " @ %zu\n", GVA_VARIANT_PRINT(variant), idx); } // for - start += length - 2; - gva_string_destroy(gva_std_allocator, graph.observed); - gva_lcs_graph_destroy(gva_std_allocator, graph); - continue; } // if - gva_edges(graph.observed.str, graph.local_supremal[0], graph.local_supremal[1], true, 1 == length - 2, &variant); if (gva_variant_eq(variants[start], variant)) { fprintf(stderr, "Nicely separated\n"); - for (size_t i = 1; i < length - 1; ++i) - { - gva_edges(graph.observed.str, graph.local_supremal[i], graph.local_supremal[i + 1], false, i == length - 2, &variant); - if (i == 1) - { - variants[start + 1] = (GVA_Variant) {variant.start, variant.end, gva_string_dup(gva_std_allocator, variant.sequence)}; - } // if - else - { - ARRAY_APPEND(gva_std_allocator, variants, ((GVA_Variant) {variant.start, variant.end, gva_string_dup(gva_std_allocator, variant.sequence)})); - } // else - } // for - start += length - 2; - gva_string_destroy(gva_std_allocator, graph.observed); - gva_lcs_graph_destroy(gva_std_allocator, graph); - continue; } // if - fprintf(stderr, "Difficult\n"); - fprintf(stderr, " " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(variant)); - while (start > 0) - { - gva_string_destroy(gva_std_allocator, variants[start].sequence); - variants[start] = (GVA_Variant) {variant.start, variant.end, gva_string_dup(gva_std_allocator, variant.sequence)}; - start -= 1; - array_header(variants)->length -= 1; - - gva_string_destroy(gva_std_allocator, graph.observed); - gva_lcs_graph_destroy(gva_std_allocator, graph); - - fprintf(stderr, "from: [%zu, %zu)\n", start, array_length(variants)); - graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, array_length(variants) - start, variants + start); - - gva_edges(graph.observed.str, graph.local_supremal[0], graph.local_supremal[1], true, 1 == length - 2, &variant); - if (gva_variant_eq(variants[start], variant)) - { - gva_string_destroy(gva_std_allocator, graph.observed); - gva_lcs_graph_destroy(gva_std_allocator, graph); - break; - } // if - } // while - start += 1; + gva_string_destroy(gva_std_allocator, graph.observed); + gva_lcs_graph_destroy(gva_std_allocator, graph); } // while if (variants != NULL) { - fprintf(stderr, "======\nlength: %zu\n", array_length(variants)); + fprintf(stderr, "=======\n"); for (size_t i = 0; i < array_length(variants); ++i) { fprintf(stderr, "%3zu: " GVA_VARIANT_FMT "\n", i, GVA_VARIANT_PRINT(variants[i])); diff --git a/src/variant.c b/src/variant.c index e180121..c9894b2 100644 --- a/src/variant.c +++ b/src/variant.c @@ -4,7 +4,7 @@ #include "../include/allocator.h" // GVA_Allocator #include "../include/types.h" // gva_uint -#include "../include/string.h" // GVA_String, gva_string_concat +#include "../include/string.h" // GVA_String, gva_string_* #include "../include/variant.h" // gva_parse_spdi, gva_patch #include "common.h" // MIN @@ -120,6 +120,13 @@ gva_variant_eq(GVA_Variant const lhs, GVA_Variant const rhs) } // gva_variant_eq +inline GVA_Variant +gva_variant_dup(GVA_Allocator const allocator, GVA_Variant const variant) +{ + return (GVA_Variant) {variant.start, variant.end, gva_string_dup(allocator, variant.sequence)}; +} // gva_variant_dup + + inline size_t gva_variant_length(GVA_Variant const variant) { From abdb9366c7bff3396512702fcf6b4253257b7bf9 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Tue, 11 Nov 2025 15:56:36 +0100 Subject: [PATCH 430/704] WIP. --- src/main.c | 65 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 38 insertions(+), 27 deletions(-) diff --git a/src/main.c b/src/main.c index 8d7b6ee..5190b15 100644 --- a/src/main.c +++ b/src/main.c @@ -430,11 +430,9 @@ vcf_main2(int argc, char* argv[static argc + 1]) size_t count = 0; static char line[LINE_SIZE] = {0}; - while (fgets(line, sizeof(line), stdin) != NULL) - { + while (fgets(line, sizeof(line), stdin) != NULL) { GVA_Variant variant; - if (gva_parse_spdi(strlen(line) - 1, line, &variant) == 0) - { + if (gva_parse_spdi(strlen(line) - 1, line, &variant) == 0) { fprintf(stderr, "error: SPDI parsing failed at line %zu: %s", count + 1, line); continue; } // if @@ -446,8 +444,7 @@ vcf_main2(int argc, char* argv[static argc + 1]) fprintf(stderr, "trimmed: " GVA_VARIANT_FMT " @ %zu\n", GVA_VARIANT_PRINT(variant), idx); size_t start = 0; - if (array_length(variants) > 1) - { + if (array_length(variants) > 1) { start = array_length(variants) - 2; variant = variants[start]; variants[start] = suffix_trimmed(reference.len, reference.str, variants[start]); @@ -457,45 +454,59 @@ vcf_main2(int argc, char* argv[static argc + 1]) fprintf(stderr, "[%zu, %zu)\n", start, array_length(variants)); - GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, array_length(variants) - start, variants + start); + GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, + array_length(variants) - start, variants + start); size_t const length = array_length(graph.local_supremal) - 1; fprintf(stderr, "#local supremal parts: %zu\n", length); - if (length == 0) - { + if (length == 0) { fprintf(stderr, "Cancelling and NIL-variants\n"); + // TODO: 1 or 2 array_header(variants)->length -= 1; gva_string_destroy(gva_std_allocator, graph.observed); gva_lcs_graph_destroy(gva_std_allocator, graph); continue; } // if - variants[start] = variant; - fprintf(stderr, "restore: " GVA_VARIANT_FMT " @ %zu\n", GVA_VARIANT_PRINT(variants[start]), start); + // if (array_length(variants) > 1) + // { + // variants[start] = variant; + // fprintf(stderr, "restore: " GVA_VARIANT_FMT " @ %zu\n", GVA_VARIANT_PRINT(variants[start]), start); + // } gva_edges(graph.observed.str, graph.local_supremal[0], graph.local_supremal[1], true, 1 == length - 1, &variant); - if (array_length(variants) == 1) + while (start > 0 && !gva_variant_eq(variants[start], variant)) { - fprintf(stderr, "First variant\n"); - variants[0] = gva_variant_dup(gva_std_allocator, variant); - fprintf(stderr, "store: " GVA_VARIANT_FMT " @ %zu\n", GVA_VARIANT_PRINT(variants[0]), 0UL); - for (size_t i = 1; i < length; ++i) - { - gva_edges(graph.observed.str, - graph.local_supremal[i], graph.local_supremal[i + 1], - false, i == length - 1, &variant); - size_t const idx = ARRAY_APPEND(gva_std_allocator, variants, gva_variant_dup(gva_std_allocator, variant)) - 1; - fprintf(stderr, "add: " GVA_VARIANT_FMT " @ %zu\n", GVA_VARIANT_PRINT(variant), idx); - } // for - } // if + fprintf(stderr, "inside while loop\n"); + start -= 1; + gva_string_destroy(gva_std_allocator, graph.observed); + gva_lcs_graph_destroy(gva_std_allocator, graph); - if (gva_variant_eq(variants[start], variant)) + graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, array_length(variants) - start, variants + start); + size_t const length = array_length(graph.local_supremal) - 1; + gva_edges(graph.observed.str, + graph.local_supremal[0], graph.local_supremal[1], + true, 1 == length - 1, &variant); + } // while + fprintf(stderr, "Start after while loop: %zu\n", start); + for (size_t i = 0; i < array_length(graph.local_supremal) - 1; ++i) { - fprintf(stderr, "Nicely separated\n"); - } // if + gva_edges(graph.observed.str, + graph.local_supremal[i], graph.local_supremal[i + 1], + i == 0, i == length - 2, &variant); + if (start + i < array_length(variants)) + { + variants[start + i] = gva_variant_dup(gva_std_allocator, variant); + } // if + else + { + ARRAY_APPEND(gva_std_allocator, variants, gva_variant_dup(gva_std_allocator, variant)); + } // else + } // for + gva_string_destroy(gva_std_allocator, graph.observed); gva_lcs_graph_destroy(gva_std_allocator, graph); From 3dab416db0a788aa52759c6bd5684dc7e149a58f Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 12 Nov 2025 16:03:38 +0100 Subject: [PATCH 431/704] Cutoff based allele reader --- src/main.c | 112 +++++++++++++++++++++++------------------------------ 1 file changed, 48 insertions(+), 64 deletions(-) diff --git a/src/main.c b/src/main.c index 5190b15..786754d 100644 --- a/src/main.c +++ b/src/main.c @@ -415,9 +415,16 @@ suffix_trimmed(size_t const len_ref, char const reference[static len_ref], int vcf_main2(int argc, char* argv[static argc + 1]) { + if (argc < 3) + { + fprintf(stderr, "usage: %s reference.blob cutoff\n", argv[0]); + return EXIT_FAILURE; + } // if + errno = 0; FILE *stream = fopen(argv[1], "r"); - if (stream == NULL) { + if (stream == NULL) + { fprintf(stderr, "error: %s\n", strerror(errno)); return EXIT_FAILURE; } // if @@ -426,7 +433,11 @@ vcf_main2(int argc, char* argv[static argc + 1]) fclose(stream); fprintf(stderr, "reference length: %zu\n", reference.len); + size_t const cutoff = atoll(argv[2]); + fprintf(stderr, "cutoff: %zu\n", cutoff); + GVA_Variant* variants = NULL; + GVA_Variant last = {0, 0, {0, NULL}}; size_t count = 0; static char line[LINE_SIZE] = {0}; @@ -438,89 +449,62 @@ vcf_main2(int argc, char* argv[static argc + 1]) } // if count += 1; - fprintf(stderr, "input: " GVA_VARIANT_FMT " at line %zu\n", GVA_VARIANT_PRINT(variant), count); - variant = prefix_trimmed(reference.len, reference.str, variant); - size_t const idx = ARRAY_APPEND(gva_std_allocator, variants, variant) - 1; - fprintf(stderr, "trimmed: " GVA_VARIANT_FMT " @ %zu\n", GVA_VARIANT_PRINT(variant), idx); - - size_t start = 0; - if (array_length(variants) > 1) { - start = array_length(variants) - 2; - variant = variants[start]; - variants[start] = suffix_trimmed(reference.len, reference.str, variants[start]); - fprintf(stderr, "last part: " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(variant)); - fprintf(stderr, "suffix trimmed: " GVA_VARIANT_FMT " @ %zu\n", GVA_VARIANT_PRINT(variants[start]), start); + if (prefix_trimmed(reference.len, reference.str, variant).start < last.end) + { + fprintf(stderr, "dropped: " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(variant)); + continue; } // if - fprintf(stderr, "[%zu, %zu)\n", start, array_length(variants)); + if (variants != NULL && variant.start - last.end > cutoff) + { + GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, array_length(variants), variants); + + for (size_t i = 0; i < array_length(graph.local_supremal) - 1; ++i) + { + GVA_Variant part; + gva_edges(graph.observed.str, + graph.local_supremal[i], graph.local_supremal[i + 1], + i == 0, i == array_length(graph.local_supremal) - 2, &part); + fprintf(stdout, GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(part)); + } // for + + for (size_t i = 0; i < array_length(variants); ++i) + { + gva_string_destroy(gva_std_allocator, variants[i].sequence); + } // for - GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, - array_length(variants) - start, variants + start); - size_t const length = array_length(graph.local_supremal) - 1; - fprintf(stderr, "#local supremal parts: %zu\n", length); + variants = ARRAY_DESTROY(gva_std_allocator, variants); - if (length == 0) { - fprintf(stderr, "Cancelling and NIL-variants\n"); - // TODO: 1 or 2 - array_header(variants)->length -= 1; gva_string_destroy(gva_std_allocator, graph.observed); gva_lcs_graph_destroy(gva_std_allocator, graph); - continue; } // if - // if (array_length(variants) > 1) - // { - // variants[start] = variant; - // fprintf(stderr, "restore: " GVA_VARIANT_FMT " @ %zu\n", GVA_VARIANT_PRINT(variants[start]), start); - // } - - gva_edges(graph.observed.str, - graph.local_supremal[0], graph.local_supremal[1], - true, 1 == length - 1, &variant); + ARRAY_APPEND(gva_std_allocator, variants, gva_variant_dup(gva_std_allocator, prefix_trimmed(reference.len, reference.str, variant))); + last = variants[array_length(variants) - 1]; + } // while - while (start > 0 && !gva_variant_eq(variants[start], variant)) - { - fprintf(stderr, "inside while loop\n"); - start -= 1; - gva_string_destroy(gva_std_allocator, graph.observed); - gva_lcs_graph_destroy(gva_std_allocator, graph); + if (variants != NULL) + { + GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, array_length(variants), variants); - graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, array_length(variants) - start, variants + start); - size_t const length = array_length(graph.local_supremal) - 1; - gva_edges(graph.observed.str, - graph.local_supremal[0], graph.local_supremal[1], - true, 1 == length - 1, &variant); - } // while - fprintf(stderr, "Start after while loop: %zu\n", start); for (size_t i = 0; i < array_length(graph.local_supremal) - 1; ++i) { + GVA_Variant part; gva_edges(graph.observed.str, - graph.local_supremal[i], graph.local_supremal[i + 1], - i == 0, i == length - 2, &variant); - if (start + i < array_length(variants)) - { - variants[start + i] = gva_variant_dup(gva_std_allocator, variant); - } // if - else - { - ARRAY_APPEND(gva_std_allocator, variants, gva_variant_dup(gva_std_allocator, variant)); - } // else + graph.local_supremal[i], graph.local_supremal[i + 1], + i == 0, i == array_length(graph.local_supremal) - 2, &part); + fprintf(stdout, GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(part)); } // for - - gva_string_destroy(gva_std_allocator, graph.observed); - gva_lcs_graph_destroy(gva_std_allocator, graph); - } // while - - if (variants != NULL) - { - fprintf(stderr, "=======\n"); for (size_t i = 0; i < array_length(variants); ++i) { - fprintf(stderr, "%3zu: " GVA_VARIANT_FMT "\n", i, GVA_VARIANT_PRINT(variants[i])); gva_string_destroy(gva_std_allocator, variants[i].sequence); } // for + variants = ARRAY_DESTROY(gva_std_allocator, variants); + + gva_string_destroy(gva_std_allocator, graph.observed); + gva_lcs_graph_destroy(gva_std_allocator, graph); } // if gva_string_destroy(gva_std_allocator, reference); From 60ec18fbc7926a62a79a7e94332fcd8e3f57f8d7 Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 12 Nov 2025 17:03:40 +0100 Subject: [PATCH 432/704] SPDI output --- src/main.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/main.c b/src/main.c index 786754d..1614905 100644 --- a/src/main.c +++ b/src/main.c @@ -440,6 +440,8 @@ vcf_main2(int argc, char* argv[static argc + 1]) GVA_Variant last = {0, 0, {0, NULL}}; size_t count = 0; + size_t dropped = 0; + size_t created = 0; static char line[LINE_SIZE] = {0}; while (fgets(line, sizeof(line), stdin) != NULL) { GVA_Variant variant; @@ -451,7 +453,8 @@ vcf_main2(int argc, char* argv[static argc + 1]) if (prefix_trimmed(reference.len, reference.str, variant).start < last.end) { - fprintf(stderr, "dropped: " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(variant)); + fprintf(stderr, "dropped: " GVA_VARIANT_FMT_SPDI "\n", GVA_VARIANT_PRINT_SPDI("NC_000001.11", variant)); + dropped += 1; continue; } // if @@ -461,11 +464,12 @@ vcf_main2(int argc, char* argv[static argc + 1]) for (size_t i = 0; i < array_length(graph.local_supremal) - 1; ++i) { - GVA_Variant part; + GVA_Variant variant; gva_edges(graph.observed.str, graph.local_supremal[i], graph.local_supremal[i + 1], - i == 0, i == array_length(graph.local_supremal) - 2, &part); - fprintf(stdout, GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(part)); + i == 0, i == array_length(graph.local_supremal) - 2, &variant); + fprintf(stdout, GVA_VARIANT_FMT_SPDI "\n", GVA_VARIANT_PRINT_SPDI("NC_000001.11", variant)); + created += 1; } // for for (size_t i = 0; i < array_length(variants); ++i) @@ -489,11 +493,11 @@ vcf_main2(int argc, char* argv[static argc + 1]) for (size_t i = 0; i < array_length(graph.local_supremal) - 1; ++i) { - GVA_Variant part; + GVA_Variant variant; gva_edges(graph.observed.str, graph.local_supremal[i], graph.local_supremal[i + 1], - i == 0, i == array_length(graph.local_supremal) - 2, &part); - fprintf(stdout, GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(part)); + i == 0, i == array_length(graph.local_supremal) - 2, &variant); + fprintf(stdout, GVA_VARIANT_FMT_SPDI "\n", GVA_VARIANT_PRINT_SPDI("NC_000001.11", variant)); } // for for (size_t i = 0; i < array_length(variants); ++i) @@ -507,6 +511,10 @@ vcf_main2(int argc, char* argv[static argc + 1]) gva_lcs_graph_destroy(gva_std_allocator, graph); } // if + fprintf(stderr, "count: %zu\n", count); + fprintf(stderr, "dropped: %zu\n", dropped); + fprintf(stderr, "created: %zu\n", created); + gva_string_destroy(gva_std_allocator, reference); return EXIT_SUCCESS; From 5aca2de6aa55173e6786cb18bf5d251af708ff06 Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 12 Nov 2025 17:07:03 +0100 Subject: [PATCH 433/704] SPDI and distance output --- src/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.c b/src/main.c index 1614905..fd64e83 100644 --- a/src/main.c +++ b/src/main.c @@ -468,7 +468,7 @@ vcf_main2(int argc, char* argv[static argc + 1]) gva_edges(graph.observed.str, graph.local_supremal[i], graph.local_supremal[i + 1], i == 0, i == array_length(graph.local_supremal) - 2, &variant); - fprintf(stdout, GVA_VARIANT_FMT_SPDI "\n", GVA_VARIANT_PRINT_SPDI("NC_000001.11", variant)); + fprintf(stdout, GVA_VARIANT_FMT_SPDI "\t%u\n", GVA_VARIANT_PRINT_SPDI("NC_000001.11", variant), graph.local_supremal[i + 1].distance); created += 1; } // for @@ -497,7 +497,7 @@ vcf_main2(int argc, char* argv[static argc + 1]) gva_edges(graph.observed.str, graph.local_supremal[i], graph.local_supremal[i + 1], i == 0, i == array_length(graph.local_supremal) - 2, &variant); - fprintf(stdout, GVA_VARIANT_FMT_SPDI "\n", GVA_VARIANT_PRINT_SPDI("NC_000001.11", variant)); + fprintf(stdout, GVA_VARIANT_FMT_SPDI "\t%u\n", GVA_VARIANT_PRINT_SPDI("NC_000001.11", variant), graph.local_supremal[i + 1].distance); } // for for (size_t i = 0; i < array_length(variants); ++i) From 15142c174da0f2dcdc3a65909632ba0da3dcf806 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Wed, 19 Nov 2025 11:23:32 +0100 Subject: [PATCH 434/704] Also count after the main loop. --- src/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main.c b/src/main.c index fd64e83..8b850d4 100644 --- a/src/main.c +++ b/src/main.c @@ -498,6 +498,7 @@ vcf_main2(int argc, char* argv[static argc + 1]) graph.local_supremal[i], graph.local_supremal[i + 1], i == 0, i == array_length(graph.local_supremal) - 2, &variant); fprintf(stdout, GVA_VARIANT_FMT_SPDI "\t%u\n", GVA_VARIANT_PRINT_SPDI("NC_000001.11", variant), graph.local_supremal[i + 1].distance); + created += 1; } // for for (size_t i = 0; i < array_length(variants); ++i) From 1b244f8600bced69a75d31358f234a9916f4fefb Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Fri, 21 Nov 2025 17:35:36 +0100 Subject: [PATCH 435/704] Reorder and space. --- src/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.c b/src/main.c index 8b850d4..68aaea8 100644 --- a/src/main.c +++ b/src/main.c @@ -468,7 +468,7 @@ vcf_main2(int argc, char* argv[static argc + 1]) gva_edges(graph.observed.str, graph.local_supremal[i], graph.local_supremal[i + 1], i == 0, i == array_length(graph.local_supremal) - 2, &variant); - fprintf(stdout, GVA_VARIANT_FMT_SPDI "\t%u\n", GVA_VARIANT_PRINT_SPDI("NC_000001.11", variant), graph.local_supremal[i + 1].distance); + fprintf(stdout, "%u " GVA_VARIANT_FMT_SPDI "\n", graph.local_supremal[i + 1].distance, GVA_VARIANT_PRINT_SPDI("NC_000001.11", variant)); created += 1; } // for @@ -497,7 +497,7 @@ vcf_main2(int argc, char* argv[static argc + 1]) gva_edges(graph.observed.str, graph.local_supremal[i], graph.local_supremal[i + 1], i == 0, i == array_length(graph.local_supremal) - 2, &variant); - fprintf(stdout, GVA_VARIANT_FMT_SPDI "\t%u\n", GVA_VARIANT_PRINT_SPDI("NC_000001.11", variant), graph.local_supremal[i + 1].distance); + fprintf(stdout, "%u " GVA_VARIANT_FMT_SPDI "\n", graph.local_supremal[i + 1].distance, GVA_VARIANT_PRINT_SPDI("NC_000001.11", variant)); created += 1; } // for From 41e23f2af99a06791359bd04d967aa31ec5659eb Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 2 Dec 2025 11:26:46 +0100 Subject: [PATCH 436/704] Read original allele --- src/main.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 59 insertions(+), 2 deletions(-) diff --git a/src/main.c b/src/main.c index 8b850d4..7c3ed4d 100644 --- a/src/main.c +++ b/src/main.c @@ -412,6 +412,62 @@ suffix_trimmed(size_t const len_ref, char const reference[static len_ref], } // suffix_trimmed +int wu_main(int argc, char* argv[static argc + 1]) +{ + if (argc < 2) + { + fprintf(stderr, "usage: %s reference.blob\n", argv[0]); + return EXIT_FAILURE; + } // if + + errno = 0; + FILE *stream = fopen(argv[1], "r"); + if (stream == NULL) + { + fprintf(stderr, "error: %s\n", strerror(errno)); + return EXIT_FAILURE; + } // if + + GVA_String reference = gva_fasta_sequence_blob(gva_std_allocator, stream); + fclose(stream); + fprintf(stderr, "reference length: %zu\n", reference.len); + + GVA_Variant* variants = NULL; + + size_t line_count = 0; + static char line[LINE_SIZE] = {0}; + while (fgets(line, sizeof(line), stdin) != NULL) + { + //size_t idx = 0; + //size_t const distance = parse_number(line, &idx); + //idx += 1; // skip space or tab + //int const len = (char*) memchr(line + idx, '\n', LINE_SIZE - idx) - (line + idx); + size_t const len = strlen(line) - 1; + GVA_Variant variant; + if (gva_parse_spdi(len, line, &variant) == 0) + { + fprintf(stderr, "error: SPDI parsing failed at line %zu: %s", line_count + 1, line); + continue; + } // if + + ARRAY_APPEND(gva_std_allocator, variants, gva_variant_dup(gva_std_allocator, prefix_trimmed(reference.len, reference.str, variant))); + line_count += 1; + } // while + + fprintf(stderr, "#parts: %zu\n", array_length(variants)); + + GVA_String observed = gva_patch(gva_std_allocator, reference.len, reference.str, array_length(variants), variants); + + fprintf(stderr, "observed length: %zu\n", observed.len); + + size_t const distance = gva_edit_distance(gva_std_allocator, reference.len, reference.str, observed.len, observed.str); + + fprintf(stderr, "distance: %zu\n", distance); + + return EXIT_SUCCESS; +} // wu_main + + int vcf_main2(int argc, char* argv[static argc + 1]) { @@ -451,7 +507,7 @@ vcf_main2(int argc, char* argv[static argc + 1]) } // if count += 1; - if (prefix_trimmed(reference.len, reference.str, variant).start < last.end) + if (variant.start < last.end) { fprintf(stderr, "dropped: " GVA_VARIANT_FMT_SPDI "\n", GVA_VARIANT_PRINT_SPDI("NC_000001.11", variant)); dropped += 1; @@ -1294,7 +1350,8 @@ main(int argc, char* argv[static argc + 1]) { // return fasta_blob_read(argc, argv); // return fasta_blob_write(argc, argv); - return vcf_main2(argc, argv); + // return vcf_main2(argc, argv); + return wu_main(argc, argv); // return vcf_main(argc, argv); // return dbsnp_main(argc, argv); // return locals_main(argc, argv); From 2591aaad26020eff27058ff96e29a924262240ea Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 2 Dec 2025 14:42:13 +0100 Subject: [PATCH 437/704] Gap-based local supremal guessing --- src/main.c | 258 ++++++++++++----------------------------------------- 1 file changed, 58 insertions(+), 200 deletions(-) diff --git a/src/main.c b/src/main.c index 085f106..bf03b17 100644 --- a/src/main.c +++ b/src/main.c @@ -412,11 +412,11 @@ suffix_trimmed(size_t const len_ref, char const reference[static len_ref], } // suffix_trimmed -int wu_main(int argc, char* argv[static argc + 1]) +int vcf_main(int argc, char* argv[static argc + 1]) { - if (argc < 2) + if (argc < 3) { - fprintf(stderr, "usage: %s reference.blob\n", argv[0]); + fprintf(stderr, "usage: %s reference.blob gap\n", argv[0]); return EXIT_FAILURE; } // if @@ -432,9 +432,16 @@ int wu_main(int argc, char* argv[static argc + 1]) fclose(stream); fprintf(stderr, "reference length: %zu\n", reference.len); + size_t const gap = atoll(argv[2]); + fprintf(stderr, "gap: %zu\n", gap); + GVA_Variant* variants = NULL; + GVA_Variant* lss = NULL; + size_t last = 0; size_t line_count = 0; + size_t dropped = 0; + size_t distance = 0; static char line[LINE_SIZE] = {0}; while (fgets(line, sizeof(line), stdin) != NULL) { @@ -450,73 +457,19 @@ int wu_main(int argc, char* argv[static argc + 1]) continue; } // if - ARRAY_APPEND(gva_std_allocator, variants, gva_variant_dup(gva_std_allocator, prefix_trimmed(reference.len, reference.str, variant))); - line_count += 1; - } // while - - fprintf(stderr, "#parts: %zu\n", array_length(variants)); - - GVA_String observed = gva_patch(gva_std_allocator, reference.len, reference.str, array_length(variants), variants); - - fprintf(stderr, "observed length: %zu\n", observed.len); - - size_t const distance = gva_edit_distance(gva_std_allocator, reference.len, reference.str, observed.len, observed.str); - - fprintf(stderr, "distance: %zu\n", distance); - - return EXIT_SUCCESS; -} // wu_main - - -int -vcf_main2(int argc, char* argv[static argc + 1]) -{ - if (argc < 3) - { - fprintf(stderr, "usage: %s reference.blob cutoff\n", argv[0]); - return EXIT_FAILURE; - } // if - - errno = 0; - FILE *stream = fopen(argv[1], "r"); - if (stream == NULL) - { - fprintf(stderr, "error: %s\n", strerror(errno)); - return EXIT_FAILURE; - } // if + GVA_Variant trimmed = prefix_trimmed(reference.len, reference.str, variant); - GVA_String reference = gva_fasta_sequence_blob(gva_std_allocator, stream); - fclose(stream); - fprintf(stderr, "reference length: %zu\n", reference.len); - - size_t const cutoff = atoll(argv[2]); - fprintf(stderr, "cutoff: %zu\n", cutoff); - - GVA_Variant* variants = NULL; - GVA_Variant last = {0, 0, {0, NULL}}; - - size_t count = 0; - size_t dropped = 0; - size_t created = 0; - static char line[LINE_SIZE] = {0}; - while (fgets(line, sizeof(line), stdin) != NULL) { - GVA_Variant variant; - if (gva_parse_spdi(strlen(line) - 1, line, &variant) == 0) { - fprintf(stderr, "error: SPDI parsing failed at line %zu: %s", count + 1, line); - continue; - } // if - count += 1; - - if (variant.start < last.end) + if (array_length(variants) > 0 && trimmed.start < variants[array_length(variants) - 1].end) { - fprintf(stderr, "dropped: " GVA_VARIANT_FMT_SPDI "\n", GVA_VARIANT_PRINT_SPDI("NC_000001.11", variant)); + //fprintf(stderr, "dropped: at line %zu: %s", line_count + 1, line); dropped += 1; continue; } // if - if (variants != NULL && variant.start - last.end > cutoff) + if (array_length(variants) > 0 && trimmed.start - variants[array_length(variants) - 1].end > gap) { - GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, array_length(variants), variants); + //fprintf(stderr, "Maak graaf: %zu\n", last); + GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, array_length(variants) - last, variants + last); for (size_t i = 0; i < array_length(graph.local_supremal) - 1; ++i) { @@ -525,27 +478,25 @@ vcf_main2(int argc, char* argv[static argc + 1]) graph.local_supremal[i], graph.local_supremal[i + 1], i == 0, i == array_length(graph.local_supremal) - 2, &variant); fprintf(stdout, "%u " GVA_VARIANT_FMT_SPDI "\n", graph.local_supremal[i + 1].distance, GVA_VARIANT_PRINT_SPDI("NC_000001.11", variant)); - created += 1; - } // for - - for (size_t i = 0; i < array_length(variants); ++i) - { - gva_string_destroy(gva_std_allocator, variants[i].sequence); + distance += graph.local_supremal[i + 1].distance; + ARRAY_APPEND(gva_std_allocator, lss, gva_variant_dup(gva_std_allocator, variant)); } // for - variants = ARRAY_DESTROY(gva_std_allocator, variants); + last = array_length(variants); gva_string_destroy(gva_std_allocator, graph.observed); gva_lcs_graph_destroy(gva_std_allocator, graph); } // if - ARRAY_APPEND(gva_std_allocator, variants, gva_variant_dup(gva_std_allocator, prefix_trimmed(reference.len, reference.str, variant))); - last = variants[array_length(variants) - 1]; - } // while + //fprintf(stderr, "Add variant\n"); - if (variants != NULL) + ARRAY_APPEND(gva_std_allocator, variants, gva_variant_dup(gva_std_allocator, trimmed)); + line_count += 1; + } // while + if (last < array_length(variants)) { - GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, array_length(variants), variants); + //fprintf(stderr, "Maak graaf: %zu\n", last); + GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, array_length(variants) - last, variants + last); for (size_t i = 0; i < array_length(graph.local_supremal) - 1; ++i) { @@ -554,145 +505,54 @@ vcf_main2(int argc, char* argv[static argc + 1]) graph.local_supremal[i], graph.local_supremal[i + 1], i == 0, i == array_length(graph.local_supremal) - 2, &variant); fprintf(stdout, "%u " GVA_VARIANT_FMT_SPDI "\n", graph.local_supremal[i + 1].distance, GVA_VARIANT_PRINT_SPDI("NC_000001.11", variant)); - created += 1; - } // for - - for (size_t i = 0; i < array_length(variants); ++i) - { - gva_string_destroy(gva_std_allocator, variants[i].sequence); + distance += graph.local_supremal[i + 1].distance; + ARRAY_APPEND(gva_std_allocator, lss, gva_variant_dup(gva_std_allocator, variant)); } // for - variants = ARRAY_DESTROY(gva_std_allocator, variants); + last = array_length(variants); gva_string_destroy(gva_std_allocator, graph.observed); gva_lcs_graph_destroy(gva_std_allocator, graph); } // if - fprintf(stderr, "count: %zu\n", count); - fprintf(stderr, "dropped: %zu\n", dropped); - fprintf(stderr, "created: %zu\n", created); - - gva_string_destroy(gva_std_allocator, reference); - - return EXIT_SUCCESS; -} // vcf_main2 - - -int -vcf_main(int argc, char* argv[static argc + 1]) -{ - errno = 0; - FILE* stream = fopen(argv[1], "r"); - if (stream == NULL) + GVA_String observed = gva_patch(gva_std_allocator, reference.len, reference.str, array_length(variants), variants); + GVA_String lss_observed = gva_patch(gva_std_allocator, reference.len, reference.str, array_length(lss), lss); + size_t const in_distance = gva_edit_distance(gva_std_allocator, reference.len, reference.str, observed.len, observed.str); + + fprintf(stderr, "===INPUT===\n"); + fprintf(stderr, "#variants: %zu\n", array_length(variants)); + fprintf(stderr, "#dropped: %zu\n", dropped); + fprintf(stderr, "distance: %zu\n", in_distance); + fprintf(stderr, "===OUTPUT===\n"); + fprintf(stderr, "#parts: %zu\n", array_length(lss)); + fprintf(stderr, "distance: %zu\n", distance); + + for (size_t i = 0; i < array_length(variants); ++i) { - fprintf(stderr, "error: %s\n", strerror(errno)); - return EXIT_FAILURE; - } // if - - GVA_String reference = gva_fasta_sequence(gva_std_allocator, stream); - fclose(stream); - fprintf(stderr, "reference length: %zu\n", reference.len); + gva_string_destroy(gva_std_allocator, variants[i].sequence); + } // for + variants = ARRAY_DESTROY(gva_std_allocator, variants); - GVA_Variant variants[2]; - size_t count = 0; - size_t out_count = 0; - size_t drop_count = 0; - static char line[LINE_SIZE] = {0}; - // read line - while (fgets(line, sizeof(line), stdin) != NULL) + for (size_t i = 0; i < array_length(lss); ++i) { - // fprintf(stderr, "count: %zu\n", count); - int const len = (char*) memchr(line, '\n', LINE_SIZE) - line; - if (gva_parse_spdi(len, line, &variants[count > 0]) == 0) - { - fprintf(stderr, "error: SPDI parsing failed at line %zu: %s", count + 1, line); - continue; - } // if - - variants[count > 0] = prefix_trimmed(reference.len, reference.str, variants[count > 0]); - // fprintf(stderr, "variant: " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(variants[count > 0])); - - if (count > 0 && variants[0].end > variants[1].start) - { - fprintf(stderr, "drop: " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(variants[1])); - drop_count += 1; - continue; - } // if - - // TODO: memory allocated here - GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1 + (count > 0), variants); - // fprintf(stderr, "graph distance: %u\n", graph.distance); - - if (graph.distance == 0) - { - fprintf(stderr, "drop0: " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(variants[0])); - fprintf(stderr, "drop1: " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(variants[1])); - count = 0; - gva_string_destroy(gva_std_allocator, variants[0].sequence); - gva_string_destroy(gva_std_allocator, graph.observed); - gva_lcs_graph_destroy(gva_std_allocator, graph); - continue; - } // if - - GVA_Variant local; - for (size_t i = 0; i < array_length(graph.local_supremal) - 1; ++i) - { - // fprintf(stderr, "i: %zu\n", i); - gva_edges(graph.observed.str, - graph.local_supremal[i], graph.local_supremal[i + 1], - i == 0, i == array_length(graph.local_supremal) - 2, - &local); - if (i < array_length(graph.local_supremal) - 2) - { - printf("%u " GVA_VARIANT_FMT_SPDI "\n", graph.local_supremal[i + 1].distance, GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, local)); - out_count += 1; - } // if - } // for - if (count > 0) - { - gva_string_destroy(gva_std_allocator, variants[0].sequence); - } // if - // TODO: memory accessed here - // fprintf(stderr, "before\n"); - // fprintf(stderr, "%u_%u:%.*s(%zu)\n", local.start, local.end, (int)local.sequence.len, local.sequence.str, local.sequence.len); - variants[0] = (GVA_Variant) {local.start, local.end, gva_string_dup(gva_std_allocator, local.sequence)}; - // fprintf(stderr, "after\n"); - variants[0] = suffix_trimmed(reference.len, reference.str, variants[0]); + gva_string_destroy(gva_std_allocator, lss[i].sequence); + } // for + lss = ARRAY_DESTROY(gva_std_allocator, lss); - count += 1; + bool const eq = observed.len == lss_observed.len && strncmp(observed.str, lss_observed.str, observed.len) == 0; - // TODO: memory freed here - // fprintf(stderr, "string destroy %zu\n", graph.observed.len); - gva_string_destroy(gva_std_allocator, graph.observed); - gva_lcs_graph_destroy(gva_std_allocator, graph); + gva_string_destroy(gva_std_allocator, lss_observed); + gva_string_destroy(gva_std_allocator, observed); + gva_string_destroy(gva_std_allocator, reference); - } // while - // fprintf(stderr, "count: %zu\n", count); - if (count > 0) + if (eq) { - GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, variants); - // fprintf(stderr, "bottom graph distance: %u\n", graph.distance); - - for (size_t i = 0; i < array_length(graph.local_supremal) - 1; ++i) - { - GVA_Variant local; - gva_edges(graph.observed.str, - graph.local_supremal[i], graph.local_supremal[i + 1], - i == 0, i == array_length(graph.local_supremal) - 2, - &local); - printf("%u " GVA_VARIANT_FMT_SPDI "\n", graph.local_supremal[i + 1].distance, GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, local)); - out_count += 1; - } // for - gva_string_destroy(gva_std_allocator, variants[0].sequence); - gva_string_destroy(gva_std_allocator, graph.observed); - gva_lcs_graph_destroy(gva_std_allocator, graph); + return EXIT_SUCCESS; } // if - fprintf(stderr, "#local supremal parts: %zu\n", out_count); - fprintf(stderr, "#dropped variants: %zu\n", drop_count); + fprintf(stderr, "ERROR\n"); - gva_string_destroy(gva_std_allocator, reference); - return EXIT_SUCCESS; + return EXIT_FAILURE; } // vcf_main @@ -1350,9 +1210,7 @@ main(int argc, char* argv[static argc + 1]) { // return fasta_blob_read(argc, argv); // return fasta_blob_write(argc, argv); - // return vcf_main2(argc, argv); - return wu_main(argc, argv); - // return vcf_main(argc, argv); + return vcf_main(argc, argv); // return dbsnp_main(argc, argv); // return locals_main(argc, argv); } // main From efa84c1e740a7401abcacedaed3e40bde157cc85 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Wed, 17 Dec 2025 10:51:21 +0100 Subject: [PATCH 438/704] XOR based double join table. --- src/main.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/main.c b/src/main.c index bf03b17..994dce1 100644 --- a/src/main.c +++ b/src/main.c @@ -604,14 +604,14 @@ dbsnp_main(int argc, char* argv[static argc + 1]) Interval_Tree tree = interval_tree_init(); struct Node_Allele { - gva_uint node; - gva_uint allele; + gva_uint link; gva_uint next; }* node_allele_join = NULL; struct Allele { gva_uint line; gva_uint join_start; // offset into node_allele_join + gva_uint join_end; // end of offset into node_allele_join gva_uint distance; }* db_alleles = NULL; @@ -634,7 +634,9 @@ dbsnp_main(int argc, char* argv[static argc + 1]) gva_uint const allele_idx = ARRAY_APPEND( gva_std_allocator, db_alleles, - ((struct Allele) {line_count, array_length(node_allele_join), graph.distance}) + ((struct Allele) {line_count, array_length(node_allele_join), + array_length(node_allele_join) + array_length(graph.local_supremal) - 1, + graph.distance}) ) - 1; for (size_t i = 0; i < array_length(graph.local_supremal) - 1; ++i) @@ -652,7 +654,7 @@ dbsnp_main(int argc, char* argv[static argc + 1]) { array_header(tree.nodes)->length -= 1; // reverse; node already in the tree } // if - tree.nodes[node_idx].alleles = ARRAY_APPEND(gva_std_allocator, node_allele_join, ((struct Node_Allele) {node_idx, allele_idx, tree.nodes[node_idx].alleles})) - 1; + tree.nodes[node_idx].alleles = ARRAY_APPEND(gva_std_allocator, node_allele_join, ((struct Node_Allele) {node_idx ^ allele_idx, tree.nodes[node_idx].alleles})) - 1; } // for gva_string_destroy(gva_std_allocator, graph.observed); @@ -825,7 +827,7 @@ dbsnp_main(int argc, char* argv[static argc + 1]) naj_table_idx != GVA_NULL; naj_table_idx = node_allele_join[naj_table_idx].next) { - size_t const allele_idx = node_allele_join[naj_table_idx].allele; + size_t const allele_idx = node_allele_join[naj_table_idx].link ^ node_idx; HASH_TABLE_SET(gva_std_allocator, results_table, allele_idx, ((struct RESULT_ALLELES) {allele_idx})); } // for alleles } // for node_parts_table @@ -846,12 +848,9 @@ dbsnp_main(int argc, char* argv[static argc + 1]) gva_uint is_contained_part_idx = -1; // loop over all nodes for this allele - for (size_t join_idx = db_alleles[allele_idx].join_start; - join_idx < array_length(node_allele_join) && node_allele_join[join_idx].allele == allele_idx; - ++join_idx) + for (size_t join_idx = db_alleles[allele_idx].join_start; join_idx < db_alleles[allele_idx].join_end; ++join_idx) { - size_t const node_idx = node_allele_join[join_idx].node; - + size_t node_idx = node_allele_join[join_idx].link ^ allele_idx; size_t const hash_idx = HASH_TABLE_INDEX(node_parts_table, node_idx); if (node_idx != node_parts_table[hash_idx].gva_key) { @@ -1210,7 +1209,7 @@ main(int argc, char* argv[static argc + 1]) { // return fasta_blob_read(argc, argv); // return fasta_blob_write(argc, argv); - return vcf_main(argc, argv); - // return dbsnp_main(argc, argv); + // return vcf_main(argc, argv); + return dbsnp_main(argc, argv); // return locals_main(argc, argv); } // main From 814ce0d629cf0f093827af3359c6016d49999f73 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Wed, 17 Dec 2025 10:51:45 +0100 Subject: [PATCH 439/704] Use fasta blob. --- src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.c b/src/main.c index 994dce1..9dcb4f9 100644 --- a/src/main.c +++ b/src/main.c @@ -595,7 +595,7 @@ dbsnp_main(int argc, char* argv[static argc + 1]) } // if GVA_String reference = {0, NULL}; - reference = gva_fasta_sequence(gva_std_allocator, stream); + reference = gva_fasta_sequence_blob(gva_std_allocator, stream); fclose(stream); fprintf(stderr, "reference length: %zu\n", reference.len); From 3282bb4bbcf24349d2afde9a84ccc16f81b06267 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Wed, 17 Dec 2025 21:06:22 +0100 Subject: [PATCH 440/704] Get rid of commented out code block. --- src/main.c | 145 ----------------------------------------------------- 1 file changed, 145 deletions(-) diff --git a/src/main.c b/src/main.c index 9dcb4f9..95a4886 100644 --- a/src/main.c +++ b/src/main.c @@ -1049,151 +1049,6 @@ locals_main(int argc, char* argv[static argc + 1]) fprintf(stderr, "#db_alleles: %zu\n", array_length(db_alleles)); fprintf(stderr, "#join: %zu\n", array_length(node_allele_join)); - // line_count = 0; - // parts = 0; - // while (fgets(line, sizeof(line), stdin) != NULL) { - // size_t idx = 0; - // size_t data = parse_number(line, &idx); // glob index - // idx += 1; // skip space or tab - // size_t allele_entries = parse_number(line, &idx); - // parts += allele_entries; - // - // size_t const allele_idx = ARRAY_APPEND(gva_std_allocator, db_alleles, - // ((struct Allele) {data, array_length(node_allele_join), 0})) - 1; - // fprintf(stderr, "allele: %zu (%zu) length: %zu\n", data, allele_idx, allele_entries); - // - // // Join nodes in the index to parts in the query - // struct NODE_PARTS - // { - // HASH_TABLE_KEY; - // GVA_Relation relation; - // gva_uint start; - // gva_uint end; - // gva_uint included; - // }* node_parts_table = hash_table_init(gva_std_allocator, 1024, sizeof(*node_parts_table)); - // - // gva_uint part_distances[allele_entries]; - // gva_uint part_starts[allele_entries]; - // gva_uint part_ends[allele_entries]; - // - // size_t allele_distance = 0; - // line_count += 1; - // for (size_t part_idx = 0; part_idx < allele_entries; ++part_idx) { - // fgets(line, sizeof(line), stdin); - // idx = 0; - // size_t const rhs_distance = parse_number(line, &idx); - // allele_distance += rhs_distance; - // idx += 1; - // int const len = (char *) memchr(line + idx, '\n', LINE_SIZE - idx) - (line + idx); - // GVA_Variant rhs_part; - // if (gva_parse_spdi(len, line + idx, &rhs_part) == 0) { - // fprintf(stderr, "error: SPDI parsing failed at line %zu: %s", line_count + 1, line); - // continue; - // } // - // // fprintf(stderr, GVA_VARIANT_FMT " %zu\n", GVA_VARIANT_PRINT(rhs_part), distance); - // part_distances[part_idx] = rhs_distance; - // part_starts[part_idx] = rhs_part.start; - // part_ends[part_idx] = rhs_part.end; - // - // gva_uint* candidates = interval_tree_intersection(gva_std_allocator, tree, rhs_part.start, rhs_part.end); - // for (size_t can_idx = 0; can_idx < array_length(candidates); ++can_idx) - // { - // gva_uint const node_idx = candidates[can_idx]; - // GVA_Variant const db_var = {tree.nodes[node_idx].start, tree.nodes[node_idx].end, - // trie_string(trie, tree.nodes[node_idx].inserted)}; - // GVA_Relation const relation = compare_from_index(reference, db_var, tree.nodes[node_idx].distance, rhs_part, rhs_distance); - // if (relation == GVA_DISJOINT) - // { - // continue; - // } // if - // - // // link nodes to query parts - // size_t hash_idx = HASH_TABLE_INDEX(node_parts_table, node_idx); - // if (node_parts_table[hash_idx].gva_key != node_idx) - // { - // HASH_TABLE_SET(gva_std_allocator, node_parts_table, node_idx, - // ((struct NODE_PARTS) {node_idx, relation, part_idx, part_idx + 1, rhs_distance})); - // hash_idx = HASH_TABLE_INDEX(node_parts_table, node_idx); - // } // if - // - // if (relation == GVA_EQUIVALENT || relation == GVA_IS_CONTAINED) - // { - // node_parts_table[hash_idx].included = tree.nodes[node_idx].distance; - // } // if - // else if (relation == GVA_CONTAINS) - // { - // node_parts_table[hash_idx].end = part_idx + 1; - // } // if - // else // GVA_OVERLAP - // { - // node_parts_table[hash_idx].included = 1; - // } // else - // } // for every candidate - // candidates = ARRAY_DESTROY(gva_std_allocator, candidates); - // - // } // for - // - // // fix containment for multiple parts in single node for every query - // for (size_t npt_index = 0; npt_index < array_header(node_parts_table)->capacity; ++npt_index) - // { - // size_t const node_idx = node_parts_table[npt_index].gva_key; - // if (node_idx == GVA_NOT_FOUND) - // { - // continue; - // } // if - // - // if (node_parts_table[npt_index].relation == GVA_CONTAINS && - // node_parts_table[npt_index].end - node_parts_table[npt_index].start > 1) - // { - // size_t const lhs_distance = tree.nodes[node_idx].distance; - // size_t rhs_distance = 0; - // for (size_t i = node_parts_table[npt_index].start; i < node_parts_table[npt_index].end; ++i) - // { - // // TODO: which distance?! - // // rhs_distance += rhs_graph.local_supremal[i + 1].distance; - // rhs_distance += part_distances[i]; - // - // } // for - // if (rhs_distance >= lhs_distance) - // { - // node_parts_table[npt_index].included = 1; - // node_parts_table[npt_index].relation = GVA_OVERLAP; - // continue; - // } // if - // - // GVA_Variant const lhs = {tree.nodes[node_idx].start, - // tree.nodes[node_idx].end, - // trie_string(trie, tree.nodes[node_idx].inserted)}; - // - // GVA_Variant rhs; - // gva_edges(rhs_graph.observed.str, - // // rhs_graph.local_supremal[node_parts_table[npt_index].start], - // // rhs_graph.local_supremal[node_parts_table[npt_index].end], - // rhs_graph.local_supremal[node_parts_table[npt_index].start], - // rhs_graph.local_supremal[node_parts_table[npt_index].end], - // node_parts_table[npt_index].start == 0, - // node_parts_table[npt_index].end == array_length(rhs_graph.local_supremal) - 1, - // &rhs); - // - // size_t const distance = variants_distance(gva_std_allocator, reference.len, reference.str, lhs, rhs); - // if (lhs_distance - distance == rhs_distance) - // { - // node_parts_table[npt_index].included = rhs_distance; - // } // if - // else - // { - // node_parts_table[npt_index].included = 1; - // node_parts_table[npt_index].relation = GVA_OVERLAP; - // } // if - // } // if - // } // for node_parts_table - // - // node_parts_table = HASH_TABLE_DESTROY(gva_std_allocator, node_parts_table); - // } // while - - - - db_alleles = ARRAY_DESTROY(gva_std_allocator, db_alleles); node_allele_join = ARRAY_DESTROY(gva_std_allocator, node_allele_join); interval_tree_destroy(gva_std_allocator, &tree); From f3f6e0442dfd12e59022c046126039a507d0bc2c Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 9 Jan 2026 15:24:04 +0100 Subject: [PATCH 441/704] Calculated bitfields --- src/align.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/align.h b/src/align.h index d7ff0e9..a201bd6 100644 --- a/src/align.h +++ b/src/align.h @@ -2,6 +2,7 @@ #define GVA_ALIGN_H +#include // CHAR_BIT #include // size_t #include "../include/allocator.h" // GVA_Allocator @@ -12,8 +13,8 @@ typedef struct { gva_uint row; gva_uint col; - gva_uint length : 31; - gva_uint moved : 1; + gva_uint length : sizeof(gva_uint) * CHAR_BIT - 1; + gva_uint moved : 1; gva_uint incoming; gva_uint idx; gva_uint next; From 2441f33c6957043d91732e61bba98799817f8c4c Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 9 Jan 2026 15:24:51 +0100 Subject: [PATCH 442/704] WIP: onp-based local supremals --- include/edit.h | 13 ++ src/edit.c | 61 ++++++-- src/main.c | 413 +++++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 409 insertions(+), 78 deletions(-) diff --git a/include/edit.h b/include/edit.h index 70f30ed..30b706d 100644 --- a/include/edit.h +++ b/include/edit.h @@ -5,6 +5,19 @@ #include // size_t #include "allocator.h" // GVA_Allocator +#include "types.h" // gva_uint + + +typedef struct +{ + gva_uint row; + gva_uint col; +} MNode; + + +extern size_t max_lcs_pos; +extern MNode* matches; +extern char* uniq; size_t diff --git a/src/edit.c b/src/edit.c index 36513fa..19cd154 100644 --- a/src/edit.c +++ b/src/edit.c @@ -1,10 +1,19 @@ #include // intmax_t +#include // bool, false, true #include // NULL, size_t #include "../include/allocator.h" // GVA_Allocator #include "../include/edit.h" // gva_edit_distance -#include "common.h" // MAX +#include "common.h" // ABS, MAX + + +#include // DEBUG + + +size_t max_lcs_pos = 0; +MNode* matches = NULL; +char* uniq = NULL; static inline size_t @@ -12,14 +21,38 @@ onp_snake(size_t const m, char const a[static restrict m], size_t const n, char const b[static restrict n], intmax_t const k, intmax_t const lower, - intmax_t const upper) + intmax_t const upper, + intmax_t const delta, + size_t const p, + bool const swapped) { size_t col = MAX(lower, upper); size_t row = col - k; + + intmax_t const d_row = m - row; + intmax_t const d_col = n - col; + while (row < m && col < n && a[row] == b[col]) { row += 1; col += 1; + size_t const lcs_pos = (row + col - ABS(delta) - 2 * p + ABS(d_row - d_col)) / 2; + fprintf(stderr, "%zu: (%zu, %zu)\n", lcs_pos - 1, row - 1, col - 1); + uniq[lcs_pos - 1] = 0; + //matches[lcs_pos - 1] = (MNode) {-1, -1}; + if (lcs_pos > max_lcs_pos) + { + max_lcs_pos = lcs_pos; + uniq[lcs_pos - 1] = 1; + if (swapped) + { + matches[lcs_pos - 1] = (MNode) {col - 1, row - 1}; + } // if + else + { + matches[lcs_pos - 1] = (MNode) {row - 1, col - 1}; + } // else + } // if } // while return col; } // onp_snake @@ -28,7 +61,8 @@ onp_snake(size_t const m, char const a[static restrict m], static size_t onp_compare(GVA_Allocator const allocator, size_t const m, char const a[static restrict m], - size_t const n, char const b[static restrict n]) + size_t const n, char const b[static restrict n], + bool const swapped) { intmax_t const delta = n - m; size_t const offset = m + 1; @@ -39,23 +73,29 @@ onp_compare(GVA_Allocator const allocator, return -1; } // if - for (size_t i = 0; i < size; ++i) + for (intmax_t i = -1; i <= delta; ++i) { - fp[i] = -1; + fp[i + offset] = -1; } // for + max_lcs_pos = 0; + matches = allocator.allocate(allocator.context, NULL, 0, sizeof(*matches) * m); + uniq = allocator.allocate(allocator.context, NULL, 0, sizeof(*uniq) * m); + size_t p = 0; while ((size_t) fp[delta + offset] != n) { + fp[-p - 1 + offset] = -1; + fp[delta + p + 1 + offset] = -1; for (intmax_t k = -p; k <= delta - 1; ++k) { - fp[k + offset] = onp_snake(m, a, n, b, k, fp[k - 1 + offset] + 1, fp[k + 1 + offset]); + fp[k + offset] = onp_snake(m, a, n, b, k, fp[k - 1 + offset] + 1, fp[k + 1 + offset], delta, p, swapped); } // for for (intmax_t k = delta + p; k >= delta + 1; --k) { - fp[k + offset] = onp_snake(m, a, n, b, k, fp[k - 1 + offset] + 1, fp[k + 1 + offset]); + fp[k + offset] = onp_snake(m, a, n, b, k, fp[k - 1 + offset] + 1, fp[k + 1 + offset], delta, p, swapped); } // for - fp[delta + offset] = onp_snake(m, a, n, b, delta, fp[delta - 1 + offset] + 1, fp[delta + 1 + offset]); + fp[delta + offset] = onp_snake(m, a, n, b, delta, fp[delta - 1 + offset] + 1, fp[delta + 1 + offset], delta, p, swapped); p += 1; } // while @@ -69,7 +109,8 @@ gva_edit_distance(GVA_Allocator const allocator, size_t const len_ref, char const reference[static restrict len_ref], size_t const len_obs, char const observed[static restrict len_obs]) { + fprintf(stderr, "ALIGN\n"); return len_ref > len_obs ? - onp_compare(allocator, len_obs, observed, len_ref, reference) : - onp_compare(allocator, len_ref, reference, len_obs, observed); + onp_compare(allocator, len_obs, observed, len_ref, reference, true) : + onp_compare(allocator, len_ref, reference, len_obs, observed, false); } // gva_edit_distance diff --git a/src/main.c b/src/main.c index bf03b17..91bb20e 100644 --- a/src/main.c +++ b/src/main.c @@ -33,6 +33,42 @@ #define REFERENCE_ID "NC_000001.11" +static void +lcs_graph_dot(FILE* const stream, GVA_LCS_Graph const graph) +{ + fprintf(stream, "strict digraph{\nrankdir=LR\nedge[fontname=monospace]\nnode[fixedsize=true,fontname=serif,shape=circle,width=1]\ni[label=\"\",shape=none,width=0]\ni->%u\n", graph.source); + for (size_t i = 0; i < array_length(graph.nodes); ++i) + { + fprintf(stream, "%zu[label=\"(%u, %u, %u)\"%s]\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, graph.nodes[i].edges == GVA_NULL ? ",peripheries=2" : ""); + if (graph.nodes[i].lambda != GVA_NULL) + { + fprintf(stream, "%zu->%u[label=\"λ\",style=dashed]\n", i, graph.nodes[i].lambda); + } // if + for (gva_uint j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) + { + GVA_Variant variant; + gva_uint const count = gva_edges(graph.observed.str, + graph.nodes[i], graph.nodes[graph.edges[j].tail], + i == graph.source, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, + &variant); + if (count > 1) + { + fprintf(stream, "%zu->%u[label=\"" GVA_VARIANT_FMT " x %u\",penwidth=2]\n", i, graph.edges[j].tail, GVA_VARIANT_PRINT(variant), count); + } // if + else + { + fprintf(stream, "%zu->%u[label=\"" GVA_VARIANT_FMT "\"]\n", i, graph.edges[j].tail, GVA_VARIANT_PRINT(variant)); + } // else + } // for + } // for + for (size_t i = 0; i < array_length(graph.local_supremal); ++i) + { + fprintf(stream, "%u[penwidth=2]\n", graph.local_supremal[i].lambda); + } // for + fprintf(stream, "}\n"); +} // lcs_graph_dot + + // FIXME: see `match_number` in src/variant.c static inline size_t parse_number(char const buffer[static 1], size_t idx[static 1]) @@ -52,81 +88,49 @@ gva_fasta_sequence_blob(GVA_Allocator const allocator, FILE* const stream) { GVA_String reference = {0, NULL}; - static char line[42] = {0}; - if (fgets(line, sizeof(line), stream) == NULL) + errno = 0; + if (fread(&reference.len, sizeof(reference.len), 1, stream) != 1) { fprintf(stderr, "error: %s\n", strerror(errno)); - return reference; - } // if - size_t idx = 0; - size_t length = parse_number(line, &idx); + return (GVA_String) {0, NULL}; + } // if - reference.str = allocator.allocate(allocator.context, NULL, 0, length); + reference.str = allocator.allocate(allocator.context, NULL, 0, reference.len); if (reference.str == NULL) { - fprintf(stderr, "allocate error: %s\n", strerror(errno)); - return reference; + fprintf(stderr, "OOM\n"); + return (GVA_String) {0, NULL}; } // if - if (fgets((char *)reference.str, length, stream) == NULL) + errno = 0; + if (fread((char*) reference.str, 1, reference.len, stream) != reference.len) { - fprintf(stderr, "read error: %s\n", strerror(errno)); - gva_string_destroy(gva_std_allocator, reference); - return reference; + fprintf(stderr, "error: %s\n", strerror(errno)); + gva_string_destroy(allocator, reference); + return (GVA_String) {0, NULL}; } // if - reference.len = length; return reference; } // gva_fasta_sequence_blob -int -fasta_blob_write(int argc, char* argv[static argc + 1]) +static void +fasta_blob_write(FILE* stream, GVA_String const sequence) { errno = 0; - FILE* stream = fopen(argv[1], "r"); - if (stream == NULL) + if (fwrite(&sequence.len, sizeof(sequence.len), 1, stream) != 1) { fprintf(stderr, "error: %s\n", strerror(errno)); - return EXIT_FAILURE; + return; } // if - GVA_String reference = {0, NULL}; - reference = gva_fasta_sequence(gva_std_allocator, stream); - fclose(stream); - - fprintf(stderr, "reference length: %zu\n", reference.len); - - fprintf(stdout, "%zu\n", reference.len); - size_t const ret = fwrite(reference.str, 1, reference.len, stdout); - if (ret != reference.len) - { - return EXIT_FAILURE; - } // if - - return EXIT_SUCCESS; -} // fasta_blob_write - - -int -fasta_blob_read(int argc, char* argv[static argc + 1]) -{ errno = 0; - FILE* stream = fopen(argv[1], "r"); - if (stream == NULL) + if (fwrite(sequence.str, 1, sequence.len, stream) != sequence.len) { fprintf(stderr, "error: %s\n", strerror(errno)); - return EXIT_FAILURE; + return; } // if - - GVA_String reference = gva_fasta_sequence_blob(gva_std_allocator, stream); - fclose(stream); - - fprintf(stderr, "reference length: %zu\n", reference.len); - gva_string_destroy(gva_std_allocator, reference); - - return EXIT_SUCCESS; -} // fasta_blob_read +} // fasta_blob_write GVA_Relation @@ -445,10 +449,6 @@ int vcf_main(int argc, char* argv[static argc + 1]) static char line[LINE_SIZE] = {0}; while (fgets(line, sizeof(line), stdin) != NULL) { - //size_t idx = 0; - //size_t const distance = parse_number(line, &idx); - //idx += 1; // skip space or tab - //int const len = (char*) memchr(line + idx, '\n', LINE_SIZE - idx) - (line + idx); size_t const len = strlen(line) - 1; GVA_Variant variant; if (gva_parse_spdi(len, line, &variant) == 0) @@ -468,7 +468,6 @@ int vcf_main(int argc, char* argv[static argc + 1]) if (array_length(variants) > 0 && trimmed.start - variants[array_length(variants) - 1].end > gap) { - //fprintf(stderr, "Maak graaf: %zu\n", last); GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, array_length(variants) - last, variants + last); for (size_t i = 0; i < array_length(graph.local_supremal) - 1; ++i) @@ -477,7 +476,7 @@ int vcf_main(int argc, char* argv[static argc + 1]) gva_edges(graph.observed.str, graph.local_supremal[i], graph.local_supremal[i + 1], i == 0, i == array_length(graph.local_supremal) - 2, &variant); - fprintf(stdout, "%u " GVA_VARIANT_FMT_SPDI "\n", graph.local_supremal[i + 1].distance, GVA_VARIANT_PRINT_SPDI("NC_000001.11", variant)); + //fprintf(stdout, "%u " GVA_VARIANT_FMT_SPDI "\n", graph.local_supremal[i + 1].distance, GVA_VARIANT_PRINT_SPDI("NC_000001.11", variant)); distance += graph.local_supremal[i + 1].distance; ARRAY_APPEND(gva_std_allocator, lss, gva_variant_dup(gva_std_allocator, variant)); } // for @@ -488,14 +487,11 @@ int vcf_main(int argc, char* argv[static argc + 1]) gva_lcs_graph_destroy(gva_std_allocator, graph); } // if - //fprintf(stderr, "Add variant\n"); - ARRAY_APPEND(gva_std_allocator, variants, gva_variant_dup(gva_std_allocator, trimmed)); line_count += 1; } // while if (last < array_length(variants)) { - //fprintf(stderr, "Maak graaf: %zu\n", last); GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, array_length(variants) - last, variants + last); for (size_t i = 0; i < array_length(graph.local_supremal) - 1; ++i) @@ -504,7 +500,7 @@ int vcf_main(int argc, char* argv[static argc + 1]) gva_edges(graph.observed.str, graph.local_supremal[i], graph.local_supremal[i + 1], i == 0, i == array_length(graph.local_supremal) - 2, &variant); - fprintf(stdout, "%u " GVA_VARIANT_FMT_SPDI "\n", graph.local_supremal[i + 1].distance, GVA_VARIANT_PRINT_SPDI("NC_000001.11", variant)); + //fprintf(stdout, "%u " GVA_VARIANT_FMT_SPDI "\n", graph.local_supremal[i + 1].distance, GVA_VARIANT_PRINT_SPDI("NC_000001.11", variant)); distance += graph.local_supremal[i + 1].distance; ARRAY_APPEND(gva_std_allocator, lss, gva_variant_dup(gva_std_allocator, variant)); } // for @@ -515,18 +511,36 @@ int vcf_main(int argc, char* argv[static argc + 1]) gva_lcs_graph_destroy(gva_std_allocator, graph); } // if + fprintf(stderr, "===INPUT===\n"); + fprintf(stderr, "#variants: %zu\n", array_length(variants)); + fprintf(stderr, "#dropped: %zu\n", dropped); + GVA_String observed = gva_patch(gva_std_allocator, reference.len, reference.str, array_length(variants), variants); GVA_String lss_observed = gva_patch(gva_std_allocator, reference.len, reference.str, array_length(lss), lss); + + fasta_blob_write(stdout, observed); + + return EXIT_SUCCESS; + size_t const in_distance = gva_edit_distance(gva_std_allocator, reference.len, reference.str, observed.len, observed.str); - fprintf(stderr, "===INPUT===\n"); - fprintf(stderr, "#variants: %zu\n", array_length(variants)); - fprintf(stderr, "#dropped: %zu\n", dropped); + for (size_t i = 0; i < MIN(reference.len, observed.len); ++i) + { + if (matches[i].row != (gva_uint) -1) + { + printf("%zu: (%u, %u)\n", i, matches[i].row, matches[i].col); + } // if + } // for + + matches = gva_std_allocator.allocate(gva_std_allocator.context, matches, MIN(reference.len, observed.len), 0); + fprintf(stderr, "distance: %zu\n", in_distance); fprintf(stderr, "===OUTPUT===\n"); fprintf(stderr, "#parts: %zu\n", array_length(lss)); fprintf(stderr, "distance: %zu\n", distance); + //printf("%zu\n", in_distance); + for (size_t i = 0; i < array_length(variants); ++i) { gva_string_destroy(gva_std_allocator, variants[i].sequence); @@ -550,7 +564,7 @@ int vcf_main(int argc, char* argv[static argc + 1]) return EXIT_SUCCESS; } // if - fprintf(stderr, "ERROR\n"); +// fprintf(stderr, "ERROR\n"); return EXIT_FAILURE; } // vcf_main @@ -1205,12 +1219,275 @@ locals_main(int argc, char* argv[static argc + 1]) } // dbsnp_main +static char* +strrev(size_t const n, char str[static n]) +{ + size_t i = n - 1; + size_t j = 0; + while (i > j) + { + char const ch = str[i]; + str[i] = str[j]; + str[j] = ch; + i -= 1; + j += 1; + } // while + return str; +} // strrev + + +#define SMALL + + +void +local_supremal(size_t const len_ref, char const reference[static len_ref], + size_t const len_obs, char const observed[static len_obs], + size_t const offset) +{ + //fprintf(stderr, "LOCAL %zu %zu :: %zu\n", len_ref, len_obs, offset); + if (len_ref == 0 || len_obs == 0) + { + printf("T " GVA_VARIANT_FMT_SPDI " %zu\n", GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, ((GVA_Variant) {offset, offset + len_ref, {len_obs, observed}})), len_ref + len_obs); + return; + } // if + size_t distance = gva_edit_distance(gva_std_allocator, len_ref, reference, len_obs, observed); + MNode* forward = matches; + char* f_uniq = uniq; + //fprintf(stderr, "distance: %zu\n", distance); + //fprintf(stderr, "max_lcs_pos: %zu\n", max_lcs_pos); + + reference = strrev(len_ref, (char*) reference); + observed = strrev(len_obs, (char*) observed); + + distance = gva_edit_distance(gva_std_allocator, len_ref, reference, len_obs, observed); + MNode* backward = matches; + char* b_uniq = uniq; + //fprintf(stderr, "distance: %zu\n", distance); + //fprintf(stderr, "max_lcs_pos: %zu\n", max_lcs_pos); + size_t const max_lcs_pos_local = max_lcs_pos; + + reference = strrev(len_ref, (char*) reference); + observed = strrev(len_obs, (char*) observed); + + size_t sum = 0; + size_t prev_lcs_pos = 0; + size_t prev_row = -1; + size_t prev_col = -1; + bool graaf_maken = false; + for (size_t i = 0; i < max_lcs_pos_local; ++i) + { + size_t const j = max_lcs_pos_local - i - 1; +/* + if (forward[i].row != (gva_uint) -1 && + backward[j].row != (gva_uint) -1 && + forward[i].row == len_ref - backward[j].row - 1 && + forward[i].col == len_obs - backward[j].col - 1) +*/ + if (forward[i].row == len_ref - backward[j].row - 1 && + forward[i].col == len_obs - backward[j].col - 1) + { + if (f_uniq[i] == 1 || b_uniq[j] == 1) + { + #ifdef SMALL + fprintf(stderr, "common: %zu: (%u, %u)\n", i, forward[i].row, forward[i].col); + #endif + if (i > prev_lcs_pos + 1 || + forward[i].row > prev_row + 1 || + forward[i].col > prev_col + 1) + { + size_t const distance = forward[i].row + forward[i].col - 2 * i - sum; + sum += distance; + local_supremal(forward[i].row - prev_row - 1, reference + prev_row + 1, forward[i].col - prev_col - 1, observed + prev_col + 1, offset + prev_row + 1); + //printf(GVA_STRING_FMT "\n", (int) (forward[i].row - prev_row - 1), reference + prev_row + 1); + //printf(GVA_STRING_FMT "\n", (int) (forward[i].col - prev_col - 1), observed + prev_col + 1); + } // if + prev_lcs_pos = i; + prev_row = forward[i].row; + prev_col = forward[i].col; + } // if + else + { + graaf_maken = true; + } // else + } // if + } // for + if (len_ref > prev_row + 1 || len_obs > prev_col + 1) + { + size_t const distance = len_ref + len_obs - 2 * max_lcs_pos_local - sum; + sum += distance; + if (graaf_maken) + { + GVA_LCS_Graph graph = gva_lcs_graph_init(gva_std_allocator, len_ref - prev_row - 1, reference + prev_row + 1, len_obs - prev_col - 1, observed + prev_col + 1, offset + prev_row + 1); + for (size_t i = 0; i < array_length(graph.local_supremal) - 1; ++i) + { + GVA_Variant part; + gva_edges(graph.observed.str, + graph.local_supremal[i], graph.local_supremal[i + 1], + i == 0, i == array_length(graph.local_supremal) - 2, + &part); + printf("G " GVA_VARIANT_FMT_SPDI " %u\n", GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, part), graph.local_supremal[i + 1].distance); + } // for + gva_lcs_graph_destroy(gva_std_allocator, graph); + } // if + else + { + printf("L " GVA_VARIANT_FMT " %zu %zu+[(%zu, %zu)--(%zu, %zu)]\n", GVA_VARIANT_PRINT(((GVA_Variant) {offset + prev_row + 1, offset + len_ref, {len_obs - prev_col - 1, observed + prev_col + 1}})), distance, offset, prev_row + 1, prev_col + 1, len_ref, len_obs); + } // else + //printf("gap %zu: (%zu, %zu)--(%zu, %zu) %zu\n", max_lcs_pos_local, prev_row + 1, prev_col + 1, len_ref, len_obs, distance); + //printf(GVA_STRING_FMT "\n", (int) (len_ref - prev_row - 1), reference + prev_row + 1); + //printf(GVA_STRING_FMT "\n", (int) (len_obs - prev_col - 1), observed + prev_col + 1); + } // if + + //fprintf(stderr, "distance: %zu\n", sum); + + forward = gva_std_allocator.allocate(gva_std_allocator.context, forward, MIN(len_ref, len_obs), 0); + f_uniq = gva_std_allocator.allocate(gva_std_allocator.context, f_uniq, MIN(len_ref, len_obs), 0); + backward = gva_std_allocator.allocate(gva_std_allocator.context, backward, MIN(len_ref, len_obs), 0); + b_uniq = gva_std_allocator.allocate(gva_std_allocator.context, b_uniq, MIN(len_ref, len_obs), 0); +} // local_supremal + + +int +wu_main(int argc, char* argv[static argc + 1]) +{ + if (argc < 3) + { + fprintf(stderr, "usage: %s reference observed\n", argv[0]); + return EXIT_FAILURE; + } // if + +#ifdef SMALL + GVA_String reference = {strlen(argv[1]), argv[1]}; + GVA_String observed = {strlen(argv[2]), argv[2]}; + + GVA_LCS_Graph graph = gva_lcs_graph_init(gva_std_allocator, reference.len, reference.str, observed.len, observed.str, 0); + lcs_graph_dot(stderr, graph); + for (size_t i = 0; i < array_length(graph.local_supremal) - 1; ++i) + { + GVA_Variant part; + gva_edges(graph.observed.str, + graph.local_supremal[i], graph.local_supremal[i + 1], + i == 0, i == array_length(graph.local_supremal) - 2, + &part); + fprintf(stderr, GVA_VARIANT_FMT " %u\n", GVA_VARIANT_PRINT(part), graph.local_supremal[i + 1].distance); + } // for + + gva_lcs_graph_destroy(gva_std_allocator, graph); + +#else + errno = 0; + FILE* stream = fopen(argv[1], "r"); + if (stream == NULL) + { + fprintf(stderr, "error: %s\n", strerror(errno)); + return EXIT_FAILURE; + } // if + + GVA_String reference = gva_fasta_sequence_blob(gva_std_allocator, stream); + fclose(stream); + fprintf(stderr, "reference length: %zu\n", reference.len); + + errno = 0; + stream = fopen(argv[2], "r"); + if (stream == NULL) + { + gva_string_destroy(gva_std_allocator, reference); + fprintf(stderr, "error: %s\n", strerror(errno)); + return EXIT_FAILURE; + } // if + + GVA_String observed = gva_fasta_sequence_blob(gva_std_allocator, stream); + fclose(stream); + fprintf(stderr, "observed length: %zu\n", observed.len); + + if (reference.str == NULL || observed.str == NULL) + { + gva_string_destroy(gva_std_allocator, reference); + gva_string_destroy(gva_std_allocator, observed); + return EXIT_FAILURE; + } // if +#endif + + local_supremal(reference.len, reference.str, observed.len, observed.str, 0); + +#ifndef SMALL + gva_string_destroy(gva_std_allocator, observed); + gva_string_destroy(gva_std_allocator, reference); +#endif + + return EXIT_SUCCESS; +} // wu_main + + +int +slice_blob_main(int argc, char* argv[static argc + 1]) +{ + if (argc < 3) + { + fprintf(stderr, "usage: %s reference observed\n", argv[0]); + return EXIT_FAILURE; + } // if + + errno = 0; + FILE* stream = fopen(argv[1], "r"); + if (stream == NULL) + { + fprintf(stderr, "error: %s\n", strerror(errno)); + return EXIT_FAILURE; + } // if + + GVA_String reference = gva_fasta_sequence_blob(gva_std_allocator, stream); + fclose(stream); + fprintf(stderr, "reference length: %zu\n", reference.len); + + errno = 0; + stream = fopen(argv[2], "r"); + if (stream == NULL) + { + gva_string_destroy(gva_std_allocator, reference); + fprintf(stderr, "error: %s\n", strerror(errno)); + return EXIT_FAILURE; + } // if + + GVA_String observed = gva_fasta_sequence_blob(gva_std_allocator, stream); + fclose(stream); + fprintf(stderr, "observed length: %zu\n", observed.len); + + if (reference.str == NULL || observed.str == NULL) + { + gva_string_destroy(gva_std_allocator, reference); + gva_string_destroy(gva_std_allocator, observed); + return EXIT_FAILURE; + } // if + + fprintf(stderr, GVA_STRING_FMT "\n", (int) 839585 - 839404, reference.str + 839404); + + + return EXIT_SUCCESS; + + MNode const start = {2750171, 2750160}; + MNode const end = {12954448, 12953797}; + + stream = fopen("ref_p1.blob", "w"); + fasta_blob_write(stream, (GVA_String) {end.row - start.row, reference.str + start.row}); + fclose(stream); + + stream = fopen("obs_p1.blob", "w"); + fasta_blob_write(stream, (GVA_String) {end.col - start.col, observed.str + start.col}); + fclose(stream); + + gva_string_destroy(gva_std_allocator, reference); + gva_string_destroy(gva_std_allocator, observed); + return EXIT_SUCCESS; +} // slice_blob_main + + int main(int argc, char* argv[static argc + 1]) { - // return fasta_blob_read(argc, argv); - // return fasta_blob_write(argc, argv); - return vcf_main(argc, argv); + // return vcf_main(argc, argv); + return wu_main(argc, argv); + //return slice_blob_main(argc, argv); // return dbsnp_main(argc, argv); // return locals_main(argc, argv); } // main From 559bb57ba4b1940e59bc12c75d7b63f7736f987d Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Fri, 9 Jan 2026 15:29:23 +0100 Subject: [PATCH 443/704] Add extract_main. --- src/main.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/main.c b/src/main.c index 1860ad8..741ac58 100644 --- a/src/main.c +++ b/src/main.c @@ -1063,6 +1063,8 @@ locals_main(int argc, char* argv[static argc + 1]) fprintf(stderr, "#db_alleles: %zu\n", array_length(db_alleles)); fprintf(stderr, "#join: %zu\n", array_length(node_allele_join)); + + db_alleles = ARRAY_DESTROY(gva_std_allocator, db_alleles); node_allele_join = ARRAY_DESTROY(gva_std_allocator, node_allele_join); interval_tree_destroy(gva_std_allocator, &tree); @@ -1336,6 +1338,42 @@ slice_blob_main(int argc, char* argv[static argc + 1]) } // slice_blob_main +int +extract_main(int argc, char* argv[static argc + 1]) { + errno = 0; + FILE *stream = fopen(argv[1], "r"); + if (stream == NULL) { + fprintf(stderr, "error: %s\n", strerror(errno)); + return EXIT_FAILURE; + } // if + + GVA_String reference = {0, NULL}; + reference = gva_fasta_sequence(gva_std_allocator, stream); + fclose(stream); + + fprintf(stderr, "reference length: %zu\n", reference.len); + + size_t line_count = 0; + static char line[LINE_SIZE] = {0}; + while (fgets(line, sizeof(line), stdin) != NULL) { + size_t const len = strlen(line) - 1; + GVA_Variant variant; + if (gva_parse_spdi(len, line, &variant) == 0) { + fprintf(stderr, "error: SPDI parsing failed at line %zu: %s", line_count + 1, line); + continue; + } // if + + GVA_LCS_Graph const graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &variant); + + gva_string_destroy(gva_std_allocator, graph.observed); + gva_lcs_graph_destroy(gva_std_allocator, graph); + gva_canonical(gva_std_allocator, graph); + } // while + + return EXIT_SUCCESS; +} // extract_main + + int main(int argc, char* argv[static argc + 1]) { @@ -1344,5 +1382,7 @@ main(int argc, char* argv[static argc + 1]) // return dbsnp_main(argc, argv); // return fasta_blob_write(argc, argv); // return vcf_main(argc, argv); + // return dbsnp_main(argc, argv); // return locals_main(argc, argv); + // return extract_main(argc, argv); } // main From c87575ad4c2fb4f0e478132241eeef1ace139dcc Mon Sep 17 00:00:00 2001 From: jkvis Date: Sat, 10 Jan 2026 11:00:02 +0100 Subject: [PATCH 444/704] More bitsets --- src/bitset.c | 36 ++++++++++++++++++++++++++++++++++++ src/bitset.h | 13 +++++++++++++ 2 files changed, 49 insertions(+) diff --git a/src/bitset.c b/src/bitset.c index 94c2867..36e436f 100644 --- a/src/bitset.c +++ b/src/bitset.c @@ -1,5 +1,6 @@ // FIXME: __builtin_popcountll #include // CHAR_BIT +#include // bool #include // NULL, size_t #include // memset @@ -9,6 +10,20 @@ #include "common.h" // MIN +static inline size_t +mask(size_t const value) +{ + return 1ULL << (value % (sizeof(size_t) * CHAR_BIT)); +} // mask + + +static inline size_t +slot(size_t const value) +{ + return value / (sizeof(size_t) * CHAR_BIT); +} // slot + + inline size_t* bitset_init(GVA_Allocator const allocator, size_t const size) { @@ -57,6 +72,27 @@ bitset_intersection_cnt(size_t const lhs[static 1], size_t const rhs[static 1]) } // bitset_intersection_cnt +inline void +bitset_set(size_t self[static 1], size_t const value) +{ + self[slot(value)] |= mask(value); +} // bitset_set + + +inline void +bitset_clear(size_t self[static 1], size_t const value) +{ + self[slot(value)] &= ~mask(value); +} // bitset_clear + + +inline bool +bitset_test(size_t const self[static 1], size_t const value) +{ + return self[slot(value)] & mask(value); +} // bitset_test + + inline size_t* bitset_destroy(GVA_Allocator const allocator, size_t const* const self) { diff --git a/src/bitset.h b/src/bitset.h index 3a61c1b..e2b5dbb 100644 --- a/src/bitset.h +++ b/src/bitset.h @@ -2,6 +2,7 @@ #define GVA_BITSET_H +#include // bool #include // size_t #include "../include/allocator.h" // GVA_Allocator @@ -19,6 +20,18 @@ size_t bitset_intersection_cnt(size_t const lhs[static 1], size_t const rhs[static 1]); +void +bitset_set(size_t self[static 1], size_t const value); + + +void +bitset_clear(size_t self[static 1], size_t const value); + + +bool +bitset_test(size_t const self[static 1], size_t const value); + + size_t* bitset_destroy(GVA_Allocator const allocator, size_t const* const self); From 6ba970594efbee7c1225a2ea694a8ba7477ba03e Mon Sep 17 00:00:00 2001 From: jkvis Date: Sat, 10 Jan 2026 11:00:17 +0100 Subject: [PATCH 445/704] Disable debug in edit --- src/edit.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/edit.c b/src/edit.c index 19cd154..dd28270 100644 --- a/src/edit.c +++ b/src/edit.c @@ -37,7 +37,7 @@ onp_snake(size_t const m, char const a[static restrict m], row += 1; col += 1; size_t const lcs_pos = (row + col - ABS(delta) - 2 * p + ABS(d_row - d_col)) / 2; - fprintf(stderr, "%zu: (%zu, %zu)\n", lcs_pos - 1, row - 1, col - 1); + //fprintf(stderr, "%zu: (%zu, %zu)\n", lcs_pos - 1, row - 1, col - 1); uniq[lcs_pos - 1] = 0; //matches[lcs_pos - 1] = (MNode) {-1, -1}; if (lcs_pos > max_lcs_pos) @@ -109,7 +109,7 @@ gva_edit_distance(GVA_Allocator const allocator, size_t const len_ref, char const reference[static restrict len_ref], size_t const len_obs, char const observed[static restrict len_obs]) { - fprintf(stderr, "ALIGN\n"); + //fprintf(stderr, "ALIGN\n"); return len_ref > len_obs ? onp_compare(allocator, len_obs, observed, len_ref, reference, true) : onp_compare(allocator, len_ref, reference, len_obs, observed, false); From 651f78bc70f297bb83c05c482884f70516300275 Mon Sep 17 00:00:00 2001 From: jkvis Date: Sat, 10 Jan 2026 16:09:47 +0100 Subject: [PATCH 446/704] Revert "More bitsets" This reverts commit c87575ad4c2fb4f0e478132241eeef1ace139dcc. --- src/bitset.c | 36 ------------------------------------ src/bitset.h | 13 ------------- 2 files changed, 49 deletions(-) diff --git a/src/bitset.c b/src/bitset.c index 36e436f..94c2867 100644 --- a/src/bitset.c +++ b/src/bitset.c @@ -1,6 +1,5 @@ // FIXME: __builtin_popcountll #include // CHAR_BIT -#include // bool #include // NULL, size_t #include // memset @@ -10,20 +9,6 @@ #include "common.h" // MIN -static inline size_t -mask(size_t const value) -{ - return 1ULL << (value % (sizeof(size_t) * CHAR_BIT)); -} // mask - - -static inline size_t -slot(size_t const value) -{ - return value / (sizeof(size_t) * CHAR_BIT); -} // slot - - inline size_t* bitset_init(GVA_Allocator const allocator, size_t const size) { @@ -72,27 +57,6 @@ bitset_intersection_cnt(size_t const lhs[static 1], size_t const rhs[static 1]) } // bitset_intersection_cnt -inline void -bitset_set(size_t self[static 1], size_t const value) -{ - self[slot(value)] |= mask(value); -} // bitset_set - - -inline void -bitset_clear(size_t self[static 1], size_t const value) -{ - self[slot(value)] &= ~mask(value); -} // bitset_clear - - -inline bool -bitset_test(size_t const self[static 1], size_t const value) -{ - return self[slot(value)] & mask(value); -} // bitset_test - - inline size_t* bitset_destroy(GVA_Allocator const allocator, size_t const* const self) { diff --git a/src/bitset.h b/src/bitset.h index e2b5dbb..3a61c1b 100644 --- a/src/bitset.h +++ b/src/bitset.h @@ -2,7 +2,6 @@ #define GVA_BITSET_H -#include // bool #include // size_t #include "../include/allocator.h" // GVA_Allocator @@ -20,18 +19,6 @@ size_t bitset_intersection_cnt(size_t const lhs[static 1], size_t const rhs[static 1]); -void -bitset_set(size_t self[static 1], size_t const value); - - -void -bitset_clear(size_t self[static 1], size_t const value); - - -bool -bitset_test(size_t const self[static 1], size_t const value); - - size_t* bitset_destroy(GVA_Allocator const allocator, size_t const* const self); From 503f7b0ae822a55b2eab9d54bc1ed4c590e49181 Mon Sep 17 00:00:00 2001 From: jkvis Date: Sun, 11 Jan 2026 13:28:38 +0100 Subject: [PATCH 447/704] WIP: local supremal for HG00096_A --- src/edit.c | 2 +- src/lcs_graph.c | 6 ++-- src/main.c | 74 +++++++++++++++++++++---------------------------- 3 files changed, 35 insertions(+), 47 deletions(-) diff --git a/src/edit.c b/src/edit.c index dd28270..83dd954 100644 --- a/src/edit.c +++ b/src/edit.c @@ -8,7 +8,7 @@ #include "common.h" // ABS, MAX -#include // DEBUG +//#include // DEBUG size_t max_lcs_pos = 0; diff --git a/src/lcs_graph.c b/src/lcs_graph.c index 65da6c7..82d478d 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -52,7 +52,7 @@ gva_lcs_graph_init(GVA_Allocator const allocator, shift, 0, 0, {0}, GVA_NULL })); ARRAY_APPEND(allocator, graph.local_supremal, ((GVA_Node) { - len_ref + shift, len_obs, 0, {0}, GVA_NULL + len_ref + shift, len_obs, 0, {graph.distance}, GVA_NULL })); graph.supremal = (GVA_Variant) {shift, len_ref + shift, {len_obs, observed}}; return graph; @@ -236,7 +236,7 @@ gva_lcs_graph_init(GVA_Allocator const allocator, { gva_uint const idx = lcs.nodes[prev].idx; gva_uint const offset = graph.nodes[idx].length - lcs.index[lcs.length - 1].offset - len; - gva_uint const distance = graph.nodes[idx].row + graph.nodes[idx].col + 2 * offset + 2 * len - 2 * (lcs.length - len); + gva_uint const distance = graph.nodes[idx].row + graph.nodes[idx].col + 2 * offset + 2 * len - 2 * lcs.length; ARRAY_APPEND(allocator, graph.local_supremal, ((GVA_Node) { graph.nodes[idx].row + offset, graph.nodes[idx].col + offset, len, {distance - prev_distance}, idx })); @@ -245,7 +245,7 @@ gva_lcs_graph_init(GVA_Allocator const allocator, } // if if (graph.nodes != NULL) { - gva_uint const distance = graph.nodes[0].row + graph.nodes[0].length - len + graph.nodes[0].col + graph.nodes[0].length - len - 2 * (lcs.length - len); + gva_uint const distance = graph.nodes[0].row + graph.nodes[0].length - len + graph.nodes[0].col + graph.nodes[0].length - len - 2 * lcs.length; ARRAY_APPEND(allocator, graph.local_supremal, ((GVA_Node) { graph.nodes[0].row + graph.nodes[0].length - len, graph.nodes[0].col + graph.nodes[0].length - len, 0, {distance - prev_distance}, 0 })); diff --git a/src/main.c b/src/main.c index 741ac58..e89e0f5 100644 --- a/src/main.c +++ b/src/main.c @@ -33,7 +33,7 @@ #define REFERENCE_ID "NC_000001.11" -static void +void lcs_graph_dot(FILE* const stream, GVA_LCS_Graph const graph) { fprintf(stream, "strict digraph{\nrankdir=LR\nedge[fontname=monospace]\nnode[fixedsize=true,fontname=serif,shape=circle,width=1]\ni[label=\"\",shape=none,width=0]\ni->%u\n", graph.source); @@ -1092,7 +1092,7 @@ strrev(size_t const n, char str[static n]) } // strrev -#define SMALL +//#define SMALL void @@ -1103,7 +1103,7 @@ local_supremal(size_t const len_ref, char const reference[static len_ref], //fprintf(stderr, "LOCAL %zu %zu :: %zu\n", len_ref, len_obs, offset); if (len_ref == 0 || len_obs == 0) { - printf("T " GVA_VARIANT_FMT_SPDI " %zu\n", GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, ((GVA_Variant) {offset, offset + len_ref, {len_obs, observed}})), len_ref + len_obs); + printf(GVA_VARIANT_FMT_SPDI " %zu\n", GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, ((GVA_Variant) {offset, offset + len_ref, {len_obs, observed}})), len_ref + len_obs); return; } // if size_t distance = gva_edit_distance(gva_std_allocator, len_ref, reference, len_obs, observed); @@ -1129,7 +1129,6 @@ local_supremal(size_t const len_ref, char const reference[static len_ref], size_t prev_lcs_pos = 0; size_t prev_row = -1; size_t prev_col = -1; - bool graaf_maken = false; for (size_t i = 0; i < max_lcs_pos_local; ++i) { size_t const j = max_lcs_pos_local - i - 1; @@ -1140,56 +1139,50 @@ local_supremal(size_t const len_ref, char const reference[static len_ref], forward[i].col == len_obs - backward[j].col - 1) */ if (forward[i].row == len_ref - backward[j].row - 1 && - forward[i].col == len_obs - backward[j].col - 1) + forward[i].col == len_obs - backward[j].col - 1 && + (f_uniq[i] == 1 || b_uniq[j] == 1)) { - if (f_uniq[i] == 1 || b_uniq[j] == 1) + #ifdef SMALL + fprintf(stderr, "common: %zu: (%u, %u)\n", i, forward[i].row, forward[i].col); + #endif + if (i > prev_lcs_pos + 1 || + forward[i].row > prev_row + 1 || + forward[i].col > prev_col + 1) { - #ifdef SMALL - fprintf(stderr, "common: %zu: (%u, %u)\n", i, forward[i].row, forward[i].col); - #endif - if (i > prev_lcs_pos + 1 || - forward[i].row > prev_row + 1 || - forward[i].col > prev_col + 1) + size_t const distance = forward[i].row + forward[i].col - 2 * i - sum; + if (distance > 0) { - size_t const distance = forward[i].row + forward[i].col - 2 * i - sum; sum += distance; + //printf("R gap %zu: (%zu, %zu)--(%u, %u) %zu\n", i, prev_row + 1, prev_col + 1, forward[i].row, forward[i].col, distance); local_supremal(forward[i].row - prev_row - 1, reference + prev_row + 1, forward[i].col - prev_col - 1, observed + prev_col + 1, offset + prev_row + 1); //printf(GVA_STRING_FMT "\n", (int) (forward[i].row - prev_row - 1), reference + prev_row + 1); //printf(GVA_STRING_FMT "\n", (int) (forward[i].col - prev_col - 1), observed + prev_col + 1); } // if - prev_lcs_pos = i; - prev_row = forward[i].row; - prev_col = forward[i].col; } // if - else - { - graaf_maken = true; - } // else + prev_lcs_pos = i; + prev_row = forward[i].row; + prev_col = forward[i].col; } // if } // for if (len_ref > prev_row + 1 || len_obs > prev_col + 1) { size_t const distance = len_ref + len_obs - 2 * max_lcs_pos_local - sum; sum += distance; - if (graaf_maken) - { - GVA_LCS_Graph graph = gva_lcs_graph_init(gva_std_allocator, len_ref - prev_row - 1, reference + prev_row + 1, len_obs - prev_col - 1, observed + prev_col + 1, offset + prev_row + 1); - for (size_t i = 0; i < array_length(graph.local_supremal) - 1; ++i) - { - GVA_Variant part; - gva_edges(graph.observed.str, - graph.local_supremal[i], graph.local_supremal[i + 1], - i == 0, i == array_length(graph.local_supremal) - 2, - &part); - printf("G " GVA_VARIANT_FMT_SPDI " %u\n", GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, part), graph.local_supremal[i + 1].distance); - } // for - gva_lcs_graph_destroy(gva_std_allocator, graph); - } // if - else + //printf(GVA_STRING_FMT " ", (int) (len_ref - prev_row - 1), reference + prev_row + 1); + //printf(GVA_STRING_FMT "\n", (int) (len_obs - prev_col - 1), observed + prev_col + 1); + GVA_LCS_Graph graph = gva_lcs_graph_init(gva_std_allocator, len_ref - prev_row - 1, reference + prev_row + 1, len_obs - prev_col - 1, observed + prev_col + 1, offset + prev_row + 1); + for (size_t i = 0; i < array_length(graph.local_supremal) - 1; ++i) { - printf("L " GVA_VARIANT_FMT " %zu %zu+[(%zu, %zu)--(%zu, %zu)]\n", GVA_VARIANT_PRINT(((GVA_Variant) {offset + prev_row + 1, offset + len_ref, {len_obs - prev_col - 1, observed + prev_col + 1}})), distance, offset, prev_row + 1, prev_col + 1, len_ref, len_obs); - } // else - //printf("gap %zu: (%zu, %zu)--(%zu, %zu) %zu\n", max_lcs_pos_local, prev_row + 1, prev_col + 1, len_ref, len_obs, distance); + GVA_Variant variant; + gva_edges(graph.observed.str, + graph.local_supremal[i], graph.local_supremal[i + 1], + i == 0, i == array_length(graph.local_supremal) - 2, + &variant); + printf(GVA_VARIANT_FMT_SPDI " %u\n", GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, variant), graph.local_supremal[i + 1].distance); + } // for + gva_lcs_graph_destroy(gva_std_allocator, graph); + //printf("L " GVA_VARIANT_FMT " %zu %zu+[(%zu, %zu)--(%zu, %zu)]\n", GVA_VARIANT_PRINT(((GVA_Variant) {offset + prev_row + 1, offset + len_ref, {len_obs - prev_col - 1, observed + prev_col + 1}})), distance, offset, prev_row + 1, prev_col + 1, len_ref, len_obs); + //printf("L gap %zu: (%zu, %zu)--(%zu, %zu) %zu\n", max_lcs_pos_local, prev_row + 1, prev_col + 1, len_ref, len_obs, distance); //printf(GVA_STRING_FMT "\n", (int) (len_ref - prev_row - 1), reference + prev_row + 1); //printf(GVA_STRING_FMT "\n", (int) (len_obs - prev_col - 1), observed + prev_col + 1); } // if @@ -1316,11 +1309,6 @@ slice_blob_main(int argc, char* argv[static argc + 1]) return EXIT_FAILURE; } // if - fprintf(stderr, GVA_STRING_FMT "\n", (int) 839585 - 839404, reference.str + 839404); - - - return EXIT_SUCCESS; - MNode const start = {2750171, 2750160}; MNode const end = {12954448, 12953797}; From 8ff2415dc42192c1c5bbcacece8ecf4153229117 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Mon, 12 Jan 2026 12:24:55 +0100 Subject: [PATCH 448/704] Make blob helpers. --- src/main.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/src/main.c b/src/main.c index e89e0f5..5ff5915 100644 --- a/src/main.c +++ b/src/main.c @@ -1362,6 +1362,87 @@ extract_main(int argc, char* argv[static argc + 1]) { } // extract_main +int make_ref_blob_main(int argc, char* argv[static argc + 1]) { + if (argc < 2) { + fprintf(stderr, "usage: %s reference\n", argv[0]); + return EXIT_FAILURE; + } // if + + errno = 0; + FILE *stream = fopen(argv[1], "r"); + if (stream == NULL) { + fprintf(stderr, "error: %s\n", strerror(errno)); + return EXIT_FAILURE; + } // if + + GVA_String reference = gva_fasta_sequence(gva_std_allocator, stream); + fclose(stream); + fprintf(stderr, "reference length: %zu\n", reference.len); + + fasta_blob_write(stdout, reference); + + return EXIT_SUCCESS; +} // make_ref_blob_main + + +int make_obs_blob_main(int argc, char* argv[static argc + 1]) { + if (argc < 2) { + fprintf(stderr, "usage: %s reference.blob\n", argv[0]); + return EXIT_FAILURE; + } // if + + errno = 0; + FILE *stream = fopen(argv[1], "r"); + if (stream == NULL) { + fprintf(stderr, "error: %s\n", strerror(errno)); + return EXIT_FAILURE; + } // if + + GVA_String reference = gva_fasta_sequence_blob(gva_std_allocator, stream); + fclose(stream); + fprintf(stderr, "reference length: %zu\n", reference.len); + + GVA_Variant * variants = NULL; + GVA_Variant * lss = NULL; + + size_t last = 0; + size_t line_count = 0; + size_t dropped = 0; + size_t distance = 0; + static char line[LINE_SIZE] = {0}; + while (fgets(line, sizeof(line), stdin) != NULL) { + size_t const len = strlen(line) - 1; + GVA_Variant variant; + if (gva_parse_spdi(len, line, &variant) == 0) { + fprintf(stderr, "error: SPDI parsing failed at line %zu: %s", line_count + 1, line); + continue; + } // if + + GVA_Variant trimmed = prefix_trimmed(reference.len, reference.str, variant); + + if (array_length(variants) > 0 && trimmed.start < variants[array_length(variants) - 1].end) { + //fprintf(stderr, "dropped: at line %zu: %s", line_count + 1, line); + dropped += 1; + continue; + } // if + + ARRAY_APPEND(gva_std_allocator, variants, gva_variant_dup(gva_std_allocator, trimmed)); + line_count += 1; + } // while + + fprintf(stderr, "===INPUT===\n"); + fprintf(stderr, "#variants: %zu\n", array_length(variants)); + fprintf(stderr, "#dropped: %zu\n", dropped); + + GVA_String observed = gva_patch(gva_std_allocator, reference.len, reference.str, array_length(variants), variants); + GVA_String lss_observed = gva_patch(gva_std_allocator, reference.len, reference.str, array_length(lss), lss); + + fasta_blob_write(stdout, observed); + + return EXIT_SUCCESS; +} // make_obs_blob_main + + int main(int argc, char* argv[static argc + 1]) { @@ -1373,4 +1454,6 @@ main(int argc, char* argv[static argc + 1]) // return dbsnp_main(argc, argv); // return locals_main(argc, argv); // return extract_main(argc, argv); + // return make_ref_blob_main(argc, argv); + // return make_obs_blob_main(argc, argv); } // main From b1a419e367f19eee5ab96cf40bc0a20ef2bcef33 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Mon, 12 Jan 2026 13:39:15 +0100 Subject: [PATCH 449/704] Break out vcf2obs. --- src/main.c | 47 ++++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/src/main.c b/src/main.c index 5ff5915..808d07f 100644 --- a/src/main.c +++ b/src/main.c @@ -1385,32 +1385,14 @@ int make_ref_blob_main(int argc, char* argv[static argc + 1]) { } // make_ref_blob_main -int make_obs_blob_main(int argc, char* argv[static argc + 1]) { - if (argc < 2) { - fprintf(stderr, "usage: %s reference.blob\n", argv[0]); - return EXIT_FAILURE; - } // if - - errno = 0; - FILE *stream = fopen(argv[1], "r"); - if (stream == NULL) { - fprintf(stderr, "error: %s\n", strerror(errno)); - return EXIT_FAILURE; - } // if - - GVA_String reference = gva_fasta_sequence_blob(gva_std_allocator, stream); - fclose(stream); - fprintf(stderr, "reference length: %zu\n", reference.len); - +GVA_String vcf2obs(GVA_String reference, FILE *stream) +{ GVA_Variant * variants = NULL; - GVA_Variant * lss = NULL; - size_t last = 0; size_t line_count = 0; size_t dropped = 0; - size_t distance = 0; static char line[LINE_SIZE] = {0}; - while (fgets(line, sizeof(line), stdin) != NULL) { + while (fgets(line, sizeof(line), stream) != NULL) { size_t const len = strlen(line) - 1; GVA_Variant variant; if (gva_parse_spdi(len, line, &variant) == 0) { @@ -1434,9 +1416,28 @@ int make_obs_blob_main(int argc, char* argv[static argc + 1]) { fprintf(stderr, "#variants: %zu\n", array_length(variants)); fprintf(stderr, "#dropped: %zu\n", dropped); - GVA_String observed = gva_patch(gva_std_allocator, reference.len, reference.str, array_length(variants), variants); - GVA_String lss_observed = gva_patch(gva_std_allocator, reference.len, reference.str, array_length(lss), lss); + return gva_patch(gva_std_allocator, reference.len, reference.str, array_length(variants), variants); +} // vcf2obs + + +int make_obs_blob_main(int argc, char* argv[static argc + 1]) { + if (argc < 2) { + fprintf(stderr, "usage: %s reference.blob\n", argv[0]); + return EXIT_FAILURE; + } // if + + errno = 0; + FILE *stream = fopen(argv[1], "r"); + if (stream == NULL) { + fprintf(stderr, "error: %s\n", strerror(errno)); + return EXIT_FAILURE; + } // if + + GVA_String reference = gva_fasta_sequence_blob(gva_std_allocator, stream); + fclose(stream); + fprintf(stderr, "reference length: %zu\n", reference.len); + GVA_String observed = vcf2obs(reference, stdin); fasta_blob_write(stdout, observed); return EXIT_SUCCESS; From 3fa6f2f0bcb47ee1caa67e08d606ca5d81861a87 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Mon, 12 Jan 2026 13:43:03 +0100 Subject: [PATCH 450/704] Move up. --- src/main.c | 70 +++++++++++++++++++++++++++--------------------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/src/main.c b/src/main.c index 808d07f..385af8d 100644 --- a/src/main.c +++ b/src/main.c @@ -1092,6 +1092,41 @@ strrev(size_t const n, char str[static n]) } // strrev +GVA_String vcf2obs(GVA_String reference, FILE *stream) +{ + GVA_Variant * variants = NULL; + + size_t line_count = 0; + size_t dropped = 0; + static char line[LINE_SIZE] = {0}; + while (fgets(line, sizeof(line), stream) != NULL) { + size_t const len = strlen(line) - 1; + GVA_Variant variant; + if (gva_parse_spdi(len, line, &variant) == 0) { + fprintf(stderr, "error: SPDI parsing failed at line %zu: %s", line_count + 1, line); + continue; + } // if + + GVA_Variant trimmed = prefix_trimmed(reference.len, reference.str, variant); + + if (array_length(variants) > 0 && trimmed.start < variants[array_length(variants) - 1].end) { + //fprintf(stderr, "dropped: at line %zu: %s", line_count + 1, line); + dropped += 1; + continue; + } // if + + ARRAY_APPEND(gva_std_allocator, variants, gva_variant_dup(gva_std_allocator, trimmed)); + line_count += 1; + } // while + + fprintf(stderr, "===INPUT===\n"); + fprintf(stderr, "#variants: %zu\n", array_length(variants)); + fprintf(stderr, "#dropped: %zu\n", dropped); + + return gva_patch(gva_std_allocator, reference.len, reference.str, array_length(variants), variants); +} // vcf2obs + + //#define SMALL @@ -1385,41 +1420,6 @@ int make_ref_blob_main(int argc, char* argv[static argc + 1]) { } // make_ref_blob_main -GVA_String vcf2obs(GVA_String reference, FILE *stream) -{ - GVA_Variant * variants = NULL; - - size_t line_count = 0; - size_t dropped = 0; - static char line[LINE_SIZE] = {0}; - while (fgets(line, sizeof(line), stream) != NULL) { - size_t const len = strlen(line) - 1; - GVA_Variant variant; - if (gva_parse_spdi(len, line, &variant) == 0) { - fprintf(stderr, "error: SPDI parsing failed at line %zu: %s", line_count + 1, line); - continue; - } // if - - GVA_Variant trimmed = prefix_trimmed(reference.len, reference.str, variant); - - if (array_length(variants) > 0 && trimmed.start < variants[array_length(variants) - 1].end) { - //fprintf(stderr, "dropped: at line %zu: %s", line_count + 1, line); - dropped += 1; - continue; - } // if - - ARRAY_APPEND(gva_std_allocator, variants, gva_variant_dup(gva_std_allocator, trimmed)); - line_count += 1; - } // while - - fprintf(stderr, "===INPUT===\n"); - fprintf(stderr, "#variants: %zu\n", array_length(variants)); - fprintf(stderr, "#dropped: %zu\n", dropped); - - return gva_patch(gva_std_allocator, reference.len, reference.str, array_length(variants), variants); -} // vcf2obs - - int make_obs_blob_main(int argc, char* argv[static argc + 1]) { if (argc < 2) { fprintf(stderr, "usage: %s reference.blob\n", argv[0]); From 9f464eaf798be390a1294bc22755c1220adbef22 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Mon, 12 Jan 2026 14:23:44 +0100 Subject: [PATCH 451/704] Operate from "vcf". --- src/main.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/main.c b/src/main.c index 385af8d..99f2cf7 100644 --- a/src/main.c +++ b/src/main.c @@ -1092,7 +1092,7 @@ strrev(size_t const n, char str[static n]) } // strrev -GVA_String vcf2obs(GVA_String reference, FILE *stream) +GVA_String vcf2obs(GVA_Allocator const allocator, GVA_String reference, FILE *stream) { GVA_Variant * variants = NULL; @@ -1115,7 +1115,7 @@ GVA_String vcf2obs(GVA_String reference, FILE *stream) continue; } // if - ARRAY_APPEND(gva_std_allocator, variants, gva_variant_dup(gva_std_allocator, trimmed)); + ARRAY_APPEND(allocator, variants, gva_variant_dup(allocator, trimmed)); line_count += 1; } // while @@ -1123,7 +1123,7 @@ GVA_String vcf2obs(GVA_String reference, FILE *stream) fprintf(stderr, "#variants: %zu\n", array_length(variants)); fprintf(stderr, "#dropped: %zu\n", dropped); - return gva_patch(gva_std_allocator, reference.len, reference.str, array_length(variants), variants); + return gva_patch(allocator, reference.len, reference.str, array_length(variants), variants); } // vcf2obs @@ -1280,7 +1280,8 @@ wu_main(int argc, char* argv[static argc + 1]) return EXIT_FAILURE; } // if - GVA_String observed = gva_fasta_sequence_blob(gva_std_allocator, stream); + // GVA_String observed = gva_fasta_sequence_blob(gva_std_allocator, stream); // blob + GVA_String observed = vcf2obs(gva_std_allocator, reference, stream); // vcf fclose(stream); fprintf(stderr, "observed length: %zu\n", observed.len); @@ -1437,7 +1438,7 @@ int make_obs_blob_main(int argc, char* argv[static argc + 1]) { fclose(stream); fprintf(stderr, "reference length: %zu\n", reference.len); - GVA_String observed = vcf2obs(reference, stdin); + GVA_String observed = vcf2obs(gva_std_allocator, reference, stdin); fasta_blob_write(stdout, observed); return EXIT_SUCCESS; From b02b2d02cb03c22987ea5dc95c366425ddeadfe1 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Thu, 22 Jan 2026 08:39:18 +0100 Subject: [PATCH 452/704] Sequence blob for locals. --- src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.c b/src/main.c index 99f2cf7..00b26c8 100644 --- a/src/main.c +++ b/src/main.c @@ -980,7 +980,7 @@ locals_main(int argc, char* argv[static argc + 1]) } // if GVA_String reference = {0, NULL}; - reference = gva_fasta_sequence(gva_std_allocator, stream); + reference = gva_fasta_sequence_blob(gva_std_allocator, stream); fclose(stream); fprintf(stderr, "reference length: %zu\n", reference.len); From f3d40aae541029e98ddebcb84f0b68c8baf07f75 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Thu, 22 Jan 2026 08:42:19 +0100 Subject: [PATCH 453/704] New phase. --- src/main.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main.c b/src/main.c index 00b26c8..16a6088 100644 --- a/src/main.c +++ b/src/main.c @@ -1448,13 +1448,12 @@ int make_obs_blob_main(int argc, char* argv[static argc + 1]) { int main(int argc, char* argv[static argc + 1]) { - return wu_main(argc, argv); + // return wu_main(argc, argv); // return slice_blob_main(argc, argv); - // return dbsnp_main(argc, argv); // return fasta_blob_write(argc, argv); // return vcf_main(argc, argv); // return dbsnp_main(argc, argv); - // return locals_main(argc, argv); + return locals_main(argc, argv); // return extract_main(argc, argv); // return make_ref_blob_main(argc, argv); // return make_obs_blob_main(argc, argv); From 59d3a0cc786a0203924e0b19a88d8a563fcf53c9 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Thu, 22 Jan 2026 08:47:01 +0100 Subject: [PATCH 454/704] Reordered fields. --- src/main.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main.c b/src/main.c index 16a6088..2f0ff6c 100644 --- a/src/main.c +++ b/src/main.c @@ -1029,16 +1029,16 @@ locals_main(int argc, char* argv[static argc + 1]) { fgets(line, sizeof(line), stream); idx = 0; - size_t const distance = parse_number(line, &idx); - allele_distance += distance; - idx += 1; - int const len = (char*) memchr(line + idx, '\n', LINE_SIZE - idx) - (line + idx); + int const len = (char*) memchr(line + idx, ' ', LINE_SIZE - idx) - (line + idx); GVA_Variant variant; if (gva_parse_spdi(len, line + idx, &variant) == 0) { fprintf(stderr, "error: SPDI parsing failed at line %zu: %s", line_count + 1, line); continue; } // + idx += len + 1; + size_t const distance = parse_number(line, &idx); // fprintf(stderr, GVA_VARIANT_FMT " %zu\n", GVA_VARIANT_PRINT(variant), distance); + allele_distance += distance; gva_uint const inserted_idx = trie_insert(gva_std_allocator, &trie, variant.sequence.len, variant.sequence.str); gva_uint const tmp_idx = ARRAY_APPEND(gva_std_allocator, tree.nodes, From 8663c9df21297fdd2789ee35439e34a52bcae803 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Mon, 26 Jan 2026 12:52:22 +0100 Subject: [PATCH 455/704] WIP version that can query HLA to a chr6 1KG database. --- src/main.c | 401 +++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 358 insertions(+), 43 deletions(-) diff --git a/src/main.c b/src/main.c index 2f0ff6c..7eea408 100644 --- a/src/main.c +++ b/src/main.c @@ -30,7 +30,7 @@ #define LINE_SIZE 8194 -#define REFERENCE_ID "NC_000001.11" +#define REFERENCE_ID "NC_000006.12" void @@ -990,14 +990,14 @@ locals_main(int argc, char* argv[static argc + 1]) struct Node_Allele { - gva_uint node; - gva_uint allele; + gva_uint link; gva_uint next; }* node_allele_join = NULL; struct Allele { - gva_uint data; + gva_uint sample_id; gva_uint join_start; // offset into node_allele_join + gva_uint join_end; gva_uint distance; }* db_alleles = NULL; @@ -1006,73 +1006,388 @@ locals_main(int argc, char* argv[static argc + 1]) if (stream == NULL) { fprintf(stderr, "error: %s\n", strerror(errno)); + gva_string_destroy(gva_std_allocator, reference); return EXIT_FAILURE; } // if + Trie sample_trie = trie_init(); + static char line[LINE_SIZE] = {0}; size_t line_count = 0; - size_t parts = 0; + size_t prev_sample_id = -1; + size_t allele_idx = -1; while (fgets(line, sizeof(line), stream) != NULL) { - size_t idx = 0; - size_t data = parse_number(line, &idx); // glob index - idx += 1; // skip space or tab - size_t allele_entries = parse_number(line, &idx); - parts += allele_entries; + // label + size_t len = strcspn(line, "\t "); + if (len == 0) + { + fprintf(stderr, "error: parsing failed at line %zu: %s", line_count + 1, line); + continue; + } + size_t const sample_id = trie_insert(gva_std_allocator, &sample_trie, len, line); - size_t const allele_idx = ARRAY_APPEND(gva_std_allocator, db_alleles, ((struct Allele) {data, array_length(node_allele_join), 0})) - 1; - fprintf(stderr, "allele: %zu (%zu) length: %zu\n", data, allele_idx, allele_entries); + // variant + size_t idx = len + 1; + len = strcspn(line + idx, "\t "); + GVA_Variant variant; + if (gva_parse_spdi(len, line + idx, &variant) == 0) + { + fprintf(stderr, "error: SPDI parsing failed at line %zu: %s", line_count + 1, line); + continue; + } // - size_t allele_distance = 0; - line_count += 1; - for (size_t i = 0; i < allele_entries; ++i) + // distance + idx += len + 1; + size_t distance = parse_number(line, &idx); + if (distance == 0) { - fgets(line, sizeof(line), stream); - idx = 0; - int const len = (char*) memchr(line + idx, ' ', LINE_SIZE - idx) - (line + idx); - GVA_Variant variant; - if (gva_parse_spdi(len, line + idx, &variant) == 0) { - fprintf(stderr, "error: SPDI parsing failed at line %zu: %s", line_count + 1, line); - continue; - } // - idx += len + 1; - size_t const distance = parse_number(line, &idx); - // fprintf(stderr, GVA_VARIANT_FMT " %zu\n", GVA_VARIANT_PRINT(variant), distance); - allele_distance += distance; - - gva_uint const inserted_idx = trie_insert(gva_std_allocator, &trie, variant.sequence.len, variant.sequence.str); - gva_uint const tmp_idx = ARRAY_APPEND(gva_std_allocator, tree.nodes, - ((Interval_Tree_Node) {{GVA_NULL, GVA_NULL}, - variant.start, variant.end, variant.end, 0, inserted_idx, GVA_NULL, distance})) - 1; - gva_uint const node_idx = interval_tree_insert(&tree, tmp_idx); - if (node_idx != tmp_idx) + fprintf(stderr, "error: parsing failed at line %zu: %s", line_count + 1, line); + continue; + } + + // new sample + if (sample_id != prev_sample_id) + { + allele_idx = ARRAY_APPEND(gva_std_allocator, db_alleles, ((struct Allele) {sample_id, array_length(node_allele_join), 0, 0})) - 1; + if (allele_idx > 0) { - array_header(tree.nodes)->length -= 1; // reverse; node already in the tree - } // if - tree.nodes[node_idx].alleles = ARRAY_APPEND(gva_std_allocator, node_allele_join, ((struct Node_Allele) {node_idx, allele_idx, tree.nodes[node_idx].alleles})) - 1; + db_alleles[allele_idx - 1].join_end = array_length(node_allele_join); + } + + fprintf(stderr, "allele: %zu (" GVA_STRING_FMT ") (%zu)\n", sample_id, GVA_STRING_PRINT(trie_string(sample_trie, sample_id)), allele_idx); + prev_sample_id = sample_id; + } + // fprintf(stderr, "%zu " GVA_VARIANT_FMT " %zu\n", sample_id, GVA_VARIANT_PRINT(variant), distance); + db_alleles[allele_idx].distance += distance; + + gva_uint const inserted_idx = trie_insert(gva_std_allocator, &trie, variant.sequence.len, variant.sequence.str); + gva_uint const tmp_idx = ARRAY_APPEND(gva_std_allocator, tree.nodes, + ((Interval_Tree_Node) {{GVA_NULL, GVA_NULL}, + variant.start, variant.end, variant.end, 0, inserted_idx, GVA_NULL, distance})) - 1; + gva_uint const node_idx = interval_tree_insert(&tree, tmp_idx); + if (node_idx != tmp_idx) + { + array_header(tree.nodes)->length -= 1; // reverse; node already in the tree + } // if + tree.nodes[node_idx].alleles = ARRAY_APPEND(gva_std_allocator, node_allele_join, ((struct Node_Allele) {node_idx ^ allele_idx, tree.nodes[node_idx].alleles})) - 1; - line_count += 1; - } // for + line_count += 1; } // while + if (array_length(db_alleles) > 0) + { + db_alleles[array_length(db_alleles) - 1].join_end = array_length(node_allele_join); + } + fclose(stream); fprintf(stderr, "line count: %zu\n", line_count); - - fprintf(stderr, "parts: %zu\n", parts); fprintf(stderr, "tree nodes: %zu\n", array_length(tree.nodes)); - fprintf(stderr, "trie nodes: %zu (%zu)\n", array_length(trie.nodes), trie.strings.len); + fprintf(stderr, "sequence trie nodes: %zu (%zu)\n", array_length(trie.nodes), trie.strings.len); + fprintf(stderr, "sample trie nodes: %zu (%zu)\n", array_length(sample_trie.nodes), sample_trie.strings.len); fprintf(stderr, "#db_alleles: %zu\n", array_length(db_alleles)); fprintf(stderr, "#join: %zu\n", array_length(node_allele_join)); + for (size_t i = 0; i < array_length(db_alleles); ++i) + { + fprintf(stderr, "allele: %u (" GVA_STRING_FMT ") (%zu) dist: %u (%u - %u)\n", + db_alleles[i].sample_id, + GVA_STRING_PRINT(trie_string(sample_trie, db_alleles[i].sample_id)), + i, + db_alleles[i].distance, + db_alleles[i].join_start, + db_alleles[i].join_end); + } + + Trie query_trie = trie_init(); + + // for every query + line_count = 0; + while (fgets(line, sizeof(line), stdin) != NULL) { + // label + size_t len = strcspn(line, "\t "); + if (len == 0) + { + fprintf(stderr, "error: parsing failed at line %zu: %s", line_count + 1, line); + continue; + } + size_t const query_id = trie_insert(gva_std_allocator, &query_trie, len, line); + + // variant + size_t idx = len + 1; + len = strcspn(line + idx, "\n"); + GVA_Variant rhs_var; + if (gva_parse_spdi(len, line + idx, &rhs_var) == 0) + { + fprintf(stderr, "error: SPDI parsing failed at line %zu: %s", line_count + 1, line); + continue; + } // + + GVA_LCS_Graph const rhs_graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &rhs_var); + // fprintf(stderr, GVA_VARIANT_FMT " (%u) \n", GVA_VARIANT_PRINT(rhs_var), rhs_graph.distance); + + // Join nodes in the index to parts in the query + struct NODE_PARTS + { + HASH_TABLE_KEY; + GVA_Relation relation; + gva_uint start; + gva_uint end; + gva_uint included; + }* node_parts_table = hash_table_init(gva_std_allocator, 1024, sizeof(*node_parts_table)); + + for (size_t part_idx = 0; part_idx < array_length(rhs_graph.local_supremal) - 1; ++part_idx) + { + GVA_Variant rhs_part; + gva_edges(rhs_graph.observed.str, + rhs_graph.local_supremal[part_idx], rhs_graph.local_supremal[part_idx + 1], + part_idx == 0, part_idx == array_length(rhs_graph.local_supremal) - 2, + &rhs_part); + gva_uint const rhs_distance = rhs_graph.local_supremal[part_idx + 1].distance; + + gva_uint* candidates = interval_tree_intersection(gva_std_allocator, tree, rhs_part.start, rhs_part.end); + for (size_t can_idx = 0; can_idx < array_length(candidates); ++can_idx) + { + gva_uint const node_idx = candidates[can_idx]; + GVA_Variant const db_var = {tree.nodes[node_idx].start, tree.nodes[node_idx].end, + trie_string(trie, tree.nodes[node_idx].inserted)}; + GVA_Relation const relation = compare_from_index(reference, db_var, tree.nodes[node_idx].distance, rhs_part, rhs_distance); + if (relation == GVA_DISJOINT) + { + continue; + } // if + fprintf(stderr, "%zu " GVA_VARIANT_FMT_SPDI " %s " GVA_VARIANT_FMT_SPDI "\n", line_count, + GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, db_var), + GVA_RELATION_LABELS[relation], + GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, rhs_part)); + + // link nodes to query parts + size_t hash_idx = HASH_TABLE_INDEX(node_parts_table, node_idx); + if (node_parts_table[hash_idx].gva_key != node_idx) + { + HASH_TABLE_SET(gva_std_allocator, node_parts_table, node_idx, + ((struct NODE_PARTS) {node_idx, relation, part_idx, part_idx + 1, rhs_distance})); + hash_idx = HASH_TABLE_INDEX(node_parts_table, node_idx); + } // if + + if (relation == GVA_EQUIVALENT || relation == GVA_IS_CONTAINED) + { + node_parts_table[hash_idx].included = tree.nodes[node_idx].distance; + } // if + else if (relation == GVA_CONTAINS) + { + node_parts_table[hash_idx].end = part_idx + 1; + } // if + else // GVA_OVERLAP + { + node_parts_table[hash_idx].included = 1; + } // else + } // for every candidate + candidates = ARRAY_DESTROY(gva_std_allocator, candidates); + } // for query allele parts + + // We have now compared all query parts to the index + + // fix containment for multiple parts in single node for every query + for (size_t npt_index = 0; npt_index < array_header(node_parts_table)->capacity; ++npt_index) + { + size_t const node_idx = node_parts_table[npt_index].gva_key; + if (node_idx == GVA_NOT_FOUND) + { + continue; + } // if + + if (node_parts_table[npt_index].relation == GVA_CONTAINS && + node_parts_table[npt_index].end - node_parts_table[npt_index].start > 1) + { + size_t const lhs_distance = tree.nodes[node_idx].distance; + size_t rhs_distance = 0; + for (size_t i = node_parts_table[npt_index].start; i < node_parts_table[npt_index].end; ++i) + { + rhs_distance += rhs_graph.local_supremal[i + 1].distance; + } // for + if (rhs_distance >= lhs_distance) + { + node_parts_table[npt_index].included = 1; + node_parts_table[npt_index].relation = GVA_OVERLAP; + continue; + } // if + + GVA_Variant const lhs = {tree.nodes[node_idx].start, + tree.nodes[node_idx].end, + trie_string(trie, tree.nodes[node_idx].inserted)}; + + GVA_Variant rhs; + gva_edges(rhs_graph.observed.str, + rhs_graph.local_supremal[node_parts_table[npt_index].start], + rhs_graph.local_supremal[node_parts_table[npt_index].end], + node_parts_table[npt_index].start == 0, + node_parts_table[npt_index].end == array_length(rhs_graph.local_supremal) - 1, + &rhs); + + size_t const distance = variants_distance(gva_std_allocator, reference.len, reference.str, lhs, rhs); + if (lhs_distance - distance == rhs_distance) + { + node_parts_table[npt_index].included = rhs_distance; + } // if + else + { + node_parts_table[npt_index].included = 1; + node_parts_table[npt_index].relation = GVA_OVERLAP; + } // if + } // if + } // for node_parts_table + + struct RESULT_ALLELES + { + HASH_TABLE_KEY; + }* results_table = hash_table_init(gva_std_allocator, 1024, sizeof(*results_table)); + + // find all alleles that were part of a non-disjoint relation + for (size_t npt_idx = 0; npt_idx < array_header(node_parts_table)->capacity; ++npt_idx) + { + size_t const node_idx = node_parts_table[npt_idx].gva_key; + if (node_idx == GVA_NOT_FOUND) + { + continue; + } // if + + for (size_t naj_table_idx = tree.nodes[node_idx].alleles; + naj_table_idx != GVA_NULL; + naj_table_idx = node_allele_join[naj_table_idx].next) + { + size_t const allele_idx = node_allele_join[naj_table_idx].link ^ node_idx; + HASH_TABLE_SET(gva_std_allocator, results_table, allele_idx, ((struct RESULT_ALLELES) {allele_idx})); + } // for alleles + } // for node_parts_table + + // build result vector for every query + for (size_t results_idx = 0; results_idx < array_header(results_table)->capacity; ++results_idx) + { + size_t allele_idx = results_table[results_idx].gva_key; + if (allele_idx == GVA_NOT_FOUND) + { + continue; + } // if + + gva_uint included = 0; + GVA_Relation relation = GVA_DISJOINT; + + gva_uint* is_contained_nodes = NULL; + gva_uint is_contained_part_idx = -1; + + // loop over all nodes for this allele + for (size_t join_idx = db_alleles[allele_idx].join_start; join_idx < db_alleles[allele_idx].join_end; ++join_idx) + { + size_t node_idx = node_allele_join[join_idx].link ^ allele_idx; + size_t const hash_idx = HASH_TABLE_INDEX(node_parts_table, node_idx); + if (node_idx != node_parts_table[hash_idx].gva_key) + { + continue; + } // if + + if (node_parts_table[hash_idx].relation == GVA_EQUIVALENT) + { + included += node_parts_table[hash_idx].included; + if (relation == GVA_EQUIVALENT || relation == GVA_DISJOINT) + { + relation = GVA_EQUIVALENT; + } // if + } // if + else if (node_parts_table[hash_idx].relation == GVA_CONTAINS) + { + included += node_parts_table[hash_idx].included; + if (relation == GVA_IS_CONTAINED) + { + relation = GVA_OVERLAP; // TODO: included = 1; ??? + break; + } // if + relation = GVA_CONTAINS; + } // if + else if (node_parts_table[hash_idx].relation == GVA_IS_CONTAINED) + { + size_t const part_idx = node_parts_table[hash_idx].start; + if (relation == GVA_CONTAINS) + { + included += node_parts_table[hash_idx].included; // TODO: included = 1; ??? + relation = GVA_OVERLAP; + break; + } // if + + if (part_idx != is_contained_part_idx) + { + repair_is_contained(gva_std_allocator, reference, rhs_graph, tree, trie, + &is_contained_nodes, is_contained_part_idx, &included, &relation); + is_contained_part_idx = part_idx; + } // if + ARRAY_APPEND(gva_std_allocator, is_contained_nodes, node_idx); + relation = GVA_IS_CONTAINED; + } // if + else if (node_parts_table[hash_idx].relation == GVA_OVERLAP) + { + included = 1; + relation = GVA_OVERLAP; + break; + } // if + } // for all nodes for this allele + repair_is_contained(gva_std_allocator, reference, rhs_graph, tree, trie, + &is_contained_nodes, is_contained_part_idx, &included, &relation); + + if (included > 0) + { + gva_uint const lhs_excluded = db_alleles[allele_idx].distance - included; + gva_uint const rhs_excluded = rhs_graph.distance - included; + + if (lhs_excluded > 0 && rhs_excluded > 0) + { + relation = GVA_OVERLAP; + } // if + else if (lhs_excluded > 0) + { + relation = GVA_CONTAINS; + } // if + else if (rhs_excluded > 0) + { + relation = GVA_IS_CONTAINED; + } // if + else // if (lhs_excluded == 0 && rhs_excluded == 0) + { + relation = GVA_EQUIVALENT; + } // else + + // only for testing + // if (relation != GVA_EQUIVALENT || db_alleles[allele_idx].line < line_count) + // if (relation != GVA_OVERLAP) + { + fprintf(stderr, GVA_STRING_FMT " %s " GVA_STRING_FMT " %u %u %u\n", + GVA_STRING_PRINT(trie_string(sample_trie, db_alleles[allele_idx].sample_id)), + GVA_RELATION_LABELS[relation], + GVA_STRING_PRINT(trie_string(query_trie, query_id)), + included, lhs_excluded, rhs_excluded + ); + } // if + } // if + } // for all alleles + + results_table = HASH_TABLE_DESTROY(gva_std_allocator, results_table); + + node_parts_table = HASH_TABLE_DESTROY(gva_std_allocator, node_parts_table); + + gva_string_destroy(gva_std_allocator, rhs_graph.observed); + gva_lcs_graph_destroy(gva_std_allocator, rhs_graph); + line_count++; + } // while query db_alleles = ARRAY_DESTROY(gva_std_allocator, db_alleles); node_allele_join = ARRAY_DESTROY(gva_std_allocator, node_allele_join); interval_tree_destroy(gva_std_allocator, &tree); + trie_destroy(gva_std_allocator, &query_trie); + trie_destroy(gva_std_allocator, &sample_trie); trie_destroy(gva_std_allocator, &trie); gva_string_destroy(gva_std_allocator, reference); return EXIT_SUCCESS; -} // dbsnp_main +} // locals_main static char* From 43f3ba3cfef9e1bea0cf1469943c8e9151732b40 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Mon, 2 Feb 2026 09:50:49 +0100 Subject: [PATCH 456/704] Snapshot before local supremal distance overhaul. --- include/lcs_graph.h | 8 +- src/lcs_graph.c | 243 +++++++++++++++++++++++++++++++------------- src/main.c | 134 ++++++++++++------------ 3 files changed, 249 insertions(+), 136 deletions(-) diff --git a/include/lcs_graph.h b/include/lcs_graph.h index 4ff4da8..9e0396f 100644 --- a/include/lcs_graph.h +++ b/include/lcs_graph.h @@ -35,7 +35,11 @@ typedef struct gva_uint edges; gva_uint distance; }; - gva_uint lambda; + union + { + gva_uint lambda; + gva_uint link; + }; } GVA_Node; @@ -45,7 +49,7 @@ typedef struct { GVA_Node* nodes; GVA_Edge* edges; - GVA_Node* local_supremal; + GVA_Node* dom_nodes; GVA_Variant supremal; GVA_String observed; // FIXME: ownership and destroy gva_uint source; diff --git a/src/lcs_graph.c b/src/lcs_graph.c index 82d478d..f479082 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -11,6 +11,8 @@ #include "array.h" // ARRAY_*, array_length #include "common.h" // GVA_NULL, MAX, MIN, gva_uint +#include +#include GVA_LCS_Graph gva_lcs_graph_init(GVA_Allocator const allocator, @@ -20,69 +22,117 @@ gva_lcs_graph_init(GVA_Allocator const allocator, { LCS_Alignment lcs = lcs_align(allocator, len_ref, reference, len_obs, observed, shift); - GVA_LCS_Graph graph = {NULL, NULL, NULL, {0, 0, {0, observed}}, {len_obs, observed}, GVA_NULL, len_ref + len_obs - 2 * lcs.length}; + GVA_LCS_Graph graph = + { + .nodes = NULL, + .edges = NULL, + .dom_nodes = NULL, + .supremal = {0, 0, {0, observed}}, + .observed = {len_obs, observed}, + .source = GVA_NULL, + .distance = len_ref + len_obs - 2 * lcs.length + }; + // no matches or ref == obs if (lcs.nodes == NULL || graph.distance == 0) { - gva_uint const sink = ARRAY_APPEND(allocator, graph.nodes, ((GVA_Node) { - len_ref + shift, len_obs, 0, {GVA_NULL}, GVA_NULL - })) - 1; - if ((len_ref == 0 && len_obs == 0) || graph.distance == 0) + // create sink + gva_uint const sink = ARRAY_APPEND(allocator, graph.nodes, + ((GVA_Node) + { + .row = len_ref + shift, + .col = len_obs, + .length = 0, + .edges = GVA_NULL, + .lambda = GVA_NULL + }) + ) - 1; + + if (graph.distance == 0) { graph.source = sink; graph.nodes[sink].row = 0; graph.nodes[sink].col = 0; - graph.nodes[sink].length = 0; - ARRAY_APPEND(allocator, graph.local_supremal, ((GVA_Node) { - shift, 0, 0, {GVA_NULL}, graph.source - })); + ARRAY_APPEND(allocator, graph.dom_nodes, ((GVA_Node) {.link = graph.source})); lcs.index = allocator.allocate(allocator.context, lcs.index, lcs.length * sizeof(*lcs.index), 0); lcs.nodes = ARRAY_DESTROY(allocator, lcs.nodes); return graph; } // if - graph.source = ARRAY_APPEND(allocator, graph.nodes, ((GVA_Node) { - shift, 0, 0, - {ARRAY_APPEND(allocator, graph.edges, ((GVA_Edge) {sink, GVA_NULL})) - 1}, - GVA_NULL - })) - 1; - - ARRAY_APPEND(allocator, graph.local_supremal, ((GVA_Node) { - shift, 0, 0, {0}, GVA_NULL - })); - ARRAY_APPEND(allocator, graph.local_supremal, ((GVA_Node) { - len_ref + shift, len_obs, 0, {graph.distance}, GVA_NULL - })); + graph.source = ARRAY_APPEND(allocator, graph.nodes, + ((GVA_Node) + { + .row = shift, + .col = 0, + .length = 0, + .edges = ARRAY_APPEND(allocator, graph.edges, ((GVA_Edge) {sink, GVA_NULL})) - 1, + .lambda = GVA_NULL + })) - 1; + + ARRAY_APPEND(allocator, graph.dom_nodes, + ((GVA_Node) + { + .row = shift, + .col = 0, + .length = 0, + .distance = 0, + .link = graph.source + })); + ARRAY_APPEND(allocator, graph.dom_nodes, + ((GVA_Node) + { + .row = len_ref + shift, + .col = len_obs, + .length = 0, + .distance = graph.distance, + .link = sink + })); graph.supremal = (GVA_Variant) {shift, len_ref + shift, {len_obs, observed}}; return graph; - } // if + } // if (no matches) gva_uint tail_idx = lcs.index[lcs.length - 1].tail; LCS_Node sink = lcs.nodes[tail_idx]; if (sink.row + sink.length == len_ref + shift && sink.col + sink.length == len_obs) { - lcs.nodes[tail_idx].idx = ARRAY_APPEND(allocator, graph.nodes, ((GVA_Node) { - sink.row, sink.col, sink.length, {GVA_NULL}, GVA_NULL - })) - 1; + lcs.nodes[tail_idx].idx = ARRAY_APPEND(allocator, graph.nodes, + ((GVA_Node) + { + .row = sink.row, + .col = sink.col, + .length = sink.length, + .edges = GVA_NULL, + .lambda = GVA_NULL + })) - 1; lcs.nodes[tail_idx].moved = true; sink = lcs.nodes[tail_idx]; } // if else { sink = (LCS_Node) {.row = len_ref + shift, .col = len_obs, .length = 0}; - sink.idx = ARRAY_APPEND(allocator, graph.nodes, ((GVA_Node) { - sink.row, sink.col, sink.length, {GVA_NULL}, GVA_NULL - })) - 1; + sink.idx = ARRAY_APPEND(allocator, graph.nodes, + ((GVA_Node) + { + .row = sink.row, + .col = sink.col, + .length = sink.length, + .edges = GVA_NULL, + .lambda = GVA_NULL + })) - 1; tail_idx = GVA_NULL; } // else for (gva_uint i = lcs.index[lcs.length - 1].head; i != tail_idx; i = lcs.nodes[i].next) { - lcs.nodes[i].idx = ARRAY_APPEND(allocator, graph.nodes, ((GVA_Node) { - lcs.nodes[i].row, lcs.nodes[i].col, lcs.nodes[i].length, - {ARRAY_APPEND(allocator, graph.edges, ((GVA_Edge) {sink.idx, GVA_NULL})) - 1}, - GVA_NULL - })) - 1; + lcs.nodes[i].idx = ARRAY_APPEND(allocator, graph.nodes, + ((GVA_Node) + { + .row = lcs.nodes[i].row, + .col = lcs.nodes[i].col, + .length = lcs.nodes[i].length, + .edges = ARRAY_APPEND(allocator, graph.edges, ((GVA_Edge) {sink.idx, GVA_NULL})) - 1, + .lambda = GVA_NULL + })) - 1; } // for for (gva_uint i = lcs.length - 1; i >= 1; --i) @@ -117,11 +167,15 @@ gva_lcs_graph_init(GVA_Allocator const allocator, if (head->incoming == i) { gva_uint const split_idx = head->idx; - head->idx = ARRAY_APPEND(allocator, graph.nodes, ((GVA_Node) { - head->row, head->col, head->length, - {ARRAY_APPEND(allocator, graph.edges, ((GVA_Edge) {tail->idx, GVA_NULL})) - 1}, - split_idx - })) - 1; + head->idx = ARRAY_APPEND(allocator, graph.nodes, + ((GVA_Node) + { + .row = head->row, + .col = head->col, + .length = head->length, + .edges = ARRAY_APPEND(allocator, graph.edges, ((GVA_Edge) {tail->idx, GVA_NULL})) - 1, + .lambda = split_idx + })) - 1; head->moved = false; head->incoming = 0; @@ -131,11 +185,15 @@ gva_lcs_graph_init(GVA_Allocator const allocator, } // if else if (head->idx == GVA_NULL) { - head->idx = ARRAY_APPEND(allocator, graph.nodes, ((GVA_Node) { - head->row, head->col, head->length, - {ARRAY_APPEND(allocator, graph.edges, ((GVA_Edge) {tail->idx, GVA_NULL})) - 1}, - GVA_NULL - })) - 1; + head->idx = ARRAY_APPEND(allocator, graph.nodes, + ((GVA_Node) + { + .row = head->row, + .col = head->col, + .length = head->length, + .edges = ARRAY_APPEND(allocator, graph.edges, ((GVA_Edge) {tail->idx, GVA_NULL})) - 1, + .lambda = GVA_NULL + })) - 1; } // if else if (!head->moved || !tail->moved) { @@ -177,9 +235,15 @@ gva_lcs_graph_init(GVA_Allocator const allocator, else { source = (LCS_Node) {.row = shift, .col = 0, .length = 0}; - source.idx = ARRAY_APPEND(allocator, graph.nodes, ((GVA_Node) { - source.row, source.col, source.length, {GVA_NULL}, GVA_NULL - })) - 1; + source.idx = ARRAY_APPEND(allocator, graph.nodes, + ((GVA_Node) + { + .row = source.row, + .col = source.col, + .length = source.length, + .edges = GVA_NULL, + .lambda = GVA_NULL + })) - 1; } // else for (gva_uint i = head_idx; i != GVA_NULL; i = lcs.nodes[i].next) { @@ -200,6 +264,10 @@ gva_lcs_graph_init(GVA_Allocator const allocator, } // if } // for + + // start constructing the local supremal + + fprintf(stderr, "shift: %zu\n", shift); gva_uint len = 0; gva_uint prev = GVA_NULL; gva_uint prev_distance = 0; @@ -207,20 +275,34 @@ gva_lcs_graph_init(GVA_Allocator const allocator, { if (prev == GVA_NULL && lcs.nodes[lcs.index[i].tail].idx != source.idx) { - gva_uint const distance = graph.nodes[source.idx].row + graph.nodes[source.idx].col - 2 * i; - ARRAY_APPEND(allocator, graph.local_supremal, ((GVA_Node) { - graph.nodes[source.idx].row, graph.nodes[source.idx].col, 0, {distance - prev_distance}, source.idx - })); - prev_distance = distance; + ARRAY_APPEND(allocator, graph.dom_nodes, + ((GVA_Node) + { + .row = graph.nodes[source.idx].row, + .col = graph.nodes[source.idx].col, + .length = 0, + .distance = 0, + .link = source.idx + })); + prev_distance = 0; } // if if (len > 0 && (lcs.index[i].count > 1 || prev != lcs.index[i].tail)) { gva_uint const idx = lcs.nodes[prev].idx; gva_uint const offset = graph.nodes[idx].length - lcs.index[i - 1].offset - len; gva_uint const distance = graph.nodes[idx].row + graph.nodes[idx].col + 2 * offset + 2 * len - 2 * i; - ARRAY_APPEND(allocator, graph.local_supremal, ((GVA_Node) { - graph.nodes[idx].row + offset, graph.nodes[idx].col + offset, len, {distance - prev_distance}, idx - })); + fprintf(stderr, "B distance: %u\n", distance); + fprintf(stderr, "B prev_distance: %u\n", prev_distance); + fprintf(stderr, "B dist - prev: %u\n", distance - prev_distance); + ARRAY_APPEND(allocator, graph.dom_nodes, + ((GVA_Node) + { + .row = graph.nodes[idx].row + offset, + .col = graph.nodes[idx].col + offset, + .length = len, + .distance = distance - prev_distance, + .link = idx + })); len = 0; prev_distance = distance; } // if @@ -236,31 +318,56 @@ gva_lcs_graph_init(GVA_Allocator const allocator, { gva_uint const idx = lcs.nodes[prev].idx; gva_uint const offset = graph.nodes[idx].length - lcs.index[lcs.length - 1].offset - len; - gva_uint const distance = graph.nodes[idx].row + graph.nodes[idx].col + 2 * offset + 2 * len - 2 * lcs.length; - ARRAY_APPEND(allocator, graph.local_supremal, ((GVA_Node) { - graph.nodes[idx].row + offset, graph.nodes[idx].col + offset, len, {distance - prev_distance}, idx - })); + fprintf(stderr, "offset: %u\n", offset); + gva_uint const distance = graph.nodes[idx].row - shift + graph.nodes[idx].col + 2 * offset + 2 * len - 2 * (lcs.length ); + fprintf(stderr, "C distance: %u\n", distance); + ARRAY_APPEND(allocator, graph.dom_nodes, + ((GVA_Node) + { + .row = graph.nodes[idx].row + offset, + .col = graph.nodes[idx].col + offset, + .length = len, + .distance = distance - prev_distance, + .link = idx + })); len = 0; prev_distance = distance; } // if if (graph.nodes != NULL) { - gva_uint const distance = graph.nodes[0].row + graph.nodes[0].length - len + graph.nodes[0].col + graph.nodes[0].length - len - 2 * lcs.length; - ARRAY_APPEND(allocator, graph.local_supremal, ((GVA_Node) { - graph.nodes[0].row + graph.nodes[0].length - len, graph.nodes[0].col + graph.nodes[0].length - len, 0, {distance - prev_distance}, 0 - })); + assert(len == 0); + fprintf(stderr, "row: %u col: %u shift: %zu, length: %u len: %u\n", + graph.nodes[0].row, graph.nodes[0].col, shift, graph.nodes[0].length, len); + gva_uint const distance = graph.nodes[0].row - shift + + graph.nodes[0].col + + 2 * (graph.nodes[0].length - len) + // + graph.nodes[0].length - len + - 2 * lcs.length; + fprintf(stderr, "D distance: %u\n", distance); + fprintf(stderr, "D prev_distance: %u\n", prev_distance); + fprintf(stderr, "D dist - prev: %u\n", distance - prev_distance); + ARRAY_APPEND(allocator, graph.dom_nodes, + ((GVA_Node) + { + .row = graph.nodes[0].row + graph.nodes[0].length - len, + .col = graph.nodes[0].col + graph.nodes[0].length - len, + .length = 0, + .distance = distance - prev_distance, + .link = 0 + })); } //if - if (graph.local_supremal != NULL) + // construct supremal + if (graph.dom_nodes != NULL) { - graph.nodes[source.idx].row += graph.local_supremal[0].length; - graph.nodes[source.idx].col += graph.local_supremal[0].length; - graph.nodes[source.idx].length -= graph.local_supremal[0].length; + graph.nodes[source.idx].row += graph.dom_nodes[0].length; + graph.nodes[source.idx].col += graph.dom_nodes[0].length; + graph.nodes[source.idx].length -= graph.dom_nodes[0].length; graph.nodes[0].length -= len; gva_edges(graph.observed.str, - graph.local_supremal[0], graph.local_supremal[array_length(graph.local_supremal) - 1], + graph.dom_nodes[0], graph.dom_nodes[array_length(graph.dom_nodes) - 1], true, true, &graph.supremal); } // if @@ -278,7 +385,7 @@ gva_lcs_graph_destroy(GVA_Allocator const allocator, GVA_LCS_Graph self) { self.nodes = ARRAY_DESTROY(allocator, self.nodes); self.edges = ARRAY_DESTROY(allocator, self.edges); - self.local_supremal = ARRAY_DESTROY(allocator, self.local_supremal); + self.dom_nodes = ARRAY_DESTROY(allocator, self.dom_nodes); // FIXME: ownership of observed } // gva_lcs_graph_destroy diff --git a/src/main.c b/src/main.c index 7eea408..49a9094 100644 --- a/src/main.c +++ b/src/main.c @@ -30,7 +30,8 @@ #define LINE_SIZE 8194 -#define REFERENCE_ID "NC_000006.12" +// #define REFERENCE_ID "NC_000006.12" +#define REFERENCE_ID "NC_000001.11" void @@ -61,9 +62,9 @@ lcs_graph_dot(FILE* const stream, GVA_LCS_Graph const graph) } // else } // for } // for - for (size_t i = 0; i < array_length(graph.local_supremal); ++i) + for (size_t i = 0; i < array_length(graph.dom_nodes); ++i) { - fprintf(stream, "%u[penwidth=2]\n", graph.local_supremal[i].lambda); + fprintf(stream, "%u[penwidth=2]\n", graph.dom_nodes[i].link); } // for fprintf(stream, "}\n"); } // lcs_graph_dot @@ -140,6 +141,10 @@ compare_from_index(GVA_String const reference, { // TODO: possibly reuse rhs_graph + fprintf(stderr, GVA_VARIANT_FMT_SPDI " " GVA_VARIANT_FMT_SPDI "\n", + GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, lhs), + GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, rhs)); + if (gva_variant_eq(lhs, rhs)) { return GVA_EQUIVALENT; @@ -147,9 +152,11 @@ compare_from_index(GVA_String const reference, size_t const start = MIN(lhs.start, rhs.start); size_t const end = MAX(lhs.end, rhs.end); + fprintf(stderr, "start: %zu end: %zu\n", start, end); size_t const lhs_len = (lhs.start - start) + lhs.sequence.len + (end - lhs.end); size_t const rhs_len = (rhs.start - start) + rhs.sequence.len + (end - rhs.end); + fprintf(stderr, "lhs_len: %zu rhs_len: %zu\n", lhs_len, rhs_len); gva_uint distance = 0; if (lhs_len == 0) @@ -186,6 +193,8 @@ compare_from_index(GVA_String const reference, lhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, lhs_obs, lhs_len, 0); } // else + fprintf(stderr, "distance: %u lhs_distance: %u rhs_distance: %u\n", distance, lhs_distance, rhs_distance); + if (lhs_distance + rhs_distance == distance) { return GVA_DISJOINT; @@ -193,6 +202,7 @@ compare_from_index(GVA_String const reference, if (lhs_distance - rhs_distance == distance) { + fprintf(stderr, "this return?!\n"); return GVA_CONTAINS; } // if @@ -345,7 +355,7 @@ multiple_is_contained_distance(GVA_Allocator const allocator, lhs_distance += tree.nodes[nodes[i]].distance; } // for - size_t const rhs_distance = graph.local_supremal[part_idx + 1].distance; + size_t const rhs_distance = graph.dom_nodes[part_idx + 1].distance; if (lhs_distance >= rhs_distance) { return 1; // overlap @@ -355,8 +365,8 @@ multiple_is_contained_distance(GVA_Allocator const allocator, GVA_Variant rhs; gva_edges(graph.observed.str, - graph.local_supremal[part_idx], graph.local_supremal[part_idx + 1], - part_idx == 0, part_idx == array_length(graph.local_supremal) - 2, + graph.dom_nodes[part_idx], graph.dom_nodes[part_idx + 1], + part_idx == 0, part_idx == array_length(graph.dom_nodes) - 2, &rhs); size_t const distance = variants_distance(allocator, len_ref, reference, rhs, lhs); @@ -470,14 +480,14 @@ int vcf_main(int argc, char* argv[static argc + 1]) { GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, array_length(variants) - last, variants + last); - for (size_t i = 0; i < array_length(graph.local_supremal) - 1; ++i) + for (size_t i = 0; i < array_length(graph.dom_nodes) - 1; ++i) { GVA_Variant variant; gva_edges(graph.observed.str, - graph.local_supremal[i], graph.local_supremal[i + 1], - i == 0, i == array_length(graph.local_supremal) - 2, &variant); - //fprintf(stdout, "%u " GVA_VARIANT_FMT_SPDI "\n", graph.local_supremal[i + 1].distance, GVA_VARIANT_PRINT_SPDI("NC_000001.11", variant)); - distance += graph.local_supremal[i + 1].distance; + graph.dom_nodes[i], graph.dom_nodes[i + 1], + i == 0, i == array_length(graph.dom_nodes) - 2, &variant); + //fprintf(stdout, "%u " GVA_VARIANT_FMT_SPDI "\n", graph.dom_nodes[i + 1].distance, GVA_VARIANT_PRINT_SPDI("NC_000001.11", variant)); + distance += graph.dom_nodes[i + 1].distance; ARRAY_APPEND(gva_std_allocator, lss, gva_variant_dup(gva_std_allocator, variant)); } // for @@ -494,14 +504,14 @@ int vcf_main(int argc, char* argv[static argc + 1]) { GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, array_length(variants) - last, variants + last); - for (size_t i = 0; i < array_length(graph.local_supremal) - 1; ++i) + for (size_t i = 0; i < array_length(graph.dom_nodes) - 1; ++i) { GVA_Variant variant; gva_edges(graph.observed.str, - graph.local_supremal[i], graph.local_supremal[i + 1], - i == 0, i == array_length(graph.local_supremal) - 2, &variant); - //fprintf(stdout, "%u " GVA_VARIANT_FMT_SPDI "\n", graph.local_supremal[i + 1].distance, GVA_VARIANT_PRINT_SPDI("NC_000001.11", variant)); - distance += graph.local_supremal[i + 1].distance; + graph.dom_nodes[i], graph.dom_nodes[i + 1], + i == 0, i == array_length(graph.dom_nodes) - 2, &variant); + //fprintf(stdout, "%u " GVA_VARIANT_FMT_SPDI "\n", graph.dom_nodes[i + 1].distance, GVA_VARIANT_PRINT_SPDI("NC_000001.11", variant)); + distance += graph.dom_nodes[i + 1].distance; ARRAY_APPEND(gva_std_allocator, lss, gva_variant_dup(gva_std_allocator, variant)); } // for @@ -649,20 +659,20 @@ dbsnp_main(int argc, char* argv[static argc + 1]) gva_uint const allele_idx = ARRAY_APPEND( gva_std_allocator, db_alleles, ((struct Allele) {line_count, array_length(node_allele_join), - array_length(node_allele_join) + array_length(graph.local_supremal) - 1, + array_length(node_allele_join) + array_length(graph.dom_nodes) - 1, graph.distance}) ) - 1; - for (size_t i = 0; i < array_length(graph.local_supremal) - 1; ++i) + for (size_t i = 0; i < array_length(graph.dom_nodes) - 1; ++i) { GVA_Variant part; gva_edges(graph.observed.str, - graph.local_supremal[i], graph.local_supremal[i + 1], - i == 0, i == array_length(graph.local_supremal) - 2, + graph.dom_nodes[i], graph.dom_nodes[i + 1], + i == 0, i == array_length(graph.dom_nodes) - 2, &part); gva_uint const inserted_idx = trie_insert(gva_std_allocator, &trie, part.sequence.len, part.sequence.str); - gva_uint const tmp_idx = ARRAY_APPEND(gva_std_allocator, tree.nodes, ((Interval_Tree_Node) {{GVA_NULL, GVA_NULL}, part.start, part.end, part.end, 0, inserted_idx, GVA_NULL, graph.local_supremal[i + 1].distance})) - 1; + gva_uint const tmp_idx = ARRAY_APPEND(gva_std_allocator, tree.nodes, ((Interval_Tree_Node) {{GVA_NULL, GVA_NULL}, part.start, part.end, part.end, 0, inserted_idx, GVA_NULL, graph.dom_nodes[i + 1].distance})) - 1; gva_uint const node_idx = interval_tree_insert(&tree, tmp_idx); if (node_idx != tmp_idx) { @@ -724,15 +734,15 @@ dbsnp_main(int argc, char* argv[static argc + 1]) GVA_LCS_Graph const rhs_graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &rhs_var); - for (size_t part_idx = 0; part_idx < array_length(rhs_graph.local_supremal) - 1; ++part_idx) + for (size_t part_idx = 0; part_idx < array_length(rhs_graph.dom_nodes) - 1; ++part_idx) { GVA_Variant rhs_part; gva_edges(rhs_graph.observed.str, - rhs_graph.local_supremal[part_idx], rhs_graph.local_supremal[part_idx + 1], - part_idx == 0, part_idx == array_length(rhs_graph.local_supremal) - 2, + rhs_graph.dom_nodes[part_idx], rhs_graph.dom_nodes[part_idx + 1], + part_idx == 0, part_idx == array_length(rhs_graph.dom_nodes) - 2, &rhs_part); - gva_uint const rhs_distance = rhs_graph.local_supremal[part_idx + 1].distance; + gva_uint const rhs_distance = rhs_graph.dom_nodes[part_idx + 1].distance; gva_uint* candidates = interval_tree_intersection(gva_std_allocator, tree, rhs_part.start, rhs_part.end); for (size_t can_idx = 0; can_idx < array_length(candidates); ++can_idx) @@ -789,7 +799,7 @@ dbsnp_main(int argc, char* argv[static argc + 1]) size_t rhs_distance = 0; for (size_t i = node_parts_table[npt_index].start; i < node_parts_table[npt_index].end; ++i) { - rhs_distance += rhs_graph.local_supremal[i + 1].distance; + rhs_distance += rhs_graph.dom_nodes[i + 1].distance; } // for if (rhs_distance >= lhs_distance) { @@ -804,10 +814,10 @@ dbsnp_main(int argc, char* argv[static argc + 1]) GVA_Variant rhs; gva_edges(rhs_graph.observed.str, - rhs_graph.local_supremal[node_parts_table[npt_index].start], - rhs_graph.local_supremal[node_parts_table[npt_index].end], + rhs_graph.dom_nodes[node_parts_table[npt_index].start], + rhs_graph.dom_nodes[node_parts_table[npt_index].end], node_parts_table[npt_index].start == 0, - node_parts_table[npt_index].end == array_length(rhs_graph.local_supremal) - 1, + node_parts_table[npt_index].end == array_length(rhs_graph.dom_nodes) - 1, &rhs); size_t const distance = variants_distance(gva_std_allocator, reference.len, reference.str, lhs, rhs); @@ -1123,7 +1133,7 @@ locals_main(int argc, char* argv[static argc + 1]) } // GVA_LCS_Graph const rhs_graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &rhs_var); - // fprintf(stderr, GVA_VARIANT_FMT " (%u) \n", GVA_VARIANT_PRINT(rhs_var), rhs_graph.distance); + fprintf(stderr, GVA_VARIANT_FMT_SPDI " (%u) \n", GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, rhs_var), rhs_graph.distance); // Join nodes in the index to parts in the query struct NODE_PARTS @@ -1135,16 +1145,18 @@ locals_main(int argc, char* argv[static argc + 1]) gva_uint included; }* node_parts_table = hash_table_init(gva_std_allocator, 1024, sizeof(*node_parts_table)); - for (size_t part_idx = 0; part_idx < array_length(rhs_graph.local_supremal) - 1; ++part_idx) + for (size_t part_idx = 0; part_idx < array_length(rhs_graph.dom_nodes) - 1; ++part_idx) { + fprintf(stderr, "part_idx: %zu\n", part_idx); + gva_uint const rhs_distance = rhs_graph.dom_nodes[part_idx + 1].distance; + fprintf(stderr, "rhs_distance from local: %u\n", rhs_distance); + GVA_Variant rhs_part; gva_edges(rhs_graph.observed.str, - rhs_graph.local_supremal[part_idx], rhs_graph.local_supremal[part_idx + 1], - part_idx == 0, part_idx == array_length(rhs_graph.local_supremal) - 2, + rhs_graph.dom_nodes[part_idx], rhs_graph.dom_nodes[part_idx + 1], + part_idx == 0, part_idx == array_length(rhs_graph.dom_nodes) - 2, &rhs_part); - gva_uint const rhs_distance = rhs_graph.local_supremal[part_idx + 1].distance; - gva_uint* candidates = interval_tree_intersection(gva_std_allocator, tree, rhs_part.start, rhs_part.end); for (size_t can_idx = 0; can_idx < array_length(candidates); ++can_idx) { @@ -1204,7 +1216,7 @@ locals_main(int argc, char* argv[static argc + 1]) size_t rhs_distance = 0; for (size_t i = node_parts_table[npt_index].start; i < node_parts_table[npt_index].end; ++i) { - rhs_distance += rhs_graph.local_supremal[i + 1].distance; + rhs_distance += rhs_graph.dom_nodes[i + 1].distance; } // for if (rhs_distance >= lhs_distance) { @@ -1219,10 +1231,10 @@ locals_main(int argc, char* argv[static argc + 1]) GVA_Variant rhs; gva_edges(rhs_graph.observed.str, - rhs_graph.local_supremal[node_parts_table[npt_index].start], - rhs_graph.local_supremal[node_parts_table[npt_index].end], + rhs_graph.dom_nodes[node_parts_table[npt_index].start], + rhs_graph.dom_nodes[node_parts_table[npt_index].end], node_parts_table[npt_index].start == 0, - node_parts_table[npt_index].end == array_length(rhs_graph.local_supremal) - 1, + node_parts_table[npt_index].end == array_length(rhs_graph.dom_nodes) - 1, &rhs); size_t const distance = variants_distance(gva_std_allocator, reference.len, reference.str, lhs, rhs); @@ -1468,7 +1480,7 @@ local_supremal(size_t const len_ref, char const reference[static len_ref], distance = gva_edit_distance(gva_std_allocator, len_ref, reference, len_obs, observed); MNode* backward = matches; char* b_uniq = uniq; - //fprintf(stderr, "distance: %zu\n", distance); + fprintf(stderr, "distance: %zu\n", distance); //fprintf(stderr, "max_lcs_pos: %zu\n", max_lcs_pos); size_t const max_lcs_pos_local = max_lcs_pos; @@ -1518,17 +1530,18 @@ local_supremal(size_t const len_ref, char const reference[static len_ref], { size_t const distance = len_ref + len_obs - 2 * max_lcs_pos_local - sum; sum += distance; - //printf(GVA_STRING_FMT " ", (int) (len_ref - prev_row - 1), reference + prev_row + 1); - //printf(GVA_STRING_FMT "\n", (int) (len_obs - prev_col - 1), observed + prev_col + 1); + fprintf(stderr, "dist: %zu\n", distance); + printf(GVA_STRING_FMT " ", (int) (len_ref - prev_row - 1), reference + prev_row + 1); + printf(GVA_STRING_FMT "\n", (int) (len_obs - prev_col - 1), observed + prev_col + 1); GVA_LCS_Graph graph = gva_lcs_graph_init(gva_std_allocator, len_ref - prev_row - 1, reference + prev_row + 1, len_obs - prev_col - 1, observed + prev_col + 1, offset + prev_row + 1); - for (size_t i = 0; i < array_length(graph.local_supremal) - 1; ++i) + for (size_t i = 0; i < array_length(graph.dom_nodes) - 1; ++i) { GVA_Variant variant; gva_edges(graph.observed.str, - graph.local_supremal[i], graph.local_supremal[i + 1], - i == 0, i == array_length(graph.local_supremal) - 2, + graph.dom_nodes[i], graph.dom_nodes[i + 1], + i == 0, i == array_length(graph.dom_nodes) - 2, &variant); - printf(GVA_VARIANT_FMT_SPDI " %u\n", GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, variant), graph.local_supremal[i + 1].distance); + printf(GVA_VARIANT_FMT_SPDI " %u\n", GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, variant), graph.dom_nodes[i + 1].distance); } // for gva_lcs_graph_destroy(gva_std_allocator, graph); //printf("L " GVA_VARIANT_FMT " %zu %zu+[(%zu, %zu)--(%zu, %zu)]\n", GVA_VARIANT_PRINT(((GVA_Variant) {offset + prev_row + 1, offset + len_ref, {len_obs - prev_col - 1, observed + prev_col + 1}})), distance, offset, prev_row + 1, prev_col + 1, len_ref, len_obs); @@ -1561,14 +1574,14 @@ wu_main(int argc, char* argv[static argc + 1]) GVA_LCS_Graph graph = gva_lcs_graph_init(gva_std_allocator, reference.len, reference.str, observed.len, observed.str, 0); lcs_graph_dot(stderr, graph); - for (size_t i = 0; i < array_length(graph.local_supremal) - 1; ++i) + for (size_t i = 0; i < array_length(graph.dom_nodes) - 1; ++i) { GVA_Variant part; gva_edges(graph.observed.str, - graph.local_supremal[i], graph.local_supremal[i + 1], - i == 0, i == array_length(graph.local_supremal) - 2, + graph.dom_nodes[i], graph.dom_nodes[i + 1], + i == 0, i == array_length(graph.dom_nodes) - 2, &part); - fprintf(stderr, GVA_VARIANT_FMT " %u\n", GVA_VARIANT_PRINT(part), graph.local_supremal[i + 1].distance); + fprintf(stderr, GVA_VARIANT_FMT " %u\n", GVA_VARIANT_PRINT(part), graph.dom_nodes[i + 1].distance); } // for gva_lcs_graph_destroy(gva_std_allocator, graph); @@ -1692,22 +1705,11 @@ extract_main(int argc, char* argv[static argc + 1]) { fprintf(stderr, "reference length: %zu\n", reference.len); - size_t line_count = 0; - static char line[LINE_SIZE] = {0}; - while (fgets(line, sizeof(line), stdin) != NULL) { - size_t const len = strlen(line) - 1; - GVA_Variant variant; - if (gva_parse_spdi(len, line, &variant) == 0) { - fprintf(stderr, "error: SPDI parsing failed at line %zu: %s", line_count + 1, line); - continue; - } // if + GVA_LCS_Graph graph = gva_lcs_graph_init(gva_std_allocator, 31, "CAGATGACAGGGTTGGGCTCAGAGTCAGAGT", 25, "CTCTCATACACACTCTCATCAGATT", 0); + fprintf(stderr, "graph distance: %zu\n", graph.distance); - GVA_LCS_Graph const graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &variant); + lcs_graph_dot(stderr, graph); - gva_string_destroy(gva_std_allocator, graph.observed); - gva_lcs_graph_destroy(gva_std_allocator, graph); - gva_canonical(gva_std_allocator, graph); - } // while return EXIT_SUCCESS; } // extract_main @@ -1763,12 +1765,12 @@ int make_obs_blob_main(int argc, char* argv[static argc + 1]) { int main(int argc, char* argv[static argc + 1]) { - // return wu_main(argc, argv); + return wu_main(argc, argv); // return slice_blob_main(argc, argv); // return fasta_blob_write(argc, argv); // return vcf_main(argc, argv); // return dbsnp_main(argc, argv); - return locals_main(argc, argv); + // return locals_main(argc, argv); // return extract_main(argc, argv); // return make_ref_blob_main(argc, argv); // return make_obs_blob_main(argc, argv); From a56a9dc957fce20d4092187acb71ff6abbd4f800 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Mon, 2 Feb 2026 19:54:54 +0100 Subject: [PATCH 457/704] Simplify local supremal creation. --- src/lcs_graph.c | 137 ++++++++++++++++++++++-------------------------- src/main.c | 28 +++++++--- 2 files changed, 84 insertions(+), 81 deletions(-) diff --git a/src/lcs_graph.c b/src/lcs_graph.c index f479082..9f9e9fe 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -266,96 +266,83 @@ gva_lcs_graph_init(GVA_Allocator const allocator, // start constructing the local supremal - - fprintf(stderr, "shift: %zu\n", shift); - gva_uint len = 0; - gva_uint prev = GVA_NULL; - gva_uint prev_distance = 0; + ARRAY_APPEND(allocator, graph.dom_nodes, + ((GVA_Node) + { + .row = shift, + .col = 0, + .length = 0, + .distance = 0, + .link = source.idx + })); + //fprintf(stderr, "shift: %zu\n", shift); + gva_uint distance = 0; + gva_uint prev = lcs.index[0].tail; + if (lcs.nodes[lcs.index[0].tail].idx != source.idx) + { + prev = GVA_NULL; + } for (gva_uint i = 0; i < lcs.length; ++i) { - if (prev == GVA_NULL && lcs.nodes[lcs.index[i].tail].idx != source.idx) + // LCS_Node t = lcs.nodes[lcs.index[i].tail]; + //fprintf(stderr, "allignment: i: %u head: %u tail: %u count: %u offset: %u\n", + // i, lcs.index[i].head, lcs.index[i].tail, lcs.index[i].count, lcs.index[i].offset); + //fprintf(stderr, "head: (%u, %u, %u)\n", h.row - shift, h.col, h.length); + //fprintf(stderr, "tail: (%u, %u, %u)\n", t.row - shift, t.col, t.length); + + // when to extend + if (lcs.index[i].count == 1) { - ARRAY_APPEND(allocator, graph.dom_nodes, + // start new + if (lcs.index[i].tail != prev) + { + gva_uint const offset = graph.nodes[lcs.nodes[lcs.index[i].tail].idx].length - lcs.index[i].offset - 1; + ARRAY_APPEND(allocator, graph.dom_nodes, ((GVA_Node) { - .row = graph.nodes[source.idx].row, - .col = graph.nodes[source.idx].col, + .row = lcs.nodes[lcs.index[i].tail].row + offset, + .col = lcs.nodes[lcs.index[i].tail].col + offset, .length = 0, - .distance = 0, - .link = source.idx + .distance = lcs.nodes[lcs.index[i].tail].row + offset - shift + + lcs.nodes[lcs.index[i].tail].col + offset - + 2 * i - distance, + .link = lcs.nodes[lcs.index[i].tail].idx })); - prev_distance = 0; - } // if - if (len > 0 && (lcs.index[i].count > 1 || prev != lcs.index[i].tail)) - { - gva_uint const idx = lcs.nodes[prev].idx; - gva_uint const offset = graph.nodes[idx].length - lcs.index[i - 1].offset - len; - gva_uint const distance = graph.nodes[idx].row + graph.nodes[idx].col + 2 * offset + 2 * len - 2 * i; - fprintf(stderr, "B distance: %u\n", distance); - fprintf(stderr, "B prev_distance: %u\n", prev_distance); - fprintf(stderr, "B dist - prev: %u\n", distance - prev_distance); - ARRAY_APPEND(allocator, graph.dom_nodes, - ((GVA_Node) - { - .row = graph.nodes[idx].row + offset, - .col = graph.nodes[idx].col + offset, - .length = len, - .distance = distance - prev_distance, - .link = idx - })); - len = 0; - prev_distance = distance; - } // if - if (lcs.index[i].count == 1) - { - len += 1; - } // if - prev = lcs.index[i].tail; + //fprintf(stderr, "new node: (%u, %u, %u) %u\n", + // lcs.nodes[lcs.index[i].tail].row + offset, + // lcs.nodes[lcs.index[i].tail].col + offset, 0, + // offset); + prev = lcs.index[i].tail; + distance += graph.dom_nodes[array_length(graph.dom_nodes) - 1].distance; + } // if + + // increase length + graph.dom_nodes[array_length(graph.dom_nodes) - 1].length += 1; + } // if } // for - if (len > 0 && lcs.nodes[prev].idx != 0) - { - gva_uint const idx = lcs.nodes[prev].idx; - gva_uint const offset = graph.nodes[idx].length - lcs.index[lcs.length - 1].offset - len; - fprintf(stderr, "offset: %u\n", offset); - gva_uint const distance = graph.nodes[idx].row - shift + graph.nodes[idx].col + 2 * offset + 2 * len - 2 * (lcs.length ); - fprintf(stderr, "C distance: %u\n", distance); - ARRAY_APPEND(allocator, graph.dom_nodes, - ((GVA_Node) - { - .row = graph.nodes[idx].row + offset, - .col = graph.nodes[idx].col + offset, - .length = len, - .distance = distance - prev_distance, - .link = idx - })); - len = 0; - prev_distance = distance; - } // if - if (graph.nodes != NULL) + + // add empty match sink if not already handled because of unique matches + if (graph.dom_nodes[array_length(graph.dom_nodes) - 1].link != sink.idx) { - assert(len == 0); - fprintf(stderr, "row: %u col: %u shift: %zu, length: %u len: %u\n", - graph.nodes[0].row, graph.nodes[0].col, shift, graph.nodes[0].length, len); - gva_uint const distance = graph.nodes[0].row - shift - + graph.nodes[0].col - + 2 * (graph.nodes[0].length - len) - // + graph.nodes[0].length - len - - 2 * lcs.length; - fprintf(stderr, "D distance: %u\n", distance); - fprintf(stderr, "D prev_distance: %u\n", prev_distance); - fprintf(stderr, "D dist - prev: %u\n", distance - prev_distance); ARRAY_APPEND(allocator, graph.dom_nodes, ((GVA_Node) { - .row = graph.nodes[0].row + graph.nodes[0].length - len, - .col = graph.nodes[0].col + graph.nodes[0].length - len, + .row = sink.row + sink.length, + .col = sink.col + sink.length, .length = 0, - .distance = distance - prev_distance, - .link = 0 + .distance = graph.distance - distance, + .link = sink.idx, })); - } //if + //fprintf(stderr, "add sink\n"); + } + + //for (size_t i = 0; i < array_length(graph.dom_nodes); ++i) + //{ + //fprintf(stderr, "(%u, %u, %u)\n", graph.dom_nodes[i].row, + // graph.dom_nodes[i].col, graph.dom_nodes[i].length); + //} // construct supremal if (graph.dom_nodes != NULL) @@ -364,7 +351,7 @@ gva_lcs_graph_init(GVA_Allocator const allocator, graph.nodes[source.idx].col += graph.dom_nodes[0].length; graph.nodes[source.idx].length -= graph.dom_nodes[0].length; - graph.nodes[0].length -= len; + graph.nodes[sink.idx].length -= graph.dom_nodes[array_length(graph.dom_nodes) - 1].length; gva_edges(graph.observed.str, graph.dom_nodes[0], graph.dom_nodes[array_length(graph.dom_nodes) - 1], diff --git a/src/main.c b/src/main.c index 49a9094..cb1fb7c 100644 --- a/src/main.c +++ b/src/main.c @@ -1465,10 +1465,11 @@ local_supremal(size_t const len_ref, char const reference[static len_ref], //fprintf(stderr, "LOCAL %zu %zu :: %zu\n", len_ref, len_obs, offset); if (len_ref == 0 || len_obs == 0) { + fprintf(stderr, "triv distance: %zu\n", len_ref + len_obs); printf(GVA_VARIANT_FMT_SPDI " %zu\n", GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, ((GVA_Variant) {offset, offset + len_ref, {len_obs, observed}})), len_ref + len_obs); return; } // if - size_t distance = gva_edit_distance(gva_std_allocator, len_ref, reference, len_obs, observed); + size_t f_distance = gva_edit_distance(gva_std_allocator, len_ref, reference, len_obs, observed); MNode* forward = matches; char* f_uniq = uniq; //fprintf(stderr, "distance: %zu\n", distance); @@ -1477,13 +1478,19 @@ local_supremal(size_t const len_ref, char const reference[static len_ref], reference = strrev(len_ref, (char*) reference); observed = strrev(len_obs, (char*) observed); - distance = gva_edit_distance(gva_std_allocator, len_ref, reference, len_obs, observed); + size_t b_distance = gva_edit_distance(gva_std_allocator, len_ref, reference, len_obs, observed); MNode* backward = matches; char* b_uniq = uniq; - fprintf(stderr, "distance: %zu\n", distance); + fprintf(stderr, "wu distance: %zu\n", b_distance); //fprintf(stderr, "max_lcs_pos: %zu\n", max_lcs_pos); size_t const max_lcs_pos_local = max_lcs_pos; + if (f_distance != b_distance) + { + fprintf(stderr, "distance mismatch between f and b\n"); + exit(EXIT_FAILURE); + } + reference = strrev(len_ref, (char*) reference); observed = strrev(len_obs, (char*) observed); @@ -1530,7 +1537,7 @@ local_supremal(size_t const len_ref, char const reference[static len_ref], { size_t const distance = len_ref + len_obs - 2 * max_lcs_pos_local - sum; sum += distance; - fprintf(stderr, "dist: %zu\n", distance); + fprintf(stderr, "sum dist: %zu\n", distance); printf(GVA_STRING_FMT " ", (int) (len_ref - prev_row - 1), reference + prev_row + 1); printf(GVA_STRING_FMT "\n", (int) (len_obs - prev_col - 1), observed + prev_col + 1); GVA_LCS_Graph graph = gva_lcs_graph_init(gva_std_allocator, len_ref - prev_row - 1, reference + prev_row + 1, len_obs - prev_col - 1, observed + prev_col + 1, offset + prev_row + 1); @@ -1552,6 +1559,12 @@ local_supremal(size_t const len_ref, char const reference[static len_ref], //fprintf(stderr, "distance: %zu\n", sum); + if (f_distance != sum) + { + fprintf(stderr, "distance mismatch between f and sum\n"); + exit(EXIT_FAILURE); + } + forward = gva_std_allocator.allocate(gva_std_allocator.context, forward, MIN(len_ref, len_obs), 0); f_uniq = gva_std_allocator.allocate(gva_std_allocator.context, f_uniq, MIN(len_ref, len_obs), 0); backward = gva_std_allocator.allocate(gva_std_allocator.context, backward, MIN(len_ref, len_obs), 0); @@ -1573,7 +1586,7 @@ wu_main(int argc, char* argv[static argc + 1]) GVA_String observed = {strlen(argv[2]), argv[2]}; GVA_LCS_Graph graph = gva_lcs_graph_init(gva_std_allocator, reference.len, reference.str, observed.len, observed.str, 0); - lcs_graph_dot(stderr, graph); + // lcs_graph_dot(stderr, graph); for (size_t i = 0; i < array_length(graph.dom_nodes) - 1; ++i) { GVA_Variant part; @@ -1583,9 +1596,12 @@ wu_main(int argc, char* argv[static argc + 1]) &part); fprintf(stderr, GVA_VARIANT_FMT " %u\n", GVA_VARIANT_PRINT(part), graph.dom_nodes[i + 1].distance); } // for + fprintf(stderr, GVA_VARIANT_FMT " %u\n", GVA_VARIANT_PRINT(graph.supremal), graph.distance); gva_lcs_graph_destroy(gva_std_allocator, graph); + return 0; + #else errno = 0; FILE* stream = fopen(argv[1], "r"); @@ -1706,7 +1722,7 @@ extract_main(int argc, char* argv[static argc + 1]) { fprintf(stderr, "reference length: %zu\n", reference.len); GVA_LCS_Graph graph = gva_lcs_graph_init(gva_std_allocator, 31, "CAGATGACAGGGTTGGGCTCAGAGTCAGAGT", 25, "CTCTCATACACACTCTCATCAGATT", 0); - fprintf(stderr, "graph distance: %zu\n", graph.distance); + fprintf(stderr, "graph distance: %u\n", graph.distance); lcs_graph_dot(stderr, graph); From 52e9f6f9514aa8c151a561f5a2a36291fe8736ff Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Mon, 2 Feb 2026 22:56:33 +0100 Subject: [PATCH 458/704] Quiet. --- src/main.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main.c b/src/main.c index cb1fb7c..bc770b1 100644 --- a/src/main.c +++ b/src/main.c @@ -1465,7 +1465,7 @@ local_supremal(size_t const len_ref, char const reference[static len_ref], //fprintf(stderr, "LOCAL %zu %zu :: %zu\n", len_ref, len_obs, offset); if (len_ref == 0 || len_obs == 0) { - fprintf(stderr, "triv distance: %zu\n", len_ref + len_obs); + // fprintf(stderr, "triv distance: %zu\n", len_ref + len_obs); printf(GVA_VARIANT_FMT_SPDI " %zu\n", GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, ((GVA_Variant) {offset, offset + len_ref, {len_obs, observed}})), len_ref + len_obs); return; } // if @@ -1481,7 +1481,7 @@ local_supremal(size_t const len_ref, char const reference[static len_ref], size_t b_distance = gva_edit_distance(gva_std_allocator, len_ref, reference, len_obs, observed); MNode* backward = matches; char* b_uniq = uniq; - fprintf(stderr, "wu distance: %zu\n", b_distance); + // fprintf(stderr, "wu distance: %zu\n", b_distance); //fprintf(stderr, "max_lcs_pos: %zu\n", max_lcs_pos); size_t const max_lcs_pos_local = max_lcs_pos; @@ -1537,9 +1537,9 @@ local_supremal(size_t const len_ref, char const reference[static len_ref], { size_t const distance = len_ref + len_obs - 2 * max_lcs_pos_local - sum; sum += distance; - fprintf(stderr, "sum dist: %zu\n", distance); - printf(GVA_STRING_FMT " ", (int) (len_ref - prev_row - 1), reference + prev_row + 1); - printf(GVA_STRING_FMT "\n", (int) (len_obs - prev_col - 1), observed + prev_col + 1); + // fprintf(stderr, "sum dist: %zu\n", distance); + // printf(GVA_STRING_FMT " ", (int) (len_ref - prev_row - 1), reference + prev_row + 1); + // printf(GVA_STRING_FMT "\n", (int) (len_obs - prev_col - 1), observed + prev_col + 1); GVA_LCS_Graph graph = gva_lcs_graph_init(gva_std_allocator, len_ref - prev_row - 1, reference + prev_row + 1, len_obs - prev_col - 1, observed + prev_col + 1, offset + prev_row + 1); for (size_t i = 0; i < array_length(graph.dom_nodes) - 1; ++i) { From 0022a9af1d5ed57ed723ef9574e07e59917a0b40 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 3 Feb 2026 08:06:32 +0100 Subject: [PATCH 459/704] Reordered alignment fiels and (de)serialization --- include/lcs_graph.h | 4 ++++ src/align.c | 20 +++++++++---------- src/align.h | 6 +++--- src/main.c | 48 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 65 insertions(+), 13 deletions(-) diff --git a/include/lcs_graph.h b/include/lcs_graph.h index 4ff4da8..8558f1a 100644 --- a/include/lcs_graph.h +++ b/include/lcs_graph.h @@ -21,6 +21,10 @@ typedef struct } GVA_Edge; +// FIXME: refactor: typedef struct { row; col; lenght; } GVA_Match; +// see also: src/align.h + + // Internal: The triple (`row`, `col`, `length`) uniquely defines each // node in the graph. Its outgoing edges are found in the edges array of // graph as a singly linked list with `edges` as entry point. diff --git a/src/align.c b/src/align.c index f35c476..1aeef7e 100644 --- a/src/align.c +++ b/src/align.c @@ -75,18 +75,18 @@ expand(Context const context, intmax_t const d_col = context.len_obs - col; size_t const lcs_pos = (row + col - ABS(delta) - 2 * p + ABS(d_row - d_col)) / 2 - 1; size_t const length = row - match_row; - gva_uint const len = ARRAY_APPEND(context.allocator, lcs->nodes, ((LCS_Node) { - match_row + context.shift, match_col, length, false, 0, GVA_NULL, GVA_NULL + gva_uint const idx = ARRAY_APPEND(context.allocator, lcs->nodes, ((LCS_Node) { + match_row + context.shift, match_col, length, 0, false, GVA_NULL, GVA_NULL })) - 1; if (lcs->index[lcs_pos].head != GVA_NULL) { - lcs->nodes[lcs->index[lcs_pos].tail].next = len; + lcs->nodes[lcs->index[lcs_pos].tail].next = idx; } // if else { - lcs->index[lcs_pos].head = len; + lcs->index[lcs_pos].head = idx; } // else - lcs->index[lcs_pos].tail = len; + lcs->index[lcs_pos].tail = idx; if (lcs_pos + 1 > lcs->length) { @@ -116,18 +116,18 @@ expand(Context const context, intmax_t const d_col = context.len_obs - col; size_t const lcs_pos = (row + col - ABS(delta) - 2 * p + ABS(d_row - d_col)) / 2 - 1; size_t const length = row - match_row; - gva_uint const len = ARRAY_APPEND(context.allocator, lcs->nodes, ((LCS_Node) { - match_row + context.shift, match_col, length, false, 0, GVA_NULL, GVA_NULL + gva_uint const idx = ARRAY_APPEND(context.allocator, lcs->nodes, ((LCS_Node) { + match_row + context.shift, match_col, length, 0, false, GVA_NULL, GVA_NULL })) - 1; if (lcs->index[lcs_pos].head != GVA_NULL) { - lcs->nodes[lcs->index[lcs_pos].tail].next = len; + lcs->nodes[lcs->index[lcs_pos].tail].next = idx; } // if else { - lcs->index[lcs_pos].head = len; + lcs->index[lcs_pos].head = idx; } // else - lcs->index[lcs_pos].tail = len; + lcs->index[lcs_pos].tail = idx; if (lcs_pos + 1 > lcs->length) { diff --git a/src/align.h b/src/align.h index a201bd6..3721f6c 100644 --- a/src/align.h +++ b/src/align.h @@ -13,9 +13,9 @@ typedef struct { gva_uint row; gva_uint col; - gva_uint length : sizeof(gva_uint) * CHAR_BIT - 1; - gva_uint moved : 1; - gva_uint incoming; + gva_uint length; + gva_uint incoming : sizeof(gva_uint) * CHAR_BIT - 1; + gva_uint moved : 1; gva_uint idx; gva_uint next; } LCS_Node; diff --git a/src/main.c b/src/main.c index 2f0ff6c..e6f0f9e 100644 --- a/src/main.c +++ b/src/main.c @@ -33,6 +33,54 @@ #define REFERENCE_ID "NC_000001.11" +inline void +serialize_array(FILE* restrict const stream, + void* restrict const self, size_t const item_size) +{ + size_t const length = array_length(self); + if (fwrite(&length, sizeof(length), 1, stream) != 1 || + fwrite(self, item_size, length, stream) != length) + { + fprintf(stderr, "error: fwrite()\n"); + return; + } // if +} // serialize_array + + +inline void* +deserialize_array(GVA_Allocator const allocator, FILE* const stream, + size_t const item_size) +{ + size_t length = 0; + if (fread(&length, sizeof(length), 1, stream) != 1) + { + fprintf(stderr, "error: fread()\n"); + return NULL; + } // if + + if (length == 0) + { + return NULL; + } // if + + void* const restrict array = array_init(allocator, length, item_size); + if (array == NULL) + { + fprintf(stderr, "error: OOM\n"); + return NULL; + } // if + + if (fread(array, item_size, length, stream) != length) + { + fprintf(stderr, "error: fread()\n"); + return allocator.allocate(allocator.context, array_header(array), length * item_size, 0); + } // if + + array_header(array)->length = length; + return array; +} // deserialize_array + + void lcs_graph_dot(FILE* const stream, GVA_LCS_Graph const graph) { From 289f7c49b1f643e207b3f61e9ef45e858d18bcef Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Tue, 3 Feb 2026 14:09:00 +0100 Subject: [PATCH 460/704] Get rid of query label trie. --- src/main.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/main.c b/src/main.c index 73c58d3..13547e9 100644 --- a/src/main.c +++ b/src/main.c @@ -1156,25 +1156,20 @@ locals_main(int argc, char* argv[static argc + 1]) db_alleles[i].join_end); } - Trie query_trie = trie_init(); - // for every query line_count = 0; while (fgets(line, sizeof(line), stdin) != NULL) { // label - size_t len = strcspn(line, "\t "); - if (len == 0) + size_t query_len = strcspn(line, "\t "); + if (query_len == 0) { fprintf(stderr, "error: parsing failed at line %zu: %s", line_count + 1, line); continue; } - size_t const query_id = trie_insert(gva_std_allocator, &query_trie, len, line); // variant - size_t idx = len + 1; - len = strcspn(line + idx, "\n"); GVA_Variant rhs_var; - if (gva_parse_spdi(len, line + idx, &rhs_var) == 0) + if (gva_parse_spdi(strcspn(line + query_len + 1, "\n"), line + query_len + 1, &rhs_var) == 0) { fprintf(stderr, "error: SPDI parsing failed at line %zu: %s", line_count + 1, line); continue; @@ -1422,7 +1417,7 @@ locals_main(int argc, char* argv[static argc + 1]) fprintf(stderr, GVA_STRING_FMT " %s " GVA_STRING_FMT " %u %u %u\n", GVA_STRING_PRINT(trie_string(sample_trie, db_alleles[allele_idx].sample_id)), GVA_RELATION_LABELS[relation], - GVA_STRING_PRINT(trie_string(query_trie, query_id)), + GVA_STRING_PRINT(((GVA_String) {query_len, line})), included, lhs_excluded, rhs_excluded ); } // if @@ -1441,7 +1436,6 @@ locals_main(int argc, char* argv[static argc + 1]) db_alleles = ARRAY_DESTROY(gva_std_allocator, db_alleles); node_allele_join = ARRAY_DESTROY(gva_std_allocator, node_allele_join); interval_tree_destroy(gva_std_allocator, &tree); - trie_destroy(gva_std_allocator, &query_trie); trie_destroy(gva_std_allocator, &sample_trie); trie_destroy(gva_std_allocator, &trie); gva_string_destroy(gva_std_allocator, reference); From 66407b90d82f7332224d2602e12e01db545e0df9 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Tue, 3 Feb 2026 16:37:22 +0100 Subject: [PATCH 461/704] Minor and comments. --- src/main.c | 43 +++++++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/src/main.c b/src/main.c index 13547e9..8fdb200 100644 --- a/src/main.c +++ b/src/main.c @@ -189,9 +189,9 @@ compare_from_index(GVA_String const reference, { // TODO: possibly reuse rhs_graph - fprintf(stderr, GVA_VARIANT_FMT_SPDI " " GVA_VARIANT_FMT_SPDI "\n", - GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, lhs), - GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, rhs)); + // fprintf(stderr, GVA_VARIANT_FMT_SPDI " " GVA_VARIANT_FMT_SPDI "\n", + // GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, lhs), + // GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, rhs)); if (gva_variant_eq(lhs, rhs)) { @@ -200,11 +200,11 @@ compare_from_index(GVA_String const reference, size_t const start = MIN(lhs.start, rhs.start); size_t const end = MAX(lhs.end, rhs.end); - fprintf(stderr, "start: %zu end: %zu\n", start, end); + // fprintf(stderr, "start: %zu end: %zu\n", start, end); size_t const lhs_len = (lhs.start - start) + lhs.sequence.len + (end - lhs.end); size_t const rhs_len = (rhs.start - start) + rhs.sequence.len + (end - rhs.end); - fprintf(stderr, "lhs_len: %zu rhs_len: %zu\n", lhs_len, rhs_len); + // fprintf(stderr, "lhs_len: %zu rhs_len: %zu\n", lhs_len, rhs_len); gva_uint distance = 0; if (lhs_len == 0) @@ -241,7 +241,7 @@ compare_from_index(GVA_String const reference, lhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, lhs_obs, lhs_len, 0); } // else - fprintf(stderr, "distance: %u lhs_distance: %u rhs_distance: %u\n", distance, lhs_distance, rhs_distance); + // fprintf(stderr, "distance: %u lhs_distance: %u rhs_distance: %u\n", distance, lhs_distance, rhs_distance); if (lhs_distance + rhs_distance == distance) { @@ -250,7 +250,7 @@ compare_from_index(GVA_String const reference, if (lhs_distance - rhs_distance == distance) { - fprintf(stderr, "this return?!\n"); + // fprintf(stderr, "this return?!\n"); return GVA_CONTAINS; } // if @@ -1176,7 +1176,7 @@ locals_main(int argc, char* argv[static argc + 1]) } // GVA_LCS_Graph const rhs_graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &rhs_var); - fprintf(stderr, GVA_VARIANT_FMT_SPDI " (%u) \n", GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, rhs_var), rhs_graph.distance); + // fprintf(stderr, GVA_VARIANT_FMT_SPDI " (%u) \n", GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, rhs_var), rhs_graph.distance); // Join nodes in the index to parts in the query struct NODE_PARTS @@ -1190,9 +1190,9 @@ locals_main(int argc, char* argv[static argc + 1]) for (size_t part_idx = 0; part_idx < array_length(rhs_graph.dom_nodes) - 1; ++part_idx) { - fprintf(stderr, "part_idx: %zu\n", part_idx); + // fprintf(stderr, "part_idx: %zu\n", part_idx); gva_uint const rhs_distance = rhs_graph.dom_nodes[part_idx + 1].distance; - fprintf(stderr, "rhs_distance from local: %u\n", rhs_distance); + // fprintf(stderr, "rhs_distance from local: %u\n", rhs_distance); GVA_Variant rhs_part; gva_edges(rhs_graph.observed.str, @@ -1211,10 +1211,10 @@ locals_main(int argc, char* argv[static argc + 1]) { continue; } // if - fprintf(stderr, "%zu " GVA_VARIANT_FMT_SPDI " %s " GVA_VARIANT_FMT_SPDI "\n", line_count, - GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, db_var), - GVA_RELATION_LABELS[relation], - GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, rhs_part)); + // fprintf(stderr, "%zu " GVA_VARIANT_FMT_SPDI " %s " GVA_VARIANT_FMT_SPDI "\n", line_count, + // GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, db_var), + // GVA_RELATION_LABELS[relation], + // GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, rhs_part)); // link nodes to query parts size_t hash_idx = HASH_TABLE_INDEX(node_parts_table, node_idx); @@ -1227,6 +1227,7 @@ locals_main(int argc, char* argv[static argc + 1]) if (relation == GVA_EQUIVALENT || relation == GVA_IS_CONTAINED) { + // TODO: default value is already set for equivalence? node_parts_table[hash_idx].included = tree.nodes[node_idx].distance; } // if else if (relation == GVA_CONTAINS) @@ -1235,6 +1236,8 @@ locals_main(int argc, char* argv[static argc + 1]) } // if else // GVA_OVERLAP { + // TODO: Set relation to OVERLAP? + // TODO: +=1 ? node_parts_table[hash_idx].included = 1; } // else } // for every candidate @@ -1293,6 +1296,9 @@ locals_main(int argc, char* argv[static argc + 1]) } // if } // for node_parts_table + // TODO: get rid of struct + // or + // store relation struct RESULT_ALLELES { HASH_TABLE_KEY; @@ -1388,6 +1394,7 @@ locals_main(int argc, char* argv[static argc + 1]) repair_is_contained(gva_std_allocator, reference, rhs_graph, tree, trie, &is_contained_nodes, is_contained_part_idx, &included, &relation); + // TODO: always true?! if (included > 0) { gva_uint const lhs_excluded = db_alleles[allele_idx].distance - included; @@ -1414,7 +1421,7 @@ locals_main(int argc, char* argv[static argc + 1]) // if (relation != GVA_EQUIVALENT || db_alleles[allele_idx].line < line_count) // if (relation != GVA_OVERLAP) { - fprintf(stderr, GVA_STRING_FMT " %s " GVA_STRING_FMT " %u %u %u\n", + fprintf(stdout, GVA_STRING_FMT " %s " GVA_STRING_FMT " %u %u %u\n", GVA_STRING_PRINT(trie_string(sample_trie, db_alleles[allele_idx].sample_id)), GVA_RELATION_LABELS[relation], GVA_STRING_PRINT(((GVA_String) {query_len, line})), @@ -1590,7 +1597,7 @@ local_supremal(size_t const len_ref, char const reference[static len_ref], graph.dom_nodes[i], graph.dom_nodes[i + 1], i == 0, i == array_length(graph.dom_nodes) - 2, &variant); - printf(GVA_VARIANT_FMT_SPDI " %u\n", GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, variant), graph.dom_nodes[i + 1].distance); + // printf(GVA_VARIANT_FMT_SPDI " %u\n", GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, variant), graph.dom_nodes[i + 1].distance); } // for gva_lcs_graph_destroy(gva_std_allocator, graph); //printf("L " GVA_VARIANT_FMT " %zu %zu+[(%zu, %zu)--(%zu, %zu)]\n", GVA_VARIANT_PRINT(((GVA_Variant) {offset + prev_row + 1, offset + len_ref, {len_obs - prev_col - 1, observed + prev_col + 1}})), distance, offset, prev_row + 1, prev_col + 1, len_ref, len_obs); @@ -1823,12 +1830,12 @@ int make_obs_blob_main(int argc, char* argv[static argc + 1]) { int main(int argc, char* argv[static argc + 1]) { - return wu_main(argc, argv); + // return wu_main(argc, argv); // return slice_blob_main(argc, argv); // return fasta_blob_write(argc, argv); // return vcf_main(argc, argv); // return dbsnp_main(argc, argv); - // return locals_main(argc, argv); + return locals_main(argc, argv); // return extract_main(argc, argv); // return make_ref_blob_main(argc, argv); // return make_obs_blob_main(argc, argv); From aebe7321ac14b92d744dc0fece1138491c232251 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Fri, 6 Feb 2026 09:34:48 +0100 Subject: [PATCH 462/704] Truth files. --- test_alleles_supremal2.txt | 43 + truth/XA | 1 + truth/XB | 1 + truth/XC | 1 + truth/XD | 1 + truth/XE | 1 + truth/XF | 1 + truth/XG | 1 + truth/XH | 1 + truth/XI | 1 + truth/XJ | 1 + truth/XK | 1 + truth/XL | 1 + truth/XM | 1 + truth/XN | 1 + truth/XO | 1 + truth/XP | 1 + truth/XQ | 1 + truth/XR | 1 + truth/XS | 2 + truth/XT | 1 + truth/XU | 2 + truth/XV | 3 + truth/XW | 1 + truth/XX | 1 + truth/XY | 1 + truth/XZ | 1 + truth/YA | 5 + truth/YB | 1 + truth/YC | 2 + truth/YD | 1 + truth/YE | 2 + truth/YF | 2 + truth/YG | 2 + truth/YH | 1 + truth/YI | 3 + truth/YJ | 2 + truth/YK | 2 + truth/YL | 1 + truth/YM | 1 + truth/YN | 2 + truth/YO | 1 + truth/YP | 2 + truth/YQ | 11 + truth_2026.txt | 1849 ++++++++++++++++++++++++++++++++++++ 45 files changed, 1963 insertions(+) create mode 100644 test_alleles_supremal2.txt create mode 100644 truth/XA create mode 100644 truth/XB create mode 100644 truth/XC create mode 100644 truth/XD create mode 100644 truth/XE create mode 100644 truth/XF create mode 100644 truth/XG create mode 100644 truth/XH create mode 100644 truth/XI create mode 100644 truth/XJ create mode 100644 truth/XK create mode 100644 truth/XL create mode 100644 truth/XM create mode 100644 truth/XN create mode 100644 truth/XO create mode 100644 truth/XP create mode 100644 truth/XQ create mode 100644 truth/XR create mode 100644 truth/XS create mode 100644 truth/XT create mode 100644 truth/XU create mode 100644 truth/XV create mode 100644 truth/XW create mode 100644 truth/XX create mode 100644 truth/XY create mode 100644 truth/XZ create mode 100644 truth/YA create mode 100644 truth/YB create mode 100644 truth/YC create mode 100644 truth/YD create mode 100644 truth/YE create mode 100644 truth/YF create mode 100644 truth/YG create mode 100644 truth/YH create mode 100644 truth/YI create mode 100644 truth/YJ create mode 100644 truth/YK create mode 100644 truth/YL create mode 100644 truth/YM create mode 100644 truth/YN create mode 100644 truth/YO create mode 100644 truth/YP create mode 100644 truth/YQ create mode 100644 truth_2026.txt diff --git a/test_alleles_supremal2.txt b/test_alleles_supremal2.txt new file mode 100644 index 0000000..152f9f4 --- /dev/null +++ b/test_alleles_supremal2.txt @@ -0,0 +1,43 @@ +XA NC_000001.11:85456095:12:AAAAAAAAAA 2 +XB NC_000001.11:85456095:12:AAAAAAAAAAA 1 +XC NC_000001.11:85456095:12:AAAAAAAAAAAAA 1 +XD NC_000001.11:85456095:12:AAAAAAAAAAAAAA 2 +XE NC_000001.11:85456095:12:AAAAGAAAAAAA 2 +XF NC_000001.11:6100897:1:T 2 +XG NC_000001.11:6100897:2:CC 2 +XH NC_000001.11:6100895:3:GGG 2 +XI NC_000001.11:15220327:2:CC 2 +XJ NC_000001.11:15220328:1:G 2 +XK NC_000001.11:15220328:2:TT 2 +XL NC_000001.11:236991590:3:CCT 2 +XM NC_000001.11:236991589:2:CC 2 +XN NC_000001.11:52722559:21:TTTTTTTTTCTTTTTTTTTTT 2 +XO NC_000001.11:52722559:21:TTTTTCTTTTTTTTTTTTTTT 2 +XP NC_000001.11:74278135:3:TTT 2 +XQ NC_000001.11:74278137:1:TTTTT 4 +XR NC_000001.11:209714022:2:AA 2 +XS NC_000001.11:209714023:2:GTCATT 4 +XT NC_000001.11:149733075:4:GGTT 2 +XU NC_000001.11:149733077:2:TGTTTT 4 +XV NC_000001.11:154309540:45:CACACACACACACACACACACACACACACACACACACACACACA 5 +XW NC_000001.11:154309583:3:AAA 2 +XX NC_000001.11:154309584:1:C 2 +XY NC_000001.11:154309584:1:G 2 +XZ NC_000001.11:58651436:3:TGT 2 +YA NC_000001.11:58651407:35:TGTGTGTGTGTGTGTGTGTGTGTGTGTGTGTGTGTGTG 7 +YB NC_000001.11:175225135:1:A 2 +YC NC_000001.11:175225135:4:ACACA 3 +YD NC_000001.11:147276340:5:CACCAGCCC 4 +YE NC_000001.11:147276342:2:GCCA 2 +YF NC_000001.11:248280509:2:AC 2 +YG NC_000001.11:248280507:4:GTAC 4 +YH NC_000001.11:144735932:18:GGAGAGAGAGAGAGAGAGAGAGA 5 +YI NC_000001.11:144735947:2:GAGAG 3 +YJ NC_000001.11:148271316:3:ACTAAGATT 6 +YK NC_000001.11:148271316:3:TACTAAGATTT 8 +YL NC_000001.11:143535768:9:TTTTTTTTTTT 2 +YM NC_000001.11:143535768:9:TTTTTTTTTTT 2 +YN NC_000001.11:164871874:5:AC 3 +YO NC_000001.11:164871870:9: 9 +YP NC_000001.11:2656569:79:CCACCCACACCACCAGGCGATCATCCGCAG 53 +YQ NC_000001.11:2656569:79:CAACCCACACCCCCAGGCGAGCATCTGAAG 49 diff --git a/truth/XA b/truth/XA new file mode 100644 index 0000000..749f8c5 --- /dev/null +++ b/truth/XA @@ -0,0 +1 @@ +XA NC_000001.11:85456095:12:AAAAAAAAAA 2 diff --git a/truth/XB b/truth/XB new file mode 100644 index 0000000..48fcd1d --- /dev/null +++ b/truth/XB @@ -0,0 +1 @@ +XB NC_000001.11:85456095:12:AAAAAAAAAAA 1 diff --git a/truth/XC b/truth/XC new file mode 100644 index 0000000..71e2163 --- /dev/null +++ b/truth/XC @@ -0,0 +1 @@ +XC NC_000001.11:85456095:12:AAAAAAAAAAAAA 1 diff --git a/truth/XD b/truth/XD new file mode 100644 index 0000000..092265d --- /dev/null +++ b/truth/XD @@ -0,0 +1 @@ +XD NC_000001.11:85456095:12:AAAAAAAAAAAAAA 2 diff --git a/truth/XE b/truth/XE new file mode 100644 index 0000000..dab78ac --- /dev/null +++ b/truth/XE @@ -0,0 +1 @@ +XE NC_000001.11:85456095:12:AAAAGAAAAAAA 2 diff --git a/truth/XF b/truth/XF new file mode 100644 index 0000000..000987f --- /dev/null +++ b/truth/XF @@ -0,0 +1 @@ +XF NC_000001.11:248956422:-248956422: 2 diff --git a/truth/XG b/truth/XG new file mode 100644 index 0000000..eca52ba --- /dev/null +++ b/truth/XG @@ -0,0 +1 @@ +XG NC_000001.11:6100897:2:CC 2 diff --git a/truth/XH b/truth/XH new file mode 100644 index 0000000..4028400 --- /dev/null +++ b/truth/XH @@ -0,0 +1 @@ +XH NC_000001.11:6100895:3:GGG 2 diff --git a/truth/XI b/truth/XI new file mode 100644 index 0000000..dbbe1d1 --- /dev/null +++ b/truth/XI @@ -0,0 +1 @@ +XI NC_000001.11:15220327:2:CC 2 diff --git a/truth/XJ b/truth/XJ new file mode 100644 index 0000000..df6abd0 --- /dev/null +++ b/truth/XJ @@ -0,0 +1 @@ +XJ NC_000001.11:248956422:-248956422: 2 diff --git a/truth/XK b/truth/XK new file mode 100644 index 0000000..7c07c8c --- /dev/null +++ b/truth/XK @@ -0,0 +1 @@ +XK NC_000001.11:15220328:2:TT 2 diff --git a/truth/XL b/truth/XL new file mode 100644 index 0000000..4869d3b --- /dev/null +++ b/truth/XL @@ -0,0 +1 @@ +XL NC_000001.11:236991590:3:CCT 2 diff --git a/truth/XM b/truth/XM new file mode 100644 index 0000000..a64c9b3 --- /dev/null +++ b/truth/XM @@ -0,0 +1 @@ +XM NC_000001.11:236991589:2:CC 2 diff --git a/truth/XN b/truth/XN new file mode 100644 index 0000000..c0597f1 --- /dev/null +++ b/truth/XN @@ -0,0 +1 @@ +XN NC_000001.11:52722559:21:TTTTTTTTTCTTTTTTTTTTT 2 diff --git a/truth/XO b/truth/XO new file mode 100644 index 0000000..4d9a115 --- /dev/null +++ b/truth/XO @@ -0,0 +1 @@ +XO NC_000001.11:52722559:21:TTTTTCTTTTTTTTTTTTTTT 2 diff --git a/truth/XP b/truth/XP new file mode 100644 index 0000000..065564d --- /dev/null +++ b/truth/XP @@ -0,0 +1 @@ +XP NC_000001.11:74278135:3:TTT 2 diff --git a/truth/XQ b/truth/XQ new file mode 100644 index 0000000..902d370 --- /dev/null +++ b/truth/XQ @@ -0,0 +1 @@ +XQ NC_000001.11:74278137:1:TTTTT 4 diff --git a/truth/XR b/truth/XR new file mode 100644 index 0000000..23729be --- /dev/null +++ b/truth/XR @@ -0,0 +1 @@ +XR NC_000001.11:209714022:2:AA 2 diff --git a/truth/XS b/truth/XS new file mode 100644 index 0000000..466c535 --- /dev/null +++ b/truth/XS @@ -0,0 +1,2 @@ +XS NC_000001.11:209714023:0:GT 4 +XS NC_000001.11:209714024:1:ATT 4 diff --git a/truth/XT b/truth/XT new file mode 100644 index 0000000..1b68fd3 --- /dev/null +++ b/truth/XT @@ -0,0 +1 @@ +XT NC_000001.11:149733075:4:GGTT 2 diff --git a/truth/XU b/truth/XU new file mode 100644 index 0000000..1a3e54a --- /dev/null +++ b/truth/XU @@ -0,0 +1,2 @@ +XU NC_000001.11:149733077:0:T 4 +XU NC_000001.11:149733078:1:TTTT 4 diff --git a/truth/XV b/truth/XV new file mode 100644 index 0000000..1fb3921 --- /dev/null +++ b/truth/XV @@ -0,0 +1,3 @@ +XV NC_000001.11:154309540:1:C 5 +XV NC_000001.11:154309582:1:C 5 +XV NC_000001.11:154309584:1: 5 diff --git a/truth/XW b/truth/XW new file mode 100644 index 0000000..f64d567 --- /dev/null +++ b/truth/XW @@ -0,0 +1 @@ +XW NC_000001.11:154309583:3:AAA 2 diff --git a/truth/XX b/truth/XX new file mode 100644 index 0000000..cabfb0f --- /dev/null +++ b/truth/XX @@ -0,0 +1 @@ +XX NC_000001.11:248956422:-248956422: 2 diff --git a/truth/XY b/truth/XY new file mode 100644 index 0000000..b3edfa6 --- /dev/null +++ b/truth/XY @@ -0,0 +1 @@ +XY NC_000001.11:248956422:-248956422: 2 diff --git a/truth/XZ b/truth/XZ new file mode 100644 index 0000000..619b724 --- /dev/null +++ b/truth/XZ @@ -0,0 +1 @@ +XZ NC_000001.11:58651436:3:TGT 2 diff --git a/truth/YA b/truth/YA new file mode 100644 index 0000000..9a267c2 --- /dev/null +++ b/truth/YA @@ -0,0 +1,5 @@ +YA NC_000001.11:58651407:0:T 7 +YA NC_000001.11:58651435:1:G 7 +YA NC_000001.11:58651437:0:G 7 +YA NC_000001.11:58651438:0:G 7 +YA NC_000001.11:58651441:1:G 7 diff --git a/truth/YB b/truth/YB new file mode 100644 index 0000000..9114e4c --- /dev/null +++ b/truth/YB @@ -0,0 +1 @@ +YB NC_000001.11:248956422:-248956422: 2 diff --git a/truth/YC b/truth/YC new file mode 100644 index 0000000..6172ce1 --- /dev/null +++ b/truth/YC @@ -0,0 +1,2 @@ +YC NC_000001.11:175225135:1:A 3 +YC NC_000001.11:175225139:0:A 3 diff --git a/truth/YD b/truth/YD new file mode 100644 index 0000000..adb6f5e --- /dev/null +++ b/truth/YD @@ -0,0 +1 @@ +YD NC_000001.11:147276340:5:CACCAGCCC 4 diff --git a/truth/YE b/truth/YE new file mode 100644 index 0000000..338ef30 --- /dev/null +++ b/truth/YE @@ -0,0 +1,2 @@ +YE NC_000001.11:147276342:0:G 2 +YE NC_000001.11:147276344:0:A 2 diff --git a/truth/YF b/truth/YF new file mode 100644 index 0000000..17d2e6d --- /dev/null +++ b/truth/YF @@ -0,0 +1,2 @@ +YF NC_000001.11:248280509:1: 2 +YF NC_000001.11:248280511:0:C 2 diff --git a/truth/YG b/truth/YG new file mode 100644 index 0000000..d7bf5af --- /dev/null +++ b/truth/YG @@ -0,0 +1,2 @@ +YG NC_000001.11:248280507:3:GT 4 +YG NC_000001.11:248280511:0:C 4 diff --git a/truth/YH b/truth/YH new file mode 100644 index 0000000..64001f8 --- /dev/null +++ b/truth/YH @@ -0,0 +1 @@ +YH NC_000001.11:144735932:18:GGAGAGAGAGAGAGAGAGAGAGA 5 diff --git a/truth/YI b/truth/YI new file mode 100644 index 0000000..96093ff --- /dev/null +++ b/truth/YI @@ -0,0 +1,3 @@ +YI NC_000001.11:144735947:0:G 3 +YI NC_000001.11:144735948:0:G 3 +YI NC_000001.11:144735949:0:G 3 diff --git a/truth/YJ b/truth/YJ new file mode 100644 index 0000000..abe594d --- /dev/null +++ b/truth/YJ @@ -0,0 +1,2 @@ +YJ NC_000001.11:148271316:0:A 6 +YJ NC_000001.11:148271317:2:TAAGATT 6 diff --git a/truth/YK b/truth/YK new file mode 100644 index 0000000..fd4440d --- /dev/null +++ b/truth/YK @@ -0,0 +1,2 @@ +YK NC_000001.11:148271316:0:TA 8 +YK NC_000001.11:148271317:2:TAAGATTT 8 diff --git a/truth/YL b/truth/YL new file mode 100644 index 0000000..5cdb13e --- /dev/null +++ b/truth/YL @@ -0,0 +1 @@ +YL NC_000001.11:143535768:9:TTTTTTTTTTT 2 diff --git a/truth/YM b/truth/YM new file mode 100644 index 0000000..347a9d1 --- /dev/null +++ b/truth/YM @@ -0,0 +1 @@ +YM NC_000001.11:143535768:9:TTTTTTTTTTT 2 diff --git a/truth/YN b/truth/YN new file mode 100644 index 0000000..1fdc6ff --- /dev/null +++ b/truth/YN @@ -0,0 +1,2 @@ +YN NC_000001.11:164871874:3:A 3 +YN NC_000001.11:164871878:1: 3 diff --git a/truth/YO b/truth/YO new file mode 100644 index 0000000..9b09989 --- /dev/null +++ b/truth/YO @@ -0,0 +1 @@ +YO NC_000001.11:248956422:-248956422: 9 diff --git a/truth/YP b/truth/YP new file mode 100644 index 0000000..fa6bc57 --- /dev/null +++ b/truth/YP @@ -0,0 +1,2 @@ +YP NC_000001.11:2656569:19:CCACCCA 53 +YP NC_000001.11:2656590:58:CCACCAGGCGATCATCCGCAG 53 diff --git a/truth/YQ b/truth/YQ new file mode 100644 index 0000000..82e4727 --- /dev/null +++ b/truth/YQ @@ -0,0 +1,11 @@ +YQ NC_000001.11:2656569:4:C 49 +YQ NC_000001.11:2656574:1: 49 +YQ NC_000001.11:2656576:12:CCCA 49 +YQ NC_000001.11:2656590:1: 49 +YQ NC_000001.11:2656593:2: 49 +YQ NC_000001.11:2656596:2: 49 +YQ NC_000001.11:2656600:3: 49 +YQ NC_000001.11:2656605:2: 49 +YQ NC_000001.11:2656608:18:CG 49 +YQ NC_000001.11:2656630:10:TC 49 +YQ NC_000001.11:2656641:7:GAAG 49 diff --git a/truth_2026.txt b/truth_2026.txt new file mode 100644 index 0000000..987a1de --- /dev/null +++ b/truth_2026.txt @@ -0,0 +1,1849 @@ +XA equivalent XA +XA contains XB +XA disjoint XC +XA disjoint XD +XA overlap XE +XA disjoint XF +XA disjoint XG +XA disjoint XH +XA disjoint XI +XA disjoint XJ +XA disjoint XK +XA disjoint XL +XA disjoint XM +XA disjoint XN +XA disjoint XO +XA disjoint XP +XA disjoint XQ +XA disjoint XR +XA disjoint XS +XA disjoint XT +XA disjoint XU +XA disjoint XV +XA disjoint XW +XA disjoint XX +XA disjoint XY +XA disjoint XZ +XA disjoint YA +XA disjoint YB +XA disjoint YC +XA disjoint YD +XA disjoint YE +XA disjoint YF +XA disjoint YG +XA disjoint YH +XA disjoint YI +XA disjoint YJ +XA disjoint YK +XA disjoint YL +XA disjoint YM +XA disjoint YN +XA disjoint YO +XA disjoint YP +XA disjoint YQ +XB is_contained XA +XB equivalent XB +XB disjoint XC +XB disjoint XD +XB is_contained XE +XB disjoint XF +XB disjoint XG +XB disjoint XH +XB disjoint XI +XB disjoint XJ +XB disjoint XK +XB disjoint XL +XB disjoint XM +XB disjoint XN +XB disjoint XO +XB disjoint XP +XB disjoint XQ +XB disjoint XR +XB disjoint XS +XB disjoint XT +XB disjoint XU +XB disjoint XV +XB disjoint XW +XB disjoint XX +XB disjoint XY +XB disjoint XZ +XB disjoint YA +XB disjoint YB +XB disjoint YC +XB disjoint YD +XB disjoint YE +XB disjoint YF +XB disjoint YG +XB disjoint YH +XB disjoint YI +XB disjoint YJ +XB disjoint YK +XB disjoint YL +XB disjoint YM +XB disjoint YN +XB disjoint YO +XB disjoint YP +XB disjoint YQ +XC disjoint XA +XC disjoint XB +XC equivalent XC +XC is_contained XD +XC disjoint XE +XC disjoint XF +XC disjoint XG +XC disjoint XH +XC disjoint XI +XC disjoint XJ +XC disjoint XK +XC disjoint XL +XC disjoint XM +XC disjoint XN +XC disjoint XO +XC disjoint XP +XC disjoint XQ +XC disjoint XR +XC disjoint XS +XC disjoint XT +XC disjoint XU +XC disjoint XV +XC disjoint XW +XC disjoint XX +XC disjoint XY +XC disjoint XZ +XC disjoint YA +XC disjoint YB +XC disjoint YC +XC disjoint YD +XC disjoint YE +XC disjoint YF +XC disjoint YG +XC disjoint YH +XC disjoint YI +XC disjoint YJ +XC disjoint YK +XC disjoint YL +XC disjoint YM +XC disjoint YN +XC disjoint YO +XC disjoint YP +XC disjoint YQ +XD disjoint XA +XD disjoint XB +XD contains XC +XD equivalent XD +XD disjoint XE +XD disjoint XF +XD disjoint XG +XD disjoint XH +XD disjoint XI +XD disjoint XJ +XD disjoint XK +XD disjoint XL +XD disjoint XM +XD disjoint XN +XD disjoint XO +XD disjoint XP +XD disjoint XQ +XD disjoint XR +XD disjoint XS +XD disjoint XT +XD disjoint XU +XD disjoint XV +XD disjoint XW +XD disjoint XX +XD disjoint XY +XD disjoint XZ +XD disjoint YA +XD disjoint YB +XD disjoint YC +XD disjoint YD +XD disjoint YE +XD disjoint YF +XD disjoint YG +XD disjoint YH +XD disjoint YI +XD disjoint YJ +XD disjoint YK +XD disjoint YL +XD disjoint YM +XD disjoint YN +XD disjoint YO +XD disjoint YP +XD disjoint YQ +XE overlap XA +XE contains XB +XE disjoint XC +XE disjoint XD +XE equivalent XE +XE disjoint XF +XE disjoint XG +XE disjoint XH +XE disjoint XI +XE disjoint XJ +XE disjoint XK +XE disjoint XL +XE disjoint XM +XE disjoint XN +XE disjoint XO +XE disjoint XP +XE disjoint XQ +XE disjoint XR +XE disjoint XS +XE disjoint XT +XE disjoint XU +XE disjoint XV +XE disjoint XW +XE disjoint XX +XE disjoint XY +XE disjoint XZ +XE disjoint YA +XE disjoint YB +XE disjoint YC +XE disjoint YD +XE disjoint YE +XE disjoint YF +XE disjoint YG +XE disjoint YH +XE disjoint YI +XE disjoint YJ +XE disjoint YK +XE disjoint YL +XE disjoint YM +XE disjoint YN +XE disjoint YO +XE disjoint YP +XE disjoint YQ +XF disjoint XA +XF disjoint XB +XF disjoint XC +XF disjoint XD +XF disjoint XE +XF equivalent XF +XF overlap XG +XF overlap XH +XF disjoint XI +XF disjoint XJ +XF disjoint XK +XF disjoint XL +XF disjoint XM +XF disjoint XN +XF disjoint XO +XF disjoint XP +XF disjoint XQ +XF disjoint XR +XF disjoint XS +XF disjoint XT +XF disjoint XU +XF disjoint XV +XF disjoint XW +XF disjoint XX +XF disjoint XY +XF disjoint XZ +XF disjoint YA +XF disjoint YB +XF disjoint YC +XF disjoint YD +XF disjoint YE +XF disjoint YF +XF disjoint YG +XF disjoint YH +XF disjoint YI +XF disjoint YJ +XF disjoint YK +XF disjoint YL +XF disjoint YM +XF disjoint YN +XF disjoint YO +XF disjoint YP +XF disjoint YQ +XG disjoint XA +XG disjoint XB +XG disjoint XC +XG disjoint XD +XG disjoint XE +XG overlap XF +XG equivalent XG +XG overlap XH +XG disjoint XI +XG disjoint XJ +XG disjoint XK +XG disjoint XL +XG disjoint XM +XG disjoint XN +XG disjoint XO +XG disjoint XP +XG disjoint XQ +XG disjoint XR +XG disjoint XS +XG disjoint XT +XG disjoint XU +XG disjoint XV +XG disjoint XW +XG disjoint XX +XG disjoint XY +XG disjoint XZ +XG disjoint YA +XG disjoint YB +XG disjoint YC +XG disjoint YD +XG disjoint YE +XG disjoint YF +XG disjoint YG +XG disjoint YH +XG disjoint YI +XG disjoint YJ +XG disjoint YK +XG disjoint YL +XG disjoint YM +XG disjoint YN +XG disjoint YO +XG disjoint YP +XG disjoint YQ +XH disjoint XA +XH disjoint XB +XH disjoint XC +XH disjoint XD +XH disjoint XE +XH overlap XF +XH overlap XG +XH equivalent XH +XH disjoint XI +XH disjoint XJ +XH disjoint XK +XH disjoint XL +XH disjoint XM +XH disjoint XN +XH disjoint XO +XH disjoint XP +XH disjoint XQ +XH disjoint XR +XH disjoint XS +XH disjoint XT +XH disjoint XU +XH disjoint XV +XH disjoint XW +XH disjoint XX +XH disjoint XY +XH disjoint XZ +XH disjoint YA +XH disjoint YB +XH disjoint YC +XH disjoint YD +XH disjoint YE +XH disjoint YF +XH disjoint YG +XH disjoint YH +XH disjoint YI +XH disjoint YJ +XH disjoint YK +XH disjoint YL +XH disjoint YM +XH disjoint YN +XH disjoint YO +XH disjoint YP +XH disjoint YQ +XI disjoint XA +XI disjoint XB +XI disjoint XC +XI disjoint XD +XI disjoint XE +XI disjoint XF +XI disjoint XG +XI disjoint XH +XI equivalent XI +XI overlap XJ +XI overlap XK +XI disjoint XL +XI disjoint XM +XI disjoint XN +XI disjoint XO +XI disjoint XP +XI disjoint XQ +XI disjoint XR +XI disjoint XS +XI disjoint XT +XI disjoint XU +XI disjoint XV +XI disjoint XW +XI disjoint XX +XI disjoint XY +XI disjoint XZ +XI disjoint YA +XI disjoint YB +XI disjoint YC +XI disjoint YD +XI disjoint YE +XI disjoint YF +XI disjoint YG +XI disjoint YH +XI disjoint YI +XI disjoint YJ +XI disjoint YK +XI disjoint YL +XI disjoint YM +XI disjoint YN +XI disjoint YO +XI disjoint YP +XI disjoint YQ +XJ disjoint XA +XJ disjoint XB +XJ disjoint XC +XJ disjoint XD +XJ disjoint XE +XJ disjoint XF +XJ disjoint XG +XJ disjoint XH +XJ overlap XI +XJ equivalent XJ +XJ overlap XK +XJ disjoint XL +XJ disjoint XM +XJ disjoint XN +XJ disjoint XO +XJ disjoint XP +XJ disjoint XQ +XJ disjoint XR +XJ disjoint XS +XJ disjoint XT +XJ disjoint XU +XJ disjoint XV +XJ disjoint XW +XJ disjoint XX +XJ disjoint XY +XJ disjoint XZ +XJ disjoint YA +XJ disjoint YB +XJ disjoint YC +XJ disjoint YD +XJ disjoint YE +XJ disjoint YF +XJ disjoint YG +XJ disjoint YH +XJ disjoint YI +XJ disjoint YJ +XJ disjoint YK +XJ disjoint YL +XJ disjoint YM +XJ disjoint YN +XJ disjoint YO +XJ disjoint YP +XJ disjoint YQ +XK disjoint XA +XK disjoint XB +XK disjoint XC +XK disjoint XD +XK disjoint XE +XK disjoint XF +XK disjoint XG +XK disjoint XH +XK overlap XI +XK overlap XJ +XK equivalent XK +XK disjoint XL +XK disjoint XM +XK disjoint XN +XK disjoint XO +XK disjoint XP +XK disjoint XQ +XK disjoint XR +XK disjoint XS +XK disjoint XT +XK disjoint XU +XK disjoint XV +XK disjoint XW +XK disjoint XX +XK disjoint XY +XK disjoint XZ +XK disjoint YA +XK disjoint YB +XK disjoint YC +XK disjoint YD +XK disjoint YE +XK disjoint YF +XK disjoint YG +XK disjoint YH +XK disjoint YI +XK disjoint YJ +XK disjoint YK +XK disjoint YL +XK disjoint YM +XK disjoint YN +XK disjoint YO +XK disjoint YP +XK disjoint YQ +XL disjoint XA +XL disjoint XB +XL disjoint XC +XL disjoint XD +XL disjoint XE +XL disjoint XF +XL disjoint XG +XL disjoint XH +XL disjoint XI +XL disjoint XJ +XL disjoint XK +XL equivalent XL +XL overlap XM +XL disjoint XN +XL disjoint XO +XL disjoint XP +XL disjoint XQ +XL disjoint XR +XL disjoint XS +XL disjoint XT +XL disjoint XU +XL disjoint XV +XL disjoint XW +XL disjoint XX +XL disjoint XY +XL disjoint XZ +XL disjoint YA +XL disjoint YB +XL disjoint YC +XL disjoint YD +XL disjoint YE +XL disjoint YF +XL disjoint YG +XL disjoint YH +XL disjoint YI +XL disjoint YJ +XL disjoint YK +XL disjoint YL +XL disjoint YM +XL disjoint YN +XL disjoint YO +XL disjoint YP +XL disjoint YQ +XM disjoint XA +XM disjoint XB +XM disjoint XC +XM disjoint XD +XM disjoint XE +XM disjoint XF +XM disjoint XG +XM disjoint XH +XM disjoint XI +XM disjoint XJ +XM disjoint XK +XM overlap XL +XM equivalent XM +XM disjoint XN +XM disjoint XO +XM disjoint XP +XM disjoint XQ +XM disjoint XR +XM disjoint XS +XM disjoint XT +XM disjoint XU +XM disjoint XV +XM disjoint XW +XM disjoint XX +XM disjoint XY +XM disjoint XZ +XM disjoint YA +XM disjoint YB +XM disjoint YC +XM disjoint YD +XM disjoint YE +XM disjoint YF +XM disjoint YG +XM disjoint YH +XM disjoint YI +XM disjoint YJ +XM disjoint YK +XM disjoint YL +XM disjoint YM +XM disjoint YN +XM disjoint YO +XM disjoint YP +XM disjoint YQ +XN disjoint XA +XN disjoint XB +XN disjoint XC +XN disjoint XD +XN disjoint XE +XN disjoint XF +XN disjoint XG +XN disjoint XH +XN disjoint XI +XN disjoint XJ +XN disjoint XK +XN disjoint XL +XN disjoint XM +XN equivalent XN +XN overlap XO +XN disjoint XP +XN disjoint XQ +XN disjoint XR +XN disjoint XS +XN disjoint XT +XN disjoint XU +XN disjoint XV +XN disjoint XW +XN disjoint XX +XN disjoint XY +XN disjoint XZ +XN disjoint YA +XN disjoint YB +XN disjoint YC +XN disjoint YD +XN disjoint YE +XN disjoint YF +XN disjoint YG +XN disjoint YH +XN disjoint YI +XN disjoint YJ +XN disjoint YK +XN disjoint YL +XN disjoint YM +XN disjoint YN +XN disjoint YO +XN disjoint YP +XN disjoint YQ +XO disjoint XA +XO disjoint XB +XO disjoint XC +XO disjoint XD +XO disjoint XE +XO disjoint XF +XO disjoint XG +XO disjoint XH +XO disjoint XI +XO disjoint XJ +XO disjoint XK +XO disjoint XL +XO disjoint XM +XO overlap XN +XO equivalent XO +XO disjoint XP +XO disjoint XQ +XO disjoint XR +XO disjoint XS +XO disjoint XT +XO disjoint XU +XO disjoint XV +XO disjoint XW +XO disjoint XX +XO disjoint XY +XO disjoint XZ +XO disjoint YA +XO disjoint YB +XO disjoint YC +XO disjoint YD +XO disjoint YE +XO disjoint YF +XO disjoint YG +XO disjoint YH +XO disjoint YI +XO disjoint YJ +XO disjoint YK +XO disjoint YL +XO disjoint YM +XO disjoint YN +XO disjoint YO +XO disjoint YP +XO disjoint YQ +XP disjoint XA +XP disjoint XB +XP disjoint XC +XP disjoint XD +XP disjoint XE +XP disjoint XF +XP disjoint XG +XP disjoint XH +XP disjoint XI +XP disjoint XJ +XP disjoint XK +XP disjoint XL +XP disjoint XM +XP disjoint XN +XP disjoint XO +XP equivalent XP +XP overlap XQ +XP disjoint XR +XP disjoint XS +XP disjoint XT +XP disjoint XU +XP disjoint XV +XP disjoint XW +XP disjoint XX +XP disjoint XY +XP disjoint XZ +XP disjoint YA +XP disjoint YB +XP disjoint YC +XP disjoint YD +XP disjoint YE +XP disjoint YF +XP disjoint YG +XP disjoint YH +XP disjoint YI +XP disjoint YJ +XP disjoint YK +XP disjoint YL +XP disjoint YM +XP disjoint YN +XP disjoint YO +XP disjoint YP +XP disjoint YQ +XQ disjoint XA +XQ disjoint XB +XQ disjoint XC +XQ disjoint XD +XQ disjoint XE +XQ disjoint XF +XQ disjoint XG +XQ disjoint XH +XQ disjoint XI +XQ disjoint XJ +XQ disjoint XK +XQ disjoint XL +XQ disjoint XM +XQ disjoint XN +XQ disjoint XO +XQ overlap XP +XQ equivalent XQ +XQ disjoint XR +XQ disjoint XS +XQ disjoint XT +XQ disjoint XU +XQ disjoint XV +XQ disjoint XW +XQ disjoint XX +XQ disjoint XY +XQ disjoint XZ +XQ disjoint YA +XQ disjoint YB +XQ disjoint YC +XQ disjoint YD +XQ disjoint YE +XQ disjoint YF +XQ disjoint YG +XQ disjoint YH +XQ disjoint YI +XQ disjoint YJ +XQ disjoint YK +XQ disjoint YL +XQ disjoint YM +XQ disjoint YN +XQ disjoint YO +XQ disjoint YP +XQ disjoint YQ +XR disjoint XA +XR disjoint XB +XR disjoint XC +XR disjoint XD +XR disjoint XE +XR disjoint XF +XR disjoint XG +XR disjoint XH +XR disjoint XI +XR disjoint XJ +XR disjoint XK +XR disjoint XL +XR disjoint XM +XR disjoint XN +XR disjoint XO +XR disjoint XP +XR disjoint XQ +XR equivalent XR +XR overlap XS +XR disjoint XT +XR disjoint XU +XR disjoint XV +XR disjoint XW +XR disjoint XX +XR disjoint XY +XR disjoint XZ +XR disjoint YA +XR disjoint YB +XR disjoint YC +XR disjoint YD +XR disjoint YE +XR disjoint YF +XR disjoint YG +XR disjoint YH +XR disjoint YI +XR disjoint YJ +XR disjoint YK +XR disjoint YL +XR disjoint YM +XR disjoint YN +XR disjoint YO +XR disjoint YP +XR disjoint YQ +XS disjoint XA +XS disjoint XB +XS disjoint XC +XS disjoint XD +XS disjoint XE +XS disjoint XF +XS disjoint XG +XS disjoint XH +XS disjoint XI +XS disjoint XJ +XS disjoint XK +XS disjoint XL +XS disjoint XM +XS disjoint XN +XS disjoint XO +XS disjoint XP +XS disjoint XQ +XS overlap XR +XS equivalent XS +XS disjoint XT +XS disjoint XU +XS disjoint XV +XS disjoint XW +XS disjoint XX +XS disjoint XY +XS disjoint XZ +XS disjoint YA +XS disjoint YB +XS disjoint YC +XS disjoint YD +XS disjoint YE +XS disjoint YF +XS disjoint YG +XS disjoint YH +XS disjoint YI +XS disjoint YJ +XS disjoint YK +XS disjoint YL +XS disjoint YM +XS disjoint YN +XS disjoint YO +XS disjoint YP +XS disjoint YQ +XT disjoint XA +XT disjoint XB +XT disjoint XC +XT disjoint XD +XT disjoint XE +XT disjoint XF +XT disjoint XG +XT disjoint XH +XT disjoint XI +XT disjoint XJ +XT disjoint XK +XT disjoint XL +XT disjoint XM +XT disjoint XN +XT disjoint XO +XT disjoint XP +XT disjoint XQ +XT disjoint XR +XT disjoint XS +XT equivalent XT +XT overlap XU +XT disjoint XV +XT disjoint XW +XT disjoint XX +XT disjoint XY +XT disjoint XZ +XT disjoint YA +XT disjoint YB +XT disjoint YC +XT disjoint YD +XT disjoint YE +XT disjoint YF +XT disjoint YG +XT disjoint YH +XT disjoint YI +XT disjoint YJ +XT disjoint YK +XT disjoint YL +XT disjoint YM +XT disjoint YN +XT disjoint YO +XT disjoint YP +XT disjoint YQ +XU disjoint XA +XU disjoint XB +XU disjoint XC +XU disjoint XD +XU disjoint XE +XU disjoint XF +XU disjoint XG +XU disjoint XH +XU disjoint XI +XU disjoint XJ +XU disjoint XK +XU disjoint XL +XU disjoint XM +XU disjoint XN +XU disjoint XO +XU disjoint XP +XU disjoint XQ +XU disjoint XR +XU disjoint XS +XU overlap XT +XU equivalent XU +XU disjoint XV +XU disjoint XW +XU disjoint XX +XU disjoint XY +XU disjoint XZ +XU disjoint YA +XU disjoint YB +XU disjoint YC +XU disjoint YD +XU disjoint YE +XU disjoint YF +XU disjoint YG +XU disjoint YH +XU disjoint YI +XU disjoint YJ +XU disjoint YK +XU disjoint YL +XU disjoint YM +XU disjoint YN +XU disjoint YO +XU disjoint YP +XU disjoint YQ +XV disjoint XA +XV disjoint XB +XV disjoint XC +XV disjoint XD +XV disjoint XE +XV disjoint XF +XV disjoint XG +XV disjoint XH +XV disjoint XI +XV disjoint XJ +XV disjoint XK +XV disjoint XL +XV disjoint XM +XV disjoint XN +XV disjoint XO +XV disjoint XP +XV disjoint XQ +XV disjoint XR +XV disjoint XS +XV disjoint XT +XV disjoint XU +XV equivalent XV +XV overlap XW +XV overlap XX +XV overlap XY +XV disjoint XZ +XV disjoint YA +XV disjoint YB +XV disjoint YC +XV disjoint YD +XV disjoint YE +XV disjoint YF +XV disjoint YG +XV disjoint YH +XV disjoint YI +XV disjoint YJ +XV disjoint YK +XV disjoint YL +XV disjoint YM +XV disjoint YN +XV disjoint YO +XV disjoint YP +XV disjoint YQ +XW disjoint XA +XW disjoint XB +XW disjoint XC +XW disjoint XD +XW disjoint XE +XW disjoint XF +XW disjoint XG +XW disjoint XH +XW disjoint XI +XW disjoint XJ +XW disjoint XK +XW disjoint XL +XW disjoint XM +XW disjoint XN +XW disjoint XO +XW disjoint XP +XW disjoint XQ +XW disjoint XR +XW disjoint XS +XW disjoint XT +XW disjoint XU +XW overlap XV +XW equivalent XW +XW overlap XX +XW overlap XY +XW disjoint XZ +XW disjoint YA +XW disjoint YB +XW disjoint YC +XW disjoint YD +XW disjoint YE +XW disjoint YF +XW disjoint YG +XW disjoint YH +XW disjoint YI +XW disjoint YJ +XW disjoint YK +XW disjoint YL +XW disjoint YM +XW disjoint YN +XW disjoint YO +XW disjoint YP +XW disjoint YQ +XX disjoint XA +XX disjoint XB +XX disjoint XC +XX disjoint XD +XX disjoint XE +XX disjoint XF +XX disjoint XG +XX disjoint XH +XX disjoint XI +XX disjoint XJ +XX disjoint XK +XX disjoint XL +XX disjoint XM +XX disjoint XN +XX disjoint XO +XX disjoint XP +XX disjoint XQ +XX disjoint XR +XX disjoint XS +XX disjoint XT +XX disjoint XU +XX overlap XV +XX overlap XW +XX equivalent XX +XX overlap XY +XX disjoint XZ +XX disjoint YA +XX disjoint YB +XX disjoint YC +XX disjoint YD +XX disjoint YE +XX disjoint YF +XX disjoint YG +XX disjoint YH +XX disjoint YI +XX disjoint YJ +XX disjoint YK +XX disjoint YL +XX disjoint YM +XX disjoint YN +XX disjoint YO +XX disjoint YP +XX disjoint YQ +XY disjoint XA +XY disjoint XB +XY disjoint XC +XY disjoint XD +XY disjoint XE +XY disjoint XF +XY disjoint XG +XY disjoint XH +XY disjoint XI +XY disjoint XJ +XY disjoint XK +XY disjoint XL +XY disjoint XM +XY disjoint XN +XY disjoint XO +XY disjoint XP +XY disjoint XQ +XY disjoint XR +XY disjoint XS +XY disjoint XT +XY disjoint XU +XY overlap XV +XY overlap XW +XY overlap XX +XY equivalent XY +XY disjoint XZ +XY disjoint YA +XY disjoint YB +XY disjoint YC +XY disjoint YD +XY disjoint YE +XY disjoint YF +XY disjoint YG +XY disjoint YH +XY disjoint YI +XY disjoint YJ +XY disjoint YK +XY disjoint YL +XY disjoint YM +XY disjoint YN +XY disjoint YO +XY disjoint YP +XY disjoint YQ +XZ disjoint XA +XZ disjoint XB +XZ disjoint XC +XZ disjoint XD +XZ disjoint XE +XZ disjoint XF +XZ disjoint XG +XZ disjoint XH +XZ disjoint XI +XZ disjoint XJ +XZ disjoint XK +XZ disjoint XL +XZ disjoint XM +XZ disjoint XN +XZ disjoint XO +XZ disjoint XP +XZ disjoint XQ +XZ disjoint XR +XZ disjoint XS +XZ disjoint XT +XZ disjoint XU +XZ disjoint XV +XZ disjoint XW +XZ disjoint XX +XZ disjoint XY +XZ equivalent XZ +XZ overlap YA +XZ disjoint YB +XZ disjoint YC +XZ disjoint YD +XZ disjoint YE +XZ disjoint YF +XZ disjoint YG +XZ disjoint YH +XZ disjoint YI +XZ disjoint YJ +XZ disjoint YK +XZ disjoint YL +XZ disjoint YM +XZ disjoint YN +XZ disjoint YO +XZ disjoint YP +XZ disjoint YQ +YA disjoint XA +YA disjoint XB +YA disjoint XC +YA disjoint XD +YA disjoint XE +YA disjoint XF +YA disjoint XG +YA disjoint XH +YA disjoint XI +YA disjoint XJ +YA disjoint XK +YA disjoint XL +YA disjoint XM +YA disjoint XN +YA disjoint XO +YA disjoint XP +YA disjoint XQ +YA disjoint XR +YA disjoint XS +YA disjoint XT +YA disjoint XU +YA disjoint XV +YA disjoint XW +YA disjoint XX +YA disjoint XY +YA overlap XZ +YA equivalent YA +YA disjoint YB +YA disjoint YC +YA disjoint YD +YA disjoint YE +YA disjoint YF +YA disjoint YG +YA disjoint YH +YA disjoint YI +YA disjoint YJ +YA disjoint YK +YA disjoint YL +YA disjoint YM +YA disjoint YN +YA disjoint YO +YA disjoint YP +YA disjoint YQ +YB disjoint XA +YB disjoint XB +YB disjoint XC +YB disjoint XD +YB disjoint XE +YB disjoint XF +YB disjoint XG +YB disjoint XH +YB disjoint XI +YB disjoint XJ +YB disjoint XK +YB disjoint XL +YB disjoint XM +YB disjoint XN +YB disjoint XO +YB disjoint XP +YB disjoint XQ +YB disjoint XR +YB disjoint XS +YB disjoint XT +YB disjoint XU +YB disjoint XV +YB disjoint XW +YB disjoint XX +YB disjoint XY +YB disjoint XZ +YB disjoint YA +YB equivalent YB +YB is_contained YC +YB disjoint YD +YB disjoint YE +YB disjoint YF +YB disjoint YG +YB disjoint YH +YB disjoint YI +YB disjoint YJ +YB disjoint YK +YB disjoint YL +YB disjoint YM +YB disjoint YN +YB disjoint YO +YB disjoint YP +YB disjoint YQ +YC disjoint XA +YC disjoint XB +YC disjoint XC +YC disjoint XD +YC disjoint XE +YC disjoint XF +YC disjoint XG +YC disjoint XH +YC disjoint XI +YC disjoint XJ +YC disjoint XK +YC disjoint XL +YC disjoint XM +YC disjoint XN +YC disjoint XO +YC disjoint XP +YC disjoint XQ +YC disjoint XR +YC disjoint XS +YC disjoint XT +YC disjoint XU +YC disjoint XV +YC disjoint XW +YC disjoint XX +YC disjoint XY +YC disjoint XZ +YC disjoint YA +YC contains YB +YC equivalent YC +YC disjoint YD +YC disjoint YE +YC disjoint YF +YC disjoint YG +YC disjoint YH +YC disjoint YI +YC disjoint YJ +YC disjoint YK +YC disjoint YL +YC disjoint YM +YC disjoint YN +YC disjoint YO +YC disjoint YP +YC disjoint YQ +YD disjoint XA +YD disjoint XB +YD disjoint XC +YD disjoint XD +YD disjoint XE +YD disjoint XF +YD disjoint XG +YD disjoint XH +YD disjoint XI +YD disjoint XJ +YD disjoint XK +YD disjoint XL +YD disjoint XM +YD disjoint XN +YD disjoint XO +YD disjoint XP +YD disjoint XQ +YD disjoint XR +YD disjoint XS +YD disjoint XT +YD disjoint XU +YD disjoint XV +YD disjoint XW +YD disjoint XX +YD disjoint XY +YD disjoint XZ +YD disjoint YA +YD disjoint YB +YD disjoint YC +YD equivalent YD +YD overlap YE +YD disjoint YF +YD disjoint YG +YD disjoint YH +YD disjoint YI +YD disjoint YJ +YD disjoint YK +YD disjoint YL +YD disjoint YM +YD disjoint YN +YD disjoint YO +YD disjoint YP +YD disjoint YQ +YE disjoint XA +YE disjoint XB +YE disjoint XC +YE disjoint XD +YE disjoint XE +YE disjoint XF +YE disjoint XG +YE disjoint XH +YE disjoint XI +YE disjoint XJ +YE disjoint XK +YE disjoint XL +YE disjoint XM +YE disjoint XN +YE disjoint XO +YE disjoint XP +YE disjoint XQ +YE disjoint XR +YE disjoint XS +YE disjoint XT +YE disjoint XU +YE disjoint XV +YE disjoint XW +YE disjoint XX +YE disjoint XY +YE disjoint XZ +YE disjoint YA +YE disjoint YB +YE disjoint YC +YE overlap YD +YE equivalent YE +YE disjoint YF +YE disjoint YG +YE disjoint YH +YE disjoint YI +YE disjoint YJ +YE disjoint YK +YE disjoint YL +YE disjoint YM +YE disjoint YN +YE disjoint YO +YE disjoint YP +YE disjoint YQ +YF disjoint XA +YF disjoint XB +YF disjoint XC +YF disjoint XD +YF disjoint XE +YF disjoint XF +YF disjoint XG +YF disjoint XH +YF disjoint XI +YF disjoint XJ +YF disjoint XK +YF disjoint XL +YF disjoint XM +YF disjoint XN +YF disjoint XO +YF disjoint XP +YF disjoint XQ +YF disjoint XR +YF disjoint XS +YF disjoint XT +YF disjoint XU +YF disjoint XV +YF disjoint XW +YF disjoint XX +YF disjoint XY +YF disjoint XZ +YF disjoint YA +YF disjoint YB +YF disjoint YC +YF disjoint YD +YF disjoint YE +YF equivalent YF +YF is_contained YG +YF disjoint YH +YF disjoint YI +YF disjoint YJ +YF disjoint YK +YF disjoint YL +YF disjoint YM +YF disjoint YN +YF disjoint YO +YF disjoint YP +YF disjoint YQ +YG disjoint XA +YG disjoint XB +YG disjoint XC +YG disjoint XD +YG disjoint XE +YG disjoint XF +YG disjoint XG +YG disjoint XH +YG disjoint XI +YG disjoint XJ +YG disjoint XK +YG disjoint XL +YG disjoint XM +YG disjoint XN +YG disjoint XO +YG disjoint XP +YG disjoint XQ +YG disjoint XR +YG disjoint XS +YG disjoint XT +YG disjoint XU +YG disjoint XV +YG disjoint XW +YG disjoint XX +YG disjoint XY +YG disjoint XZ +YG disjoint YA +YG disjoint YB +YG disjoint YC +YG disjoint YD +YG disjoint YE +YG contains YF +YG equivalent YG +YG disjoint YH +YG disjoint YI +YG disjoint YJ +YG disjoint YK +YG disjoint YL +YG disjoint YM +YG disjoint YN +YG disjoint YO +YG disjoint YP +YG disjoint YQ +YH disjoint XA +YH disjoint XB +YH disjoint XC +YH disjoint XD +YH disjoint XE +YH disjoint XF +YH disjoint XG +YH disjoint XH +YH disjoint XI +YH disjoint XJ +YH disjoint XK +YH disjoint XL +YH disjoint XM +YH disjoint XN +YH disjoint XO +YH disjoint XP +YH disjoint XQ +YH disjoint XR +YH disjoint XS +YH disjoint XT +YH disjoint XU +YH disjoint XV +YH disjoint XW +YH disjoint XX +YH disjoint XY +YH disjoint XZ +YH disjoint YA +YH disjoint YB +YH disjoint YC +YH disjoint YD +YH disjoint YE +YH disjoint YF +YH disjoint YG +YH equivalent YH +YH contains YI +YH disjoint YJ +YH disjoint YK +YH disjoint YL +YH disjoint YM +YH disjoint YN +YH disjoint YO +YH disjoint YP +YH disjoint YQ +YI disjoint XA +YI disjoint XB +YI disjoint XC +YI disjoint XD +YI disjoint XE +YI disjoint XF +YI disjoint XG +YI disjoint XH +YI disjoint XI +YI disjoint XJ +YI disjoint XK +YI disjoint XL +YI disjoint XM +YI disjoint XN +YI disjoint XO +YI disjoint XP +YI disjoint XQ +YI disjoint XR +YI disjoint XS +YI disjoint XT +YI disjoint XU +YI disjoint XV +YI disjoint XW +YI disjoint XX +YI disjoint XY +YI disjoint XZ +YI disjoint YA +YI disjoint YB +YI disjoint YC +YI disjoint YD +YI disjoint YE +YI disjoint YF +YI disjoint YG +YI is_contained YH +YI equivalent YI +YI disjoint YJ +YI disjoint YK +YI disjoint YL +YI disjoint YM +YI disjoint YN +YI disjoint YO +YI disjoint YP +YI disjoint YQ +YJ disjoint XA +YJ disjoint XB +YJ disjoint XC +YJ disjoint XD +YJ disjoint XE +YJ disjoint XF +YJ disjoint XG +YJ disjoint XH +YJ disjoint XI +YJ disjoint XJ +YJ disjoint XK +YJ disjoint XL +YJ disjoint XM +YJ disjoint XN +YJ disjoint XO +YJ disjoint XP +YJ disjoint XQ +YJ disjoint XR +YJ disjoint XS +YJ disjoint XT +YJ disjoint XU +YJ disjoint XV +YJ disjoint XW +YJ disjoint XX +YJ disjoint XY +YJ disjoint XZ +YJ disjoint YA +YJ disjoint YB +YJ disjoint YC +YJ disjoint YD +YJ disjoint YE +YJ disjoint YF +YJ disjoint YG +YJ disjoint YH +YJ disjoint YI +YJ equivalent YJ +YJ is_contained YK +YJ disjoint YL +YJ disjoint YM +YJ disjoint YN +YJ disjoint YO +YJ disjoint YP +YJ disjoint YQ +YK disjoint XA +YK disjoint XB +YK disjoint XC +YK disjoint XD +YK disjoint XE +YK disjoint XF +YK disjoint XG +YK disjoint XH +YK disjoint XI +YK disjoint XJ +YK disjoint XK +YK disjoint XL +YK disjoint XM +YK disjoint XN +YK disjoint XO +YK disjoint XP +YK disjoint XQ +YK disjoint XR +YK disjoint XS +YK disjoint XT +YK disjoint XU +YK disjoint XV +YK disjoint XW +YK disjoint XX +YK disjoint XY +YK disjoint XZ +YK disjoint YA +YK disjoint YB +YK disjoint YC +YK disjoint YD +YK disjoint YE +YK disjoint YF +YK disjoint YG +YK disjoint YH +YK disjoint YI +YK contains YJ +YK equivalent YK +YK disjoint YL +YK disjoint YM +YK disjoint YN +YK disjoint YO +YK disjoint YP +YK disjoint YQ +YL disjoint XA +YL disjoint XB +YL disjoint XC +YL disjoint XD +YL disjoint XE +YL disjoint XF +YL disjoint XG +YL disjoint XH +YL disjoint XI +YL disjoint XJ +YL disjoint XK +YL disjoint XL +YL disjoint XM +YL disjoint XN +YL disjoint XO +YL disjoint XP +YL disjoint XQ +YL disjoint XR +YL disjoint XS +YL disjoint XT +YL disjoint XU +YL disjoint XV +YL disjoint XW +YL disjoint XX +YL disjoint XY +YL disjoint XZ +YL disjoint YA +YL disjoint YB +YL disjoint YC +YL disjoint YD +YL disjoint YE +YL disjoint YF +YL disjoint YG +YL disjoint YH +YL disjoint YI +YL disjoint YJ +YL disjoint YK +YL equivalent YL +YL equivalent YM +YL disjoint YN +YL disjoint YO +YL disjoint YP +YL disjoint YQ +YM disjoint XA +YM disjoint XB +YM disjoint XC +YM disjoint XD +YM disjoint XE +YM disjoint XF +YM disjoint XG +YM disjoint XH +YM disjoint XI +YM disjoint XJ +YM disjoint XK +YM disjoint XL +YM disjoint XM +YM disjoint XN +YM disjoint XO +YM disjoint XP +YM disjoint XQ +YM disjoint XR +YM disjoint XS +YM disjoint XT +YM disjoint XU +YM disjoint XV +YM disjoint XW +YM disjoint XX +YM disjoint XY +YM disjoint XZ +YM disjoint YA +YM disjoint YB +YM disjoint YC +YM disjoint YD +YM disjoint YE +YM disjoint YF +YM disjoint YG +YM disjoint YH +YM disjoint YI +YM disjoint YJ +YM disjoint YK +YM equivalent YL +YM equivalent YM +YM disjoint YN +YM disjoint YO +YM disjoint YP +YM disjoint YQ +YN disjoint XA +YN disjoint XB +YN disjoint XC +YN disjoint XD +YN disjoint XE +YN disjoint XF +YN disjoint XG +YN disjoint XH +YN disjoint XI +YN disjoint XJ +YN disjoint XK +YN disjoint XL +YN disjoint XM +YN disjoint XN +YN disjoint XO +YN disjoint XP +YN disjoint XQ +YN disjoint XR +YN disjoint XS +YN disjoint XT +YN disjoint XU +YN disjoint XV +YN disjoint XW +YN disjoint XX +YN disjoint XY +YN disjoint XZ +YN disjoint YA +YN disjoint YB +YN disjoint YC +YN disjoint YD +YN disjoint YE +YN disjoint YF +YN disjoint YG +YN disjoint YH +YN disjoint YI +YN disjoint YJ +YN disjoint YK +YN disjoint YL +YN disjoint YM +YN equivalent YN +YN is_contained YO +YN disjoint YP +YN disjoint YQ +YO disjoint XA +YO disjoint XB +YO disjoint XC +YO disjoint XD +YO disjoint XE +YO disjoint XF +YO disjoint XG +YO disjoint XH +YO disjoint XI +YO disjoint XJ +YO disjoint XK +YO disjoint XL +YO disjoint XM +YO disjoint XN +YO disjoint XO +YO disjoint XP +YO disjoint XQ +YO disjoint XR +YO disjoint XS +YO disjoint XT +YO disjoint XU +YO disjoint XV +YO disjoint XW +YO disjoint XX +YO disjoint XY +YO disjoint XZ +YO disjoint YA +YO disjoint YB +YO disjoint YC +YO disjoint YD +YO disjoint YE +YO disjoint YF +YO disjoint YG +YO disjoint YH +YO disjoint YI +YO disjoint YJ +YO disjoint YK +YO disjoint YL +YO disjoint YM +YO contains YN +YO equivalent YO +YO disjoint YP +YO disjoint YQ +YP disjoint XA +YP disjoint XB +YP disjoint XC +YP disjoint XD +YP disjoint XE +YP disjoint XF +YP disjoint XG +YP disjoint XH +YP disjoint XI +YP disjoint XJ +YP disjoint XK +YP disjoint XL +YP disjoint XM +YP disjoint XN +YP disjoint XO +YP disjoint XP +YP disjoint XQ +YP disjoint XR +YP disjoint XS +YP disjoint XT +YP disjoint XU +YP disjoint XV +YP disjoint XW +YP disjoint XX +YP disjoint XY +YP disjoint XZ +YP disjoint YA +YP disjoint YB +YP disjoint YC +YP disjoint YD +YP disjoint YE +YP disjoint YF +YP disjoint YG +YP disjoint YH +YP disjoint YI +YP disjoint YJ +YP disjoint YK +YP disjoint YL +YP disjoint YM +YP disjoint YN +YP disjoint YO +YP equivalent YP +YP overlap YQ +YQ disjoint XA +YQ disjoint XB +YQ disjoint XC +YQ disjoint XD +YQ disjoint XE +YQ disjoint XF +YQ disjoint XG +YQ disjoint XH +YQ disjoint XI +YQ disjoint XJ +YQ disjoint XK +YQ disjoint XL +YQ disjoint XM +YQ disjoint XN +YQ disjoint XO +YQ disjoint XP +YQ disjoint XQ +YQ disjoint XR +YQ disjoint XS +YQ disjoint XT +YQ disjoint XU +YQ disjoint XV +YQ disjoint XW +YQ disjoint XX +YQ disjoint XY +YQ disjoint XZ +YQ disjoint YA +YQ disjoint YB +YQ disjoint YC +YQ disjoint YD +YQ disjoint YE +YQ disjoint YF +YQ disjoint YG +YQ disjoint YH +YQ disjoint YI +YQ disjoint YJ +YQ disjoint YK +YQ disjoint YL +YQ disjoint YM +YQ disjoint YN +YQ disjoint YO +YQ overlap YP +YQ equivalent YQ From 32b7b76bd9af3fcd56b75acc5ce7276747db5736 Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 6 Feb 2026 17:17:25 +0100 Subject: [PATCH 463/704] WIP: query --- include/compare.h | 10 +- include/edit.h | 1 + include/index.h | 37 +++ include/lcs_graph.h | 3 +- src/align.h | 1 + src/array.h | 8 +- src/compare.c | 112 +++++++ src/hash_table.h | 10 +- src/index.c | 293 +++++++++++++++++++ src/lcs_graph.c | 2 - src/main.c | 699 +++++++++++--------------------------------- 11 files changed, 630 insertions(+), 546 deletions(-) create mode 100644 include/index.h create mode 100644 src/index.c diff --git a/include/compare.h b/include/compare.h index b4b97ff..6b7aec4 100644 --- a/include/compare.h +++ b/include/compare.h @@ -8,7 +8,7 @@ #include "lcs_graph.h" // GVA_LCS_Graph #include "relations.h" // GVA_Relation #include "types.h" // gva_uint -#include "variant.h" // GVA_VARIANT +#include "variant.h" // GVA_Variant // FIXME: move to lcs_graph as `uniq_atomics`. @@ -23,6 +23,7 @@ bitset_fill(GVA_LCS_Graph const graph, size_t ts[static restrict 1]); +// FIXME: too many similar functions GVA_Relation gva_compare_graphs(GVA_Allocator const allocator, size_t const len_ref, char const reference[static len_ref], @@ -35,4 +36,11 @@ gva_compare_supremals(GVA_Allocator const allocator, GVA_Variant const lhs, GVA_Variant const rhs); +GVA_Relation +gva_compare_with_distance(GVA_Allocator const allocator, + size_t const len_ref, char const reference[static len_ref], + GVA_Variant const lhs, size_t const lhs_distance, + GVA_Variant const rhs, size_t const rhs_distance); + + #endif // GVA_COMPARE_H diff --git a/include/edit.h b/include/edit.h index 30b706d..9fbbbe0 100644 --- a/include/edit.h +++ b/include/edit.h @@ -15,6 +15,7 @@ typedef struct } MNode; +// FIXME: globals extern size_t max_lcs_pos; extern MNode* matches; extern char* uniq; diff --git a/include/index.h b/include/index.h new file mode 100644 index 0000000..e31cf28 --- /dev/null +++ b/include/index.h @@ -0,0 +1,37 @@ +#ifndef GVA_INDEX_H +#define GVA_INDEX_H + + +#include // size_t + +#include "allocator.h" // GVA_Allocator +#include "lcs_graph.h" // GVA_LCS_Graph +#include "variant.h" // GVA_Variant + + +typedef struct GVA_Index GVA_Index; // opaque + + +GVA_Index* +gva_index_init(GVA_Allocator const allocator, + size_t const len, char const reference[static len]); + + +GVA_Index* +gva_index_destroy(GVA_Index* const self); + + +// insertions need to happen in allele-order +void +gva_index_insert(GVA_Index* restrict const self, + size_t const len, char const allele_id[static restrict len], + GVA_Variant const variant, size_t const distance); + + +// FIXME: returns +void +gva_index_query(GVA_Allocator const allocator, + GVA_Index* const self, GVA_LCS_Graph const graph); + + +#endif // GVA_INDEX_H diff --git a/include/lcs_graph.h b/include/lcs_graph.h index 518d063..f1d3f0a 100644 --- a/include/lcs_graph.h +++ b/include/lcs_graph.h @@ -54,13 +54,14 @@ typedef struct GVA_Node* nodes; GVA_Edge* edges; GVA_Node* dom_nodes; - GVA_Variant supremal; + GVA_Variant supremal; // FIXME: remove GVA_String observed; // FIXME: ownership and destroy gva_uint source; gva_uint distance; } GVA_LCS_Graph; +// FIXME: shift -> offset GVA_LCS_Graph gva_lcs_graph_init(GVA_Allocator const allocator, size_t const len_ref, char const reference[static restrict len_ref], diff --git a/src/align.h b/src/align.h index 3721f6c..9ed5ef3 100644 --- a/src/align.h +++ b/src/align.h @@ -35,6 +35,7 @@ typedef struct } LCS_Alignment; +// FIXME: shift -> offset LCS_Alignment lcs_align(GVA_Allocator const allocator, size_t const len_ref, char const reference[static restrict len_ref], diff --git a/src/array.h b/src/array.h index e1b9622..e34675c 100644 --- a/src/array.h +++ b/src/array.h @@ -52,11 +52,11 @@ array_ensure(GVA_Allocator const allocator, void* const self, // Returns `NULL`. // Usage: // a = ARRAY_DESTROY(gva_std_allocator, a); -// Warning: `self` is evaluated multiple times. +// Warning: `allocator and ``self` are evaluated multiple times. #define ARRAY_DESTROY(allocator, self) ( \ (self) == NULL ? NULL : \ - allocator.allocate( \ - allocator.context, \ + (allocator).allocate( \ + (allocator).context, \ array_header(self), \ array_header(self)->capacity * sizeof(*(self)), \ 0 \ @@ -68,7 +68,7 @@ array_ensure(GVA_Allocator const allocator, void* const self, // array. 0 if (re)allocation failed. // Warning: `self` is evaluated multiple times. #define ARRAY_APPEND(allocator, self, value) ( \ - (self) = array_ensure(allocator, (self), sizeof(*(self)), 1), \ + (self) = array_ensure((allocator), (self), sizeof(*(self)), 1), \ (self) == NULL ? 0 : ( \ (self)[array_header(self)->length] = (value), \ array_header(self)->length += 1 \ diff --git a/src/compare.c b/src/compare.c index 94c1514..940163e 100644 --- a/src/compare.c +++ b/src/compare.c @@ -349,3 +349,115 @@ gva_compare_supremals(GVA_Allocator const allocator, return relation; } // gva_compare_supremals + + +GVA_Relation +gva_compare_with_distance(GVA_Allocator const allocator, + size_t const len_ref, char const reference[static len_ref], + GVA_Variant const lhs, size_t const lhs_distance, + GVA_Variant const rhs, size_t const rhs_distance) +{ + if (gva_variant_eq(lhs, rhs)) + { + return GVA_EQUIVALENT; + } // if + + size_t const start = MIN(lhs.start, rhs.start); + size_t const end = MAX(lhs.end, rhs.end); + + size_t const len_lhs = (lhs.start - start) + lhs.sequence.len + (end - lhs.end); + size_t const len_rhs = (rhs.start - start) + rhs.sequence.len + (end - rhs.end); + + size_t distance = 0; + if (len_lhs == 0) + { + distance = len_rhs; + } // if + else if (len_rhs == 0) + { + distance = len_rhs; + } // if + else + { + char* lhs_obs = allocator.allocate(allocator.context, NULL, 0, len_lhs); + char* rhs_obs = allocator.allocate(allocator.context, NULL, 0, len_rhs); + if (lhs_obs == NULL || rhs_obs == NULL) + { + rhs_obs = allocator.allocate(allocator.context, rhs_obs, len_rhs, 0); + lhs_obs = allocator.allocate(allocator.context, lhs_obs, len_lhs, 0); + return -1; // FIXME + } // if + + memcpy(lhs_obs, reference + start, lhs.start - start); + memcpy(lhs_obs + lhs.start - start, lhs.sequence.str, lhs.sequence.len); + memcpy(lhs_obs + lhs.start - start + lhs.sequence.len, reference + lhs.end, end - lhs.end); + memcpy(rhs_obs, reference + start, rhs.start - start); + memcpy(rhs_obs + rhs.start - start, rhs.sequence.str, rhs.sequence.len); + memcpy(rhs_obs + rhs.start - start + rhs.sequence.len, reference + rhs.end, end - rhs.end); + + distance = gva_edit_distance(allocator, len_lhs, lhs_obs, len_rhs, rhs_obs); + rhs_obs = allocator.allocate(allocator.context, rhs_obs, len_rhs, 0); + lhs_obs = allocator.allocate(allocator.context, lhs_obs, len_lhs, 0); + } // else + + if (lhs_distance + rhs_distance == distance) + { + return GVA_DISJOINT; + } // if + + if (lhs_distance - rhs_distance == distance) + { + return GVA_CONTAINS; + } // if + + if (rhs_distance - lhs_distance == distance) + { + return GVA_IS_CONTAINED; + } // if + + size_t const len = end - start + 1; + size_t const start_intersection = MAX(lhs.start, rhs.start); + size_t const end_intersection = MIN(lhs.end, rhs.end); + + GVA_LCS_Graph lhs_graph = gva_lcs_graph_init(allocator, lhs.end - lhs.start, reference + lhs.start, lhs.sequence.len, lhs.sequence.str, lhs.start); + size_t* lhs_dels = bitset_init(allocator, len); // can be one shorter + size_t* lhs_as = bitset_init(allocator, len); + size_t* lhs_cs = bitset_init(allocator, len); + size_t* lhs_gs = bitset_init(allocator, len); + size_t* lhs_ts = bitset_init(allocator, len); + bitset_fill(lhs_graph, start, start_intersection, end_intersection, lhs_dels, lhs_as, lhs_cs, lhs_gs, lhs_ts); + + GVA_LCS_Graph rhs_graph = gva_lcs_graph_init(allocator, rhs.end - rhs.start, reference + rhs.start, rhs.sequence.len, rhs.sequence.str, rhs.start); + size_t* rhs_dels = bitset_init(allocator, len); // can be one shorter + size_t* rhs_as = bitset_init(allocator, len); + size_t* rhs_cs = bitset_init(allocator, len); + size_t* rhs_gs = bitset_init(allocator, len); + size_t* rhs_ts = bitset_init(allocator, len); + bitset_fill(rhs_graph, start, start_intersection, end_intersection, rhs_dels, rhs_as, rhs_cs, rhs_gs, rhs_ts); + + GVA_Relation relation = GVA_DISJOINT; + if (bitset_intersection_cnt(lhs_dels, rhs_dels) > 0 || + bitset_intersection_cnt(lhs_as, rhs_as) > 0 || + bitset_intersection_cnt(lhs_cs, rhs_cs) > 0 || + bitset_intersection_cnt(lhs_gs, rhs_gs) > 0 || + bitset_intersection_cnt(lhs_ts, rhs_ts) > 0) + { + relation = GVA_OVERLAP; + } // if + + rhs_ts = bitset_destroy(allocator, rhs_ts); + rhs_gs = bitset_destroy(allocator, rhs_gs); + rhs_cs = bitset_destroy(allocator, rhs_cs); + rhs_as = bitset_destroy(allocator, rhs_as); + rhs_dels = bitset_destroy(allocator, rhs_dels); + gva_lcs_graph_destroy(allocator, rhs_graph); + + lhs_ts = bitset_destroy(allocator, lhs_ts); + lhs_gs = bitset_destroy(allocator, lhs_gs); + lhs_cs = bitset_destroy(allocator, lhs_cs); + lhs_as = bitset_destroy(allocator, lhs_as); + lhs_dels = bitset_destroy(allocator, lhs_dels); + gva_lcs_graph_destroy(allocator, lhs_graph); + + return relation; +} // gva_compare_with_distance diff --git a/src/hash_table.h b/src/hash_table.h index 4014b0f..865671b 100644 --- a/src/hash_table.h +++ b/src/hash_table.h @@ -12,7 +12,7 @@ #define HASH_TABLE_KEY uint32_t gva_key -static uint32_t const GVA_NOT_FOUND = UINT32_MAX; +static uint32_t const NOT_FOUND = UINT32_MAX; void* @@ -27,16 +27,16 @@ void* hash_table_ensure(GVA_Allocator const allocator, void* const self, size_t const item_size); -#define HASH_TABLE_DESTROY(allocator, self) ARRAY_DESTROY(allocator, self) +#define HASH_TABLE_DESTROY(allocator, self) ARRAY_DESTROY((allocator), (self)) -#define HASH_TABLE_INDEX(self, key) hash_table_index(self, sizeof(*self), key) +#define HASH_TABLE_INDEX(self, key) hash_table_index((self), sizeof(*(self)), (key)) #define HASH_TABLE_SET(allocator, self, key, value) ( \ - (self) = hash_table_ensure(allocator, self, sizeof(*(self))), \ + (self) = hash_table_ensure((allocator), (self), sizeof(*(self))), \ array_header(self)->length += 1, \ - self[hash_table_index(self, sizeof(*(self)), key)] = (value) \ + (self)[hash_table_index((self), sizeof(*(self)), (key))] = (value) \ ) diff --git a/src/index.c b/src/index.c new file mode 100644 index 0000000..95e85e8 --- /dev/null +++ b/src/index.c @@ -0,0 +1,293 @@ +#include // NULL, size_t +#include // memcpy + + +#include "../include/allocator.h" // GVA_Allocator +#include "../include/compare.h" // gva_compare_with_distance +#include "../include/edit.h" // gva_edit_distance +#include "../include/index.h" // GVA_Index, gva_index_* +#include "../include/lcs_graph.h" // GVA_LCS_Graph, gva_edges +#include "../include/relations.h" // GVA_Relation, GVA_CONTAINS, + // GVA_DISJOINT, GVA_EQUIVALENT, + // GVA_IS_CONTAINED +#include "../include/string.h" // GVA_String +#include "../include/types.h" // GVA_NULL, gva_uint +#include "../include/variant.h" // GVA_Variant, gva_variant_* +#include "array.h" // ARRAY_*, array_* +#include "common.h" // MAX, MIN +#include "hash_table.h" // NOT_FOUND, HASH_TABLE_*, hash_table_* +#include "interval_tree.h" // Interval_Tree, interval_tree_* +#include "trie.h" // Trie, trie_* + + +#include // DEBUG + + +typedef struct +{ + gva_uint link; // X-OR link between interval_idx and allele_idx + gva_uint next; +} Join; + + +typedef struct +{ + gva_uint id_idx; + gva_uint distance; + + // wrt to join + gva_uint start; + gva_uint end; +} Allele; + + +struct GVA_Index +{ + GVA_Allocator allocator; + GVA_String reference; + Interval_Tree intervals; + Trie inserted; + Trie ids; + Allele* alleles; + Join* join; +}; + + +static inline GVA_Variant +variant_from_index(GVA_Index const self[static 1], size_t const idx) +{ + return (GVA_Variant) + { + self->intervals.nodes[idx].start, + self->intervals.nodes[idx].end, + trie_string(self->inserted, self->intervals.nodes[idx].inserted) + }; +} // variant_from_index + + +static size_t +variants_distance(GVA_Allocator const allocator, + size_t const len_ref, char const reference[static len_ref], + GVA_Variant const lhs, GVA_Variant const rhs) +{ + size_t const start = MIN(lhs.start, rhs.start); + size_t const end = MAX(lhs.end, rhs.end); + + size_t const len_lhs = (lhs.start - start) + lhs.sequence.len + (end - lhs.end); + size_t const len_rhs = (rhs.start - start) + rhs.sequence.len + (end - rhs.end); + + if (len_lhs == 0) + { + return len_rhs; + } // if + if (len_rhs == 0) + { + return len_lhs; + } // if + + char* lhs_obs = allocator.allocate(allocator.context, NULL, 0, len_lhs); + char* rhs_obs = allocator.allocate(allocator.context, NULL, 0, len_rhs); + if (lhs_obs == NULL || rhs_obs == NULL) + { + rhs_obs = allocator.allocate(allocator.context, rhs_obs, len_rhs, 0); + lhs_obs = allocator.allocate(allocator.context, lhs_obs, len_lhs, 0); + return -1; // FIXME: OOM + } // if + + memcpy(lhs_obs, reference + start, lhs.start - start); + memcpy(lhs_obs + lhs.start - start, lhs.sequence.str, lhs.sequence.len); + memcpy(lhs_obs + lhs.start - start + lhs.sequence.len, reference + lhs.end, end - lhs.end); + + memcpy(rhs_obs, reference + start, rhs.start - start); + memcpy(rhs_obs + rhs.start - start, rhs.sequence.str, rhs.sequence.len); + memcpy(rhs_obs + rhs.start - start + rhs.sequence.len, reference + rhs.end, end - rhs.end); + + size_t const distance = gva_edit_distance(allocator, len_lhs, lhs_obs, len_rhs, rhs_obs); + + rhs_obs = allocator.allocate(allocator.context, rhs_obs, len_rhs, 0); + lhs_obs = allocator.allocate(allocator.context, lhs_obs, len_lhs, 0); + + return distance; +} // variants_distance + + +inline GVA_Index* +gva_index_init(GVA_Allocator const allocator, + size_t const len, char const reference[static len]) +{ + GVA_Index* index = allocator.allocate(allocator.context, NULL, 0, sizeof(*index)); + if (index == NULL) + { + return NULL; + } // if + + index->allocator = allocator; + index->reference = (GVA_String) {len, reference}; + + index->intervals = interval_tree_init(); + index->inserted = trie_init(); + index->ids = trie_init(); + index->join = NULL; + index->alleles = NULL; + + return index; +} // gva_index_init + + +inline GVA_Index* +gva_index_destroy(GVA_Index* const self) +{ + if (self == NULL) + { + return NULL; + } // if + + interval_tree_destroy(self->allocator, &self->intervals); + trie_destroy(self->allocator, &self->inserted); + trie_destroy(self->allocator, &self->ids); + self->join = ARRAY_DESTROY(self->allocator, self->join); + self->alleles = ARRAY_DESTROY(self->allocator, self->alleles); + + return self->allocator.allocate(self->allocator.context, self, sizeof(*self), 0); +} // gva_index_destroy + + +void +gva_index_insert(GVA_Index* restrict const self, + size_t const len, char const allele_id[static restrict len], + GVA_Variant const variant, size_t const distance) +{ + size_t const id_idx = trie_insert(self->allocator, &self->ids, len, allele_id); + size_t allele_idx = array_length(self->alleles) - 1; + + // new allele + if (array_length(self->alleles) == 0 || id_idx != self->alleles[allele_idx].id_idx) + { + allele_idx = ARRAY_APPEND(self->allocator, self->alleles, ((Allele) {id_idx, array_length(self->join), 0, 0})) - 1; + } // if + + // add variant + gva_uint const inserted_idx = trie_insert(self->allocator, &self->inserted, variant.sequence.len, variant.sequence.str); + gva_uint const tmp_idx = ARRAY_APPEND(self->allocator, self->intervals.nodes, + ((Interval_Tree_Node) {{GVA_NULL, GVA_NULL}, + variant.start, variant.end, variant.end, 0, inserted_idx, GVA_NULL, distance})) - 1; + gva_uint const node_idx = interval_tree_insert(&self->intervals, tmp_idx); + // undo append: interval already in the tree + if (node_idx != tmp_idx) + { + array_header(self->intervals.nodes)->length -= 1; + } // if + self->intervals.nodes[node_idx].alleles = ARRAY_APPEND(self->allocator, self->join, ((Join) {node_idx ^ allele_idx, self->intervals.nodes[node_idx].alleles})) - 1; + + // update allele + self->alleles[allele_idx].distance += distance; + self->alleles[allele_idx].end = self->intervals.nodes[node_idx].alleles; +} // gva_index_insert + + +void +gva_index_query(GVA_Allocator const allocator, + GVA_Index* const self, GVA_LCS_Graph const graph) +{ + struct Parts + { + HASH_TABLE_KEY; + gva_uint start; + gva_uint end; + gva_uint distance; + }* parts = hash_table_init(allocator, 1024, sizeof(*parts)); + + for (size_t i = 0; i < array_length(graph.dom_nodes) - 1; ++i) + { + GVA_Variant variant; + gva_edges(graph.observed.str, + graph.dom_nodes[i], graph.dom_nodes[i + 1], + i == 0, i == array_length(graph.dom_nodes) - 2, + &variant); + + fprintf(stderr, " " GVA_VARIANT_FMT_SPDI "\n", GVA_VARIANT_PRINT_SPDI("", variant)); + + gva_uint* intervals = interval_tree_intersection(allocator, self->intervals, variant.start, variant.end); + for (size_t j = 0; j < array_length(intervals); ++j) + { + fprintf(stderr, " check: " GVA_VARIANT_FMT_SPDI "\n", GVA_VARIANT_PRINT_SPDI("", variant_from_index(self, intervals[j]))); + size_t const distance = variants_distance(allocator, self->reference.len, self->reference.str, variant_from_index(self, intervals[j]), variant); + if (distance >= self->intervals.nodes[intervals[j]].distance + graph.dom_nodes[i + 1].distance) + { + continue; // disjoint + } // if + + size_t const idx = HASH_TABLE_INDEX(parts, intervals[j]); + if (parts[idx].gva_key == intervals[j]) + { + parts[idx].end = i + 1; + fprintf(stderr, " update\n"); + } // if + else + { + HASH_TABLE_SET(allocator, parts, intervals[j], ((struct Parts) {intervals[j], i, i + 1, distance})); + fprintf(stderr, " add new\n"); + } // else + } // for + intervals = ARRAY_DESTROY(allocator, intervals); + } // for + + for (size_t i = 0; i < array_header(parts)->capacity; ++i) + { + if (parts[i].gva_key == NOT_FOUND) + { + continue; + } // if + + fprintf(stderr, "%u %u %u %u\n", parts[i].gva_key, parts[i].start, parts[i].end, parts[i].distance); + + size_t included = 0; + if (parts[i].end - parts[i].start == 1) + { + if (parts[i].distance == 0 || + self->intervals.nodes[parts[i].gva_key].distance - graph.dom_nodes[parts[i].start + 1].distance == parts[i].distance) + { + // equivalent and contains + included = graph.dom_nodes[parts[i].start + 1].distance; + } // if + else if (graph.dom_nodes[parts[i].start + 1].distance - self->intervals.nodes[parts[i].gva_key].distance == parts[i].distance) + { + // is_contained + included = self->intervals.nodes[parts[i].gva_key].distance; + } // if + } // if + + if (included == 0) + { + GVA_Variant variant; + gva_edges(graph.observed.str, + graph.dom_nodes[parts[i].start], graph.dom_nodes[parts[i].end], + parts[i].start == 0, parts[i].end == array_length(graph.dom_nodes) - 2, + &variant); + size_t distance = 0; + for (gva_uint j = parts[i].start; j < parts[i].end; ++j) + { + distance += graph.dom_nodes[j + 1].distance; + } // for + + included = gva_compare_with_distance(allocator, self->reference.len, self->reference.str, + variant_from_index(self, parts[i].gva_key), self->intervals.nodes[parts[i].gva_key].distance, + variant, distance); + + if (included == 0) // disjoint + { + continue; + } // if + } // if + + for (gva_uint j = self->intervals.nodes[parts[i].gva_key].alleles; j != GVA_NULL; j = self->join[j].next) + { + gva_uint const idx = j ^ parts[i].gva_key; + } // for + + } // for + + + + parts = HASH_TABLE_DESTROY(allocator, parts); +} // gva_index_query diff --git a/src/lcs_graph.c b/src/lcs_graph.c index 9f9e9fe..f07b393 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -264,7 +264,6 @@ gva_lcs_graph_init(GVA_Allocator const allocator, } // if } // for - // start constructing the local supremal ARRAY_APPEND(allocator, graph.dom_nodes, ((GVA_Node) @@ -322,7 +321,6 @@ gva_lcs_graph_init(GVA_Allocator const allocator, } // if } // for - // add empty match sink if not already handled because of unique matches if (graph.dom_nodes[array_length(graph.dom_nodes) - 1].link != sink.idx) { diff --git a/src/main.c b/src/main.c index 8fdb200..b106933 100644 --- a/src/main.c +++ b/src/main.c @@ -11,6 +11,7 @@ #include "../include/compare.h" // bitset_fill #include "../include/edit.h" // gva_edit_distance #include "../include/extractor.h" // gva_canonical +#include "../include/index.h" // GVA_Index, gva_index_* #include "../include/lcs_graph.h" // GVA_LCS_Graph, GVA_Variant, gva_lcs_graph_*, gva_edges #include "../include/std_alloc.h" // gva_std_allocator #include "../include/string.h" // GVA_String, gva_string_destroy @@ -182,131 +183,6 @@ fasta_blob_write(FILE* stream, GVA_String const sequence) } // fasta_blob_write -GVA_Relation -compare_from_index(GVA_String const reference, - GVA_Variant const lhs, gva_uint const lhs_distance, - GVA_Variant const rhs, gva_uint const rhs_distance) -{ - // TODO: possibly reuse rhs_graph - - // fprintf(stderr, GVA_VARIANT_FMT_SPDI " " GVA_VARIANT_FMT_SPDI "\n", - // GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, lhs), - // GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, rhs)); - - if (gva_variant_eq(lhs, rhs)) - { - return GVA_EQUIVALENT; - } // if - - size_t const start = MIN(lhs.start, rhs.start); - size_t const end = MAX(lhs.end, rhs.end); - // fprintf(stderr, "start: %zu end: %zu\n", start, end); - - size_t const lhs_len = (lhs.start - start) + lhs.sequence.len + (end - lhs.end); - size_t const rhs_len = (rhs.start - start) + rhs.sequence.len + (end - rhs.end); - // fprintf(stderr, "lhs_len: %zu rhs_len: %zu\n", lhs_len, rhs_len); - - gva_uint distance = 0; - if (lhs_len == 0) - { - distance = rhs_len; - } // if - else if (rhs_len == 0) - { - distance = lhs_len; - } // if - else - { - char* lhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, NULL, 0, lhs_len); - if (lhs_obs == NULL) - { - return -1; - } // if - memcpy(lhs_obs, reference.str + start, lhs.start - start); - memcpy(lhs_obs + lhs.start - start, lhs.sequence.str, lhs.sequence.len); - memcpy(lhs_obs + lhs.start - start + lhs.sequence.len, reference.str + lhs.end, end - lhs.end); - - char* rhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, NULL, 0, rhs_len); - if (rhs_obs == NULL) - { - lhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, lhs_obs, lhs_len, 0); - return -1; - } // if - memcpy(rhs_obs, reference.str + start, rhs.start - start); - memcpy(rhs_obs + rhs.start - start, rhs.sequence.str, rhs.sequence.len); - memcpy(rhs_obs + rhs.start - start + rhs.sequence.len, reference.str + rhs.end, end - rhs.end); - - distance = gva_edit_distance(gva_std_allocator, lhs_len, lhs_obs, rhs_len, rhs_obs); - rhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, rhs_obs, rhs_len, 0); - lhs_obs = gva_std_allocator.allocate(gva_std_allocator.context, lhs_obs, lhs_len, 0); - } // else - - // fprintf(stderr, "distance: %u lhs_distance: %u rhs_distance: %u\n", distance, lhs_distance, rhs_distance); - - if (lhs_distance + rhs_distance == distance) - { - return GVA_DISJOINT; - } // if - - if (lhs_distance - rhs_distance == distance) - { - // fprintf(stderr, "this return?!\n"); - return GVA_CONTAINS; - } // if - - if (rhs_distance - lhs_distance == distance) - { - return GVA_IS_CONTAINED; - } // if - - size_t const len = end - start + 1; - size_t const start_intersection = MAX(lhs.start, rhs.start); - size_t const end_intersection = MIN(lhs.end, rhs.end); - - GVA_LCS_Graph lhs_graph = gva_lcs_graph_init(gva_std_allocator, lhs.end - lhs.start, reference.str + lhs.start, lhs.sequence.len, lhs.sequence.str, lhs.start); - size_t* lhs_dels = bitset_init(gva_std_allocator, len); // can be one shorter - size_t* lhs_as = bitset_init(gva_std_allocator, len); - size_t* lhs_cs = bitset_init(gva_std_allocator, len); - size_t* lhs_gs = bitset_init(gva_std_allocator, len); - size_t* lhs_ts = bitset_init(gva_std_allocator, len); - bitset_fill(lhs_graph, start, start_intersection, end_intersection, lhs_dels, lhs_as, lhs_cs, lhs_gs, lhs_ts); - - GVA_LCS_Graph rhs_graph = gva_lcs_graph_init(gva_std_allocator, rhs.end - rhs.start, reference.str + rhs.start, rhs.sequence.len, rhs.sequence.str, rhs.start); - size_t* rhs_dels = bitset_init(gva_std_allocator, len); // can be one shorter - size_t* rhs_as = bitset_init(gva_std_allocator, len); - size_t* rhs_cs = bitset_init(gva_std_allocator, len); - size_t* rhs_gs = bitset_init(gva_std_allocator, len); - size_t* rhs_ts = bitset_init(gva_std_allocator, len); - bitset_fill(rhs_graph, start, start_intersection, end_intersection, rhs_dels, rhs_as, rhs_cs, rhs_gs, rhs_ts); - - GVA_Relation relation = GVA_DISJOINT; - if (bitset_intersection_cnt(lhs_dels, rhs_dels) > 0 || - bitset_intersection_cnt(lhs_as, rhs_as) > 0 || - bitset_intersection_cnt(lhs_cs, rhs_cs) > 0 || - bitset_intersection_cnt(lhs_gs, rhs_gs) > 0 || - bitset_intersection_cnt(lhs_ts, rhs_ts) > 0) - { - relation = GVA_OVERLAP; - } // if - - lhs_ts = bitset_destroy(gva_std_allocator, lhs_ts); - lhs_gs = bitset_destroy(gva_std_allocator, lhs_gs); - lhs_cs = bitset_destroy(gva_std_allocator, lhs_cs); - lhs_as = bitset_destroy(gva_std_allocator, lhs_as); - lhs_dels = bitset_destroy(gva_std_allocator, lhs_dels); - gva_lcs_graph_destroy(gva_std_allocator, lhs_graph); - - rhs_ts = bitset_destroy(gva_std_allocator, rhs_ts); - rhs_gs = bitset_destroy(gva_std_allocator, rhs_gs); - rhs_cs = bitset_destroy(gva_std_allocator, rhs_cs); - rhs_as = bitset_destroy(gva_std_allocator, rhs_as); - rhs_dels = bitset_destroy(gva_std_allocator, rhs_dels); - gva_lcs_graph_destroy(gva_std_allocator, rhs_graph); - - return relation; -} // compare_from_index - - static size_t variants_distance(GVA_Allocator const allocator, size_t const len_ref, char const reference[static len_ref], @@ -331,8 +207,8 @@ variants_distance(GVA_Allocator const allocator, char* rhs_obs = allocator.allocate(allocator.context, NULL, 0, rhs_len); if (lhs_obs == NULL || rhs_obs == NULL) { - lhs_obs = allocator.allocate(allocator.context, lhs_obs, lhs_len, 0); rhs_obs = allocator.allocate(allocator.context, rhs_obs, rhs_len, 0); + lhs_obs = allocator.allocate(allocator.context, lhs_obs, lhs_len, 0); return -1; } // if @@ -474,7 +350,7 @@ suffix_trimmed(size_t const len_ref, char const reference[static len_ref], } // suffix_trimmed -int vcf_main(int argc, char* argv[static argc + 1]) +int vcf_main(int argc, char* argv[static argc]) { if (argc < 3) { @@ -651,13 +527,45 @@ repair_is_contained(GVA_Allocator const allocator, GVA_String const reference, G *included += slice_dist; } // else } // if - *nodes = ARRAY_DESTROY(gva_std_allocator, *nodes); + *nodes = ARRAY_DESTROY(gva_std_allocator, *nodes); // FIXME } // repair_is_contained +static bool +parse_line(char const line[static LINE_SIZE], + size_t* id_len, GVA_Variant* variant, size_t* distance) +{ + *id_len = strcspn(line, "\t "); + if (*id_len == 0) + { + return false; + } // if + + size_t const spdi_len = strcspn(line + *id_len + 1, "\t "); + if (gva_parse_spdi(spdi_len, line + *id_len + 1, variant) == 0) + { + return false; + } // if + + *distance = parse_number(line, &(size_t) {*id_len + spdi_len + 2}); + if (*distance == 0) + { + return false; + } // if + + return true; +} // parse_line + + int -dbsnp_main(int argc, char* argv[static argc + 1]) +index_main(int argc, char* argv[static argc]) { + if (argc < 3) + { + fprintf(stderr, "usage %s reference.blob data\n", argv[0]); + return EXIT_FAILURE; + } // if + errno = 0; FILE* stream = fopen(argv[1], "r"); if (stream == NULL) @@ -672,79 +580,11 @@ dbsnp_main(int argc, char* argv[static argc + 1]) fprintf(stderr, "reference length: %zu\n", reference.len); - Trie trie = trie_init(); - Interval_Tree tree = interval_tree_init(); - struct Node_Allele - { - gva_uint link; - gva_uint next; - }* node_allele_join = NULL; - struct Allele + GVA_Index* index = gva_index_init(gva_std_allocator, reference.len, reference.str); + if (index == NULL) { - gva_uint line; - gva_uint join_start; // offset into node_allele_join - gva_uint join_end; // end of offset into node_allele_join - gva_uint distance; - }* db_alleles = NULL; - - size_t line_count = 0; - static char line[LINE_SIZE] = {0}; - while (fgets(line, sizeof(line), stdin) != NULL) - { - size_t idx = 0; - parse_number(line, &idx); - idx += 1; // skip space or tab - int const len = (char*) memchr(line + idx, '\n', LINE_SIZE - idx) - (line + idx); - GVA_Variant variant; - if (gva_parse_spdi(len, line + idx, &variant) == 0) - { - fprintf(stderr, "error: SPDI parsing failed at line %zu: %s", line_count + 1, line); - continue; - } // if - - GVA_LCS_Graph const graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &variant); - - gva_uint const allele_idx = ARRAY_APPEND( - gva_std_allocator, db_alleles, - ((struct Allele) {line_count, array_length(node_allele_join), - array_length(node_allele_join) + array_length(graph.dom_nodes) - 1, - graph.distance}) - ) - 1; - - for (size_t i = 0; i < array_length(graph.dom_nodes) - 1; ++i) - { - GVA_Variant part; - gva_edges(graph.observed.str, - graph.dom_nodes[i], graph.dom_nodes[i + 1], - i == 0, i == array_length(graph.dom_nodes) - 2, - &part); - - gva_uint const inserted_idx = trie_insert(gva_std_allocator, &trie, part.sequence.len, part.sequence.str); - gva_uint const tmp_idx = ARRAY_APPEND(gva_std_allocator, tree.nodes, ((Interval_Tree_Node) {{GVA_NULL, GVA_NULL}, part.start, part.end, part.end, 0, inserted_idx, GVA_NULL, graph.dom_nodes[i + 1].distance})) - 1; - gva_uint const node_idx = interval_tree_insert(&tree, tmp_idx); - if (node_idx != tmp_idx) - { - array_header(tree.nodes)->length -= 1; // reverse; node already in the tree - } // if - tree.nodes[node_idx].alleles = ARRAY_APPEND(gva_std_allocator, node_allele_join, ((struct Node_Allele) {node_idx ^ allele_idx, tree.nodes[node_idx].alleles})) - 1; - } // for - - gva_string_destroy(gva_std_allocator, graph.observed); - gva_lcs_graph_destroy(gva_std_allocator, graph); - - line_count += 1; - } // while - fprintf(stderr, "line count: %zu\n", line_count); - - fprintf(stderr, "tree nodes: %zu\n", array_length(tree.nodes)); - fprintf(stderr, "trie nodes: %zu (%zu)\n", array_length(trie.nodes), trie.strings.len); - - fprintf(stderr, "#db_alleles: %zu\n", array_length(db_alleles)); - fprintf(stderr, "#join: %zu\n", array_length(node_allele_join)); - - if (db_alleles == NULL || node_allele_join == NULL) - { - return -1; + fprintf(stderr, "OOM\n"); + return EXIT_FAILURE; } // if errno = 0; @@ -752,282 +592,60 @@ dbsnp_main(int argc, char* argv[static argc + 1]) if (stream == NULL) { fprintf(stderr, "error: %s\n", strerror(errno)); + gva_string_destroy(gva_std_allocator, reference); return EXIT_FAILURE; } // if - // for every query - line_count = 0; + size_t line_count = 0; + static char line[LINE_SIZE] = {0}; while (fgets(line, sizeof(line), stream) != NULL) { - size_t idx = 0; - parse_number(line, &idx); - idx += 1; // skip space or tab - int const len = (char*) memchr(line + idx, '\n', LINE_SIZE - idx) - (line + idx); - GVA_Variant rhs_var; - if (gva_parse_spdi(len, line + idx, &rhs_var) == 0) + line_count += 1; + size_t id_len = 0; + GVA_Variant variant; + size_t distance = 0; + if (!parse_line(line, &id_len, &variant, &distance)) { - fprintf(stderr, "error: SPDI parsing failed at line %zu: %s", line_count + 1, line); + fprintf(stderr, "parsing failed at line %zu: %s\n", line_count, line); continue; } // if + gva_index_insert(index, id_len, line, variant, distance); + } // while - // Join nodes in the index to parts in the query - struct NODE_PARTS - { - HASH_TABLE_KEY; - GVA_Relation relation; - gva_uint start; - gva_uint end; - gva_uint included; - }* node_parts_table = hash_table_init(gva_std_allocator, 1024, sizeof(*node_parts_table)); - - GVA_LCS_Graph const rhs_graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &rhs_var); - - for (size_t part_idx = 0; part_idx < array_length(rhs_graph.dom_nodes) - 1; ++part_idx) - { - GVA_Variant rhs_part; - gva_edges(rhs_graph.observed.str, - rhs_graph.dom_nodes[part_idx], rhs_graph.dom_nodes[part_idx + 1], - part_idx == 0, part_idx == array_length(rhs_graph.dom_nodes) - 2, - &rhs_part); - - gva_uint const rhs_distance = rhs_graph.dom_nodes[part_idx + 1].distance; - - gva_uint* candidates = interval_tree_intersection(gva_std_allocator, tree, rhs_part.start, rhs_part.end); - for (size_t can_idx = 0; can_idx < array_length(candidates); ++can_idx) - { - gva_uint const node_idx = candidates[can_idx]; - GVA_Variant const db_var = {tree.nodes[node_idx].start, tree.nodes[node_idx].end, - trie_string(trie, tree.nodes[node_idx].inserted)}; - GVA_Relation const relation = compare_from_index(reference, db_var, tree.nodes[node_idx].distance, rhs_part, rhs_distance); - if (relation == GVA_DISJOINT) - { - continue; - } // if - - // link nodes to query parts - size_t hash_idx = HASH_TABLE_INDEX(node_parts_table, node_idx); - if (node_parts_table[hash_idx].gva_key != node_idx) - { - HASH_TABLE_SET(gva_std_allocator, node_parts_table, node_idx, - ((struct NODE_PARTS) {node_idx, relation, part_idx, part_idx + 1, rhs_distance})); - hash_idx = HASH_TABLE_INDEX(node_parts_table, node_idx); - } // if - - if (relation == GVA_EQUIVALENT || relation == GVA_IS_CONTAINED) - { - node_parts_table[hash_idx].included = tree.nodes[node_idx].distance; - } // if - else if (relation == GVA_CONTAINS) - { - node_parts_table[hash_idx].end = part_idx + 1; - } // if - else // GVA_OVERLAP - { - node_parts_table[hash_idx].included = 1; - } // else - } // for every candidate - candidates = ARRAY_DESTROY(gva_std_allocator, candidates); - } // for query allele parts - - // We have now compared all query parts to the index - - // fix containment for multiple parts in single node for every query - for (size_t npt_index = 0; npt_index < array_header(node_parts_table)->capacity; ++npt_index) - { - size_t const node_idx = node_parts_table[npt_index].gva_key; - if (node_idx == GVA_NOT_FOUND) - { - continue; - } // if - - if (node_parts_table[npt_index].relation == GVA_CONTAINS && - node_parts_table[npt_index].end - node_parts_table[npt_index].start > 1) - { - size_t const lhs_distance = tree.nodes[node_idx].distance; - size_t rhs_distance = 0; - for (size_t i = node_parts_table[npt_index].start; i < node_parts_table[npt_index].end; ++i) - { - rhs_distance += rhs_graph.dom_nodes[i + 1].distance; - } // for - if (rhs_distance >= lhs_distance) - { - node_parts_table[npt_index].included = 1; - node_parts_table[npt_index].relation = GVA_OVERLAP; - continue; - } // if - - GVA_Variant const lhs = {tree.nodes[node_idx].start, - tree.nodes[node_idx].end, - trie_string(trie, tree.nodes[node_idx].inserted)}; - - GVA_Variant rhs; - gva_edges(rhs_graph.observed.str, - rhs_graph.dom_nodes[node_parts_table[npt_index].start], - rhs_graph.dom_nodes[node_parts_table[npt_index].end], - node_parts_table[npt_index].start == 0, - node_parts_table[npt_index].end == array_length(rhs_graph.dom_nodes) - 1, - &rhs); - - size_t const distance = variants_distance(gva_std_allocator, reference.len, reference.str, lhs, rhs); - if (lhs_distance - distance == rhs_distance) - { - node_parts_table[npt_index].included = rhs_distance; - } // if - else - { - node_parts_table[npt_index].included = 1; - node_parts_table[npt_index].relation = GVA_OVERLAP; - } // if - } // if - } // for node_parts_table - - struct RESULT_ALLELES - { - HASH_TABLE_KEY; - }* results_table = hash_table_init(gva_std_allocator, 1024, sizeof(*results_table)); - - // find all alleles that were part of a non-disjoint relation - for (size_t npt_idx = 0; npt_idx < array_header(node_parts_table)->capacity; ++npt_idx) - { - size_t const node_idx = node_parts_table[npt_idx].gva_key; - if (node_idx == GVA_NOT_FOUND) - { - continue; - } // if - - for (size_t naj_table_idx = tree.nodes[node_idx].alleles; - naj_table_idx != GVA_NULL; - naj_table_idx = node_allele_join[naj_table_idx].next) - { - size_t const allele_idx = node_allele_join[naj_table_idx].link ^ node_idx; - HASH_TABLE_SET(gva_std_allocator, results_table, allele_idx, ((struct RESULT_ALLELES) {allele_idx})); - } // for alleles - } // for node_parts_table + fclose(stream); - // build result vector for every query - for (size_t results_idx = 0; results_idx < array_header(results_table)->capacity; ++results_idx) + line_count = 0; + while (fgets(line, sizeof(line), stdin) != NULL) + { + line_count += 1; + size_t id_len = 0; + GVA_Variant variant; + size_t distance = 0; + if (!parse_line(line, &id_len, &variant, &distance)) { - size_t allele_idx = results_table[results_idx].gva_key; - if (allele_idx == GVA_NOT_FOUND) - { - continue; - } // if - - gva_uint included = 0; - GVA_Relation relation = GVA_DISJOINT; - - gva_uint* is_contained_nodes = NULL; - gva_uint is_contained_part_idx = -1; - - // loop over all nodes for this allele - for (size_t join_idx = db_alleles[allele_idx].join_start; join_idx < db_alleles[allele_idx].join_end; ++join_idx) - { - size_t node_idx = node_allele_join[join_idx].link ^ allele_idx; - size_t const hash_idx = HASH_TABLE_INDEX(node_parts_table, node_idx); - if (node_idx != node_parts_table[hash_idx].gva_key) - { - continue; - } // if - - if (node_parts_table[hash_idx].relation == GVA_EQUIVALENT) - { - included += node_parts_table[hash_idx].included; - if (relation == GVA_EQUIVALENT || relation == GVA_DISJOINT) - { - relation = GVA_EQUIVALENT; - } // if - } // if - else if (node_parts_table[hash_idx].relation == GVA_CONTAINS) - { - included += node_parts_table[hash_idx].included; - if (relation == GVA_IS_CONTAINED) - { - relation = GVA_OVERLAP; // TODO: included = 1; ??? - break; - } // if - relation = GVA_CONTAINS; - } // if - else if (node_parts_table[hash_idx].relation == GVA_IS_CONTAINED) - { - size_t const part_idx = node_parts_table[hash_idx].start; - if (relation == GVA_CONTAINS) - { - included += node_parts_table[hash_idx].included; // TODO: included = 1; ??? - relation = GVA_OVERLAP; - break; - } // if - - if (part_idx != is_contained_part_idx) - { - repair_is_contained(gva_std_allocator, reference, rhs_graph, tree, trie, - &is_contained_nodes, is_contained_part_idx, &included, &relation); - is_contained_part_idx = part_idx; - } // if - ARRAY_APPEND(gva_std_allocator, is_contained_nodes, node_idx); - relation = GVA_IS_CONTAINED; - } // if - else if (node_parts_table[hash_idx].relation == GVA_OVERLAP) - { - included = 1; - relation = GVA_OVERLAP; - break; - } // if - } // for all nodes for this allele - repair_is_contained(gva_std_allocator, reference, rhs_graph, tree, trie, - &is_contained_nodes, is_contained_part_idx, &included, &relation); - - if (included > 0) - { - gva_uint const lhs_excluded = db_alleles[allele_idx].distance - included; - gva_uint const rhs_excluded = rhs_graph.distance - included; + fprintf(stderr, "parsing failed at line %zu: %s\n", line_count, line); + continue; + } // if - if (lhs_excluded > 0 && rhs_excluded > 0) - { - relation = GVA_OVERLAP; - } // if - else if (lhs_excluded > 0) - { - relation = GVA_CONTAINS; - } // if - else if (rhs_excluded > 0) - { - relation = GVA_IS_CONTAINED; - } // if - else // if (lhs_excluded == 0 && rhs_excluded == 0) - { - relation = GVA_EQUIVALENT; - } // else + GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &variant); - // only for testing - if (relation != GVA_EQUIVALENT || db_alleles[allele_idx].line < line_count) - { - printf("%u %zu %s\n", db_alleles[allele_idx].line, line_count, GVA_RELATION_LABELS[relation]); - } // if - } // if - } // for all alleles + fprintf(stderr, "Query: " GVA_VARIANT_FMT_SPDI " (%u)\n", GVA_VARIANT_PRINT_SPDI("chr1", graph.supremal), graph.distance); - results_table = HASH_TABLE_DESTROY(gva_std_allocator, results_table); - node_parts_table = HASH_TABLE_DESTROY(gva_std_allocator, node_parts_table); + gva_index_query(gva_std_allocator, index, graph); - gva_string_destroy(gva_std_allocator, rhs_graph.observed); - gva_lcs_graph_destroy(gva_std_allocator, rhs_graph); - - line_count += 1; - } // while fgets - fclose(stream); + gva_string_destroy(gva_std_allocator, graph.observed); + gva_lcs_graph_destroy(gva_std_allocator, graph); + } // while - db_alleles = ARRAY_DESTROY(gva_std_allocator, db_alleles); - node_allele_join = ARRAY_DESTROY(gva_std_allocator, node_allele_join); - interval_tree_destroy(gva_std_allocator, &tree); - trie_destroy(gva_std_allocator, &trie); + index = gva_index_destroy(index); gva_string_destroy(gva_std_allocator, reference); return EXIT_SUCCESS; -} // dbsnp_main +} // index_main int -locals_main(int argc, char* argv[static argc + 1]) +locals_main(int argc, char* argv[static argc]) { errno = 0; FILE* stream = fopen(argv[1], "r"); @@ -1082,7 +700,7 @@ locals_main(int argc, char* argv[static argc + 1]) { fprintf(stderr, "error: parsing failed at line %zu: %s", line_count + 1, line); continue; - } + } // if size_t const sample_id = trie_insert(gva_std_allocator, &sample_trie, len, line); // variant @@ -1093,7 +711,7 @@ locals_main(int argc, char* argv[static argc + 1]) { fprintf(stderr, "error: SPDI parsing failed at line %zu: %s", line_count + 1, line); continue; - } // + } // if // distance idx += len + 1; @@ -1102,7 +720,7 @@ locals_main(int argc, char* argv[static argc + 1]) { fprintf(stderr, "error: parsing failed at line %zu: %s", line_count + 1, line); continue; - } + } // if // new sample if (sample_id != prev_sample_id) @@ -1111,11 +729,11 @@ locals_main(int argc, char* argv[static argc + 1]) if (allele_idx > 0) { db_alleles[allele_idx - 1].join_end = array_length(node_allele_join); - } + } // if fprintf(stderr, "allele: %zu (" GVA_STRING_FMT ") (%zu)\n", sample_id, GVA_STRING_PRINT(trie_string(sample_trie, sample_id)), allele_idx); prev_sample_id = sample_id; - } + } // if // fprintf(stderr, "%zu " GVA_VARIANT_FMT " %zu\n", sample_id, GVA_VARIANT_PRINT(variant), distance); db_alleles[allele_idx].distance += distance; @@ -1126,7 +744,7 @@ locals_main(int argc, char* argv[static argc + 1]) gva_uint const node_idx = interval_tree_insert(&tree, tmp_idx); if (node_idx != tmp_idx) { - array_header(tree.nodes)->length -= 1; // reverse; node already in the tree + array_header(tree.nodes)->length -= 1; // undo; node already in the tree } // if tree.nodes[node_idx].alleles = ARRAY_APPEND(gva_std_allocator, node_allele_join, ((struct Node_Allele) {node_idx ^ allele_idx, tree.nodes[node_idx].alleles})) - 1; @@ -1135,7 +753,7 @@ locals_main(int argc, char* argv[static argc + 1]) if (array_length(db_alleles) > 0) { db_alleles[array_length(db_alleles) - 1].join_end = array_length(node_allele_join); - } + } // if fclose(stream); fprintf(stderr, "line count: %zu\n", line_count); fprintf(stderr, "tree nodes: %zu\n", array_length(tree.nodes)); @@ -1154,7 +772,7 @@ locals_main(int argc, char* argv[static argc + 1]) db_alleles[i].distance, db_alleles[i].join_start, db_alleles[i].join_end); - } + } // for // for every query line_count = 0; @@ -1165,7 +783,7 @@ locals_main(int argc, char* argv[static argc + 1]) { fprintf(stderr, "error: parsing failed at line %zu: %s", line_count + 1, line); continue; - } + } // if // variant GVA_Variant rhs_var; @@ -1173,20 +791,20 @@ locals_main(int argc, char* argv[static argc + 1]) { fprintf(stderr, "error: SPDI parsing failed at line %zu: %s", line_count + 1, line); continue; - } // + } // if GVA_LCS_Graph const rhs_graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &rhs_var); // fprintf(stderr, GVA_VARIANT_FMT_SPDI " (%u) \n", GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, rhs_var), rhs_graph.distance); // Join nodes in the index to parts in the query - struct NODE_PARTS + struct Node_Parts { HASH_TABLE_KEY; GVA_Relation relation; gva_uint start; gva_uint end; gva_uint included; - }* node_parts_table = hash_table_init(gva_std_allocator, 1024, sizeof(*node_parts_table)); + }* node_parts = hash_table_init(gva_std_allocator, 1024, sizeof(*node_parts)); for (size_t part_idx = 0; part_idx < array_length(rhs_graph.dom_nodes) - 1; ++part_idx) { @@ -1206,7 +824,7 @@ locals_main(int argc, char* argv[static argc + 1]) gva_uint const node_idx = candidates[can_idx]; GVA_Variant const db_var = {tree.nodes[node_idx].start, tree.nodes[node_idx].end, trie_string(trie, tree.nodes[node_idx].inserted)}; - GVA_Relation const relation = compare_from_index(reference, db_var, tree.nodes[node_idx].distance, rhs_part, rhs_distance); + GVA_Relation const relation = gva_compare_with_distance(gva_std_allocator, reference.len, reference.str, db_var, tree.nodes[node_idx].distance, rhs_part, rhs_distance); if (relation == GVA_DISJOINT) { continue; @@ -1217,28 +835,28 @@ locals_main(int argc, char* argv[static argc + 1]) // GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, rhs_part)); // link nodes to query parts - size_t hash_idx = HASH_TABLE_INDEX(node_parts_table, node_idx); - if (node_parts_table[hash_idx].gva_key != node_idx) + size_t hash_idx = HASH_TABLE_INDEX(node_parts, node_idx); + if (node_parts[hash_idx].gva_key != node_idx) { - HASH_TABLE_SET(gva_std_allocator, node_parts_table, node_idx, - ((struct NODE_PARTS) {node_idx, relation, part_idx, part_idx + 1, rhs_distance})); - hash_idx = HASH_TABLE_INDEX(node_parts_table, node_idx); + HASH_TABLE_SET(gva_std_allocator, node_parts, node_idx, + ((struct Node_Parts) {node_idx, relation, part_idx, part_idx + 1, rhs_distance})); + hash_idx = HASH_TABLE_INDEX(node_parts, node_idx); } // if if (relation == GVA_EQUIVALENT || relation == GVA_IS_CONTAINED) { // TODO: default value is already set for equivalence? - node_parts_table[hash_idx].included = tree.nodes[node_idx].distance; + node_parts[hash_idx].included = tree.nodes[node_idx].distance; } // if else if (relation == GVA_CONTAINS) { - node_parts_table[hash_idx].end = part_idx + 1; + node_parts[hash_idx].end = part_idx + 1; } // if else // GVA_OVERLAP { // TODO: Set relation to OVERLAP? // TODO: +=1 ? - node_parts_table[hash_idx].included = 1; + node_parts[hash_idx].included = 1; } // else } // for every candidate candidates = ARRAY_DESTROY(gva_std_allocator, candidates); @@ -1247,27 +865,27 @@ locals_main(int argc, char* argv[static argc + 1]) // We have now compared all query parts to the index // fix containment for multiple parts in single node for every query - for (size_t npt_index = 0; npt_index < array_header(node_parts_table)->capacity; ++npt_index) + for (size_t npt_index = 0; npt_index < array_header(node_parts)->capacity; ++npt_index) { - size_t const node_idx = node_parts_table[npt_index].gva_key; - if (node_idx == GVA_NOT_FOUND) + size_t const node_idx = node_parts[npt_index].gva_key; + if (node_idx == NOT_FOUND) { continue; } // if - if (node_parts_table[npt_index].relation == GVA_CONTAINS && - node_parts_table[npt_index].end - node_parts_table[npt_index].start > 1) + if (node_parts[npt_index].relation == GVA_CONTAINS && + node_parts[npt_index].end - node_parts[npt_index].start > 1) { size_t const lhs_distance = tree.nodes[node_idx].distance; size_t rhs_distance = 0; - for (size_t i = node_parts_table[npt_index].start; i < node_parts_table[npt_index].end; ++i) + for (size_t i = node_parts[npt_index].start; i < node_parts[npt_index].end; ++i) { rhs_distance += rhs_graph.dom_nodes[i + 1].distance; } // for if (rhs_distance >= lhs_distance) { - node_parts_table[npt_index].included = 1; - node_parts_table[npt_index].relation = GVA_OVERLAP; + node_parts[npt_index].included = 1; + node_parts[npt_index].relation = GVA_OVERLAP; continue; } // if @@ -1277,21 +895,21 @@ locals_main(int argc, char* argv[static argc + 1]) GVA_Variant rhs; gva_edges(rhs_graph.observed.str, - rhs_graph.dom_nodes[node_parts_table[npt_index].start], - rhs_graph.dom_nodes[node_parts_table[npt_index].end], - node_parts_table[npt_index].start == 0, - node_parts_table[npt_index].end == array_length(rhs_graph.dom_nodes) - 1, + rhs_graph.dom_nodes[node_parts[npt_index].start], + rhs_graph.dom_nodes[node_parts[npt_index].end], + node_parts[npt_index].start == 0, + node_parts[npt_index].end == array_length(rhs_graph.dom_nodes) - 1, &rhs); size_t const distance = variants_distance(gva_std_allocator, reference.len, reference.str, lhs, rhs); if (lhs_distance - distance == rhs_distance) { - node_parts_table[npt_index].included = rhs_distance; + node_parts[npt_index].included = rhs_distance; } // if else { - node_parts_table[npt_index].included = 1; - node_parts_table[npt_index].relation = GVA_OVERLAP; + node_parts[npt_index].included = 1; + node_parts[npt_index].relation = GVA_OVERLAP; } // if } // if } // for node_parts_table @@ -1299,16 +917,16 @@ locals_main(int argc, char* argv[static argc + 1]) // TODO: get rid of struct // or // store relation - struct RESULT_ALLELES + struct Result { HASH_TABLE_KEY; - }* results_table = hash_table_init(gva_std_allocator, 1024, sizeof(*results_table)); + }* results = hash_table_init(gva_std_allocator, 1024, sizeof(*results)); // find all alleles that were part of a non-disjoint relation - for (size_t npt_idx = 0; npt_idx < array_header(node_parts_table)->capacity; ++npt_idx) + for (size_t npt_idx = 0; npt_idx < array_header(node_parts)->capacity; ++npt_idx) { - size_t const node_idx = node_parts_table[npt_idx].gva_key; - if (node_idx == GVA_NOT_FOUND) + size_t const node_idx = node_parts[npt_idx].gva_key; + if (node_idx == NOT_FOUND) { continue; } // if @@ -1318,15 +936,15 @@ locals_main(int argc, char* argv[static argc + 1]) naj_table_idx = node_allele_join[naj_table_idx].next) { size_t const allele_idx = node_allele_join[naj_table_idx].link ^ node_idx; - HASH_TABLE_SET(gva_std_allocator, results_table, allele_idx, ((struct RESULT_ALLELES) {allele_idx})); + HASH_TABLE_SET(gva_std_allocator, results, allele_idx, ((struct Result) {allele_idx})); } // for alleles } // for node_parts_table // build result vector for every query - for (size_t results_idx = 0; results_idx < array_header(results_table)->capacity; ++results_idx) + for (size_t results_idx = 0; results_idx < array_header(results)->capacity; ++results_idx) { - size_t allele_idx = results_table[results_idx].gva_key; - if (allele_idx == GVA_NOT_FOUND) + size_t allele_idx = results[results_idx].gva_key; + if (allele_idx == NOT_FOUND) { continue; } // if @@ -1341,23 +959,23 @@ locals_main(int argc, char* argv[static argc + 1]) for (size_t join_idx = db_alleles[allele_idx].join_start; join_idx < db_alleles[allele_idx].join_end; ++join_idx) { size_t node_idx = node_allele_join[join_idx].link ^ allele_idx; - size_t const hash_idx = HASH_TABLE_INDEX(node_parts_table, node_idx); - if (node_idx != node_parts_table[hash_idx].gva_key) + size_t const hash_idx = HASH_TABLE_INDEX(node_parts, node_idx); + if (node_idx != node_parts[hash_idx].gva_key) { continue; } // if - if (node_parts_table[hash_idx].relation == GVA_EQUIVALENT) + if (node_parts[hash_idx].relation == GVA_EQUIVALENT) { - included += node_parts_table[hash_idx].included; + included += node_parts[hash_idx].included; if (relation == GVA_EQUIVALENT || relation == GVA_DISJOINT) { relation = GVA_EQUIVALENT; } // if } // if - else if (node_parts_table[hash_idx].relation == GVA_CONTAINS) + else if (node_parts[hash_idx].relation == GVA_CONTAINS) { - included += node_parts_table[hash_idx].included; + included += node_parts[hash_idx].included; if (relation == GVA_IS_CONTAINED) { relation = GVA_OVERLAP; // TODO: included = 1; ??? @@ -1365,12 +983,12 @@ locals_main(int argc, char* argv[static argc + 1]) } // if relation = GVA_CONTAINS; } // if - else if (node_parts_table[hash_idx].relation == GVA_IS_CONTAINED) + else if (node_parts[hash_idx].relation == GVA_IS_CONTAINED) { - size_t const part_idx = node_parts_table[hash_idx].start; + size_t const part_idx = node_parts[hash_idx].start; if (relation == GVA_CONTAINS) { - included += node_parts_table[hash_idx].included; // TODO: included = 1; ??? + included += node_parts[hash_idx].included; // TODO: included = 1; ??? relation = GVA_OVERLAP; break; } // if @@ -1384,7 +1002,7 @@ locals_main(int argc, char* argv[static argc + 1]) ARRAY_APPEND(gva_std_allocator, is_contained_nodes, node_idx); relation = GVA_IS_CONTAINED; } // if - else if (node_parts_table[hash_idx].relation == GVA_OVERLAP) + else if (node_parts[hash_idx].relation == GVA_OVERLAP) { included = 1; relation = GVA_OVERLAP; @@ -1412,7 +1030,7 @@ locals_main(int argc, char* argv[static argc + 1]) { relation = GVA_IS_CONTAINED; } // if - else // if (lhs_excluded == 0 && rhs_excluded == 0) + else // lhs_excluded == 0 && rhs_excluded == 0 { relation = GVA_EQUIVALENT; } // else @@ -1431,9 +1049,9 @@ locals_main(int argc, char* argv[static argc + 1]) } // if } // for all alleles - results_table = HASH_TABLE_DESTROY(gva_std_allocator, results_table); + results = HASH_TABLE_DESTROY(gva_std_allocator, results); - node_parts_table = HASH_TABLE_DESTROY(gva_std_allocator, node_parts_table); + node_parts = HASH_TABLE_DESTROY(gva_std_allocator, node_parts); gva_string_destroy(gva_std_allocator, rhs_graph.observed); gva_lcs_graph_destroy(gva_std_allocator, rhs_graph); @@ -1451,6 +1069,7 @@ locals_main(int argc, char* argv[static argc + 1]) } // locals_main +// FIXME: to string module? static char* strrev(size_t const n, char str[static n]) { @@ -1468,24 +1087,28 @@ strrev(size_t const n, char str[static n]) } // strrev -GVA_String vcf2obs(GVA_Allocator const allocator, GVA_String reference, FILE *stream) +GVA_String +vcf2obs(GVA_Allocator const allocator, GVA_String const reference, FILE* stream) { - GVA_Variant * variants = NULL; + GVA_Variant* variants = NULL; size_t line_count = 0; size_t dropped = 0; static char line[LINE_SIZE] = {0}; - while (fgets(line, sizeof(line), stream) != NULL) { + while (fgets(line, sizeof(line), stream) != NULL) + { size_t const len = strlen(line) - 1; GVA_Variant variant; - if (gva_parse_spdi(len, line, &variant) == 0) { + if (gva_parse_spdi(len, line, &variant) == 0) + { fprintf(stderr, "error: SPDI parsing failed at line %zu: %s", line_count + 1, line); continue; } // if GVA_Variant trimmed = prefix_trimmed(reference.len, reference.str, variant); - if (array_length(variants) > 0 && trimmed.start < variants[array_length(variants) - 1].end) { + if (array_length(variants) > 0 && trimmed.start < variants[array_length(variants) - 1].end) + { //fprintf(stderr, "dropped: at line %zu: %s", line_count + 1, line); dropped += 1; continue; @@ -1538,7 +1161,7 @@ local_supremal(size_t const len_ref, char const reference[static len_ref], { fprintf(stderr, "distance mismatch between f and b\n"); exit(EXIT_FAILURE); - } + } // if reference = strrev(len_ref, (char*) reference); observed = strrev(len_obs, (char*) observed); @@ -1612,7 +1235,7 @@ local_supremal(size_t const len_ref, char const reference[static len_ref], { fprintf(stderr, "distance mismatch between f and sum\n"); exit(EXIT_FAILURE); - } + } // if forward = gva_std_allocator.allocate(gva_std_allocator.context, forward, MIN(len_ref, len_obs), 0); f_uniq = gva_std_allocator.allocate(gva_std_allocator.context, f_uniq, MIN(len_ref, len_obs), 0); @@ -1622,7 +1245,7 @@ local_supremal(size_t const len_ref, char const reference[static len_ref], int -wu_main(int argc, char* argv[static argc + 1]) +wu_main(int argc, char* argv[static argc]) { if (argc < 3) { @@ -1698,7 +1321,7 @@ wu_main(int argc, char* argv[static argc + 1]) int -slice_blob_main(int argc, char* argv[static argc + 1]) +slice_blob_main(int argc, char* argv[static argc]) { if (argc < 3) { @@ -1756,10 +1379,12 @@ slice_blob_main(int argc, char* argv[static argc + 1]) int -extract_main(int argc, char* argv[static argc + 1]) { +extract_main(int argc, char* argv[static argc]) +{ errno = 0; FILE *stream = fopen(argv[1], "r"); - if (stream == NULL) { + if (stream == NULL) + { fprintf(stderr, "error: %s\n", strerror(errno)); return EXIT_FAILURE; } // if @@ -1775,20 +1400,23 @@ extract_main(int argc, char* argv[static argc + 1]) { lcs_graph_dot(stderr, graph); - return EXIT_SUCCESS; } // extract_main -int make_ref_blob_main(int argc, char* argv[static argc + 1]) { - if (argc < 2) { +int +make_ref_blob_main(int argc, char* argv[static argc]) +{ + if (argc < 2) + { fprintf(stderr, "usage: %s reference\n", argv[0]); return EXIT_FAILURE; } // if errno = 0; FILE *stream = fopen(argv[1], "r"); - if (stream == NULL) { + if (stream == NULL) + { fprintf(stderr, "error: %s\n", strerror(errno)); return EXIT_FAILURE; } // if @@ -1803,15 +1431,19 @@ int make_ref_blob_main(int argc, char* argv[static argc + 1]) { } // make_ref_blob_main -int make_obs_blob_main(int argc, char* argv[static argc + 1]) { - if (argc < 2) { +int +make_obs_blob_main(int argc, char* argv[static argc]) +{ + if (argc < 2) + { fprintf(stderr, "usage: %s reference.blob\n", argv[0]); return EXIT_FAILURE; } // if errno = 0; FILE *stream = fopen(argv[1], "r"); - if (stream == NULL) { + if (stream == NULL) + { fprintf(stderr, "error: %s\n", strerror(errno)); return EXIT_FAILURE; } // if @@ -1828,15 +1460,16 @@ int make_obs_blob_main(int argc, char* argv[static argc + 1]) { int -main(int argc, char* argv[static argc + 1]) +main(int argc, char* argv[static argc]) { // return wu_main(argc, argv); // return slice_blob_main(argc, argv); // return fasta_blob_write(argc, argv); // return vcf_main(argc, argv); // return dbsnp_main(argc, argv); - return locals_main(argc, argv); + // return locals_main(argc, argv); // return extract_main(argc, argv); // return make_ref_blob_main(argc, argv); // return make_obs_blob_main(argc, argv); + return index_main(argc, argv); } // main From 903828679d552c426e12756b4f2ed21c0896f64a Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 6 Feb 2026 18:31:51 +0100 Subject: [PATCH 464/704] Proper local supremals --- truth/XF | 2 +- truth/XJ | 2 +- truth/XS | 4 ++-- truth/XU | 4 ++-- truth/XV | 6 +++--- truth/XX | 2 +- truth/XY | 2 +- truth/YA | 10 +++++----- truth/YB | 2 +- truth/YC | 4 ++-- truth/YE | 4 ++-- truth/YF | 4 ++-- truth/YG | 4 ++-- truth/YI | 6 +++--- truth/YJ | 4 ++-- truth/YK | 4 ++-- truth/YN | 4 ++-- truth/YO | 2 +- truth/YP | 4 ++-- truth/YQ | 22 +++++++++++----------- 20 files changed, 48 insertions(+), 48 deletions(-) diff --git a/truth/XF b/truth/XF index 000987f..6b1497b 100644 --- a/truth/XF +++ b/truth/XF @@ -1 +1 @@ -XF NC_000001.11:248956422:-248956422: 2 +XF NC_000001.11:6100897:1:T 2 diff --git a/truth/XJ b/truth/XJ index df6abd0..b31f4b7 100644 --- a/truth/XJ +++ b/truth/XJ @@ -1 +1 @@ -XJ NC_000001.11:248956422:-248956422: 2 +XJ NC_000001.11:15220328:1:G 2 diff --git a/truth/XS b/truth/XS index 466c535..7790296 100644 --- a/truth/XS +++ b/truth/XS @@ -1,2 +1,2 @@ -XS NC_000001.11:209714023:0:GT 4 -XS NC_000001.11:209714024:1:ATT 4 +XS NC_000001.11:209714023:0:GT 2 +XS NC_000001.11:209714024:1:ATT 2 diff --git a/truth/XU b/truth/XU index 1a3e54a..dbead21 100644 --- a/truth/XU +++ b/truth/XU @@ -1,2 +1,2 @@ -XU NC_000001.11:149733077:0:T 4 -XU NC_000001.11:149733078:1:TTTT 4 +XU NC_000001.11:149733077:0:T 1 +XU NC_000001.11:149733078:1:TTTT 3 diff --git a/truth/XV b/truth/XV index 1fb3921..fd7f1cb 100644 --- a/truth/XV +++ b/truth/XV @@ -1,3 +1,3 @@ -XV NC_000001.11:154309540:1:C 5 -XV NC_000001.11:154309582:1:C 5 -XV NC_000001.11:154309584:1: 5 +XV NC_000001.11:154309540:1:C 2 +XV NC_000001.11:154309582:1:C 2 +XV NC_000001.11:154309584:1: 1 diff --git a/truth/XX b/truth/XX index cabfb0f..2b5d31c 100644 --- a/truth/XX +++ b/truth/XX @@ -1 +1 @@ -XX NC_000001.11:248956422:-248956422: 2 +XX NC_000001.11:154309584:1:C 2 diff --git a/truth/XY b/truth/XY index b3edfa6..2004965 100644 --- a/truth/XY +++ b/truth/XY @@ -1 +1 @@ -XY NC_000001.11:248956422:-248956422: 2 +XY NC_000001.11:154309584:1:G 2 diff --git a/truth/YA b/truth/YA index 9a267c2..b9151df 100644 --- a/truth/YA +++ b/truth/YA @@ -1,5 +1,5 @@ -YA NC_000001.11:58651407:0:T 7 -YA NC_000001.11:58651435:1:G 7 -YA NC_000001.11:58651437:0:G 7 -YA NC_000001.11:58651438:0:G 7 -YA NC_000001.11:58651441:1:G 7 +YA NC_000001.11:58651407:0:T 1 +YA NC_000001.11:58651435:1:G 2 +YA NC_000001.11:58651437:0:G 1 +YA NC_000001.11:58651438:0:G 1 +YA NC_000001.11:58651441:1:G 2 diff --git a/truth/YB b/truth/YB index 9114e4c..7850777 100644 --- a/truth/YB +++ b/truth/YB @@ -1 +1 @@ -YB NC_000001.11:248956422:-248956422: 2 +YB NC_000001.11:175225135:1:A 2 diff --git a/truth/YC b/truth/YC index 6172ce1..2e16aff 100644 --- a/truth/YC +++ b/truth/YC @@ -1,2 +1,2 @@ -YC NC_000001.11:175225135:1:A 3 -YC NC_000001.11:175225139:0:A 3 +YC NC_000001.11:175225135:1:A 2 +YC NC_000001.11:175225139:0:A 1 diff --git a/truth/YE b/truth/YE index 338ef30..84878ce 100644 --- a/truth/YE +++ b/truth/YE @@ -1,2 +1,2 @@ -YE NC_000001.11:147276342:0:G 2 -YE NC_000001.11:147276344:0:A 2 +YE NC_000001.11:147276342:0:G 1 +YE NC_000001.11:147276344:0:A 1 diff --git a/truth/YF b/truth/YF index 17d2e6d..38a754e 100644 --- a/truth/YF +++ b/truth/YF @@ -1,2 +1,2 @@ -YF NC_000001.11:248280509:1: 2 -YF NC_000001.11:248280511:0:C 2 +YF NC_000001.11:248280509:1: 1 +YF NC_000001.11:248280511:0:C 1 diff --git a/truth/YG b/truth/YG index d7bf5af..7c403c4 100644 --- a/truth/YG +++ b/truth/YG @@ -1,2 +1,2 @@ -YG NC_000001.11:248280507:3:GT 4 -YG NC_000001.11:248280511:0:C 4 +YG NC_000001.11:248280507:3:GT 3 +YG NC_000001.11:248280511:0:C 1 diff --git a/truth/YI b/truth/YI index 96093ff..9bb055c 100644 --- a/truth/YI +++ b/truth/YI @@ -1,3 +1,3 @@ -YI NC_000001.11:144735947:0:G 3 -YI NC_000001.11:144735948:0:G 3 -YI NC_000001.11:144735949:0:G 3 +YI NC_000001.11:144735947:0:G 1 +YI NC_000001.11:144735948:0:G 1 +YI NC_000001.11:144735949:0:G 1 diff --git a/truth/YJ b/truth/YJ index abe594d..e3acefc 100644 --- a/truth/YJ +++ b/truth/YJ @@ -1,2 +1,2 @@ -YJ NC_000001.11:148271316:0:A 6 -YJ NC_000001.11:148271317:2:TAAGATT 6 +YJ NC_000001.11:148271316:0:A 1 +YJ NC_000001.11:148271317:2:TAAGATT 5 diff --git a/truth/YK b/truth/YK index fd4440d..04b9700 100644 --- a/truth/YK +++ b/truth/YK @@ -1,2 +1,2 @@ -YK NC_000001.11:148271316:0:TA 8 -YK NC_000001.11:148271317:2:TAAGATTT 8 +YK NC_000001.11:148271316:0:TA 2 +YK NC_000001.11:148271317:2:TAAGATTT 6 diff --git a/truth/YN b/truth/YN index 1fdc6ff..68487cc 100644 --- a/truth/YN +++ b/truth/YN @@ -1,2 +1,2 @@ -YN NC_000001.11:164871874:3:A 3 -YN NC_000001.11:164871878:1: 3 +YN NC_000001.11:164871874:3:A 2 +YN NC_000001.11:164871878:1: 1 diff --git a/truth/YO b/truth/YO index 9b09989..5da3da2 100644 --- a/truth/YO +++ b/truth/YO @@ -1 +1 @@ -YO NC_000001.11:248956422:-248956422: 9 +YO NC_000001.11:164871870:9: 9 diff --git a/truth/YP b/truth/YP index fa6bc57..4d9c96a 100644 --- a/truth/YP +++ b/truth/YP @@ -1,2 +1,2 @@ -YP NC_000001.11:2656569:19:CCACCCA 53 -YP NC_000001.11:2656590:58:CCACCAGGCGATCATCCGCAG 53 +YP NC_000001.11:2656569:19:CCACCCA 12 +YP NC_000001.11:2656590:58:CCACCAGGCGATCATCCGCAG 41 diff --git a/truth/YQ b/truth/YQ index 82e4727..62ee41c 100644 --- a/truth/YQ +++ b/truth/YQ @@ -1,11 +1,11 @@ -YQ NC_000001.11:2656569:4:C 49 -YQ NC_000001.11:2656574:1: 49 -YQ NC_000001.11:2656576:12:CCCA 49 -YQ NC_000001.11:2656590:1: 49 -YQ NC_000001.11:2656593:2: 49 -YQ NC_000001.11:2656596:2: 49 -YQ NC_000001.11:2656600:3: 49 -YQ NC_000001.11:2656605:2: 49 -YQ NC_000001.11:2656608:18:CG 49 -YQ NC_000001.11:2656630:10:TC 49 -YQ NC_000001.11:2656641:7:GAAG 49 +YQ NC_000001.11:2656569:4:C 3 +YQ NC_000001.11:2656574:1: 1 +YQ NC_000001.11:2656576:12:CCCA 8 +YQ NC_000001.11:2656590:1: 1 +YQ NC_000001.11:2656593:2: 2 +YQ NC_000001.11:2656596:2: 2 +YQ NC_000001.11:2656600:3: 3 +YQ NC_000001.11:2656605:2: 2 +YQ NC_000001.11:2656608:18:CG 16 +YQ NC_000001.11:2656630:10:TC 8 +YQ NC_000001.11:2656641:7:GAAG 3 From 9397af4b51fc15c4d2a0ead824d0a28d0ffc31bb Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 6 Feb 2026 22:39:29 +0100 Subject: [PATCH 465/704] Debug --- src/index.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/index.c b/src/index.c index 95e85e8..a6e7919 100644 --- a/src/index.c +++ b/src/index.c @@ -205,12 +205,12 @@ gva_index_query(GVA_Allocator const allocator, i == 0, i == array_length(graph.dom_nodes) - 2, &variant); - fprintf(stderr, " " GVA_VARIANT_FMT_SPDI "\n", GVA_VARIANT_PRINT_SPDI("", variant)); + fprintf(stderr, " " GVA_VARIANT_FMT_SPDI "\n", GVA_VARIANT_PRINT_SPDI("NC_000001.11", variant)); gva_uint* intervals = interval_tree_intersection(allocator, self->intervals, variant.start, variant.end); for (size_t j = 0; j < array_length(intervals); ++j) { - fprintf(stderr, " check: " GVA_VARIANT_FMT_SPDI "\n", GVA_VARIANT_PRINT_SPDI("", variant_from_index(self, intervals[j]))); + fprintf(stderr, " check: " GVA_VARIANT_FMT_SPDI "\n", GVA_VARIANT_PRINT_SPDI("NC_000001.11", variant_from_index(self, intervals[j]))); size_t const distance = variants_distance(allocator, self->reference.len, self->reference.str, variant_from_index(self, intervals[j]), variant); if (distance >= self->intervals.nodes[intervals[j]].distance + graph.dom_nodes[i + 1].distance) { @@ -239,7 +239,7 @@ gva_index_query(GVA_Allocator const allocator, continue; } // if - fprintf(stderr, "%u %u %u %u\n", parts[i].gva_key, parts[i].start, parts[i].end, parts[i].distance); + fprintf(stderr, GVA_VARIANT_FMT_SPDI " %u %u %u\n", GVA_VARIANT_PRINT_SPDI("NC_000001.11", variant_from_index(self, parts[i].gva_key)), parts[i].start, parts[i].end, parts[i].distance); size_t included = 0; if (parts[i].end - parts[i].start == 1) From 12acb6d59265710df829ec5451ffc8a95450d930 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Tue, 10 Feb 2026 13:06:11 +0100 Subject: [PATCH 466/704] WIP. --- src/index.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/main.c | 2 +- 2 files changed, 72 insertions(+), 1 deletion(-) diff --git a/src/index.c b/src/index.c index a6e7919..9e4e555 100644 --- a/src/index.c +++ b/src/index.c @@ -158,6 +158,7 @@ gva_index_insert(GVA_Index* restrict const self, GVA_Variant const variant, size_t const distance) { size_t const id_idx = trie_insert(self->allocator, &self->ids, len, allele_id); + fprintf(stderr, "%zu " GVA_STRING_FMT " == " GVA_STRING_FMT "\n", id_idx, GVA_STRING_PRINT(((GVA_String) {len, allele_id})), GVA_STRING_PRINT(trie_string(self->ids, id_idx))); size_t allele_idx = array_length(self->alleles) - 1; // new allele @@ -197,8 +198,16 @@ gva_index_query(GVA_Allocator const allocator, gva_uint distance; }* parts = hash_table_init(allocator, 1024, sizeof(*parts)); + for (size_t i = 0; i < array_length(graph.dom_nodes) - 1; ++i) { + struct X + { + HASH_TABLE_KEY; + gva_uint start; + gva_uint end; + }* x = hash_table_init(allocator, 1024, sizeof(*x)); + GVA_Variant variant; gva_edges(graph.observed.str, graph.dom_nodes[i], graph.dom_nodes[i + 1], @@ -228,8 +237,70 @@ gva_index_query(GVA_Allocator const allocator, HASH_TABLE_SET(allocator, parts, intervals[j], ((struct Parts) {intervals[j], i, i + 1, distance})); fprintf(stderr, " add new\n"); } // else + + for (gva_uint k = self->intervals.nodes[intervals[j]].alleles; k != GVA_NULL; k = self->join[k].next) + { + gva_uint allele_idx = self->join[k].link ^ intervals[j]; + fprintf(stderr, "allele idx: %u - " GVA_STRING_FMT "\n", allele_idx, GVA_STRING_PRINT(trie_string(self->ids, self->alleles[allele_idx].id_idx))); + fprintf(stderr, "allele start: %u\n", self->alleles[allele_idx].start); + + size_t const idx = HASH_TABLE_INDEX(x, allele_idx); + if (x[idx].gva_key == allele_idx) + { + x[idx].end = k + 1; + fprintf(stderr, " update. k: %u\n", k); + } // if + else + { + HASH_TABLE_SET(allocator, x, allele_idx, ((struct X) {allele_idx, k, k + 1})); + fprintf(stderr, " add new. k: %u\n", k); + } // else + } // for + + } // for + + for (size_t j = 0; j < array_header(x)->capacity; ++j) + { + if (x[j].gva_key == NOT_FOUND) + { + continue; + } // if + + fprintf(stderr, "key: %u - " GVA_STRING_FMT "(%u, %u)\n", + x[j].gva_key, GVA_STRING_PRINT(trie_string(self->ids, self->alleles[x[j].gva_key].id_idx)), + x[j].start, x[j].end); + + size_t len = x[j].end - x[j].start; + if (len > 1) + { + GVA_Variant* variants = allocator.allocate(allocator.context, NULL, 0, len * sizeof(*variants)); + size_t distance = 0; + + for (size_t k = 0; k < len; ++k) + { + variants[k] = variant_from_index(self, self->join[x[j].start + k].link ^ x[j].gva_key); + distance += self->intervals.nodes[self->join[x[j].start + k].link ^ x[j].gva_key].distance; + } + + GVA_LCS_Graph lhs_graph = gva_lcs_graph_from_variants(allocator, self->reference.len, self->reference.str, len, variants); + GVA_LCS_Graph rhs_graph = gva_lcs_graph_from_variants(allocator, self->reference.len, self->reference.str, 1, &variant); + + GVA_Relation rel = gva_compare_graphs(allocator, self->reference.len, self->reference.str, lhs_graph, rhs_graph); + + fprintf(stderr, "rel: %s\n", GVA_RELATION_LABELS[rel]); + + + gva_string_destroy(allocator, rhs_graph.observed); + gva_lcs_graph_destroy(allocator, rhs_graph); + gva_string_destroy(allocator, lhs_graph.observed); + gva_lcs_graph_destroy(allocator, lhs_graph); + + variants = allocator.allocate(allocator.context, variants, len * sizeof(*variants), 0); + } } // for + intervals = ARRAY_DESTROY(allocator, intervals); + x = HASH_TABLE_DESTROY(allocator, x); } // for for (size_t i = 0; i < array_header(parts)->capacity; ++i) diff --git a/src/main.c b/src/main.c index b106933..7c6dda9 100644 --- a/src/main.c +++ b/src/main.c @@ -629,7 +629,7 @@ index_main(int argc, char* argv[static argc]) GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &variant); - fprintf(stderr, "Query: " GVA_VARIANT_FMT_SPDI " (%u)\n", GVA_VARIANT_PRINT_SPDI("chr1", graph.supremal), graph.distance); + fprintf(stderr, "\nQuery (" GVA_STRING_FMT "): " GVA_VARIANT_FMT_SPDI " (%u)\n", GVA_STRING_PRINT(((GVA_String){id_len, line})), GVA_VARIANT_PRINT_SPDI("chr1", graph.supremal), graph.distance); gva_index_query(gva_std_allocator, index, graph); From 16c456761e44a25f8ac421098332098c744f2655 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 10 Feb 2026 13:51:35 +0100 Subject: [PATCH 467/704] Made two versions of the edit_distance calculation --- include/edit.h | 24 ++++--- src/edit.c | 151 +++++++++++++++++++++++++++++----------- src/main.c | 184 ++++++++----------------------------------------- 3 files changed, 154 insertions(+), 205 deletions(-) diff --git a/include/edit.h b/include/edit.h index 9fbbbe0..9d10f58 100644 --- a/include/edit.h +++ b/include/edit.h @@ -10,15 +10,15 @@ typedef struct { - gva_uint row; - gva_uint col; -} MNode; - - -// FIXME: globals -extern size_t max_lcs_pos; -extern MNode* matches; -extern char* uniq; + struct Match + { + gva_uint row; + gva_uint col; + }* matches; + char* uniq; + size_t max_lcs_pos; + size_t distance; +} GVA_Matches; size_t @@ -27,4 +27,10 @@ gva_edit_distance(GVA_Allocator const allocator, size_t const len_obs, char const observed[static restrict len_obs]); +GVA_Matches +gva_edit_distance_matches(GVA_Allocator const allocator, + size_t const len_ref, char const reference[static restrict len_ref], + size_t const len_obs, char const observed[static restrict len_obs]); + + #endif // GVA_EDIT_H diff --git a/src/edit.c b/src/edit.c index 83dd954..3ea3658 100644 --- a/src/edit.c +++ b/src/edit.c @@ -8,23 +8,74 @@ #include "common.h" // ABS, MAX -//#include // DEBUG +static inline size_t +onp_snake(size_t const m, char const a[static restrict m], + size_t const n, char const b[static restrict n], + intmax_t const k, + intmax_t const lower, + intmax_t const upper) +{ + size_t col = MAX(lower, upper); + size_t row = col - k; + + while (row < m && col < n && a[row] == b[col]) + { + row += 1; + col += 1; + } // while + return col; +} // onp_snake + + +static size_t +onp_compare(GVA_Allocator const allocator, + size_t const m, char const a[static restrict m], + size_t const n, char const b[static restrict n]) +{ + intmax_t const delta = n - m; + size_t const offset = m + 1; + size_t const size = m + n + 3; + intmax_t* const restrict fp = allocator.allocate(allocator.context, NULL, 0, size * sizeof(*fp)); + if (fp == NULL) + { + return -1; + } // if + for (intmax_t i = -1; i <= delta; ++i) + { + fp[i + offset] = -1; + } // for + + size_t p = 0; + while ((size_t) fp[delta + offset] != n) + { + fp[-p - 1 + offset] = -1; + fp[delta + p + 1 + offset] = -1; + for (intmax_t k = -p; k <= delta - 1; ++k) + { + fp[k + offset] = onp_snake(m, a, n, b, k, fp[k - 1 + offset] + 1, fp[k + 1 + offset]); + } // for + for (intmax_t k = delta + p; k >= delta + 1; --k) + { + fp[k + offset] = onp_snake(m, a, n, b, k, fp[k - 1 + offset] + 1, fp[k + 1 + offset]); + } // for + fp[delta + offset] = onp_snake(m, a, n, b, delta, fp[delta - 1 + offset] + 1, fp[delta + 1 + offset]); + p += 1; + } // while -size_t max_lcs_pos = 0; -MNode* matches = NULL; -char* uniq = NULL; + allocator.allocate(allocator.context, fp, size * sizeof(*fp), 0); + return delta + 2 * (p - 1); +} // onp_compare static inline size_t -onp_snake(size_t const m, char const a[static restrict m], +onp_snake_matches(size_t const m, char const a[static restrict m], size_t const n, char const b[static restrict n], intmax_t const k, intmax_t const lower, intmax_t const upper, - intmax_t const delta, size_t const p, - bool const swapped) + GVA_Matches matches) { size_t col = MAX(lower, upper); size_t row = col - k; @@ -36,33 +87,24 @@ onp_snake(size_t const m, char const a[static restrict m], { row += 1; col += 1; - size_t const lcs_pos = (row + col - ABS(delta) - 2 * p + ABS(d_row - d_col)) / 2; - //fprintf(stderr, "%zu: (%zu, %zu)\n", lcs_pos - 1, row - 1, col - 1); - uniq[lcs_pos - 1] = 0; - //matches[lcs_pos - 1] = (MNode) {-1, -1}; - if (lcs_pos > max_lcs_pos) + size_t const lcs_pos = (row + col - (n - m) - 2 * p + ABS(d_row - d_col)) / 2; + matches.uniq[lcs_pos - 1] = 0; + if (lcs_pos > matches.max_lcs_pos) { - max_lcs_pos = lcs_pos; - uniq[lcs_pos - 1] = 1; - if (swapped) - { - matches[lcs_pos - 1] = (MNode) {col - 1, row - 1}; - } // if - else - { - matches[lcs_pos - 1] = (MNode) {row - 1, col - 1}; - } // else + matches.max_lcs_pos = lcs_pos; + matches.uniq[lcs_pos - 1] = 1; + matches.matches[lcs_pos - 1].row = row - 1; + matches.matches[lcs_pos - 1].col = col - 1; } // if } // while return col; -} // onp_snake +} // onp_snake_matches -static size_t -onp_compare(GVA_Allocator const allocator, +static GVA_Matches +onp_compare_matches(GVA_Allocator const allocator, size_t const m, char const a[static restrict m], - size_t const n, char const b[static restrict n], - bool const swapped) + size_t const n, char const b[static restrict n]) { intmax_t const delta = n - m; size_t const offset = m + 1; @@ -70,7 +112,7 @@ onp_compare(GVA_Allocator const allocator, intmax_t* const restrict fp = allocator.allocate(allocator.context, NULL, 0, size * sizeof(*fp)); if (fp == NULL) { - return -1; + return (GVA_Matches) {NULL, NULL, 0, -1}; } // if for (intmax_t i = -1; i <= delta; ++i) @@ -78,9 +120,19 @@ onp_compare(GVA_Allocator const allocator, fp[i + offset] = -1; } // for - max_lcs_pos = 0; - matches = allocator.allocate(allocator.context, NULL, 0, sizeof(*matches) * m); - uniq = allocator.allocate(allocator.context, NULL, 0, sizeof(*uniq) * m); + GVA_Matches result = + { + .matches = allocator.allocate(allocator.context, NULL, 0, sizeof(*result.matches) * m), + .uniq = allocator.allocate(allocator.context, NULL, 0, sizeof(*result.uniq) * m), + .max_lcs_pos = 0, + }; + if (result.matches == NULL || result.uniq == NULL) + { + result.uniq = allocator.allocate(allocator.context, result.uniq, sizeof(*result.uniq) * m, 0); + result.matches = allocator.allocate(allocator.context, result.matches, sizeof(*result.matches) * m, 0); + allocator.allocate(allocator.context, fp, size * sizeof(*fp), 0); + return (GVA_Matches) {NULL, NULL, 0, -1}; + } // if size_t p = 0; while ((size_t) fp[delta + offset] != n) @@ -89,19 +141,20 @@ onp_compare(GVA_Allocator const allocator, fp[delta + p + 1 + offset] = -1; for (intmax_t k = -p; k <= delta - 1; ++k) { - fp[k + offset] = onp_snake(m, a, n, b, k, fp[k - 1 + offset] + 1, fp[k + 1 + offset], delta, p, swapped); + fp[k + offset] = onp_snake_matches(m, a, n, b, k, fp[k - 1 + offset] + 1, fp[k + 1 + offset], p, result); } // for for (intmax_t k = delta + p; k >= delta + 1; --k) { - fp[k + offset] = onp_snake(m, a, n, b, k, fp[k - 1 + offset] + 1, fp[k + 1 + offset], delta, p, swapped); + fp[k + offset] = onp_snake_matches(m, a, n, b, k, fp[k - 1 + offset] + 1, fp[k + 1 + offset], p, result); } // for - fp[delta + offset] = onp_snake(m, a, n, b, delta, fp[delta - 1 + offset] + 1, fp[delta + 1 + offset], delta, p, swapped); + fp[delta + offset] = onp_snake_matches(m, a, n, b, delta, fp[delta - 1 + offset] + 1, fp[delta + 1 + offset], p, result); p += 1; } // while allocator.allocate(allocator.context, fp, size * sizeof(*fp), 0); - return delta + 2 * (p - 1); -} // onp_compare + result.distance = delta + 2 * (p - 1); + return result; +} // onp_compare_matches inline size_t @@ -109,8 +162,28 @@ gva_edit_distance(GVA_Allocator const allocator, size_t const len_ref, char const reference[static restrict len_ref], size_t const len_obs, char const observed[static restrict len_obs]) { - //fprintf(stderr, "ALIGN\n"); return len_ref > len_obs ? - onp_compare(allocator, len_obs, observed, len_ref, reference, true) : - onp_compare(allocator, len_ref, reference, len_obs, observed, false); + onp_compare(allocator, len_obs, observed, len_ref, reference) : + onp_compare(allocator, len_ref, reference, len_obs, observed); } // gva_edit_distance + + +inline GVA_Matches +gva_edit_distance_matches(GVA_Allocator const allocator, + size_t const len_ref, char const reference[static restrict len_ref], + size_t const len_obs, char const observed[static restrict len_obs]) +{ + if (len_ref > len_obs) + { + GVA_Matches result = onp_compare_matches(allocator, len_obs, observed, len_ref, reference); + for (size_t i = 0; i < result.max_lcs_pos; ++i) + { + gva_uint const temp = result.matches[i].row; + result.matches[i].row = result.matches[i].col; + result.matches[i].col = temp; + } // for + return result; + } // if + + return onp_compare_matches(allocator, len_ref, reference, len_obs, observed); +} // gva_edit_distance_matches diff --git a/src/main.c b/src/main.c index b106933..0fed624 100644 --- a/src/main.c +++ b/src/main.c @@ -450,57 +450,10 @@ int vcf_main(int argc, char* argv[static argc]) fprintf(stderr, "#dropped: %zu\n", dropped); GVA_String observed = gva_patch(gva_std_allocator, reference.len, reference.str, array_length(variants), variants); - GVA_String lss_observed = gva_patch(gva_std_allocator, reference.len, reference.str, array_length(lss), lss); fasta_blob_write(stdout, observed); return EXIT_SUCCESS; - - size_t const in_distance = gva_edit_distance(gva_std_allocator, reference.len, reference.str, observed.len, observed.str); - - for (size_t i = 0; i < MIN(reference.len, observed.len); ++i) - { - if (matches[i].row != (gva_uint) -1) - { - printf("%zu: (%u, %u)\n", i, matches[i].row, matches[i].col); - } // if - } // for - - matches = gva_std_allocator.allocate(gva_std_allocator.context, matches, MIN(reference.len, observed.len), 0); - - fprintf(stderr, "distance: %zu\n", in_distance); - fprintf(stderr, "===OUTPUT===\n"); - fprintf(stderr, "#parts: %zu\n", array_length(lss)); - fprintf(stderr, "distance: %zu\n", distance); - - //printf("%zu\n", in_distance); - - for (size_t i = 0; i < array_length(variants); ++i) - { - gva_string_destroy(gva_std_allocator, variants[i].sequence); - } // for - variants = ARRAY_DESTROY(gva_std_allocator, variants); - - for (size_t i = 0; i < array_length(lss); ++i) - { - gva_string_destroy(gva_std_allocator, lss[i].sequence); - } // for - lss = ARRAY_DESTROY(gva_std_allocator, lss); - - bool const eq = observed.len == lss_observed.len && strncmp(observed.str, lss_observed.str, observed.len) == 0; - - gva_string_destroy(gva_std_allocator, lss_observed); - gva_string_destroy(gva_std_allocator, observed); - gva_string_destroy(gva_std_allocator, reference); - - if (eq) - { - return EXIT_SUCCESS; - } // if - -// fprintf(stderr, "ERROR\n"); - - return EXIT_FAILURE; } // vcf_main @@ -584,6 +537,7 @@ index_main(int argc, char* argv[static argc]) if (index == NULL) { fprintf(stderr, "OOM\n"); + gva_string_destroy(gva_std_allocator, reference); return EXIT_FAILURE; } // if @@ -629,7 +583,7 @@ index_main(int argc, char* argv[static argc]) GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &variant); - fprintf(stderr, "Query: " GVA_VARIANT_FMT_SPDI " (%u)\n", GVA_VARIANT_PRINT_SPDI("chr1", graph.supremal), graph.distance); + fprintf(stderr, "Query: " GVA_VARIANT_FMT_SPDI " (%u)\n", GVA_VARIANT_PRINT_SPDI("NC_000001.11", graph.supremal), graph.distance); gva_index_query(gva_std_allocator, index, graph); @@ -1141,26 +1095,18 @@ local_supremal(size_t const len_ref, char const reference[static len_ref], printf(GVA_VARIANT_FMT_SPDI " %zu\n", GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, ((GVA_Variant) {offset, offset + len_ref, {len_obs, observed}})), len_ref + len_obs); return; } // if - size_t f_distance = gva_edit_distance(gva_std_allocator, len_ref, reference, len_obs, observed); - MNode* forward = matches; - char* f_uniq = uniq; - //fprintf(stderr, "distance: %zu\n", distance); - //fprintf(stderr, "max_lcs_pos: %zu\n", max_lcs_pos); + + GVA_Matches forward = gva_edit_distance_matches(gva_std_allocator, len_ref, reference, len_obs, observed); reference = strrev(len_ref, (char*) reference); observed = strrev(len_obs, (char*) observed); - size_t b_distance = gva_edit_distance(gva_std_allocator, len_ref, reference, len_obs, observed); - MNode* backward = matches; - char* b_uniq = uniq; - // fprintf(stderr, "wu distance: %zu\n", b_distance); - //fprintf(stderr, "max_lcs_pos: %zu\n", max_lcs_pos); - size_t const max_lcs_pos_local = max_lcs_pos; + GVA_Matches backward = gva_edit_distance_matches(gva_std_allocator, len_ref, reference, len_obs, observed); - if (f_distance != b_distance) + if (forward.distance != backward.distance) { fprintf(stderr, "distance mismatch between f and b\n"); - exit(EXIT_FAILURE); + exit(EXIT_FAILURE); // FIXME } // if reference = strrev(len_ref, (char*) reference); @@ -1170,48 +1116,36 @@ local_supremal(size_t const len_ref, char const reference[static len_ref], size_t prev_lcs_pos = 0; size_t prev_row = -1; size_t prev_col = -1; - for (size_t i = 0; i < max_lcs_pos_local; ++i) + for (size_t i = 0; i < forward.max_lcs_pos; ++i) { - size_t const j = max_lcs_pos_local - i - 1; -/* - if (forward[i].row != (gva_uint) -1 && - backward[j].row != (gva_uint) -1 && - forward[i].row == len_ref - backward[j].row - 1 && - forward[i].col == len_obs - backward[j].col - 1) -*/ - if (forward[i].row == len_ref - backward[j].row - 1 && - forward[i].col == len_obs - backward[j].col - 1 && - (f_uniq[i] == 1 || b_uniq[j] == 1)) + size_t const j = forward.max_lcs_pos - i - 1; + if (forward.matches[i].row == len_ref - backward.matches[j].row - 1 && + forward.matches[i].col == len_obs - backward.matches[j].col - 1 && + (forward.uniq[i] == 1 || backward.uniq[j] == 1)) { #ifdef SMALL - fprintf(stderr, "common: %zu: (%u, %u)\n", i, forward[i].row, forward[i].col); + fprintf(stderr, "common: %zu: (%u, %u)\n", i, forward.matches[i].row, forward.matches[i].col); #endif if (i > prev_lcs_pos + 1 || - forward[i].row > prev_row + 1 || - forward[i].col > prev_col + 1) + forward.matches[i].row > prev_row + 1 || + forward.matches[i].col > prev_col + 1) { - size_t const distance = forward[i].row + forward[i].col - 2 * i - sum; + size_t const distance = forward.matches[i].row + forward.matches[i].col - 2 * i - sum; if (distance > 0) { sum += distance; - //printf("R gap %zu: (%zu, %zu)--(%u, %u) %zu\n", i, prev_row + 1, prev_col + 1, forward[i].row, forward[i].col, distance); - local_supremal(forward[i].row - prev_row - 1, reference + prev_row + 1, forward[i].col - prev_col - 1, observed + prev_col + 1, offset + prev_row + 1); - //printf(GVA_STRING_FMT "\n", (int) (forward[i].row - prev_row - 1), reference + prev_row + 1); - //printf(GVA_STRING_FMT "\n", (int) (forward[i].col - prev_col - 1), observed + prev_col + 1); + local_supremal(forward.matches[i].row - prev_row - 1, reference + prev_row + 1, forward.matches[i].col - prev_col - 1, observed + prev_col + 1, offset + prev_row + 1); } // if } // if prev_lcs_pos = i; - prev_row = forward[i].row; - prev_col = forward[i].col; + prev_row = forward.matches[i].row; + prev_col = forward.matches[i].col; } // if } // for if (len_ref > prev_row + 1 || len_obs > prev_col + 1) { - size_t const distance = len_ref + len_obs - 2 * max_lcs_pos_local - sum; + size_t const distance = len_ref + len_obs - 2 * forward.max_lcs_pos - sum; sum += distance; - // fprintf(stderr, "sum dist: %zu\n", distance); - // printf(GVA_STRING_FMT " ", (int) (len_ref - prev_row - 1), reference + prev_row + 1); - // printf(GVA_STRING_FMT "\n", (int) (len_obs - prev_col - 1), observed + prev_col + 1); GVA_LCS_Graph graph = gva_lcs_graph_init(gva_std_allocator, len_ref - prev_row - 1, reference + prev_row + 1, len_obs - prev_col - 1, observed + prev_col + 1, offset + prev_row + 1); for (size_t i = 0; i < array_length(graph.dom_nodes) - 1; ++i) { @@ -1220,27 +1154,21 @@ local_supremal(size_t const len_ref, char const reference[static len_ref], graph.dom_nodes[i], graph.dom_nodes[i + 1], i == 0, i == array_length(graph.dom_nodes) - 2, &variant); - // printf(GVA_VARIANT_FMT_SPDI " %u\n", GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, variant), graph.dom_nodes[i + 1].distance); + printf(GVA_VARIANT_FMT_SPDI " %u\n", GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, variant), graph.dom_nodes[i + 1].distance); } // for gva_lcs_graph_destroy(gva_std_allocator, graph); - //printf("L " GVA_VARIANT_FMT " %zu %zu+[(%zu, %zu)--(%zu, %zu)]\n", GVA_VARIANT_PRINT(((GVA_Variant) {offset + prev_row + 1, offset + len_ref, {len_obs - prev_col - 1, observed + prev_col + 1}})), distance, offset, prev_row + 1, prev_col + 1, len_ref, len_obs); - //printf("L gap %zu: (%zu, %zu)--(%zu, %zu) %zu\n", max_lcs_pos_local, prev_row + 1, prev_col + 1, len_ref, len_obs, distance); - //printf(GVA_STRING_FMT "\n", (int) (len_ref - prev_row - 1), reference + prev_row + 1); - //printf(GVA_STRING_FMT "\n", (int) (len_obs - prev_col - 1), observed + prev_col + 1); } // if - //fprintf(stderr, "distance: %zu\n", sum); - - if (f_distance != sum) + if (forward.distance != sum) { fprintf(stderr, "distance mismatch between f and sum\n"); - exit(EXIT_FAILURE); + exit(EXIT_FAILURE); // FIXME } // if - forward = gva_std_allocator.allocate(gva_std_allocator.context, forward, MIN(len_ref, len_obs), 0); - f_uniq = gva_std_allocator.allocate(gva_std_allocator.context, f_uniq, MIN(len_ref, len_obs), 0); - backward = gva_std_allocator.allocate(gva_std_allocator.context, backward, MIN(len_ref, len_obs), 0); - b_uniq = gva_std_allocator.allocate(gva_std_allocator.context, b_uniq, MIN(len_ref, len_obs), 0); + backward.uniq = gva_std_allocator.allocate(gva_std_allocator.context, backward.uniq, MIN(len_ref, len_obs), 0); + backward.matches = gva_std_allocator.allocate(gva_std_allocator.context, backward.matches, MIN(len_ref, len_obs) * sizeof(*backward.matches), 0); + forward.uniq = gva_std_allocator.allocate(gva_std_allocator.context, forward.uniq, MIN(len_ref, len_obs), 0); + forward.matches = gva_std_allocator.allocate(gva_std_allocator.context, forward.matches, MIN(len_ref, len_obs) * sizeof(*forward.matches), 0); } // local_supremal @@ -1320,64 +1248,6 @@ wu_main(int argc, char* argv[static argc]) } // wu_main -int -slice_blob_main(int argc, char* argv[static argc]) -{ - if (argc < 3) - { - fprintf(stderr, "usage: %s reference observed\n", argv[0]); - return EXIT_FAILURE; - } // if - - errno = 0; - FILE* stream = fopen(argv[1], "r"); - if (stream == NULL) - { - fprintf(stderr, "error: %s\n", strerror(errno)); - return EXIT_FAILURE; - } // if - - GVA_String reference = gva_fasta_sequence_blob(gva_std_allocator, stream); - fclose(stream); - fprintf(stderr, "reference length: %zu\n", reference.len); - - errno = 0; - stream = fopen(argv[2], "r"); - if (stream == NULL) - { - gva_string_destroy(gva_std_allocator, reference); - fprintf(stderr, "error: %s\n", strerror(errno)); - return EXIT_FAILURE; - } // if - - GVA_String observed = gva_fasta_sequence_blob(gva_std_allocator, stream); - fclose(stream); - fprintf(stderr, "observed length: %zu\n", observed.len); - - if (reference.str == NULL || observed.str == NULL) - { - gva_string_destroy(gva_std_allocator, reference); - gva_string_destroy(gva_std_allocator, observed); - return EXIT_FAILURE; - } // if - - MNode const start = {2750171, 2750160}; - MNode const end = {12954448, 12953797}; - - stream = fopen("ref_p1.blob", "w"); - fasta_blob_write(stream, (GVA_String) {end.row - start.row, reference.str + start.row}); - fclose(stream); - - stream = fopen("obs_p1.blob", "w"); - fasta_blob_write(stream, (GVA_String) {end.col - start.col, observed.str + start.col}); - fclose(stream); - - gva_string_destroy(gva_std_allocator, reference); - gva_string_destroy(gva_std_allocator, observed); - return EXIT_SUCCESS; -} // slice_blob_main - - int extract_main(int argc, char* argv[static argc]) { From 71d69143b260345f4e0e7c4e8be2a06fe55e336d Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 10 Feb 2026 13:56:47 +0100 Subject: [PATCH 468/704] Updated license --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 780503f..f4d3f50 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2025 Leiden University Medical Center +Copyright (c) 2026 Leiden University Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From 304cc9f1e5b30e807f8bed03b836dd8cd0d2107d Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 10 Feb 2026 14:18:01 +0100 Subject: [PATCH 469/704] small --- src/index.c | 40 ++++++++++++++++------------------------ 1 file changed, 16 insertions(+), 24 deletions(-) diff --git a/src/index.c b/src/index.c index 9e4e555..037af90 100644 --- a/src/index.c +++ b/src/index.c @@ -158,7 +158,6 @@ gva_index_insert(GVA_Index* restrict const self, GVA_Variant const variant, size_t const distance) { size_t const id_idx = trie_insert(self->allocator, &self->ids, len, allele_id); - fprintf(stderr, "%zu " GVA_STRING_FMT " == " GVA_STRING_FMT "\n", id_idx, GVA_STRING_PRINT(((GVA_String) {len, allele_id})), GVA_STRING_PRINT(trie_string(self->ids, id_idx))); size_t allele_idx = array_length(self->alleles) - 1; // new allele @@ -167,6 +166,8 @@ gva_index_insert(GVA_Index* restrict const self, allele_idx = ARRAY_APPEND(self->allocator, self->alleles, ((Allele) {id_idx, array_length(self->join), 0, 0})) - 1; } // if + fprintf(stderr, "%zu: " GVA_STRING_FMT "\n", allele_idx, GVA_STRING_PRINT(trie_string(self->ids, id_idx))); + // add variant gva_uint const inserted_idx = trie_insert(self->allocator, &self->inserted, variant.sequence.len, variant.sequence.str); gva_uint const tmp_idx = ARRAY_APPEND(self->allocator, self->intervals.nodes, @@ -198,7 +199,6 @@ gva_index_query(GVA_Allocator const allocator, gva_uint distance; }* parts = hash_table_init(allocator, 1024, sizeof(*parts)); - for (size_t i = 0; i < array_length(graph.dom_nodes) - 1; ++i) { struct X @@ -240,9 +240,8 @@ gva_index_query(GVA_Allocator const allocator, for (gva_uint k = self->intervals.nodes[intervals[j]].alleles; k != GVA_NULL; k = self->join[k].next) { - gva_uint allele_idx = self->join[k].link ^ intervals[j]; + gva_uint const allele_idx = self->join[k].link ^ intervals[j]; fprintf(stderr, "allele idx: %u - " GVA_STRING_FMT "\n", allele_idx, GVA_STRING_PRINT(trie_string(self->ids, self->alleles[allele_idx].id_idx))); - fprintf(stderr, "allele start: %u\n", self->alleles[allele_idx].start); size_t const idx = HASH_TABLE_INDEX(x, allele_idx); if (x[idx].gva_key == allele_idx) @@ -256,7 +255,6 @@ gva_index_query(GVA_Allocator const allocator, fprintf(stderr, " add new. k: %u\n", k); } // else } // for - } // for for (size_t j = 0; j < array_header(x)->capacity; ++j) @@ -266,29 +264,27 @@ gva_index_query(GVA_Allocator const allocator, continue; } // if - fprintf(stderr, "key: %u - " GVA_STRING_FMT "(%u, %u)\n", - x[j].gva_key, GVA_STRING_PRINT(trie_string(self->ids, self->alleles[x[j].gva_key].id_idx)), + fprintf(stderr, GVA_STRING_FMT "[%u, %u)\n", + GVA_STRING_PRINT(trie_string(self->ids, self->alleles[x[j].gva_key].id_idx)), x[j].start, x[j].end); - size_t len = x[j].end - x[j].start; + size_t const len = x[j].end - x[j].start; if (len > 1) { GVA_Variant* variants = allocator.allocate(allocator.context, NULL, 0, len * sizeof(*variants)); size_t distance = 0; - for (size_t k = 0; k < len; ++k) { variants[k] = variant_from_index(self, self->join[x[j].start + k].link ^ x[j].gva_key); distance += self->intervals.nodes[self->join[x[j].start + k].link ^ x[j].gva_key].distance; - } + } // for GVA_LCS_Graph lhs_graph = gva_lcs_graph_from_variants(allocator, self->reference.len, self->reference.str, len, variants); GVA_LCS_Graph rhs_graph = gva_lcs_graph_from_variants(allocator, self->reference.len, self->reference.str, 1, &variant); - GVA_Relation rel = gva_compare_graphs(allocator, self->reference.len, self->reference.str, lhs_graph, rhs_graph); - - fprintf(stderr, "rel: %s\n", GVA_RELATION_LABELS[rel]); + GVA_Relation const relation = gva_compare_graphs(allocator, self->reference.len, self->reference.str, lhs_graph, rhs_graph); + fprintf(stderr, "relation: %s\n", GVA_RELATION_LABELS[relation]); gva_string_destroy(allocator, rhs_graph.observed); gva_lcs_graph_destroy(allocator, rhs_graph); @@ -296,7 +292,7 @@ gva_index_query(GVA_Allocator const allocator, gva_lcs_graph_destroy(allocator, lhs_graph); variants = allocator.allocate(allocator.context, variants, len * sizeof(*variants), 0); - } + } // if } // for intervals = ARRAY_DESTROY(allocator, intervals); @@ -341,24 +337,20 @@ gva_index_query(GVA_Allocator const allocator, distance += graph.dom_nodes[j + 1].distance; } // for - included = gva_compare_with_distance(allocator, self->reference.len, self->reference.str, + fprintf(stderr, "Calculate relation\n"); + + GVA_Relation const relation = gva_compare_with_distance(allocator, self->reference.len, self->reference.str, variant_from_index(self, parts[i].gva_key), self->intervals.nodes[parts[i].gva_key].distance, variant, distance); - if (included == 0) // disjoint + if (relation == GVA_DISJOINT) { continue; } // if - } // if - - for (gva_uint j = self->intervals.nodes[parts[i].gva_key].alleles; j != GVA_NULL; j = self->join[j].next) - { - gva_uint const idx = j ^ parts[i].gva_key; - } // for + fprintf(stderr, "relation: %s\n", GVA_RELATION_LABELS[relation]); + } // if } // for - - parts = HASH_TABLE_DESTROY(allocator, parts); } // gva_index_query From 53a5e15729a8f039f581871e1c88d14997804e38 Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 11 Feb 2026 11:56:43 +0100 Subject: [PATCH 470/704] WIP: queries --- src/index.c | 77 +++++++++- src/main.c | 425 ---------------------------------------------------- 2 files changed, 70 insertions(+), 432 deletions(-) diff --git a/src/index.c b/src/index.c index 037af90..00ed328 100644 --- a/src/index.c +++ b/src/index.c @@ -163,11 +163,9 @@ gva_index_insert(GVA_Index* restrict const self, // new allele if (array_length(self->alleles) == 0 || id_idx != self->alleles[allele_idx].id_idx) { - allele_idx = ARRAY_APPEND(self->allocator, self->alleles, ((Allele) {id_idx, array_length(self->join), 0, 0})) - 1; + allele_idx = ARRAY_APPEND(self->allocator, self->alleles, ((Allele) {id_idx, 0, array_length(self->join), 0})) - 1; } // if - fprintf(stderr, "%zu: " GVA_STRING_FMT "\n", allele_idx, GVA_STRING_PRINT(trie_string(self->ids, id_idx))); - // add variant gva_uint const inserted_idx = trie_insert(self->allocator, &self->inserted, variant.sequence.len, variant.sequence.str); gva_uint const tmp_idx = ARRAY_APPEND(self->allocator, self->intervals.nodes, @@ -191,6 +189,12 @@ void gva_index_query(GVA_Allocator const allocator, GVA_Index* const self, GVA_LCS_Graph const graph) { + struct Y + { + HASH_TABLE_KEY; + gva_uint included; + }* y = hash_table_init(allocator, 1024, sizeof(*y)); + struct Parts { HASH_TABLE_KEY; @@ -241,18 +245,18 @@ gva_index_query(GVA_Allocator const allocator, for (gva_uint k = self->intervals.nodes[intervals[j]].alleles; k != GVA_NULL; k = self->join[k].next) { gva_uint const allele_idx = self->join[k].link ^ intervals[j]; - fprintf(stderr, "allele idx: %u - " GVA_STRING_FMT "\n", allele_idx, GVA_STRING_PRINT(trie_string(self->ids, self->alleles[allele_idx].id_idx))); + fprintf(stderr, " allele idx: %u - " GVA_STRING_FMT "\n", allele_idx, GVA_STRING_PRINT(trie_string(self->ids, self->alleles[allele_idx].id_idx))); size_t const idx = HASH_TABLE_INDEX(x, allele_idx); if (x[idx].gva_key == allele_idx) { x[idx].end = k + 1; - fprintf(stderr, " update. k: %u\n", k); + fprintf(stderr, " update. k: %u\n", k); } // if else { HASH_TABLE_SET(allocator, x, allele_idx, ((struct X) {allele_idx, k, k + 1})); - fprintf(stderr, " add new. k: %u\n", k); + fprintf(stderr, " add new. k: %u\n", k); } // else } // for } // for @@ -264,7 +268,7 @@ gva_index_query(GVA_Allocator const allocator, continue; } // if - fprintf(stderr, GVA_STRING_FMT "[%u, %u)\n", + fprintf(stderr, " " GVA_STRING_FMT "[%u, %u)\n", GVA_STRING_PRINT(trie_string(self->ids, self->alleles[x[j].gva_key].id_idx)), x[j].start, x[j].end); @@ -316,11 +320,13 @@ gva_index_query(GVA_Allocator const allocator, { // equivalent and contains included = graph.dom_nodes[parts[i].start + 1].distance; + fprintf(stderr, "relation: equivalent/contains\n"); } // if else if (graph.dom_nodes[parts[i].start + 1].distance - self->intervals.nodes[parts[i].gva_key].distance == parts[i].distance) { // is_contained included = self->intervals.nodes[parts[i].gva_key].distance; + fprintf(stderr, "relation: is_contained\n"); } // if } // if @@ -348,9 +354,66 @@ gva_index_query(GVA_Allocator const allocator, continue; } // if + if (relation == GVA_EQUIVALENT || relation == GVA_CONTAINS) + { + included = distance; + } // if + else if (relation == GVA_IS_CONTAINED) + { + included = self->intervals.nodes[parts[i].gva_key].distance; + } // if + else // GVA_OVERLAP + { + included = 1; + } // else + fprintf(stderr, "relation: %s\n", GVA_RELATION_LABELS[relation]); } // if + + for (gva_uint j = self->intervals.nodes[parts[i].gva_key].alleles; j != GVA_NULL; j = self->join[j].next) + { + size_t const idx = HASH_TABLE_INDEX(y, j); + if (y[idx].gva_key != j) + { + fprintf(stderr, "new allele %u\n", j); + HASH_TABLE_SET(allocator, y, j, ((struct Y) {j, included})); + continue; + } // if + fprintf(stderr, "update allele %u\n", j); + y[idx].included += included; + } // for + } // for + + fprintf(stderr, "Query distance %u\n", graph.distance); + for (size_t i = 0; i < array_header(y)->capacity; ++i) + { + if (y[i].gva_key == NOT_FOUND) + { + continue; + } // if + + fprintf(stderr, GVA_STRING_FMT " %u %u: ", GVA_STRING_PRINT(trie_string(self->ids, self->alleles[y[i].gva_key].id_idx)), self->alleles[y[i].gva_key].distance, y[i].included); + if (y[i].included == self->alleles[y[i].gva_key].distance) + { + if (y[i].included == graph.distance) + { + fprintf(stderr, "%s\n", GVA_RELATION_LABELS[GVA_EQUIVALENT]); + } // if + else + { + fprintf(stderr, "%s\n", GVA_RELATION_LABELS[GVA_IS_CONTAINED]); + } // else + } // if + else if (y[i].included == graph.distance) + { + fprintf(stderr, "%s\n", GVA_RELATION_LABELS[GVA_CONTAINS]); + } // if + else + { + fprintf(stderr, "%s\n", GVA_RELATION_LABELS[GVA_OVERLAP]); + } // else } // for parts = HASH_TABLE_DESTROY(allocator, parts); + y = HASH_TABLE_DESTROY(allocator, y); } // gva_index_query diff --git a/src/main.c b/src/main.c index f4ef74f..988a839 100644 --- a/src/main.c +++ b/src/main.c @@ -597,431 +597,6 @@ index_main(int argc, char* argv[static argc]) } // index_main -int -locals_main(int argc, char* argv[static argc]) -{ - errno = 0; - FILE* stream = fopen(argv[1], "r"); - if (stream == NULL) - { - fprintf(stderr, "error: %s\n", strerror(errno)); - return EXIT_FAILURE; - } // if - - GVA_String reference = {0, NULL}; - reference = gva_fasta_sequence_blob(gva_std_allocator, stream); - fclose(stream); - - fprintf(stderr, "reference length: %zu\n", reference.len); - - Trie trie = trie_init(); - Interval_Tree tree = interval_tree_init(); - - struct Node_Allele - { - gva_uint link; - gva_uint next; - }* node_allele_join = NULL; - struct Allele - { - gva_uint sample_id; - gva_uint join_start; // offset into node_allele_join - gva_uint join_end; - gva_uint distance; - }* db_alleles = NULL; - - errno = 0; - stream = fopen(argv[2], "r"); - if (stream == NULL) - { - fprintf(stderr, "error: %s\n", strerror(errno)); - gva_string_destroy(gva_std_allocator, reference); - return EXIT_FAILURE; - } // if - - Trie sample_trie = trie_init(); - - static char line[LINE_SIZE] = {0}; - size_t line_count = 0; - size_t prev_sample_id = -1; - size_t allele_idx = -1; - while (fgets(line, sizeof(line), stream) != NULL) - { - // label - size_t len = strcspn(line, "\t "); - if (len == 0) - { - fprintf(stderr, "error: parsing failed at line %zu: %s", line_count + 1, line); - continue; - } // if - size_t const sample_id = trie_insert(gva_std_allocator, &sample_trie, len, line); - - // variant - size_t idx = len + 1; - len = strcspn(line + idx, "\t "); - GVA_Variant variant; - if (gva_parse_spdi(len, line + idx, &variant) == 0) - { - fprintf(stderr, "error: SPDI parsing failed at line %zu: %s", line_count + 1, line); - continue; - } // if - - // distance - idx += len + 1; - size_t distance = parse_number(line, &idx); - if (distance == 0) - { - fprintf(stderr, "error: parsing failed at line %zu: %s", line_count + 1, line); - continue; - } // if - - // new sample - if (sample_id != prev_sample_id) - { - allele_idx = ARRAY_APPEND(gva_std_allocator, db_alleles, ((struct Allele) {sample_id, array_length(node_allele_join), 0, 0})) - 1; - if (allele_idx > 0) - { - db_alleles[allele_idx - 1].join_end = array_length(node_allele_join); - } // if - - fprintf(stderr, "allele: %zu (" GVA_STRING_FMT ") (%zu)\n", sample_id, GVA_STRING_PRINT(trie_string(sample_trie, sample_id)), allele_idx); - prev_sample_id = sample_id; - } // if - // fprintf(stderr, "%zu " GVA_VARIANT_FMT " %zu\n", sample_id, GVA_VARIANT_PRINT(variant), distance); - db_alleles[allele_idx].distance += distance; - - gva_uint const inserted_idx = trie_insert(gva_std_allocator, &trie, variant.sequence.len, variant.sequence.str); - gva_uint const tmp_idx = ARRAY_APPEND(gva_std_allocator, tree.nodes, - ((Interval_Tree_Node) {{GVA_NULL, GVA_NULL}, - variant.start, variant.end, variant.end, 0, inserted_idx, GVA_NULL, distance})) - 1; - gva_uint const node_idx = interval_tree_insert(&tree, tmp_idx); - if (node_idx != tmp_idx) - { - array_header(tree.nodes)->length -= 1; // undo; node already in the tree - } // if - tree.nodes[node_idx].alleles = ARRAY_APPEND(gva_std_allocator, node_allele_join, ((struct Node_Allele) {node_idx ^ allele_idx, tree.nodes[node_idx].alleles})) - 1; - - line_count += 1; - } // while - if (array_length(db_alleles) > 0) - { - db_alleles[array_length(db_alleles) - 1].join_end = array_length(node_allele_join); - } // if - fclose(stream); - fprintf(stderr, "line count: %zu\n", line_count); - fprintf(stderr, "tree nodes: %zu\n", array_length(tree.nodes)); - fprintf(stderr, "sequence trie nodes: %zu (%zu)\n", array_length(trie.nodes), trie.strings.len); - fprintf(stderr, "sample trie nodes: %zu (%zu)\n", array_length(sample_trie.nodes), sample_trie.strings.len); - - fprintf(stderr, "#db_alleles: %zu\n", array_length(db_alleles)); - fprintf(stderr, "#join: %zu\n", array_length(node_allele_join)); - - for (size_t i = 0; i < array_length(db_alleles); ++i) - { - fprintf(stderr, "allele: %u (" GVA_STRING_FMT ") (%zu) dist: %u (%u - %u)\n", - db_alleles[i].sample_id, - GVA_STRING_PRINT(trie_string(sample_trie, db_alleles[i].sample_id)), - i, - db_alleles[i].distance, - db_alleles[i].join_start, - db_alleles[i].join_end); - } // for - - // for every query - line_count = 0; - while (fgets(line, sizeof(line), stdin) != NULL) { - // label - size_t query_len = strcspn(line, "\t "); - if (query_len == 0) - { - fprintf(stderr, "error: parsing failed at line %zu: %s", line_count + 1, line); - continue; - } // if - - // variant - GVA_Variant rhs_var; - if (gva_parse_spdi(strcspn(line + query_len + 1, "\n"), line + query_len + 1, &rhs_var) == 0) - { - fprintf(stderr, "error: SPDI parsing failed at line %zu: %s", line_count + 1, line); - continue; - } // if - - GVA_LCS_Graph const rhs_graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &rhs_var); - // fprintf(stderr, GVA_VARIANT_FMT_SPDI " (%u) \n", GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, rhs_var), rhs_graph.distance); - - // Join nodes in the index to parts in the query - struct Node_Parts - { - HASH_TABLE_KEY; - GVA_Relation relation; - gva_uint start; - gva_uint end; - gva_uint included; - }* node_parts = hash_table_init(gva_std_allocator, 1024, sizeof(*node_parts)); - - for (size_t part_idx = 0; part_idx < array_length(rhs_graph.dom_nodes) - 1; ++part_idx) - { - // fprintf(stderr, "part_idx: %zu\n", part_idx); - gva_uint const rhs_distance = rhs_graph.dom_nodes[part_idx + 1].distance; - // fprintf(stderr, "rhs_distance from local: %u\n", rhs_distance); - - GVA_Variant rhs_part; - gva_edges(rhs_graph.observed.str, - rhs_graph.dom_nodes[part_idx], rhs_graph.dom_nodes[part_idx + 1], - part_idx == 0, part_idx == array_length(rhs_graph.dom_nodes) - 2, - &rhs_part); - - gva_uint* candidates = interval_tree_intersection(gva_std_allocator, tree, rhs_part.start, rhs_part.end); - for (size_t can_idx = 0; can_idx < array_length(candidates); ++can_idx) - { - gva_uint const node_idx = candidates[can_idx]; - GVA_Variant const db_var = {tree.nodes[node_idx].start, tree.nodes[node_idx].end, - trie_string(trie, tree.nodes[node_idx].inserted)}; - GVA_Relation const relation = gva_compare_with_distance(gva_std_allocator, reference.len, reference.str, db_var, tree.nodes[node_idx].distance, rhs_part, rhs_distance); - if (relation == GVA_DISJOINT) - { - continue; - } // if - // fprintf(stderr, "%zu " GVA_VARIANT_FMT_SPDI " %s " GVA_VARIANT_FMT_SPDI "\n", line_count, - // GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, db_var), - // GVA_RELATION_LABELS[relation], - // GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, rhs_part)); - - // link nodes to query parts - size_t hash_idx = HASH_TABLE_INDEX(node_parts, node_idx); - if (node_parts[hash_idx].gva_key != node_idx) - { - HASH_TABLE_SET(gva_std_allocator, node_parts, node_idx, - ((struct Node_Parts) {node_idx, relation, part_idx, part_idx + 1, rhs_distance})); - hash_idx = HASH_TABLE_INDEX(node_parts, node_idx); - } // if - - if (relation == GVA_EQUIVALENT || relation == GVA_IS_CONTAINED) - { - // TODO: default value is already set for equivalence? - node_parts[hash_idx].included = tree.nodes[node_idx].distance; - } // if - else if (relation == GVA_CONTAINS) - { - node_parts[hash_idx].end = part_idx + 1; - } // if - else // GVA_OVERLAP - { - // TODO: Set relation to OVERLAP? - // TODO: +=1 ? - node_parts[hash_idx].included = 1; - } // else - } // for every candidate - candidates = ARRAY_DESTROY(gva_std_allocator, candidates); - } // for query allele parts - - // We have now compared all query parts to the index - - // fix containment for multiple parts in single node for every query - for (size_t npt_index = 0; npt_index < array_header(node_parts)->capacity; ++npt_index) - { - size_t const node_idx = node_parts[npt_index].gva_key; - if (node_idx == NOT_FOUND) - { - continue; - } // if - - if (node_parts[npt_index].relation == GVA_CONTAINS && - node_parts[npt_index].end - node_parts[npt_index].start > 1) - { - size_t const lhs_distance = tree.nodes[node_idx].distance; - size_t rhs_distance = 0; - for (size_t i = node_parts[npt_index].start; i < node_parts[npt_index].end; ++i) - { - rhs_distance += rhs_graph.dom_nodes[i + 1].distance; - } // for - if (rhs_distance >= lhs_distance) - { - node_parts[npt_index].included = 1; - node_parts[npt_index].relation = GVA_OVERLAP; - continue; - } // if - - GVA_Variant const lhs = {tree.nodes[node_idx].start, - tree.nodes[node_idx].end, - trie_string(trie, tree.nodes[node_idx].inserted)}; - - GVA_Variant rhs; - gva_edges(rhs_graph.observed.str, - rhs_graph.dom_nodes[node_parts[npt_index].start], - rhs_graph.dom_nodes[node_parts[npt_index].end], - node_parts[npt_index].start == 0, - node_parts[npt_index].end == array_length(rhs_graph.dom_nodes) - 1, - &rhs); - - size_t const distance = variants_distance(gva_std_allocator, reference.len, reference.str, lhs, rhs); - if (lhs_distance - distance == rhs_distance) - { - node_parts[npt_index].included = rhs_distance; - } // if - else - { - node_parts[npt_index].included = 1; - node_parts[npt_index].relation = GVA_OVERLAP; - } // if - } // if - } // for node_parts_table - - // TODO: get rid of struct - // or - // store relation - struct Result - { - HASH_TABLE_KEY; - }* results = hash_table_init(gva_std_allocator, 1024, sizeof(*results)); - - // find all alleles that were part of a non-disjoint relation - for (size_t npt_idx = 0; npt_idx < array_header(node_parts)->capacity; ++npt_idx) - { - size_t const node_idx = node_parts[npt_idx].gva_key; - if (node_idx == NOT_FOUND) - { - continue; - } // if - - for (size_t naj_table_idx = tree.nodes[node_idx].alleles; - naj_table_idx != GVA_NULL; - naj_table_idx = node_allele_join[naj_table_idx].next) - { - size_t const allele_idx = node_allele_join[naj_table_idx].link ^ node_idx; - HASH_TABLE_SET(gva_std_allocator, results, allele_idx, ((struct Result) {allele_idx})); - } // for alleles - } // for node_parts_table - - // build result vector for every query - for (size_t results_idx = 0; results_idx < array_header(results)->capacity; ++results_idx) - { - size_t allele_idx = results[results_idx].gva_key; - if (allele_idx == NOT_FOUND) - { - continue; - } // if - - gva_uint included = 0; - GVA_Relation relation = GVA_DISJOINT; - - gva_uint* is_contained_nodes = NULL; - gva_uint is_contained_part_idx = -1; - - // loop over all nodes for this allele - for (size_t join_idx = db_alleles[allele_idx].join_start; join_idx < db_alleles[allele_idx].join_end; ++join_idx) - { - size_t node_idx = node_allele_join[join_idx].link ^ allele_idx; - size_t const hash_idx = HASH_TABLE_INDEX(node_parts, node_idx); - if (node_idx != node_parts[hash_idx].gva_key) - { - continue; - } // if - - if (node_parts[hash_idx].relation == GVA_EQUIVALENT) - { - included += node_parts[hash_idx].included; - if (relation == GVA_EQUIVALENT || relation == GVA_DISJOINT) - { - relation = GVA_EQUIVALENT; - } // if - } // if - else if (node_parts[hash_idx].relation == GVA_CONTAINS) - { - included += node_parts[hash_idx].included; - if (relation == GVA_IS_CONTAINED) - { - relation = GVA_OVERLAP; // TODO: included = 1; ??? - break; - } // if - relation = GVA_CONTAINS; - } // if - else if (node_parts[hash_idx].relation == GVA_IS_CONTAINED) - { - size_t const part_idx = node_parts[hash_idx].start; - if (relation == GVA_CONTAINS) - { - included += node_parts[hash_idx].included; // TODO: included = 1; ??? - relation = GVA_OVERLAP; - break; - } // if - - if (part_idx != is_contained_part_idx) - { - repair_is_contained(gva_std_allocator, reference, rhs_graph, tree, trie, - &is_contained_nodes, is_contained_part_idx, &included, &relation); - is_contained_part_idx = part_idx; - } // if - ARRAY_APPEND(gva_std_allocator, is_contained_nodes, node_idx); - relation = GVA_IS_CONTAINED; - } // if - else if (node_parts[hash_idx].relation == GVA_OVERLAP) - { - included = 1; - relation = GVA_OVERLAP; - break; - } // if - } // for all nodes for this allele - repair_is_contained(gva_std_allocator, reference, rhs_graph, tree, trie, - &is_contained_nodes, is_contained_part_idx, &included, &relation); - - // TODO: always true?! - if (included > 0) - { - gva_uint const lhs_excluded = db_alleles[allele_idx].distance - included; - gva_uint const rhs_excluded = rhs_graph.distance - included; - - if (lhs_excluded > 0 && rhs_excluded > 0) - { - relation = GVA_OVERLAP; - } // if - else if (lhs_excluded > 0) - { - relation = GVA_CONTAINS; - } // if - else if (rhs_excluded > 0) - { - relation = GVA_IS_CONTAINED; - } // if - else // lhs_excluded == 0 && rhs_excluded == 0 - { - relation = GVA_EQUIVALENT; - } // else - - // only for testing - // if (relation != GVA_EQUIVALENT || db_alleles[allele_idx].line < line_count) - // if (relation != GVA_OVERLAP) - { - fprintf(stdout, GVA_STRING_FMT " %s " GVA_STRING_FMT " %u %u %u\n", - GVA_STRING_PRINT(trie_string(sample_trie, db_alleles[allele_idx].sample_id)), - GVA_RELATION_LABELS[relation], - GVA_STRING_PRINT(((GVA_String) {query_len, line})), - included, lhs_excluded, rhs_excluded - ); - } // if - } // if - } // for all alleles - - results = HASH_TABLE_DESTROY(gva_std_allocator, results); - - node_parts = HASH_TABLE_DESTROY(gva_std_allocator, node_parts); - - gva_string_destroy(gva_std_allocator, rhs_graph.observed); - gva_lcs_graph_destroy(gva_std_allocator, rhs_graph); - line_count++; - } // while query - - db_alleles = ARRAY_DESTROY(gva_std_allocator, db_alleles); - node_allele_join = ARRAY_DESTROY(gva_std_allocator, node_allele_join); - interval_tree_destroy(gva_std_allocator, &tree); - trie_destroy(gva_std_allocator, &sample_trie); - trie_destroy(gva_std_allocator, &trie); - gva_string_destroy(gva_std_allocator, reference); - - return EXIT_SUCCESS; -} // locals_main - - // FIXME: to string module? static char* strrev(size_t const n, char str[static n]) From 229848f4955f6aa947f9fd653a9a6b1cc64d936f Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 11 Feb 2026 15:20:03 +0100 Subject: [PATCH 471/704] WIP: queries with allele_idx --- src/index.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/index.c b/src/index.c index 00ed328..0b5c59c 100644 --- a/src/index.c +++ b/src/index.c @@ -343,8 +343,6 @@ gva_index_query(GVA_Allocator const allocator, distance += graph.dom_nodes[j + 1].distance; } // for - fprintf(stderr, "Calculate relation\n"); - GVA_Relation const relation = gva_compare_with_distance(allocator, self->reference.len, self->reference.str, variant_from_index(self, parts[i].gva_key), self->intervals.nodes[parts[i].gva_key].distance, variant, distance); @@ -372,14 +370,16 @@ gva_index_query(GVA_Allocator const allocator, for (gva_uint j = self->intervals.nodes[parts[i].gva_key].alleles; j != GVA_NULL; j = self->join[j].next) { - size_t const idx = HASH_TABLE_INDEX(y, j); - if (y[idx].gva_key != j) + gva_uint const allele_idx = self->join[j].link ^ parts[i].gva_key; + + size_t const idx = HASH_TABLE_INDEX(y, allele_idx); + if (y[idx].gva_key != allele_idx) { - fprintf(stderr, "new allele %u\n", j); - HASH_TABLE_SET(allocator, y, j, ((struct Y) {j, included})); + fprintf(stderr, "new allele %u\n", allele_idx); + HASH_TABLE_SET(allocator, y, allele_idx, ((struct Y) {allele_idx, included})); continue; } // if - fprintf(stderr, "update allele %u\n", j); + fprintf(stderr, "update allele %u\n", allele_idx); y[idx].included += included; } // for } // for From 6ce975efee9f201061562afae68c282390aacfae Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 12 Feb 2026 13:26:43 +0100 Subject: [PATCH 472/704] WIP: new query layout --- src/index.c | 206 ++++++++-------------------------------------------- 1 file changed, 30 insertions(+), 176 deletions(-) diff --git a/src/index.c b/src/index.c index 0b5c59c..2b855db 100644 --- a/src/index.c +++ b/src/index.c @@ -189,29 +189,24 @@ void gva_index_query(GVA_Allocator const allocator, GVA_Index* const self, GVA_LCS_Graph const graph) { - struct Y + struct Result_Allele { HASH_TABLE_KEY; - gva_uint included; - }* y = hash_table_init(allocator, 1024, sizeof(*y)); + gva_uint head; + gva_uint tail; + }* alleles = hash_table_init(allocator, 1024, sizeof(*alleles)); - struct Parts + struct Result_Part { - HASH_TABLE_KEY; + gva_uint part; + gva_uint distance; gva_uint start; gva_uint end; - gva_uint distance; - }* parts = hash_table_init(allocator, 1024, sizeof(*parts)); + gva_uint next; + }* parts = NULL; for (size_t i = 0; i < array_length(graph.dom_nodes) - 1; ++i) { - struct X - { - HASH_TABLE_KEY; - gva_uint start; - gva_uint end; - }* x = hash_table_init(allocator, 1024, sizeof(*x)); - GVA_Variant variant; gva_edges(graph.observed.str, graph.dom_nodes[i], graph.dom_nodes[i + 1], @@ -223,197 +218,56 @@ gva_index_query(GVA_Allocator const allocator, gva_uint* intervals = interval_tree_intersection(allocator, self->intervals, variant.start, variant.end); for (size_t j = 0; j < array_length(intervals); ++j) { - fprintf(stderr, " check: " GVA_VARIANT_FMT_SPDI "\n", GVA_VARIANT_PRINT_SPDI("NC_000001.11", variant_from_index(self, intervals[j]))); size_t const distance = variants_distance(allocator, self->reference.len, self->reference.str, variant_from_index(self, intervals[j]), variant); if (distance >= self->intervals.nodes[intervals[j]].distance + graph.dom_nodes[i + 1].distance) { continue; // disjoint } // if - size_t const idx = HASH_TABLE_INDEX(parts, intervals[j]); - if (parts[idx].gva_key == intervals[j]) - { - parts[idx].end = i + 1; - fprintf(stderr, " update\n"); - } // if - else - { - HASH_TABLE_SET(allocator, parts, intervals[j], ((struct Parts) {intervals[j], i, i + 1, distance})); - fprintf(stderr, " add new\n"); - } // else + fprintf(stderr, " vs " GVA_VARIANT_FMT_SPDI "\n", GVA_VARIANT_PRINT_SPDI("NC_000001.11", variant_from_index(self, intervals[j]))); for (gva_uint k = self->intervals.nodes[intervals[j]].alleles; k != GVA_NULL; k = self->join[k].next) { gva_uint const allele_idx = self->join[k].link ^ intervals[j]; - fprintf(stderr, " allele idx: %u - " GVA_STRING_FMT "\n", allele_idx, GVA_STRING_PRINT(trie_string(self->ids, self->alleles[allele_idx].id_idx))); - size_t const idx = HASH_TABLE_INDEX(x, allele_idx); - if (x[idx].gva_key == allele_idx) + size_t const idx = HASH_TABLE_INDEX(alleles, allele_idx); + if (alleles[idx].gva_key != allele_idx) { - x[idx].end = k + 1; - fprintf(stderr, " update. k: %u\n", k); + gva_uint const tail = ARRAY_APPEND(allocator, parts, ((struct Result_Part) {k, distance, i, i + 1, GVA_NULL})) - 1; + HASH_TABLE_SET(allocator, alleles, allele_idx, ((struct Result_Allele) {allele_idx, tail, tail})); + continue; + } // if + + if (parts[alleles[idx].tail].part != k || parts[alleles[idx].tail].start == i) + { + gva_uint const tail = ARRAY_APPEND(allocator, parts, ((struct Result_Part) {k, distance, i, i + 1, GVA_NULL})) - 1; + parts[alleles[idx].tail].next = tail; + alleles[idx].tail = tail; } // if else { - HASH_TABLE_SET(allocator, x, allele_idx, ((struct X) {allele_idx, k, k + 1})); - fprintf(stderr, " add new. k: %u\n", k); + parts[alleles[idx].tail].end = i + 1; } // else } // for } // for - - for (size_t j = 0; j < array_header(x)->capacity; ++j) - { - if (x[j].gva_key == NOT_FOUND) - { - continue; - } // if - - fprintf(stderr, " " GVA_STRING_FMT "[%u, %u)\n", - GVA_STRING_PRINT(trie_string(self->ids, self->alleles[x[j].gva_key].id_idx)), - x[j].start, x[j].end); - - size_t const len = x[j].end - x[j].start; - if (len > 1) - { - GVA_Variant* variants = allocator.allocate(allocator.context, NULL, 0, len * sizeof(*variants)); - size_t distance = 0; - for (size_t k = 0; k < len; ++k) - { - variants[k] = variant_from_index(self, self->join[x[j].start + k].link ^ x[j].gva_key); - distance += self->intervals.nodes[self->join[x[j].start + k].link ^ x[j].gva_key].distance; - } // for - - GVA_LCS_Graph lhs_graph = gva_lcs_graph_from_variants(allocator, self->reference.len, self->reference.str, len, variants); - GVA_LCS_Graph rhs_graph = gva_lcs_graph_from_variants(allocator, self->reference.len, self->reference.str, 1, &variant); - - GVA_Relation const relation = gva_compare_graphs(allocator, self->reference.len, self->reference.str, lhs_graph, rhs_graph); - - fprintf(stderr, "relation: %s\n", GVA_RELATION_LABELS[relation]); - - gva_string_destroy(allocator, rhs_graph.observed); - gva_lcs_graph_destroy(allocator, rhs_graph); - gva_string_destroy(allocator, lhs_graph.observed); - gva_lcs_graph_destroy(allocator, lhs_graph); - - variants = allocator.allocate(allocator.context, variants, len * sizeof(*variants), 0); - } // if - } // for - intervals = ARRAY_DESTROY(allocator, intervals); - x = HASH_TABLE_DESTROY(allocator, x); } // for - for (size_t i = 0; i < array_header(parts)->capacity; ++i) + for (size_t idx = 0; idx < array_header(alleles)->capacity; ++idx) { - if (parts[i].gva_key == NOT_FOUND) + if (alleles[idx].gva_key == NOT_FOUND) { continue; } // if - fprintf(stderr, GVA_VARIANT_FMT_SPDI " %u %u %u\n", GVA_VARIANT_PRINT_SPDI("NC_000001.11", variant_from_index(self, parts[i].gva_key)), parts[i].start, parts[i].end, parts[i].distance); - - size_t included = 0; - if (parts[i].end - parts[i].start == 1) - { - if (parts[i].distance == 0 || - self->intervals.nodes[parts[i].gva_key].distance - graph.dom_nodes[parts[i].start + 1].distance == parts[i].distance) - { - // equivalent and contains - included = graph.dom_nodes[parts[i].start + 1].distance; - fprintf(stderr, "relation: equivalent/contains\n"); - } // if - else if (graph.dom_nodes[parts[i].start + 1].distance - self->intervals.nodes[parts[i].gva_key].distance == parts[i].distance) - { - // is_contained - included = self->intervals.nodes[parts[i].gva_key].distance; - fprintf(stderr, "relation: is_contained\n"); - } // if - } // if - - if (included == 0) - { - GVA_Variant variant; - gva_edges(graph.observed.str, - graph.dom_nodes[parts[i].start], graph.dom_nodes[parts[i].end], - parts[i].start == 0, parts[i].end == array_length(graph.dom_nodes) - 2, - &variant); - size_t distance = 0; - for (gva_uint j = parts[i].start; j < parts[i].end; ++j) - { - distance += graph.dom_nodes[j + 1].distance; - } // for - - GVA_Relation const relation = gva_compare_with_distance(allocator, self->reference.len, self->reference.str, - variant_from_index(self, parts[i].gva_key), self->intervals.nodes[parts[i].gva_key].distance, - variant, distance); + fprintf(stderr, GVA_STRING_FMT ":\n", GVA_STRING_PRINT(trie_string(self->ids, self->alleles[alleles[idx].gva_key].id_idx))); - if (relation == GVA_DISJOINT) - { - continue; - } // if - - if (relation == GVA_EQUIVALENT || relation == GVA_CONTAINS) - { - included = distance; - } // if - else if (relation == GVA_IS_CONTAINED) - { - included = self->intervals.nodes[parts[i].gva_key].distance; - } // if - else // GVA_OVERLAP - { - included = 1; - } // else - - fprintf(stderr, "relation: %s\n", GVA_RELATION_LABELS[relation]); - } // if - - for (gva_uint j = self->intervals.nodes[parts[i].gva_key].alleles; j != GVA_NULL; j = self->join[j].next) + for (gva_uint i = alleles[idx].head; i != GVA_NULL; i = parts[i].next) { - gva_uint const allele_idx = self->join[j].link ^ parts[i].gva_key; - - size_t const idx = HASH_TABLE_INDEX(y, allele_idx); - if (y[idx].gva_key != allele_idx) - { - fprintf(stderr, "new allele %u\n", allele_idx); - HASH_TABLE_SET(allocator, y, allele_idx, ((struct Y) {allele_idx, included})); - continue; - } // if - fprintf(stderr, "update allele %u\n", allele_idx); - y[idx].included += included; + fprintf(stderr, " %u %u %u %u\n", parts[i].part, parts[i].distance, parts[i].start, parts[i].end); } // for } // for - fprintf(stderr, "Query distance %u\n", graph.distance); - for (size_t i = 0; i < array_header(y)->capacity; ++i) - { - if (y[i].gva_key == NOT_FOUND) - { - continue; - } // if - - fprintf(stderr, GVA_STRING_FMT " %u %u: ", GVA_STRING_PRINT(trie_string(self->ids, self->alleles[y[i].gva_key].id_idx)), self->alleles[y[i].gva_key].distance, y[i].included); - if (y[i].included == self->alleles[y[i].gva_key].distance) - { - if (y[i].included == graph.distance) - { - fprintf(stderr, "%s\n", GVA_RELATION_LABELS[GVA_EQUIVALENT]); - } // if - else - { - fprintf(stderr, "%s\n", GVA_RELATION_LABELS[GVA_IS_CONTAINED]); - } // else - } // if - else if (y[i].included == graph.distance) - { - fprintf(stderr, "%s\n", GVA_RELATION_LABELS[GVA_CONTAINS]); - } // if - else - { - fprintf(stderr, "%s\n", GVA_RELATION_LABELS[GVA_OVERLAP]); - } // else - } // for - - parts = HASH_TABLE_DESTROY(allocator, parts); - y = HASH_TABLE_DESTROY(allocator, y); + parts = ARRAY_DESTROY(allocator, parts); + alleles = HASH_TABLE_DESTROY(allocator, alleles); } // gva_index_query From 933695ef74495d76fdeb1ea107105415bd50b9c5 Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 13 Feb 2026 09:55:15 +0100 Subject: [PATCH 473/704] WIP: annotated query recalculations --- src/index.c | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/src/index.c b/src/index.c index 2b855db..b6612c9 100644 --- a/src/index.c +++ b/src/index.c @@ -1,4 +1,5 @@ #include // NULL, size_t +#include // intmax_t #include // memcpy @@ -14,7 +15,7 @@ #include "../include/types.h" // GVA_NULL, gva_uint #include "../include/variant.h" // GVA_Variant, gva_variant_* #include "array.h" // ARRAY_*, array_* -#include "common.h" // MAX, MIN +#include "common.h" // ABS, MAX, MIN #include "hash_table.h" // NOT_FOUND, HASH_TABLE_*, hash_table_* #include "interval_tree.h" // Interval_Tree, interval_tree_* #include "trie.h" // Trie, trie_* @@ -265,6 +266,38 @@ gva_index_query(GVA_Allocator const allocator, for (gva_uint i = alleles[idx].head; i != GVA_NULL; i = parts[i].next) { fprintf(stderr, " %u %u %u %u\n", parts[i].part, parts[i].distance, parts[i].start, parts[i].end); + + GVA_Variant* variants = NULL; + size_t distance = 0; + while (parts[i].next != GVA_NULL && parts[parts[i].next].start == parts[i].start) + { + if (variants == NULL) + { + ARRAY_APPEND(allocator, variants, variant_from_index(self, self->join[parts[i].part].link ^ alleles[idx].gva_key)); + distance += parts[i].distance; + } // if + i = parts[i].next; + ARRAY_APPEND(allocator, variants, variant_from_index(self, self->join[parts[i].part].link ^ alleles[idx].gva_key)); + distance += parts[i].distance; + fprintf(stderr, " %u %u %u %u\n", parts[i].part, parts[i].distance, parts[i].start, parts[i].end); + } // while + if (variants != NULL) + { + // TODO: multiple DB hits with one query hit + fprintf(stderr, " DB multi hit: %zu (%zu)\n", array_length(variants), distance); + variants = ARRAY_DESTROY(allocator, variants); + } // if + else if (parts[i].end - parts[i].start > 1) + { + // TODO: multiple query hits with one DB hit + fprintf(stderr, " Query multi hit: %u\n", parts[i].end - parts[i].start); + } // if + else if (ABS((intmax_t) self->intervals.nodes[self->join[parts[i].part].link ^ alleles[idx].gva_key].distance - graph.dom_nodes[parts[i].start + 1].distance) != parts[i].distance) + { + // TODO: calculate not fully calculated relations + fprintf(stderr, " Fully calculate\n"); + } // if + // TODO: aggregate independent results } // for } // for From e605149cb7189de8de49596de2bb8f73c6af60b2 Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 13 Feb 2026 15:46:14 +0100 Subject: [PATCH 474/704] Convenience string constructor --- include/string.h | 4 ++++ src/string.c | 12 ++++++++++++ 2 files changed, 16 insertions(+) diff --git a/include/string.h b/include/string.h index d839d1b..88dbe73 100644 --- a/include/string.h +++ b/include/string.h @@ -18,6 +18,10 @@ typedef struct } GVA_String; +GVA_String +gva_string_init(GVA_Allocator const allocator, size_t const len); + + void gva_string_destroy(GVA_Allocator const allocator, GVA_String self); diff --git a/src/string.c b/src/string.c index 951c3c9..6a49667 100644 --- a/src/string.c +++ b/src/string.c @@ -5,6 +5,18 @@ #include "../include/string.h" // GVA_String, gva_string_* +inline GVA_String +gva_string_init(GVA_Allocator const allocator, size_t const len) +{ + GVA_String string = {len, allocator.allocate(allocator.context, NULL, 0, len)}; + if (string.str == NULL) + { + return (GVA_String) {0, NULL}; + } // if + return string; +} // gva_string_init + + inline void gva_string_destroy(GVA_Allocator const allocator, GVA_String self) { From efb7612b449337374204c6d6cd16146427fb84e2 Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 13 Feb 2026 15:46:30 +0100 Subject: [PATCH 475/704] WIP: query --- src/index.c | 151 +++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 126 insertions(+), 25 deletions(-) diff --git a/src/index.c b/src/index.c index b6612c9..c72f1d4 100644 --- a/src/index.c +++ b/src/index.c @@ -4,7 +4,6 @@ #include "../include/allocator.h" // GVA_Allocator -#include "../include/compare.h" // gva_compare_with_distance #include "../include/edit.h" // gva_edit_distance #include "../include/index.h" // GVA_Index, gva_index_* #include "../include/lcs_graph.h" // GVA_LCS_Graph, gva_edges @@ -15,6 +14,7 @@ #include "../include/types.h" // GVA_NULL, gva_uint #include "../include/variant.h" // GVA_Variant, gva_variant_* #include "array.h" // ARRAY_*, array_* +#include "bitset.h" // bitset_* #include "common.h" // ABS, MAX, MIN #include "hash_table.h" // NOT_FOUND, HASH_TABLE_*, hash_table_* #include "interval_tree.h" // Interval_Tree, interval_tree_* @@ -86,32 +86,120 @@ variants_distance(GVA_Allocator const allocator, return len_lhs; } // if - char* lhs_obs = allocator.allocate(allocator.context, NULL, 0, len_lhs); - char* rhs_obs = allocator.allocate(allocator.context, NULL, 0, len_rhs); - if (lhs_obs == NULL || rhs_obs == NULL) + GVA_String observed_lhs = gva_string_init(allocator, len_lhs); + GVA_String observed_rhs = gva_string_init(allocator, len_rhs); + if (observed_lhs.str == NULL || observed_rhs.str == NULL) { - rhs_obs = allocator.allocate(allocator.context, rhs_obs, len_rhs, 0); - lhs_obs = allocator.allocate(allocator.context, lhs_obs, len_lhs, 0); + gva_string_destroy(allocator, observed_rhs); + gva_string_destroy(allocator, observed_lhs); return -1; // FIXME: OOM } // if - memcpy(lhs_obs, reference + start, lhs.start - start); - memcpy(lhs_obs + lhs.start - start, lhs.sequence.str, lhs.sequence.len); - memcpy(lhs_obs + lhs.start - start + lhs.sequence.len, reference + lhs.end, end - lhs.end); + memcpy((char*) observed_lhs.str, reference + start, lhs.start - start); + memcpy((char*) observed_lhs.str + lhs.start - start, lhs.sequence.str, lhs.sequence.len); + memcpy((char*) observed_lhs.str + lhs.start - start + lhs.sequence.len, reference + lhs.end, end - lhs.end); - memcpy(rhs_obs, reference + start, rhs.start - start); - memcpy(rhs_obs + rhs.start - start, rhs.sequence.str, rhs.sequence.len); - memcpy(rhs_obs + rhs.start - start + rhs.sequence.len, reference + rhs.end, end - rhs.end); + memcpy((char*) observed_rhs.str, reference + start, rhs.start - start); + memcpy((char*) observed_rhs.str + rhs.start - start, rhs.sequence.str, rhs.sequence.len); + memcpy((char*) observed_rhs.str + rhs.start - start + rhs.sequence.len, reference + rhs.end, end - rhs.end); - size_t const distance = gva_edit_distance(allocator, len_lhs, lhs_obs, len_rhs, rhs_obs); + size_t const distance = gva_edit_distance(allocator, observed_lhs.len, observed_lhs.str, observed_rhs.len, observed_rhs.str); - rhs_obs = allocator.allocate(allocator.context, rhs_obs, len_rhs, 0); - lhs_obs = allocator.allocate(allocator.context, lhs_obs, len_lhs, 0); + gva_string_destroy(allocator, observed_rhs); + gva_string_destroy(allocator, observed_lhs); return distance; } // variants_distance +// FIXME: taken from compare_supremals +// FIXME: overlap with variants_distance +static size_t +variants_common(GVA_Allocator const allocator, + size_t const len_ref, char const reference[static len_ref], + GVA_Variant const lhs, GVA_Variant const rhs) +{ + size_t const start = MIN(lhs.start, rhs.start); + size_t const end = MAX(lhs.end, rhs.end); + + GVA_String observed_lhs = gva_string_init(allocator, (lhs.start - start) + lhs.sequence.len + (end - lhs.end)); + GVA_String observed_rhs = gva_string_init(allocator, (rhs.start - start) + rhs.sequence.len + (end - rhs.end)); + + memcpy((char*) observed_lhs.str, reference + start, lhs.start - start); + memcpy((char*) observed_lhs.str + lhs.start - start, lhs.sequence.str, lhs.sequence.len); + memcpy((char*) observed_lhs.str + lhs.start - start + lhs.sequence.len, reference + lhs.end, end - lhs.end); + + memcpy((char*) observed_rhs.str, reference + start, rhs.start - start); + memcpy((char*) observed_rhs.str + rhs.start - start, rhs.sequence.str, rhs.sequence.len); + memcpy((char*) observed_rhs.str + rhs.start - start + rhs.sequence.len, reference + rhs.end, end - rhs.end); + + GVA_LCS_Graph lhs_graph = gva_lcs_graph_init(allocator, end - start, reference + start, observed_lhs.len, observed_lhs.str, start); + GVA_LCS_Graph rhs_graph = gva_lcs_graph_init(allocator, end - start, reference + start, observed_rhs.len, observed_rhs.str, start); + + gva_uint const len = end - start + 1; + size_t* lhs_dels = bitset_init(allocator, len); + size_t* lhs_as = bitset_init(allocator, len); + size_t* lhs_cs = bitset_init(allocator, len); + size_t* lhs_gs = bitset_init(allocator, len); + size_t* lhs_ts = bitset_init(allocator, len); + + size_t* rhs_dels = bitset_init(allocator, len); + size_t* rhs_as = bitset_init(allocator, len); + size_t* rhs_cs = bitset_init(allocator, len); + size_t* rhs_gs = bitset_init(allocator, len); + size_t* rhs_ts = bitset_init(allocator, len); + + size_t const start_intersection = MAX(lhs.start, rhs.start); + size_t const end_intersection = MIN(lhs.end, rhs.end); + + // could be done on intersection instead of union + bitset_fill(rhs_graph, start, start_intersection, end_intersection, rhs_dels, rhs_as, rhs_cs, rhs_gs, rhs_ts); + gva_lcs_graph_destroy(allocator, rhs_graph); + + bitset_fill(lhs_graph, start, start_intersection, end_intersection, lhs_dels, lhs_as, lhs_cs, lhs_gs, lhs_ts); + gva_lcs_graph_destroy(allocator, lhs_graph); + + size_t const common = + bitset_intersection_cnt(lhs_dels, rhs_dels) + + bitset_intersection_cnt(lhs_as, rhs_as) + + bitset_intersection_cnt(lhs_cs, rhs_cs) + + bitset_intersection_cnt(lhs_gs, rhs_gs) + + bitset_intersection_cnt(lhs_ts, rhs_ts); + + // Also calculate the union + // Note: bitset_fill needs to use "plain" start and end. + // + // size_t const union1 = + // bitset_intersection_cnt(lhs_dels, lhs_dels) + + // bitset_intersection_cnt(lhs_as, lhs_as) + + // bitset_intersection_cnt(lhs_cs, lhs_cs) + + // bitset_intersection_cnt(lhs_gs, lhs_gs) + + // bitset_intersection_cnt(lhs_ts, lhs_ts) + + // bitset_intersection_cnt(rhs_dels, rhs_dels) + + // bitset_intersection_cnt(rhs_as, rhs_as) + + // bitset_intersection_cnt(rhs_cs, rhs_cs) + + // bitset_intersection_cnt(rhs_gs, rhs_gs) + + // bitset_intersection_cnt(rhs_ts, rhs_ts) - common; + + rhs_ts = bitset_destroy(allocator, rhs_ts); + rhs_gs = bitset_destroy(allocator, rhs_gs); + rhs_cs = bitset_destroy(allocator, rhs_cs); + rhs_as = bitset_destroy(allocator, rhs_as); + rhs_dels = bitset_destroy(allocator, rhs_dels); + + lhs_ts = bitset_destroy(allocator, lhs_ts); + lhs_gs = bitset_destroy(allocator, lhs_gs); + lhs_cs = bitset_destroy(allocator, lhs_cs); + lhs_as = bitset_destroy(allocator, lhs_as); + lhs_dels = bitset_destroy(allocator, lhs_dels); + + gva_string_destroy(allocator, observed_rhs); + gva_string_destroy(allocator, observed_lhs); + + return common > 0 ? 1 : 0; +} // variants_common + + inline GVA_Index* gva_index_init(GVA_Allocator const allocator, size_t const len, char const reference[static len]) @@ -193,6 +281,7 @@ gva_index_query(GVA_Allocator const allocator, struct Result_Allele { HASH_TABLE_KEY; + gva_uint included; gva_uint head; gva_uint tail; }* alleles = hash_table_init(allocator, 1024, sizeof(*alleles)); @@ -214,7 +303,7 @@ gva_index_query(GVA_Allocator const allocator, i == 0, i == array_length(graph.dom_nodes) - 2, &variant); - fprintf(stderr, " " GVA_VARIANT_FMT_SPDI "\n", GVA_VARIANT_PRINT_SPDI("NC_000001.11", variant)); + fprintf(stderr, " %2zu " GVA_VARIANT_FMT_SPDI " (%u)\n", i, GVA_VARIANT_PRINT_SPDI("NC_000001.11", variant), graph.dom_nodes[i + 1].distance); gva_uint* intervals = interval_tree_intersection(allocator, self->intervals, variant.start, variant.end); for (size_t j = 0; j < array_length(intervals); ++j) @@ -225,7 +314,7 @@ gva_index_query(GVA_Allocator const allocator, continue; // disjoint } // if - fprintf(stderr, " vs " GVA_VARIANT_FMT_SPDI "\n", GVA_VARIANT_PRINT_SPDI("NC_000001.11", variant_from_index(self, intervals[j]))); + fprintf(stderr, " vs " GVA_VARIANT_FMT_SPDI " (%u)\n", GVA_VARIANT_PRINT_SPDI("NC_000001.11", variant_from_index(self, intervals[j])), self->intervals.nodes[intervals[j]].distance); for (gva_uint k = self->intervals.nodes[intervals[j]].alleles; k != GVA_NULL; k = self->join[k].next) { @@ -235,7 +324,7 @@ gva_index_query(GVA_Allocator const allocator, if (alleles[idx].gva_key != allele_idx) { gva_uint const tail = ARRAY_APPEND(allocator, parts, ((struct Result_Part) {k, distance, i, i + 1, GVA_NULL})) - 1; - HASH_TABLE_SET(allocator, alleles, allele_idx, ((struct Result_Allele) {allele_idx, tail, tail})); + HASH_TABLE_SET(allocator, alleles, allele_idx, ((struct Result_Allele) {allele_idx, 0, tail, tail})); continue; } // if @@ -273,12 +362,14 @@ gva_index_query(GVA_Allocator const allocator, { if (variants == NULL) { - ARRAY_APPEND(allocator, variants, variant_from_index(self, self->join[parts[i].part].link ^ alleles[idx].gva_key)); - distance += parts[i].distance; + gva_uint const node_idx = self->join[parts[i].part].link ^ alleles[idx].gva_key; + ARRAY_APPEND(allocator, variants, variant_from_index(self, node_idx)); + distance += self->intervals.nodes[node_idx].distance; } // if i = parts[i].next; - ARRAY_APPEND(allocator, variants, variant_from_index(self, self->join[parts[i].part].link ^ alleles[idx].gva_key)); - distance += parts[i].distance; + gva_uint const node_idx = self->join[parts[i].part].link ^ alleles[idx].gva_key; + ARRAY_APPEND(allocator, variants, variant_from_index(self, node_idx)); + distance += self->intervals.nodes[node_idx].distance; fprintf(stderr, " %u %u %u %u\n", parts[i].part, parts[i].distance, parts[i].start, parts[i].end); } // while if (variants != NULL) @@ -289,13 +380,23 @@ gva_index_query(GVA_Allocator const allocator, } // if else if (parts[i].end - parts[i].start > 1) { + size_t distance = 0; + for (gva_uint j = parts[i].start; j < parts[i].end; ++j) + { + distance += graph.dom_nodes[j + 1].distance; + } // for // TODO: multiple query hits with one DB hit - fprintf(stderr, " Query multi hit: %u\n", parts[i].end - parts[i].start); + fprintf(stderr, " Query multi hit: %u (%zu)\n", parts[i].end - parts[i].start, distance); } // if else if (ABS((intmax_t) self->intervals.nodes[self->join[parts[i].part].link ^ alleles[idx].gva_key].distance - graph.dom_nodes[parts[i].start + 1].distance) != parts[i].distance) { - // TODO: calculate not fully calculated relations - fprintf(stderr, " Fully calculate\n"); + GVA_Variant variant; + gva_edges(graph.observed.str, + graph.dom_nodes[parts[i].start], graph.dom_nodes[parts[i].end], + parts[i].start == 0, parts[i].end == array_length(graph.dom_nodes) - 2, + &variant); + gva_uint const included = variants_common(allocator, self->reference.len, self->reference.str, variant_from_index(self, self->join[parts[i].part].link ^ alleles[idx].gva_key), variant); + fprintf(stderr, " Fully calculate: %u\n", included); } // if // TODO: aggregate independent results } // for From 94ddcee2765e230bede9646ed07e7b949c74db3e Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 13 Feb 2026 16:07:14 +0100 Subject: [PATCH 476/704] Rename --- include/index.h | 2 +- src/index.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/index.h b/include/index.h index e31cf28..61fab8c 100644 --- a/include/index.h +++ b/include/index.h @@ -24,7 +24,7 @@ gva_index_destroy(GVA_Index* const self); // insertions need to happen in allele-order void gva_index_insert(GVA_Index* restrict const self, - size_t const len, char const allele_id[static restrict len], + size_t const len_id, char const id[static restrict len_id], GVA_Variant const variant, size_t const distance); diff --git a/src/index.c b/src/index.c index c72f1d4..04b04b6 100644 --- a/src/index.c +++ b/src/index.c @@ -243,10 +243,10 @@ gva_index_destroy(GVA_Index* const self) void gva_index_insert(GVA_Index* restrict const self, - size_t const len, char const allele_id[static restrict len], + size_t const len_id, char const id[static restrict len_id], GVA_Variant const variant, size_t const distance) { - size_t const id_idx = trie_insert(self->allocator, &self->ids, len, allele_id); + size_t const id_idx = trie_insert(self->allocator, &self->ids, len_id, id); size_t allele_idx = array_length(self->alleles) - 1; // new allele From 8729a96acceaee602a30b3fc43969d1b33c8bf8c Mon Sep 17 00:00:00 2001 From: jkvis Date: Sun, 15 Feb 2026 22:18:44 +0100 Subject: [PATCH 477/704] WIP: refactor --- include/compare.h | 28 ---- include/lcs_graph.h | 15 +- include/std_alloc.h | 2 +- src/compare.c | 398 ++++---------------------------------------- src/index.c | 8 +- src/lcs_graph.c | 115 ++++++++++--- 6 files changed, 136 insertions(+), 430 deletions(-) diff --git a/include/compare.h b/include/compare.h index 6b7aec4..2dfc184 100644 --- a/include/compare.h +++ b/include/compare.h @@ -7,40 +7,12 @@ #include "allocator.h" // GVA_Allocator #include "lcs_graph.h" // GVA_LCS_Graph #include "relations.h" // GVA_Relation -#include "types.h" // gva_uint -#include "variant.h" // GVA_Variant -// FIXME: move to lcs_graph as `uniq_atomics`. -void -bitset_fill(GVA_LCS_Graph const graph, - gva_uint const offset, - gva_uint const start, gva_uint const end, - size_t dels[static restrict 1], - size_t as[static restrict 1], - size_t cs[static restrict 1], - size_t gs[static restrict 1], - size_t ts[static restrict 1]); - - -// FIXME: too many similar functions GVA_Relation gva_compare_graphs(GVA_Allocator const allocator, size_t const len_ref, char const reference[static len_ref], GVA_LCS_Graph const lhs, GVA_LCS_Graph const rhs); -GVA_Relation -gva_compare_supremals(GVA_Allocator const allocator, - size_t const len_ref, char const reference[static len_ref], - GVA_Variant const lhs, GVA_Variant const rhs); - - -GVA_Relation -gva_compare_with_distance(GVA_Allocator const allocator, - size_t const len_ref, char const reference[static len_ref], - GVA_Variant const lhs, size_t const lhs_distance, - GVA_Variant const rhs, size_t const rhs_distance); - - #endif // GVA_COMPARE_H diff --git a/include/lcs_graph.h b/include/lcs_graph.h index f1d3f0a..72dad59 100644 --- a/include/lcs_graph.h +++ b/include/lcs_graph.h @@ -37,7 +37,7 @@ typedef struct union { gva_uint edges; - gva_uint distance; + gva_uint distance; // FIXME: this should be cumulative }; union { @@ -57,7 +57,7 @@ typedef struct GVA_Variant supremal; // FIXME: remove GVA_String observed; // FIXME: ownership and destroy gva_uint source; - gva_uint distance; + gva_uint distance; // FIXME: remove } GVA_LCS_Graph; @@ -79,6 +79,17 @@ gva_lcs_graph_from_variants(GVA_Allocator const allocator, size_t const n, GVA_Variant const variants[static restrict n]); +void +gva_lcs_graph_uniq_atomics(GVA_LCS_Graph const self, + gva_uint const offset, + gva_uint const start, gva_uint const end, + size_t dels[static restrict 1], + size_t as[static restrict 1], + size_t cs[static restrict 1], + size_t gs[static restrict 1], + size_t ts[static restrict 1]); + + gva_uint gva_edges(char const observed[static restrict 1], GVA_Node const head, GVA_Node const tail, diff --git a/include/std_alloc.h b/include/std_alloc.h index 978c41e..3951f6d 100644 --- a/include/std_alloc.h +++ b/include/std_alloc.h @@ -31,7 +31,7 @@ gva_std_allocate(void* const restrict context, void* const restrict ptr, size_t } // if return new_ptr; -} // va_std_allocate +} // gva_std_allocate static GVA_Allocator const gva_std_allocator = { .allocate = gva_std_allocate }; diff --git a/src/compare.c b/src/compare.c index 940163e..30743ca 100644 --- a/src/compare.c +++ b/src/compare.c @@ -1,105 +1,18 @@ #include // bool #include // NULL, size_t -#include // uint8_t -#include // memcpy, strncmp +#include // memcpy #include "../include/allocator.h" // GVA_Allocator -#include "../include/compare.h" // gva_compare_supremals +#include "../include/compare.h" // gva_compare_graphs #include "../include/edit.h" // gva_edit_distance #include "../include/lcs_graph.h" // GVA_LCS_Graph, gva_lcs_graph_*, gva_edges #include "../include/relations.h" // GVA_Relation, GVA_CONTAINS, GVA_DISJOINT, // GVA_EQUIVALENT GVA_IS_CONTAINED, GVA_OVERLAP -#include "../include/types.h" // GVA_NULL, gva_uint #include "../include/variant.h" // GVA_Variant, gva_variant_eq -#include "array.h" // ARRAY_DESTROY, array_length #include "common.h" // MAX, MIN #include "bitset.h" // bitset_* -static uint8_t const NUC_A = 0x1; -static uint8_t const NUC_C = 0x2; -static uint8_t const NUC_G = 0x4; -static uint8_t const NUC_T = 0x8; - - -inline static uint8_t -nucleotides(size_t const len, char const sequence[static len]) -{ - static uint8_t const MASK[256] = - { - ['A'] = NUC_A, - ['C'] = NUC_C, - ['G'] = NUC_G, - ['T'] = NUC_T, - }; - static uint8_t const UNIVERSE = 0xF; - - uint8_t mask = 0x0; - for (size_t i = 0; mask < UNIVERSE && i < len; ++i) - { - mask |= MASK[(size_t) sequence[i]]; - } // for - return mask; -} // nucleotides - - -void -bitset_fill(GVA_LCS_Graph const graph, - gva_uint const offset, - gva_uint const start, gva_uint const end, - size_t dels[static restrict 1], - size_t as[static restrict 1], - size_t cs[static restrict 1], - size_t gs[static restrict 1], - size_t ts[static restrict 1]) -{ - for (size_t i = 0; i < array_length(graph.nodes); ++i) - { - if (graph.nodes[i].row > end) - { - continue; - } // if - - for (gva_uint j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) - { - if (graph.nodes[graph.edges[j].tail].row + graph.nodes[graph.edges[j].tail].length < start) - { - continue; - } // if - - GVA_Variant variant; - gva_uint const count = gva_edges(graph.observed.str, - graph.nodes[i], graph.nodes[graph.edges[j].tail], - i == graph.source, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, - &variant); - - if (variant.end > variant.start) - { - bitset_add(dels, variant.start - offset, variant.end + count - 1 - offset); - } // if - - uint8_t const mask = nucleotides(variant.sequence.len, variant.sequence.str); - if ((mask & NUC_A) == NUC_A) - { - bitset_add(as, variant.start - offset, variant.end + count - offset); - } // if - if ((mask & NUC_C) == NUC_C) - { - bitset_add(cs, variant.start - offset, variant.end + count - offset); - } // if - if ((mask & NUC_G) == NUC_G) - { - bitset_add(gs, variant.start - offset, variant.end + count - offset); - } // if - if ((mask & NUC_T) == NUC_T) - { - bitset_add(ts, variant.start - offset, variant.end + count - offset); - } // if - } // for - } // for -} // bitset_fill - - GVA_Relation gva_compare_graphs(GVA_Allocator const allocator, size_t const len_ref, char const reference[static len_ref], @@ -118,42 +31,40 @@ gva_compare_graphs(GVA_Allocator const allocator, size_t const start = MIN(lhs.supremal.start, rhs.supremal.start); size_t const end = MAX(lhs.supremal.end, rhs.supremal.end); - size_t const lhs_len = (lhs.supremal.start - start) + lhs.supremal.sequence.len + (end - lhs.supremal.end); - size_t const rhs_len = (rhs.supremal.start - start) + rhs.supremal.sequence.len + (end - rhs.supremal.end); + size_t const len_lhs = (lhs.supremal.start - start) + lhs.supremal.sequence.len + (end - lhs.supremal.end); + size_t const len_rhs = (rhs.supremal.start - start) + rhs.supremal.sequence.len + (end - rhs.supremal.end); size_t distance = 0; - if (lhs_len == 0) + if (len_lhs == 0) { - distance = rhs_len; + distance = len_rhs; } // if - else if (rhs_len == 0) + else if (len_rhs == 0) { - distance = lhs_len; + distance = len_lhs; } // if else { - char* lhs_obs = allocator.allocate(allocator.context, NULL, 0, lhs_len); - if (lhs_obs == NULL) + GVA_String observed_lhs = gva_string_init(allocator, len_lhs); + GVA_String observed_rhs = gva_string_init(allocator, len_rhs); + if (observed_lhs.str == NULL || observed_rhs.str == NULL) { - return GVA_DISJOINT; // FIXME: error + gva_string_destroy(allocator, observed_rhs); + gva_string_destroy(allocator, observed_lhs); + return GVA_DISJOINT; // FIXME: OOM } // if - memcpy(lhs_obs, reference + start, lhs.supremal.start - start); - memcpy(lhs_obs + lhs.supremal.start - start, lhs.supremal.sequence.str, lhs.supremal.sequence.len); - memcpy(lhs_obs + lhs.supremal.start - start + lhs.supremal.sequence.len, reference + lhs.supremal.end, end - lhs.supremal.end); - char* rhs_obs = allocator.allocate(allocator.context, NULL, 0, rhs_len); - if (rhs_obs == NULL) - { - lhs_obs = allocator.allocate(allocator.context, lhs_obs, lhs_len, 0); - return GVA_DISJOINT; // FIXME: error - } // if - memcpy(rhs_obs, reference + start, rhs.supremal.start - start); - memcpy(rhs_obs + rhs.supremal.start - start, rhs.supremal.sequence.str, rhs.supremal.sequence.len); - memcpy(rhs_obs + rhs.supremal.start - start + rhs.supremal.sequence.len, reference + rhs.supremal.end, end - rhs.supremal.end); + memcpy((char*) observed_lhs.str, reference + start, lhs.supremal.start - start); + memcpy((char*) observed_lhs.str + lhs.supremal.start - start, lhs.supremal.sequence.str, lhs.supremal.sequence.len); + memcpy((char*) observed_lhs.str + lhs.supremal.start - start + lhs.supremal.sequence.len, reference + lhs.supremal.end, end - lhs.supremal.end); - distance = gva_edit_distance(allocator, lhs_len, lhs_obs, rhs_len, rhs_obs); - rhs_obs = allocator.allocate(allocator.context, rhs_obs, rhs_len, 0); - lhs_obs = allocator.allocate(allocator.context, lhs_obs, lhs_len, 0); + memcpy((char*) observed_rhs.str, reference + start, rhs.supremal.start - start); + memcpy((char*) observed_rhs.str + rhs.supremal.start - start, rhs.supremal.sequence.str, rhs.supremal.sequence.len); + memcpy((char*) observed_rhs.str + rhs.supremal.start - start + rhs.supremal.sequence.len, reference + rhs.supremal.end, end - rhs.supremal.end); + + distance = gva_edit_distance(allocator, observed_lhs.len, observed_lhs.str, observed_rhs.len, observed_rhs.str); + gva_string_destroy(allocator, observed_rhs); + gva_string_destroy(allocator, observed_lhs); } // else if (lhs.distance + rhs.distance == distance) @@ -171,14 +82,14 @@ gva_compare_graphs(GVA_Allocator const allocator, return GVA_IS_CONTAINED; } // if - gva_uint const len = end - start + 1; - size_t* lhs_dels = bitset_init(allocator, len); // can be one shorter + size_t const len = end - start + 1; + size_t* lhs_dels = bitset_init(allocator, len); size_t* lhs_as = bitset_init(allocator, len); size_t* lhs_cs = bitset_init(allocator, len); size_t* lhs_gs = bitset_init(allocator, len); size_t* lhs_ts = bitset_init(allocator, len); - size_t* rhs_dels = bitset_init(allocator, len); // can be one shorter + size_t* rhs_dels = bitset_init(allocator, len); size_t* rhs_as = bitset_init(allocator, len); size_t* rhs_cs = bitset_init(allocator, len); size_t* rhs_gs = bitset_init(allocator, len); @@ -187,8 +98,8 @@ gva_compare_graphs(GVA_Allocator const allocator, size_t const start_intersection = MAX(lhs.supremal.start, rhs.supremal.start); size_t const end_intersection = MIN(lhs.supremal.end, rhs.supremal.end); - bitset_fill(lhs, start, start_intersection, end_intersection, lhs_dels, lhs_as, lhs_cs, lhs_gs, lhs_ts); - bitset_fill(rhs, start, start_intersection, end_intersection, rhs_dels, rhs_as, rhs_cs, rhs_gs, rhs_ts); + gva_lcs_graph_uniq_atomics(lhs, start, start_intersection, end_intersection, lhs_dels, lhs_as, lhs_cs, lhs_gs, lhs_ts); + gva_lcs_graph_uniq_atomics(rhs, start, start_intersection, end_intersection, rhs_dels, rhs_as, rhs_cs, rhs_gs, rhs_ts); bool const overlap = bitset_intersection_cnt(lhs_dels, rhs_dels) > 0 || bitset_intersection_cnt(lhs_as, rhs_as) > 0 || @@ -210,254 +121,3 @@ gva_compare_graphs(GVA_Allocator const allocator, return overlap ? GVA_OVERLAP : GVA_DISJOINT; } // gva_compare_graphs - - -GVA_Relation -gva_compare_supremals(GVA_Allocator const allocator, - size_t const len_ref, char const reference[static len_ref], - GVA_Variant const lhs, GVA_Variant const rhs) -{ - GVA_Relation relation; - - if (gva_variant_eq(lhs, rhs)) - { - return GVA_EQUIVALENT; - } // if - - if (lhs.start > rhs.end || rhs.start > lhs.end) - { - return GVA_DISJOINT; - } // if - - size_t const start = MIN(lhs.start, rhs.start); - size_t const end = MAX(lhs.end, rhs.end); - - size_t const lhs_len = (lhs.start - start) + lhs.sequence.len + (end - lhs.end); - char* lhs_obs = allocator.allocate(allocator.context, NULL, 0, lhs_len); - if (lhs_len > 0 && lhs_obs == NULL) - { - return -1; - } // if - - size_t const rhs_len = (rhs.start - start) + rhs.sequence.len + (end - rhs.end); - char* rhs_obs = allocator.allocate(allocator.context, NULL, 0, rhs_len); - if (rhs_len > 0 && rhs_obs == NULL) - { - lhs_obs = allocator.allocate(allocator.context, lhs_obs, lhs_len, 0); - return -1; - } // if - - size_t const lhs_dist = gva_edit_distance(allocator, lhs.end - lhs.start, reference + lhs.start, lhs.sequence.len, lhs.sequence.str); - size_t const rhs_dist = gva_edit_distance(allocator, rhs.end - rhs.start, reference + rhs.start, rhs.sequence.len, rhs.sequence.str); - - memcpy(lhs_obs, reference + start, lhs.start - start); - memcpy(lhs_obs + lhs.start - start, lhs.sequence.str, lhs.sequence.len); - memcpy(lhs_obs + lhs.start - start + lhs.sequence.len, reference + lhs.end, end - lhs.end); - - memcpy(rhs_obs, reference + start, rhs.start - start); - memcpy(rhs_obs + rhs.start - start, rhs.sequence.str, rhs.sequence.len); - memcpy(rhs_obs + rhs.start - start + rhs.sequence.len, reference + rhs.end, end - rhs.end); - - size_t const dist = gva_edit_distance(allocator, lhs_len, lhs_obs, rhs_len, rhs_obs); - - if (lhs_dist + rhs_dist == dist) - { - relation = GVA_DISJOINT; - } // if - else if (lhs_dist - rhs_dist == dist) - { - relation = GVA_CONTAINS; - } // if - else if (rhs_dist - lhs_dist == dist) - { - relation = GVA_IS_CONTAINED; - } // if - else - { - GVA_LCS_Graph lhs_graph = gva_lcs_graph_init(allocator, end - start, reference + start, lhs_len, lhs_obs, start); - GVA_LCS_Graph rhs_graph = gva_lcs_graph_init(allocator, end - start, reference + start, rhs_len, rhs_obs, start); - - gva_uint const len = end - start + 1; - size_t* lhs_dels = bitset_init(allocator, len); // can be one shorter - size_t* lhs_as = bitset_init(allocator, len); - size_t* lhs_cs = bitset_init(allocator, len); - size_t* lhs_gs = bitset_init(allocator, len); - size_t* lhs_ts = bitset_init(allocator, len); - - size_t* rhs_dels = bitset_init(allocator, len); // can be one shorter - size_t* rhs_as = bitset_init(allocator, len); - size_t* rhs_cs = bitset_init(allocator, len); - size_t* rhs_gs = bitset_init(allocator, len); - size_t* rhs_ts = bitset_init(allocator, len); - - size_t const start_intersection = MAX(lhs.start, rhs.start); - size_t const end_intersection = MIN(lhs.end, rhs.end); - - // could be done on intersection instead of union - bitset_fill(lhs_graph, start, start_intersection, end_intersection, lhs_dels, lhs_as, lhs_cs, lhs_gs, lhs_ts); - gva_lcs_graph_destroy(allocator, lhs_graph); - - bitset_fill(rhs_graph, start, start_intersection, end_intersection, rhs_dels, rhs_as, rhs_cs, rhs_gs, rhs_ts); - gva_lcs_graph_destroy(allocator, rhs_graph); - - size_t const common = - bitset_intersection_cnt(lhs_dels, rhs_dels) + - bitset_intersection_cnt(lhs_as, rhs_as) + - bitset_intersection_cnt(lhs_cs, rhs_cs) + - bitset_intersection_cnt(lhs_gs, rhs_gs) + - bitset_intersection_cnt(lhs_ts, rhs_ts); - - // Also calculate the union - // Note: bitset_fill needs to use "plain" start and end. - // - // size_t const union1 = - // bitset_intersection_cnt(lhs_dels, lhs_dels) + - // bitset_intersection_cnt(lhs_as, lhs_as) + - // bitset_intersection_cnt(lhs_cs, lhs_cs) + - // bitset_intersection_cnt(lhs_gs, lhs_gs) + - // bitset_intersection_cnt(lhs_ts, lhs_ts) + - // bitset_intersection_cnt(rhs_dels, rhs_dels) + - // bitset_intersection_cnt(rhs_as, rhs_as) + - // bitset_intersection_cnt(rhs_cs, rhs_cs) + - // bitset_intersection_cnt(rhs_gs, rhs_gs) + - // bitset_intersection_cnt(rhs_ts, rhs_ts) - common; - - if (common > 0) - { - relation = GVA_OVERLAP; - } // if - else - { - relation = GVA_DISJOINT; - } // else - - lhs_ts = bitset_destroy(allocator, lhs_ts); - lhs_gs = bitset_destroy(allocator, lhs_gs); - lhs_cs = bitset_destroy(allocator, lhs_cs); - lhs_as = bitset_destroy(allocator, lhs_as); - lhs_dels = bitset_destroy(allocator, lhs_dels); - - rhs_ts = bitset_destroy(allocator, rhs_ts); - rhs_gs = bitset_destroy(allocator, rhs_gs); - rhs_cs = bitset_destroy(allocator, rhs_cs); - rhs_as = bitset_destroy(allocator, rhs_as); - rhs_dels = bitset_destroy(allocator, rhs_dels); - } // else - - rhs_obs = allocator.allocate(allocator.context, rhs_obs, rhs_len, 0); - lhs_obs = allocator.allocate(allocator.context, lhs_obs, lhs_len, 0); - - return relation; -} // gva_compare_supremals - - -GVA_Relation -gva_compare_with_distance(GVA_Allocator const allocator, - size_t const len_ref, char const reference[static len_ref], - GVA_Variant const lhs, size_t const lhs_distance, - GVA_Variant const rhs, size_t const rhs_distance) -{ - if (gva_variant_eq(lhs, rhs)) - { - return GVA_EQUIVALENT; - } // if - - size_t const start = MIN(lhs.start, rhs.start); - size_t const end = MAX(lhs.end, rhs.end); - - size_t const len_lhs = (lhs.start - start) + lhs.sequence.len + (end - lhs.end); - size_t const len_rhs = (rhs.start - start) + rhs.sequence.len + (end - rhs.end); - - size_t distance = 0; - if (len_lhs == 0) - { - distance = len_rhs; - } // if - else if (len_rhs == 0) - { - distance = len_rhs; - } // if - else - { - char* lhs_obs = allocator.allocate(allocator.context, NULL, 0, len_lhs); - char* rhs_obs = allocator.allocate(allocator.context, NULL, 0, len_rhs); - if (lhs_obs == NULL || rhs_obs == NULL) - { - rhs_obs = allocator.allocate(allocator.context, rhs_obs, len_rhs, 0); - lhs_obs = allocator.allocate(allocator.context, lhs_obs, len_lhs, 0); - return -1; // FIXME - } // if - - memcpy(lhs_obs, reference + start, lhs.start - start); - memcpy(lhs_obs + lhs.start - start, lhs.sequence.str, lhs.sequence.len); - memcpy(lhs_obs + lhs.start - start + lhs.sequence.len, reference + lhs.end, end - lhs.end); - memcpy(rhs_obs, reference + start, rhs.start - start); - memcpy(rhs_obs + rhs.start - start, rhs.sequence.str, rhs.sequence.len); - memcpy(rhs_obs + rhs.start - start + rhs.sequence.len, reference + rhs.end, end - rhs.end); - - distance = gva_edit_distance(allocator, len_lhs, lhs_obs, len_rhs, rhs_obs); - rhs_obs = allocator.allocate(allocator.context, rhs_obs, len_rhs, 0); - lhs_obs = allocator.allocate(allocator.context, lhs_obs, len_lhs, 0); - } // else - - if (lhs_distance + rhs_distance == distance) - { - return GVA_DISJOINT; - } // if - - if (lhs_distance - rhs_distance == distance) - { - return GVA_CONTAINS; - } // if - - if (rhs_distance - lhs_distance == distance) - { - return GVA_IS_CONTAINED; - } // if - - size_t const len = end - start + 1; - size_t const start_intersection = MAX(lhs.start, rhs.start); - size_t const end_intersection = MIN(lhs.end, rhs.end); - - GVA_LCS_Graph lhs_graph = gva_lcs_graph_init(allocator, lhs.end - lhs.start, reference + lhs.start, lhs.sequence.len, lhs.sequence.str, lhs.start); - size_t* lhs_dels = bitset_init(allocator, len); // can be one shorter - size_t* lhs_as = bitset_init(allocator, len); - size_t* lhs_cs = bitset_init(allocator, len); - size_t* lhs_gs = bitset_init(allocator, len); - size_t* lhs_ts = bitset_init(allocator, len); - bitset_fill(lhs_graph, start, start_intersection, end_intersection, lhs_dels, lhs_as, lhs_cs, lhs_gs, lhs_ts); - - GVA_LCS_Graph rhs_graph = gva_lcs_graph_init(allocator, rhs.end - rhs.start, reference + rhs.start, rhs.sequence.len, rhs.sequence.str, rhs.start); - size_t* rhs_dels = bitset_init(allocator, len); // can be one shorter - size_t* rhs_as = bitset_init(allocator, len); - size_t* rhs_cs = bitset_init(allocator, len); - size_t* rhs_gs = bitset_init(allocator, len); - size_t* rhs_ts = bitset_init(allocator, len); - bitset_fill(rhs_graph, start, start_intersection, end_intersection, rhs_dels, rhs_as, rhs_cs, rhs_gs, rhs_ts); - - GVA_Relation relation = GVA_DISJOINT; - if (bitset_intersection_cnt(lhs_dels, rhs_dels) > 0 || - bitset_intersection_cnt(lhs_as, rhs_as) > 0 || - bitset_intersection_cnt(lhs_cs, rhs_cs) > 0 || - bitset_intersection_cnt(lhs_gs, rhs_gs) > 0 || - bitset_intersection_cnt(lhs_ts, rhs_ts) > 0) - { - relation = GVA_OVERLAP; - } // if - - rhs_ts = bitset_destroy(allocator, rhs_ts); - rhs_gs = bitset_destroy(allocator, rhs_gs); - rhs_cs = bitset_destroy(allocator, rhs_cs); - rhs_as = bitset_destroy(allocator, rhs_as); - rhs_dels = bitset_destroy(allocator, rhs_dels); - gva_lcs_graph_destroy(allocator, rhs_graph); - - lhs_ts = bitset_destroy(allocator, lhs_ts); - lhs_gs = bitset_destroy(allocator, lhs_gs); - lhs_cs = bitset_destroy(allocator, lhs_cs); - lhs_as = bitset_destroy(allocator, lhs_as); - lhs_dels = bitset_destroy(allocator, lhs_dels); - gva_lcs_graph_destroy(allocator, lhs_graph); - - return relation; -} // gva_compare_with_distance diff --git a/src/index.c b/src/index.c index 04b04b6..40e894c 100644 --- a/src/index.c +++ b/src/index.c @@ -153,12 +153,12 @@ variants_common(GVA_Allocator const allocator, size_t const end_intersection = MIN(lhs.end, rhs.end); // could be done on intersection instead of union - bitset_fill(rhs_graph, start, start_intersection, end_intersection, rhs_dels, rhs_as, rhs_cs, rhs_gs, rhs_ts); - gva_lcs_graph_destroy(allocator, rhs_graph); - - bitset_fill(lhs_graph, start, start_intersection, end_intersection, lhs_dels, lhs_as, lhs_cs, lhs_gs, lhs_ts); + gva_lcs_graph_uniq_atomics(lhs_graph, start, start_intersection, end_intersection, lhs_dels, lhs_as, lhs_cs, lhs_gs, lhs_ts); gva_lcs_graph_destroy(allocator, lhs_graph); + gva_lcs_graph_uniq_atomics(rhs_graph, start, start_intersection, end_intersection, rhs_dels, rhs_as, rhs_cs, rhs_gs, rhs_ts); + gva_lcs_graph_destroy(allocator, rhs_graph); + size_t const common = bitset_intersection_cnt(lhs_dels, rhs_dels) + bitset_intersection_cnt(lhs_as, rhs_as) + diff --git a/src/lcs_graph.c b/src/lcs_graph.c index f07b393..335ed45 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -1,6 +1,7 @@ #include // intmax_t #include // bool, false, true #include // NULL, size_t +#include // uint8_t #include // memcpy #include "../include/allocator.h" // GVA_Allocator @@ -9,10 +10,9 @@ #include "../include/variant.h" // GVA_Variant, gva_variant_length #include "align.h" // LCS_Alignment, lcs_align #include "array.h" // ARRAY_*, array_length +#include "bitset.h" // bitset_add #include "common.h" // GVA_NULL, MAX, MIN, gva_uint -#include -#include GVA_LCS_Graph gva_lcs_graph_init(GVA_Allocator const allocator, @@ -33,10 +33,8 @@ gva_lcs_graph_init(GVA_Allocator const allocator, .distance = len_ref + len_obs - 2 * lcs.length }; - // no matches or ref == obs if (lcs.nodes == NULL || graph.distance == 0) { - // create sink gva_uint const sink = ARRAY_APPEND(allocator, graph.nodes, ((GVA_Node) { @@ -90,7 +88,7 @@ gva_lcs_graph_init(GVA_Allocator const allocator, })); graph.supremal = (GVA_Variant) {shift, len_ref + shift, {len_obs, observed}}; return graph; - } // if (no matches) + } // if gva_uint tail_idx = lcs.index[lcs.length - 1].tail; LCS_Node sink = lcs.nodes[tail_idx]; @@ -274,21 +272,14 @@ gva_lcs_graph_init(GVA_Allocator const allocator, .distance = 0, .link = source.idx })); - //fprintf(stderr, "shift: %zu\n", shift); gva_uint distance = 0; gva_uint prev = lcs.index[0].tail; if (lcs.nodes[lcs.index[0].tail].idx != source.idx) { prev = GVA_NULL; - } + } // if for (gva_uint i = 0; i < lcs.length; ++i) { - // LCS_Node t = lcs.nodes[lcs.index[i].tail]; - //fprintf(stderr, "allignment: i: %u head: %u tail: %u count: %u offset: %u\n", - // i, lcs.index[i].head, lcs.index[i].tail, lcs.index[i].count, lcs.index[i].offset); - //fprintf(stderr, "head: (%u, %u, %u)\n", h.row - shift, h.col, h.length); - //fprintf(stderr, "tail: (%u, %u, %u)\n", t.row - shift, t.col, t.length); - // when to extend if (lcs.index[i].count == 1) { @@ -308,15 +299,10 @@ gva_lcs_graph_init(GVA_Allocator const allocator, .link = lcs.nodes[lcs.index[i].tail].idx })); - //fprintf(stderr, "new node: (%u, %u, %u) %u\n", - // lcs.nodes[lcs.index[i].tail].row + offset, - // lcs.nodes[lcs.index[i].tail].col + offset, 0, - // offset); prev = lcs.index[i].tail; distance += graph.dom_nodes[array_length(graph.dom_nodes) - 1].distance; } // if - // increase length graph.dom_nodes[array_length(graph.dom_nodes) - 1].length += 1; } // if } // for @@ -333,14 +319,7 @@ gva_lcs_graph_init(GVA_Allocator const allocator, .distance = graph.distance - distance, .link = sink.idx, })); - //fprintf(stderr, "add sink\n"); - } - - //for (size_t i = 0; i < array_length(graph.dom_nodes); ++i) - //{ - //fprintf(stderr, "(%u, %u, %u)\n", graph.dom_nodes[i].row, - // graph.dom_nodes[i].col, graph.dom_nodes[i].length); - //} + } // if // construct supremal if (graph.dom_nodes != NULL) @@ -427,6 +406,90 @@ gva_lcs_graph_from_variants(GVA_Allocator const allocator, } // gva_lcs_graph_from_variants +static uint8_t const NUC_A = 0x1; +static uint8_t const NUC_C = 0x2; +static uint8_t const NUC_G = 0x4; +static uint8_t const NUC_T = 0x8; + + +inline static uint8_t +nucleotides(size_t const len, char const sequence[static len]) +{ + static uint8_t const MASK[256] = + { + ['A'] = NUC_A, + ['C'] = NUC_C, + ['G'] = NUC_G, + ['T'] = NUC_T, + }; + static uint8_t const UNIVERSE = 0xF; + + uint8_t mask = 0x0; + for (size_t i = 0; mask < UNIVERSE && i < len; ++i) + { + mask |= MASK[(size_t) sequence[i]]; + } // for + return mask; +} // nucleotides + + +void +gva_lcs_graph_uniq_atomics(GVA_LCS_Graph const self, + gva_uint const offset, + gva_uint const start, gva_uint const end, + size_t dels[static restrict 1], + size_t as[static restrict 1], + size_t cs[static restrict 1], + size_t gs[static restrict 1], + size_t ts[static restrict 1]) +{ + for (size_t i = 0; i < array_length(self.nodes); ++i) + { + if (self.nodes[i].row > end) + { + continue; + } // if + + for (gva_uint j = self.nodes[i].edges; j != GVA_NULL; j = self.edges[j].next) + { + if (self.nodes[self.edges[j].tail].row + self.nodes[self.edges[j].tail].length < start) + { + continue; + } // if + + GVA_Variant variant; + gva_uint const count = gva_edges(self.observed.str, + self.nodes[i], self.nodes[self.edges[j].tail], + i == self.source, self.nodes[self.edges[j].tail].edges == GVA_NULL, + &variant); + + if (variant.end > variant.start) + { + bitset_add(dels, variant.start - offset, variant.end + count - 1 - offset); + } // if + + uint8_t const mask = nucleotides(variant.sequence.len, variant.sequence.str); + if ((mask & NUC_A) == NUC_A) + { + bitset_add(as, variant.start - offset, variant.end + count - offset); + } // if + if ((mask & NUC_C) == NUC_C) + { + bitset_add(cs, variant.start - offset, variant.end + count - offset); + } // if + if ((mask & NUC_G) == NUC_G) + { + bitset_add(gs, variant.start - offset, variant.end + count - offset); + } // if + if ((mask & NUC_T) == NUC_T) + { + bitset_add(ts, variant.start - offset, variant.end + count - offset); + } // if + } // for + } // for +} // gva_lcs_graph_uniq_atomics + + gva_uint gva_edges(char const observed[static restrict 1], GVA_Node const head, GVA_Node const tail, From 9789983f080855386cee5842c1fe71133f797850 Mon Sep 17 00:00:00 2001 From: jkvis Date: Sun, 15 Feb 2026 22:19:14 +0100 Subject: [PATCH 478/704] WIP: bring back unit tests --- Makefile | 3 -- tests/test_array.c | 94 ++++++++++++++++++++++++++++++++++++++++++ tests/test_std_alloc.c | 29 +++++++++++++ 3 files changed, 123 insertions(+), 3 deletions(-) create mode 100644 tests/test_array.c create mode 100644 tests/test_std_alloc.c diff --git a/Makefile b/Makefile index c3545b2..96a9678 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,6 @@ OBJECTS = $(SOURCES:.c=.o) DEPS = $(SOURCES:.c=.d) TESTS = $(wildcard $(TEST_DIR)/*.c) TEST_BINS = $(TESTS:.c=.out) -TEST_DEPS = $(TESTS:.c=.d) TEST_GCNOS = $(TESTS:.c=.gcno) TEST_GCDAS = $(TESTS:.c=.gcda) TEST_COVS = $(TESTS:.c=.c.gcov) @@ -44,8 +43,6 @@ $(TARGET): $(OBJECTS) $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $^ --include $(TEST_DEPS) - %.out: %.c $(CC) $(CFLAGS) $(CPPFLAGS) -MMD -o $@ $< diff --git a/tests/test_array.c b/tests/test_array.c new file mode 100644 index 0000000..31fbf5e --- /dev/null +++ b/tests/test_array.c @@ -0,0 +1,94 @@ +#include // assert +#include // NULL, size_t +#include // EXIT_SUCCESS + +#include "../include/std_alloc.h" // gva_std_allocator + +#include "../src/array.h" // ARRAY_*, array_* +#include "../src/array.c" // ARRAY_*, array_* + + +static void +test_array_init_null(void) +{ + int* a = NULL; + assert(array_length(a) == 0); + + a = ARRAY_DESTROY(gva_std_allocator, a); + assert(a == NULL); + + a = array_init(gva_std_allocator, 0, sizeof(*a)); + assert(a == NULL); +} // test_array_init + + +static void +test_array_append_null(void) +{ + int* a = NULL; + + assert(ARRAY_APPEND(gva_std_allocator, a, 0) == 1); + assert(array_header(a)->capacity == 1); + + assert(ARRAY_APPEND(gva_std_allocator, a, 1) == 2); + assert(array_header(a)->capacity == 2); + + assert(ARRAY_APPEND(gva_std_allocator, a, 2) == 3); + assert(array_header(a)->capacity == 4); + + assert(ARRAY_APPEND(gva_std_allocator, a, 3) == 4); + assert(array_header(a)->capacity == 4); + + assert(array_length(a) == 4); + assert(a[0] == 0); + assert(a[1] == 1); + assert(a[2] == 2); + assert(a[3] == 3); + + a = ARRAY_DESTROY(gva_std_allocator, a); +} // test_array_append_null + + +static void +test_array_ensure(void) +{ + int* a = array_init(gva_std_allocator, 2, sizeof(*a)); + assert(array_header(a)->capacity == 2); + + a = array_ensure(gva_std_allocator, a, sizeof(*a), 10); + assert(array_header(a)->capacity == 16); + + a = ARRAY_DESTROY(gva_std_allocator, a); +} // test_array_ensure + + +static void +test_array_usage(void) +{ + struct S + { + int x; + int y; + }* a = NULL; + + for (size_t i = 0; i < 1000; ++i) + { + ARRAY_APPEND(gva_std_allocator, a, ((struct S) {i, i})); + } // for + + a = ARRAY_DESTROY(gva_std_allocator, a); +} // test_array_usage + + +int +main(int argc, char* argv[static argc]) +{ + (void) argv; + + test_array_init_null(); + test_array_append_null(); + test_array_ensure(); + test_array_usage(); + + return EXIT_SUCCESS; +} // main \ No newline at end of file diff --git a/tests/test_std_alloc.c b/tests/test_std_alloc.c new file mode 100644 index 0000000..9b53a08 --- /dev/null +++ b/tests/test_std_alloc.c @@ -0,0 +1,29 @@ +#include // assert +#include // NULL +#include // EXIT_SUCCESS + +#include "../include/std_alloc.h" // gva_std_allocate + + +static void +test_std_allocate(void) +{ + int* a = gva_std_allocate(NULL, NULL, 0, 0); + assert(a == NULL); + + a = gva_std_allocate(NULL, a, 0, 1000); + assert(a != NULL); + + a = gva_std_allocate(NULL, a, 1000, 0); +} // test_std_allocate + + +int +main(int argc, char* argv[static argc]) +{ + (void) argv; + + test_std_allocate(); + + return EXIT_SUCCESS; +} // main \ No newline at end of file From 706f60868d38f9f18c5be52a7f285bd8cab08f5c Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 16 Feb 2026 11:02:21 +0100 Subject: [PATCH 479/704] WIP snapshot --- include/index.h | 2 +- src/index.c | 62 ++++++++++++++++++++++++++++++------------------- 2 files changed, 39 insertions(+), 25 deletions(-) diff --git a/include/index.h b/include/index.h index 61fab8c..6940587 100644 --- a/include/index.h +++ b/include/index.h @@ -14,7 +14,7 @@ typedef struct GVA_Index GVA_Index; // opaque GVA_Index* gva_index_init(GVA_Allocator const allocator, - size_t const len, char const reference[static len]); + size_t const len_ref, char const reference[static len_ref]); GVA_Index* diff --git a/src/index.c b/src/index.c index 40e894c..5c8d085 100644 --- a/src/index.c +++ b/src/index.c @@ -2,7 +2,6 @@ #include // intmax_t #include // memcpy - #include "../include/allocator.h" // GVA_Allocator #include "../include/edit.h" // gva_edit_distance #include "../include/index.h" // GVA_Index, gva_index_* @@ -112,8 +111,6 @@ variants_distance(GVA_Allocator const allocator, } // variants_distance -// FIXME: taken from compare_supremals -// FIXME: overlap with variants_distance static size_t variants_common(GVA_Allocator const allocator, size_t const len_ref, char const reference[static len_ref], @@ -152,7 +149,6 @@ variants_common(GVA_Allocator const allocator, size_t const start_intersection = MAX(lhs.start, rhs.start); size_t const end_intersection = MIN(lhs.end, rhs.end); - // could be done on intersection instead of union gva_lcs_graph_uniq_atomics(lhs_graph, start, start_intersection, end_intersection, lhs_dels, lhs_as, lhs_cs, lhs_gs, lhs_ts); gva_lcs_graph_destroy(allocator, lhs_graph); @@ -166,21 +162,6 @@ variants_common(GVA_Allocator const allocator, bitset_intersection_cnt(lhs_gs, rhs_gs) + bitset_intersection_cnt(lhs_ts, rhs_ts); - // Also calculate the union - // Note: bitset_fill needs to use "plain" start and end. - // - // size_t const union1 = - // bitset_intersection_cnt(lhs_dels, lhs_dels) + - // bitset_intersection_cnt(lhs_as, lhs_as) + - // bitset_intersection_cnt(lhs_cs, lhs_cs) + - // bitset_intersection_cnt(lhs_gs, lhs_gs) + - // bitset_intersection_cnt(lhs_ts, lhs_ts) + - // bitset_intersection_cnt(rhs_dels, rhs_dels) + - // bitset_intersection_cnt(rhs_as, rhs_as) + - // bitset_intersection_cnt(rhs_cs, rhs_cs) + - // bitset_intersection_cnt(rhs_gs, rhs_gs) + - // bitset_intersection_cnt(rhs_ts, rhs_ts) - common; - rhs_ts = bitset_destroy(allocator, rhs_ts); rhs_gs = bitset_destroy(allocator, rhs_gs); rhs_cs = bitset_destroy(allocator, rhs_cs); @@ -200,9 +181,30 @@ variants_common(GVA_Allocator const allocator, } // variants_common +static inline size_t +variants_with_distance(GVA_Allocator const allocator, + size_t const len_ref, char const reference[static len_ref], + GVA_Variant const lhs, size_t const distance_lhs, + GVA_Variant const rhs, size_t const distance_rhs) +{ + size_t const distance = variants_distance(allocator, len_ref, reference, lhs, rhs); + + if (distance == 0 || distance_rhs - distance_lhs == distance) + { + return distance_lhs; + } // if + if (distance_lhs - distance_rhs == distance) + { + return distance_rhs; + } // if + + return variants_common(allocator, len_ref, reference, lhs, rhs); +} // variants_with_distance + + inline GVA_Index* gva_index_init(GVA_Allocator const allocator, - size_t const len, char const reference[static len]) + size_t const len_ref, char const reference[static len_ref]) { GVA_Index* index = allocator.allocate(allocator.context, NULL, 0, sizeof(*index)); if (index == NULL) @@ -211,7 +213,7 @@ gva_index_init(GVA_Allocator const allocator, } // if index->allocator = allocator; - index->reference = (GVA_String) {len, reference}; + index->reference = (GVA_String) {len_ref, reference}; index->intervals = interval_tree_init(); index->inserted = trie_init(); @@ -356,6 +358,7 @@ gva_index_query(GVA_Allocator const allocator, { fprintf(stderr, " %u %u %u %u\n", parts[i].part, parts[i].distance, parts[i].start, parts[i].end); + // FIXME: don't build an allele, but a supremal instead GVA_Variant* variants = NULL; size_t distance = 0; while (parts[i].next != GVA_NULL && parts[parts[i].next].start == parts[i].start) @@ -378,15 +381,26 @@ gva_index_query(GVA_Allocator const allocator, fprintf(stderr, " DB multi hit: %zu (%zu)\n", array_length(variants), distance); variants = ARRAY_DESTROY(allocator, variants); } // if - else if (parts[i].end - parts[i].start > 1) + else if (parts[i].end - parts[i].start > 1) // FIXME: similar body to if below? { - size_t distance = 0; + // FIXME: use cumulative distances in dom_nodes + size_t distance = 0; // graph.dom_nodes[parts[i].end].distance - graph.dom_nodes[parts[i].start].distance for (gva_uint j = parts[i].start; j < parts[i].end; ++j) { distance += graph.dom_nodes[j + 1].distance; } // for + GVA_Variant variant; + gva_edges(graph.observed.str, + graph.dom_nodes[parts[i].start], graph.dom_nodes[parts[i].end], + parts[i].start == 0, parts[i].end == array_length(graph.dom_nodes) - 2, + &variant); + gva_uint const node_idx = self->join[parts[i].part].link ^ alleles[idx].gva_key; + gva_uint const included = variants_with_distance(allocator, self->reference.len, self->reference.str, + variant_from_index(self, node_idx), self->intervals.nodes[node_idx].distance, + variant, distance); + // TODO: multiple query hits with one DB hit - fprintf(stderr, " Query multi hit: %u (%zu)\n", parts[i].end - parts[i].start, distance); + fprintf(stderr, " Query multi hit: %u (%zu) :: %u\n", parts[i].end - parts[i].start, distance, included); } // if else if (ABS((intmax_t) self->intervals.nodes[self->join[parts[i].part].link ^ alleles[idx].gva_key].distance - graph.dom_nodes[parts[i].start + 1].distance) != parts[i].distance) { From 738efa1351ba2e229aad9e1c0ea49e573094e627 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Mon, 16 Feb 2026 16:32:38 +0100 Subject: [PATCH 480/704] End to end validation of truth_2026!! --- src/index.c | 145 +++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 120 insertions(+), 25 deletions(-) diff --git a/src/index.c b/src/index.c index 5c8d085..302b500 100644 --- a/src/index.c +++ b/src/index.c @@ -95,11 +95,17 @@ variants_distance(GVA_Allocator const allocator, } // if memcpy((char*) observed_lhs.str, reference + start, lhs.start - start); - memcpy((char*) observed_lhs.str + lhs.start - start, lhs.sequence.str, lhs.sequence.len); + if (lhs.sequence.str != NULL) + { + memcpy((char*) observed_lhs.str + lhs.start - start, lhs.sequence.str, lhs.sequence.len); + } memcpy((char*) observed_lhs.str + lhs.start - start + lhs.sequence.len, reference + lhs.end, end - lhs.end); memcpy((char*) observed_rhs.str, reference + start, rhs.start - start); - memcpy((char*) observed_rhs.str + rhs.start - start, rhs.sequence.str, rhs.sequence.len); + if (rhs.sequence.str != NULL) + { + memcpy((char*) observed_rhs.str + rhs.start - start, rhs.sequence.str, rhs.sequence.len); + } memcpy((char*) observed_rhs.str + rhs.start - start + rhs.sequence.len, reference + rhs.end, end - rhs.end); size_t const distance = gva_edit_distance(allocator, observed_lhs.len, observed_lhs.str, observed_rhs.len, observed_rhs.str); @@ -123,11 +129,17 @@ variants_common(GVA_Allocator const allocator, GVA_String observed_rhs = gva_string_init(allocator, (rhs.start - start) + rhs.sequence.len + (end - rhs.end)); memcpy((char*) observed_lhs.str, reference + start, lhs.start - start); - memcpy((char*) observed_lhs.str + lhs.start - start, lhs.sequence.str, lhs.sequence.len); + if (lhs.sequence.str != NULL) + { + memcpy((char*) observed_lhs.str + lhs.start - start, lhs.sequence.str, lhs.sequence.len); + } memcpy((char*) observed_lhs.str + lhs.start - start + lhs.sequence.len, reference + lhs.end, end - lhs.end); memcpy((char*) observed_rhs.str, reference + start, rhs.start - start); - memcpy((char*) observed_rhs.str + rhs.start - start, rhs.sequence.str, rhs.sequence.len); + if (rhs.sequence.str != NULL) + { + memcpy((char*) observed_rhs.str + rhs.start - start, rhs.sequence.str, rhs.sequence.len); + } memcpy((char*) observed_rhs.str + rhs.start - start + rhs.sequence.len, reference + rhs.end, end - rhs.end); GVA_LCS_Graph lhs_graph = gva_lcs_graph_init(allocator, end - start, reference + start, observed_lhs.len, observed_lhs.str, start); @@ -291,7 +303,7 @@ gva_index_query(GVA_Allocator const allocator, struct Result_Part { gva_uint part; - gva_uint distance; + gva_uint included; gva_uint start; gva_uint end; gva_uint next; @@ -317,7 +329,7 @@ gva_index_query(GVA_Allocator const allocator, } // if fprintf(stderr, " vs " GVA_VARIANT_FMT_SPDI " (%u)\n", GVA_VARIANT_PRINT_SPDI("NC_000001.11", variant_from_index(self, intervals[j])), self->intervals.nodes[intervals[j]].distance); - +test_alleles_supremal2.txt for (gva_uint k = self->intervals.nodes[intervals[j]].alleles; k != GVA_NULL; k = self->join[k].next) { gva_uint const allele_idx = self->join[k].link ^ intervals[j]; @@ -354,32 +366,53 @@ gva_index_query(GVA_Allocator const allocator, fprintf(stderr, GVA_STRING_FMT ":\n", GVA_STRING_PRINT(trie_string(self->ids, self->alleles[alleles[idx].gva_key].id_idx))); + gva_uint prev = GVA_NULL; for (gva_uint i = alleles[idx].head; i != GVA_NULL; i = parts[i].next) { - fprintf(stderr, " %u %u %u %u\n", parts[i].part, parts[i].distance, parts[i].start, parts[i].end); + fprintf(stderr, " %u %u %u %u\n", parts[i].part, parts[i].included, parts[i].start, parts[i].end); - // FIXME: don't build an allele, but a supremal instead - GVA_Variant* variants = NULL; + GVA_Variant variant = {0, 0, {0, NULL}}; size_t distance = 0; while (parts[i].next != GVA_NULL && parts[parts[i].next].start == parts[i].start) { - if (variants == NULL) + if (gva_variant_length(variant) == 0) { gva_uint const node_idx = self->join[parts[i].part].link ^ alleles[idx].gva_key; - ARRAY_APPEND(allocator, variants, variant_from_index(self, node_idx)); - distance += self->intervals.nodes[node_idx].distance; + variant = gva_variant_dup(allocator, variant_from_index(self, node_idx)); + distance = self->intervals.nodes[node_idx].distance; } // if i = parts[i].next; gva_uint const node_idx = self->join[parts[i].part].link ^ alleles[idx].gva_key; - ARRAY_APPEND(allocator, variants, variant_from_index(self, node_idx)); + GVA_Variant const current = variant_from_index(self, node_idx); + variant.sequence = gva_string_concat(allocator, variant.sequence, + (GVA_String) {current.start - variant.end, self->reference.str + variant.end}); + variant.sequence = gva_string_concat(allocator, variant.sequence, current.sequence); + variant.end = current.end; distance += self->intervals.nodes[node_idx].distance; - fprintf(stderr, " %u %u %u %u\n", parts[i].part, parts[i].distance, parts[i].start, parts[i].end); + + fprintf(stderr, " %u %u %u %u\n", parts[i].part, parts[i].included, parts[i].start, parts[i].end); } // while - if (variants != NULL) + + + if (gva_variant_length(variant) != 0) { - // TODO: multiple DB hits with one query hit - fprintf(stderr, " DB multi hit: %zu (%zu)\n", array_length(variants), distance); - variants = ARRAY_DESTROY(allocator, variants); + GVA_Variant rhs; + gva_edges(graph.observed.str, + graph.dom_nodes[parts[i].start], graph.dom_nodes[parts[i].end], + parts[i].start == 0, parts[i].end == array_length(graph.dom_nodes) - 2, + &rhs); + parts[i].included = variants_with_distance(allocator, self->reference.len, self->reference.str, + variant, distance, rhs, graph.dom_nodes[parts[i].start + 1].distance); + if (prev == GVA_NULL) + { + alleles[idx].head = i; + } // if + else + { + parts[prev].next = i; + } // else + fprintf(stderr, " DB multi hit: " GVA_VARIANT_FMT_SPDI " (%zu) :: %u\n", GVA_VARIANT_PRINT_SPDI("NC_000001.11", variant), distance, parts[i].included); + gva_string_destroy(allocator, variant.sequence); } // if else if (parts[i].end - parts[i].start > 1) // FIXME: similar body to if below? { @@ -395,27 +428,89 @@ gva_index_query(GVA_Allocator const allocator, parts[i].start == 0, parts[i].end == array_length(graph.dom_nodes) - 2, &variant); gva_uint const node_idx = self->join[parts[i].part].link ^ alleles[idx].gva_key; - gva_uint const included = variants_with_distance(allocator, self->reference.len, self->reference.str, + parts[i].included = variants_with_distance(allocator, self->reference.len, self->reference.str, variant_from_index(self, node_idx), self->intervals.nodes[node_idx].distance, variant, distance); - // TODO: multiple query hits with one DB hit - fprintf(stderr, " Query multi hit: %u (%zu) :: %u\n", parts[i].end - parts[i].start, distance, included); + fprintf(stderr, " Query multi hit: %u (%zu) :: %u\n", parts[i].end - parts[i].start, distance, parts[i].included); } // if - else if (ABS((intmax_t) self->intervals.nodes[self->join[parts[i].part].link ^ alleles[idx].gva_key].distance - graph.dom_nodes[parts[i].start + 1].distance) != parts[i].distance) + else if (ABS((intmax_t) self->intervals.nodes[self->join[parts[i].part].link ^ alleles[idx].gva_key].distance - graph.dom_nodes[parts[i].start + 1].distance) != parts[i].included) { GVA_Variant variant; gva_edges(graph.observed.str, graph.dom_nodes[parts[i].start], graph.dom_nodes[parts[i].end], parts[i].start == 0, parts[i].end == array_length(graph.dom_nodes) - 2, &variant); - gva_uint const included = variants_common(allocator, self->reference.len, self->reference.str, variant_from_index(self, self->join[parts[i].part].link ^ alleles[idx].gva_key), variant); - fprintf(stderr, " Fully calculate: %u\n", included); + parts[i].included = variants_common(allocator, self->reference.len, self->reference.str, variant_from_index(self, self->join[parts[i].part].link ^ alleles[idx].gva_key), variant); + fprintf(stderr, " Fully calculate: %u\n", parts[i].included); } // if - // TODO: aggregate independent results + else + { + gva_uint const node_idx = self->join[parts[i].part].link ^ alleles[idx].gva_key; + if (parts[i].included == 0 || graph.dom_nodes[parts[i].start + 1].distance - self->intervals.nodes[node_idx].distance == parts[i].included) + { + parts[i].included = self->intervals.nodes[node_idx].distance; + } // if + else if (self->intervals.nodes[node_idx].distance - graph.dom_nodes[parts[i].start + 1].distance == parts[i].included) + { + parts[i].included = graph.dom_nodes[parts[i].start + 1].distance; + } // if + } + alleles[idx].included += parts[i].included; + prev = i; } // for + // TODO: exclude included == 0? } // for + for (size_t idx = 0; idx < array_header(alleles)->capacity; ++idx) + { + if (alleles[idx].gva_key == NOT_FOUND) + { + continue; + } // if + + gva_uint const excluded = self->alleles[alleles[idx].gva_key].distance + graph.distance - 2 * alleles[idx].included; + fprintf(stderr, GVA_STRING_FMT ": %u\n", + GVA_STRING_PRINT(trie_string(self->ids, self->alleles[alleles[idx].gva_key].id_idx)), + alleles[idx].included);test_alleles_supremal2.txt + + for (gva_uint i = alleles[idx].head; i != GVA_NULL; i = parts[i].next) + { + fprintf(stderr, " parts incl: %u\n", parts[i].included); + } + + if (alleles[idx].included == 0) + { + fprintf(stdout, GVA_STRING_FMT " %s\n", + GVA_STRING_PRINT(trie_string(self->ids, self->alleles[alleles[idx].gva_key].id_idx)), GVA_RELATION_LABELS[GVA_DISJOINT]); + continue; + } + + if (excluded == 0) + { + fprintf(stdout, GVA_STRING_FMT " %s\n", + GVA_STRING_PRINT(trie_string(self->ids, self->alleles[alleles[idx].gva_key].id_idx)), GVA_RELATION_LABELS[GVA_EQUIVALENT]); + continue; + } + + if (alleles[idx].included == graph.distance) + { + fprintf(stdout, GVA_STRING_FMT " %s\n", + GVA_STRING_PRINT(trie_string(self->ids, self->alleles[alleles[idx].gva_key].id_idx)), GVA_RELATION_LABELS[GVA_CONTAINS]); + continue; + } + + if (alleles[idx].included == self->alleles[alleles[idx].gva_key].distance) + { + fprintf(stdout, GVA_STRING_FMT " %s\n", + GVA_STRING_PRINT(trie_string(self->ids, self->alleles[alleles[idx].gva_key].id_idx)), GVA_RELATION_LABELS[GVA_IS_CONTAINED]); + continue; + } + + fprintf(stdout, GVA_STRING_FMT " %s\n", + GVA_STRING_PRINT(trie_string(self->ids, self->alleles[alleles[idx].gva_key].id_idx)), GVA_RELATION_LABELS[GVA_OVERLAP]); + } + parts = ARRAY_DESTROY(allocator, parts); alleles = HASH_TABLE_DESTROY(allocator, alleles); } // gva_index_query From d20df24099f6ccbecce6795cc3d2fde93d9463d3 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Mon, 16 Feb 2026 16:53:35 +0100 Subject: [PATCH 481/704] Oops. --- src/index.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/index.c b/src/index.c index 302b500..5576eb6 100644 --- a/src/index.c +++ b/src/index.c @@ -329,7 +329,6 @@ gva_index_query(GVA_Allocator const allocator, } // if fprintf(stderr, " vs " GVA_VARIANT_FMT_SPDI " (%u)\n", GVA_VARIANT_PRINT_SPDI("NC_000001.11", variant_from_index(self, intervals[j])), self->intervals.nodes[intervals[j]].distance); -test_alleles_supremal2.txt for (gva_uint k = self->intervals.nodes[intervals[j]].alleles; k != GVA_NULL; k = self->join[k].next) { gva_uint const allele_idx = self->join[k].link ^ intervals[j]; From 69b31fa2ab431f1935a0b182b51935a6cdbfa63a Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Mon, 16 Feb 2026 16:54:45 +0100 Subject: [PATCH 482/704] Oops 2. --- src/index.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.c b/src/index.c index 5576eb6..6b4a3cb 100644 --- a/src/index.c +++ b/src/index.c @@ -471,7 +471,7 @@ gva_index_query(GVA_Allocator const allocator, gva_uint const excluded = self->alleles[alleles[idx].gva_key].distance + graph.distance - 2 * alleles[idx].included; fprintf(stderr, GVA_STRING_FMT ": %u\n", GVA_STRING_PRINT(trie_string(self->ids, self->alleles[alleles[idx].gva_key].id_idx)), - alleles[idx].included);test_alleles_supremal2.txt + alleles[idx].included); for (gva_uint i = alleles[idx].head; i != GVA_NULL; i = parts[i].next) { From f88162c5ebd1edeb7417c1099b1ab40ac163f43b Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 16 Feb 2026 17:01:03 +0100 Subject: [PATCH 483/704] Revert test dependencies --- Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Makefile b/Makefile index 96a9678..146acdd 100644 --- a/Makefile +++ b/Makefile @@ -5,6 +5,7 @@ SOURCES = $(wildcard $(SRC_DIR)/*.c) OBJECTS = $(SOURCES:.c=.o) DEPS = $(SOURCES:.c=.d) TESTS = $(wildcard $(TEST_DIR)/*.c) +TEST_DEPS = $(TESTS:.c=.d) TEST_BINS = $(TESTS:.c=.out) TEST_GCNOS = $(TESTS:.c=.gcno) TEST_GCDAS = $(TESTS:.c=.gcda) @@ -43,6 +44,8 @@ $(TARGET): $(OBJECTS) $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $^ +-include $(TEST_DEPS) + %.out: %.c $(CC) $(CFLAGS) $(CPPFLAGS) -MMD -o $@ $< From 086e05e30ff707316cef43104732f2323f70bdf6 Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 16 Feb 2026 17:01:15 +0100 Subject: [PATCH 484/704] Minor style --- src/index.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/index.c b/src/index.c index 6b4a3cb..28c8d46 100644 --- a/src/index.c +++ b/src/index.c @@ -98,14 +98,14 @@ variants_distance(GVA_Allocator const allocator, if (lhs.sequence.str != NULL) { memcpy((char*) observed_lhs.str + lhs.start - start, lhs.sequence.str, lhs.sequence.len); - } + } // if memcpy((char*) observed_lhs.str + lhs.start - start + lhs.sequence.len, reference + lhs.end, end - lhs.end); memcpy((char*) observed_rhs.str, reference + start, rhs.start - start); if (rhs.sequence.str != NULL) { memcpy((char*) observed_rhs.str + rhs.start - start, rhs.sequence.str, rhs.sequence.len); - } + } // if memcpy((char*) observed_rhs.str + rhs.start - start + rhs.sequence.len, reference + rhs.end, end - rhs.end); size_t const distance = gva_edit_distance(allocator, observed_lhs.len, observed_lhs.str, observed_rhs.len, observed_rhs.str); @@ -132,14 +132,14 @@ variants_common(GVA_Allocator const allocator, if (lhs.sequence.str != NULL) { memcpy((char*) observed_lhs.str + lhs.start - start, lhs.sequence.str, lhs.sequence.len); - } + } // if memcpy((char*) observed_lhs.str + lhs.start - start + lhs.sequence.len, reference + lhs.end, end - lhs.end); memcpy((char*) observed_rhs.str, reference + start, rhs.start - start); if (rhs.sequence.str != NULL) { memcpy((char*) observed_rhs.str + rhs.start - start, rhs.sequence.str, rhs.sequence.len); - } + } // if memcpy((char*) observed_rhs.str + rhs.start - start + rhs.sequence.len, reference + rhs.end, end - rhs.end); GVA_LCS_Graph lhs_graph = gva_lcs_graph_init(allocator, end - start, reference + start, observed_lhs.len, observed_lhs.str, start); @@ -392,7 +392,6 @@ gva_index_query(GVA_Allocator const allocator, fprintf(stderr, " %u %u %u %u\n", parts[i].part, parts[i].included, parts[i].start, parts[i].end); } // while - if (gva_variant_length(variant) != 0) { GVA_Variant rhs; @@ -454,7 +453,7 @@ gva_index_query(GVA_Allocator const allocator, { parts[i].included = graph.dom_nodes[parts[i].start + 1].distance; } // if - } + } // else alleles[idx].included += parts[i].included; prev = i; } // for @@ -476,39 +475,39 @@ gva_index_query(GVA_Allocator const allocator, for (gva_uint i = alleles[idx].head; i != GVA_NULL; i = parts[i].next) { fprintf(stderr, " parts incl: %u\n", parts[i].included); - } + } // for if (alleles[idx].included == 0) { fprintf(stdout, GVA_STRING_FMT " %s\n", GVA_STRING_PRINT(trie_string(self->ids, self->alleles[alleles[idx].gva_key].id_idx)), GVA_RELATION_LABELS[GVA_DISJOINT]); continue; - } + } // if if (excluded == 0) { fprintf(stdout, GVA_STRING_FMT " %s\n", GVA_STRING_PRINT(trie_string(self->ids, self->alleles[alleles[idx].gva_key].id_idx)), GVA_RELATION_LABELS[GVA_EQUIVALENT]); continue; - } + } // if if (alleles[idx].included == graph.distance) { fprintf(stdout, GVA_STRING_FMT " %s\n", GVA_STRING_PRINT(trie_string(self->ids, self->alleles[alleles[idx].gva_key].id_idx)), GVA_RELATION_LABELS[GVA_CONTAINS]); continue; - } + } // if if (alleles[idx].included == self->alleles[alleles[idx].gva_key].distance) { fprintf(stdout, GVA_STRING_FMT " %s\n", GVA_STRING_PRINT(trie_string(self->ids, self->alleles[alleles[idx].gva_key].id_idx)), GVA_RELATION_LABELS[GVA_IS_CONTAINED]); continue; - } + } // if fprintf(stdout, GVA_STRING_FMT " %s\n", GVA_STRING_PRINT(trie_string(self->ids, self->alleles[alleles[idx].gva_key].id_idx)), GVA_RELATION_LABELS[GVA_OVERLAP]); - } + } // for parts = ARRAY_DESTROY(allocator, parts); alleles = HASH_TABLE_DESTROY(allocator, alleles); From 0aac99baa0a7ceb383d5852a4859167c248d476b Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Mon, 16 Feb 2026 22:58:14 +0100 Subject: [PATCH 485/704] Manual merge. --- include/index.h | 10 +++++++++- src/index.c | 49 ++++++++++++++++++++++++------------------------- src/main.c | 6 +++--- 3 files changed, 36 insertions(+), 29 deletions(-) diff --git a/include/index.h b/include/index.h index 6940587..f854fc1 100644 --- a/include/index.h +++ b/include/index.h @@ -6,12 +6,20 @@ #include "allocator.h" // GVA_Allocator #include "lcs_graph.h" // GVA_LCS_Graph +#include "relations.h" // GVA_Relation #include "variant.h" // GVA_Variant typedef struct GVA_Index GVA_Index; // opaque +typedef struct +{ + gva_uint allele_idx; + GVA_Relation relation; +} GVA_Result; + + GVA_Index* gva_index_init(GVA_Allocator const allocator, size_t const len_ref, char const reference[static len_ref]); @@ -29,7 +37,7 @@ gva_index_insert(GVA_Index* restrict const self, // FIXME: returns -void +GVA_Result* gva_index_query(GVA_Allocator const allocator, GVA_Index* const self, GVA_LCS_Graph const graph); diff --git a/src/index.c b/src/index.c index 28c8d46..aa15cce 100644 --- a/src/index.c +++ b/src/index.c @@ -4,7 +4,7 @@ #include "../include/allocator.h" // GVA_Allocator #include "../include/edit.h" // gva_edit_distance -#include "../include/index.h" // GVA_Index, gva_index_* +#include "../include/index.h" // GVA_Index, gva_index_*, GVA_Result #include "../include/lcs_graph.h" // GVA_LCS_Graph, gva_edges #include "../include/relations.h" // GVA_Relation, GVA_CONTAINS, // GVA_DISJOINT, GVA_EQUIVALENT, @@ -288,7 +288,7 @@ gva_index_insert(GVA_Index* restrict const self, } // gva_index_insert -void +GVA_Result* gva_index_query(GVA_Allocator const allocator, GVA_Index* const self, GVA_LCS_Graph const graph) { @@ -460,6 +460,8 @@ gva_index_query(GVA_Allocator const allocator, // TODO: exclude included == 0? } // for + GVA_Result* results = NULL; + for (size_t idx = 0; idx < array_header(alleles)->capacity; ++idx) { if (alleles[idx].gva_key == NOT_FOUND) @@ -467,7 +469,6 @@ gva_index_query(GVA_Allocator const allocator, continue; } // if - gva_uint const excluded = self->alleles[alleles[idx].gva_key].distance + graph.distance - 2 * alleles[idx].included; fprintf(stderr, GVA_STRING_FMT ": %u\n", GVA_STRING_PRINT(trie_string(self->ids, self->alleles[alleles[idx].gva_key].id_idx)), alleles[idx].included); @@ -477,38 +478,36 @@ gva_index_query(GVA_Allocator const allocator, fprintf(stderr, " parts incl: %u\n", parts[i].included); } // for + GVA_Relation relation; if (alleles[idx].included == 0) { - fprintf(stdout, GVA_STRING_FMT " %s\n", - GVA_STRING_PRINT(trie_string(self->ids, self->alleles[alleles[idx].gva_key].id_idx)), GVA_RELATION_LABELS[GVA_DISJOINT]); - continue; + relation = GVA_DISJOINT; } // if - - if (excluded == 0) + else if (self->alleles[alleles[idx].gva_key].distance + graph.distance - 2 * alleles[idx].included == 0) { - fprintf(stdout, GVA_STRING_FMT " %s\n", - GVA_STRING_PRINT(trie_string(self->ids, self->alleles[alleles[idx].gva_key].id_idx)), GVA_RELATION_LABELS[GVA_EQUIVALENT]); - continue; + relation = GVA_EQUIVALENT; } // if - - if (alleles[idx].included == graph.distance) + else if (alleles[idx].included == graph.distance) { - fprintf(stdout, GVA_STRING_FMT " %s\n", - GVA_STRING_PRINT(trie_string(self->ids, self->alleles[alleles[idx].gva_key].id_idx)), GVA_RELATION_LABELS[GVA_CONTAINS]); - continue; - } // if - - if (alleles[idx].included == self->alleles[alleles[idx].gva_key].distance) + relation = GVA_CONTAINS; + } // else if + else if (alleles[idx].included == self->alleles[alleles[idx].gva_key].distance) { - fprintf(stdout, GVA_STRING_FMT " %s\n", - GVA_STRING_PRINT(trie_string(self->ids, self->alleles[alleles[idx].gva_key].id_idx)), GVA_RELATION_LABELS[GVA_IS_CONTAINED]); - continue; - } // if + relation = GVA_IS_CONTAINED; + } // else if + else + { + relation = GVA_OVERLAP; + } // else - fprintf(stdout, GVA_STRING_FMT " %s\n", - GVA_STRING_PRINT(trie_string(self->ids, self->alleles[alleles[idx].gva_key].id_idx)), GVA_RELATION_LABELS[GVA_OVERLAP]); + ARRAY_APPEND(self->allocator, results, + ((GVA_Result) {trie_string(self->ids, self->alleles[alleles[idx].gva_key].id_idx), relation}) + ); } // for + parts = ARRAY_DESTROY(allocator, parts); alleles = HASH_TABLE_DESTROY(allocator, alleles); + + return results; } // gva_index_query diff --git a/src/main.c b/src/main.c index 988a839..8fe6a9c 100644 --- a/src/main.c +++ b/src/main.c @@ -11,7 +11,7 @@ #include "../include/compare.h" // bitset_fill #include "../include/edit.h" // gva_edit_distance #include "../include/extractor.h" // gva_canonical -#include "../include/index.h" // GVA_Index, gva_index_* +#include "../include/index.h" // GVA_Index, gva_index_*, GVA_Result #include "../include/lcs_graph.h" // GVA_LCS_Graph, GVA_Variant, gva_lcs_graph_*, gva_edges #include "../include/std_alloc.h" // gva_std_allocator #include "../include/string.h" // GVA_String, gva_string_destroy @@ -583,8 +583,8 @@ index_main(int argc, char* argv[static argc]) GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &variant); - fprintf(stderr, "\nQuery (" GVA_STRING_FMT "): " GVA_VARIANT_FMT_SPDI " (%u)\n", GVA_STRING_PRINT(((GVA_String) {id_len, line})), GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, graph.supremal), graph.distance); - gva_index_query(gva_std_allocator, index, graph); + fprintf(stdout, "\nQuery (" GVA_STRING_FMT "): " GVA_VARIANT_FMT_SPDI " (%u)\n", GVA_STRING_PRINT(((GVA_String) {id_len, line})), GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, graph.supremal), graph.distance); + GVA_Result* results = gva_index_query(gva_std_allocator, index, graph); gva_string_destroy(gva_std_allocator, graph.observed); gva_lcs_graph_destroy(gva_std_allocator, graph); From 9c85f9c614a48aeb402cf67f931baebd7ce879a2 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Mon, 16 Feb 2026 22:58:39 +0100 Subject: [PATCH 486/704] print relation triples. --- include/index.h | 2 +- src/main.c | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/include/index.h b/include/index.h index f854fc1..7e7086e 100644 --- a/include/index.h +++ b/include/index.h @@ -15,7 +15,7 @@ typedef struct GVA_Index GVA_Index; // opaque typedef struct { - gva_uint allele_idx; + GVA_String allele; GVA_Relation relation; } GVA_Result; diff --git a/src/main.c b/src/main.c index 8fe6a9c..e56ecf4 100644 --- a/src/main.c +++ b/src/main.c @@ -583,11 +583,19 @@ index_main(int argc, char* argv[static argc]) GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &variant); - fprintf(stdout, "\nQuery (" GVA_STRING_FMT "): " GVA_VARIANT_FMT_SPDI " (%u)\n", GVA_STRING_PRINT(((GVA_String) {id_len, line})), GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, graph.supremal), graph.distance); + // fprintf(stdout, "\nQuery (" GVA_STRING_FMT "): " GVA_VARIANT_FMT_SPDI " (%u)\n", GVA_STRING_PRINT(((GVA_String) {id_len, line})), GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, graph.supremal), graph.distance); GVA_Result* results = gva_index_query(gva_std_allocator, index, graph); + for (size_t i = 0; i < array_length(results); ++i) + { + fprintf(stdout, GVA_STRING_FMT " %s %.*s\n", + GVA_STRING_PRINT(results[i].allele), + GVA_RELATION_LABELS[results[i].relation], + (int)id_len, line); + } gva_string_destroy(gva_std_allocator, graph.observed); gva_lcs_graph_destroy(gva_std_allocator, graph); + ARRAY_DESTROY(gva_std_allocator, results); } // while index = gva_index_destroy(index); From 5b7133642b09d5bc221f1a960578bed197f8fa2a Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Tue, 17 Feb 2026 09:40:58 +0100 Subject: [PATCH 487/704] Parsing for input without distance. --- src/main.c | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/src/main.c b/src/main.c index e56ecf4..62ac53b 100644 --- a/src/main.c +++ b/src/main.c @@ -31,8 +31,8 @@ #define LINE_SIZE 8194 -// #define REFERENCE_ID "NC_000006.12" -#define REFERENCE_ID "NC_000001.11" +#define REFERENCE_ID "NC_000006.12" +// #define REFERENCE_ID "NC_000001.11" inline void @@ -510,6 +510,28 @@ parse_line(char const line[static LINE_SIZE], } // parse_line +static bool +parse_line2(char const line[static LINE_SIZE], + size_t* id_len, GVA_Variant* variant) +{ + *id_len = strcspn(line, "\t "); + if (*id_len == 0) + { + fprintf(stderr, "here?!\n"); + return false; + } // if + + size_t const spdi_len = strcspn(line + *id_len + 1, "\n"); + if (gva_parse_spdi(spdi_len, line + *id_len + 1, variant) == 0) + { + fprintf(stderr, "or here?!\n"); + return false; + } // if + + return true; +} // parse_line2 +// + int index_main(int argc, char* argv[static argc]) { @@ -574,8 +596,7 @@ index_main(int argc, char* argv[static argc]) line_count += 1; size_t id_len = 0; GVA_Variant variant; - size_t distance = 0; - if (!parse_line(line, &id_len, &variant, &distance)) + if (!parse_line2(line, &id_len, &variant)) { fprintf(stderr, "parsing failed at line %zu: %s\n", line_count, line); continue; From 78192e14c3599b783293925431020df92da6a5d2 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Tue, 17 Feb 2026 09:41:28 +0100 Subject: [PATCH 488/704] Silence. --- src/index.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/index.c b/src/index.c index aa15cce..cec3e47 100644 --- a/src/index.c +++ b/src/index.c @@ -317,7 +317,7 @@ gva_index_query(GVA_Allocator const allocator, i == 0, i == array_length(graph.dom_nodes) - 2, &variant); - fprintf(stderr, " %2zu " GVA_VARIANT_FMT_SPDI " (%u)\n", i, GVA_VARIANT_PRINT_SPDI("NC_000001.11", variant), graph.dom_nodes[i + 1].distance); + // fprintf(stderr, " %2zu " GVA_VARIANT_FMT_SPDI " (%u)\n", i, GVA_VARIANT_PRINT_SPDI("NC_000001.11", variant), graph.dom_nodes[i + 1].distance); gva_uint* intervals = interval_tree_intersection(allocator, self->intervals, variant.start, variant.end); for (size_t j = 0; j < array_length(intervals); ++j) @@ -328,7 +328,7 @@ gva_index_query(GVA_Allocator const allocator, continue; // disjoint } // if - fprintf(stderr, " vs " GVA_VARIANT_FMT_SPDI " (%u)\n", GVA_VARIANT_PRINT_SPDI("NC_000001.11", variant_from_index(self, intervals[j])), self->intervals.nodes[intervals[j]].distance); + // fprintf(stderr, " vs " GVA_VARIANT_FMT_SPDI " (%u)\n", GVA_VARIANT_PRINT_SPDI("NC_000001.11", variant_from_index(self, intervals[j])), self->intervals.nodes[intervals[j]].distance); for (gva_uint k = self->intervals.nodes[intervals[j]].alleles; k != GVA_NULL; k = self->join[k].next) { gva_uint const allele_idx = self->join[k].link ^ intervals[j]; @@ -363,12 +363,12 @@ gva_index_query(GVA_Allocator const allocator, continue; } // if - fprintf(stderr, GVA_STRING_FMT ":\n", GVA_STRING_PRINT(trie_string(self->ids, self->alleles[alleles[idx].gva_key].id_idx))); + // fprintf(stderr, GVA_STRING_FMT ":\n", GVA_STRING_PRINT(trie_string(self->ids, self->alleles[alleles[idx].gva_key].id_idx))); gva_uint prev = GVA_NULL; for (gva_uint i = alleles[idx].head; i != GVA_NULL; i = parts[i].next) { - fprintf(stderr, " %u %u %u %u\n", parts[i].part, parts[i].included, parts[i].start, parts[i].end); + // fprintf(stderr, " %u %u %u %u\n", parts[i].part, parts[i].included, parts[i].start, parts[i].end); GVA_Variant variant = {0, 0, {0, NULL}}; size_t distance = 0; @@ -389,7 +389,7 @@ gva_index_query(GVA_Allocator const allocator, variant.end = current.end; distance += self->intervals.nodes[node_idx].distance; - fprintf(stderr, " %u %u %u %u\n", parts[i].part, parts[i].included, parts[i].start, parts[i].end); + // fprintf(stderr, " %u %u %u %u\n", parts[i].part, parts[i].included, parts[i].start, parts[i].end); } // while if (gva_variant_length(variant) != 0) @@ -409,7 +409,7 @@ gva_index_query(GVA_Allocator const allocator, { parts[prev].next = i; } // else - fprintf(stderr, " DB multi hit: " GVA_VARIANT_FMT_SPDI " (%zu) :: %u\n", GVA_VARIANT_PRINT_SPDI("NC_000001.11", variant), distance, parts[i].included); + // fprintf(stderr, " DB multi hit: " GVA_VARIANT_FMT_SPDI " (%zu) :: %u\n", GVA_VARIANT_PRINT_SPDI("NC_000001.11", variant), distance, parts[i].included); gva_string_destroy(allocator, variant.sequence); } // if else if (parts[i].end - parts[i].start > 1) // FIXME: similar body to if below? @@ -430,7 +430,7 @@ gva_index_query(GVA_Allocator const allocator, variant_from_index(self, node_idx), self->intervals.nodes[node_idx].distance, variant, distance); - fprintf(stderr, " Query multi hit: %u (%zu) :: %u\n", parts[i].end - parts[i].start, distance, parts[i].included); + // fprintf(stderr, " Query multi hit: %u (%zu) :: %u\n", parts[i].end - parts[i].start, distance, parts[i].included); } // if else if (ABS((intmax_t) self->intervals.nodes[self->join[parts[i].part].link ^ alleles[idx].gva_key].distance - graph.dom_nodes[parts[i].start + 1].distance) != parts[i].included) { @@ -440,7 +440,7 @@ gva_index_query(GVA_Allocator const allocator, parts[i].start == 0, parts[i].end == array_length(graph.dom_nodes) - 2, &variant); parts[i].included = variants_common(allocator, self->reference.len, self->reference.str, variant_from_index(self, self->join[parts[i].part].link ^ alleles[idx].gva_key), variant); - fprintf(stderr, " Fully calculate: %u\n", parts[i].included); + // fprintf(stderr, " Fully calculate: %u\n", parts[i].included); } // if else { @@ -469,14 +469,14 @@ gva_index_query(GVA_Allocator const allocator, continue; } // if - fprintf(stderr, GVA_STRING_FMT ": %u\n", - GVA_STRING_PRINT(trie_string(self->ids, self->alleles[alleles[idx].gva_key].id_idx)), - alleles[idx].included); + // fprintf(stderr, GVA_STRING_FMT ": %u\n", + // GVA_STRING_PRINT(trie_string(self->ids, self->alleles[alleles[idx].gva_key].id_idx)), + // alleles[idx].included); - for (gva_uint i = alleles[idx].head; i != GVA_NULL; i = parts[i].next) - { - fprintf(stderr, " parts incl: %u\n", parts[i].included); - } // for + // for (gva_uint i = alleles[idx].head; i != GVA_NULL; i = parts[i].next) + // { + // fprintf(stderr, " parts incl: %u\n", parts[i].included); + // } // for GVA_Relation relation; if (alleles[idx].included == 0) From 9dae47dc1e7cd09e8f9ba7cb41053a104e100cfe Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Thu, 19 Feb 2026 16:18:38 +0100 Subject: [PATCH 489/704] Refactor for future selfs. --- include/index.h | 4 +- src/index.c | 272 ++++++++++++++++++++++++++++++------------------ src/main.c | 10 +- 3 files changed, 181 insertions(+), 105 deletions(-) diff --git a/include/index.h b/include/index.h index 7e7086e..95039f3 100644 --- a/include/index.h +++ b/include/index.h @@ -15,8 +15,10 @@ typedef struct GVA_Index GVA_Index; // opaque typedef struct { - GVA_String allele; + GVA_String allele; // FIXME: allele_idx GVA_Relation relation; + size_t included; + size_t excluded; } GVA_Result; diff --git a/src/index.c b/src/index.c index cec3e47..e865e47 100644 --- a/src/index.c +++ b/src/index.c @@ -118,7 +118,7 @@ variants_distance(GVA_Allocator const allocator, static size_t -variants_common(GVA_Allocator const allocator, +variants_included(GVA_Allocator const allocator, size_t const len_ref, char const reference[static len_ref], GVA_Variant const lhs, GVA_Variant const rhs) { @@ -167,7 +167,7 @@ variants_common(GVA_Allocator const allocator, gva_lcs_graph_uniq_atomics(rhs_graph, start, start_intersection, end_intersection, rhs_dels, rhs_as, rhs_cs, rhs_gs, rhs_ts); gva_lcs_graph_destroy(allocator, rhs_graph); - size_t const common = + size_t const included = bitset_intersection_cnt(lhs_dels, rhs_dels) + bitset_intersection_cnt(lhs_as, rhs_as) + bitset_intersection_cnt(lhs_cs, rhs_cs) + @@ -189,8 +189,8 @@ variants_common(GVA_Allocator const allocator, gva_string_destroy(allocator, observed_rhs); gva_string_destroy(allocator, observed_lhs); - return common > 0 ? 1 : 0; -} // variants_common + return included > 0 ? 1 : 0; +} // variants_included static inline size_t @@ -210,7 +210,7 @@ variants_with_distance(GVA_Allocator const allocator, return distance_rhs; } // if - return variants_common(allocator, len_ref, reference, lhs, rhs); + return variants_included(allocator, len_ref, reference, lhs, rhs); } // variants_with_distance @@ -280,7 +280,8 @@ gva_index_insert(GVA_Index* restrict const self, { array_header(self->intervals.nodes)->length -= 1; } // if - self->intervals.nodes[node_idx].alleles = ARRAY_APPEND(self->allocator, self->join, ((Join) {node_idx ^ allele_idx, self->intervals.nodes[node_idx].alleles})) - 1; + self->intervals.nodes[node_idx].alleles = ARRAY_APPEND(self->allocator, self->join, + ((Join) {node_idx ^ allele_idx, self->intervals.nodes[node_idx].alleles})) - 1; // update allele self->alleles[allele_idx].distance += distance; @@ -292,23 +293,29 @@ GVA_Result* gva_index_query(GVA_Allocator const allocator, GVA_Index* const self, GVA_LCS_Graph const graph) { - struct Result_Allele + struct Allele_Entry { - HASH_TABLE_KEY; + HASH_TABLE_KEY; // index into self->alleles gva_uint included; - gva_uint head; + gva_uint head; // singly linked list in hits gva_uint tail; - }* alleles = hash_table_init(allocator, 1024, sizeof(*alleles)); + }* entries = hash_table_init(allocator, 1024, sizeof(*entries)); - struct Result_Part + struct Hit { - gva_uint part; - gva_uint included; - gva_uint start; + gva_uint idx; // index into self->join + gva_uint included; // double purpose: distance or included + gva_uint start; // wrt local supremal parts in the query gva_uint end; gva_uint next; - }* parts = NULL; - + }* hits = NULL; + + // + // Phase 1: for every local supremal part: + // - find candidates based on interval query + // - calculate the distance with the candidates, + // and quickly eject disjoint candidates based on distance + // for (size_t i = 0; i < array_length(graph.dom_nodes) - 1; ++i) { GVA_Variant variant; @@ -322,176 +329,243 @@ gva_index_query(GVA_Allocator const allocator, gva_uint* intervals = interval_tree_intersection(allocator, self->intervals, variant.start, variant.end); for (size_t j = 0; j < array_length(intervals); ++j) { - size_t const distance = variants_distance(allocator, self->reference.len, self->reference.str, variant_from_index(self, intervals[j]), variant); - if (distance >= self->intervals.nodes[intervals[j]].distance + graph.dom_nodes[i + 1].distance) + gva_uint const node_idx = intervals[j]; + size_t const distance = variants_distance(allocator, self->reference.len, self->reference.str, + variant_from_index(self, node_idx), variant); + if (distance >= self->intervals.nodes[node_idx].distance + graph.dom_nodes[i + 1].distance) { - continue; // disjoint + // Disjoint based on distance + continue; } // if - // fprintf(stderr, " vs " GVA_VARIANT_FMT_SPDI " (%u)\n", GVA_VARIANT_PRINT_SPDI("NC_000001.11", variant_from_index(self, intervals[j])), self->intervals.nodes[intervals[j]].distance); - for (gva_uint k = self->intervals.nodes[intervals[j]].alleles; k != GVA_NULL; k = self->join[k].next) + // fprintf(stderr, " vs " GVA_VARIANT_FMT_SPDI " (%u)\n", GVA_VARIANT_PRINT_SPDI("NC_000001.11", variant_from_index(self, node_idx)), self->intervals.nodes[node_idx].distance); + + for (gva_uint k = self->intervals.nodes[node_idx].alleles; k != GVA_NULL; k = self->join[k].next) { - gva_uint const allele_idx = self->join[k].link ^ intervals[j]; + gva_uint const allele_idx = self->join[k].link ^ node_idx; - size_t const idx = HASH_TABLE_INDEX(alleles, allele_idx); - if (alleles[idx].gva_key != allele_idx) + size_t const idx = HASH_TABLE_INDEX(entries, allele_idx); + if (entries[idx].gva_key != allele_idx) { - gva_uint const tail = ARRAY_APPEND(allocator, parts, ((struct Result_Part) {k, distance, i, i + 1, GVA_NULL})) - 1; - HASH_TABLE_SET(allocator, alleles, allele_idx, ((struct Result_Allele) {allele_idx, 0, tail, tail})); + // The first time a part is associated with this allele_idx + // we point it to the freshly created result part entry + gva_uint const tail = ARRAY_APPEND(allocator, hits, + ((struct Hit) + { + .idx = k, + .included = distance, + .start = i, + .end = i + 1, + .next = GVA_NULL + }) + ) - 1; + HASH_TABLE_SET(allocator, entries, allele_idx, + ((struct Allele_Entry) + { + .gva_key = allele_idx, + .included = 0, + .head = tail, + .tail = tail + }) + ); continue; } // if - if (parts[alleles[idx].tail].part != k || parts[alleles[idx].tail].start == i) + // is there a new hit for this allele? + if (hits[entries[idx].tail].idx != k) { - gva_uint const tail = ARRAY_APPEND(allocator, parts, ((struct Result_Part) {k, distance, i, i + 1, GVA_NULL})) - 1; - parts[alleles[idx].tail].next = tail; - alleles[idx].tail = tail; + gva_uint const tail = ARRAY_APPEND(allocator, hits, + ((struct Hit) + { + .idx = k, + .included = distance, + .start = i, + .end = i + 1, + .next = GVA_NULL + }) + ) - 1; + // add to end of list + hits[entries[idx].tail].next = tail; + entries[idx].tail = tail; } // if + // otherwise the same hit for this query part else { - parts[alleles[idx].tail].end = i + 1; + hits[entries[idx].tail].end = i + 1; } // else } // for } // for intervals = ARRAY_DESTROY(allocator, intervals); } // for - for (size_t idx = 0; idx < array_header(alleles)->capacity; ++idx) + + // + // Phase 2: + // + for (size_t idx = 0; idx < array_header(entries)->capacity; ++idx) { - if (alleles[idx].gva_key == NOT_FOUND) + if (entries[idx].gva_key == NOT_FOUND) { continue; } // if - // fprintf(stderr, GVA_STRING_FMT ":\n", GVA_STRING_PRINT(trie_string(self->ids, self->alleles[alleles[idx].gva_key].id_idx))); + // fprintf(stderr, GVA_STRING_FMT ":\n", GVA_STRING_PRINT(trie_string(self->ids, self->alleles[entries[idx].gva_key].id_idx))); gva_uint prev = GVA_NULL; - for (gva_uint i = alleles[idx].head; i != GVA_NULL; i = parts[i].next) + for (gva_uint i = entries[idx].head; i != GVA_NULL; i = hits[i].next) { - // fprintf(stderr, " %u %u %u %u\n", parts[i].part, parts[i].included, parts[i].start, parts[i].end); + // fprintf(stderr, " %u %u %u %u\n", hits[i].idx, hits[i].included, hits[i].start, hits[i].end); - GVA_Variant variant = {0, 0, {0, NULL}}; + GVA_Variant lhs = {0, 0, {0, NULL}}; size_t distance = 0; - while (parts[i].next != GVA_NULL && parts[parts[i].next].start == parts[i].start) + // look ahead for the same local supremal part in the query + while (hits[i].next != GVA_NULL && hits[hits[i].next].start == hits[i].start) { - if (gva_variant_length(variant) == 0) + if (gva_variant_length(lhs) == 0) { - gva_uint const node_idx = self->join[parts[i].part].link ^ alleles[idx].gva_key; - variant = gva_variant_dup(allocator, variant_from_index(self, node_idx)); + gva_uint const node_idx = self->join[hits[i].idx].link ^ entries[idx].gva_key; + lhs = gva_variant_dup(allocator, variant_from_index(self, node_idx)); distance = self->intervals.nodes[node_idx].distance; } // if - i = parts[i].next; - gva_uint const node_idx = self->join[parts[i].part].link ^ alleles[idx].gva_key; - GVA_Variant const current = variant_from_index(self, node_idx); - variant.sequence = gva_string_concat(allocator, variant.sequence, - (GVA_String) {current.start - variant.end, self->reference.str + variant.end}); - variant.sequence = gva_string_concat(allocator, variant.sequence, current.sequence); - variant.end = current.end; + i = hits[i].next; + gva_uint const node_idx = self->join[hits[i].idx].link ^ entries[idx].gva_key; + GVA_Variant const variant = variant_from_index(self, node_idx); + lhs.sequence = gva_string_concat(allocator, lhs.sequence, + (GVA_String) {variant.start - lhs.end, self->reference.str + lhs.end}); + lhs.sequence = gva_string_concat(allocator, lhs.sequence, variant.sequence); + lhs.end = variant.end; distance += self->intervals.nodes[node_idx].distance; - // fprintf(stderr, " %u %u %u %u\n", parts[i].part, parts[i].included, parts[i].start, parts[i].end); + // fprintf(stderr, " %u %u %u %u\n", hits[i].idx, hits[i].included, hits[i].start, hits[i].end); } // while - if (gva_variant_length(variant) != 0) + gva_uint const node_idx = self->join[hits[i].idx].link ^ entries[idx].gva_key; + + // single query part has multiple hits + if (gva_variant_length(lhs) != 0) { GVA_Variant rhs; + // TODO: break out into gva_lcs_graph_local_supremal_part() function? gva_edges(graph.observed.str, - graph.dom_nodes[parts[i].start], graph.dom_nodes[parts[i].end], - parts[i].start == 0, parts[i].end == array_length(graph.dom_nodes) - 2, + graph.dom_nodes[hits[i].start], graph.dom_nodes[hits[i].end], + hits[i].start == 0, hits[i].end == array_length(graph.dom_nodes) - 2, &rhs); - parts[i].included = variants_with_distance(allocator, self->reference.len, self->reference.str, - variant, distance, rhs, graph.dom_nodes[parts[i].start + 1].distance); - if (prev == GVA_NULL) + + // aggregate hits in last hit + hits[i].included = variants_with_distance(allocator, self->reference.len, self->reference.str, + lhs, distance, rhs, graph.dom_nodes[hits[i].start + 1].distance); + + // disable aggregated hits except the last + if (prev != GVA_NULL) { - alleles[idx].head = i; + hits[prev].next = i; } // if else { - parts[prev].next = i; + entries[idx].head = i; } // else - // fprintf(stderr, " DB multi hit: " GVA_VARIANT_FMT_SPDI " (%zu) :: %u\n", GVA_VARIANT_PRINT_SPDI("NC_000001.11", variant), distance, parts[i].included); - gva_string_destroy(allocator, variant.sequence); + + // fprintf(stderr, " DB multi hit: " GVA_VARIANT_FMT_SPDI " (%zu) :: %u\n", GVA_VARIANT_PRINT_SPDI("NC_000001.11", lhs), distance, hits[i].included); + gva_string_destroy(allocator, lhs.sequence); } // if - else if (parts[i].end - parts[i].start > 1) // FIXME: similar body to if below? + // single hit with multiple query parts + else if (hits[i].end - hits[i].start > 1) // FIXME: similar body to if below? { // FIXME: use cumulative distances in dom_nodes - size_t distance = 0; // graph.dom_nodes[parts[i].end].distance - graph.dom_nodes[parts[i].start].distance - for (gva_uint j = parts[i].start; j < parts[i].end; ++j) + size_t distance = 0; // graph.dom_nodes[hits[i].end].distance - graph.dom_nodes[hits[i].start].distance + for (gva_uint j = hits[i].start; j < hits[i].end; ++j) { distance += graph.dom_nodes[j + 1].distance; } // for - GVA_Variant variant; + GVA_Variant rhs; gva_edges(graph.observed.str, - graph.dom_nodes[parts[i].start], graph.dom_nodes[parts[i].end], - parts[i].start == 0, parts[i].end == array_length(graph.dom_nodes) - 2, - &variant); - gva_uint const node_idx = self->join[parts[i].part].link ^ alleles[idx].gva_key; - parts[i].included = variants_with_distance(allocator, self->reference.len, self->reference.str, + graph.dom_nodes[hits[i].start], graph.dom_nodes[hits[i].end], + hits[i].start == 0, hits[i].end == array_length(graph.dom_nodes) - 2, + &rhs); + hits[i].included = variants_with_distance(allocator, self->reference.len, self->reference.str, variant_from_index(self, node_idx), self->intervals.nodes[node_idx].distance, - variant, distance); + rhs, distance); - // fprintf(stderr, " Query multi hit: %u (%zu) :: %u\n", parts[i].end - parts[i].start, distance, parts[i].included); + // fprintf(stderr, " Query multi hit: %u (%zu) :: %u\n", hits[i].end - hits[i].start, distance, hits[i].included); } // if - else if (ABS((intmax_t) self->intervals.nodes[self->join[parts[i].part].link ^ alleles[idx].gva_key].distance - graph.dom_nodes[parts[i].start + 1].distance) != parts[i].included) + // single hit for single query part, relation is not determined by the distances + else if (ABS((intmax_t) self->intervals.nodes[node_idx].distance - graph.dom_nodes[hits[i].start + 1].distance) != hits[i].included) { - GVA_Variant variant; + GVA_Variant rhs; gva_edges(graph.observed.str, - graph.dom_nodes[parts[i].start], graph.dom_nodes[parts[i].end], - parts[i].start == 0, parts[i].end == array_length(graph.dom_nodes) - 2, - &variant); - parts[i].included = variants_common(allocator, self->reference.len, self->reference.str, variant_from_index(self, self->join[parts[i].part].link ^ alleles[idx].gva_key), variant); - // fprintf(stderr, " Fully calculate: %u\n", parts[i].included); + graph.dom_nodes[hits[i].start], graph.dom_nodes[hits[i].end], + hits[i].start == 0, hits[i].end == array_length(graph.dom_nodes) - 2, + &rhs); + hits[i].included = variants_included(allocator, self->reference.len, self->reference.str, + variant_from_index(self, node_idx), rhs); + // fprintf(stderr, " Fully calculate: %u\n", hits[i].included); } // if + // single hit for single query part, relation is already determined else { - gva_uint const node_idx = self->join[parts[i].part].link ^ alleles[idx].gva_key; - if (parts[i].included == 0 || graph.dom_nodes[parts[i].start + 1].distance - self->intervals.nodes[node_idx].distance == parts[i].included) + // equivalent or contains + if (self->intervals.nodes[node_idx].distance - graph.dom_nodes[hits[i].start + 1].distance == hits[i].included) { - parts[i].included = self->intervals.nodes[node_idx].distance; + hits[i].included = graph.dom_nodes[hits[i].start + 1].distance; } // if - else if (self->intervals.nodes[node_idx].distance - graph.dom_nodes[parts[i].start + 1].distance == parts[i].included) + // is_contained + else if (graph.dom_nodes[hits[i].start + 1].distance - self->intervals.nodes[node_idx].distance == hits[i].included) { - parts[i].included = graph.dom_nodes[parts[i].start + 1].distance; + hits[i].included = self->intervals.nodes[node_idx].distance; } // if } // else - alleles[idx].included += parts[i].included; + entries[idx].included += hits[i].included; prev = i; } // for // TODO: exclude included == 0? + if (entries[idx].included == 0) + { + entries[idx].gva_key = NOT_FOUND; + } // if } // for + + // + // Phase 3: + // + GVA_Result* results = NULL; - for (size_t idx = 0; idx < array_header(alleles)->capacity; ++idx) + for (size_t idx = 0; idx < array_header(entries)->capacity; ++idx) { - if (alleles[idx].gva_key == NOT_FOUND) + if (entries[idx].gva_key == NOT_FOUND) { continue; } // if + // fprintf(stderr, GVA_STRING_FMT ": %u\n", - // GVA_STRING_PRINT(trie_string(self->ids, self->alleles[alleles[idx].gva_key].id_idx)), - // alleles[idx].included); + // GVA_STRING_PRINT(trie_string(self->ids, self->alleles[entries[idx].gva_key].id_idx)), + // entries[idx].included); - // for (gva_uint i = alleles[idx].head; i != GVA_NULL; i = parts[i].next) + // for (gva_uint i = entries[idx].head; i != GVA_NULL; i = hits[i].next) // { - // fprintf(stderr, " parts incl: %u\n", parts[i].included); + // GVA_Variant variant; + // gva_edges(graph.observed.str, + // graph.dom_nodes[hits[i].start], graph.dom_nodes[hits[i].end], + // hits[i].start == 0, hits[i].end == array_length(graph.dom_nodes) - 2, + // &variant); + // + // gva_uint const node_idx = self->join[hits[i].idx].link ^ entries[idx].gva_key; + // fprintf(stderr, " " GVA_VARIANT_FMT_SPDI " " GVA_VARIANT_FMT_SPDI " %u\n", GVA_VARIANT_PRINT_SPDI("NC_000006.12", variant_from_index(self, node_idx)), GVA_VARIANT_PRINT_SPDI("NC_000006.12", variant), hits[i].included); // } // for GVA_Relation relation; - if (alleles[idx].included == 0) - { - relation = GVA_DISJOINT; - } // if - else if (self->alleles[alleles[idx].gva_key].distance + graph.distance - 2 * alleles[idx].included == 0) + size_t const excluded = self->alleles[entries[idx].gva_key].distance + graph.distance - 2 * entries[idx].included; + if (excluded == 0) { relation = GVA_EQUIVALENT; } // if - else if (alleles[idx].included == graph.distance) + else if (entries[idx].included == graph.distance) { relation = GVA_CONTAINS; } // else if - else if (alleles[idx].included == self->alleles[alleles[idx].gva_key].distance) + else if (entries[idx].included == self->alleles[entries[idx].gva_key].distance) { relation = GVA_IS_CONTAINED; } // else if @@ -501,13 +575,13 @@ gva_index_query(GVA_Allocator const allocator, } // else ARRAY_APPEND(self->allocator, results, - ((GVA_Result) {trie_string(self->ids, self->alleles[alleles[idx].gva_key].id_idx), relation}) + ((GVA_Result) {trie_string(self->ids, self->alleles[entries[idx].gva_key].id_idx), relation, entries[idx].included, excluded}) ); } // for - parts = ARRAY_DESTROY(allocator, parts); - alleles = HASH_TABLE_DESTROY(allocator, alleles); + hits = ARRAY_DESTROY(allocator, hits); + entries = HASH_TABLE_DESTROY(allocator, entries); return results; } // gva_index_query diff --git a/src/main.c b/src/main.c index 62ac53b..061ae74 100644 --- a/src/main.c +++ b/src/main.c @@ -31,8 +31,8 @@ #define LINE_SIZE 8194 -#define REFERENCE_ID "NC_000006.12" -// #define REFERENCE_ID "NC_000001.11" +// #define REFERENCE_ID "NC_000006.12" +#define REFERENCE_ID "NC_000001.11" inline void @@ -604,14 +604,14 @@ index_main(int argc, char* argv[static argc]) GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &variant); - // fprintf(stdout, "\nQuery (" GVA_STRING_FMT "): " GVA_VARIANT_FMT_SPDI " (%u)\n", GVA_STRING_PRINT(((GVA_String) {id_len, line})), GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, graph.supremal), graph.distance); + // fprintf(stderr, "\nQuery (" GVA_STRING_FMT "): " GVA_VARIANT_FMT_SPDI " (%u)\n", GVA_STRING_PRINT(((GVA_String) {id_len, line})), GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, graph.supremal), graph.distance); GVA_Result* results = gva_index_query(gva_std_allocator, index, graph); for (size_t i = 0; i < array_length(results); ++i) { - fprintf(stdout, GVA_STRING_FMT " %s %.*s\n", + fprintf(stdout, GVA_STRING_FMT " %s %.*s %zu %zu\n", GVA_STRING_PRINT(results[i].allele), GVA_RELATION_LABELS[results[i].relation], - (int)id_len, line); + (int)id_len, line, results[i].included, results[i].excluded); } gva_string_destroy(gva_std_allocator, graph.observed); From fc8262521593febc5b3bb8629d2b742de1308e0f Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Thu, 19 Feb 2026 16:47:53 +0100 Subject: [PATCH 490/704] Comments. --- src/index.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/src/index.c b/src/index.c index e865e47..9b93d43 100644 --- a/src/index.c +++ b/src/index.c @@ -393,14 +393,13 @@ gva_index_query(GVA_Allocator const allocator, { hits[entries[idx].tail].end = i + 1; } // else - } // for - } // for + } // for alleles + } // for intervals intervals = ARRAY_DESTROY(allocator, intervals); - } // for - + } // for dom_nodes // - // Phase 2: + // Phase 2: combine 1:N and N:1 hits into single hits // for (size_t idx = 0; idx < array_header(entries)->capacity; ++idx) { @@ -516,21 +515,19 @@ gva_index_query(GVA_Allocator const allocator, } // else entries[idx].included += hits[i].included; prev = i; - } // for - // TODO: exclude included == 0? + } // for hits + + // Disable disjoint entries if (entries[idx].included == 0) { entries[idx].gva_key = NOT_FOUND; } // if - } // for - + } // for entries // - // Phase 3: + // Phase 3: determine relation per allele based on included // - GVA_Result* results = NULL; - for (size_t idx = 0; idx < array_header(entries)->capacity; ++idx) { if (entries[idx].gva_key == NOT_FOUND) @@ -579,7 +576,6 @@ gva_index_query(GVA_Allocator const allocator, ); } // for - hits = ARRAY_DESTROY(allocator, hits); entries = HASH_TABLE_DESTROY(allocator, entries); From 0630ce0e5af9933666253aef30078e790f1de0dd Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 19 Feb 2026 21:40:16 +0100 Subject: [PATCH 491/704] ARRAY_APPENDS returns the index of the appended value --- src/array.c | 2 +- src/array.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/array.c b/src/array.c index a8f032c..89a2917 100644 --- a/src/array.c +++ b/src/array.c @@ -79,4 +79,4 @@ array_ensure(GVA_Allocator const allocator, void* const self, new_header->capacity = new_capacity; return new_header + 1; -} // array_ensure_one +} // array_ensure diff --git a/src/array.h b/src/array.h index e34675c..29be138 100644 --- a/src/array.h +++ b/src/array.h @@ -65,13 +65,13 @@ array_ensure(GVA_Allocator const allocator, void* const self, // Adds an element at the end of the array. Returns the new length of the -// array. 0 if (re)allocation failed. +// array. -1 if (re)allocation failed. // Warning: `self` is evaluated multiple times. #define ARRAY_APPEND(allocator, self, value) ( \ (self) = array_ensure((allocator), (self), sizeof(*(self)), 1), \ - (self) == NULL ? 0 : ( \ + (self) == NULL ? (size_t) -1 : ( \ (self)[array_header(self)->length] = (value), \ - array_header(self)->length += 1 \ + array_header(self)->length++ \ ) \ ) From 76b06a6644089cf1de8ed88ed2246d347aaaa755 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 19 Feb 2026 21:49:19 +0100 Subject: [PATCH 492/704] Catch up with the ARRAY_APPEND interface --- src/align.c | 24 ++++++++++++---- src/index.c | 35 +++++++++++------------ src/lcs_graph.c | 75 ++++++++++++++++++++++--------------------------- src/trie.c | 10 +++---- 4 files changed, 73 insertions(+), 71 deletions(-) diff --git a/src/align.c b/src/align.c index 1aeef7e..95b4d34 100644 --- a/src/align.c +++ b/src/align.c @@ -75,9 +75,15 @@ expand(Context const context, intmax_t const d_col = context.len_obs - col; size_t const lcs_pos = (row + col - ABS(delta) - 2 * p + ABS(d_row - d_col)) / 2 - 1; size_t const length = row - match_row; - gva_uint const idx = ARRAY_APPEND(context.allocator, lcs->nodes, ((LCS_Node) { - match_row + context.shift, match_col, length, 0, false, GVA_NULL, GVA_NULL - })) - 1; + gva_uint const idx = ARRAY_APPEND(context.allocator, lcs->nodes, + ((LCS_Node) + { + .row = match_row + context.shift, + .col = match_col, + .length = length, + .idx = GVA_NULL, + .next = GVA_NULL + })); if (lcs->index[lcs_pos].head != GVA_NULL) { lcs->nodes[lcs->index[lcs_pos].tail].next = idx; @@ -116,9 +122,15 @@ expand(Context const context, intmax_t const d_col = context.len_obs - col; size_t const lcs_pos = (row + col - ABS(delta) - 2 * p + ABS(d_row - d_col)) / 2 - 1; size_t const length = row - match_row; - gva_uint const idx = ARRAY_APPEND(context.allocator, lcs->nodes, ((LCS_Node) { - match_row + context.shift, match_col, length, 0, false, GVA_NULL, GVA_NULL - })) - 1; + gva_uint const idx = ARRAY_APPEND(context.allocator, lcs->nodes, + ((LCS_Node) + { + .row = match_row + context.shift, + .col = match_col, + .length = length, + .idx = GVA_NULL, + .next = GVA_NULL + })); if (lcs->index[lcs_pos].head != GVA_NULL) { lcs->nodes[lcs->index[lcs_pos].tail].next = idx; diff --git a/src/index.c b/src/index.c index 9b93d43..9407bf2 100644 --- a/src/index.c +++ b/src/index.c @@ -266,14 +266,14 @@ gva_index_insert(GVA_Index* restrict const self, // new allele if (array_length(self->alleles) == 0 || id_idx != self->alleles[allele_idx].id_idx) { - allele_idx = ARRAY_APPEND(self->allocator, self->alleles, ((Allele) {id_idx, 0, array_length(self->join), 0})) - 1; + allele_idx = ARRAY_APPEND(self->allocator, self->alleles, ((Allele) {id_idx, 0, array_length(self->join), 0})); } // if // add variant gva_uint const inserted_idx = trie_insert(self->allocator, &self->inserted, variant.sequence.len, variant.sequence.str); gva_uint const tmp_idx = ARRAY_APPEND(self->allocator, self->intervals.nodes, ((Interval_Tree_Node) {{GVA_NULL, GVA_NULL}, - variant.start, variant.end, variant.end, 0, inserted_idx, GVA_NULL, distance})) - 1; + variant.start, variant.end, variant.end, 0, inserted_idx, GVA_NULL, distance})); gva_uint const node_idx = interval_tree_insert(&self->intervals, tmp_idx); // undo append: interval already in the tree if (node_idx != tmp_idx) @@ -281,7 +281,7 @@ gva_index_insert(GVA_Index* restrict const self, array_header(self->intervals.nodes)->length -= 1; } // if self->intervals.nodes[node_idx].alleles = ARRAY_APPEND(self->allocator, self->join, - ((Join) {node_idx ^ allele_idx, self->intervals.nodes[node_idx].alleles})) - 1; + ((Join) {node_idx ^ allele_idx, self->intervals.nodes[node_idx].alleles})); // update allele self->alleles[allele_idx].distance += distance; @@ -357,17 +357,14 @@ gva_index_query(GVA_Allocator const allocator, .start = i, .end = i + 1, .next = GVA_NULL - }) - ) - 1; + })); HASH_TABLE_SET(allocator, entries, allele_idx, ((struct Allele_Entry) { .gva_key = allele_idx, - .included = 0, .head = tail, .tail = tail - }) - ); + })); continue; } // if @@ -382,8 +379,7 @@ gva_index_query(GVA_Allocator const allocator, .start = i, .end = i + 1, .next = GVA_NULL - }) - ) - 1; + })); // add to end of list hits[entries[idx].tail].next = tail; entries[idx].tail = tail; @@ -393,13 +389,13 @@ gva_index_query(GVA_Allocator const allocator, { hits[entries[idx].tail].end = i + 1; } // else - } // for alleles - } // for intervals + } // for + } // for intervals = ARRAY_DESTROY(allocator, intervals); - } // for dom_nodes + } // for // - // Phase 2: combine 1:N and N:1 hits into single hits + // Phase 2: // for (size_t idx = 0; idx < array_header(entries)->capacity; ++idx) { @@ -515,19 +511,20 @@ gva_index_query(GVA_Allocator const allocator, } // else entries[idx].included += hits[i].included; prev = i; - } // for hits - - // Disable disjoint entries + } // for + // TODO: exclude included == 0? if (entries[idx].included == 0) { entries[idx].gva_key = NOT_FOUND; } // if - } // for entries + } // for // - // Phase 3: determine relation per allele based on included + // Phase 3: // + GVA_Result* results = NULL; + for (size_t idx = 0; idx < array_header(entries)->capacity; ++idx) { if (entries[idx].gva_key == NOT_FOUND) diff --git a/src/lcs_graph.c b/src/lcs_graph.c index 335ed45..07dc941 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -40,11 +40,9 @@ gva_lcs_graph_init(GVA_Allocator const allocator, { .row = len_ref + shift, .col = len_obs, - .length = 0, .edges = GVA_NULL, .lambda = GVA_NULL - }) - ) - 1; + })); if (graph.distance == 0) { @@ -62,19 +60,14 @@ gva_lcs_graph_init(GVA_Allocator const allocator, ((GVA_Node) { .row = shift, - .col = 0, - .length = 0, - .edges = ARRAY_APPEND(allocator, graph.edges, ((GVA_Edge) {sink, GVA_NULL})) - 1, + .edges = ARRAY_APPEND(allocator, graph.edges, ((GVA_Edge) {sink, GVA_NULL})), .lambda = GVA_NULL - })) - 1; + })); ARRAY_APPEND(allocator, graph.dom_nodes, ((GVA_Node) { .row = shift, - .col = 0, - .length = 0, - .distance = 0, .link = graph.source })); ARRAY_APPEND(allocator, graph.dom_nodes, @@ -82,7 +75,6 @@ gva_lcs_graph_init(GVA_Allocator const allocator, { .row = len_ref + shift, .col = len_obs, - .length = 0, .distance = graph.distance, .link = sink })); @@ -102,7 +94,7 @@ gva_lcs_graph_init(GVA_Allocator const allocator, .length = sink.length, .edges = GVA_NULL, .lambda = GVA_NULL - })) - 1; + })); lcs.nodes[tail_idx].moved = true; sink = lcs.nodes[tail_idx]; } // if @@ -117,7 +109,7 @@ gva_lcs_graph_init(GVA_Allocator const allocator, .length = sink.length, .edges = GVA_NULL, .lambda = GVA_NULL - })) - 1; + })); tail_idx = GVA_NULL; } // else for (gva_uint i = lcs.index[lcs.length - 1].head; i != tail_idx; i = lcs.nodes[i].next) @@ -128,9 +120,9 @@ gva_lcs_graph_init(GVA_Allocator const allocator, .row = lcs.nodes[i].row, .col = lcs.nodes[i].col, .length = lcs.nodes[i].length, - .edges = ARRAY_APPEND(allocator, graph.edges, ((GVA_Edge) {sink.idx, GVA_NULL})) - 1, + .edges = ARRAY_APPEND(allocator, graph.edges, ((GVA_Edge) {sink.idx, GVA_NULL})), .lambda = GVA_NULL - })) - 1; + })); } // for for (gva_uint i = lcs.length - 1; i >= 1; --i) @@ -171,9 +163,9 @@ gva_lcs_graph_init(GVA_Allocator const allocator, .row = head->row, .col = head->col, .length = head->length, - .edges = ARRAY_APPEND(allocator, graph.edges, ((GVA_Edge) {tail->idx, GVA_NULL})) - 1, + .edges = ARRAY_APPEND(allocator, graph.edges, ((GVA_Edge) {tail->idx, GVA_NULL})), .lambda = split_idx - })) - 1; + })); head->moved = false; head->incoming = 0; @@ -189,15 +181,18 @@ gva_lcs_graph_init(GVA_Allocator const allocator, .row = head->row, .col = head->col, .length = head->length, - .edges = ARRAY_APPEND(allocator, graph.edges, ((GVA_Edge) {tail->idx, GVA_NULL})) - 1, + .edges = ARRAY_APPEND(allocator, graph.edges, ((GVA_Edge) {tail->idx, GVA_NULL})), .lambda = GVA_NULL - })) - 1; + })); } // if else if (!head->moved || !tail->moved) { - graph.nodes[head->idx].edges = ARRAY_APPEND(allocator, graph.edges, ((GVA_Edge) { - tail->idx, graph.nodes[head->idx].edges - })) - 1; + graph.nodes[head->idx].edges = ARRAY_APPEND(allocator, graph.edges, + ((GVA_Edge) + { + tail->idx, + graph.nodes[head->idx].edges + })); } // if } // for @@ -241,7 +236,7 @@ gva_lcs_graph_init(GVA_Allocator const allocator, .length = source.length, .edges = GVA_NULL, .lambda = GVA_NULL - })) - 1; + })); } // else for (gva_uint i = head_idx; i != GVA_NULL; i = lcs.nodes[i].next) { @@ -256,9 +251,12 @@ gva_lcs_graph_init(GVA_Allocator const allocator, if (source.length == 0 || !lcs.nodes[i].moved) { - graph.nodes[source.idx].edges = ARRAY_APPEND(allocator, graph.edges, ((GVA_Edge) { - lcs.nodes[i].idx, graph.nodes[source.idx].edges - })) - 1; + graph.nodes[source.idx].edges = ARRAY_APPEND(allocator, graph.edges, + ((GVA_Edge) + { + lcs.nodes[i].idx, + graph.nodes[source.idx].edges + })); } // if } // for @@ -267,9 +265,6 @@ gva_lcs_graph_init(GVA_Allocator const allocator, ((GVA_Node) { .row = shift, - .col = 0, - .length = 0, - .distance = 0, .link = source.idx })); gva_uint distance = 0; @@ -287,17 +282,16 @@ gva_lcs_graph_init(GVA_Allocator const allocator, if (lcs.index[i].tail != prev) { gva_uint const offset = graph.nodes[lcs.nodes[lcs.index[i].tail].idx].length - lcs.index[i].offset - 1; - ARRAY_APPEND(allocator, graph.dom_nodes, - ((GVA_Node) - { - .row = lcs.nodes[lcs.index[i].tail].row + offset, - .col = lcs.nodes[lcs.index[i].tail].col + offset, - .length = 0, - .distance = lcs.nodes[lcs.index[i].tail].row + offset - shift + - lcs.nodes[lcs.index[i].tail].col + offset - - 2 * i - distance, - .link = lcs.nodes[lcs.index[i].tail].idx - })); + ARRAY_APPEND(allocator, graph.dom_nodes, + ((GVA_Node) + { + .row = lcs.nodes[lcs.index[i].tail].row + offset, + .col = lcs.nodes[lcs.index[i].tail].col + offset, + .distance = lcs.nodes[lcs.index[i].tail].row + offset - shift + + lcs.nodes[lcs.index[i].tail].col + offset - + 2 * i - distance, + .link = lcs.nodes[lcs.index[i].tail].idx + })); prev = lcs.index[i].tail; distance += graph.dom_nodes[array_length(graph.dom_nodes) - 1].distance; @@ -315,7 +309,6 @@ gva_lcs_graph_init(GVA_Allocator const allocator, { .row = sink.row + sink.length, .col = sink.col + sink.length, - .length = 0, .distance = graph.distance - distance, .link = sink.idx, })); diff --git a/src/trie.c b/src/trie.c index cd10acf..f3a1abf 100644 --- a/src/trie.c +++ b/src/trie.c @@ -47,7 +47,7 @@ trie_insert(GVA_Allocator const allocator, Trie self[static restrict 1], { gva_uint const start = 0; self->strings = gva_string_concat(allocator, self->strings, (GVA_String) {len, key}); - self->root = ARRAY_APPEND(allocator, self->nodes, ((TrieNode) {GVA_NULL, GVA_NULL, start, start, len})) - 1; + self->root = ARRAY_APPEND(allocator, self->nodes, ((TrieNode) {GVA_NULL, GVA_NULL, start, start, len})); return self->root; } // if @@ -70,7 +70,7 @@ trie_insert(GVA_Allocator const allocator, Trie self[static restrict 1], gva_uint const start = self->strings.len; self->strings = gva_string_concat(allocator, self->strings, (GVA_String) {len, key}); gva_uint const end = self->strings.len; - gva_uint const next = ARRAY_APPEND(allocator, self->nodes, ((TrieNode) {GVA_NULL, GVA_NULL, start + prefix, start, end})) - 1; + gva_uint const next = ARRAY_APPEND(allocator, self->nodes, ((TrieNode) {GVA_NULL, GVA_NULL, start + prefix, start, end})); self->nodes[idx].next = next; return next; } // if @@ -85,7 +85,7 @@ trie_insert(GVA_Allocator const allocator, Trie self[static restrict 1], gva_uint const start = self->strings.len; self->strings = gva_string_concat(allocator, self->strings, (GVA_String) {len, key}); gva_uint const end = self->strings.len; - gva_uint const link = ARRAY_APPEND(allocator, self->nodes, ((TrieNode) {GVA_NULL, GVA_NULL, start + prefix, start, end})) - 1; + gva_uint const link = ARRAY_APPEND(allocator, self->nodes, ((TrieNode) {GVA_NULL, GVA_NULL, start + prefix, start, end})); self->nodes[idx].link = link; return link; } // if @@ -101,9 +101,9 @@ trie_insert(GVA_Allocator const allocator, Trie self[static restrict 1], gva_uint const start = self->strings.len; self->strings = gva_string_concat(allocator, self->strings, (GVA_String) {len, key}); gva_uint const end = self->strings.len; - next = ARRAY_APPEND(allocator, self->nodes, ((TrieNode) {GVA_NULL, GVA_NULL, start + prefix, start, end})) - 1; + next = ARRAY_APPEND(allocator, self->nodes, ((TrieNode) {GVA_NULL, GVA_NULL, start + prefix, start, end})); } // if - gva_uint const link = ARRAY_APPEND(allocator, self->nodes, ((TrieNode) {idx, self->nodes[idx].next, self->nodes[idx].p_start, self->nodes[idx].start, self->nodes[idx].p_start + k})) - 1; + gva_uint const link = ARRAY_APPEND(allocator, self->nodes, ((TrieNode) {idx, self->nodes[idx].next, self->nodes[idx].p_start, self->nodes[idx].start, self->nodes[idx].p_start + k})); self->nodes[idx].next = next; self->nodes[idx].p_start += k; if (prev != GVA_NULL) From 3906889dc1725074fbc9b324a962dc767cd0e57c Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 19 Feb 2026 22:04:57 +0100 Subject: [PATCH 493/704] Added local supremal slice to LCS graph --- include/lcs_graph.h | 5 +++++ src/index.c | 34 +++++++--------------------------- src/lcs_graph.c | 20 ++++++++++++++++++-- 3 files changed, 30 insertions(+), 29 deletions(-) diff --git a/include/lcs_graph.h b/include/lcs_graph.h index 72dad59..88dd57e 100644 --- a/include/lcs_graph.h +++ b/include/lcs_graph.h @@ -90,6 +90,11 @@ gva_lcs_graph_uniq_atomics(GVA_LCS_Graph const self, size_t ts[static restrict 1]); +GVA_Variant +gva_lcs_graph_ls_slice(GVA_LCS_Graph const self, + size_t const start, size_t const end); + + gva_uint gva_edges(char const observed[static restrict 1], GVA_Node const head, GVA_Node const tail, diff --git a/src/index.c b/src/index.c index 9407bf2..0e1c750 100644 --- a/src/index.c +++ b/src/index.c @@ -5,7 +5,7 @@ #include "../include/allocator.h" // GVA_Allocator #include "../include/edit.h" // gva_edit_distance #include "../include/index.h" // GVA_Index, gva_index_*, GVA_Result -#include "../include/lcs_graph.h" // GVA_LCS_Graph, gva_edges +#include "../include/lcs_graph.h" // GVA_LCS_Graph, gva_lcs_graph_* #include "../include/relations.h" // GVA_Relation, GVA_CONTAINS, // GVA_DISJOINT, GVA_EQUIVALENT, // GVA_IS_CONTAINED @@ -318,12 +318,7 @@ gva_index_query(GVA_Allocator const allocator, // for (size_t i = 0; i < array_length(graph.dom_nodes) - 1; ++i) { - GVA_Variant variant; - gva_edges(graph.observed.str, - graph.dom_nodes[i], graph.dom_nodes[i + 1], - i == 0, i == array_length(graph.dom_nodes) - 2, - &variant); - + GVA_Variant const variant = gva_lcs_graph_ls_slice(graph, i, i + 1); // fprintf(stderr, " %2zu " GVA_VARIANT_FMT_SPDI " (%u)\n", i, GVA_VARIANT_PRINT_SPDI("NC_000001.11", variant), graph.dom_nodes[i + 1].distance); gva_uint* intervals = interval_tree_intersection(allocator, self->intervals, variant.start, variant.end); @@ -439,16 +434,10 @@ gva_index_query(GVA_Allocator const allocator, // single query part has multiple hits if (gva_variant_length(lhs) != 0) { - GVA_Variant rhs; - // TODO: break out into gva_lcs_graph_local_supremal_part() function? - gva_edges(graph.observed.str, - graph.dom_nodes[hits[i].start], graph.dom_nodes[hits[i].end], - hits[i].start == 0, hits[i].end == array_length(graph.dom_nodes) - 2, - &rhs); - // aggregate hits in last hit hits[i].included = variants_with_distance(allocator, self->reference.len, self->reference.str, - lhs, distance, rhs, graph.dom_nodes[hits[i].start + 1].distance); + lhs, distance, + gva_lcs_graph_ls_slice(graph, hits[i].start, hits[i].end), graph.dom_nodes[hits[i].start + 1].distance); // disable aggregated hits except the last if (prev != GVA_NULL) @@ -472,27 +461,18 @@ gva_index_query(GVA_Allocator const allocator, { distance += graph.dom_nodes[j + 1].distance; } // for - GVA_Variant rhs; - gva_edges(graph.observed.str, - graph.dom_nodes[hits[i].start], graph.dom_nodes[hits[i].end], - hits[i].start == 0, hits[i].end == array_length(graph.dom_nodes) - 2, - &rhs); hits[i].included = variants_with_distance(allocator, self->reference.len, self->reference.str, variant_from_index(self, node_idx), self->intervals.nodes[node_idx].distance, - rhs, distance); + gva_lcs_graph_ls_slice(graph, hits[i].start, hits[i].end), distance); // fprintf(stderr, " Query multi hit: %u (%zu) :: %u\n", hits[i].end - hits[i].start, distance, hits[i].included); } // if // single hit for single query part, relation is not determined by the distances else if (ABS((intmax_t) self->intervals.nodes[node_idx].distance - graph.dom_nodes[hits[i].start + 1].distance) != hits[i].included) { - GVA_Variant rhs; - gva_edges(graph.observed.str, - graph.dom_nodes[hits[i].start], graph.dom_nodes[hits[i].end], - hits[i].start == 0, hits[i].end == array_length(graph.dom_nodes) - 2, - &rhs); hits[i].included = variants_included(allocator, self->reference.len, self->reference.str, - variant_from_index(self, node_idx), rhs); + variant_from_index(self, node_idx), + gva_lcs_graph_ls_slice(graph, hits[i].start, hits[i].end)); // fprintf(stderr, " Fully calculate: %u\n", hits[i].included); } // if // single hit for single query part, relation is already determined diff --git a/src/lcs_graph.c b/src/lcs_graph.c index 07dc941..e64007f 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -483,6 +483,19 @@ gva_lcs_graph_uniq_atomics(GVA_LCS_Graph const self, } // gva_lcs_graph_uniq_atomics +inline GVA_Variant +gva_lcs_graph_ls_slice(GVA_LCS_Graph const self, + size_t const start, size_t const end) +{ + GVA_Variant variant; + gva_edges(self.observed.str, + self.dom_nodes[start], self.dom_nodes[end], + start == 0, end == array_length(self.dom_nodes) - 2, + &variant); + return variant; +} // gva_lcs_graph_ls_slice + + gva_uint gva_edges(char const observed[static restrict 1], GVA_Node const head, GVA_Node const tail, @@ -499,8 +512,11 @@ gva_edges(char const observed[static restrict 1], gva_uint const head_offset = offset > 0 ? MIN(head_length, offset + 1) : 1; gva_uint const tail_offset = offset < 0 ? MIN(tail_length, -offset) : 0; - *variant = (GVA_Variant) { - row + head_offset, tail.row + tail_offset, { + *variant = (GVA_Variant) + { + row + head_offset, + tail.row + tail_offset, + { (tail.col + tail_offset) - (col + head_offset), observed + col + head_offset } From 79da64616bf78856757a8eaa61f207db57a5e995 Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 20 Feb 2026 07:14:20 +0100 Subject: [PATCH 494/704] Layout and bring back some comments --- src/index.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/src/index.c b/src/index.c index 0e1c750..bf9ed4c 100644 --- a/src/index.c +++ b/src/index.c @@ -272,8 +272,16 @@ gva_index_insert(GVA_Index* restrict const self, // add variant gva_uint const inserted_idx = trie_insert(self->allocator, &self->inserted, variant.sequence.len, variant.sequence.str); gva_uint const tmp_idx = ARRAY_APPEND(self->allocator, self->intervals.nodes, - ((Interval_Tree_Node) {{GVA_NULL, GVA_NULL}, - variant.start, variant.end, variant.end, 0, inserted_idx, GVA_NULL, distance})); + ((Interval_Tree_Node) + { + .child = {GVA_NULL, GVA_NULL}, + .start = variant.start, + .end = variant.end, + .max = variant.end, + .inserted = inserted_idx, + .alleles = GVA_NULL, + .distance = distance + })); gva_uint const node_idx = interval_tree_insert(&self->intervals, tmp_idx); // undo append: interval already in the tree if (node_idx != tmp_idx) @@ -281,7 +289,11 @@ gva_index_insert(GVA_Index* restrict const self, array_header(self->intervals.nodes)->length -= 1; } // if self->intervals.nodes[node_idx].alleles = ARRAY_APPEND(self->allocator, self->join, - ((Join) {node_idx ^ allele_idx, self->intervals.nodes[node_idx].alleles})); + ((Join) + { + node_idx ^ allele_idx, + self->intervals.nodes[node_idx].alleles + })); // update allele self->alleles[allele_idx].distance += distance; @@ -390,7 +402,11 @@ gva_index_query(GVA_Allocator const allocator, } // for // - // Phase 2: + // Phase 2: combine 1:N and N:1 hits into single hits + // - calculate relations that could not be determined on distances + // - switch from distances to `included` perspective + // - aggregate `included` per allele + // - discard disjoint alleles // for (size_t idx = 0; idx < array_header(entries)->capacity; ++idx) { @@ -500,7 +516,7 @@ gva_index_query(GVA_Allocator const allocator, } // for // - // Phase 3: + // Phase 3: determine relation per allele based on included // GVA_Result* results = NULL; From d148daee53519075fc6f7c7056a4532221280364 Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 20 Feb 2026 08:58:29 +0100 Subject: [PATCH 495/704] Minor style --- include/index.h | 7 ++- src/index.c | 127 +++++++++++++++++++----------------------------- src/main.c | 21 ++++---- 3 files changed, 63 insertions(+), 92 deletions(-) diff --git a/include/index.h b/include/index.h index 95039f3..bc879aa 100644 --- a/include/index.h +++ b/include/index.h @@ -15,11 +15,11 @@ typedef struct GVA_Index GVA_Index; // opaque typedef struct { - GVA_String allele; // FIXME: allele_idx + GVA_String allele; // FIXME: allele_idx GVA_Relation relation; size_t included; size_t excluded; -} GVA_Result; +} GVA_Query_Result; GVA_Index* @@ -38,8 +38,7 @@ gva_index_insert(GVA_Index* restrict const self, GVA_Variant const variant, size_t const distance); -// FIXME: returns -GVA_Result* +GVA_Query_Result* gva_index_query(GVA_Allocator const allocator, GVA_Index* const self, GVA_LCS_Graph const graph); diff --git a/src/index.c b/src/index.c index bf9ed4c..415c723 100644 --- a/src/index.c +++ b/src/index.c @@ -4,7 +4,7 @@ #include "../include/allocator.h" // GVA_Allocator #include "../include/edit.h" // gva_edit_distance -#include "../include/index.h" // GVA_Index, gva_index_*, GVA_Result +#include "../include/index.h" // GVA_Index, GVA_Query_Result, gva_index_* #include "../include/lcs_graph.h" // GVA_LCS_Graph, gva_lcs_graph_* #include "../include/relations.h" // GVA_Relation, GVA_CONTAINS, // GVA_DISJOINT, GVA_EQUIVALENT, @@ -12,7 +12,7 @@ #include "../include/string.h" // GVA_String #include "../include/types.h" // GVA_NULL, gva_uint #include "../include/variant.h" // GVA_Variant, gva_variant_* -#include "array.h" // ARRAY_*, array_* +#include "array.h" // ARRAY_*, array_length #include "bitset.h" // bitset_* #include "common.h" // ABS, MAX, MIN #include "hash_table.h" // NOT_FOUND, HASH_TABLE_*, hash_table_* @@ -20,9 +20,6 @@ #include "trie.h" // Trie, trie_* -#include // DEBUG - - typedef struct { gva_uint link; // X-OR link between interval_idx and allele_idx @@ -34,9 +31,7 @@ typedef struct { gva_uint id_idx; gva_uint distance; - - // wrt to join - gva_uint start; + gva_uint start; // wrt to join gva_uint end; } Allele; @@ -264,13 +259,20 @@ gva_index_insert(GVA_Index* restrict const self, size_t allele_idx = array_length(self->alleles) - 1; // new allele - if (array_length(self->alleles) == 0 || id_idx != self->alleles[allele_idx].id_idx) + if (array_length(self->alleles) == 0 || + self->alleles[allele_idx].id_idx != id_idx) { - allele_idx = ARRAY_APPEND(self->allocator, self->alleles, ((Allele) {id_idx, 0, array_length(self->join), 0})); + allele_idx = ARRAY_APPEND(self->allocator, self->alleles, + ((Allele) + { + .id_idx = id_idx, + .start = array_length(self->join), + })); } // if // add variant - gva_uint const inserted_idx = trie_insert(self->allocator, &self->inserted, variant.sequence.len, variant.sequence.str); + gva_uint const inserted_idx = trie_insert(self->allocator, &self->inserted, + variant.sequence.len, variant.sequence.str); gva_uint const tmp_idx = ARRAY_APPEND(self->allocator, self->intervals.nodes, ((Interval_Tree_Node) { @@ -280,7 +282,7 @@ gva_index_insert(GVA_Index* restrict const self, .max = variant.end, .inserted = inserted_idx, .alleles = GVA_NULL, - .distance = distance + .distance = distance, })); gva_uint const node_idx = interval_tree_insert(&self->intervals, tmp_idx); // undo append: interval already in the tree @@ -291,8 +293,8 @@ gva_index_insert(GVA_Index* restrict const self, self->intervals.nodes[node_idx].alleles = ARRAY_APPEND(self->allocator, self->join, ((Join) { - node_idx ^ allele_idx, - self->intervals.nodes[node_idx].alleles + .link = node_idx ^ allele_idx, + .next = self->intervals.nodes[node_idx].alleles, })); // update allele @@ -301,7 +303,7 @@ gva_index_insert(GVA_Index* restrict const self, } // gva_index_insert -GVA_Result* +GVA_Query_Result* gva_index_query(GVA_Allocator const allocator, GVA_Index* const self, GVA_LCS_Graph const graph) { @@ -311,7 +313,7 @@ gva_index_query(GVA_Allocator const allocator, gva_uint included; gva_uint head; // singly linked list in hits gva_uint tail; - }* entries = hash_table_init(allocator, 1024, sizeof(*entries)); + }* entries = hash_table_init(allocator, 1024, sizeof(*entries)); // FIXME: magic number struct Hit { @@ -322,40 +324,37 @@ gva_index_query(GVA_Allocator const allocator, gva_uint next; }* hits = NULL; - // // Phase 1: for every local supremal part: // - find candidates based on interval query // - calculate the distance with the candidates, // and quickly eject disjoint candidates based on distance - // for (size_t i = 0; i < array_length(graph.dom_nodes) - 1; ++i) { GVA_Variant const variant = gva_lcs_graph_ls_slice(graph, i, i + 1); - // fprintf(stderr, " %2zu " GVA_VARIANT_FMT_SPDI " (%u)\n", i, GVA_VARIANT_PRINT_SPDI("NC_000001.11", variant), graph.dom_nodes[i + 1].distance); gva_uint* intervals = interval_tree_intersection(allocator, self->intervals, variant.start, variant.end); for (size_t j = 0; j < array_length(intervals); ++j) { gva_uint const node_idx = intervals[j]; + size_t const distance = variants_distance(allocator, self->reference.len, self->reference.str, - variant_from_index(self, node_idx), variant); - if (distance >= self->intervals.nodes[node_idx].distance + graph.dom_nodes[i + 1].distance) + variant_from_index(self, node_idx), variant); + if (self->intervals.nodes[node_idx].distance + graph.dom_nodes[i + 1].distance <= distance) { // Disjoint based on distance continue; } // if - // fprintf(stderr, " vs " GVA_VARIANT_FMT_SPDI " (%u)\n", GVA_VARIANT_PRINT_SPDI("NC_000001.11", variant_from_index(self, node_idx)), self->intervals.nodes[node_idx].distance); - for (gva_uint k = self->intervals.nodes[node_idx].alleles; k != GVA_NULL; k = self->join[k].next) { gva_uint const allele_idx = self->join[k].link ^ node_idx; size_t const idx = HASH_TABLE_INDEX(entries, allele_idx); + // The first time a hit is associated with this allele: + // - create a new allele entry + // - add this first hit for that allele if (entries[idx].gva_key != allele_idx) { - // The first time a part is associated with this allele_idx - // we point it to the freshly created result part entry gva_uint const tail = ARRAY_APPEND(allocator, hits, ((struct Hit) { @@ -363,19 +362,20 @@ gva_index_query(GVA_Allocator const allocator, .included = distance, .start = i, .end = i + 1, - .next = GVA_NULL + .next = GVA_NULL, })); HASH_TABLE_SET(allocator, entries, allele_idx, ((struct Allele_Entry) { .gva_key = allele_idx, .head = tail, - .tail = tail + .tail = tail, })); continue; } // if - // is there a new hit for this allele? + // Add a new hit to an existing allele entry + // - only when this hit is with a different query part than before if (hits[entries[idx].tail].idx != k) { gva_uint const tail = ARRAY_APPEND(allocator, hits, @@ -385,13 +385,13 @@ gva_index_query(GVA_Allocator const allocator, .included = distance, .start = i, .end = i + 1, - .next = GVA_NULL + .next = GVA_NULL, })); // add to end of list hits[entries[idx].tail].next = tail; entries[idx].tail = tail; } // if - // otherwise the same hit for this query part + // otherwise: update the hit for this query part else { hits[entries[idx].tail].end = i + 1; @@ -401,13 +401,11 @@ gva_index_query(GVA_Allocator const allocator, intervals = ARRAY_DESTROY(allocator, intervals); } // for - // - // Phase 2: combine 1:N and N:1 hits into single hits - // - calculate relations that could not be determined on distances - // - switch from distances to `included` perspective - // - aggregate `included` per allele - // - discard disjoint alleles - // + // Phase 2: resolve 1:N and N:1 hits into 1:1 hits + // - calculate relations that could not be determined on distances + // - switch from distances to `included` perspective + // - aggregate `included` per allele + // - discard disjoint alleles for (size_t idx = 0; idx < array_header(entries)->capacity; ++idx) { if (entries[idx].gva_key == NOT_FOUND) @@ -415,16 +413,12 @@ gva_index_query(GVA_Allocator const allocator, continue; } // if - // fprintf(stderr, GVA_STRING_FMT ":\n", GVA_STRING_PRINT(trie_string(self->ids, self->alleles[entries[idx].gva_key].id_idx))); - gva_uint prev = GVA_NULL; for (gva_uint i = entries[idx].head; i != GVA_NULL; i = hits[i].next) { - // fprintf(stderr, " %u %u %u %u\n", hits[i].idx, hits[i].included, hits[i].start, hits[i].end); - + // Look ahead for the same local supremal part in the query GVA_Variant lhs = {0, 0, {0, NULL}}; size_t distance = 0; - // look ahead for the same local supremal part in the query while (hits[i].next != GVA_NULL && hits[hits[i].next].start == hits[i].start) { if (gva_variant_length(lhs) == 0) @@ -441,8 +435,6 @@ gva_index_query(GVA_Allocator const allocator, lhs.sequence = gva_string_concat(allocator, lhs.sequence, variant.sequence); lhs.end = variant.end; distance += self->intervals.nodes[node_idx].distance; - - // fprintf(stderr, " %u %u %u %u\n", hits[i].idx, hits[i].included, hits[i].start, hits[i].end); } // while gva_uint const node_idx = self->join[hits[i].idx].link ^ entries[idx].gva_key; @@ -465,11 +457,10 @@ gva_index_query(GVA_Allocator const allocator, entries[idx].head = i; } // else - // fprintf(stderr, " DB multi hit: " GVA_VARIANT_FMT_SPDI " (%zu) :: %u\n", GVA_VARIANT_PRINT_SPDI("NC_000001.11", lhs), distance, hits[i].included); gva_string_destroy(allocator, lhs.sequence); } // if // single hit with multiple query parts - else if (hits[i].end - hits[i].start > 1) // FIXME: similar body to if below? + else if (hits[i].end - hits[i].start > 1) { // FIXME: use cumulative distances in dom_nodes size_t distance = 0; // graph.dom_nodes[hits[i].end].distance - graph.dom_nodes[hits[i].start].distance @@ -480,8 +471,6 @@ gva_index_query(GVA_Allocator const allocator, hits[i].included = variants_with_distance(allocator, self->reference.len, self->reference.str, variant_from_index(self, node_idx), self->intervals.nodes[node_idx].distance, gva_lcs_graph_ls_slice(graph, hits[i].start, hits[i].end), distance); - - // fprintf(stderr, " Query multi hit: %u (%zu) :: %u\n", hits[i].end - hits[i].start, distance, hits[i].included); } // if // single hit for single query part, relation is not determined by the distances else if (ABS((intmax_t) self->intervals.nodes[node_idx].distance - graph.dom_nodes[hits[i].start + 1].distance) != hits[i].included) @@ -489,7 +478,6 @@ gva_index_query(GVA_Allocator const allocator, hits[i].included = variants_included(allocator, self->reference.len, self->reference.str, variant_from_index(self, node_idx), gva_lcs_graph_ls_slice(graph, hits[i].start, hits[i].end)); - // fprintf(stderr, " Fully calculate: %u\n", hits[i].included); } // if // single hit for single query part, relation is already determined else @@ -508,19 +496,14 @@ gva_index_query(GVA_Allocator const allocator, entries[idx].included += hits[i].included; prev = i; } // for - // TODO: exclude included == 0? if (entries[idx].included == 0) { entries[idx].gva_key = NOT_FOUND; } // if } // for - // // Phase 3: determine relation per allele based on included - // - - GVA_Result* results = NULL; - + GVA_Query_Result* results = NULL; for (size_t idx = 0; idx < array_header(entries)->capacity; ++idx) { if (entries[idx].gva_key == NOT_FOUND) @@ -528,45 +511,33 @@ gva_index_query(GVA_Allocator const allocator, continue; } // if - - // fprintf(stderr, GVA_STRING_FMT ": %u\n", - // GVA_STRING_PRINT(trie_string(self->ids, self->alleles[entries[idx].gva_key].id_idx)), - // entries[idx].included); - - // for (gva_uint i = entries[idx].head; i != GVA_NULL; i = hits[i].next) - // { - // GVA_Variant variant; - // gva_edges(graph.observed.str, - // graph.dom_nodes[hits[i].start], graph.dom_nodes[hits[i].end], - // hits[i].start == 0, hits[i].end == array_length(graph.dom_nodes) - 2, - // &variant); - // - // gva_uint const node_idx = self->join[hits[i].idx].link ^ entries[idx].gva_key; - // fprintf(stderr, " " GVA_VARIANT_FMT_SPDI " " GVA_VARIANT_FMT_SPDI " %u\n", GVA_VARIANT_PRINT_SPDI("NC_000006.12", variant_from_index(self, node_idx)), GVA_VARIANT_PRINT_SPDI("NC_000006.12", variant), hits[i].included); - // } // for - GVA_Relation relation; size_t const excluded = self->alleles[entries[idx].gva_key].distance + graph.distance - 2 * entries[idx].included; if (excluded == 0) { relation = GVA_EQUIVALENT; } // if - else if (entries[idx].included == graph.distance) + else if (graph.distance == entries[idx].included) { relation = GVA_CONTAINS; - } // else if - else if (entries[idx].included == self->alleles[entries[idx].gva_key].distance) + } // if + else if (self->alleles[entries[idx].gva_key].distance == entries[idx].included) { relation = GVA_IS_CONTAINED; - } // else if + } // if else { relation = GVA_OVERLAP; } // else ARRAY_APPEND(self->allocator, results, - ((GVA_Result) {trie_string(self->ids, self->alleles[entries[idx].gva_key].id_idx), relation, entries[idx].included, excluded}) - ); + ((GVA_Query_Result) + { + .allele = trie_string(self->ids, self->alleles[entries[idx].gva_key].id_idx), + .relation = relation, + .included = entries[idx].included, + .excluded = excluded, + })); } // for hits = ARRAY_DESTROY(allocator, hits); diff --git a/src/main.c b/src/main.c index 061ae74..bd8b257 100644 --- a/src/main.c +++ b/src/main.c @@ -577,15 +577,15 @@ index_main(int argc, char* argv[static argc]) while (fgets(line, sizeof(line), stream) != NULL) { line_count += 1; - size_t id_len = 0; + size_t len_id = 0; GVA_Variant variant; size_t distance = 0; - if (!parse_line(line, &id_len, &variant, &distance)) + if (!parse_line(line, &len_id, &variant, &distance)) { fprintf(stderr, "parsing failed at line %zu: %s\n", line_count, line); continue; } // if - gva_index_insert(index, id_len, line, variant, distance); + gva_index_insert(index, len_id, line, variant, distance); } // while fclose(stream); @@ -594,9 +594,9 @@ index_main(int argc, char* argv[static argc]) while (fgets(line, sizeof(line), stdin) != NULL) { line_count += 1; - size_t id_len = 0; + size_t len_id = 0; GVA_Variant variant; - if (!parse_line2(line, &id_len, &variant)) + if (!parse_line2(line, &len_id, &variant)) { fprintf(stderr, "parsing failed at line %zu: %s\n", line_count, line); continue; @@ -605,18 +605,19 @@ index_main(int argc, char* argv[static argc]) GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &variant); // fprintf(stderr, "\nQuery (" GVA_STRING_FMT "): " GVA_VARIANT_FMT_SPDI " (%u)\n", GVA_STRING_PRINT(((GVA_String) {id_len, line})), GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, graph.supremal), graph.distance); - GVA_Result* results = gva_index_query(gva_std_allocator, index, graph); + GVA_Query_Result* results = gva_index_query(gva_std_allocator, index, graph); for (size_t i = 0; i < array_length(results); ++i) { - fprintf(stdout, GVA_STRING_FMT " %s %.*s %zu %zu\n", + fprintf(stdout, GVA_STRING_FMT " %s " GVA_STRING_FMT " %zu %zu\n", GVA_STRING_PRINT(results[i].allele), GVA_RELATION_LABELS[results[i].relation], - (int)id_len, line, results[i].included, results[i].excluded); - } + GVA_STRING_PRINT(((GVA_String) {len_id, line})), + results[i].included, results[i].excluded); + } // for + ARRAY_DESTROY(gva_std_allocator, results); gva_string_destroy(gva_std_allocator, graph.observed); gva_lcs_graph_destroy(gva_std_allocator, graph); - ARRAY_DESTROY(gva_std_allocator, results); } // while index = gva_index_destroy(index); From fc80e04f6df7e75b498a3f6d3bcea3b6ce9dc509 Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 20 Feb 2026 10:04:50 +0100 Subject: [PATCH 496/704] shift -> offset --- src/align.c | 38 +++++++++++++++++++++----------------- src/align.h | 3 +-- 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/src/align.c b/src/align.c index 95b4d34..c8799c8 100644 --- a/src/align.c +++ b/src/align.c @@ -17,7 +17,7 @@ typedef struct char const* const restrict reference; size_t const len_obs; char const* const restrict observed; - size_t const shift; + size_t const offset; size_t* const restrict diagonals; } Context; @@ -78,11 +78,11 @@ expand(Context const context, gva_uint const idx = ARRAY_APPEND(context.allocator, lcs->nodes, ((LCS_Node) { - .row = match_row + context.shift, + .row = match_row + context.offset, .col = match_col, .length = length, .idx = GVA_NULL, - .next = GVA_NULL + .next = GVA_NULL, })); if (lcs->index[lcs_pos].head != GVA_NULL) { @@ -125,11 +125,11 @@ expand(Context const context, gva_uint const idx = ARRAY_APPEND(context.allocator, lcs->nodes, ((LCS_Node) { - .row = match_row + context.shift, + .row = match_row + context.offset, .col = match_col, .length = length, .idx = GVA_NULL, - .next = GVA_NULL + .next = GVA_NULL, })); if (lcs->index[lcs_pos].head != GVA_NULL) { @@ -154,15 +154,15 @@ LCS_Alignment lcs_align(GVA_Allocator const allocator, size_t const len_ref, char const reference[static restrict len_ref], size_t const len_obs, char const observed[static restrict len_obs], - size_t const shift) + size_t const offset) { intmax_t const delta = len_obs - len_ref; - size_t const offset = len_ref + 1; size_t const size = len_ref + len_obs + 3; LCS_Alignment lcs = {0, NULL, NULL}; - lcs.index = allocator.allocate(allocator.context, NULL, 0, MIN(len_ref, len_obs) * sizeof(*lcs.index)); + lcs.index = allocator.allocate(allocator.context, NULL, + 0, MIN(len_ref, len_obs) * sizeof(*lcs.index)); if (lcs.index == NULL) { return lcs; @@ -175,12 +175,14 @@ lcs_align(GVA_Allocator const allocator, reference, len_obs, observed, - shift, - .diagonals = allocator.allocate(allocator.context, NULL, 0, size * sizeof(*context.diagonals)), + offset, + .diagonals = allocator.allocate(allocator.context, NULL, + 0, size * sizeof(*context.diagonals)), }; if (context.diagonals == NULL) { - lcs.index = allocator.allocate(allocator.context, lcs.index, MIN(len_ref, len_obs) * sizeof(*lcs.index), lcs.length * sizeof(*lcs.index)); + lcs.index = allocator.allocate(allocator.context, lcs.index, + MIN(len_ref, len_obs) * sizeof(*lcs.index), lcs.length * sizeof(*lcs.index)); return lcs; } // if @@ -197,22 +199,24 @@ lcs_align(GVA_Allocator const allocator, size_t const upper = delta > 0 ? delta : 0; size_t const len = MAX(len_ref, len_obs) - ABS(delta); size_t p = 0; - while (context.diagonals[offset + delta] <= len) + while (context.diagonals[len_ref + 1 + delta] <= len) { for (intmax_t idx = lower - p; idx < delta; ++idx) { - context.diagonals[offset + idx] = expand(context, idx, p, &lcs); + context.diagonals[len_ref + 1 + idx] = expand(context, idx, p, &lcs); } // for for (intmax_t idx = upper + p; idx > delta; --idx) { - context.diagonals[offset + idx] = expand(context, idx, p, &lcs); + context.diagonals[len_ref + 1 + idx] = expand(context, idx, p, &lcs); } // for - context.diagonals[offset + delta] = expand(context, delta, p, &lcs); + context.diagonals[len_ref + 1 + delta] = expand(context, delta, p, &lcs); p += 1; } // while - lcs.index = allocator.allocate(allocator.context, lcs.index, MIN(len_ref, len_obs) * sizeof(*lcs.index), lcs.length * sizeof(*lcs.index)); - allocator.allocate(allocator.context, context.diagonals, size * sizeof(*context.diagonals), 0); + lcs.index = allocator.allocate(allocator.context, lcs.index, + MIN(len_ref, len_obs) * sizeof(*lcs.index), lcs.length * sizeof(*lcs.index)); + allocator.allocate(allocator.context, context.diagonals, + size * sizeof(*context.diagonals), 0); return lcs; } // lcs_align diff --git a/src/align.h b/src/align.h index 9ed5ef3..b0adcd9 100644 --- a/src/align.h +++ b/src/align.h @@ -35,12 +35,11 @@ typedef struct } LCS_Alignment; -// FIXME: shift -> offset LCS_Alignment lcs_align(GVA_Allocator const allocator, size_t const len_ref, char const reference[static restrict len_ref], size_t const len_obs, char const observed[static restrict len_obs], - size_t const shift); + size_t const offset); #endif // GVA_ALIGN_H From 5f110fc0c717baa39eaf0099047514a84a630ac0 Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 20 Feb 2026 10:13:37 +0100 Subject: [PATCH 497/704] Refactoring: offset and cumulative distances --- include/lcs_graph.h | 5 ++- src/index.c | 19 ++++------ src/lcs_graph.c | 88 +++++++++++++++++++++------------------------ 3 files changed, 49 insertions(+), 63 deletions(-) diff --git a/include/lcs_graph.h b/include/lcs_graph.h index 88dd57e..8a2cb3f 100644 --- a/include/lcs_graph.h +++ b/include/lcs_graph.h @@ -37,7 +37,7 @@ typedef struct union { gva_uint edges; - gva_uint distance; // FIXME: this should be cumulative + gva_uint distance; }; union { @@ -61,12 +61,11 @@ typedef struct } GVA_LCS_Graph; -// FIXME: shift -> offset GVA_LCS_Graph gva_lcs_graph_init(GVA_Allocator const allocator, size_t const len_ref, char const reference[static restrict len_ref], size_t const len_obs, char const observed[static restrict len_obs], - size_t const shift); + size_t const offset); void diff --git a/src/index.c b/src/index.c index 415c723..6dd6f75 100644 --- a/src/index.c +++ b/src/index.c @@ -445,7 +445,7 @@ gva_index_query(GVA_Allocator const allocator, // aggregate hits in last hit hits[i].included = variants_with_distance(allocator, self->reference.len, self->reference.str, lhs, distance, - gva_lcs_graph_ls_slice(graph, hits[i].start, hits[i].end), graph.dom_nodes[hits[i].start + 1].distance); + gva_lcs_graph_ls_slice(graph, hits[i].start, hits[i].end), graph.dom_nodes[hits[i].end].distance - graph.dom_nodes[hits[i].start].distance); // disable aggregated hits except the last if (prev != GVA_NULL) @@ -462,18 +462,12 @@ gva_index_query(GVA_Allocator const allocator, // single hit with multiple query parts else if (hits[i].end - hits[i].start > 1) { - // FIXME: use cumulative distances in dom_nodes - size_t distance = 0; // graph.dom_nodes[hits[i].end].distance - graph.dom_nodes[hits[i].start].distance - for (gva_uint j = hits[i].start; j < hits[i].end; ++j) - { - distance += graph.dom_nodes[j + 1].distance; - } // for hits[i].included = variants_with_distance(allocator, self->reference.len, self->reference.str, variant_from_index(self, node_idx), self->intervals.nodes[node_idx].distance, - gva_lcs_graph_ls_slice(graph, hits[i].start, hits[i].end), distance); + gva_lcs_graph_ls_slice(graph, hits[i].start, hits[i].end), graph.dom_nodes[hits[i].end].distance - graph.dom_nodes[hits[i].start].distance); } // if // single hit for single query part, relation is not determined by the distances - else if (ABS((intmax_t) self->intervals.nodes[node_idx].distance - graph.dom_nodes[hits[i].start + 1].distance) != hits[i].included) + else if (ABS((intmax_t) self->intervals.nodes[node_idx].distance - (graph.dom_nodes[hits[i].end].distance - graph.dom_nodes[hits[i].start].distance)) != hits[i].included) { hits[i].included = variants_included(allocator, self->reference.len, self->reference.str, variant_from_index(self, node_idx), @@ -482,13 +476,14 @@ gva_index_query(GVA_Allocator const allocator, // single hit for single query part, relation is already determined else { + gva_uint const distance = graph.dom_nodes[hits[i].end].distance - graph.dom_nodes[hits[i].start].distance; // equivalent or contains - if (self->intervals.nodes[node_idx].distance - graph.dom_nodes[hits[i].start + 1].distance == hits[i].included) + if (self->intervals.nodes[node_idx].distance - distance == hits[i].included) { - hits[i].included = graph.dom_nodes[hits[i].start + 1].distance; + hits[i].included = distance; } // if // is_contained - else if (graph.dom_nodes[hits[i].start + 1].distance - self->intervals.nodes[node_idx].distance == hits[i].included) + else if (distance - self->intervals.nodes[node_idx].distance == hits[i].included) { hits[i].included = self->intervals.nodes[node_idx].distance; } // if diff --git a/src/lcs_graph.c b/src/lcs_graph.c index e64007f..a0e1059 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -18,33 +18,31 @@ GVA_LCS_Graph gva_lcs_graph_init(GVA_Allocator const allocator, size_t const len_ref, char const reference[static restrict len_ref], size_t const len_obs, char const observed[static restrict len_obs], - size_t const shift) + size_t const offset) { - LCS_Alignment lcs = lcs_align(allocator, len_ref, reference, len_obs, observed, shift); + LCS_Alignment lcs = lcs_align(allocator, len_ref, reference, len_obs, observed, offset); + size_t const distance = len_ref + len_obs - 2 * lcs.length; GVA_LCS_Graph graph = { - .nodes = NULL, - .edges = NULL, - .dom_nodes = NULL, .supremal = {0, 0, {0, observed}}, .observed = {len_obs, observed}, .source = GVA_NULL, - .distance = len_ref + len_obs - 2 * lcs.length + .distance = distance, }; - if (lcs.nodes == NULL || graph.distance == 0) + if (lcs.nodes == NULL || distance == 0) { gva_uint const sink = ARRAY_APPEND(allocator, graph.nodes, ((GVA_Node) { - .row = len_ref + shift, + .row = len_ref + offset, .col = len_obs, .edges = GVA_NULL, - .lambda = GVA_NULL + .lambda = GVA_NULL, })); - if (graph.distance == 0) + if (distance == 0) { graph.source = sink; graph.nodes[sink].row = 0; @@ -59,32 +57,32 @@ gva_lcs_graph_init(GVA_Allocator const allocator, graph.source = ARRAY_APPEND(allocator, graph.nodes, ((GVA_Node) { - .row = shift, + .row = offset, .edges = ARRAY_APPEND(allocator, graph.edges, ((GVA_Edge) {sink, GVA_NULL})), - .lambda = GVA_NULL + .lambda = GVA_NULL, })); ARRAY_APPEND(allocator, graph.dom_nodes, ((GVA_Node) { - .row = shift, - .link = graph.source + .row = offset, + .link = graph.source, })); ARRAY_APPEND(allocator, graph.dom_nodes, ((GVA_Node) { - .row = len_ref + shift, + .row = len_ref + offset, .col = len_obs, - .distance = graph.distance, - .link = sink + .distance = distance, + .link = sink, })); - graph.supremal = (GVA_Variant) {shift, len_ref + shift, {len_obs, observed}}; + graph.supremal = (GVA_Variant) {offset, len_ref + offset, {len_obs, observed}}; return graph; } // if gva_uint tail_idx = lcs.index[lcs.length - 1].tail; LCS_Node sink = lcs.nodes[tail_idx]; - if (sink.row + sink.length == len_ref + shift && sink.col + sink.length == len_obs) + if (sink.row + sink.length == len_ref + offset && sink.col + sink.length == len_obs) { lcs.nodes[tail_idx].idx = ARRAY_APPEND(allocator, graph.nodes, ((GVA_Node) @@ -93,14 +91,14 @@ gva_lcs_graph_init(GVA_Allocator const allocator, .col = sink.col, .length = sink.length, .edges = GVA_NULL, - .lambda = GVA_NULL + .lambda = GVA_NULL, })); lcs.nodes[tail_idx].moved = true; sink = lcs.nodes[tail_idx]; } // if else { - sink = (LCS_Node) {.row = len_ref + shift, .col = len_obs, .length = 0}; + sink = (LCS_Node) {.row = len_ref + offset, .col = len_obs, .length = 0}; sink.idx = ARRAY_APPEND(allocator, graph.nodes, ((GVA_Node) { @@ -108,7 +106,7 @@ gva_lcs_graph_init(GVA_Allocator const allocator, .col = sink.col, .length = sink.length, .edges = GVA_NULL, - .lambda = GVA_NULL + .lambda = GVA_NULL, })); tail_idx = GVA_NULL; } // else @@ -121,7 +119,7 @@ gva_lcs_graph_init(GVA_Allocator const allocator, .col = lcs.nodes[i].col, .length = lcs.nodes[i].length, .edges = ARRAY_APPEND(allocator, graph.edges, ((GVA_Edge) {sink.idx, GVA_NULL})), - .lambda = GVA_NULL + .lambda = GVA_NULL, })); } // for @@ -190,8 +188,8 @@ gva_lcs_graph_init(GVA_Allocator const allocator, graph.nodes[head->idx].edges = ARRAY_APPEND(allocator, graph.edges, ((GVA_Edge) { - tail->idx, - graph.nodes[head->idx].edges + .tail = tail->idx, + .next = graph.nodes[head->idx].edges, })); } // if } // for @@ -217,7 +215,7 @@ gva_lcs_graph_init(GVA_Allocator const allocator, gva_uint head_idx = lcs.index[0].head; LCS_Node source = lcs.nodes[head_idx]; - if (source.row == shift && source.col == 0) + if (source.row == offset && source.col == 0) { lcs.index[0].tail = head_idx; lcs.index[0].count += 1; @@ -227,7 +225,7 @@ gva_lcs_graph_init(GVA_Allocator const allocator, } // if else { - source = (LCS_Node) {.row = shift, .col = 0, .length = 0}; + source = (LCS_Node) {.row = offset, .col = 0, .length = 0}; source.idx = ARRAY_APPEND(allocator, graph.nodes, ((GVA_Node) { @@ -235,7 +233,7 @@ gva_lcs_graph_init(GVA_Allocator const allocator, .col = source.col, .length = source.length, .edges = GVA_NULL, - .lambda = GVA_NULL + .lambda = GVA_NULL, })); } // else for (gva_uint i = head_idx; i != GVA_NULL; i = lcs.nodes[i].next) @@ -254,8 +252,8 @@ gva_lcs_graph_init(GVA_Allocator const allocator, graph.nodes[source.idx].edges = ARRAY_APPEND(allocator, graph.edges, ((GVA_Edge) { - lcs.nodes[i].idx, - graph.nodes[source.idx].edges + .tail = lcs.nodes[i].idx, + .next = graph.nodes[source.idx].edges, })); } // if } // for @@ -264,10 +262,9 @@ gva_lcs_graph_init(GVA_Allocator const allocator, ARRAY_APPEND(allocator, graph.dom_nodes, ((GVA_Node) { - .row = shift, - .link = source.idx + .row = offset, + .link = source.idx, })); - gva_uint distance = 0; gva_uint prev = lcs.index[0].tail; if (lcs.nodes[lcs.index[0].tail].idx != source.idx) { @@ -281,20 +278,18 @@ gva_lcs_graph_init(GVA_Allocator const allocator, // start new if (lcs.index[i].tail != prev) { - gva_uint const offset = graph.nodes[lcs.nodes[lcs.index[i].tail].idx].length - lcs.index[i].offset - 1; + gva_uint const pos = graph.nodes[lcs.nodes[lcs.index[i].tail].idx].length - lcs.index[i].offset - 1; ARRAY_APPEND(allocator, graph.dom_nodes, ((GVA_Node) { - .row = lcs.nodes[lcs.index[i].tail].row + offset, - .col = lcs.nodes[lcs.index[i].tail].col + offset, - .distance = lcs.nodes[lcs.index[i].tail].row + offset - shift + - lcs.nodes[lcs.index[i].tail].col + offset - - 2 * i - distance, - .link = lcs.nodes[lcs.index[i].tail].idx + .row = lcs.nodes[lcs.index[i].tail].row + pos, + .col = lcs.nodes[lcs.index[i].tail].col + pos, + .distance = lcs.nodes[lcs.index[i].tail].row + pos - offset + + lcs.nodes[lcs.index[i].tail].col + pos - 2 * i, + .link = lcs.nodes[lcs.index[i].tail].idx, })); prev = lcs.index[i].tail; - distance += graph.dom_nodes[array_length(graph.dom_nodes) - 1].distance; } // if graph.dom_nodes[array_length(graph.dom_nodes) - 1].length += 1; @@ -309,7 +304,7 @@ gva_lcs_graph_init(GVA_Allocator const allocator, { .row = sink.row + sink.length, .col = sink.col + sink.length, - .distance = graph.distance - distance, + .distance = distance, .link = sink.idx, })); } // if @@ -514,12 +509,9 @@ gva_edges(char const observed[static restrict 1], *variant = (GVA_Variant) { - row + head_offset, - tail.row + tail_offset, - { - (tail.col + tail_offset) - (col + head_offset), - observed + col + head_offset - } + .start = row + head_offset, + .end = tail.row + tail_offset, + .sequence = {(tail.col + tail_offset) - (col + head_offset), observed + col + head_offset}, }; return MIN(head_length - head_offset, tail_length - tail_offset - 1) + 1; } // gva_edges From 2e911fdb46be6c9a748790119c0fd7691a9e63e2 Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 20 Feb 2026 14:00:28 +0100 Subject: [PATCH 498/704] Moved various functions from main to their respective modules --- include/string.h | 10 +- include/utils.h | 6 +- include/variant.h | 5 + src/interval_tree.c | 2 +- src/main.c | 468 ++------------------------------------------ src/string.c | 28 +++ src/utils.c | 55 +++--- src/variant.c | 9 + 8 files changed, 102 insertions(+), 481 deletions(-) diff --git a/include/string.h b/include/string.h index 88dbe73..18cf9c7 100644 --- a/include/string.h +++ b/include/string.h @@ -35,4 +35,12 @@ GVA_String gva_string_dup(GVA_Allocator const allocator, GVA_String const self); -#endif +void +gva_string_reverse(GVA_String self); + + +size_t +gva_string_prefix_length(GVA_String const lhs, GVA_String const rhs); + + +#endif // GVA_STRING_H diff --git a/include/utils.h b/include/utils.h index d355c15..e36213d 100644 --- a/include/utils.h +++ b/include/utils.h @@ -7,6 +7,7 @@ #include // FILE #include "allocator.h" // GVA_Allocator +#include "lcs_graph.h" // GVA_LCS_Graph #include "string.h" // GVA_String @@ -19,9 +20,8 @@ GVA_String gva_fasta_sequence(GVA_Allocator const allocator, FILE* const stream); -GVA_String -gva_random_sequence(GVA_Allocator const allocator, - size_t const min_length, size_t const max_length); +void +gva_lcs_graph_dot(FILE* const stream, GVA_LCS_Graph const graph); #endif // GVA_UTILS_H diff --git a/include/variant.h b/include/variant.h index 1f7d78e..aba88ea 100644 --- a/include/variant.h +++ b/include/variant.h @@ -42,6 +42,11 @@ size_t gva_variant_length(GVA_Variant const variant); +GVA_Variant +gva_variant_prefix_trimmed(size_t const len_ref, char const reference[static len_ref], + GVA_Variant const variant); + + GVA_String gva_patch(GVA_Allocator const allocator, size_t const len_ref, char const reference[static restrict len_ref], diff --git a/src/interval_tree.c b/src/interval_tree.c index a4f1061..4ca3277 100644 --- a/src/interval_tree.c +++ b/src/interval_tree.c @@ -26,7 +26,7 @@ interval_tree_destroy(GVA_Allocator const allocator, Interval_Tree self[static 1 enum { LEFT = 0, - RIGHT = 1 + RIGHT = 1, }; diff --git a/src/main.c b/src/main.c index bd8b257..dcf3f8e 100644 --- a/src/main.c +++ b/src/main.c @@ -1,12 +1,9 @@ -#define _POSIX_C_SOURCE 200809L #include // errno #include // CHAR_BIT #include // NULL, size_t #include // FILE, stderr, stdout, fclose, fopen, fprintf #include // EXIT_* - #include // strerror, strlen -#include // CLOCKS_PER_SEC, clock_t, clock #include "../include/compare.h" // bitset_fill #include "../include/edit.h" // gva_edit_distance @@ -16,7 +13,7 @@ #include "../include/std_alloc.h" // gva_std_allocator #include "../include/string.h" // GVA_String, gva_string_destroy #include "../include/types.h" // GVA_NULL, gva_uint -#include "../include/utils.h" // gva_fasta_sequence +#include "../include/utils.h" // gva_fasta_sequence, gva_lcs_graph_dot #include "../include/variant.h" // GVA_VARIANT_*, GVA_Variant, gva_parse_spdi #include "array.h" // ARRAY_DESTROY, array_length #include "bitset.h" // bitset_* @@ -26,99 +23,12 @@ #include "trie.h" // Trie, trie_* -#define TIC(x) clock_t const x = clock() -#define TOC(x) fprintf(stderr, "Elapsed time: %s (seconds): %.2f\n", (#x), (double)(clock() - (x)) / CLOCKS_PER_SEC) - #define LINE_SIZE 8194 // #define REFERENCE_ID "NC_000006.12" #define REFERENCE_ID "NC_000001.11" -inline void -serialize_array(FILE* restrict const stream, - void* restrict const self, size_t const item_size) -{ - size_t const length = array_length(self); - if (fwrite(&length, sizeof(length), 1, stream) != 1 || - fwrite(self, item_size, length, stream) != length) - { - fprintf(stderr, "error: fwrite()\n"); - return; - } // if -} // serialize_array - - -inline void* -deserialize_array(GVA_Allocator const allocator, FILE* const stream, - size_t const item_size) -{ - size_t length = 0; - if (fread(&length, sizeof(length), 1, stream) != 1) - { - fprintf(stderr, "error: fread()\n"); - return NULL; - } // if - - if (length == 0) - { - return NULL; - } // if - - void* const restrict array = array_init(allocator, length, item_size); - if (array == NULL) - { - fprintf(stderr, "error: OOM\n"); - return NULL; - } // if - - if (fread(array, item_size, length, stream) != length) - { - fprintf(stderr, "error: fread()\n"); - return allocator.allocate(allocator.context, array_header(array), length * item_size, 0); - } // if - - array_header(array)->length = length; - return array; -} // deserialize_array - - -void -lcs_graph_dot(FILE* const stream, GVA_LCS_Graph const graph) -{ - fprintf(stream, "strict digraph{\nrankdir=LR\nedge[fontname=monospace]\nnode[fixedsize=true,fontname=serif,shape=circle,width=1]\ni[label=\"\",shape=none,width=0]\ni->%u\n", graph.source); - for (size_t i = 0; i < array_length(graph.nodes); ++i) - { - fprintf(stream, "%zu[label=\"(%u, %u, %u)\"%s]\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, graph.nodes[i].edges == GVA_NULL ? ",peripheries=2" : ""); - if (graph.nodes[i].lambda != GVA_NULL) - { - fprintf(stream, "%zu->%u[label=\"λ\",style=dashed]\n", i, graph.nodes[i].lambda); - } // if - for (gva_uint j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) - { - GVA_Variant variant; - gva_uint const count = gva_edges(graph.observed.str, - graph.nodes[i], graph.nodes[graph.edges[j].tail], - i == graph.source, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, - &variant); - if (count > 1) - { - fprintf(stream, "%zu->%u[label=\"" GVA_VARIANT_FMT " x %u\",penwidth=2]\n", i, graph.edges[j].tail, GVA_VARIANT_PRINT(variant), count); - } // if - else - { - fprintf(stream, "%zu->%u[label=\"" GVA_VARIANT_FMT "\"]\n", i, graph.edges[j].tail, GVA_VARIANT_PRINT(variant)); - } // else - } // for - } // for - for (size_t i = 0; i < array_length(graph.dom_nodes); ++i) - { - fprintf(stream, "%u[penwidth=2]\n", graph.dom_nodes[i].link); - } // for - fprintf(stream, "}\n"); -} // lcs_graph_dot - - // FIXME: see `match_number` in src/variant.c static inline size_t parse_number(char const buffer[static 1], size_t idx[static 1]) @@ -183,355 +93,28 @@ fasta_blob_write(FILE* stream, GVA_String const sequence) } // fasta_blob_write -static size_t -variants_distance(GVA_Allocator const allocator, - size_t const len_ref, char const reference[static len_ref], - GVA_Variant const lhs, GVA_Variant const rhs) -{ - size_t const start = MIN(lhs.start, rhs.start); - size_t const end = MAX(lhs.end, rhs.end); - - size_t const lhs_len = (lhs.start - start) + lhs.sequence.len + (end - lhs.end); - size_t const rhs_len = (rhs.start - start) + rhs.sequence.len + (end - rhs.end); - - if (lhs_len == 0) - { - return rhs_len; - } // if - if (rhs_len == 0) - { - return lhs_len; - } // if - - char* lhs_obs = allocator.allocate(allocator.context, NULL, 0, lhs_len); - char* rhs_obs = allocator.allocate(allocator.context, NULL, 0, rhs_len); - if (lhs_obs == NULL || rhs_obs == NULL) - { - rhs_obs = allocator.allocate(allocator.context, rhs_obs, rhs_len, 0); - lhs_obs = allocator.allocate(allocator.context, lhs_obs, lhs_len, 0); - return -1; - } // if - - memcpy(lhs_obs, reference + start, lhs.start - start); - memcpy(lhs_obs + lhs.start - start, lhs.sequence.str, lhs.sequence.len); - memcpy(lhs_obs + lhs.start - start + lhs.sequence.len, reference + lhs.end, end - lhs.end); - - memcpy(rhs_obs, reference + start, rhs.start - start); - memcpy(rhs_obs + rhs.start - start, rhs.sequence.str, rhs.sequence.len); - memcpy(rhs_obs + rhs.start - start + rhs.sequence.len, reference + rhs.end, end - rhs.end); - - size_t const distance = gva_edit_distance(allocator, lhs_len, lhs_obs, rhs_len, rhs_obs); - - rhs_obs = allocator.allocate(allocator.context, rhs_obs, rhs_len, 0); - lhs_obs = allocator.allocate(allocator.context, lhs_obs, lhs_len, 0); - - return distance; -} // variants_distance - - -static GVA_Variant -construct_variant(GVA_Allocator const allocator, - size_t const len_ref, char const reference[static len_ref], - Interval_Tree const tree, Trie const trie, gva_uint* const nodes) -{ - // FIXME: in 1 loop - size_t const n = array_length(nodes); - GVA_Variant* variants = allocator.allocate(allocator.context, NULL, 0, n * sizeof(*variants)); - for (size_t i = 0; i < n; ++i) - { - variants[i] = (GVA_Variant) { - tree.nodes[nodes[i]].start, - tree.nodes[nodes[i]].end, - trie_string(trie, tree.nodes[nodes[i]].inserted) - }; - } // for - - GVA_Variant variant = { - tree.nodes[nodes[0]].start, - tree.nodes[nodes[n - 1]].end, - {0, NULL} - }; - variant.sequence = gva_string_concat(allocator, variant.sequence, variants[0].sequence); - for (size_t i = 1; i < n; ++i) - { - variant.sequence = gva_string_concat(allocator, variant.sequence, (GVA_String) {variants[i].start - variants[i - 1].end, reference + variants[i - 1].end}); - variant.sequence = gva_string_concat(allocator, variant.sequence, variants[i].sequence); - } // for - // fprintf(stderr, GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(variant)); - - // deallocate - variants = allocator.allocate(allocator.context, variants, n * sizeof(*variants), 0); - - return variant; -} // construct_variant - - -static size_t -multiple_is_contained_distance(GVA_Allocator const allocator, - size_t const len_ref, char const reference[static len_ref], - GVA_LCS_Graph const graph, - size_t const part_idx, Interval_Tree const tree, Trie const trie, gva_uint* const nodes) -{ - size_t const n = array_length(nodes); - size_t lhs_distance = 0; - for (size_t i = 0; i < n; ++i) - { - lhs_distance += tree.nodes[nodes[i]].distance; - } // for - - size_t const rhs_distance = graph.dom_nodes[part_idx + 1].distance; - if (lhs_distance >= rhs_distance) - { - return 1; // overlap - } // if - - GVA_Variant const lhs = construct_variant(allocator, len_ref, reference, tree, trie, nodes); - - GVA_Variant rhs; - gva_edges(graph.observed.str, - graph.dom_nodes[part_idx], graph.dom_nodes[part_idx + 1], - part_idx == 0, part_idx == array_length(graph.dom_nodes) - 2, - &rhs); - - size_t const distance = variants_distance(allocator, len_ref, reference, rhs, lhs); - gva_string_destroy(allocator, lhs.sequence); - - if (rhs_distance - distance != lhs_distance) - { - return 1; // overlap - } // if - return lhs_distance; -} // multiple_is_contained_distance - - -static inline size_t -prefix_length(size_t const len_lhs, char const lhs[static restrict len_lhs], - size_t const len_rhs, char const rhs[static restrict len_rhs]) -{ - size_t idx = 0; - while (idx < len_lhs && idx < len_rhs && lhs[idx] == rhs[idx]) - { - idx += 1; - } // while - return idx; -} // prefix_length - - -static inline size_t -suffix_length(size_t const len_lhs, char const lhs[static restrict len_lhs], - size_t const len_rhs, char const rhs[static restrict len_rhs]) -{ - size_t idx_lhs = len_lhs; - size_t idx_rhs = len_rhs; - while (idx_lhs > 0 && idx_rhs > 0 && lhs[idx_lhs - 1] == rhs[idx_rhs - 1]) - { - idx_lhs -= 1; - idx_rhs -= 1; - } // while - return len_lhs - idx_lhs; -} // suffix_length - - -static inline GVA_Variant -prefix_trimmed(size_t const len_ref, char const reference[static len_ref], - GVA_Variant const variant) -{ - size_t const len = prefix_length((variant.end - variant.start), reference + variant.start, variant.sequence.len, variant.sequence.str); - return (GVA_Variant) {variant.start + len, variant.end, {variant.sequence.len - len, variant.sequence.str + len}}; -} // prefix_trimmed - - -static inline GVA_Variant -suffix_trimmed(size_t const len_ref, char const reference[static len_ref], - GVA_Variant const variant) -{ - size_t const len = suffix_length((variant.end - variant.start), reference + variant.start, variant.sequence.len, variant.sequence.str); - return (GVA_Variant) {variant.start, variant.end - len, {variant.sequence.len - len, variant.sequence.str}}; -} // suffix_trimmed - - -int vcf_main(int argc, char* argv[static argc]) -{ - if (argc < 3) - { - fprintf(stderr, "usage: %s reference.blob gap\n", argv[0]); - return EXIT_FAILURE; - } // if - - errno = 0; - FILE *stream = fopen(argv[1], "r"); - if (stream == NULL) - { - fprintf(stderr, "error: %s\n", strerror(errno)); - return EXIT_FAILURE; - } // if - - GVA_String reference = gva_fasta_sequence_blob(gva_std_allocator, stream); - fclose(stream); - fprintf(stderr, "reference length: %zu\n", reference.len); - - size_t const gap = atoll(argv[2]); - fprintf(stderr, "gap: %zu\n", gap); - - GVA_Variant* variants = NULL; - GVA_Variant* lss = NULL; - - size_t last = 0; - size_t line_count = 0; - size_t dropped = 0; - size_t distance = 0; - static char line[LINE_SIZE] = {0}; - while (fgets(line, sizeof(line), stdin) != NULL) - { - size_t const len = strlen(line) - 1; - GVA_Variant variant; - if (gva_parse_spdi(len, line, &variant) == 0) - { - fprintf(stderr, "error: SPDI parsing failed at line %zu: %s", line_count + 1, line); - continue; - } // if - - GVA_Variant trimmed = prefix_trimmed(reference.len, reference.str, variant); - - if (array_length(variants) > 0 && trimmed.start < variants[array_length(variants) - 1].end) - { - //fprintf(stderr, "dropped: at line %zu: %s", line_count + 1, line); - dropped += 1; - continue; - } // if - - if (array_length(variants) > 0 && trimmed.start - variants[array_length(variants) - 1].end > gap) - { - GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, array_length(variants) - last, variants + last); - - for (size_t i = 0; i < array_length(graph.dom_nodes) - 1; ++i) - { - GVA_Variant variant; - gva_edges(graph.observed.str, - graph.dom_nodes[i], graph.dom_nodes[i + 1], - i == 0, i == array_length(graph.dom_nodes) - 2, &variant); - //fprintf(stdout, "%u " GVA_VARIANT_FMT_SPDI "\n", graph.dom_nodes[i + 1].distance, GVA_VARIANT_PRINT_SPDI("NC_000001.11", variant)); - distance += graph.dom_nodes[i + 1].distance; - ARRAY_APPEND(gva_std_allocator, lss, gva_variant_dup(gva_std_allocator, variant)); - } // for - - last = array_length(variants); - - gva_string_destroy(gva_std_allocator, graph.observed); - gva_lcs_graph_destroy(gva_std_allocator, graph); - } // if - - ARRAY_APPEND(gva_std_allocator, variants, gva_variant_dup(gva_std_allocator, trimmed)); - line_count += 1; - } // while - if (last < array_length(variants)) - { - GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, array_length(variants) - last, variants + last); - - for (size_t i = 0; i < array_length(graph.dom_nodes) - 1; ++i) - { - GVA_Variant variant; - gva_edges(graph.observed.str, - graph.dom_nodes[i], graph.dom_nodes[i + 1], - i == 0, i == array_length(graph.dom_nodes) - 2, &variant); - //fprintf(stdout, "%u " GVA_VARIANT_FMT_SPDI "\n", graph.dom_nodes[i + 1].distance, GVA_VARIANT_PRINT_SPDI("NC_000001.11", variant)); - distance += graph.dom_nodes[i + 1].distance; - ARRAY_APPEND(gva_std_allocator, lss, gva_variant_dup(gva_std_allocator, variant)); - } // for - - last = array_length(variants); - - gva_string_destroy(gva_std_allocator, graph.observed); - gva_lcs_graph_destroy(gva_std_allocator, graph); - } // if - - fprintf(stderr, "===INPUT===\n"); - fprintf(stderr, "#variants: %zu\n", array_length(variants)); - fprintf(stderr, "#dropped: %zu\n", dropped); - - GVA_String observed = gva_patch(gva_std_allocator, reference.len, reference.str, array_length(variants), variants); - - fasta_blob_write(stdout, observed); - - return EXIT_SUCCESS; -} // vcf_main - - -void -repair_is_contained(GVA_Allocator const allocator, GVA_String const reference, GVA_LCS_Graph const graph, Interval_Tree const tree, Trie const trie, - gva_uint** nodes, gva_uint const part_idx, gva_uint* const included, GVA_Relation* const relation) -{ - size_t const nodes_len = array_length(*nodes); - if (*relation == GVA_IS_CONTAINED && nodes_len == 1) - { - *included += tree.nodes[*nodes[0]].distance; - } // if - else if (*relation == GVA_IS_CONTAINED && nodes_len > 1) - { - size_t const slice_dist = multiple_is_contained_distance(allocator, reference.len, reference.str, - graph, part_idx, tree, trie, *nodes); - if (slice_dist == 1) - { - *included = 1; - *relation = GVA_OVERLAP; - } // if - else - { - *included += slice_dist; - } // else - } // if - *nodes = ARRAY_DESTROY(gva_std_allocator, *nodes); // FIXME -} // repair_is_contained - - +// line: alphanumeric_id SPDI [distance] static bool parse_line(char const line[static LINE_SIZE], - size_t* id_len, GVA_Variant* variant, size_t* distance) + size_t* const len_id, GVA_Variant* const variant, size_t* const distance) { - *id_len = strcspn(line, "\t "); - if (*id_len == 0) + *len_id = strcspn(line, "\t "); + if (*len_id == 0) { return false; } // if - size_t const spdi_len = strcspn(line + *id_len + 1, "\t "); - if (gva_parse_spdi(spdi_len, line + *id_len + 1, variant) == 0) - { - return false; - } // if - - *distance = parse_number(line, &(size_t) {*id_len + spdi_len + 2}); - if (*distance == 0) + size_t const spdi_len = strcspn(line + *len_id + 1, "\n\t "); + if (gva_parse_spdi(spdi_len, line + *len_id + 1, variant) == 0) { return false; } // if + *distance = parse_number(line, &(size_t) {*len_id + spdi_len + 2}); return true; } // parse_line -static bool -parse_line2(char const line[static LINE_SIZE], - size_t* id_len, GVA_Variant* variant) -{ - *id_len = strcspn(line, "\t "); - if (*id_len == 0) - { - fprintf(stderr, "here?!\n"); - return false; - } // if - - size_t const spdi_len = strcspn(line + *id_len + 1, "\n"); - if (gva_parse_spdi(spdi_len, line + *id_len + 1, variant) == 0) - { - fprintf(stderr, "or here?!\n"); - return false; - } // if - - return true; -} // parse_line2 -// - int index_main(int argc, char* argv[static argc]) { @@ -596,7 +179,7 @@ index_main(int argc, char* argv[static argc]) line_count += 1; size_t len_id = 0; GVA_Variant variant; - if (!parse_line2(line, &len_id, &variant)) + if (!parse_line(line, &len_id, &variant, &(size_t) {0})) { fprintf(stderr, "parsing failed at line %zu: %s\n", line_count, line); continue; @@ -627,24 +210,6 @@ index_main(int argc, char* argv[static argc]) } // index_main -// FIXME: to string module? -static char* -strrev(size_t const n, char str[static n]) -{ - size_t i = n - 1; - size_t j = 0; - while (i > j) - { - char const ch = str[i]; - str[i] = str[j]; - str[j] = ch; - i -= 1; - j += 1; - } // while - return str; -} // strrev - - GVA_String vcf2obs(GVA_Allocator const allocator, GVA_String const reference, FILE* stream) { @@ -663,7 +228,7 @@ vcf2obs(GVA_Allocator const allocator, GVA_String const reference, FILE* stream) continue; } // if - GVA_Variant trimmed = prefix_trimmed(reference.len, reference.str, variant); + GVA_Variant const trimmed = gva_variant_prefix_trimmed(reference.len, reference.str, variant); if (array_length(variants) > 0 && trimmed.start < variants[array_length(variants) - 1].end) { @@ -702,8 +267,8 @@ local_supremal(size_t const len_ref, char const reference[static len_ref], GVA_Matches forward = gva_edit_distance_matches(gva_std_allocator, len_ref, reference, len_obs, observed); - reference = strrev(len_ref, (char*) reference); - observed = strrev(len_obs, (char*) observed); + gva_string_reverse((GVA_String) {len_ref, reference}); + gva_string_reverse((GVA_String) {len_obs, observed}); GVA_Matches backward = gva_edit_distance_matches(gva_std_allocator, len_ref, reference, len_obs, observed); @@ -713,8 +278,8 @@ local_supremal(size_t const len_ref, char const reference[static len_ref], exit(EXIT_FAILURE); // FIXME } // if - reference = strrev(len_ref, (char*) reference); - observed = strrev(len_obs, (char*) observed); + gva_string_reverse((GVA_String) {len_ref, reference}); + gva_string_reverse((GVA_String) {len_obs, observed}); size_t sum = 0; size_t prev_lcs_pos = 0; @@ -872,7 +437,7 @@ extract_main(int argc, char* argv[static argc]) GVA_LCS_Graph graph = gva_lcs_graph_init(gva_std_allocator, 31, "CAGATGACAGGGTTGGGCTCAGAGTCAGAGT", 25, "CTCTCATACACACTCTCATCAGATT", 0); fprintf(stderr, "graph distance: %u\n", graph.distance); - lcs_graph_dot(stderr, graph); + gva_lcs_graph_dot(stderr, graph); return EXIT_SUCCESS; } // extract_main @@ -939,9 +504,6 @@ main(int argc, char* argv[static argc]) // return wu_main(argc, argv); // return slice_blob_main(argc, argv); // return fasta_blob_write(argc, argv); - // return vcf_main(argc, argv); - // return dbsnp_main(argc, argv); - // return locals_main(argc, argv); // return extract_main(argc, argv); // return make_ref_blob_main(argc, argv); // return make_obs_blob_main(argc, argv); diff --git a/src/string.c b/src/string.c index 6a49667..6414f29 100644 --- a/src/string.c +++ b/src/string.c @@ -46,3 +46,31 @@ gva_string_dup(GVA_Allocator const allocator, GVA_String const self) { return gva_string_concat(allocator, (GVA_String) {0, NULL}, self); } // gva_string_dup + + +inline void +gva_string_reverse(GVA_String self) +{ + size_t i = self.len - 1; + size_t j = 0; + while (i > j) + { + char const ch = self.str[i]; + ((char*) self.str)[i] = self.str[j]; + ((char*) self.str)[j] = ch; + i -= 1; + j += 1; + } // while +} // gva_string_reverse + + +inline size_t +gva_string_prefix_length(GVA_String const lhs, GVA_String const rhs) +{ + size_t idx = 0; + while (idx < lhs.len && idx < rhs.len && lhs.str[idx] == rhs.str[idx]) + { + idx += 1; + } // while + return idx; +} // gva_string_prefix_length diff --git a/src/utils.c b/src/utils.c index 4aca1cb..753297c 100644 --- a/src/utils.c +++ b/src/utils.c @@ -5,8 +5,10 @@ #include // strcspn #include "../include/allocator.h" // GVA_Allocator +#include "../include/lcs_graph.h" // GVA_LCS_Graph, gva_edges #include "../include/string.h" // GVA_String #include "../include/utils.h" // gva_fasta_sequence +#include "array.h" // array_length GVA_String @@ -48,30 +50,37 @@ gva_fasta_sequence(GVA_Allocator const allocator, FILE* const stream) } // gva_fasta_sequence -static inline void -random_sequence(size_t const len, char sequence[static len]) +void +gva_lcs_graph_dot(FILE* const stream, GVA_LCS_Graph const graph) { - for (size_t i = 0; i < len; ++i) + fprintf(stream, "strict digraph{\nrankdir=LR\nedge[fontname=monospace]\nnode[fixedsize=true,fontname=serif,shape=circle,width=1]\ni[label=\"\",shape=none,width=0]\ni->%u\n", graph.source); + for (size_t i = 0; i < array_length(graph.nodes); ++i) { - sequence[i] = "AC"[rand() % 2]; + fprintf(stream, "%zu[label=\"(%u, %u, %u)\"%s]\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, graph.nodes[i].edges == GVA_NULL ? ",peripheries=2" : ""); + if (graph.nodes[i].lambda != GVA_NULL) + { + fprintf(stream, "%zu->%u[label=\"λ\",style=dashed]\n", i, graph.nodes[i].lambda); + } // if + for (gva_uint j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) + { + GVA_Variant variant; + gva_uint const count = gva_edges(graph.observed.str, + graph.nodes[i], graph.nodes[graph.edges[j].tail], + i == graph.source, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, + &variant); + if (count > 1) + { + fprintf(stream, "%zu->%u[label=\"" GVA_VARIANT_FMT " x %u\",penwidth=2]\n", i, graph.edges[j].tail, GVA_VARIANT_PRINT(variant), count); + } // if + else + { + fprintf(stream, "%zu->%u[label=\"" GVA_VARIANT_FMT "\"]\n", i, graph.edges[j].tail, GVA_VARIANT_PRINT(variant)); + } // else + } // for } // for -} // random_sequence - - -GVA_String -gva_random_sequence(GVA_Allocator const allocator, size_t const min_length, size_t const max_length) -{ - if (max_length < min_length) + for (size_t i = 0; i < array_length(graph.dom_nodes); ++i) { - return (GVA_String) {0, NULL}; - } // if - - size_t const len = rand() % (max_length - min_length + 1) + min_length; - GVA_String sequence = {len, allocator.allocate(allocator.context, NULL, 0, len)}; - if (sequence.str == NULL) - { - return (GVA_String) {0, NULL}; - } // if - random_sequence(len, (char*) sequence.str); - return sequence; -} // gva_random_sequence + fprintf(stream, "%u[penwidth=2]\n", graph.dom_nodes[i].link); + } // for + fprintf(stream, "}\n"); +} // gva_lcs_graph_dot diff --git a/src/variant.c b/src/variant.c index c9894b2..7a4f780 100644 --- a/src/variant.c +++ b/src/variant.c @@ -134,6 +134,15 @@ gva_variant_length(GVA_Variant const variant) } // gva_variant_length +inline GVA_Variant +gva_variant_prefix_trimmed(size_t const len_ref, char const reference[static len_ref], + GVA_Variant const variant) +{ + size_t const len = gva_string_prefix_length((GVA_String) {(variant.end - variant.start), reference + variant.start}, variant.sequence); + return (GVA_Variant) {variant.start + len, variant.end, {variant.sequence.len - len, variant.sequence.str + len}}; +} // gva_variant_prefix_trimmed + + GVA_String gva_patch(GVA_Allocator const allocator, size_t const len_ref, char const reference[static restrict len_ref], From 4713d7aff8cd5812ba22eb91e7a62e05a84cbd6f Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 20 Feb 2026 14:16:03 +0100 Subject: [PATCH 499/704] More cleanup in main --- include/utils.h | 4 +++ src/main.c | 71 +++++++------------------------------------------ src/utils.c | 34 ++++++++++++++++++++++- 3 files changed, 47 insertions(+), 62 deletions(-) diff --git a/include/utils.h b/include/utils.h index e36213d..f03cdb8 100644 --- a/include/utils.h +++ b/include/utils.h @@ -20,6 +20,10 @@ GVA_String gva_fasta_sequence(GVA_Allocator const allocator, FILE* const stream); +GVA_String +gva_fasta_sequence_blob(GVA_Allocator const allocator, FILE* const stream); + + void gva_lcs_graph_dot(FILE* const stream, GVA_LCS_Graph const graph); diff --git a/src/main.c b/src/main.c index dcf3f8e..9641a24 100644 --- a/src/main.c +++ b/src/main.c @@ -1,26 +1,21 @@ #include // errno -#include // CHAR_BIT #include // NULL, size_t #include // FILE, stderr, stdout, fclose, fopen, fprintf -#include // EXIT_* +#include // EXIT_*, atoll #include // strerror, strlen -#include "../include/compare.h" // bitset_fill #include "../include/edit.h" // gva_edit_distance -#include "../include/extractor.h" // gva_canonical #include "../include/index.h" // GVA_Index, gva_index_*, GVA_Result #include "../include/lcs_graph.h" // GVA_LCS_Graph, GVA_Variant, gva_lcs_graph_*, gva_edges #include "../include/std_alloc.h" // gva_std_allocator #include "../include/string.h" // GVA_String, gva_string_destroy #include "../include/types.h" // GVA_NULL, gva_uint -#include "../include/utils.h" // gva_fasta_sequence, gva_lcs_graph_dot +#include "../include/utils.h" // gva_fasta_sequence*, gva_lcs_graph_dot #include "../include/variant.h" // GVA_VARIANT_*, GVA_Variant, gva_parse_spdi -#include "array.h" // ARRAY_DESTROY, array_length +#include "array.h" // ARRAY_*, array_length #include "bitset.h" // bitset_* #include "common.h" // MAX, MIN #include "hash_table.h" // GVA_NOT_FOUND, HASH_TABLE_KEY, hash_table_* -#include "interval_tree.h" // Interval_Tree, interval_tree_* -#include "trie.h" // Trie, trie_* #define LINE_SIZE 8194 @@ -29,51 +24,6 @@ #define REFERENCE_ID "NC_000001.11" -// FIXME: see `match_number` in src/variant.c -static inline size_t -parse_number(char const buffer[static 1], size_t idx[static 1]) -{ - size_t number = 0; - while (buffer[*idx] >= '0' && buffer[*idx] <= '9') - { - number = number * 10 + buffer[*idx] - '0'; - *idx += 1; - } // while - return number; -} // parse_number - - -GVA_String -gva_fasta_sequence_blob(GVA_Allocator const allocator, FILE* const stream) -{ - GVA_String reference = {0, NULL}; - - errno = 0; - if (fread(&reference.len, sizeof(reference.len), 1, stream) != 1) - { - fprintf(stderr, "error: %s\n", strerror(errno)); - return (GVA_String) {0, NULL}; - } // if - - reference.str = allocator.allocate(allocator.context, NULL, 0, reference.len); - if (reference.str == NULL) - { - fprintf(stderr, "OOM\n"); - return (GVA_String) {0, NULL}; - } // if - - errno = 0; - if (fread((char*) reference.str, 1, reference.len, stream) != reference.len) - { - fprintf(stderr, "error: %s\n", strerror(errno)); - gva_string_destroy(allocator, reference); - return (GVA_String) {0, NULL}; - } // if - - return reference; -} // gva_fasta_sequence_blob - - static void fasta_blob_write(FILE* stream, GVA_String const sequence) { @@ -104,13 +54,13 @@ parse_line(char const line[static LINE_SIZE], return false; } // if - size_t const spdi_len = strcspn(line + *len_id + 1, "\n\t "); - if (gva_parse_spdi(spdi_len, line + *len_id + 1, variant) == 0) + size_t const len_spdi = strcspn(line + *len_id + 1, "\n\t "); + if (gva_parse_spdi(len_spdi, line + *len_id + 1, variant) == 0) { return false; } // if - *distance = parse_number(line, &(size_t) {*len_id + spdi_len + 2}); + *distance = atoll(line + *len_id + len_spdi + 2); return true; } // parse_line @@ -323,7 +273,7 @@ local_supremal(size_t const len_ref, char const reference[static len_ref], graph.dom_nodes[i], graph.dom_nodes[i + 1], i == 0, i == array_length(graph.dom_nodes) - 2, &variant); - printf(GVA_VARIANT_FMT_SPDI " %u\n", GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, variant), graph.dom_nodes[i + 1].distance); + printf(GVA_VARIANT_FMT_SPDI " %u\n", GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, variant), graph.dom_nodes[i + 1].distance - graph.dom_nodes[i].distance); } // for gva_lcs_graph_destroy(gva_std_allocator, graph); } // if @@ -421,7 +371,7 @@ int extract_main(int argc, char* argv[static argc]) { errno = 0; - FILE *stream = fopen(argv[1], "r"); + FILE* stream = fopen(argv[1], "r"); if (stream == NULL) { fprintf(stderr, "error: %s\n", strerror(errno)); @@ -453,7 +403,7 @@ make_ref_blob_main(int argc, char* argv[static argc]) } // if errno = 0; - FILE *stream = fopen(argv[1], "r"); + FILE* stream = fopen(argv[1], "r"); if (stream == NULL) { fprintf(stderr, "error: %s\n", strerror(errno)); @@ -480,7 +430,7 @@ make_obs_blob_main(int argc, char* argv[static argc]) } // if errno = 0; - FILE *stream = fopen(argv[1], "r"); + FILE* stream = fopen(argv[1], "r"); if (stream == NULL) { fprintf(stderr, "error: %s\n", strerror(errno)); @@ -502,7 +452,6 @@ int main(int argc, char* argv[static argc]) { // return wu_main(argc, argv); - // return slice_blob_main(argc, argv); // return fasta_blob_write(argc, argv); // return extract_main(argc, argv); // return make_ref_blob_main(argc, argv); diff --git a/src/utils.c b/src/utils.c index 753297c..dc86066 100644 --- a/src/utils.c +++ b/src/utils.c @@ -1,7 +1,8 @@ // NOT FREESTANDING +#include // errno #include // NULL, size_t #include // rand -#include // FILE, fgets +#include // FILE, stderr, fgets, fprintf #include // strcspn #include "../include/allocator.h" // GVA_Allocator @@ -50,6 +51,37 @@ gva_fasta_sequence(GVA_Allocator const allocator, FILE* const stream) } // gva_fasta_sequence +GVA_String +gva_fasta_sequence_blob(GVA_Allocator const allocator, FILE* const stream) +{ + GVA_String reference = {0, NULL}; + + errno = 0; + if (fread(&reference.len, sizeof(reference.len), 1, stream) != 1) + { + fprintf(stderr, "error: %s\n", strerror(errno)); + return (GVA_String) {0, NULL}; + } // if + + reference.str = allocator.allocate(allocator.context, NULL, 0, reference.len); + if (reference.str == NULL) + { + fprintf(stderr, "OOM\n"); + return (GVA_String) {0, NULL}; + } // if + + errno = 0; + if (fread((char*) reference.str, 1, reference.len, stream) != reference.len) + { + fprintf(stderr, "error: %s\n", strerror(errno)); + gva_string_destroy(allocator, reference); + return (GVA_String) {0, NULL}; + } // if + + return reference; +} // gva_fasta_sequence_blob + + void gva_lcs_graph_dot(FILE* const stream, GVA_LCS_Graph const graph) { From 8948564b07bc186fc201505f8f5c1077d516c769 Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 20 Feb 2026 14:21:54 +0100 Subject: [PATCH 500/704] Update tests --- tests/test_array.c | 10 +++++----- tests/test_std_alloc.c | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/test_array.c b/tests/test_array.c index 31fbf5e..12b0d47 100644 --- a/tests/test_array.c +++ b/tests/test_array.c @@ -27,16 +27,16 @@ test_array_append_null(void) { int* a = NULL; - assert(ARRAY_APPEND(gva_std_allocator, a, 0) == 1); + assert(ARRAY_APPEND(gva_std_allocator, a, 0) == 0); assert(array_header(a)->capacity == 1); - assert(ARRAY_APPEND(gva_std_allocator, a, 1) == 2); + assert(ARRAY_APPEND(gva_std_allocator, a, 1) == 1); assert(array_header(a)->capacity == 2); - assert(ARRAY_APPEND(gva_std_allocator, a, 2) == 3); + assert(ARRAY_APPEND(gva_std_allocator, a, 2) == 2); assert(array_header(a)->capacity == 4); - assert(ARRAY_APPEND(gva_std_allocator, a, 3) == 4); + assert(ARRAY_APPEND(gva_std_allocator, a, 3) == 3); assert(array_header(a)->capacity == 4); assert(array_length(a) == 4); @@ -91,4 +91,4 @@ main(int argc, char* argv[static argc]) test_array_usage(); return EXIT_SUCCESS; -} // main \ No newline at end of file +} // main diff --git a/tests/test_std_alloc.c b/tests/test_std_alloc.c index 9b53a08..f7da1c3 100644 --- a/tests/test_std_alloc.c +++ b/tests/test_std_alloc.c @@ -26,4 +26,4 @@ main(int argc, char* argv[static argc]) test_std_allocate(); return EXIT_SUCCESS; -} // main \ No newline at end of file +} // main From 3aa083446b8cb15ae91af593ebeedb4935b79483 Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 23 Feb 2026 11:41:13 +0100 Subject: [PATCH 501/704] Debug print corrected partial results --- src/index.c | 124 +++++++++++++++++++++++++++++++++++----------------- src/main.c | 2 +- 2 files changed, 85 insertions(+), 41 deletions(-) diff --git a/src/index.c b/src/index.c index 6dd6f75..6742c4a 100644 --- a/src/index.c +++ b/src/index.c @@ -11,7 +11,7 @@ // GVA_IS_CONTAINED #include "../include/string.h" // GVA_String #include "../include/types.h" // GVA_NULL, gva_uint -#include "../include/variant.h" // GVA_Variant, gva_variant_* +#include "../include/variant.h" // GVA_Variant, gva_variant_dup #include "array.h" // ARRAY_*, array_length #include "bitset.h" // bitset_* #include "common.h" // ABS, MAX, MIN @@ -20,6 +20,9 @@ #include "trie.h" // Trie, trie_* +#include // DEBUG + + typedef struct { gva_uint link; // X-OR link between interval_idx and allele_idx @@ -48,6 +51,28 @@ struct GVA_Index }; +static inline GVA_Relation +relation_from_included(size_t const included, + size_t const lhs_distance, size_t const rhs_distance, + size_t* const excluded) +{ + *excluded = lhs_distance + rhs_distance - 2 * included; + if (*excluded == 0) + { + return GVA_EQUIVALENT; + } // if + if (rhs_distance == included) + { + return GVA_CONTAINS; + } // if + if (lhs_distance == included) + { + return GVA_IS_CONTAINED; + } // if + return GVA_OVERLAP; +} // relation_from_included + + static inline GVA_Variant variant_from_index(GVA_Index const self[static 1], size_t const idx) { @@ -317,10 +342,17 @@ gva_index_query(GVA_Allocator const allocator, struct Hit { - gva_uint idx; // index into self->join + struct + { + gva_uint start; + gva_uint end; + } join; // index into self->join gva_uint included; // double purpose: distance or included - gva_uint start; // wrt local supremal parts in the query - gva_uint end; + struct + { + gva_uint start; + gva_uint end; + } query; // wrt local supremal parts in the query gva_uint next; }* hits = NULL; @@ -358,10 +390,9 @@ gva_index_query(GVA_Allocator const allocator, gva_uint const tail = ARRAY_APPEND(allocator, hits, ((struct Hit) { - .idx = k, + .join = {k, k + 1}, .included = distance, - .start = i, - .end = i + 1, + .query = {i, i + 1}, .next = GVA_NULL, })); HASH_TABLE_SET(allocator, entries, allele_idx, @@ -376,15 +407,14 @@ gva_index_query(GVA_Allocator const allocator, // Add a new hit to an existing allele entry // - only when this hit is with a different query part than before - if (hits[entries[idx].tail].idx != k) + if (hits[entries[idx].tail].join.start != k) { gva_uint const tail = ARRAY_APPEND(allocator, hits, ((struct Hit) { - .idx = k, + .join = {k, k + 1}, .included = distance, - .start = i, - .end = i + 1, + .query = {i, i + 1}, .next = GVA_NULL, })); // add to end of list @@ -394,7 +424,7 @@ gva_index_query(GVA_Allocator const allocator, // otherwise: update the hit for this query part else { - hits[entries[idx].tail].end = i + 1; + hits[entries[idx].tail].query.end = i + 1; } // else } // for } // for @@ -419,16 +449,18 @@ gva_index_query(GVA_Allocator const allocator, // Look ahead for the same local supremal part in the query GVA_Variant lhs = {0, 0, {0, NULL}}; size_t distance = 0; - while (hits[i].next != GVA_NULL && hits[hits[i].next].start == hits[i].start) + gva_uint start = GVA_NULL; + while (hits[i].next != GVA_NULL && hits[hits[i].next].query.start == hits[i].query.start) { - if (gva_variant_length(lhs) == 0) + if (start == GVA_NULL) { - gva_uint const node_idx = self->join[hits[i].idx].link ^ entries[idx].gva_key; + start = hits[i].join.start; + gva_uint const node_idx = self->join[hits[i].join.start].link ^ entries[idx].gva_key; lhs = gva_variant_dup(allocator, variant_from_index(self, node_idx)); distance = self->intervals.nodes[node_idx].distance; } // if i = hits[i].next; - gva_uint const node_idx = self->join[hits[i].idx].link ^ entries[idx].gva_key; + gva_uint const node_idx = self->join[hits[i].join.start].link ^ entries[idx].gva_key; GVA_Variant const variant = variant_from_index(self, node_idx); lhs.sequence = gva_string_concat(allocator, lhs.sequence, (GVA_String) {variant.start - lhs.end, self->reference.str + lhs.end}); @@ -437,15 +469,16 @@ gva_index_query(GVA_Allocator const allocator, distance += self->intervals.nodes[node_idx].distance; } // while - gva_uint const node_idx = self->join[hits[i].idx].link ^ entries[idx].gva_key; + gva_uint const node_idx = self->join[hits[i].join.start].link ^ entries[idx].gva_key; // single query part has multiple hits - if (gva_variant_length(lhs) != 0) + if (start != GVA_NULL) { // aggregate hits in last hit + hits[i].join.start = start; hits[i].included = variants_with_distance(allocator, self->reference.len, self->reference.str, lhs, distance, - gva_lcs_graph_ls_slice(graph, hits[i].start, hits[i].end), graph.dom_nodes[hits[i].end].distance - graph.dom_nodes[hits[i].start].distance); + gva_lcs_graph_ls_slice(graph, hits[i].query.start, hits[i].query.end), graph.dom_nodes[hits[i].query.end].distance - graph.dom_nodes[hits[i].query.start].distance); // disable aggregated hits except the last if (prev != GVA_NULL) @@ -460,23 +493,23 @@ gva_index_query(GVA_Allocator const allocator, gva_string_destroy(allocator, lhs.sequence); } // if // single hit with multiple query parts - else if (hits[i].end - hits[i].start > 1) + else if (hits[i].query.end - hits[i].query.start > 1) { hits[i].included = variants_with_distance(allocator, self->reference.len, self->reference.str, variant_from_index(self, node_idx), self->intervals.nodes[node_idx].distance, - gva_lcs_graph_ls_slice(graph, hits[i].start, hits[i].end), graph.dom_nodes[hits[i].end].distance - graph.dom_nodes[hits[i].start].distance); + gva_lcs_graph_ls_slice(graph, hits[i].query.start, hits[i].query.end), graph.dom_nodes[hits[i].query.end].distance - graph.dom_nodes[hits[i].query.start].distance); } // if // single hit for single query part, relation is not determined by the distances - else if (ABS((intmax_t) self->intervals.nodes[node_idx].distance - (graph.dom_nodes[hits[i].end].distance - graph.dom_nodes[hits[i].start].distance)) != hits[i].included) + else if (ABS((intmax_t) self->intervals.nodes[node_idx].distance - (graph.dom_nodes[hits[i].query.end].distance - graph.dom_nodes[hits[i].query.start].distance)) != hits[i].included) { hits[i].included = variants_included(allocator, self->reference.len, self->reference.str, variant_from_index(self, node_idx), - gva_lcs_graph_ls_slice(graph, hits[i].start, hits[i].end)); + gva_lcs_graph_ls_slice(graph, hits[i].query.start, hits[i].query.end)); } // if // single hit for single query part, relation is already determined else { - gva_uint const distance = graph.dom_nodes[hits[i].end].distance - graph.dom_nodes[hits[i].start].distance; + gva_uint const distance = graph.dom_nodes[hits[i].query.end].distance - graph.dom_nodes[hits[i].query.start].distance; // equivalent or contains if (self->intervals.nodes[node_idx].distance - distance == hits[i].included) { @@ -506,24 +539,35 @@ gva_index_query(GVA_Allocator const allocator, continue; } // if - GVA_Relation relation; - size_t const excluded = self->alleles[entries[idx].gva_key].distance + graph.distance - 2 * entries[idx].included; - if (excluded == 0) - { - relation = GVA_EQUIVALENT; - } // if - else if (graph.distance == entries[idx].included) - { - relation = GVA_CONTAINS; - } // if - else if (self->alleles[entries[idx].gva_key].distance == entries[idx].included) + size_t excluded = 0; + GVA_Relation const relation = relation_from_included(entries[idx].included, self->alleles[entries[idx].gva_key].distance, graph.distance, &excluded); + + fprintf(stderr, GVA_STRING_FMT " %u %zu %s\n", + GVA_STRING_PRINT(trie_string(self->ids, self->alleles[entries[idx].gva_key].id_idx)), + entries[idx].included, excluded, GVA_RELATION_LABELS[relation]); + + if (entries[idx].head != entries[idx].tail && relation != GVA_EQUIVALENT) { - relation = GVA_IS_CONTAINED; + for (gva_uint i = entries[idx].head; i != GVA_NULL; i = hits[i].next) + { + size_t lhs_distance = 0; + for (gva_uint j = hits[i].join.start; j < hits[i].join.end; ++j) + { + gva_uint const node_idx = self->join[j].link ^ entries[idx].gva_key; + lhs_distance += self->intervals.nodes[node_idx].distance; + } // for + size_t const rhs_distance = graph.dom_nodes[hits[i].query.end].distance - graph.dom_nodes[hits[i].query.start].distance; + size_t excluded = 0; + GVA_Relation const relation = relation_from_included(hits[i].included, lhs_distance, rhs_distance, &excluded); + + fprintf(stderr, " [%u, %u) [%u, %u) %u %zu %s\n", + hits[i].join.start, hits[i].join.end, + hits[i].query.start, hits[i].query.end, + hits[i].included, + excluded, + GVA_RELATION_LABELS[relation]); + } // for } // if - else - { - relation = GVA_OVERLAP; - } // else ARRAY_APPEND(self->allocator, results, ((GVA_Query_Result) diff --git a/src/main.c b/src/main.c index 9641a24..dd97c8d 100644 --- a/src/main.c +++ b/src/main.c @@ -137,7 +137,7 @@ index_main(int argc, char* argv[static argc]) GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &variant); - // fprintf(stderr, "\nQuery (" GVA_STRING_FMT "): " GVA_VARIANT_FMT_SPDI " (%u)\n", GVA_STRING_PRINT(((GVA_String) {id_len, line})), GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, graph.supremal), graph.distance); + fprintf(stderr, "\nQuery (" GVA_STRING_FMT "): " GVA_VARIANT_FMT_SPDI " (%u)\n", GVA_STRING_PRINT(((GVA_String) {len_id, line})), GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, graph.supremal), graph.distance); GVA_Query_Result* results = gva_index_query(gva_std_allocator, index, graph); for (size_t i = 0; i < array_length(results); ++i) { From b452cb8054211160765cfb3f867a2e1b34a8ec15 Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 23 Feb 2026 13:38:57 +0100 Subject: [PATCH 502/704] Prepare for distance and supremal removal from LCS graph --- include/lcs_graph.h | 8 +++++++ src/index.c | 2 +- src/lcs_graph.c | 21 ++++++++++++++++++- src/main.c | 51 +++++++++++++++++++++++++++++++++------------ 4 files changed, 67 insertions(+), 15 deletions(-) diff --git a/include/lcs_graph.h b/include/lcs_graph.h index 8a2cb3f..86eef1a 100644 --- a/include/lcs_graph.h +++ b/include/lcs_graph.h @@ -94,6 +94,14 @@ gva_lcs_graph_ls_slice(GVA_LCS_Graph const self, size_t const start, size_t const end); +size_t +gva_lcs_graph_distance(GVA_LCS_Graph const self); + + +GVA_Variant +gva_lcs_graph_supremal(GVA_LCS_Graph const self); + + gva_uint gva_edges(char const observed[static restrict 1], GVA_Node const head, GVA_Node const tail, diff --git a/src/index.c b/src/index.c index 6742c4a..1a8af7c 100644 --- a/src/index.c +++ b/src/index.c @@ -540,7 +540,7 @@ gva_index_query(GVA_Allocator const allocator, } // if size_t excluded = 0; - GVA_Relation const relation = relation_from_included(entries[idx].included, self->alleles[entries[idx].gva_key].distance, graph.distance, &excluded); + GVA_Relation const relation = relation_from_included(entries[idx].included, self->alleles[entries[idx].gva_key].distance, gva_lcs_graph_distance(graph), &excluded); fprintf(stderr, GVA_STRING_FMT " %u %zu %s\n", GVA_STRING_PRINT(trie_string(self->ids, self->alleles[entries[idx].gva_key].id_idx)), diff --git a/src/lcs_graph.c b/src/lcs_graph.c index a0e1059..a7be708 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -485,12 +485,31 @@ gva_lcs_graph_ls_slice(GVA_LCS_Graph const self, GVA_Variant variant; gva_edges(self.observed.str, self.dom_nodes[start], self.dom_nodes[end], - start == 0, end == array_length(self.dom_nodes) - 2, + start == 0, end == array_length(self.dom_nodes) - 1, &variant); return variant; } // gva_lcs_graph_ls_slice +inline size_t +gva_lcs_graph_distance(GVA_LCS_Graph const self) +{ + return self.dom_nodes[array_length(self.dom_nodes) - 1].distance; +} // gva_lcs_graph_distance + + +inline GVA_Variant +gva_lcs_graph_supremal(GVA_LCS_Graph const self) +{ + GVA_Variant variant = {0, 0, {0, NULL}}; + gva_edges(self.observed.str, + self.dom_nodes[0], self.dom_nodes[array_length(self.dom_nodes) - 1], + true, true, + &variant); + return variant; +} // gva_lcs_graph_supremal + + gva_uint gva_edges(char const observed[static restrict 1], GVA_Node const head, GVA_Node const tail, diff --git a/src/main.c b/src/main.c index dd97c8d..a76df0a 100644 --- a/src/main.c +++ b/src/main.c @@ -1,3 +1,4 @@ +#include // assert #include // errno #include // NULL, size_t #include // FILE, stderr, stdout, fclose, fopen, fprintf @@ -370,24 +371,48 @@ wu_main(int argc, char* argv[static argc]) int extract_main(int argc, char* argv[static argc]) { - errno = 0; - FILE* stream = fopen(argv[1], "r"); - if (stream == NULL) + (void) argv; + + size_t line_count = 0; + static char line[LINE_SIZE] = {0}; + while (fgets(line, sizeof(line), stdin) != NULL) { - fprintf(stderr, "error: %s\n", strerror(errno)); - return EXIT_FAILURE; - } // if + line_count += 1; - GVA_String reference = {0, NULL}; - reference = gva_fasta_sequence(gva_std_allocator, stream); - fclose(stream); + size_t const len_ref = strcspn(line, "\t "); + GVA_String const reference = {len_ref, line}; + size_t const len_obs = strcspn(line + len_ref + 1, "\n\t "); + GVA_String const observed = {len_obs, line + len_ref + 1}; - fprintf(stderr, "reference length: %zu\n", reference.len); + fprintf(stderr, "%zu: " GVA_STRING_FMT " (%zu) " GVA_STRING_FMT " (%zu)\n", line_count, + GVA_STRING_PRINT(reference), reference.len, GVA_STRING_PRINT(observed), observed.len); - GVA_LCS_Graph graph = gva_lcs_graph_init(gva_std_allocator, 31, "CAGATGACAGGGTTGGGCTCAGAGTCAGAGT", 25, "CTCTCATACACACTCTCATCAGATT", 0); - fprintf(stderr, "graph distance: %u\n", graph.distance); + GVA_LCS_Graph graph = gva_lcs_graph_init(gva_std_allocator, + reference.len, reference.str, observed.len, observed.str, 0); - gva_lcs_graph_dot(stderr, graph); + fprintf(stderr, " distance: %u\n", graph.distance); + fprintf(stderr, " #nodes: %zu\n", array_length(graph.nodes)); + for (size_t i = 0; i < array_length(graph.nodes); ++i) + { + fprintf(stderr, " %zu: (%u, %u, %u)\n", i, + graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length); + } // for + fprintf(stderr, " #edges: %zu\n", array_length(graph.edges)); + fprintf(stderr, " #dom_nodes: %zu\n", array_length(graph.dom_nodes)); + for (size_t i = 0; i < array_length(graph.dom_nodes); ++i) + { + fprintf(stderr, " %zu: (%u, %u, %u) %u\n", i, + graph.dom_nodes[i].row, graph.dom_nodes[i].col, graph.dom_nodes[i].length, + graph.dom_nodes[i].distance); + } // for + + fprintf(stderr, " supremal: " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(graph.supremal)); + + assert(gva_lcs_graph_distance(graph) == graph.distance); + assert(gva_variant_eq(gva_lcs_graph_supremal(graph), graph.supremal)); + + gva_lcs_graph_destroy(gva_std_allocator, graph); + } // while return EXIT_SUCCESS; } // extract_main From e0ef738279b090a2270b4dcd4983e3844ad805f3 Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 23 Feb 2026 15:43:48 +0100 Subject: [PATCH 503/704] Distances, supremals and local supremals checked with Python --- src/main.c | 41 ++++++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/src/main.c b/src/main.c index a76df0a..1180b78 100644 --- a/src/main.c +++ b/src/main.c @@ -1,4 +1,3 @@ -#include // assert #include // errno #include // NULL, size_t #include // FILE, stderr, stdout, fclose, fopen, fprintf @@ -138,7 +137,7 @@ index_main(int argc, char* argv[static argc]) GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &variant); - fprintf(stderr, "\nQuery (" GVA_STRING_FMT "): " GVA_VARIANT_FMT_SPDI " (%u)\n", GVA_STRING_PRINT(((GVA_String) {len_id, line})), GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, graph.supremal), graph.distance); + fprintf(stderr, "\nQuery (" GVA_STRING_FMT "): " GVA_VARIANT_FMT_SPDI " (%zu)\n", GVA_STRING_PRINT(((GVA_String) {len_id, line})), GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, gva_lcs_graph_supremal(graph)), gva_lcs_graph_distance(graph)); GVA_Query_Result* results = gva_index_query(gva_std_allocator, index, graph); for (size_t i = 0; i < array_length(results); ++i) { @@ -272,7 +271,7 @@ local_supremal(size_t const len_ref, char const reference[static len_ref], GVA_Variant variant; gva_edges(graph.observed.str, graph.dom_nodes[i], graph.dom_nodes[i + 1], - i == 0, i == array_length(graph.dom_nodes) - 2, + i == 0, i == array_length(graph.dom_nodes) - 2, // FIXME: check &variant); printf(GVA_VARIANT_FMT_SPDI " %u\n", GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, variant), graph.dom_nodes[i + 1].distance - graph.dom_nodes[i].distance); } // for @@ -306,7 +305,7 @@ wu_main(int argc, char* argv[static argc]) GVA_String observed = {strlen(argv[2]), argv[2]}; GVA_LCS_Graph graph = gva_lcs_graph_init(gva_std_allocator, reference.len, reference.str, observed.len, observed.str, 0); - // lcs_graph_dot(stderr, graph); + // gva_lcs_graph_dot(stderr, graph); for (size_t i = 0; i < array_length(graph.dom_nodes) - 1; ++i) { GVA_Variant part; @@ -316,7 +315,7 @@ wu_main(int argc, char* argv[static argc]) &part); fprintf(stderr, GVA_VARIANT_FMT " %u\n", GVA_VARIANT_PRINT(part), graph.dom_nodes[i + 1].distance); } // for - fprintf(stderr, GVA_VARIANT_FMT " %u\n", GVA_VARIANT_PRINT(graph.supremal), graph.distance); + fprintf(stderr, GVA_VARIANT_FMT " %zu\n", GVA_VARIANT_PRINT(gva_lcs_graph_supremal(graph)), gva_lcs_graph_distance(graph)); gva_lcs_graph_destroy(gva_std_allocator, graph); @@ -384,32 +383,40 @@ extract_main(int argc, char* argv[static argc]) size_t const len_obs = strcspn(line + len_ref + 1, "\n\t "); GVA_String const observed = {len_obs, line + len_ref + 1}; - fprintf(stderr, "%zu: " GVA_STRING_FMT " (%zu) " GVA_STRING_FMT " (%zu)\n", line_count, + fprintf(stdout, "%zu: " GVA_STRING_FMT " (%zu) " GVA_STRING_FMT " (%zu)\n", line_count, GVA_STRING_PRINT(reference), reference.len, GVA_STRING_PRINT(observed), observed.len); GVA_LCS_Graph graph = gva_lcs_graph_init(gva_std_allocator, reference.len, reference.str, observed.len, observed.str, 0); - fprintf(stderr, " distance: %u\n", graph.distance); - fprintf(stderr, " #nodes: %zu\n", array_length(graph.nodes)); + fprintf(stdout, " distance: %zu\n", gva_lcs_graph_distance(graph)); + fprintf(stdout, " #nodes: %zu\n", array_length(graph.nodes)); for (size_t i = 0; i < array_length(graph.nodes); ++i) { - fprintf(stderr, " %zu: (%u, %u, %u)\n", i, + fprintf(stdout, " %zu: (%u, %u, %u)\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length); } // for - fprintf(stderr, " #edges: %zu\n", array_length(graph.edges)); - fprintf(stderr, " #dom_nodes: %zu\n", array_length(graph.dom_nodes)); + fprintf(stdout, " #edges: %zu\n", array_length(graph.edges)); + fprintf(stdout, " #dom_nodes: %zu\n", array_length(graph.dom_nodes)); for (size_t i = 0; i < array_length(graph.dom_nodes); ++i) { - fprintf(stderr, " %zu: (%u, %u, %u) %u\n", i, + if (i > 0) + { + GVA_Variant variant = {0, 0, {0, NULL}}; + gva_edges(graph.observed.str, + graph.dom_nodes[i - 1], graph.dom_nodes[i], + i - 1 == 0, i == array_length(graph.dom_nodes) - 1, + &variant); + fprintf(stdout, " " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(variant)); + } // if + fprintf(stdout, " %zu: (%u, %u, %u) %u\n", i, graph.dom_nodes[i].row, graph.dom_nodes[i].col, graph.dom_nodes[i].length, graph.dom_nodes[i].distance); } // for - fprintf(stderr, " supremal: " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(graph.supremal)); + fprintf(stdout, " supremal: " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(gva_lcs_graph_supremal(graph))); - assert(gva_lcs_graph_distance(graph) == graph.distance); - assert(gva_variant_eq(gva_lcs_graph_supremal(graph), graph.supremal)); + gva_lcs_graph_dot(stdout, graph); gva_lcs_graph_destroy(gva_std_allocator, graph); } // while @@ -478,8 +485,8 @@ main(int argc, char* argv[static argc]) { // return wu_main(argc, argv); // return fasta_blob_write(argc, argv); - // return extract_main(argc, argv); + return extract_main(argc, argv); // return make_ref_blob_main(argc, argv); // return make_obs_blob_main(argc, argv); - return index_main(argc, argv); + // return index_main(argc, argv); } // main From 142094ed42d0d4a224880a176547bc46367bd666 Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 23 Feb 2026 15:52:13 +0100 Subject: [PATCH 504/704] Removed distance from LCS graph --- include/lcs_graph.h | 3 +-- src/compare.c | 6 +++--- src/lcs_graph.c | 3 +-- src/main.c | 4 ++-- 4 files changed, 7 insertions(+), 9 deletions(-) diff --git a/include/lcs_graph.h b/include/lcs_graph.h index 86eef1a..3cf0934 100644 --- a/include/lcs_graph.h +++ b/include/lcs_graph.h @@ -21,7 +21,7 @@ typedef struct } GVA_Edge; -// FIXME: refactor: typedef struct { row; col; lenght; } GVA_Match; +// FIXME: refactor: typedef struct { row; col; length; } GVA_Match; // see also: src/align.h @@ -57,7 +57,6 @@ typedef struct GVA_Variant supremal; // FIXME: remove GVA_String observed; // FIXME: ownership and destroy gva_uint source; - gva_uint distance; // FIXME: remove } GVA_LCS_Graph; diff --git a/src/compare.c b/src/compare.c index 30743ca..44d4207 100644 --- a/src/compare.c +++ b/src/compare.c @@ -67,17 +67,17 @@ gva_compare_graphs(GVA_Allocator const allocator, gva_string_destroy(allocator, observed_lhs); } // else - if (lhs.distance + rhs.distance == distance) + if (gva_lcs_graph_distance(lhs) + gva_lcs_graph_distance(rhs) == distance) { return GVA_DISJOINT; } // if - if (lhs.distance - rhs.distance == distance) + if (gva_lcs_graph_distance(lhs) - gva_lcs_graph_distance(rhs) == distance) { return GVA_CONTAINS; } // if - if (rhs.distance - lhs.distance == distance) + if (gva_lcs_graph_distance(rhs) - gva_lcs_graph_distance(lhs) == distance) { return GVA_IS_CONTAINED; } // if diff --git a/src/lcs_graph.c b/src/lcs_graph.c index a7be708..37b0a0b 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -28,7 +28,6 @@ gva_lcs_graph_init(GVA_Allocator const allocator, .supremal = {0, 0, {0, observed}}, .observed = {len_obs, observed}, .source = GVA_NULL, - .distance = distance, }; if (lcs.nodes == NULL || distance == 0) @@ -369,7 +368,7 @@ gva_lcs_graph_from_variants(GVA_Allocator const allocator, if (observed == NULL) { gva_string_destroy(allocator, variant.sequence); - return (GVA_LCS_Graph) {NULL, NULL, NULL, {0, 0, {0, NULL}}, {0, NULL}, GVA_NULL, 0}; + return (GVA_LCS_Graph) {NULL, NULL, NULL, {0, 0, {0, NULL}}, {0, NULL}, GVA_NULL}; } // if memcpy(observed, reference + start, variant.start - start); diff --git a/src/main.c b/src/main.c index 1180b78..cec42db 100644 --- a/src/main.c +++ b/src/main.c @@ -485,8 +485,8 @@ main(int argc, char* argv[static argc]) { // return wu_main(argc, argv); // return fasta_blob_write(argc, argv); - return extract_main(argc, argv); + // return extract_main(argc, argv); // return make_ref_blob_main(argc, argv); // return make_obs_blob_main(argc, argv); - // return index_main(argc, argv); + return index_main(argc, argv); } // main From 29169afa95f97cb4ae609f4aae8612103372b561 Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 23 Feb 2026 16:00:59 +0100 Subject: [PATCH 505/704] Removed supremal from LCS graph --- include/lcs_graph.h | 11 +++++------ src/compare.c | 31 +++++++++++++++++-------------- src/lcs_graph.c | 14 ++++---------- 3 files changed, 26 insertions(+), 30 deletions(-) diff --git a/include/lcs_graph.h b/include/lcs_graph.h index 3cf0934..9c15111 100644 --- a/include/lcs_graph.h +++ b/include/lcs_graph.h @@ -51,12 +51,11 @@ typedef struct // entry point in the `nodes` array. typedef struct { - GVA_Node* nodes; - GVA_Edge* edges; - GVA_Node* dom_nodes; - GVA_Variant supremal; // FIXME: remove - GVA_String observed; // FIXME: ownership and destroy - gva_uint source; + GVA_Node* nodes; + GVA_Edge* edges; + GVA_Node* dom_nodes; + GVA_String observed; // FIXME: ownership and destroy + gva_uint source; } GVA_LCS_Graph; diff --git a/src/compare.c b/src/compare.c index 44d4207..fa6a5f1 100644 --- a/src/compare.c +++ b/src/compare.c @@ -18,21 +18,24 @@ gva_compare_graphs(GVA_Allocator const allocator, size_t const len_ref, char const reference[static len_ref], GVA_LCS_Graph const lhs, GVA_LCS_Graph const rhs) { - if (gva_variant_eq(lhs.supremal, rhs.supremal)) + GVA_Variant const supremal_lhs = gva_lcs_graph_supremal(lhs); + GVA_Variant const supremal_rhs = gva_lcs_graph_supremal(rhs); + + if (gva_variant_eq(supremal_lhs, supremal_rhs)) { return GVA_EQUIVALENT; } // if - if (lhs.supremal.start > rhs.supremal.end || rhs.supremal.start > lhs.supremal.end) + if (supremal_lhs.start > supremal_rhs.end || supremal_rhs.start > supremal_lhs.end) { return GVA_DISJOINT; } // if - size_t const start = MIN(lhs.supremal.start, rhs.supremal.start); - size_t const end = MAX(lhs.supremal.end, rhs.supremal.end); + size_t const start = MIN(supremal_lhs.start, supremal_rhs.start); + size_t const end = MAX(supremal_lhs.end, supremal_rhs.end); - size_t const len_lhs = (lhs.supremal.start - start) + lhs.supremal.sequence.len + (end - lhs.supremal.end); - size_t const len_rhs = (rhs.supremal.start - start) + rhs.supremal.sequence.len + (end - rhs.supremal.end); + size_t const len_lhs = (supremal_lhs.start - start) + supremal_lhs.sequence.len + (end - supremal_lhs.end); + size_t const len_rhs = (supremal_rhs.start - start) + supremal_rhs.sequence.len + (end - supremal_rhs.end); size_t distance = 0; if (len_lhs == 0) @@ -54,13 +57,13 @@ gva_compare_graphs(GVA_Allocator const allocator, return GVA_DISJOINT; // FIXME: OOM } // if - memcpy((char*) observed_lhs.str, reference + start, lhs.supremal.start - start); - memcpy((char*) observed_lhs.str + lhs.supremal.start - start, lhs.supremal.sequence.str, lhs.supremal.sequence.len); - memcpy((char*) observed_lhs.str + lhs.supremal.start - start + lhs.supremal.sequence.len, reference + lhs.supremal.end, end - lhs.supremal.end); + memcpy((char*) observed_lhs.str, reference + start, supremal_lhs.start - start); + memcpy((char*) observed_lhs.str + supremal_lhs.start - start, supremal_lhs.sequence.str, supremal_lhs.sequence.len); + memcpy((char*) observed_lhs.str + supremal_lhs.start - start + supremal_lhs.sequence.len, reference + supremal_lhs.end, end - supremal_lhs.end); - memcpy((char*) observed_rhs.str, reference + start, rhs.supremal.start - start); - memcpy((char*) observed_rhs.str + rhs.supremal.start - start, rhs.supremal.sequence.str, rhs.supremal.sequence.len); - memcpy((char*) observed_rhs.str + rhs.supremal.start - start + rhs.supremal.sequence.len, reference + rhs.supremal.end, end - rhs.supremal.end); + memcpy((char*) observed_rhs.str, reference + start, supremal_rhs.start - start); + memcpy((char*) observed_rhs.str + supremal_rhs.start - start, supremal_rhs.sequence.str, supremal_rhs.sequence.len); + memcpy((char*) observed_rhs.str + supremal_rhs.start - start + supremal_rhs.sequence.len, reference + supremal_rhs.end, end - supremal_rhs.end); distance = gva_edit_distance(allocator, observed_lhs.len, observed_lhs.str, observed_rhs.len, observed_rhs.str); gva_string_destroy(allocator, observed_rhs); @@ -95,8 +98,8 @@ gva_compare_graphs(GVA_Allocator const allocator, size_t* rhs_gs = bitset_init(allocator, len); size_t* rhs_ts = bitset_init(allocator, len); - size_t const start_intersection = MAX(lhs.supremal.start, rhs.supremal.start); - size_t const end_intersection = MIN(lhs.supremal.end, rhs.supremal.end); + size_t const start_intersection = MAX(supremal_lhs.start, supremal_rhs.start); + size_t const end_intersection = MIN(supremal_lhs.end, supremal_rhs.end); gva_lcs_graph_uniq_atomics(lhs, start, start_intersection, end_intersection, lhs_dels, lhs_as, lhs_cs, lhs_gs, lhs_ts); gva_lcs_graph_uniq_atomics(rhs, start, start_intersection, end_intersection, rhs_dels, rhs_as, rhs_cs, rhs_gs, rhs_ts); diff --git a/src/lcs_graph.c b/src/lcs_graph.c index 37b0a0b..6e584d2 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -25,7 +25,6 @@ gva_lcs_graph_init(GVA_Allocator const allocator, GVA_LCS_Graph graph = { - .supremal = {0, 0, {0, observed}}, .observed = {len_obs, observed}, .source = GVA_NULL, }; @@ -75,7 +74,6 @@ gva_lcs_graph_init(GVA_Allocator const allocator, .distance = distance, .link = sink, })); - graph.supremal = (GVA_Variant) {offset, len_ref + offset, {len_obs, observed}}; return graph; } // if @@ -316,11 +314,6 @@ gva_lcs_graph_init(GVA_Allocator const allocator, graph.nodes[source.idx].length -= graph.dom_nodes[0].length; graph.nodes[sink.idx].length -= graph.dom_nodes[array_length(graph.dom_nodes) - 1].length; - - gva_edges(graph.observed.str, - graph.dom_nodes[0], graph.dom_nodes[array_length(graph.dom_nodes) - 1], - true, true, - &graph.supremal); } // if graph.source = source.idx; @@ -368,7 +361,7 @@ gva_lcs_graph_from_variants(GVA_Allocator const allocator, if (observed == NULL) { gva_string_destroy(allocator, variant.sequence); - return (GVA_LCS_Graph) {NULL, NULL, NULL, {0, 0, {0, NULL}}, {0, NULL}, GVA_NULL}; + return (GVA_LCS_Graph) {NULL}; } // if memcpy(observed, reference + start, variant.start - start); @@ -376,9 +369,10 @@ gva_lcs_graph_from_variants(GVA_Allocator const allocator, memcpy(observed + variant.start - start + variant.sequence.len, reference + variant.end, end - variant.end); GVA_LCS_Graph graph = gva_lcs_graph_init(allocator, end - start, reference + start, len, observed, start); + GVA_Variant const supremal = gva_lcs_graph_supremal(graph); - if ((graph.supremal.start > start || graph.supremal.start == 0) && - (graph.supremal.end < end || graph.supremal.end == len_ref)) + if ((supremal.start > start || supremal.start == 0) && + (supremal.end < end || supremal.end == len_ref)) { // FIXME: observed is now owned by graph gva_string_destroy(allocator, variant.sequence); From 7c6bf43fa66f5f96786f707462772941511b36eb Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 23 Feb 2026 16:46:08 +0100 Subject: [PATCH 506/704] Refactored to GVA_Match --- Makefile | 2 +- include/lcs_graph.h | 44 +++++++--------- include/types.h | 8 +++ src/align.c | 8 +-- src/align.h | 6 +-- src/extractor.c | 28 ++++++---- src/lcs_graph.c | 122 ++++++++++++++++++++------------------------ src/main.c | 8 +-- src/utils.c | 4 +- 9 files changed, 110 insertions(+), 120 deletions(-) diff --git a/Makefile b/Makefile index 146acdd..7ca3f14 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ TEST_COVS = $(TESTS:.c=.c.gcov) TARGET = a.out CC = gcc -CFLAGS = -std=c11 -march=native -Wall -Wextra -Wpedantic -fanalyzer +CFLAGS = -std=c99 -march=native -Wall -Wextra -Wpedantic -fanalyzer MEMCHECK = valgrind -q --leak-check=full --error-exitcode=1 diff --git a/include/lcs_graph.h b/include/lcs_graph.h index 9c15111..a17d52c 100644 --- a/include/lcs_graph.h +++ b/include/lcs_graph.h @@ -7,7 +7,7 @@ #include "allocator.h" // GVA_Allocator #include "string.h" // GVA_String -#include "types.h" // gva_uint +#include "types.h" // GVA_Match, gva_uint #include "variant.h" // GVA_Variant @@ -21,41 +21,35 @@ typedef struct } GVA_Edge; -// FIXME: refactor: typedef struct { row; col; length; } GVA_Match; -// see also: src/align.h - - -// Internal: The triple (`row`, `col`, `length`) uniquely defines each +// Internal: The `GVA_Match` structure uniquely defines each // node in the graph. Its outgoing edges are found in the edges array of // graph as a singly linked list with `edges` as entry point. // A possible `lambda` edge is given as an index to another node. typedef struct { - gva_uint row; - gva_uint col; - gva_uint length; - union - { - gva_uint edges; - gva_uint distance; - }; - union - { - gva_uint lambda; - gva_uint link; - }; + GVA_Match match; + gva_uint edges; + gva_uint lambda; } GVA_Node; +typedef struct +{ + GVA_Match match; + gva_uint distance; + gva_uint link; +} GVA_Dom_Node; + + // The LCS graph stores arrays of nodes and edges with `source` as the // entry point in the `nodes` array. typedef struct { - GVA_Node* nodes; - GVA_Edge* edges; - GVA_Node* dom_nodes; - GVA_String observed; // FIXME: ownership and destroy - gva_uint source; + GVA_Node* nodes; + GVA_Edge* edges; + GVA_Dom_Node* dom_nodes; + GVA_String observed; // FIXME: ownership and destroy + gva_uint source; } GVA_LCS_Graph; @@ -102,7 +96,7 @@ gva_lcs_graph_supremal(GVA_LCS_Graph const self); gva_uint gva_edges(char const observed[static restrict 1], - GVA_Node const head, GVA_Node const tail, + GVA_Match const head, GVA_Match const tail, bool const is_source, bool const is_sink, GVA_Variant variant[static restrict 1]); diff --git a/include/types.h b/include/types.h index d14bd7f..6c1a28b 100644 --- a/include/types.h +++ b/include/types.h @@ -19,4 +19,12 @@ typedef uint32_t gva_uint; static gva_uint const GVA_NULL = UINT32_MAX; +typedef struct +{ + gva_uint row; + gva_uint col; + gva_uint length; +} GVA_Match; + + #endif // GVA_TYPES_H diff --git a/src/align.c b/src/align.c index c8799c8..23f6a8c 100644 --- a/src/align.c +++ b/src/align.c @@ -78,9 +78,7 @@ expand(Context const context, gva_uint const idx = ARRAY_APPEND(context.allocator, lcs->nodes, ((LCS_Node) { - .row = match_row + context.offset, - .col = match_col, - .length = length, + .match = {match_row + context.offset, match_col, length}, .idx = GVA_NULL, .next = GVA_NULL, })); @@ -125,9 +123,7 @@ expand(Context const context, gva_uint const idx = ARRAY_APPEND(context.allocator, lcs->nodes, ((LCS_Node) { - .row = match_row + context.offset, - .col = match_col, - .length = length, + .match = {match_row + context.offset, match_col, length}, .idx = GVA_NULL, .next = GVA_NULL, })); diff --git a/src/align.h b/src/align.h index b0adcd9..0d9f77c 100644 --- a/src/align.h +++ b/src/align.h @@ -6,14 +6,12 @@ #include // size_t #include "../include/allocator.h" // GVA_Allocator -#include "../include/types.h" // gva_uint +#include "../include/types.h" // GVA_Match, gva_uint typedef struct { - gva_uint row; - gva_uint col; - gva_uint length; + GVA_Match match; gva_uint incoming : sizeof(gva_uint) * CHAR_BIT - 1; gva_uint moved : 1; gva_uint idx; diff --git a/src/extractor.c b/src/extractor.c index 6783ed2..18c5d9b 100644 --- a/src/extractor.c +++ b/src/extractor.c @@ -2,7 +2,7 @@ #include "../include/extractor.h" // gva_canonical #include "../include/lcs_graph.h" // GVA_LCS_Graph, gva_edges -#include "../include/types.h" // GVA_NULL, gva_uint +#include "../include/types.h" // GVA_NULL, GVA_Match, gva_uint #include "array.h" // ARRAY_APPEND, array_length #include "common.h" // MAX, MIN @@ -114,7 +114,10 @@ gva_canonical(GVA_Allocator const allocator, GVA_LCS_Graph const graph) { // add regular successors in queue order GVA_Variant variant; - gva_uint const count = gva_edges(graph.observed.str, graph.nodes[head], graph.nodes[edge_tail], head == graph.source, edge_tail == 0, &variant); + gva_uint const count = gva_edges(graph.observed.str, + graph.nodes[head].match, graph.nodes[edge_tail].match, + head == graph.source, edge_tail == 0, + &variant); visited[edge_tail] = (LCA_Table) {head, rank, visited[head].depth + 1, variant.start, variant.end + count - 1, tail, GVA_NULL}; rank += 1; visited[tail].next = edge_tail; @@ -123,7 +126,10 @@ gva_canonical(GVA_Allocator const allocator, GVA_LCS_Graph const graph) else if (visited[edge_tail].depth - 1 == visited[head].depth) { GVA_Variant variant; - gva_uint const count = gva_edges(graph.observed.str, graph.nodes[head], graph.nodes[edge_tail], head == graph.source, edge_tail == 0, &variant); + gva_uint const count = gva_edges(graph.observed.str, + graph.nodes[head].match, graph.nodes[edge_tail].match, + head == graph.source, edge_tail == 0, + &variant); visited[edge_tail].start = MIN(visited[edge_tail].start, variant.start); visited[edge_tail].lca = lca(&visited[edge_tail].start, visited[edge_tail].lca, head, length, visited); visited[edge_tail].end = MAX(visited[edge_tail].end, variant.end + count - 1); @@ -138,13 +144,15 @@ gva_canonical(GVA_Allocator const allocator, GVA_LCS_Graph const graph) if (head != GVA_NULL && visited[tail].start != GVA_NULL) { // we need to skip lambda edges: start && end == -1 - gva_uint const start_offset = visited[tail].start - graph.nodes[head].row; - gva_uint const end_offset = visited[tail].end - graph.nodes[tail].row; - GVA_Variant const variant = { - visited[tail].start, visited[tail].end, { - (graph.nodes[tail].col + end_offset) - (graph.nodes[head].col + start_offset), - graph.observed.str + graph.nodes[head].col + start_offset - } + gva_uint const start_offset = visited[tail].start - graph.nodes[head].match.row; + gva_uint const end_offset = visited[tail].end - graph.nodes[tail].match.row; + GVA_Variant const variant = + { + visited[tail].start, visited[tail].end, + { + (graph.nodes[tail].match.col + end_offset) - (graph.nodes[head].match.col + start_offset), + graph.observed.str + graph.nodes[head].match.col + start_offset, + }, }; ARRAY_APPEND(allocator, canonical, variant); } // if diff --git a/src/lcs_graph.c b/src/lcs_graph.c index 6e584d2..b3e124d 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -5,7 +5,8 @@ #include // memcpy #include "../include/allocator.h" // GVA_Allocator -#include "../include/lcs_graph.h" // GVA_LCS_Graph, gva_lcs_graph_* +#include "../include/lcs_graph.h" // GVA_LCS_Graph, GVA_Dom_Node, + // GVA_Edge, GVA_Node, gva_lcs_graph_* #include "../include/string.h" // GVA_String, gva_string_* #include "../include/variant.h" // GVA_Variant, gva_variant_length #include "align.h" // LCS_Alignment, lcs_align @@ -34,8 +35,7 @@ gva_lcs_graph_init(GVA_Allocator const allocator, gva_uint const sink = ARRAY_APPEND(allocator, graph.nodes, ((GVA_Node) { - .row = len_ref + offset, - .col = len_obs, + .match = {len_ref + offset, len_obs}, .edges = GVA_NULL, .lambda = GVA_NULL, })); @@ -43,9 +43,9 @@ gva_lcs_graph_init(GVA_Allocator const allocator, if (distance == 0) { graph.source = sink; - graph.nodes[sink].row = 0; - graph.nodes[sink].col = 0; - ARRAY_APPEND(allocator, graph.dom_nodes, ((GVA_Node) {.link = graph.source})); + graph.nodes[sink].match.row = 0; + graph.nodes[sink].match.col = 0; + ARRAY_APPEND(allocator, graph.dom_nodes, ((GVA_Dom_Node) {.link = graph.source})); lcs.index = allocator.allocate(allocator.context, lcs.index, lcs.length * sizeof(*lcs.index), 0); lcs.nodes = ARRAY_DESTROY(allocator, lcs.nodes); @@ -55,22 +55,21 @@ gva_lcs_graph_init(GVA_Allocator const allocator, graph.source = ARRAY_APPEND(allocator, graph.nodes, ((GVA_Node) { - .row = offset, + .match.row = offset, .edges = ARRAY_APPEND(allocator, graph.edges, ((GVA_Edge) {sink, GVA_NULL})), .lambda = GVA_NULL, })); ARRAY_APPEND(allocator, graph.dom_nodes, - ((GVA_Node) + ((GVA_Dom_Node) { - .row = offset, + .match.row = offset, .link = graph.source, })); ARRAY_APPEND(allocator, graph.dom_nodes, - ((GVA_Node) + ((GVA_Dom_Node) { - .row = len_ref + offset, - .col = len_obs, + .match = {len_ref + offset, len_obs}, .distance = distance, .link = sink, })); @@ -79,14 +78,13 @@ gva_lcs_graph_init(GVA_Allocator const allocator, gva_uint tail_idx = lcs.index[lcs.length - 1].tail; LCS_Node sink = lcs.nodes[tail_idx]; - if (sink.row + sink.length == len_ref + offset && sink.col + sink.length == len_obs) + if (sink.match.row + sink.match.length == len_ref + offset && + sink.match.col + sink.match.length == len_obs) { lcs.nodes[tail_idx].idx = ARRAY_APPEND(allocator, graph.nodes, ((GVA_Node) { - .row = sink.row, - .col = sink.col, - .length = sink.length, + .match = sink.match, .edges = GVA_NULL, .lambda = GVA_NULL, })); @@ -95,13 +93,11 @@ gva_lcs_graph_init(GVA_Allocator const allocator, } // if else { - sink = (LCS_Node) {.row = len_ref + offset, .col = len_obs, .length = 0}; + sink = (LCS_Node) {.match = {len_ref + offset, len_obs}}; sink.idx = ARRAY_APPEND(allocator, graph.nodes, ((GVA_Node) { - .row = sink.row, - .col = sink.col, - .length = sink.length, + .match = sink.match, .edges = GVA_NULL, .lambda = GVA_NULL, })); @@ -112,9 +108,7 @@ gva_lcs_graph_init(GVA_Allocator const allocator, lcs.nodes[i].idx = ARRAY_APPEND(allocator, graph.nodes, ((GVA_Node) { - .row = lcs.nodes[i].row, - .col = lcs.nodes[i].col, - .length = lcs.nodes[i].length, + .match = lcs.nodes[i].match, .edges = ARRAY_APPEND(allocator, graph.edges, ((GVA_Edge) {sink.idx, GVA_NULL})), .lambda = GVA_NULL, })); @@ -134,7 +128,7 @@ gva_lcs_graph_init(GVA_Allocator const allocator, lcs.index[i].tail = j; lcs.index[i].count += 1; - lcs.index[i].offset = graph.nodes[tail->idx].length - tail->length; + lcs.index[i].offset = graph.nodes[tail->idx].match.length - tail->match.length; gva_uint here = GVA_NULL; for (gva_uint k = lcs.index[i - 1].head; k != GVA_NULL; k = lcs.nodes[k].next) @@ -142,8 +136,8 @@ gva_lcs_graph_init(GVA_Allocator const allocator, LCS_Node* const restrict head = &lcs.nodes[k]; if (k >= j || - head->row + head->length >= tail->row + tail->length || - head->col + head->length >= tail->col + tail->length) + head->match.row + head->match.length >= tail->match.row + tail->match.length || + head->match.col + head->match.length >= tail->match.col + tail->match.length) { continue; } // if @@ -155,27 +149,23 @@ gva_lcs_graph_init(GVA_Allocator const allocator, head->idx = ARRAY_APPEND(allocator, graph.nodes, ((GVA_Node) { - .row = head->row, - .col = head->col, - .length = head->length, + .match = head->match, .edges = ARRAY_APPEND(allocator, graph.edges, ((GVA_Edge) {tail->idx, GVA_NULL})), .lambda = split_idx })); head->moved = false; head->incoming = 0; - graph.nodes[split_idx].row += head->length; - graph.nodes[split_idx].col += head->length; - graph.nodes[split_idx].length -= head->length; + graph.nodes[split_idx].match.row += head->match.length; + graph.nodes[split_idx].match.col += head->match.length; + graph.nodes[split_idx].match.length -= head->match.length; } // if else if (head->idx == GVA_NULL) { head->idx = ARRAY_APPEND(allocator, graph.nodes, ((GVA_Node) { - .row = head->row, - .col = head->col, - .length = head->length, + .match = head->match, .edges = ARRAY_APPEND(allocator, graph.edges, ((GVA_Edge) {tail->idx, GVA_NULL})), .lambda = GVA_NULL })); @@ -191,9 +181,9 @@ gva_lcs_graph_init(GVA_Allocator const allocator, } // if } // for - if (tail->length > 1) + if (tail->match.length > 1) { - tail->length -= 1; + tail->match.length -= 1; tail->moved = true; if (here != GVA_NULL) { @@ -212,23 +202,21 @@ gva_lcs_graph_init(GVA_Allocator const allocator, gva_uint head_idx = lcs.index[0].head; LCS_Node source = lcs.nodes[head_idx]; - if (source.row == offset && source.col == 0) + if (source.match.row == offset && source.match.col == 0) { lcs.index[0].tail = head_idx; lcs.index[0].count += 1; - lcs.index[0].offset = graph.nodes[source.idx].length - source.length; + lcs.index[0].offset = graph.nodes[source.idx].match.length - source.match.length; head_idx = source.next; } // if else { - source = (LCS_Node) {.row = offset, .col = 0, .length = 0}; + source = (LCS_Node) {.match.row = offset}; source.idx = ARRAY_APPEND(allocator, graph.nodes, ((GVA_Node) { - .row = source.row, - .col = source.col, - .length = source.length, + .match = source.match, .edges = GVA_NULL, .lambda = GVA_NULL, })); @@ -242,9 +230,9 @@ gva_lcs_graph_init(GVA_Allocator const allocator, lcs.index[0].tail = i; lcs.index[0].count += 1; - lcs.index[0].offset = graph.nodes[lcs.nodes[i].idx].length - lcs.nodes[i].length; + lcs.index[0].offset = graph.nodes[lcs.nodes[i].idx].match.length - lcs.nodes[i].match.length; - if (source.length == 0 || !lcs.nodes[i].moved) + if (source.match.length == 0 || !lcs.nodes[i].moved) { graph.nodes[source.idx].edges = ARRAY_APPEND(allocator, graph.edges, ((GVA_Edge) @@ -257,9 +245,9 @@ gva_lcs_graph_init(GVA_Allocator const allocator, // start constructing the local supremal ARRAY_APPEND(allocator, graph.dom_nodes, - ((GVA_Node) + ((GVA_Dom_Node) { - .row = offset, + .match.row = offset, .link = source.idx, })); gva_uint prev = lcs.index[0].tail; @@ -275,21 +263,20 @@ gva_lcs_graph_init(GVA_Allocator const allocator, // start new if (lcs.index[i].tail != prev) { - gva_uint const pos = graph.nodes[lcs.nodes[lcs.index[i].tail].idx].length - lcs.index[i].offset - 1; + gva_uint const pos = graph.nodes[lcs.nodes[lcs.index[i].tail].idx].match.length - lcs.index[i].offset - 1; ARRAY_APPEND(allocator, graph.dom_nodes, - ((GVA_Node) + ((GVA_Dom_Node) { - .row = lcs.nodes[lcs.index[i].tail].row + pos, - .col = lcs.nodes[lcs.index[i].tail].col + pos, - .distance = lcs.nodes[lcs.index[i].tail].row + pos - offset + - lcs.nodes[lcs.index[i].tail].col + pos - 2 * i, + .match = {lcs.nodes[lcs.index[i].tail].match.row + pos, lcs.nodes[lcs.index[i].tail].match.col + pos}, + .distance = lcs.nodes[lcs.index[i].tail].match.row + pos - offset + + lcs.nodes[lcs.index[i].tail].match.col + pos - 2 * i, .link = lcs.nodes[lcs.index[i].tail].idx, })); prev = lcs.index[i].tail; } // if - graph.dom_nodes[array_length(graph.dom_nodes) - 1].length += 1; + graph.dom_nodes[array_length(graph.dom_nodes) - 1].match.length += 1; } // if } // for @@ -297,10 +284,9 @@ gva_lcs_graph_init(GVA_Allocator const allocator, if (graph.dom_nodes[array_length(graph.dom_nodes) - 1].link != sink.idx) { ARRAY_APPEND(allocator, graph.dom_nodes, - ((GVA_Node) + ((GVA_Dom_Node) { - .row = sink.row + sink.length, - .col = sink.col + sink.length, + .match = {sink.match.row + sink.match.length, sink.match.col + sink.match.length}, .distance = distance, .link = sink.idx, })); @@ -309,11 +295,11 @@ gva_lcs_graph_init(GVA_Allocator const allocator, // construct supremal if (graph.dom_nodes != NULL) { - graph.nodes[source.idx].row += graph.dom_nodes[0].length; - graph.nodes[source.idx].col += graph.dom_nodes[0].length; - graph.nodes[source.idx].length -= graph.dom_nodes[0].length; + graph.nodes[source.idx].match.row += graph.dom_nodes[0].match.length; + graph.nodes[source.idx].match.col += graph.dom_nodes[0].match.length; + graph.nodes[source.idx].match.length -= graph.dom_nodes[0].match.length; - graph.nodes[sink.idx].length -= graph.dom_nodes[array_length(graph.dom_nodes) - 1].length; + graph.nodes[sink.idx].match.length -= graph.dom_nodes[array_length(graph.dom_nodes) - 1].match.length; } // if graph.source = source.idx; @@ -426,21 +412,21 @@ gva_lcs_graph_uniq_atomics(GVA_LCS_Graph const self, { for (size_t i = 0; i < array_length(self.nodes); ++i) { - if (self.nodes[i].row > end) + if (self.nodes[i].match.row > end) { continue; } // if for (gva_uint j = self.nodes[i].edges; j != GVA_NULL; j = self.edges[j].next) { - if (self.nodes[self.edges[j].tail].row + self.nodes[self.edges[j].tail].length < start) + if (self.nodes[self.edges[j].tail].match.row + self.nodes[self.edges[j].tail].match.length < start) { continue; } // if GVA_Variant variant; gva_uint const count = gva_edges(self.observed.str, - self.nodes[i], self.nodes[self.edges[j].tail], + self.nodes[i].match, self.nodes[self.edges[j].tail].match, i == self.source, self.nodes[self.edges[j].tail].edges == GVA_NULL, &variant); @@ -477,7 +463,7 @@ gva_lcs_graph_ls_slice(GVA_LCS_Graph const self, { GVA_Variant variant; gva_edges(self.observed.str, - self.dom_nodes[start], self.dom_nodes[end], + self.dom_nodes[start].match, self.dom_nodes[end].match, start == 0, end == array_length(self.dom_nodes) - 1, &variant); return variant; @@ -494,9 +480,9 @@ gva_lcs_graph_distance(GVA_LCS_Graph const self) inline GVA_Variant gva_lcs_graph_supremal(GVA_LCS_Graph const self) { - GVA_Variant variant = {0, 0, {0, NULL}}; + GVA_Variant variant = {0}; gva_edges(self.observed.str, - self.dom_nodes[0], self.dom_nodes[array_length(self.dom_nodes) - 1], + self.dom_nodes[0].match, self.dom_nodes[array_length(self.dom_nodes) - 1].match, true, true, &variant); return variant; @@ -505,7 +491,7 @@ gva_lcs_graph_supremal(GVA_LCS_Graph const self) gva_uint gva_edges(char const observed[static restrict 1], - GVA_Node const head, GVA_Node const tail, + GVA_Match const head, GVA_Match const tail, bool const is_source, bool const is_sink, GVA_Variant variant[static restrict 1]) { diff --git a/src/main.c b/src/main.c index cec42db..8d87930 100644 --- a/src/main.c +++ b/src/main.c @@ -270,7 +270,7 @@ local_supremal(size_t const len_ref, char const reference[static len_ref], { GVA_Variant variant; gva_edges(graph.observed.str, - graph.dom_nodes[i], graph.dom_nodes[i + 1], + graph.dom_nodes[i].match, graph.dom_nodes[i + 1].match, i == 0, i == array_length(graph.dom_nodes) - 2, // FIXME: check &variant); printf(GVA_VARIANT_FMT_SPDI " %u\n", GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, variant), graph.dom_nodes[i + 1].distance - graph.dom_nodes[i].distance); @@ -394,7 +394,7 @@ extract_main(int argc, char* argv[static argc]) for (size_t i = 0; i < array_length(graph.nodes); ++i) { fprintf(stdout, " %zu: (%u, %u, %u)\n", i, - graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length); + graph.nodes[i].match.row, graph.nodes[i].match.col, graph.nodes[i].match.length); } // for fprintf(stdout, " #edges: %zu\n", array_length(graph.edges)); fprintf(stdout, " #dom_nodes: %zu\n", array_length(graph.dom_nodes)); @@ -404,13 +404,13 @@ extract_main(int argc, char* argv[static argc]) { GVA_Variant variant = {0, 0, {0, NULL}}; gva_edges(graph.observed.str, - graph.dom_nodes[i - 1], graph.dom_nodes[i], + graph.dom_nodes[i - 1].match, graph.dom_nodes[i].match, i - 1 == 0, i == array_length(graph.dom_nodes) - 1, &variant); fprintf(stdout, " " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(variant)); } // if fprintf(stdout, " %zu: (%u, %u, %u) %u\n", i, - graph.dom_nodes[i].row, graph.dom_nodes[i].col, graph.dom_nodes[i].length, + graph.dom_nodes[i].match.row, graph.dom_nodes[i].match.col, graph.dom_nodes[i].match.length, graph.dom_nodes[i].distance); } // for diff --git a/src/utils.c b/src/utils.c index dc86066..a5f1ac6 100644 --- a/src/utils.c +++ b/src/utils.c @@ -88,7 +88,7 @@ gva_lcs_graph_dot(FILE* const stream, GVA_LCS_Graph const graph) fprintf(stream, "strict digraph{\nrankdir=LR\nedge[fontname=monospace]\nnode[fixedsize=true,fontname=serif,shape=circle,width=1]\ni[label=\"\",shape=none,width=0]\ni->%u\n", graph.source); for (size_t i = 0; i < array_length(graph.nodes); ++i) { - fprintf(stream, "%zu[label=\"(%u, %u, %u)\"%s]\n", i, graph.nodes[i].row, graph.nodes[i].col, graph.nodes[i].length, graph.nodes[i].edges == GVA_NULL ? ",peripheries=2" : ""); + fprintf(stream, "%zu[label=\"(%u, %u, %u)\"%s]\n", i, graph.nodes[i].match.row, graph.nodes[i].match.col, graph.nodes[i].match.length, graph.nodes[i].edges == GVA_NULL ? ",peripheries=2" : ""); if (graph.nodes[i].lambda != GVA_NULL) { fprintf(stream, "%zu->%u[label=\"λ\",style=dashed]\n", i, graph.nodes[i].lambda); @@ -97,7 +97,7 @@ gva_lcs_graph_dot(FILE* const stream, GVA_LCS_Graph const graph) { GVA_Variant variant; gva_uint const count = gva_edges(graph.observed.str, - graph.nodes[i], graph.nodes[graph.edges[j].tail], + graph.nodes[i].match, graph.nodes[graph.edges[j].tail].match, i == graph.source, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, &variant); if (count > 1) From 43ccb1bfe63b273f6c1bba95c512960e2a333743 Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 23 Feb 2026 17:05:50 +0100 Subject: [PATCH 507/704] Structure init style --- src/align.c | 2 +- src/edit.c | 4 ++-- src/index.c | 2 +- src/interval_tree.c | 2 +- src/lcs_graph.c | 5 ++--- src/main.c | 4 ++-- src/string.c | 6 +++--- src/trie.c | 4 ++-- src/utils.c | 36 ++++++++++++++++++------------------ src/variant.c | 4 ++-- 10 files changed, 34 insertions(+), 35 deletions(-) diff --git a/src/align.c b/src/align.c index 23f6a8c..9f32610 100644 --- a/src/align.c +++ b/src/align.c @@ -155,7 +155,7 @@ lcs_align(GVA_Allocator const allocator, intmax_t const delta = len_obs - len_ref; size_t const size = len_ref + len_obs + 3; - LCS_Alignment lcs = {0, NULL, NULL}; + LCS_Alignment lcs = {0}; lcs.index = allocator.allocate(allocator.context, NULL, 0, MIN(len_ref, len_obs) * sizeof(*lcs.index)); diff --git a/src/edit.c b/src/edit.c index 3ea3658..f85cbf0 100644 --- a/src/edit.c +++ b/src/edit.c @@ -112,7 +112,7 @@ onp_compare_matches(GVA_Allocator const allocator, intmax_t* const restrict fp = allocator.allocate(allocator.context, NULL, 0, size * sizeof(*fp)); if (fp == NULL) { - return (GVA_Matches) {NULL, NULL, 0, -1}; + return (GVA_Matches) {NULL}; } // if for (intmax_t i = -1; i <= delta; ++i) @@ -131,7 +131,7 @@ onp_compare_matches(GVA_Allocator const allocator, result.uniq = allocator.allocate(allocator.context, result.uniq, sizeof(*result.uniq) * m, 0); result.matches = allocator.allocate(allocator.context, result.matches, sizeof(*result.matches) * m, 0); allocator.allocate(allocator.context, fp, size * sizeof(*fp), 0); - return (GVA_Matches) {NULL, NULL, 0, -1}; + return (GVA_Matches) {NULL}; } // if size_t p = 0; diff --git a/src/index.c b/src/index.c index 1a8af7c..e0d9fc1 100644 --- a/src/index.c +++ b/src/index.c @@ -447,7 +447,7 @@ gva_index_query(GVA_Allocator const allocator, for (gva_uint i = entries[idx].head; i != GVA_NULL; i = hits[i].next) { // Look ahead for the same local supremal part in the query - GVA_Variant lhs = {0, 0, {0, NULL}}; + GVA_Variant lhs = {0}; size_t distance = 0; gva_uint start = GVA_NULL; while (hits[i].next != GVA_NULL && hits[hits[i].next].query.start == hits[i].query.start) diff --git a/src/interval_tree.c b/src/interval_tree.c index 4ca3277..aecba61 100644 --- a/src/interval_tree.c +++ b/src/interval_tree.c @@ -11,7 +11,7 @@ inline Interval_Tree interval_tree_init(void) { - return (Interval_Tree) {NULL, GVA_NULL}; + return (Interval_Tree) {.root = GVA_NULL}; } // interval_tree_init diff --git a/src/lcs_graph.c b/src/lcs_graph.c index b3e124d..3c2cc74 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -292,7 +292,7 @@ gva_lcs_graph_init(GVA_Allocator const allocator, })); } // if - // construct supremal + // update source and sink according to the supremal if (graph.dom_nodes != NULL) { graph.nodes[source.idx].match.row += graph.dom_nodes[0].match.length; @@ -316,7 +316,6 @@ gva_lcs_graph_destroy(GVA_Allocator const allocator, GVA_LCS_Graph self) self.nodes = ARRAY_DESTROY(allocator, self.nodes); self.edges = ARRAY_DESTROY(allocator, self.edges); self.dom_nodes = ARRAY_DESTROY(allocator, self.dom_nodes); - // FIXME: ownership of observed } // gva_lcs_graph_destroy @@ -325,7 +324,7 @@ gva_lcs_graph_from_variants(GVA_Allocator const allocator, size_t const len_ref, char const reference[static restrict len_ref], size_t const n, GVA_Variant const variants[static restrict n]) { - GVA_Variant variant = {variants[0].start, variants[n - 1].end, {0, NULL}}; + GVA_Variant variant = {.start = variants[0].start, .end = variants[n - 1].end}; variant.sequence = gva_string_concat(allocator, variant.sequence, variants[0].sequence); for (size_t i = 1; i < n; ++i) { diff --git a/src/main.c b/src/main.c index 8d87930..af4b4c7 100644 --- a/src/main.c +++ b/src/main.c @@ -82,7 +82,7 @@ index_main(int argc, char* argv[static argc]) return EXIT_FAILURE; } // if - GVA_String reference = {0, NULL}; + GVA_String reference = {0}; reference = gva_fasta_sequence_blob(gva_std_allocator, stream); fclose(stream); @@ -402,7 +402,7 @@ extract_main(int argc, char* argv[static argc]) { if (i > 0) { - GVA_Variant variant = {0, 0, {0, NULL}}; + GVA_Variant variant = {0}; gva_edges(graph.observed.str, graph.dom_nodes[i - 1].match, graph.dom_nodes[i].match, i - 1 == 0, i == array_length(graph.dom_nodes) - 1, diff --git a/src/string.c b/src/string.c index 6414f29..2bc408b 100644 --- a/src/string.c +++ b/src/string.c @@ -11,7 +11,7 @@ gva_string_init(GVA_Allocator const allocator, size_t const len) GVA_String string = {len, allocator.allocate(allocator.context, NULL, 0, len)}; if (string.str == NULL) { - return (GVA_String) {0, NULL}; + return (GVA_String) {0}; } // if return string; } // gva_string_init @@ -32,7 +32,7 @@ gva_string_concat(GVA_Allocator const allocator, GVA_String lhs, GVA_String cons lhs.str = allocator.allocate(allocator.context, (char*) lhs.str, lhs.len, len); if (lhs.str == NULL) { - return (GVA_String) {0, NULL}; + return (GVA_String) {0}; } // if memcpy((char*) lhs.str + lhs.len, rhs.str, rhs.len); @@ -44,7 +44,7 @@ gva_string_concat(GVA_Allocator const allocator, GVA_String lhs, GVA_String cons inline GVA_String gva_string_dup(GVA_Allocator const allocator, GVA_String const self) { - return gva_string_concat(allocator, (GVA_String) {0, NULL}, self); + return gva_string_concat(allocator, (GVA_String) {0}, self); } // gva_string_dup diff --git a/src/trie.c b/src/trie.c index f3a1abf..4f4be4d 100644 --- a/src/trie.c +++ b/src/trie.c @@ -11,7 +11,7 @@ inline Trie trie_init(void) { - return (Trie) {{0, NULL}, NULL, GVA_NULL}; + return (Trie) {.root = GVA_NULL}; } // trie_init @@ -136,7 +136,7 @@ trie_string(Trie const self, size_t const idx) { if (idx >= array_length(self.nodes)) { - return (GVA_String) {0, NULL}; + return (GVA_String) {0}; } // if return (GVA_String) {self.nodes[idx].end - self.nodes[idx].start, self.strings.str + self.nodes[idx].start}; } //trie_string diff --git a/src/utils.c b/src/utils.c index a5f1ac6..1c94c62 100644 --- a/src/utils.c +++ b/src/utils.c @@ -17,57 +17,57 @@ gva_fasta_sequence(GVA_Allocator const allocator, FILE* const stream) { static size_t const FASTA_LINE_SIZE = 65536; size_t capacity = FASTA_LINE_SIZE; - GVA_String seq = {0, allocator.allocate(allocator.context, NULL, 0, capacity)}; - if (seq.str == NULL) + GVA_String sequence = {0, allocator.allocate(allocator.context, NULL, 0, capacity)}; + if (sequence.str == NULL) { - return seq; + return (GVA_String) {0}; } // if - while (fgets((char*) seq.str + seq.len, FASTA_LINE_SIZE, stream) != NULL) + while (fgets((char*) sequence.str + sequence.len, FASTA_LINE_SIZE, stream) != NULL) { - if (seq.str[seq.len] == '>') + if (sequence.str[sequence.len] == '>') { - if (seq.len == 0) + if (sequence.len == 0) { continue; } // if break; } // if - seq.len += strcspn(seq.str + seq.len, "\n"); + sequence.len += strcspn(sequence.str + sequence.len, "\n"); - if (capacity - FASTA_LINE_SIZE < seq.len) + if (capacity - FASTA_LINE_SIZE < sequence.len) { - seq.str = allocator.allocate(allocator.context, (char*) seq.str, capacity, capacity + FASTA_LINE_SIZE); - if (seq.str == NULL) + sequence.str = allocator.allocate(allocator.context, (char*) sequence.str, capacity, capacity + FASTA_LINE_SIZE); + if (sequence.str == NULL) { - seq.len = 0; - return seq; + sequence.len = 0; + return sequence; } // if capacity += FASTA_LINE_SIZE; } // if } // while - seq.str = allocator.allocate(allocator.context, (char*) seq.str, capacity, seq.len); - return seq; + sequence.str = allocator.allocate(allocator.context, (char*) sequence.str, capacity, sequence.len); + return sequence; } // gva_fasta_sequence GVA_String gva_fasta_sequence_blob(GVA_Allocator const allocator, FILE* const stream) { - GVA_String reference = {0, NULL}; + GVA_String reference = {0}; errno = 0; if (fread(&reference.len, sizeof(reference.len), 1, stream) != 1) { fprintf(stderr, "error: %s\n", strerror(errno)); - return (GVA_String) {0, NULL}; + return (GVA_String) {0}; } // if reference.str = allocator.allocate(allocator.context, NULL, 0, reference.len); if (reference.str == NULL) { fprintf(stderr, "OOM\n"); - return (GVA_String) {0, NULL}; + return (GVA_String) {0}; } // if errno = 0; @@ -75,7 +75,7 @@ gva_fasta_sequence_blob(GVA_Allocator const allocator, FILE* const stream) { fprintf(stderr, "error: %s\n", strerror(errno)); gva_string_destroy(allocator, reference); - return (GVA_String) {0, NULL}; + return (GVA_String) {0}; } // if return reference; diff --git a/src/variant.c b/src/variant.c index 7a4f780..e7ebc22 100644 --- a/src/variant.c +++ b/src/variant.c @@ -65,7 +65,7 @@ size_t gva_parse_spdi(size_t const len, char const expression[static restrict len], GVA_Variant variants[static restrict 1]) { - variants[0] = (GVA_Variant) {0, 0, {0, NULL}}; + variants[0] = (GVA_Variant) {0}; // sequence size_t idx = match_until(len, expression, ':'); if (idx >= len) @@ -148,7 +148,7 @@ gva_patch(GVA_Allocator const allocator, size_t const len_ref, char const reference[static restrict len_ref], size_t const n, GVA_Variant const variants[static restrict n]) { - GVA_String observed = {0, NULL}; + GVA_String observed = {0}; size_t start = 0; for (size_t i = 0; i < n; ++i) { From 85fbc85eb5f31d305ecd362e4e565810b9ef7b39 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 24 Feb 2026 08:26:17 +0100 Subject: [PATCH 508/704] Optionally destroy observed from the LCS graph --- include/lcs_graph.h | 3 ++- src/index.c | 10 ++++++---- src/lcs_graph.c | 11 ++++++++--- src/main.c | 9 ++++----- 4 files changed, 20 insertions(+), 13 deletions(-) diff --git a/include/lcs_graph.h b/include/lcs_graph.h index a17d52c..57a226a 100644 --- a/include/lcs_graph.h +++ b/include/lcs_graph.h @@ -61,7 +61,8 @@ gva_lcs_graph_init(GVA_Allocator const allocator, void -gva_lcs_graph_destroy(GVA_Allocator const allocator, GVA_LCS_Graph self); +gva_lcs_graph_destroy(GVA_Allocator const allocator, + GVA_LCS_Graph self, bool const observed); GVA_LCS_Graph diff --git a/src/index.c b/src/index.c index e0d9fc1..7c69a3e 100644 --- a/src/index.c +++ b/src/index.c @@ -182,10 +182,10 @@ variants_included(GVA_Allocator const allocator, size_t const end_intersection = MIN(lhs.end, rhs.end); gva_lcs_graph_uniq_atomics(lhs_graph, start, start_intersection, end_intersection, lhs_dels, lhs_as, lhs_cs, lhs_gs, lhs_ts); - gva_lcs_graph_destroy(allocator, lhs_graph); + gva_lcs_graph_destroy(allocator, lhs_graph, false); gva_lcs_graph_uniq_atomics(rhs_graph, start, start_intersection, end_intersection, rhs_dels, rhs_as, rhs_cs, rhs_gs, rhs_ts); - gva_lcs_graph_destroy(allocator, rhs_graph); + gva_lcs_graph_destroy(allocator, rhs_graph, false); size_t const included = bitset_intersection_cnt(lhs_dels, rhs_dels) + @@ -249,9 +249,11 @@ gva_index_init(GVA_Allocator const allocator, index->intervals = interval_tree_init(); index->inserted = trie_init(); + index->ids = trie_init(); - index->join = NULL; + index->alleles = NULL; + index->join = NULL; return index; } // gva_index_init @@ -268,8 +270,8 @@ gva_index_destroy(GVA_Index* const self) interval_tree_destroy(self->allocator, &self->intervals); trie_destroy(self->allocator, &self->inserted); trie_destroy(self->allocator, &self->ids); - self->join = ARRAY_DESTROY(self->allocator, self->join); self->alleles = ARRAY_DESTROY(self->allocator, self->alleles); + self->join = ARRAY_DESTROY(self->allocator, self->join); return self->allocator.allocate(self->allocator.context, self, sizeof(*self), 0); } // gva_index_destroy diff --git a/src/lcs_graph.c b/src/lcs_graph.c index 3c2cc74..2cf1929 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -311,11 +311,16 @@ gva_lcs_graph_init(GVA_Allocator const allocator, inline void -gva_lcs_graph_destroy(GVA_Allocator const allocator, GVA_LCS_Graph self) +gva_lcs_graph_destroy(GVA_Allocator const allocator, + GVA_LCS_Graph self, bool const observed) { self.nodes = ARRAY_DESTROY(allocator, self.nodes); self.edges = ARRAY_DESTROY(allocator, self.edges); self.dom_nodes = ARRAY_DESTROY(allocator, self.dom_nodes); + if (observed) + { + gva_string_destroy(allocator, self.observed); + } // if } // gva_lcs_graph_destroy @@ -359,12 +364,12 @@ gva_lcs_graph_from_variants(GVA_Allocator const allocator, if ((supremal.start > start || supremal.start == 0) && (supremal.end < end || supremal.end == len_ref)) { - // FIXME: observed is now owned by graph + // observed is now owned by graph gva_string_destroy(allocator, variant.sequence); return graph; } // if - gva_lcs_graph_destroy(allocator, graph); + gva_lcs_graph_destroy(allocator, graph, false); old_len = len; offset *= 2; // OVERFLOW diff --git a/src/main.c b/src/main.c index af4b4c7..501bdd6 100644 --- a/src/main.c +++ b/src/main.c @@ -149,8 +149,7 @@ index_main(int argc, char* argv[static argc]) } // for ARRAY_DESTROY(gva_std_allocator, results); - gva_string_destroy(gva_std_allocator, graph.observed); - gva_lcs_graph_destroy(gva_std_allocator, graph); + gva_lcs_graph_destroy(gva_std_allocator, graph, true); } // while index = gva_index_destroy(index); @@ -271,11 +270,11 @@ local_supremal(size_t const len_ref, char const reference[static len_ref], GVA_Variant variant; gva_edges(graph.observed.str, graph.dom_nodes[i].match, graph.dom_nodes[i + 1].match, - i == 0, i == array_length(graph.dom_nodes) - 2, // FIXME: check + i == 0, i + 1 == array_length(graph.dom_nodes) - 1, &variant); printf(GVA_VARIANT_FMT_SPDI " %u\n", GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, variant), graph.dom_nodes[i + 1].distance - graph.dom_nodes[i].distance); } // for - gva_lcs_graph_destroy(gva_std_allocator, graph); + gva_lcs_graph_destroy(gva_std_allocator, graph, false); } // if if (forward.distance != sum) @@ -418,7 +417,7 @@ extract_main(int argc, char* argv[static argc]) gva_lcs_graph_dot(stdout, graph); - gva_lcs_graph_destroy(gva_std_allocator, graph); + gva_lcs_graph_destroy(gva_std_allocator, graph, false); } // while return EXIT_SUCCESS; From ef90eeb1248fad61cef9305396e7139ab1ef4d7f Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 24 Feb 2026 08:29:59 +0100 Subject: [PATCH 509/704] More on FIXMEs --- include/lcs_graph.h | 2 +- src/index.c | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/include/lcs_graph.h b/include/lcs_graph.h index 57a226a..27ea208 100644 --- a/include/lcs_graph.h +++ b/include/lcs_graph.h @@ -48,7 +48,7 @@ typedef struct GVA_Node* nodes; GVA_Edge* edges; GVA_Dom_Node* dom_nodes; - GVA_String observed; // FIXME: ownership and destroy + GVA_String observed; gva_uint source; } GVA_LCS_Graph; diff --git a/src/index.c b/src/index.c index 7c69a3e..03298d8 100644 --- a/src/index.c +++ b/src/index.c @@ -334,13 +334,15 @@ GVA_Query_Result* gva_index_query(GVA_Allocator const allocator, GVA_Index* const self, GVA_LCS_Graph const graph) { + static size_t const INITIAL_SIZE = 1024; + struct Allele_Entry { HASH_TABLE_KEY; // index into self->alleles gva_uint included; gva_uint head; // singly linked list in hits gva_uint tail; - }* entries = hash_table_init(allocator, 1024, sizeof(*entries)); // FIXME: magic number + }* entries = hash_table_init(allocator, INITIAL_SIZE, sizeof(*entries)); struct Hit { @@ -533,6 +535,7 @@ gva_index_query(GVA_Allocator const allocator, } // for // Phase 3: determine relation per allele based on included + // FIXME: shouldn't this be in the outer-loop above? GVA_Query_Result* results = NULL; for (size_t idx = 0; idx < array_header(entries)->capacity; ++idx) { From 9e97d7fde1ec4cfdae20b361dda52c7ca5d2cfab Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 24 Feb 2026 08:44:46 +0100 Subject: [PATCH 510/704] Fixed confusing - 2 --- src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.c b/src/main.c index 501bdd6..ed06fe5 100644 --- a/src/main.c +++ b/src/main.c @@ -310,7 +310,7 @@ wu_main(int argc, char* argv[static argc]) GVA_Variant part; gva_edges(graph.observed.str, graph.dom_nodes[i], graph.dom_nodes[i + 1], - i == 0, i == array_length(graph.dom_nodes) - 2, + i == 0, i + 1 == array_length(graph.dom_nodes) - 1, &part); fprintf(stderr, GVA_VARIANT_FMT " %u\n", GVA_VARIANT_PRINT(part), graph.dom_nodes[i + 1].distance); } // for From 59dcc097f4556aeb0456e7e3ae34296be7276f57 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Tue, 24 Feb 2026 13:22:49 +0100 Subject: [PATCH 511/704] supremal in terms of local supremal. --- include/lcs_graph.h | 2 +- src/index.c | 8 ++++---- src/lcs_graph.c | 11 +++-------- 3 files changed, 8 insertions(+), 13 deletions(-) diff --git a/include/lcs_graph.h b/include/lcs_graph.h index 27ea208..2d050c3 100644 --- a/include/lcs_graph.h +++ b/include/lcs_graph.h @@ -83,7 +83,7 @@ gva_lcs_graph_uniq_atomics(GVA_LCS_Graph const self, GVA_Variant -gva_lcs_graph_ls_slice(GVA_LCS_Graph const self, +gva_lcs_graph_local_supremal(GVA_LCS_Graph const self, size_t const start, size_t const end); diff --git a/src/index.c b/src/index.c index 03298d8..d9e1074 100644 --- a/src/index.c +++ b/src/index.c @@ -366,7 +366,7 @@ gva_index_query(GVA_Allocator const allocator, // and quickly eject disjoint candidates based on distance for (size_t i = 0; i < array_length(graph.dom_nodes) - 1; ++i) { - GVA_Variant const variant = gva_lcs_graph_ls_slice(graph, i, i + 1); + GVA_Variant const variant = gva_lcs_graph_local_supremal(graph, i, i + 1); gva_uint* intervals = interval_tree_intersection(allocator, self->intervals, variant.start, variant.end); for (size_t j = 0; j < array_length(intervals); ++j) @@ -482,7 +482,7 @@ gva_index_query(GVA_Allocator const allocator, hits[i].join.start = start; hits[i].included = variants_with_distance(allocator, self->reference.len, self->reference.str, lhs, distance, - gva_lcs_graph_ls_slice(graph, hits[i].query.start, hits[i].query.end), graph.dom_nodes[hits[i].query.end].distance - graph.dom_nodes[hits[i].query.start].distance); + gva_lcs_graph_local_supremal(graph, hits[i].query.start, hits[i].query.end), graph.dom_nodes[hits[i].query.end].distance - graph.dom_nodes[hits[i].query.start].distance); // disable aggregated hits except the last if (prev != GVA_NULL) @@ -501,14 +501,14 @@ gva_index_query(GVA_Allocator const allocator, { hits[i].included = variants_with_distance(allocator, self->reference.len, self->reference.str, variant_from_index(self, node_idx), self->intervals.nodes[node_idx].distance, - gva_lcs_graph_ls_slice(graph, hits[i].query.start, hits[i].query.end), graph.dom_nodes[hits[i].query.end].distance - graph.dom_nodes[hits[i].query.start].distance); + gva_lcs_graph_local_supremal(graph, hits[i].query.start, hits[i].query.end), graph.dom_nodes[hits[i].query.end].distance - graph.dom_nodes[hits[i].query.start].distance); } // if // single hit for single query part, relation is not determined by the distances else if (ABS((intmax_t) self->intervals.nodes[node_idx].distance - (graph.dom_nodes[hits[i].query.end].distance - graph.dom_nodes[hits[i].query.start].distance)) != hits[i].included) { hits[i].included = variants_included(allocator, self->reference.len, self->reference.str, variant_from_index(self, node_idx), - gva_lcs_graph_ls_slice(graph, hits[i].query.start, hits[i].query.end)); + gva_lcs_graph_local_supremal(graph, hits[i].query.start, hits[i].query.end)); } // if // single hit for single query part, relation is already determined else diff --git a/src/lcs_graph.c b/src/lcs_graph.c index 2cf1929..52db55c 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -462,7 +462,7 @@ gva_lcs_graph_uniq_atomics(GVA_LCS_Graph const self, inline GVA_Variant -gva_lcs_graph_ls_slice(GVA_LCS_Graph const self, +gva_lcs_graph_local_supremal(GVA_LCS_Graph const self, size_t const start, size_t const end) { GVA_Variant variant; @@ -471,7 +471,7 @@ gva_lcs_graph_ls_slice(GVA_LCS_Graph const self, start == 0, end == array_length(self.dom_nodes) - 1, &variant); return variant; -} // gva_lcs_graph_ls_slice +} // gva_lcs_graph_local_supremal inline size_t @@ -484,12 +484,7 @@ gva_lcs_graph_distance(GVA_LCS_Graph const self) inline GVA_Variant gva_lcs_graph_supremal(GVA_LCS_Graph const self) { - GVA_Variant variant = {0}; - gva_edges(self.observed.str, - self.dom_nodes[0].match, self.dom_nodes[array_length(self.dom_nodes) - 1].match, - true, true, - &variant); - return variant; + return gva_lcs_graph_local_supremal(self, 0, array_length(self.dom_nodes) -1); } // gva_lcs_graph_supremal From f48a3da39d8ae605ae3d6f2feb0888759e9d9049 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 24 Feb 2026 13:34:47 +0100 Subject: [PATCH 512/704] Typo --- include/lcs_graph.h | 8 ++++---- src/lcs_graph.c | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/include/lcs_graph.h b/include/lcs_graph.h index 2d050c3..d64aadb 100644 --- a/include/lcs_graph.h +++ b/include/lcs_graph.h @@ -82,15 +82,15 @@ gva_lcs_graph_uniq_atomics(GVA_LCS_Graph const self, size_t ts[static restrict 1]); +size_t +gva_lcs_graph_distance(GVA_LCS_Graph const self); + + GVA_Variant gva_lcs_graph_local_supremal(GVA_LCS_Graph const self, size_t const start, size_t const end); -size_t -gva_lcs_graph_distance(GVA_LCS_Graph const self); - - GVA_Variant gva_lcs_graph_supremal(GVA_LCS_Graph const self); diff --git a/src/lcs_graph.c b/src/lcs_graph.c index 52db55c..b7ec7e8 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -461,6 +461,13 @@ gva_lcs_graph_uniq_atomics(GVA_LCS_Graph const self, } // gva_lcs_graph_uniq_atomics +inline size_t +gva_lcs_graph_distance(GVA_LCS_Graph const self) +{ + return self.dom_nodes[array_length(self.dom_nodes) - 1].distance; +} // gva_lcs_graph_distance + + inline GVA_Variant gva_lcs_graph_local_supremal(GVA_LCS_Graph const self, size_t const start, size_t const end) @@ -474,17 +481,10 @@ gva_lcs_graph_local_supremal(GVA_LCS_Graph const self, } // gva_lcs_graph_local_supremal -inline size_t -gva_lcs_graph_distance(GVA_LCS_Graph const self) -{ - return self.dom_nodes[array_length(self.dom_nodes) - 1].distance; -} // gva_lcs_graph_distance - - inline GVA_Variant gva_lcs_graph_supremal(GVA_LCS_Graph const self) { - return gva_lcs_graph_local_supremal(self, 0, array_length(self.dom_nodes) -1); + return gva_lcs_graph_local_supremal(self, 0, array_length(self.dom_nodes) - 1); } // gva_lcs_graph_supremal From fd06b296e3e8755bc7eb7b0538b8a7b9e88928ee Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Tue, 24 Feb 2026 16:10:29 +0100 Subject: [PATCH 513/704] Calculate distance in the proper way. --- src/index.c | 2 +- src/main.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/index.c b/src/index.c index d9e1074..743531e 100644 --- a/src/index.c +++ b/src/index.c @@ -375,7 +375,7 @@ gva_index_query(GVA_Allocator const allocator, size_t const distance = variants_distance(allocator, self->reference.len, self->reference.str, variant_from_index(self, node_idx), variant); - if (self->intervals.nodes[node_idx].distance + graph.dom_nodes[i + 1].distance <= distance) + if (self->intervals.nodes[node_idx].distance + graph.dom_nodes[i + 1].distance - graph.dom_nodes[i].distance <= distance) { // Disjoint based on distance continue; diff --git a/src/main.c b/src/main.c index ed06fe5..5f61aca 100644 --- a/src/main.c +++ b/src/main.c @@ -312,7 +312,7 @@ wu_main(int argc, char* argv[static argc]) graph.dom_nodes[i], graph.dom_nodes[i + 1], i == 0, i + 1 == array_length(graph.dom_nodes) - 1, &part); - fprintf(stderr, GVA_VARIANT_FMT " %u\n", GVA_VARIANT_PRINT(part), graph.dom_nodes[i + 1].distance); + fprintf(stderr, GVA_VARIANT_FMT " %u\n", GVA_VARIANT_PRINT(part), graph.dom_nodes[i + 1].distance - graph.dom_nodes[i].distance); } // for fprintf(stderr, GVA_VARIANT_FMT " %zu\n", GVA_VARIANT_PRINT(gva_lcs_graph_supremal(graph)), gva_lcs_graph_distance(graph)); From e3a0214e1f33ef31bdd18d113e8ddfc3442d3a8a Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Tue, 24 Feb 2026 17:14:58 +0100 Subject: [PATCH 514/704] Also output number of query parts. --- src/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.c b/src/main.c index 5f61aca..48ad99d 100644 --- a/src/main.c +++ b/src/main.c @@ -141,11 +141,11 @@ index_main(int argc, char* argv[static argc]) GVA_Query_Result* results = gva_index_query(gva_std_allocator, index, graph); for (size_t i = 0; i < array_length(results); ++i) { - fprintf(stdout, GVA_STRING_FMT " %s " GVA_STRING_FMT " %zu %zu\n", + fprintf(stdout, GVA_STRING_FMT " %s " GVA_STRING_FMT " %zu %zu %zu\n", GVA_STRING_PRINT(results[i].allele), GVA_RELATION_LABELS[results[i].relation], GVA_STRING_PRINT(((GVA_String) {len_id, line})), - results[i].included, results[i].excluded); + results[i].included, results[i].excluded, array_length(graph.dom_nodes) - 1); } // for ARRAY_DESTROY(gva_std_allocator, results); From d86ff54f8c0a587c32793892866af27fa6d392a6 Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 25 Feb 2026 09:50:27 +0100 Subject: [PATCH 515/704] More cleanup --- include/utils.h | 1 + src/compare.c | 2 +- src/main.c | 230 ++++++++++++++---------------------------------- 3 files changed, 68 insertions(+), 165 deletions(-) diff --git a/include/utils.h b/include/utils.h index f03cdb8..0a20b28 100644 --- a/include/utils.h +++ b/include/utils.h @@ -20,6 +20,7 @@ GVA_String gva_fasta_sequence(GVA_Allocator const allocator, FILE* const stream); +// FIXME: remove GVA_String gva_fasta_sequence_blob(GVA_Allocator const allocator, FILE* const stream); diff --git a/src/compare.c b/src/compare.c index fa6a5f1..4da95e6 100644 --- a/src/compare.c +++ b/src/compare.c @@ -5,7 +5,7 @@ #include "../include/allocator.h" // GVA_Allocator #include "../include/compare.h" // gva_compare_graphs #include "../include/edit.h" // gva_edit_distance -#include "../include/lcs_graph.h" // GVA_LCS_Graph, gva_lcs_graph_*, gva_edges +#include "../include/lcs_graph.h" // GVA_LCS_Graph, gva_lcs_graph_* #include "../include/relations.h" // GVA_Relation, GVA_CONTAINS, GVA_DISJOINT, // GVA_EQUIVALENT GVA_IS_CONTAINED, GVA_OVERLAP #include "../include/variant.h" // GVA_Variant, gva_variant_eq diff --git a/src/main.c b/src/main.c index 48ad99d..eda245f 100644 --- a/src/main.c +++ b/src/main.c @@ -1,21 +1,20 @@ #include // errno +#include // bool, false, true #include // NULL, size_t #include // FILE, stderr, stdout, fclose, fopen, fprintf #include // EXIT_*, atoll #include // strerror, strlen #include "../include/edit.h" // gva_edit_distance -#include "../include/index.h" // GVA_Index, gva_index_*, GVA_Result -#include "../include/lcs_graph.h" // GVA_LCS_Graph, GVA_Variant, gva_lcs_graph_*, gva_edges +#include "../include/index.h" // GVA_Index, gva_index_*, GVA_Query_Result +#include "../include/lcs_graph.h" // GVA_LCS_Graph, gva_lcs_graph_* +#include "../include/relations.h" // GVA_RELATION_LABELS #include "../include/std_alloc.h" // gva_std_allocator #include "../include/string.h" // GVA_String, gva_string_destroy -#include "../include/types.h" // GVA_NULL, gva_uint #include "../include/utils.h" // gva_fasta_sequence*, gva_lcs_graph_dot -#include "../include/variant.h" // GVA_VARIANT_*, GVA_Variant, gva_parse_spdi +#include "../include/variant.h" // GVA_VARIANT_*, GVA_Variant, gva_parse_spdi, gva_variant_* #include "array.h" // ARRAY_*, array_length -#include "bitset.h" // bitset_* #include "common.h" // MAX, MIN -#include "hash_table.h" // GVA_NOT_FOUND, HASH_TABLE_KEY, hash_table_* #define LINE_SIZE 8194 @@ -24,43 +23,25 @@ #define REFERENCE_ID "NC_000001.11" -static void -fasta_blob_write(FILE* stream, GVA_String const sequence) -{ - errno = 0; - if (fwrite(&sequence.len, sizeof(sequence.len), 1, stream) != 1) - { - fprintf(stderr, "error: %s\n", strerror(errno)); - return; - } // if - - errno = 0; - if (fwrite(sequence.str, 1, sequence.len, stream) != sequence.len) - { - fprintf(stderr, "error: %s\n", strerror(errno)); - return; - } // if -} // fasta_blob_write - - // line: alphanumeric_id SPDI [distance] static bool parse_line(char const line[static LINE_SIZE], - size_t* const len_id, GVA_Variant* const variant, size_t* const distance) + GVA_String* const id, GVA_Variant* const variant, size_t* const distance) { - *len_id = strcspn(line, "\t "); - if (*len_id == 0) + id->len = strcspn(line, "\t "); + if (id->len == 0) { return false; } // if + id->str = line; - size_t const len_spdi = strcspn(line + *len_id + 1, "\n\t "); - if (gva_parse_spdi(len_spdi, line + *len_id + 1, variant) == 0) + size_t const len_spdi = strcspn(line + id->len + 1, "\n\t "); + if (gva_parse_spdi(len_spdi, line + id->len + 1, variant) == 0) { return false; } // if - *distance = atoll(line + *len_id + len_spdi + 2); + *distance = atoll(line + id->len + len_spdi + 2); return true; } // parse_line @@ -110,26 +91,27 @@ index_main(int argc, char* argv[static argc]) while (fgets(line, sizeof(line), stream) != NULL) { line_count += 1; - size_t len_id = 0; - GVA_Variant variant; + GVA_String id = {0}; + GVA_Variant variant = {0}; size_t distance = 0; - if (!parse_line(line, &len_id, &variant, &distance)) + if (!parse_line(line, &id, &variant, &distance)) { fprintf(stderr, "parsing failed at line %zu: %s\n", line_count, line); continue; } // if - gva_index_insert(index, len_id, line, variant, distance); + gva_index_insert(index, id.len, id.str, variant, distance); } // while - fclose(stream); + fprintf(stderr, "Index populated\n"); + line_count = 0; while (fgets(line, sizeof(line), stdin) != NULL) { line_count += 1; - size_t len_id = 0; - GVA_Variant variant; - if (!parse_line(line, &len_id, &variant, &(size_t) {0})) + GVA_String id = {0}; + GVA_Variant variant = {0}; + if (!parse_line(line, &id, &variant, &(size_t) {0})) { fprintf(stderr, "parsing failed at line %zu: %s\n", line_count, line); continue; @@ -137,14 +119,14 @@ index_main(int argc, char* argv[static argc]) GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &variant); - fprintf(stderr, "\nQuery (" GVA_STRING_FMT "): " GVA_VARIANT_FMT_SPDI " (%zu)\n", GVA_STRING_PRINT(((GVA_String) {len_id, line})), GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, gva_lcs_graph_supremal(graph)), gva_lcs_graph_distance(graph)); + fprintf(stderr, "\nQuery (" GVA_STRING_FMT "): " GVA_VARIANT_FMT_SPDI " (%zu)\n", GVA_STRING_PRINT(id), GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, gva_lcs_graph_supremal(graph)), gva_lcs_graph_distance(graph)); GVA_Query_Result* results = gva_index_query(gva_std_allocator, index, graph); for (size_t i = 0; i < array_length(results); ++i) { fprintf(stdout, GVA_STRING_FMT " %s " GVA_STRING_FMT " %zu %zu %zu\n", GVA_STRING_PRINT(results[i].allele), GVA_RELATION_LABELS[results[i].relation], - GVA_STRING_PRINT(((GVA_String) {len_id, line})), + GVA_STRING_PRINT(id), results[i].included, results[i].excluded, array_length(graph.dom_nodes) - 1); } // for @@ -159,45 +141,6 @@ index_main(int argc, char* argv[static argc]) } // index_main -GVA_String -vcf2obs(GVA_Allocator const allocator, GVA_String const reference, FILE* stream) -{ - GVA_Variant* variants = NULL; - - size_t line_count = 0; - size_t dropped = 0; - static char line[LINE_SIZE] = {0}; - while (fgets(line, sizeof(line), stream) != NULL) - { - size_t const len = strlen(line) - 1; - GVA_Variant variant; - if (gva_parse_spdi(len, line, &variant) == 0) - { - fprintf(stderr, "error: SPDI parsing failed at line %zu: %s", line_count + 1, line); - continue; - } // if - - GVA_Variant const trimmed = gva_variant_prefix_trimmed(reference.len, reference.str, variant); - - if (array_length(variants) > 0 && trimmed.start < variants[array_length(variants) - 1].end) - { - //fprintf(stderr, "dropped: at line %zu: %s", line_count + 1, line); - dropped += 1; - continue; - } // if - - ARRAY_APPEND(allocator, variants, gva_variant_dup(allocator, trimmed)); - line_count += 1; - } // while - - fprintf(stderr, "===INPUT===\n"); - fprintf(stderr, "#variants: %zu\n", array_length(variants)); - fprintf(stderr, "#dropped: %zu\n", dropped); - - return gva_patch(allocator, reference.len, reference.str, array_length(variants), variants); -} // vcf2obs - - //#define SMALL @@ -241,9 +184,9 @@ local_supremal(size_t const len_ref, char const reference[static len_ref], forward.matches[i].col == len_obs - backward.matches[j].col - 1 && (forward.uniq[i] == 1 || backward.uniq[j] == 1)) { - #ifdef SMALL +#ifdef SMALL fprintf(stderr, "common: %zu: (%u, %u)\n", i, forward.matches[i].row, forward.matches[i].col); - #endif +#endif if (i > prev_lcs_pos + 1 || forward.matches[i].row > prev_row + 1 || forward.matches[i].col > prev_col + 1) @@ -267,12 +210,7 @@ local_supremal(size_t const len_ref, char const reference[static len_ref], GVA_LCS_Graph graph = gva_lcs_graph_init(gva_std_allocator, len_ref - prev_row - 1, reference + prev_row + 1, len_obs - prev_col - 1, observed + prev_col + 1, offset + prev_row + 1); for (size_t i = 0; i < array_length(graph.dom_nodes) - 1; ++i) { - GVA_Variant variant; - gva_edges(graph.observed.str, - graph.dom_nodes[i].match, graph.dom_nodes[i + 1].match, - i == 0, i + 1 == array_length(graph.dom_nodes) - 1, - &variant); - printf(GVA_VARIANT_FMT_SPDI " %u\n", GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, variant), graph.dom_nodes[i + 1].distance - graph.dom_nodes[i].distance); + printf(GVA_VARIANT_FMT_SPDI " %u\n", GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, gva_lcs_graph_local_supremal(graph, i, i + 1)), graph.dom_nodes[i + 1].distance - graph.dom_nodes[i].distance); } // for gva_lcs_graph_destroy(gva_std_allocator, graph, false); } // if @@ -291,7 +229,7 @@ local_supremal(size_t const len_ref, char const reference[static len_ref], int -wu_main(int argc, char* argv[static argc]) +allele_main(int argc, char* argv[static argc]) { if (argc < 3) { @@ -307,12 +245,7 @@ wu_main(int argc, char* argv[static argc]) // gva_lcs_graph_dot(stderr, graph); for (size_t i = 0; i < array_length(graph.dom_nodes) - 1; ++i) { - GVA_Variant part; - gva_edges(graph.observed.str, - graph.dom_nodes[i], graph.dom_nodes[i + 1], - i == 0, i + 1 == array_length(graph.dom_nodes) - 1, - &part); - fprintf(stderr, GVA_VARIANT_FMT " %u\n", GVA_VARIANT_PRINT(part), graph.dom_nodes[i + 1].distance - graph.dom_nodes[i].distance); + fprintf(stderr, GVA_VARIANT_FMT " %u\n", GVA_VARIANT_PRINT(gva_lcs_graph_local_supremal(graph, i, i + 1)), graph.dom_nodes[i + 1].distance - graph.dom_nodes[i].distance); } // for fprintf(stderr, GVA_VARIANT_FMT " %zu\n", GVA_VARIANT_PRINT(gva_lcs_graph_supremal(graph)), gva_lcs_graph_distance(graph)); @@ -342,15 +275,46 @@ wu_main(int argc, char* argv[static argc]) return EXIT_FAILURE; } // if - // GVA_String observed = gva_fasta_sequence_blob(gva_std_allocator, stream); // blob - GVA_String observed = vcf2obs(gva_std_allocator, reference, stream); // vcf + GVA_Variant* variants = NULL; + + size_t line_count = 0; + size_t dropped = 0; + static char line[LINE_SIZE] = {0}; + while (fgets(line, sizeof(line), stream) != NULL) + { + line_count += 1; + + GVA_Variant variant = {0}; + if (gva_parse_spdi(strlen(line) - 1, line, &variant) == 0) + { + fprintf(stderr, "error: SPDI parsing failed at line %zu: %s", line_count, line); + continue; + } // if + + GVA_Variant const trimmed = gva_variant_prefix_trimmed(reference.len, reference.str, variant); + + if (array_length(variants) > 0 && trimmed.start < variants[array_length(variants) - 1].end) + { + //fprintf(stderr, "dropped: at line %zu: %s", line_count + 1, line); + dropped += 1; + continue; + } // if + + ARRAY_APPEND(gva_std_allocator, variants, gva_variant_dup(gva_std_allocator, trimmed)); + } // while fclose(stream); + + fprintf(stderr, "===INPUT===\n"); + fprintf(stderr, "#variants: %zu\n", array_length(variants)); + fprintf(stderr, "#dropped: %zu\n", dropped); + + GVA_String observed = gva_patch(gva_std_allocator, reference.len, reference.str, array_length(variants), variants); fprintf(stderr, "observed length: %zu\n", observed.len); if (reference.str == NULL || observed.str == NULL) { - gva_string_destroy(gva_std_allocator, reference); gva_string_destroy(gva_std_allocator, observed); + gva_string_destroy(gva_std_allocator, reference); return EXIT_FAILURE; } // if #endif @@ -363,9 +327,10 @@ wu_main(int argc, char* argv[static argc]) #endif return EXIT_SUCCESS; -} // wu_main +} // allele_main +// DEBUG / check int extract_main(int argc, char* argv[static argc]) { @@ -401,12 +366,7 @@ extract_main(int argc, char* argv[static argc]) { if (i > 0) { - GVA_Variant variant = {0}; - gva_edges(graph.observed.str, - graph.dom_nodes[i - 1].match, graph.dom_nodes[i].match, - i - 1 == 0, i == array_length(graph.dom_nodes) - 1, - &variant); - fprintf(stdout, " " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(variant)); + fprintf(stdout, " " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(gva_lcs_graph_local_supremal(graph, i - 1, i))); } // if fprintf(stdout, " %zu: (%u, %u, %u) %u\n", i, graph.dom_nodes[i].match.row, graph.dom_nodes[i].match.col, graph.dom_nodes[i].match.length, @@ -424,68 +384,10 @@ extract_main(int argc, char* argv[static argc]) } // extract_main -int -make_ref_blob_main(int argc, char* argv[static argc]) -{ - if (argc < 2) - { - fprintf(stderr, "usage: %s reference\n", argv[0]); - return EXIT_FAILURE; - } // if - - errno = 0; - FILE* stream = fopen(argv[1], "r"); - if (stream == NULL) - { - fprintf(stderr, "error: %s\n", strerror(errno)); - return EXIT_FAILURE; - } // if - - GVA_String reference = gva_fasta_sequence(gva_std_allocator, stream); - fclose(stream); - fprintf(stderr, "reference length: %zu\n", reference.len); - - fasta_blob_write(stdout, reference); - - return EXIT_SUCCESS; -} // make_ref_blob_main - - -int -make_obs_blob_main(int argc, char* argv[static argc]) -{ - if (argc < 2) - { - fprintf(stderr, "usage: %s reference.blob\n", argv[0]); - return EXIT_FAILURE; - } // if - - errno = 0; - FILE* stream = fopen(argv[1], "r"); - if (stream == NULL) - { - fprintf(stderr, "error: %s\n", strerror(errno)); - return EXIT_FAILURE; - } // if - - GVA_String reference = gva_fasta_sequence_blob(gva_std_allocator, stream); - fclose(stream); - fprintf(stderr, "reference length: %zu\n", reference.len); - - GVA_String observed = vcf2obs(gva_std_allocator, reference, stdin); - fasta_blob_write(stdout, observed); - - return EXIT_SUCCESS; -} // make_obs_blob_main - - int main(int argc, char* argv[static argc]) { - // return wu_main(argc, argv); - // return fasta_blob_write(argc, argv); + // return allele_main(argc, argv); // return extract_main(argc, argv); - // return make_ref_blob_main(argc, argv); - // return make_obs_blob_main(argc, argv); return index_main(argc, argv); } // main From c0bed7637ec3a47e7059623bbb9e2c58a12cdbf9 Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 25 Feb 2026 11:25:24 +0100 Subject: [PATCH 516/704] Return partial resuls for queries --- include/index.h | 27 +++++++++++++--- include/types.h | 8 +++++ src/index.c | 82 +++++++++++++++++++++++-------------------------- src/main.c | 45 ++++++++++++++++++++++----- 4 files changed, 106 insertions(+), 56 deletions(-) diff --git a/include/index.h b/include/index.h index bc879aa..952758c 100644 --- a/include/index.h +++ b/include/index.h @@ -7,6 +7,7 @@ #include "allocator.h" // GVA_Allocator #include "lcs_graph.h" // GVA_LCS_Graph #include "relations.h" // GVA_Relation +#include "types.h" // GVA_Interval, gva_uint #include "variant.h" // GVA_Variant @@ -15,10 +16,22 @@ typedef struct GVA_Index GVA_Index; // opaque typedef struct { - GVA_String allele; // FIXME: allele_idx - GVA_Relation relation; - size_t included; - size_t excluded; + struct GVA_Query_Allele + { + gva_uint idx; + GVA_Relation relation; + gva_uint included; + gva_uint excluded; + GVA_Interval hits; + }* alleles; + struct GVA_Query_Hit + { + GVA_Relation relation; + gva_uint included; + gva_uint excluded; + GVA_Interval index; + GVA_Interval query; + }* hits; } GVA_Query_Result; @@ -38,9 +51,13 @@ gva_index_insert(GVA_Index* restrict const self, GVA_Variant const variant, size_t const distance); -GVA_Query_Result* +GVA_Query_Result gva_index_query(GVA_Allocator const allocator, GVA_Index* const self, GVA_LCS_Graph const graph); +GVA_String +gva_index_id(GVA_Index const* const self, size_t const idx); + + #endif // GVA_INDEX_H diff --git a/include/types.h b/include/types.h index 6c1a28b..7d85ce3 100644 --- a/include/types.h +++ b/include/types.h @@ -19,6 +19,14 @@ typedef uint32_t gva_uint; static gva_uint const GVA_NULL = UINT32_MAX; +typedef struct +{ + gva_uint start; + gva_uint end; +} GVA_Interval; + + + typedef struct { gva_uint row; diff --git a/src/index.c b/src/index.c index 743531e..86b93fe 100644 --- a/src/index.c +++ b/src/index.c @@ -10,7 +10,7 @@ // GVA_DISJOINT, GVA_EQUIVALENT, // GVA_IS_CONTAINED #include "../include/string.h" // GVA_String -#include "../include/types.h" // GVA_NULL, gva_uint +#include "../include/types.h" // GVA_NULL, GVA_Interval, gva_uint #include "../include/variant.h" // GVA_Variant, gva_variant_dup #include "array.h" // ARRAY_*, array_length #include "bitset.h" // bitset_* @@ -20,9 +20,6 @@ #include "trie.h" // Trie, trie_* -#include // DEBUG - - typedef struct { gva_uint link; // X-OR link between interval_idx and allele_idx @@ -330,7 +327,7 @@ gva_index_insert(GVA_Index* restrict const self, } // gva_index_insert -GVA_Query_Result* +GVA_Query_Result gva_index_query(GVA_Allocator const allocator, GVA_Index* const self, GVA_LCS_Graph const graph) { @@ -346,17 +343,9 @@ gva_index_query(GVA_Allocator const allocator, struct Hit { - struct - { - gva_uint start; - gva_uint end; - } join; // index into self->join - gva_uint included; // double purpose: distance or included - struct - { - gva_uint start; - gva_uint end; - } query; // wrt local supremal parts in the query + GVA_Interval join; // index into self->join + gva_uint included; // double purpose: distance or included + GVA_Interval query; // wrt local supremal parts in the query gva_uint next; }* hits = NULL; @@ -536,7 +525,8 @@ gva_index_query(GVA_Allocator const allocator, // Phase 3: determine relation per allele based on included // FIXME: shouldn't this be in the outer-loop above? - GVA_Query_Result* results = NULL; + GVA_Query_Result result = {NULL}; + for (size_t idx = 0; idx < array_header(entries)->capacity; ++idx) { if (entries[idx].gva_key == NOT_FOUND) @@ -544,48 +534,52 @@ gva_index_query(GVA_Allocator const allocator, continue; } // if + size_t const start = array_length(result.hits); size_t excluded = 0; GVA_Relation const relation = relation_from_included(entries[idx].included, self->alleles[entries[idx].gva_key].distance, gva_lcs_graph_distance(graph), &excluded); - fprintf(stderr, GVA_STRING_FMT " %u %zu %s\n", - GVA_STRING_PRINT(trie_string(self->ids, self->alleles[entries[idx].gva_key].id_idx)), - entries[idx].included, excluded, GVA_RELATION_LABELS[relation]); - - if (entries[idx].head != entries[idx].tail && relation != GVA_EQUIVALENT) + for (gva_uint i = entries[idx].head; i != GVA_NULL; i = hits[i].next) { - for (gva_uint i = entries[idx].head; i != GVA_NULL; i = hits[i].next) + size_t lhs_distance = 0; + for (gva_uint j = hits[i].join.start; j < hits[i].join.end; ++j) { - size_t lhs_distance = 0; - for (gva_uint j = hits[i].join.start; j < hits[i].join.end; ++j) - { - gva_uint const node_idx = self->join[j].link ^ entries[idx].gva_key; - lhs_distance += self->intervals.nodes[node_idx].distance; - } // for - size_t const rhs_distance = graph.dom_nodes[hits[i].query.end].distance - graph.dom_nodes[hits[i].query.start].distance; - size_t excluded = 0; - GVA_Relation const relation = relation_from_included(hits[i].included, lhs_distance, rhs_distance, &excluded); - - fprintf(stderr, " [%u, %u) [%u, %u) %u %zu %s\n", - hits[i].join.start, hits[i].join.end, - hits[i].query.start, hits[i].query.end, - hits[i].included, - excluded, - GVA_RELATION_LABELS[relation]); + gva_uint const node_idx = self->join[j].link ^ entries[idx].gva_key; + lhs_distance += self->intervals.nodes[node_idx].distance; } // for - } // if + size_t const rhs_distance = graph.dom_nodes[hits[i].query.end].distance - graph.dom_nodes[hits[i].query.start].distance; + size_t excluded = 0; + GVA_Relation const relation = relation_from_included(hits[i].included, lhs_distance, rhs_distance, &excluded); - ARRAY_APPEND(self->allocator, results, - ((GVA_Query_Result) + ARRAY_APPEND(allocator, result.hits, + ((struct GVA_Query_Hit) + { + .relation = relation, + .included = hits[i].included, + .excluded = excluded, + .index = hits[i].join, + .query = hits[i].query, + })); + } // for + ARRAY_APPEND(allocator, result.alleles, + ((struct GVA_Query_Allele) { - .allele = trie_string(self->ids, self->alleles[entries[idx].gva_key].id_idx), + .idx = entries[idx].gva_key, .relation = relation, .included = entries[idx].included, .excluded = excluded, + .hits = {start, array_length(result.hits)}, })); } // for hits = ARRAY_DESTROY(allocator, hits); entries = HASH_TABLE_DESTROY(allocator, entries); - return results; + return result; } // gva_index_query + + +inline GVA_String +gva_index_id(GVA_Index const* const self, size_t const idx) +{ + return trie_string(self->ids, self->alleles[idx].id_idx); +} // gva_index_id diff --git a/src/main.c b/src/main.c index eda245f..d925c33 100644 --- a/src/main.c +++ b/src/main.c @@ -46,6 +46,21 @@ parse_line(char const line[static LINE_SIZE], } // parse_line +static int +compare_alleles(void const* a, void const* b) +{ + struct GVA_Query_Allele const lhs = *(struct GVA_Query_Allele*) a; + struct GVA_Query_Allele const rhs = *(struct GVA_Query_Allele*) b; + + if (lhs.included > rhs.included || + (lhs.included == rhs.included && lhs.excluded < rhs.excluded)) + { + return -1; + } // if + return 1; +} // compare_alleles + + int index_main(int argc, char* argv[static argc]) { @@ -120,17 +135,33 @@ index_main(int argc, char* argv[static argc]) GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &variant); fprintf(stderr, "\nQuery (" GVA_STRING_FMT "): " GVA_VARIANT_FMT_SPDI " (%zu)\n", GVA_STRING_PRINT(id), GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, gva_lcs_graph_supremal(graph)), gva_lcs_graph_distance(graph)); - GVA_Query_Result* results = gva_index_query(gva_std_allocator, index, graph); - for (size_t i = 0; i < array_length(results); ++i) + GVA_Query_Result const result = gva_index_query(gva_std_allocator, index, graph); + + qsort(result.alleles, array_length(result.alleles), sizeof(*result.alleles), compare_alleles); + + for (size_t i = 0; i < array_length(result.alleles); ++i) { - fprintf(stdout, GVA_STRING_FMT " %s " GVA_STRING_FMT " %zu %zu %zu\n", - GVA_STRING_PRINT(results[i].allele), - GVA_RELATION_LABELS[results[i].relation], + fprintf(stdout, GVA_STRING_FMT " %s " GVA_STRING_FMT " %u %u %zu\n", + GVA_STRING_PRINT(gva_index_id(index, result.alleles[i].idx)), + GVA_RELATION_LABELS[result.alleles[i].relation], GVA_STRING_PRINT(id), - results[i].included, results[i].excluded, array_length(graph.dom_nodes) - 1); + result.alleles[i].included, result.alleles[i].excluded, array_length(graph.dom_nodes) - 1); + fprintf(stderr, " " GVA_STRING_FMT ": %u %u %s\n", + GVA_STRING_PRINT(gva_index_id(index, result.alleles[i].idx)), + result.alleles[i].included, result.alleles[i].excluded, + GVA_RELATION_LABELS[result.alleles[i].relation]); + for (size_t j = result.alleles[i].hits.start; j < result.alleles[i].hits.end; ++j) + { + fprintf(stderr, " [%u, %u) [%u, %u): %u %u %s\n", + result.hits[j].query.start, result.hits[j].query.end, + result.hits[j].index.start, result.hits[j].index.end, + result.hits[j].included, result.hits[j].excluded, + GVA_RELATION_LABELS[result.hits[j].relation]); + } // for } // for - ARRAY_DESTROY(gva_std_allocator, results); + ARRAY_DESTROY(gva_std_allocator, result.alleles); + ARRAY_DESTROY(gva_std_allocator, result.hits); gva_lcs_graph_destroy(gva_std_allocator, graph, true); } // while From 7a6f61b68bb0ef5cfb1f1801d2087d1dafb00fca Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 25 Feb 2026 11:28:54 +0100 Subject: [PATCH 517/704] Merge query loops --- src/index.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/src/index.c b/src/index.c index 86b93fe..cf6248e 100644 --- a/src/index.c +++ b/src/index.c @@ -424,6 +424,8 @@ gva_index_query(GVA_Allocator const allocator, intervals = ARRAY_DESTROY(allocator, intervals); } // for + GVA_Query_Result result = {NULL}; + // Phase 2: resolve 1:N and N:1 hits into 1:1 hits // - calculate relations that could not be determined on distances // - switch from distances to `included` perspective @@ -520,17 +522,6 @@ gva_index_query(GVA_Allocator const allocator, if (entries[idx].included == 0) { entries[idx].gva_key = NOT_FOUND; - } // if - } // for - - // Phase 3: determine relation per allele based on included - // FIXME: shouldn't this be in the outer-loop above? - GVA_Query_Result result = {NULL}; - - for (size_t idx = 0; idx < array_header(entries)->capacity; ++idx) - { - if (entries[idx].gva_key == NOT_FOUND) - { continue; } // if From 165b74ea09d4407584b6db69a8a8dcfa7f88939f Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 25 Feb 2026 12:16:19 +0100 Subject: [PATCH 518/704] Include --- src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.c b/src/main.c index d925c33..c1d44be 100644 --- a/src/main.c +++ b/src/main.c @@ -2,7 +2,7 @@ #include // bool, false, true #include // NULL, size_t #include // FILE, stderr, stdout, fclose, fopen, fprintf -#include // EXIT_*, atoll +#include // EXIT_*, atoll, qsort #include // strerror, strlen #include "../include/edit.h" // gva_edit_distance From 8b80fe025a538ce036b692141b58d6b1bcbaebd8 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Thu, 26 Feb 2026 13:35:13 +0100 Subject: [PATCH 519/704] Guard empty list for qsort. --- src/main.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/main.c b/src/main.c index c1d44be..6213d54 100644 --- a/src/main.c +++ b/src/main.c @@ -131,13 +131,15 @@ index_main(int argc, char* argv[static argc]) fprintf(stderr, "parsing failed at line %zu: %s\n", line_count, line); continue; } // if - GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &variant); fprintf(stderr, "\nQuery (" GVA_STRING_FMT "): " GVA_VARIANT_FMT_SPDI " (%zu)\n", GVA_STRING_PRINT(id), GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, gva_lcs_graph_supremal(graph)), gva_lcs_graph_distance(graph)); - GVA_Query_Result const result = gva_index_query(gva_std_allocator, index, graph); + GVA_Query_Result result = gva_index_query(gva_std_allocator, index, graph); - qsort(result.alleles, array_length(result.alleles), sizeof(*result.alleles), compare_alleles); + if (array_length(result.alleles) > 0) + { + qsort(result.alleles, array_length(result.alleles), sizeof(*result.alleles), compare_alleles); + } // if for (size_t i = 0; i < array_length(result.alleles); ++i) { @@ -159,9 +161,8 @@ index_main(int argc, char* argv[static argc]) GVA_RELATION_LABELS[result.hits[j].relation]); } // for } // for - - ARRAY_DESTROY(gva_std_allocator, result.alleles); - ARRAY_DESTROY(gva_std_allocator, result.hits); + result.alleles = ARRAY_DESTROY(gva_std_allocator, result.alleles); + result.hits = ARRAY_DESTROY(gva_std_allocator, result.hits); gva_lcs_graph_destroy(gva_std_allocator, graph, true); } // while From 3ca789f83b0b946115afa6b26c769e36f0827bb9 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 26 Feb 2026 17:01:32 +0100 Subject: [PATCH 520/704] WIP: refactoring the contruction of local supremals from alleles --- include/edit_m.h | 29 ++++++++++++ src/edit_m.c | 116 +++++++++++++++++++++++++++++++++++++++++++++++ src/main.c | 102 +++++++++++++++++++++++++---------------- 3 files changed, 207 insertions(+), 40 deletions(-) create mode 100644 include/edit_m.h create mode 100644 src/edit_m.c diff --git a/include/edit_m.h b/include/edit_m.h new file mode 100644 index 0000000..5512daa --- /dev/null +++ b/include/edit_m.h @@ -0,0 +1,29 @@ +#ifndef GVA_EDIT_M_H +#define GVA_EDIT_M_H + + +#include // size_t + +#include "allocator.h" // GVA_Allocator +#include "types.h" // gva_uint + + +typedef struct +{ + gva_uint row; + gva_uint col; +} MNode; + + +extern size_t max_lcs_pos; +extern MNode* matches; +extern char* uniq; + + +size_t +gva_edit_distance_m(GVA_Allocator const allocator, + size_t const len_ref, char const reference[static restrict len_ref], + size_t const len_obs, char const observed[static restrict len_obs]); + + +#endif // GVA_EDIT_M_H diff --git a/src/edit_m.c b/src/edit_m.c new file mode 100644 index 0000000..ef72c15 --- /dev/null +++ b/src/edit_m.c @@ -0,0 +1,116 @@ +#include // intmax_t +#include // bool, false, true +#include // NULL, size_t + + +#include "../include/allocator.h" // GVA_Allocator +#include "../include/edit_m.h" // gva_edit_distance_m +#include "common.h" // ABS, MAX + + +#include // DEBUG + + +size_t max_lcs_pos = 0; +MNode* matches = NULL; +char* uniq = NULL; + + +static inline size_t +onp_snake(size_t const m, char const a[static restrict m], + size_t const n, char const b[static restrict n], + intmax_t const k, + intmax_t const lower, + intmax_t const upper, + intmax_t const delta, + size_t const p, + bool const swapped) +{ + size_t col = MAX(lower, upper); + size_t row = col - k; + + intmax_t const d_row = m - row; + intmax_t const d_col = n - col; + + while (row < m && col < n && a[row] == b[col]) + { + row += 1; + col += 1; + size_t const lcs_pos = (row + col - ABS(delta) - 2 * p + ABS(d_row - d_col)) / 2; + //fprintf(stderr, "%zu: (%zu, %zu)\n", lcs_pos - 1, row - 1, col - 1); + uniq[lcs_pos - 1] = 0; + //matches[lcs_pos - 1] = (MNode) {-1, -1}; + if (lcs_pos > max_lcs_pos) + { + max_lcs_pos = lcs_pos; + uniq[lcs_pos - 1] = 1; + if (swapped) + { + matches[lcs_pos - 1] = (MNode) {col - 1, row - 1}; + } // if + else + { + matches[lcs_pos - 1] = (MNode) {row - 1, col - 1}; + } // else + } // if + } // while + return col; +} // onp_snake + + +static size_t +onp_compare(GVA_Allocator const allocator, + size_t const m, char const a[static restrict m], + size_t const n, char const b[static restrict n], + bool const swapped) +{ + intmax_t const delta = n - m; + size_t const offset = m + 1; + size_t const size = m + n + 3; + intmax_t* const restrict fp = allocator.allocate(allocator.context, NULL, 0, size * sizeof(*fp)); + if (fp == NULL) + { + return -1; + } // if + + for (intmax_t i = -1; i <= delta; ++i) + { + fp[i + offset] = -1; + } // for + + max_lcs_pos = 0; + matches = allocator.allocate(allocator.context, NULL, 0, sizeof(*matches) * m); + uniq = allocator.allocate(allocator.context, NULL, 0, sizeof(*uniq) * m); + + size_t p = 0; + while ((size_t) fp[delta + offset] != n) + { + fp[-p - 1 + offset] = -1; + fp[delta + p + 1 + offset] = -1; + for (intmax_t k = -p; k <= delta - 1; ++k) + { + fp[k + offset] = onp_snake(m, a, n, b, k, fp[k - 1 + offset] + 1, fp[k + 1 + offset], delta, p, swapped); + } // for + for (intmax_t k = delta + p; k >= delta + 1; --k) + { + fp[k + offset] = onp_snake(m, a, n, b, k, fp[k - 1 + offset] + 1, fp[k + 1 + offset], delta, p, swapped); + } // for + fp[delta + offset] = onp_snake(m, a, n, b, delta, fp[delta - 1 + offset] + 1, fp[delta + 1 + offset], delta, p, swapped); + p += 1; + } // while + + allocator.allocate(allocator.context, fp, size * sizeof(*fp), 0); + return delta + 2 * (p - 1); +} // onp_compare + + +inline size_t +gva_edit_distance_m(GVA_Allocator const allocator, + size_t const len_ref, char const reference[static restrict len_ref], + size_t const len_obs, char const observed[static restrict len_obs]) +{ + fprintf(stderr, "ALIGN\n"); + return len_ref > len_obs ? + onp_compare(allocator, len_obs, observed, len_ref, reference, true) : + onp_compare(allocator, len_ref, reference, len_obs, observed, false); +} // gva_edit_distance_m diff --git a/src/main.c b/src/main.c index 6213d54..5c19fc0 100644 --- a/src/main.c +++ b/src/main.c @@ -17,6 +17,9 @@ #include "common.h" // MAX, MIN +#include "../include/edit_m.h" + + #define LINE_SIZE 8194 // #define REFERENCE_ID "NC_000006.12" @@ -173,7 +176,7 @@ index_main(int argc, char* argv[static argc]) } // index_main -//#define SMALL +#define SMALL void @@ -181,82 +184,103 @@ local_supremal(size_t const len_ref, char const reference[static len_ref], size_t const len_obs, char const observed[static len_obs], size_t const offset) { - //fprintf(stderr, "LOCAL %zu %zu :: %zu\n", len_ref, len_obs, offset); + fprintf(stderr, "LOCAL %zu %zu :: %zu\n", len_ref, len_obs, offset); if (len_ref == 0 || len_obs == 0) { - // fprintf(stderr, "triv distance: %zu\n", len_ref + len_obs); printf(GVA_VARIANT_FMT_SPDI " %zu\n", GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, ((GVA_Variant) {offset, offset + len_ref, {len_obs, observed}})), len_ref + len_obs); return; } // if - - GVA_Matches forward = gva_edit_distance_matches(gva_std_allocator, len_ref, reference, len_obs, observed); + size_t distance = gva_edit_distance_m(gva_std_allocator, len_ref, reference, len_obs, observed); + MNode* forward = matches; + char* f_uniq = uniq; + fprintf(stderr, "distance: %zu\n", distance); + fprintf(stderr, "max_lcs_pos: %zu\n", max_lcs_pos); gva_string_reverse((GVA_String) {len_ref, reference}); gva_string_reverse((GVA_String) {len_obs, observed}); - GVA_Matches backward = gva_edit_distance_matches(gva_std_allocator, len_ref, reference, len_obs, observed); - if (forward.distance != backward.distance) - { - fprintf(stderr, "distance mismatch between f and b\n"); - exit(EXIT_FAILURE); // FIXME - } // if +// reference = strrev(len_ref, (char*) reference); +// observed = strrev(len_obs, (char*) observed); + + distance = gva_edit_distance_m(gva_std_allocator, len_ref, reference, len_obs, observed); + MNode* backward = matches; + char* b_uniq = uniq; + fprintf(stderr, "distance: %zu\n", distance); + fprintf(stderr, "max_lcs_pos: %zu\n", max_lcs_pos); + size_t const max_lcs_pos_local = max_lcs_pos; + +// reference = strrev(len_ref, (char*) reference); +// observed = strrev(len_obs, (char*) observed); gva_string_reverse((GVA_String) {len_ref, reference}); gva_string_reverse((GVA_String) {len_obs, observed}); + size_t sum = 0; size_t prev_lcs_pos = 0; size_t prev_row = -1; size_t prev_col = -1; - for (size_t i = 0; i < forward.max_lcs_pos; ++i) + for (size_t i = 0; i < max_lcs_pos_local; ++i) { - size_t const j = forward.max_lcs_pos - i - 1; - if (forward.matches[i].row == len_ref - backward.matches[j].row - 1 && - forward.matches[i].col == len_obs - backward.matches[j].col - 1 && - (forward.uniq[i] == 1 || backward.uniq[j] == 1)) + size_t const j = max_lcs_pos_local - i - 1; +/* + if (forward[i].row != (gva_uint) -1 && + backward[j].row != (gva_uint) -1 && + forward[i].row == len_ref - backward[j].row - 1 && + forward[i].col == len_obs - backward[j].col - 1) +*/ + if (forward[i].row == len_ref - backward[j].row - 1 && + forward[i].col == len_obs - backward[j].col - 1 && + (f_uniq[i] == 1 || b_uniq[j] == 1)) { #ifdef SMALL - fprintf(stderr, "common: %zu: (%u, %u)\n", i, forward.matches[i].row, forward.matches[i].col); + fprintf(stderr, "common: %zu: (%u, %u)\n", i, forward[i].row, forward[i].col); #endif if (i > prev_lcs_pos + 1 || - forward.matches[i].row > prev_row + 1 || - forward.matches[i].col > prev_col + 1) + forward[i].row > prev_row + 1 || + forward[i].col > prev_col + 1) { - size_t const distance = forward.matches[i].row + forward.matches[i].col - 2 * i - sum; + size_t const distance = forward[i].row + forward[i].col - 2 * i - sum; if (distance > 0) { sum += distance; - local_supremal(forward.matches[i].row - prev_row - 1, reference + prev_row + 1, forward.matches[i].col - prev_col - 1, observed + prev_col + 1, offset + prev_row + 1); + //printf("R gap %zu: (%zu, %zu)--(%u, %u) %zu\n", i, prev_row + 1, prev_col + 1, forward[i].row, forward[i].col, distance); + local_supremal(forward[i].row - prev_row - 1, reference + prev_row + 1, forward[i].col - prev_col - 1, observed + prev_col + 1, offset + prev_row + 1); + //printf(GVA_STRING_FMT "\n", (int) (forward[i].row - prev_row - 1), reference + prev_row + 1); + //printf(GVA_STRING_FMT "\n", (int) (forward[i].col - prev_col - 1), observed + prev_col + 1); } // if } // if prev_lcs_pos = i; - prev_row = forward.matches[i].row; - prev_col = forward.matches[i].col; + prev_row = forward[i].row; + prev_col = forward[i].col; } // if } // for if (len_ref > prev_row + 1 || len_obs > prev_col + 1) { - size_t const distance = len_ref + len_obs - 2 * forward.max_lcs_pos - sum; + size_t const distance = len_ref + len_obs - 2 * max_lcs_pos_local - sum; sum += distance; + //printf(GVA_STRING_FMT " ", (int) (len_ref - prev_row - 1), reference + prev_row + 1); + //printf(GVA_STRING_FMT "\n", (int) (len_obs - prev_col - 1), observed + prev_col + 1); GVA_LCS_Graph graph = gva_lcs_graph_init(gva_std_allocator, len_ref - prev_row - 1, reference + prev_row + 1, len_obs - prev_col - 1, observed + prev_col + 1, offset + prev_row + 1); for (size_t i = 0; i < array_length(graph.dom_nodes) - 1; ++i) { - printf(GVA_VARIANT_FMT_SPDI " %u\n", GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, gva_lcs_graph_local_supremal(graph, i, i + 1)), graph.dom_nodes[i + 1].distance - graph.dom_nodes[i].distance); + GVA_Variant const variant = gva_lcs_graph_local_supremal(graph, i, i + 1); + printf(GVA_VARIANT_FMT_SPDI " %u\n", GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, variant), graph.dom_nodes[i + 1].distance - graph.dom_nodes[i].distance); } // for gva_lcs_graph_destroy(gva_std_allocator, graph, false); + //printf("L " GVA_VARIANT_FMT " %zu %zu+[(%zu, %zu)--(%zu, %zu)]\n", GVA_VARIANT_PRINT(((GVA_Variant) {offset + prev_row + 1, offset + len_ref, {len_obs - prev_col - 1, observed + prev_col + 1}})), distance, offset, prev_row + 1, prev_col + 1, len_ref, len_obs); + //printf("L gap %zu: (%zu, %zu)--(%zu, %zu) %zu\n", max_lcs_pos_local, prev_row + 1, prev_col + 1, len_ref, len_obs, distance); + //printf(GVA_STRING_FMT "\n", (int) (len_ref - prev_row - 1), reference + prev_row + 1); + //printf(GVA_STRING_FMT "\n", (int) (len_obs - prev_col - 1), observed + prev_col + 1); } // if - if (forward.distance != sum) - { - fprintf(stderr, "distance mismatch between f and sum\n"); - exit(EXIT_FAILURE); // FIXME - } // if + //fprintf(stderr, "distance: %zu\n", sum); - backward.uniq = gva_std_allocator.allocate(gva_std_allocator.context, backward.uniq, MIN(len_ref, len_obs), 0); - backward.matches = gva_std_allocator.allocate(gva_std_allocator.context, backward.matches, MIN(len_ref, len_obs) * sizeof(*backward.matches), 0); - forward.uniq = gva_std_allocator.allocate(gva_std_allocator.context, forward.uniq, MIN(len_ref, len_obs), 0); - forward.matches = gva_std_allocator.allocate(gva_std_allocator.context, forward.matches, MIN(len_ref, len_obs) * sizeof(*forward.matches), 0); + forward = gva_std_allocator.allocate(gva_std_allocator.context, forward, MIN(len_ref, len_obs), 0); + f_uniq = gva_std_allocator.allocate(gva_std_allocator.context, f_uniq, MIN(len_ref, len_obs), 0); + backward = gva_std_allocator.allocate(gva_std_allocator.context, backward, MIN(len_ref, len_obs), 0); + b_uniq = gva_std_allocator.allocate(gva_std_allocator.context, b_uniq, MIN(len_ref, len_obs), 0); } // local_supremal @@ -281,9 +305,7 @@ allele_main(int argc, char* argv[static argc]) } // for fprintf(stderr, GVA_VARIANT_FMT " %zu\n", GVA_VARIANT_PRINT(gva_lcs_graph_supremal(graph)), gva_lcs_graph_distance(graph)); - gva_lcs_graph_destroy(gva_std_allocator, graph); - - return 0; + gva_lcs_graph_destroy(gva_std_allocator, graph, false); #else errno = 0; @@ -327,7 +349,7 @@ allele_main(int argc, char* argv[static argc]) if (array_length(variants) > 0 && trimmed.start < variants[array_length(variants) - 1].end) { - //fprintf(stderr, "dropped: at line %zu: %s", line_count + 1, line); + fprintf(stderr, "dropped: at line %zu: %s", line_count + 1, line); dropped += 1; continue; } // if @@ -419,7 +441,7 @@ extract_main(int argc, char* argv[static argc]) int main(int argc, char* argv[static argc]) { - // return allele_main(argc, argv); + return allele_main(argc, argv); // return extract_main(argc, argv); - return index_main(argc, argv); + // return index_main(argc, argv); } // main From abab3244df3cd5f3311da051d40db6745abd3ba8 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 26 Feb 2026 17:23:51 +0100 Subject: [PATCH 521/704] WIP: local vars not working --- include/edit.h | 4 +++ include/edit_m.h | 23 ++++++++--------- src/edit.c | 4 +++ src/edit_m.c | 52 +++++++++++++++++++-------------------- src/main.c | 64 ++++++++++++++++++------------------------------ 5 files changed, 69 insertions(+), 78 deletions(-) diff --git a/include/edit.h b/include/edit.h index 9d10f58..4e934c0 100644 --- a/include/edit.h +++ b/include/edit.h @@ -5,6 +5,7 @@ #include // size_t #include "allocator.h" // GVA_Allocator +/* #include "types.h" // gva_uint @@ -19,6 +20,7 @@ typedef struct size_t max_lcs_pos; size_t distance; } GVA_Matches; +*/ size_t @@ -27,10 +29,12 @@ gva_edit_distance(GVA_Allocator const allocator, size_t const len_obs, char const observed[static restrict len_obs]); +/* GVA_Matches gva_edit_distance_matches(GVA_Allocator const allocator, size_t const len_ref, char const reference[static restrict len_ref], size_t const len_obs, char const observed[static restrict len_obs]); +*/ #endif // GVA_EDIT_H diff --git a/include/edit_m.h b/include/edit_m.h index 5512daa..cb09ce2 100644 --- a/include/edit_m.h +++ b/include/edit_m.h @@ -10,17 +10,18 @@ typedef struct { - gva_uint row; - gva_uint col; -} MNode; - - -extern size_t max_lcs_pos; -extern MNode* matches; -extern char* uniq; - - -size_t + struct + { + gva_uint row; + gva_uint col; + }* restrict matches; + char* restrict uniq; + size_t max_lcs_pos; + size_t distance; +} GVA_Matches; + + +GVA_Matches gva_edit_distance_m(GVA_Allocator const allocator, size_t const len_ref, char const reference[static restrict len_ref], size_t const len_obs, char const observed[static restrict len_obs]); diff --git a/src/edit.c b/src/edit.c index f85cbf0..39deecb 100644 --- a/src/edit.c +++ b/src/edit.c @@ -68,6 +68,7 @@ onp_compare(GVA_Allocator const allocator, } // onp_compare +/* static inline size_t onp_snake_matches(size_t const m, char const a[static restrict m], size_t const n, char const b[static restrict n], @@ -155,6 +156,7 @@ onp_compare_matches(GVA_Allocator const allocator, result.distance = delta + 2 * (p - 1); return result; } // onp_compare_matches +*/ inline size_t @@ -168,6 +170,7 @@ gva_edit_distance(GVA_Allocator const allocator, } // gva_edit_distance +/* inline GVA_Matches gva_edit_distance_matches(GVA_Allocator const allocator, size_t const len_ref, char const reference[static restrict len_ref], @@ -187,3 +190,4 @@ gva_edit_distance_matches(GVA_Allocator const allocator, return onp_compare_matches(allocator, len_ref, reference, len_obs, observed); } // gva_edit_distance_matches +*/ diff --git a/src/edit_m.c b/src/edit_m.c index ef72c15..47771e6 100644 --- a/src/edit_m.c +++ b/src/edit_m.c @@ -11,20 +11,12 @@ #include // DEBUG -size_t max_lcs_pos = 0; -MNode* matches = NULL; -char* uniq = NULL; - - static inline size_t onp_snake(size_t const m, char const a[static restrict m], size_t const n, char const b[static restrict n], - intmax_t const k, - intmax_t const lower, - intmax_t const upper, - intmax_t const delta, - size_t const p, - bool const swapped) + intmax_t const k, intmax_t const lower, intmax_t const upper, + intmax_t const delta, size_t const p, bool const swapped, + GVA_Matches result) { size_t col = MAX(lower, upper); size_t row = col - k; @@ -38,19 +30,21 @@ onp_snake(size_t const m, char const a[static restrict m], col += 1; size_t const lcs_pos = (row + col - ABS(delta) - 2 * p + ABS(d_row - d_col)) / 2; //fprintf(stderr, "%zu: (%zu, %zu)\n", lcs_pos - 1, row - 1, col - 1); - uniq[lcs_pos - 1] = 0; + result.uniq[lcs_pos - 1] = 0; //matches[lcs_pos - 1] = (MNode) {-1, -1}; - if (lcs_pos > max_lcs_pos) + if (lcs_pos > result.max_lcs_pos) { - max_lcs_pos = lcs_pos; - uniq[lcs_pos - 1] = 1; + result.max_lcs_pos = lcs_pos; + result.uniq[lcs_pos - 1] = 1; if (swapped) { - matches[lcs_pos - 1] = (MNode) {col - 1, row - 1}; + result.matches[lcs_pos - 1].row = col - 1; + result.matches[lcs_pos - 1].col = row - 1; } // if else { - matches[lcs_pos - 1] = (MNode) {row - 1, col - 1}; + result.matches[lcs_pos - 1].row = row - 1; + result.matches[lcs_pos - 1].col = col - 1; } // else } // if } // while @@ -58,7 +52,7 @@ onp_snake(size_t const m, char const a[static restrict m], } // onp_snake -static size_t +static GVA_Matches onp_compare(GVA_Allocator const allocator, size_t const m, char const a[static restrict m], size_t const n, char const b[static restrict n], @@ -70,7 +64,7 @@ onp_compare(GVA_Allocator const allocator, intmax_t* const restrict fp = allocator.allocate(allocator.context, NULL, 0, size * sizeof(*fp)); if (fp == NULL) { - return -1; + return (GVA_Matches) {NULL}; } // if for (intmax_t i = -1; i <= delta; ++i) @@ -78,9 +72,11 @@ onp_compare(GVA_Allocator const allocator, fp[i + offset] = -1; } // for - max_lcs_pos = 0; - matches = allocator.allocate(allocator.context, NULL, 0, sizeof(*matches) * m); - uniq = allocator.allocate(allocator.context, NULL, 0, sizeof(*uniq) * m); + GVA_Matches result = + { + .matches = allocator.allocate(allocator.context, NULL, 0, sizeof(*result.matches) * m), + .uniq = allocator.allocate(allocator.context, NULL, 0, sizeof(*result.uniq) * m), + }; size_t p = 0; while ((size_t) fp[delta + offset] != n) @@ -89,22 +85,24 @@ onp_compare(GVA_Allocator const allocator, fp[delta + p + 1 + offset] = -1; for (intmax_t k = -p; k <= delta - 1; ++k) { - fp[k + offset] = onp_snake(m, a, n, b, k, fp[k - 1 + offset] + 1, fp[k + 1 + offset], delta, p, swapped); + fp[k + offset] = onp_snake(m, a, n, b, k, fp[k - 1 + offset] + 1, fp[k + 1 + offset], delta, p, swapped, result); } // for for (intmax_t k = delta + p; k >= delta + 1; --k) { - fp[k + offset] = onp_snake(m, a, n, b, k, fp[k - 1 + offset] + 1, fp[k + 1 + offset], delta, p, swapped); + fp[k + offset] = onp_snake(m, a, n, b, k, fp[k - 1 + offset] + 1, fp[k + 1 + offset], delta, p, swapped, result); } // for - fp[delta + offset] = onp_snake(m, a, n, b, delta, fp[delta - 1 + offset] + 1, fp[delta + 1 + offset], delta, p, swapped); + fp[delta + offset] = onp_snake(m, a, n, b, delta, fp[delta - 1 + offset] + 1, fp[delta + 1 + offset], delta, p, swapped, result); p += 1; } // while allocator.allocate(allocator.context, fp, size * sizeof(*fp), 0); - return delta + 2 * (p - 1); + + result.distance = delta + 2 * (p - 1); + return result; } // onp_compare -inline size_t +inline GVA_Matches gva_edit_distance_m(GVA_Allocator const allocator, size_t const len_ref, char const reference[static restrict len_ref], size_t const len_obs, char const observed[static restrict len_obs]) diff --git a/src/main.c b/src/main.c index 5c19fc0..6714260 100644 --- a/src/main.c +++ b/src/main.c @@ -190,33 +190,23 @@ local_supremal(size_t const len_ref, char const reference[static len_ref], printf(GVA_VARIANT_FMT_SPDI " %zu\n", GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, ((GVA_Variant) {offset, offset + len_ref, {len_obs, observed}})), len_ref + len_obs); return; } // if - size_t distance = gva_edit_distance_m(gva_std_allocator, len_ref, reference, len_obs, observed); - MNode* forward = matches; - char* f_uniq = uniq; - fprintf(stderr, "distance: %zu\n", distance); - fprintf(stderr, "max_lcs_pos: %zu\n", max_lcs_pos); + GVA_Matches forward = gva_edit_distance_m(gva_std_allocator, len_ref, reference, len_obs, observed); + + fprintf(stderr, "distance: %zu\n", forward.distance); + fprintf(stderr, "max_lcs_pos: %zu\n", forward.max_lcs_pos); gva_string_reverse((GVA_String) {len_ref, reference}); gva_string_reverse((GVA_String) {len_obs, observed}); + GVA_Matches backward = gva_edit_distance_m(gva_std_allocator, len_ref, reference, len_obs, observed); + fprintf(stderr, "distance: %zu\n", backward.distance); + fprintf(stderr, "max_lcs_pos: %zu\n", backward.max_lcs_pos); -// reference = strrev(len_ref, (char*) reference); -// observed = strrev(len_obs, (char*) observed); - - distance = gva_edit_distance_m(gva_std_allocator, len_ref, reference, len_obs, observed); - MNode* backward = matches; - char* b_uniq = uniq; - fprintf(stderr, "distance: %zu\n", distance); - fprintf(stderr, "max_lcs_pos: %zu\n", max_lcs_pos); - size_t const max_lcs_pos_local = max_lcs_pos; - -// reference = strrev(len_ref, (char*) reference); -// observed = strrev(len_obs, (char*) observed); + size_t const max_lcs_pos_local = forward.max_lcs_pos; gva_string_reverse((GVA_String) {len_ref, reference}); gva_string_reverse((GVA_String) {len_obs, observed}); - size_t sum = 0; size_t prev_lcs_pos = 0; size_t prev_row = -1; @@ -224,36 +214,31 @@ local_supremal(size_t const len_ref, char const reference[static len_ref], for (size_t i = 0; i < max_lcs_pos_local; ++i) { size_t const j = max_lcs_pos_local - i - 1; -/* - if (forward[i].row != (gva_uint) -1 && - backward[j].row != (gva_uint) -1 && - forward[i].row == len_ref - backward[j].row - 1 && - forward[i].col == len_obs - backward[j].col - 1) -*/ - if (forward[i].row == len_ref - backward[j].row - 1 && - forward[i].col == len_obs - backward[j].col - 1 && - (f_uniq[i] == 1 || b_uniq[j] == 1)) + + if (forward.matches[i].row == len_ref - backward.matches[j].row - 1 && + forward.matches[i].col == len_obs - backward.matches[j].col - 1 && + (forward.uniq[i] == 1 || backward.uniq[j] == 1)) { #ifdef SMALL - fprintf(stderr, "common: %zu: (%u, %u)\n", i, forward[i].row, forward[i].col); + fprintf(stderr, "common: %zu: (%u, %u)\n", i, forward.matches[i].row, forward.matches[i].col); #endif if (i > prev_lcs_pos + 1 || - forward[i].row > prev_row + 1 || - forward[i].col > prev_col + 1) + forward.matches[i].row > prev_row + 1 || + forward.matches[i].col > prev_col + 1) { - size_t const distance = forward[i].row + forward[i].col - 2 * i - sum; + size_t const distance = forward.matches[i].row + forward.matches[i].col - 2 * i - sum; if (distance > 0) { sum += distance; //printf("R gap %zu: (%zu, %zu)--(%u, %u) %zu\n", i, prev_row + 1, prev_col + 1, forward[i].row, forward[i].col, distance); - local_supremal(forward[i].row - prev_row - 1, reference + prev_row + 1, forward[i].col - prev_col - 1, observed + prev_col + 1, offset + prev_row + 1); + local_supremal(forward.matches[i].row - prev_row - 1, reference + prev_row + 1, forward.matches[i].col - prev_col - 1, observed + prev_col + 1, offset + prev_row + 1); //printf(GVA_STRING_FMT "\n", (int) (forward[i].row - prev_row - 1), reference + prev_row + 1); //printf(GVA_STRING_FMT "\n", (int) (forward[i].col - prev_col - 1), observed + prev_col + 1); } // if } // if prev_lcs_pos = i; - prev_row = forward[i].row; - prev_col = forward[i].col; + prev_row = forward.matches[i].row; + prev_col = forward.matches[i].col; } // if } // for if (len_ref > prev_row + 1 || len_obs > prev_col + 1) @@ -265,8 +250,7 @@ local_supremal(size_t const len_ref, char const reference[static len_ref], GVA_LCS_Graph graph = gva_lcs_graph_init(gva_std_allocator, len_ref - prev_row - 1, reference + prev_row + 1, len_obs - prev_col - 1, observed + prev_col + 1, offset + prev_row + 1); for (size_t i = 0; i < array_length(graph.dom_nodes) - 1; ++i) { - GVA_Variant const variant = gva_lcs_graph_local_supremal(graph, i, i + 1); - printf(GVA_VARIANT_FMT_SPDI " %u\n", GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, variant), graph.dom_nodes[i + 1].distance - graph.dom_nodes[i].distance); + printf(GVA_VARIANT_FMT_SPDI " %u\n", GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, gva_lcs_graph_local_supremal(graph, i, i + 1)), graph.dom_nodes[i + 1].distance - graph.dom_nodes[i].distance); } // for gva_lcs_graph_destroy(gva_std_allocator, graph, false); //printf("L " GVA_VARIANT_FMT " %zu %zu+[(%zu, %zu)--(%zu, %zu)]\n", GVA_VARIANT_PRINT(((GVA_Variant) {offset + prev_row + 1, offset + len_ref, {len_obs - prev_col - 1, observed + prev_col + 1}})), distance, offset, prev_row + 1, prev_col + 1, len_ref, len_obs); @@ -277,10 +261,10 @@ local_supremal(size_t const len_ref, char const reference[static len_ref], //fprintf(stderr, "distance: %zu\n", sum); - forward = gva_std_allocator.allocate(gva_std_allocator.context, forward, MIN(len_ref, len_obs), 0); - f_uniq = gva_std_allocator.allocate(gva_std_allocator.context, f_uniq, MIN(len_ref, len_obs), 0); - backward = gva_std_allocator.allocate(gva_std_allocator.context, backward, MIN(len_ref, len_obs), 0); - b_uniq = gva_std_allocator.allocate(gva_std_allocator.context, b_uniq, MIN(len_ref, len_obs), 0); + forward.matches = gva_std_allocator.allocate(gva_std_allocator.context, forward.matches, MIN(len_ref, len_obs), 0); + forward.uniq = gva_std_allocator.allocate(gva_std_allocator.context, forward.uniq, MIN(len_ref, len_obs), 0); + backward.matches = gva_std_allocator.allocate(gva_std_allocator.context, backward.matches, MIN(len_ref, len_obs), 0); + backward.uniq = gva_std_allocator.allocate(gva_std_allocator.context, backward.uniq, MIN(len_ref, len_obs), 0); } // local_supremal From ca151304ca9da561b060cd2be90671e7cade3ea7 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 26 Feb 2026 18:12:50 +0100 Subject: [PATCH 522/704] WIP: something is happening --- src/edit.c | 4 +--- src/edit_m.c | 49 +++++++++++++++++++++++-------------------------- src/index.c | 1 + 3 files changed, 25 insertions(+), 29 deletions(-) diff --git a/src/edit.c b/src/edit.c index 39deecb..6dca029 100644 --- a/src/edit.c +++ b/src/edit.c @@ -11,9 +11,7 @@ static inline size_t onp_snake(size_t const m, char const a[static restrict m], size_t const n, char const b[static restrict n], - intmax_t const k, - intmax_t const lower, - intmax_t const upper) + intmax_t const k, intmax_t const lower, intmax_t const upper) { size_t col = MAX(lower, upper); size_t row = col - k; diff --git a/src/edit_m.c b/src/edit_m.c index 47771e6..2f4f62d 100644 --- a/src/edit_m.c +++ b/src/edit_m.c @@ -8,15 +8,12 @@ #include "common.h" // ABS, MAX -#include // DEBUG - - static inline size_t onp_snake(size_t const m, char const a[static restrict m], size_t const n, char const b[static restrict n], intmax_t const k, intmax_t const lower, intmax_t const upper, intmax_t const delta, size_t const p, bool const swapped, - GVA_Matches result) + GVA_Matches result[static restrict 1]) { size_t col = MAX(lower, upper); size_t row = col - k; @@ -29,22 +26,20 @@ onp_snake(size_t const m, char const a[static restrict m], row += 1; col += 1; size_t const lcs_pos = (row + col - ABS(delta) - 2 * p + ABS(d_row - d_col)) / 2; - //fprintf(stderr, "%zu: (%zu, %zu)\n", lcs_pos - 1, row - 1, col - 1); - result.uniq[lcs_pos - 1] = 0; - //matches[lcs_pos - 1] = (MNode) {-1, -1}; - if (lcs_pos > result.max_lcs_pos) + result->uniq[lcs_pos - 1] = 0; + if (lcs_pos > result->max_lcs_pos) { - result.max_lcs_pos = lcs_pos; - result.uniq[lcs_pos - 1] = 1; + result->max_lcs_pos = lcs_pos; + result->uniq[lcs_pos - 1] = 1; if (swapped) { - result.matches[lcs_pos - 1].row = col - 1; - result.matches[lcs_pos - 1].col = row - 1; + result->matches[lcs_pos - 1].row = col - 1; + result->matches[lcs_pos - 1].col = row - 1; } // if else { - result.matches[lcs_pos - 1].row = row - 1; - result.matches[lcs_pos - 1].col = col - 1; + result->matches[lcs_pos - 1].row = row - 1; + result->matches[lcs_pos - 1].col = col - 1; } // else } // if } // while @@ -61,9 +56,18 @@ onp_compare(GVA_Allocator const allocator, intmax_t const delta = n - m; size_t const offset = m + 1; size_t const size = m + n + 3; - intmax_t* const restrict fp = allocator.allocate(allocator.context, NULL, 0, size * sizeof(*fp)); - if (fp == NULL) + + intmax_t* restrict fp = allocator.allocate(allocator.context, NULL, 0, size * sizeof(*fp)); + GVA_Matches result = + { + .matches = allocator.allocate(allocator.context, NULL, 0, sizeof(*result.matches) * m), + .uniq = allocator.allocate(allocator.context, NULL, 0, sizeof(*result.uniq) * m), + }; + if (fp == NULL || result.matches == NULL || result.uniq == NULL) { + result.uniq = allocator.allocate(allocator.context, result.uniq, sizeof(*result.uniq) * m, 0); + result.matches = allocator.allocate(allocator.context, result.matches, sizeof(*result.matches) * m, 0); + fp = allocator.allocate(allocator.context, fp, size * sizeof(*fp), 0); return (GVA_Matches) {NULL}; } // if @@ -72,12 +76,6 @@ onp_compare(GVA_Allocator const allocator, fp[i + offset] = -1; } // for - GVA_Matches result = - { - .matches = allocator.allocate(allocator.context, NULL, 0, sizeof(*result.matches) * m), - .uniq = allocator.allocate(allocator.context, NULL, 0, sizeof(*result.uniq) * m), - }; - size_t p = 0; while ((size_t) fp[delta + offset] != n) { @@ -85,13 +83,13 @@ onp_compare(GVA_Allocator const allocator, fp[delta + p + 1 + offset] = -1; for (intmax_t k = -p; k <= delta - 1; ++k) { - fp[k + offset] = onp_snake(m, a, n, b, k, fp[k - 1 + offset] + 1, fp[k + 1 + offset], delta, p, swapped, result); + fp[k + offset] = onp_snake(m, a, n, b, k, fp[k - 1 + offset] + 1, fp[k + 1 + offset], delta, p, swapped, &result); } // for for (intmax_t k = delta + p; k >= delta + 1; --k) { - fp[k + offset] = onp_snake(m, a, n, b, k, fp[k - 1 + offset] + 1, fp[k + 1 + offset], delta, p, swapped, result); + fp[k + offset] = onp_snake(m, a, n, b, k, fp[k - 1 + offset] + 1, fp[k + 1 + offset], delta, p, swapped, &result); } // for - fp[delta + offset] = onp_snake(m, a, n, b, delta, fp[delta - 1 + offset] + 1, fp[delta + 1 + offset], delta, p, swapped, result); + fp[delta + offset] = onp_snake(m, a, n, b, delta, fp[delta - 1 + offset] + 1, fp[delta + 1 + offset], delta, p, swapped, &result); p += 1; } // while @@ -107,7 +105,6 @@ gva_edit_distance_m(GVA_Allocator const allocator, size_t const len_ref, char const reference[static restrict len_ref], size_t const len_obs, char const observed[static restrict len_obs]) { - fprintf(stderr, "ALIGN\n"); return len_ref > len_obs ? onp_compare(allocator, len_obs, observed, len_ref, reference, true) : onp_compare(allocator, len_ref, reference, len_obs, observed, false); diff --git a/src/index.c b/src/index.c index cf6248e..1f64b7d 100644 --- a/src/index.c +++ b/src/index.c @@ -519,6 +519,7 @@ gva_index_query(GVA_Allocator const allocator, entries[idx].included += hits[i].included; prev = i; } // for + if (entries[idx].included == 0) { entries[idx].gva_key = NOT_FOUND; From 3211f2f3c654e2e8401f5ede538cb24538a37999 Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 27 Feb 2026 15:32:20 +0100 Subject: [PATCH 523/704] WIP: refactoring local supremal from allele construction --- src/main.c | 84 +++++++++++++++++++----------------------------------- 1 file changed, 29 insertions(+), 55 deletions(-) diff --git a/src/main.c b/src/main.c index 6714260..6286524 100644 --- a/src/main.c +++ b/src/main.c @@ -22,8 +22,9 @@ #define LINE_SIZE 8194 +#define REFERENCE_ID "NC_000022.11" // #define REFERENCE_ID "NC_000006.12" -#define REFERENCE_ID "NC_000001.11" +// #define REFERENCE_ID "NC_000001.11" // line: alphanumeric_id SPDI [distance] @@ -50,7 +51,7 @@ parse_line(char const line[static LINE_SIZE], static int -compare_alleles(void const* a, void const* b) +compare_query_alleles(void const* a, void const* b) { struct GVA_Query_Allele const lhs = *(struct GVA_Query_Allele*) a; struct GVA_Query_Allele const rhs = *(struct GVA_Query_Allele*) b; @@ -61,7 +62,7 @@ compare_alleles(void const* a, void const* b) return -1; } // if return 1; -} // compare_alleles +} // compare_query_alleles int @@ -141,7 +142,7 @@ index_main(int argc, char* argv[static argc]) if (array_length(result.alleles) > 0) { - qsort(result.alleles, array_length(result.alleles), sizeof(*result.alleles), compare_alleles); + qsort(result.alleles, array_length(result.alleles), sizeof(*result.alleles), compare_query_alleles); } // if for (size_t i = 0; i < array_length(result.alleles); ++i) @@ -176,98 +177,70 @@ index_main(int argc, char* argv[static argc]) } // index_main -#define SMALL - - void local_supremal(size_t const len_ref, char const reference[static len_ref], size_t const len_obs, char const observed[static len_obs], size_t const offset) { - fprintf(stderr, "LOCAL %zu %zu :: %zu\n", len_ref, len_obs, offset); if (len_ref == 0 || len_obs == 0) { printf(GVA_VARIANT_FMT_SPDI " %zu\n", GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, ((GVA_Variant) {offset, offset + len_ref, {len_obs, observed}})), len_ref + len_obs); return; } // if - GVA_Matches forward = gva_edit_distance_m(gva_std_allocator, len_ref, reference, len_obs, observed); - - fprintf(stderr, "distance: %zu\n", forward.distance); - fprintf(stderr, "max_lcs_pos: %zu\n", forward.max_lcs_pos); + GVA_Matches forward = gva_edit_distance_m(gva_std_allocator, len_ref, reference, len_obs, observed); gva_string_reverse((GVA_String) {len_ref, reference}); gva_string_reverse((GVA_String) {len_obs, observed}); GVA_Matches backward = gva_edit_distance_m(gva_std_allocator, len_ref, reference, len_obs, observed); - fprintf(stderr, "distance: %zu\n", backward.distance); - fprintf(stderr, "max_lcs_pos: %zu\n", backward.max_lcs_pos); - - size_t const max_lcs_pos_local = forward.max_lcs_pos; - gva_string_reverse((GVA_String) {len_ref, reference}); gva_string_reverse((GVA_String) {len_obs, observed}); size_t sum = 0; - size_t prev_lcs_pos = 0; size_t prev_row = -1; size_t prev_col = -1; - for (size_t i = 0; i < max_lcs_pos_local; ++i) + for (size_t i = 0; i < forward.max_lcs_pos; ++i) { - size_t const j = max_lcs_pos_local - i - 1; - + size_t const j = forward.max_lcs_pos - i - 1; if (forward.matches[i].row == len_ref - backward.matches[j].row - 1 && forward.matches[i].col == len_obs - backward.matches[j].col - 1 && (forward.uniq[i] == 1 || backward.uniq[j] == 1)) { -#ifdef SMALL - fprintf(stderr, "common: %zu: (%u, %u)\n", i, forward.matches[i].row, forward.matches[i].col); -#endif - if (i > prev_lcs_pos + 1 || - forward.matches[i].row > prev_row + 1 || - forward.matches[i].col > prev_col + 1) + size_t const distance = forward.matches[i].row + forward.matches[i].col - 2 * i - sum; + if (distance > 0) { - size_t const distance = forward.matches[i].row + forward.matches[i].col - 2 * i - sum; - if (distance > 0) - { - sum += distance; - //printf("R gap %zu: (%zu, %zu)--(%u, %u) %zu\n", i, prev_row + 1, prev_col + 1, forward[i].row, forward[i].col, distance); - local_supremal(forward.matches[i].row - prev_row - 1, reference + prev_row + 1, forward.matches[i].col - prev_col - 1, observed + prev_col + 1, offset + prev_row + 1); - //printf(GVA_STRING_FMT "\n", (int) (forward[i].row - prev_row - 1), reference + prev_row + 1); - //printf(GVA_STRING_FMT "\n", (int) (forward[i].col - prev_col - 1), observed + prev_col + 1); - } // if + sum += distance; + local_supremal(forward.matches[i].row - prev_row - 1, reference + prev_row + 1, + forward.matches[i].col - prev_col - 1, observed + prev_col + 1, + offset + prev_row + 1); } // if - prev_lcs_pos = i; + prev_row = forward.matches[i].row; prev_col = forward.matches[i].col; } // if } // for - if (len_ref > prev_row + 1 || len_obs > prev_col + 1) + size_t const distance = len_ref + len_obs - 2 * forward.max_lcs_pos - sum; + if (distance > 0) { - size_t const distance = len_ref + len_obs - 2 * max_lcs_pos_local - sum; sum += distance; - //printf(GVA_STRING_FMT " ", (int) (len_ref - prev_row - 1), reference + prev_row + 1); - //printf(GVA_STRING_FMT "\n", (int) (len_obs - prev_col - 1), observed + prev_col + 1); - GVA_LCS_Graph graph = gva_lcs_graph_init(gva_std_allocator, len_ref - prev_row - 1, reference + prev_row + 1, len_obs - prev_col - 1, observed + prev_col + 1, offset + prev_row + 1); - for (size_t i = 0; i < array_length(graph.dom_nodes) - 1; ++i) + GVA_LCS_Graph local = gva_lcs_graph_init(gva_std_allocator, len_ref - prev_row - 1, reference + prev_row + 1, len_obs - prev_col - 1, observed + prev_col + 1, offset + prev_row + 1); + for (size_t i = 0; i < array_length(local.dom_nodes) - 1; ++i) { - printf(GVA_VARIANT_FMT_SPDI " %u\n", GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, gva_lcs_graph_local_supremal(graph, i, i + 1)), graph.dom_nodes[i + 1].distance - graph.dom_nodes[i].distance); + printf(GVA_VARIANT_FMT_SPDI " %u\n", GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, gva_lcs_graph_local_supremal(local, i, i + 1)), local.dom_nodes[i + 1].distance - local.dom_nodes[i].distance); } // for - gva_lcs_graph_destroy(gva_std_allocator, graph, false); - //printf("L " GVA_VARIANT_FMT " %zu %zu+[(%zu, %zu)--(%zu, %zu)]\n", GVA_VARIANT_PRINT(((GVA_Variant) {offset + prev_row + 1, offset + len_ref, {len_obs - prev_col - 1, observed + prev_col + 1}})), distance, offset, prev_row + 1, prev_col + 1, len_ref, len_obs); - //printf("L gap %zu: (%zu, %zu)--(%zu, %zu) %zu\n", max_lcs_pos_local, prev_row + 1, prev_col + 1, len_ref, len_obs, distance); - //printf(GVA_STRING_FMT "\n", (int) (len_ref - prev_row - 1), reference + prev_row + 1); - //printf(GVA_STRING_FMT "\n", (int) (len_obs - prev_col - 1), observed + prev_col + 1); + gva_lcs_graph_destroy(gva_std_allocator, local, false); } // if - //fprintf(stderr, "distance: %zu\n", sum); - - forward.matches = gva_std_allocator.allocate(gva_std_allocator.context, forward.matches, MIN(len_ref, len_obs), 0); - forward.uniq = gva_std_allocator.allocate(gva_std_allocator.context, forward.uniq, MIN(len_ref, len_obs), 0); backward.matches = gva_std_allocator.allocate(gva_std_allocator.context, backward.matches, MIN(len_ref, len_obs), 0); backward.uniq = gva_std_allocator.allocate(gva_std_allocator.context, backward.uniq, MIN(len_ref, len_obs), 0); + forward.matches = gva_std_allocator.allocate(gva_std_allocator.context, forward.matches, MIN(len_ref, len_obs), 0); + forward.uniq = gva_std_allocator.allocate(gva_std_allocator.context, forward.uniq, MIN(len_ref, len_obs), 0); } // local_supremal +//#define SMALL + + int allele_main(int argc, char* argv[static argc]) { @@ -283,11 +256,11 @@ allele_main(int argc, char* argv[static argc]) GVA_LCS_Graph graph = gva_lcs_graph_init(gva_std_allocator, reference.len, reference.str, observed.len, observed.str, 0); // gva_lcs_graph_dot(stderr, graph); + //fprintf(stderr, GVA_VARIANT_FMT " %zu\n", GVA_VARIANT_PRINT(gva_lcs_graph_supremal(graph)), gva_lcs_graph_distance(graph)); for (size_t i = 0; i < array_length(graph.dom_nodes) - 1; ++i) { - fprintf(stderr, GVA_VARIANT_FMT " %u\n", GVA_VARIANT_PRINT(gva_lcs_graph_local_supremal(graph, i, i + 1)), graph.dom_nodes[i + 1].distance - graph.dom_nodes[i].distance); + fprintf(stderr, GVA_VARIANT_FMT_SPDI " %u\n", GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, gva_lcs_graph_local_supremal(graph, i, i + 1)), graph.dom_nodes[i + 1].distance - graph.dom_nodes[i].distance); } // for - fprintf(stderr, GVA_VARIANT_FMT " %zu\n", GVA_VARIANT_PRINT(gva_lcs_graph_supremal(graph)), gva_lcs_graph_distance(graph)); gva_lcs_graph_destroy(gva_std_allocator, graph, false); @@ -358,6 +331,7 @@ allele_main(int argc, char* argv[static argc]) #endif local_supremal(reference.len, reference.str, observed.len, observed.str, 0); + fprintf(stderr, "\n"); #ifndef SMALL gva_string_destroy(gva_std_allocator, observed); From 7895405eaa824fb55f11156ccdeed1d67ac1cf88 Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 27 Feb 2026 22:38:34 +0100 Subject: [PATCH 524/704] WIP: merging graphs --- src/main.c | 126 ++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 100 insertions(+), 26 deletions(-) diff --git a/src/main.c b/src/main.c index 6286524..a6ff31e 100644 --- a/src/main.c +++ b/src/main.c @@ -177,22 +177,93 @@ index_main(int argc, char* argv[static argc]) } // index_main -void -local_supremal(size_t const len_ref, char const reference[static len_ref], - size_t const len_obs, char const observed[static len_obs], +static void +merge(GVA_Allocator const allocator, + GVA_LCS_Graph* const lhs, GVA_LCS_Graph const rhs, size_t const offset) +{ + size_t const offset_nodes = array_length(lhs->nodes); + size_t const offset_edges = array_length(lhs->edges); + size_t const offset_distance = rhs.dom_nodes[array_length(rhs.dom_nodes) - 1].distance; + + gva_uint sink_idx = GVA_NULL; + if (lhs->nodes == NULL) + { + lhs->source = rhs.source; + } // if + else + { + sink_idx = lhs->dom_nodes[array_length(lhs->dom_nodes) - 1].link; + lhs->nodes[sink_idx].match.length += (rhs.nodes[rhs.source].match.row + rhs.nodes[rhs.source].match.length) - + (lhs->nodes[sink_idx].match.row + lhs->nodes[sink_idx].match.length); + lhs->nodes[sink_idx].edges = rhs.nodes[rhs.source].edges + offset_edges; + } // else + + for (size_t i = 0; i < array_length(rhs.nodes); ++i) + { + if (i != rhs.source || sink_idx == GVA_NULL) + { + ARRAY_APPEND(allocator, lhs->nodes, + ((GVA_Node) + { + .match = {rhs.nodes[i].match.row, rhs.nodes[i].match.col + offset, rhs.nodes[i].match.length}, + .edges = rhs.nodes[i].edges == GVA_NULL ? GVA_NULL : rhs.nodes[i].edges + offset_edges, + .lambda = rhs.nodes[i].lambda == GVA_NULL ? GVA_NULL : rhs.nodes[i].lambda + offset_nodes, + })); + } // if + } // for + + for (size_t i = 0; i < array_length(rhs.edges); ++i) + { + ARRAY_APPEND(allocator, lhs->edges, + ((GVA_Edge) + { + .tail = rhs.edges[i].tail + offset_nodes - (rhs.edges[i].tail > rhs.source), + .next = rhs.edges[i].next == GVA_NULL ? GVA_NULL : rhs.edges[i].next + offset_edges, + })); + } // for + + for (size_t i = (sink_idx == GVA_NULL ? 0 : 1); i < array_length(rhs.dom_nodes); ++i) + { + ARRAY_APPEND(allocator, lhs->dom_nodes, + ((GVA_Dom_Node) + { + .match = rhs.dom_nodes[i].match, + .distance = rhs.dom_nodes[i].distance + offset_distance, + .link = rhs.dom_nodes[i].link + offset_nodes, + })); + } // for +} // merge + + +static void +local_supremal(GVA_Allocator const allocator, + size_t const len_ref, char const reference[static len_ref], + size_t const len_obs, char const observed[static len_obs], + size_t const offset_row, size_t const offset_col, + GVA_LCS_Graph* const graph) { if (len_ref == 0 || len_obs == 0) { - printf(GVA_VARIANT_FMT_SPDI " %zu\n", GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, ((GVA_Variant) {offset, offset + len_ref, {len_obs, observed}})), len_ref + len_obs); + GVA_LCS_Graph local = gva_lcs_graph_init(allocator, len_ref, reference, len_obs, observed, offset_row); + + merge(allocator, graph, local, offset_col); + + for (size_t i = 0; i < array_length(local.dom_nodes) - 1; ++i) + { + printf(GVA_VARIANT_FMT_SPDI " %u\n", GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, gva_lcs_graph_local_supremal(local, i, i + 1)), local.dom_nodes[i + 1].distance - local.dom_nodes[i].distance); + } // for + + gva_lcs_graph_destroy(allocator, local, false); + return; } // if - GVA_Matches forward = gva_edit_distance_m(gva_std_allocator, len_ref, reference, len_obs, observed); + GVA_Matches forward = gva_edit_distance_m(allocator, len_ref, reference, len_obs, observed); gva_string_reverse((GVA_String) {len_ref, reference}); gva_string_reverse((GVA_String) {len_obs, observed}); - GVA_Matches backward = gva_edit_distance_m(gva_std_allocator, len_ref, reference, len_obs, observed); + GVA_Matches backward = gva_edit_distance_m(allocator, len_ref, reference, len_obs, observed); gva_string_reverse((GVA_String) {len_ref, reference}); gva_string_reverse((GVA_String) {len_obs, observed}); @@ -210,9 +281,11 @@ local_supremal(size_t const len_ref, char const reference[static len_ref], if (distance > 0) { sum += distance; - local_supremal(forward.matches[i].row - prev_row - 1, reference + prev_row + 1, + local_supremal(allocator, + forward.matches[i].row - prev_row - 1, reference + prev_row + 1, forward.matches[i].col - prev_col - 1, observed + prev_col + 1, - offset + prev_row + 1); + offset_row + prev_row + 1, offset_col + prev_col + 1, + graph); } // if prev_row = forward.matches[i].row; @@ -223,22 +296,25 @@ local_supremal(size_t const len_ref, char const reference[static len_ref], if (distance > 0) { sum += distance; - GVA_LCS_Graph local = gva_lcs_graph_init(gva_std_allocator, len_ref - prev_row - 1, reference + prev_row + 1, len_obs - prev_col - 1, observed + prev_col + 1, offset + prev_row + 1); + GVA_LCS_Graph local = gva_lcs_graph_init(allocator, len_ref - prev_row - 1, reference + prev_row + 1, len_obs - prev_col - 1, observed + prev_col + 1, offset_row + prev_row + 1); + + merge(allocator, graph, local, offset_col + prev_col + 1); + for (size_t i = 0; i < array_length(local.dom_nodes) - 1; ++i) { printf(GVA_VARIANT_FMT_SPDI " %u\n", GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, gva_lcs_graph_local_supremal(local, i, i + 1)), local.dom_nodes[i + 1].distance - local.dom_nodes[i].distance); } // for - gva_lcs_graph_destroy(gva_std_allocator, local, false); + gva_lcs_graph_destroy(allocator, local, false); } // if - backward.matches = gva_std_allocator.allocate(gva_std_allocator.context, backward.matches, MIN(len_ref, len_obs), 0); - backward.uniq = gva_std_allocator.allocate(gva_std_allocator.context, backward.uniq, MIN(len_ref, len_obs), 0); - forward.matches = gva_std_allocator.allocate(gva_std_allocator.context, forward.matches, MIN(len_ref, len_obs), 0); - forward.uniq = gva_std_allocator.allocate(gva_std_allocator.context, forward.uniq, MIN(len_ref, len_obs), 0); + backward.matches = allocator.allocate(allocator.context, backward.matches, MIN(len_ref, len_obs), 0); + backward.uniq = allocator.allocate(allocator.context, backward.uniq, MIN(len_ref, len_obs), 0); + forward.matches = allocator.allocate(allocator.context, forward.matches, MIN(len_ref, len_obs), 0); + forward.uniq = allocator.allocate(allocator.context, forward.uniq, MIN(len_ref, len_obs), 0); } // local_supremal -//#define SMALL +#define SMALL int @@ -254,15 +330,9 @@ allele_main(int argc, char* argv[static argc]) GVA_String reference = {strlen(argv[1]), argv[1]}; GVA_String observed = {strlen(argv[2]), argv[2]}; - GVA_LCS_Graph graph = gva_lcs_graph_init(gva_std_allocator, reference.len, reference.str, observed.len, observed.str, 0); - // gva_lcs_graph_dot(stderr, graph); - //fprintf(stderr, GVA_VARIANT_FMT " %zu\n", GVA_VARIANT_PRINT(gva_lcs_graph_supremal(graph)), gva_lcs_graph_distance(graph)); - for (size_t i = 0; i < array_length(graph.dom_nodes) - 1; ++i) - { - fprintf(stderr, GVA_VARIANT_FMT_SPDI " %u\n", GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, gva_lcs_graph_local_supremal(graph, i, i + 1)), graph.dom_nodes[i + 1].distance - graph.dom_nodes[i].distance); - } // for - - gva_lcs_graph_destroy(gva_std_allocator, graph, false); + GVA_LCS_Graph small = gva_lcs_graph_init(gva_std_allocator, reference.len, reference.str, observed.len, observed.str, 0); + gva_lcs_graph_dot(stderr, small); + gva_lcs_graph_destroy(gva_std_allocator, small, false); #else errno = 0; @@ -330,8 +400,12 @@ allele_main(int argc, char* argv[static argc]) } // if #endif - local_supremal(reference.len, reference.str, observed.len, observed.str, 0); - fprintf(stderr, "\n"); + GVA_LCS_Graph graph = {.observed = observed}; + local_supremal(gva_std_allocator, reference.len, reference.str, observed.len, observed.str, 0, 0, &graph); + + gva_lcs_graph_dot(stderr, graph); + + gva_lcs_graph_destroy(gva_std_allocator, graph, false); #ifndef SMALL gva_string_destroy(gva_std_allocator, observed); From 7ff66f4354434bc34a68d527c0f1d7a58c8dd2b8 Mon Sep 17 00:00:00 2001 From: jkvis Date: Sat, 28 Feb 2026 10:08:06 +0100 Subject: [PATCH 525/704] Also update the dom_nodes to the supremal perspective --- src/lcs_graph.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/lcs_graph.c b/src/lcs_graph.c index b7ec7e8..36538f0 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -299,7 +299,13 @@ gva_lcs_graph_init(GVA_Allocator const allocator, graph.nodes[source.idx].match.col += graph.dom_nodes[0].match.length; graph.nodes[source.idx].match.length -= graph.dom_nodes[0].match.length; + graph.dom_nodes[0].match.row += graph.dom_nodes[0].match.length; + graph.dom_nodes[0].match.col += graph.dom_nodes[0].match.length; + graph.dom_nodes[0].match.length = 0; + graph.nodes[sink.idx].match.length -= graph.dom_nodes[array_length(graph.dom_nodes) - 1].match.length; + + graph.dom_nodes[array_length(graph.dom_nodes) - 1].match.length = 0; } // if graph.source = source.idx; From 67903ca8c4e67c7beeabb7672e4d00d53d9e509f Mon Sep 17 00:00:00 2001 From: jkvis Date: Sat, 28 Feb 2026 10:08:24 +0100 Subject: [PATCH 526/704] WIP: merging graphs --- src/main.c | 67 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 40 insertions(+), 27 deletions(-) diff --git a/src/main.c b/src/main.c index a6ff31e..c5b4019 100644 --- a/src/main.c +++ b/src/main.c @@ -184,19 +184,20 @@ merge(GVA_Allocator const allocator, { size_t const offset_nodes = array_length(lhs->nodes); size_t const offset_edges = array_length(lhs->edges); - size_t const offset_distance = rhs.dom_nodes[array_length(rhs.dom_nodes) - 1].distance; gva_uint sink_idx = GVA_NULL; - if (lhs->nodes == NULL) - { - lhs->source = rhs.source; - } // if - else + if (lhs->nodes != NULL) { sink_idx = lhs->dom_nodes[array_length(lhs->dom_nodes) - 1].link; lhs->nodes[sink_idx].match.length += (rhs.nodes[rhs.source].match.row + rhs.nodes[rhs.source].match.length) - (lhs->nodes[sink_idx].match.row + lhs->nodes[sink_idx].match.length); lhs->nodes[sink_idx].edges = rhs.nodes[rhs.source].edges + offset_edges; + lhs->dom_nodes[array_length(lhs->dom_nodes) - 1].match.length += (rhs.dom_nodes[0].match.row + rhs.dom_nodes[0].match.length) - + (lhs->dom_nodes[array_length(lhs->dom_nodes) - 1].match.row + lhs->dom_nodes[array_length(lhs->dom_nodes) - 1].match.length); + } // if + else + { + lhs->source = rhs.source; } // else for (size_t i = 0; i < array_length(rhs.nodes); ++i) @@ -218,19 +219,19 @@ merge(GVA_Allocator const allocator, ARRAY_APPEND(allocator, lhs->edges, ((GVA_Edge) { - .tail = rhs.edges[i].tail + offset_nodes - (rhs.edges[i].tail > rhs.source), + .tail = rhs.edges[i].tail + offset_nodes - (rhs.edges[i].tail > rhs.source && sink_idx != GVA_NULL), .next = rhs.edges[i].next == GVA_NULL ? GVA_NULL : rhs.edges[i].next + offset_edges, })); } // for - for (size_t i = (sink_idx == GVA_NULL ? 0 : 1); i < array_length(rhs.dom_nodes); ++i) + for (size_t i = (sink_idx != GVA_NULL); i < array_length(rhs.dom_nodes); ++i) { ARRAY_APPEND(allocator, lhs->dom_nodes, ((GVA_Dom_Node) { - .match = rhs.dom_nodes[i].match, - .distance = rhs.dom_nodes[i].distance + offset_distance, - .link = rhs.dom_nodes[i].link + offset_nodes, + .match = {rhs.dom_nodes[i].match.row, rhs.dom_nodes[i].match.col + offset, rhs.dom_nodes[i].match.length}, + .distance = rhs.dom_nodes[i].distance + lhs->dom_nodes[array_length(lhs->dom_nodes) - 1].distance, + .link = rhs.dom_nodes[i].link + offset_nodes - (rhs.dom_nodes[i].link > rhs.source && sink_idx != GVA_NULL), })); } // for } // merge @@ -246,16 +247,8 @@ local_supremal(GVA_Allocator const allocator, if (len_ref == 0 || len_obs == 0) { GVA_LCS_Graph local = gva_lcs_graph_init(allocator, len_ref, reference, len_obs, observed, offset_row); - merge(allocator, graph, local, offset_col); - - for (size_t i = 0; i < array_length(local.dom_nodes) - 1; ++i) - { - printf(GVA_VARIANT_FMT_SPDI " %u\n", GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, gva_lcs_graph_local_supremal(local, i, i + 1)), local.dom_nodes[i + 1].distance - local.dom_nodes[i].distance); - } // for - gva_lcs_graph_destroy(allocator, local, false); - return; } // if @@ -297,13 +290,7 @@ local_supremal(GVA_Allocator const allocator, { sum += distance; GVA_LCS_Graph local = gva_lcs_graph_init(allocator, len_ref - prev_row - 1, reference + prev_row + 1, len_obs - prev_col - 1, observed + prev_col + 1, offset_row + prev_row + 1); - merge(allocator, graph, local, offset_col + prev_col + 1); - - for (size_t i = 0; i < array_length(local.dom_nodes) - 1; ++i) - { - printf(GVA_VARIANT_FMT_SPDI " %u\n", GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, gva_lcs_graph_local_supremal(local, i, i + 1)), local.dom_nodes[i + 1].distance - local.dom_nodes[i].distance); - } // for gva_lcs_graph_destroy(allocator, local, false); } // if @@ -331,7 +318,18 @@ allele_main(int argc, char* argv[static argc]) GVA_String observed = {strlen(argv[2]), argv[2]}; GVA_LCS_Graph small = gva_lcs_graph_init(gva_std_allocator, reference.len, reference.str, observed.len, observed.str, 0); - gva_lcs_graph_dot(stderr, small); + for (size_t i = 0; i < array_length(small.dom_nodes) - 1; ++i) + { + fprintf(stderr, "(%u, %u, %u)\n", small.dom_nodes[i].match.row, small.dom_nodes[i].match.col, small.dom_nodes[i].match.length); + fprintf(stderr, GVA_VARIANT_FMT " %u\n", + GVA_VARIANT_PRINT(gva_lcs_graph_local_supremal(small, i, i + 1)), + small.dom_nodes[i + 1].distance - small.dom_nodes[i].distance); + } // for + fprintf(stderr, "(%u, %u, %u)\n\n", + small.dom_nodes[array_length(small.dom_nodes) - 1].match.row, + small.dom_nodes[array_length(small.dom_nodes) - 1].match.col, + small.dom_nodes[array_length(small.dom_nodes) - 1].match.length); + //gva_lcs_graph_dot(stderr, small); gva_lcs_graph_destroy(gva_std_allocator, small, false); #else @@ -402,8 +400,23 @@ allele_main(int argc, char* argv[static argc]) GVA_LCS_Graph graph = {.observed = observed}; local_supremal(gva_std_allocator, reference.len, reference.str, observed.len, observed.str, 0, 0, &graph); + if (graph.nodes == NULL) + { + graph = gva_lcs_graph_init(gva_std_allocator, reference.len, reference.str, observed.len, observed.str, 0); + } // if - gva_lcs_graph_dot(stderr, graph); + for (size_t i = 0; i < array_length(graph.dom_nodes) - 1; ++i) + { + fprintf(stderr, "(%u, %u, %u)\n", graph.dom_nodes[i].match.row, graph.dom_nodes[i].match.col, graph.dom_nodes[i].match.length); + fprintf(stderr, GVA_VARIANT_FMT " %u\n", + GVA_VARIANT_PRINT(gva_lcs_graph_local_supremal(graph, i, i + 1)), + graph.dom_nodes[i + 1].distance - graph.dom_nodes[i].distance); + } // for + fprintf(stderr, "(%u, %u, %u)\n\n", + graph.dom_nodes[array_length(graph.dom_nodes) - 1].match.row, + graph.dom_nodes[array_length(graph.dom_nodes) - 1].match.col, + graph.dom_nodes[array_length(graph.dom_nodes) - 1].match.length); + //gva_lcs_graph_dot(stderr, graph); gva_lcs_graph_destroy(gva_std_allocator, graph, false); From ba88e2fc82ceef3c7090e8a713d84ad30fb525c3 Mon Sep 17 00:00:00 2001 From: jkvis Date: Sat, 28 Feb 2026 10:59:20 +0100 Subject: [PATCH 527/704] Merged LCS graph for HG00096_A chr22 --- src/main.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/main.c b/src/main.c index c5b4019..40e6729 100644 --- a/src/main.c +++ b/src/main.c @@ -184,6 +184,7 @@ merge(GVA_Allocator const allocator, { size_t const offset_nodes = array_length(lhs->nodes); size_t const offset_edges = array_length(lhs->edges); + size_t offset_distance = 0; gva_uint sink_idx = GVA_NULL; if (lhs->nodes != NULL) @@ -194,6 +195,7 @@ merge(GVA_Allocator const allocator, lhs->nodes[sink_idx].edges = rhs.nodes[rhs.source].edges + offset_edges; lhs->dom_nodes[array_length(lhs->dom_nodes) - 1].match.length += (rhs.dom_nodes[0].match.row + rhs.dom_nodes[0].match.length) - (lhs->dom_nodes[array_length(lhs->dom_nodes) - 1].match.row + lhs->dom_nodes[array_length(lhs->dom_nodes) - 1].match.length); + offset_distance = lhs->dom_nodes[array_length(lhs->dom_nodes) - 1].distance; } // if else { @@ -230,7 +232,7 @@ merge(GVA_Allocator const allocator, ((GVA_Dom_Node) { .match = {rhs.dom_nodes[i].match.row, rhs.dom_nodes[i].match.col + offset, rhs.dom_nodes[i].match.length}, - .distance = rhs.dom_nodes[i].distance + lhs->dom_nodes[array_length(lhs->dom_nodes) - 1].distance, + .distance = rhs.dom_nodes[i].distance + offset_distance, .link = rhs.dom_nodes[i].link + offset_nodes - (rhs.dom_nodes[i].link > rhs.source && sink_idx != GVA_NULL), })); } // for @@ -301,7 +303,7 @@ local_supremal(GVA_Allocator const allocator, } // local_supremal -#define SMALL +//#define SMALL int @@ -374,7 +376,7 @@ allele_main(int argc, char* argv[static argc]) if (array_length(variants) > 0 && trimmed.start < variants[array_length(variants) - 1].end) { - fprintf(stderr, "dropped: at line %zu: %s", line_count + 1, line); + fprintf(stderr, "dropped at line %zu: %s", line_count + 1, line); dropped += 1; continue; } // if @@ -407,15 +409,15 @@ allele_main(int argc, char* argv[static argc]) for (size_t i = 0; i < array_length(graph.dom_nodes) - 1; ++i) { - fprintf(stderr, "(%u, %u, %u)\n", graph.dom_nodes[i].match.row, graph.dom_nodes[i].match.col, graph.dom_nodes[i].match.length); - fprintf(stderr, GVA_VARIANT_FMT " %u\n", - GVA_VARIANT_PRINT(gva_lcs_graph_local_supremal(graph, i, i + 1)), + //fprintf(stderr, "(%u, %u, %u)\n", graph.dom_nodes[i].match.row, graph.dom_nodes[i].match.col, graph.dom_nodes[i].match.length); + fprintf(stdout, GVA_VARIANT_FMT_SPDI " %u\n", + GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, gva_lcs_graph_local_supremal(graph, i, i + 1)), graph.dom_nodes[i + 1].distance - graph.dom_nodes[i].distance); } // for - fprintf(stderr, "(%u, %u, %u)\n\n", - graph.dom_nodes[array_length(graph.dom_nodes) - 1].match.row, - graph.dom_nodes[array_length(graph.dom_nodes) - 1].match.col, - graph.dom_nodes[array_length(graph.dom_nodes) - 1].match.length); + //fprintf(stderr, "(%u, %u, %u)\n\n", + // graph.dom_nodes[array_length(graph.dom_nodes) - 1].match.row, + // graph.dom_nodes[array_length(graph.dom_nodes) - 1].match.col, + // graph.dom_nodes[array_length(graph.dom_nodes) - 1].match.length); //gva_lcs_graph_dot(stderr, graph); gva_lcs_graph_destroy(gva_std_allocator, graph, false); From 2b56bae969600211138fe0254ed82624aad1e114 Mon Sep 17 00:00:00 2001 From: jkvis Date: Sat, 28 Feb 2026 11:55:00 +0100 Subject: [PATCH 528/704] HG00096_A on chr1 --- src/main.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/main.c b/src/main.c index 40e6729..4135f5b 100644 --- a/src/main.c +++ b/src/main.c @@ -22,9 +22,9 @@ #define LINE_SIZE 8194 -#define REFERENCE_ID "NC_000022.11" +// #define REFERENCE_ID "NC_000022.11" // #define REFERENCE_ID "NC_000006.12" -// #define REFERENCE_ID "NC_000001.11" +#define REFERENCE_ID "NC_000001.11" // line: alphanumeric_id SPDI [distance] @@ -184,18 +184,20 @@ merge(GVA_Allocator const allocator, { size_t const offset_nodes = array_length(lhs->nodes); size_t const offset_edges = array_length(lhs->edges); - size_t offset_distance = 0; gva_uint sink_idx = GVA_NULL; - if (lhs->nodes != NULL) + size_t offset_distance = 0; + if (offset_nodes > 0) { sink_idx = lhs->dom_nodes[array_length(lhs->dom_nodes) - 1].link; + offset_distance = lhs->dom_nodes[array_length(lhs->dom_nodes) - 1].distance; + + // merge the sink of lhs with the source of rhs lhs->nodes[sink_idx].match.length += (rhs.nodes[rhs.source].match.row + rhs.nodes[rhs.source].match.length) - (lhs->nodes[sink_idx].match.row + lhs->nodes[sink_idx].match.length); lhs->nodes[sink_idx].edges = rhs.nodes[rhs.source].edges + offset_edges; lhs->dom_nodes[array_length(lhs->dom_nodes) - 1].match.length += (rhs.dom_nodes[0].match.row + rhs.dom_nodes[0].match.length) - (lhs->dom_nodes[array_length(lhs->dom_nodes) - 1].match.row + lhs->dom_nodes[array_length(lhs->dom_nodes) - 1].match.length); - offset_distance = lhs->dom_nodes[array_length(lhs->dom_nodes) - 1].distance; } // if else { @@ -419,6 +421,8 @@ allele_main(int argc, char* argv[static argc]) // graph.dom_nodes[array_length(graph.dom_nodes) - 1].match.col, // graph.dom_nodes[array_length(graph.dom_nodes) - 1].match.length); //gva_lcs_graph_dot(stderr, graph); + fprintf(stderr, "#nodes: %zu\n", array_length(graph.nodes)); + fprintf(stderr, "#edges: %zu\n", array_length(graph.edges)); gva_lcs_graph_destroy(gva_std_allocator, graph, false); From 55552af4231f0649b7c16f692e48a10b91b4a7b3 Mon Sep 17 00:00:00 2001 From: jkvis Date: Sat, 28 Feb 2026 12:49:08 +0100 Subject: [PATCH 529/704] Refactored LCS graph construction from alleles --- include/edit.h | 24 ------ include/edit_m.h | 30 ------- include/lcs_graph.h | 6 ++ src/align.c | 106 +++++++++++++++++++++++- src/align.h | 19 +++++ src/edit.c | 114 -------------------------- src/edit_m.c | 111 ------------------------- src/lcs_graph.c | 146 ++++++++++++++++++++++++++++++++- src/main.c | 193 +------------------------------------------- 9 files changed, 279 insertions(+), 470 deletions(-) delete mode 100644 include/edit_m.h delete mode 100644 src/edit_m.c diff --git a/include/edit.h b/include/edit.h index 4e934c0..70f30ed 100644 --- a/include/edit.h +++ b/include/edit.h @@ -5,22 +5,6 @@ #include // size_t #include "allocator.h" // GVA_Allocator -/* -#include "types.h" // gva_uint - - -typedef struct -{ - struct Match - { - gva_uint row; - gva_uint col; - }* matches; - char* uniq; - size_t max_lcs_pos; - size_t distance; -} GVA_Matches; -*/ size_t @@ -29,12 +13,4 @@ gva_edit_distance(GVA_Allocator const allocator, size_t const len_obs, char const observed[static restrict len_obs]); -/* -GVA_Matches -gva_edit_distance_matches(GVA_Allocator const allocator, - size_t const len_ref, char const reference[static restrict len_ref], - size_t const len_obs, char const observed[static restrict len_obs]); -*/ - - #endif // GVA_EDIT_H diff --git a/include/edit_m.h b/include/edit_m.h deleted file mode 100644 index cb09ce2..0000000 --- a/include/edit_m.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef GVA_EDIT_M_H -#define GVA_EDIT_M_H - - -#include // size_t - -#include "allocator.h" // GVA_Allocator -#include "types.h" // gva_uint - - -typedef struct -{ - struct - { - gva_uint row; - gva_uint col; - }* restrict matches; - char* restrict uniq; - size_t max_lcs_pos; - size_t distance; -} GVA_Matches; - - -GVA_Matches -gva_edit_distance_m(GVA_Allocator const allocator, - size_t const len_ref, char const reference[static restrict len_ref], - size_t const len_obs, char const observed[static restrict len_obs]); - - -#endif // GVA_EDIT_M_H diff --git a/include/lcs_graph.h b/include/lcs_graph.h index d64aadb..3e88a85 100644 --- a/include/lcs_graph.h +++ b/include/lcs_graph.h @@ -65,6 +65,12 @@ gva_lcs_graph_destroy(GVA_Allocator const allocator, GVA_LCS_Graph self, bool const observed); +GVA_LCS_Graph +gva_lcs_graph_from_allele(GVA_Allocator const allocator, + size_t const len_ref, char const reference[static restrict len_ref], + size_t const n, GVA_Variant const variants[static restrict n]); + + GVA_LCS_Graph gva_lcs_graph_from_variants(GVA_Allocator const allocator, size_t const len_ref, char const reference[static restrict len_ref], diff --git a/src/align.c b/src/align.c index 9f32610..2fb383c 100644 --- a/src/align.c +++ b/src/align.c @@ -5,7 +5,7 @@ #include "../include/allocator.h" // GVA_Allocator #include "../include/types.h" // GVA_NULL, gva_uint -#include "align.h" // LCS_Alignment, LCS_Node, lcs_align +#include "align.h" // LCS_Alignment, LCS_Matches, LCS_Node, lcs_align* #include "array.h" // ARRAY_APPEND #include "common.h" // ABS, MAX, MIN @@ -216,3 +216,107 @@ lcs_align(GVA_Allocator const allocator, size * sizeof(*context.diagonals), 0); return lcs; } // lcs_align + + + +static inline size_t +onp_snake(size_t const m, char const a[static restrict m], + size_t const n, char const b[static restrict n], + intmax_t const k, intmax_t const lower, intmax_t const upper, + intmax_t const delta, size_t const p, bool const swapped, + LCS_Matches result[static restrict 1]) +{ + size_t col = MAX(lower, upper); + size_t row = col - k; + + intmax_t const d_row = m - row; + intmax_t const d_col = n - col; + + while (row < m && col < n && a[row] == b[col]) + { + row += 1; + col += 1; + size_t const lcs_pos = (row + col - ABS(delta) - 2 * p + ABS(d_row - d_col)) / 2; + result->uniq[lcs_pos - 1] = 0; + if (lcs_pos > result->max_lcs_pos) + { + result->max_lcs_pos = lcs_pos; + result->uniq[lcs_pos - 1] = 1; + if (swapped) + { + result->match[lcs_pos - 1].row = col - 1; + result->match[lcs_pos - 1].col = row - 1; + } // if + else + { + result->match[lcs_pos - 1].row = row - 1; + result->match[lcs_pos - 1].col = col - 1; + } // else + } // if + } // while + return col; +} // onp_snake + + +static LCS_Matches +onp_compare(GVA_Allocator const allocator, + size_t const m, char const a[static restrict m], + size_t const n, char const b[static restrict n], + bool const swapped) +{ + intmax_t const delta = n - m; + size_t const offset = m + 1; + size_t const size = m + n + 3; + + intmax_t* restrict fp = allocator.allocate(allocator.context, NULL, 0, size * sizeof(*fp)); + LCS_Matches result = + { + .match = allocator.allocate(allocator.context, NULL, 0, sizeof(*result.match) * m), + .uniq = allocator.allocate(allocator.context, NULL, 0, sizeof(*result.uniq) * m), + }; + if (fp == NULL || result.match == NULL || result.uniq == NULL) + { + result.uniq = allocator.allocate(allocator.context, result.uniq, sizeof(*result.uniq) * m, 0); + result.match = allocator.allocate(allocator.context, result.match, sizeof(*result.match) * m, 0); + fp = allocator.allocate(allocator.context, fp, size * sizeof(*fp), 0); + return (LCS_Matches) {NULL}; + } // if + + for (intmax_t i = -1; i <= delta; ++i) + { + fp[i + offset] = -1; + } // for + + size_t p = 0; + while ((size_t) fp[delta + offset] != n) + { + fp[-p - 1 + offset] = -1; + fp[delta + p + 1 + offset] = -1; + for (intmax_t k = -p; k <= delta - 1; ++k) + { + fp[k + offset] = onp_snake(m, a, n, b, k, fp[k - 1 + offset] + 1, fp[k + 1 + offset], delta, p, swapped, &result); + } // for + for (intmax_t k = delta + p; k >= delta + 1; --k) + { + fp[k + offset] = onp_snake(m, a, n, b, k, fp[k - 1 + offset] + 1, fp[k + 1 + offset], delta, p, swapped, &result); + } // for + fp[delta + offset] = onp_snake(m, a, n, b, delta, fp[delta - 1 + offset] + 1, fp[delta + 1 + offset], delta, p, swapped, &result); + p += 1; + } // while + + allocator.allocate(allocator.context, fp, size * sizeof(*fp), 0); + + result.distance = delta + 2 * (p - 1); + return result; +} // onp_compare + + +inline LCS_Matches +lcs_align_one(GVA_Allocator const allocator, + size_t const len_ref, char const reference[static restrict len_ref], + size_t const len_obs, char const observed[static restrict len_obs]) +{ + return len_ref > len_obs ? + onp_compare(allocator, len_obs, observed, len_ref, reference, true) : + onp_compare(allocator, len_ref, reference, len_obs, observed, false); +} // lcs_align_one diff --git a/src/align.h b/src/align.h index 0d9f77c..d6a9f11 100644 --- a/src/align.h +++ b/src/align.h @@ -40,4 +40,23 @@ lcs_align(GVA_Allocator const allocator, size_t const offset); +typedef struct +{ + struct + { + gva_uint row; + gva_uint col; + }* restrict match; + char* restrict uniq; + size_t max_lcs_pos; + size_t distance; +} LCS_Matches; + + +LCS_Matches +lcs_align_one(GVA_Allocator const allocator, + size_t const len_ref, char const reference[static restrict len_ref], + size_t const len_obs, char const observed[static restrict len_obs]); + + #endif // GVA_ALIGN_H diff --git a/src/edit.c b/src/edit.c index 6dca029..3da7534 100644 --- a/src/edit.c +++ b/src/edit.c @@ -66,97 +66,6 @@ onp_compare(GVA_Allocator const allocator, } // onp_compare -/* -static inline size_t -onp_snake_matches(size_t const m, char const a[static restrict m], - size_t const n, char const b[static restrict n], - intmax_t const k, - intmax_t const lower, - intmax_t const upper, - size_t const p, - GVA_Matches matches) -{ - size_t col = MAX(lower, upper); - size_t row = col - k; - - intmax_t const d_row = m - row; - intmax_t const d_col = n - col; - - while (row < m && col < n && a[row] == b[col]) - { - row += 1; - col += 1; - size_t const lcs_pos = (row + col - (n - m) - 2 * p + ABS(d_row - d_col)) / 2; - matches.uniq[lcs_pos - 1] = 0; - if (lcs_pos > matches.max_lcs_pos) - { - matches.max_lcs_pos = lcs_pos; - matches.uniq[lcs_pos - 1] = 1; - matches.matches[lcs_pos - 1].row = row - 1; - matches.matches[lcs_pos - 1].col = col - 1; - } // if - } // while - return col; -} // onp_snake_matches - - -static GVA_Matches -onp_compare_matches(GVA_Allocator const allocator, - size_t const m, char const a[static restrict m], - size_t const n, char const b[static restrict n]) -{ - intmax_t const delta = n - m; - size_t const offset = m + 1; - size_t const size = m + n + 3; - intmax_t* const restrict fp = allocator.allocate(allocator.context, NULL, 0, size * sizeof(*fp)); - if (fp == NULL) - { - return (GVA_Matches) {NULL}; - } // if - - for (intmax_t i = -1; i <= delta; ++i) - { - fp[i + offset] = -1; - } // for - - GVA_Matches result = - { - .matches = allocator.allocate(allocator.context, NULL, 0, sizeof(*result.matches) * m), - .uniq = allocator.allocate(allocator.context, NULL, 0, sizeof(*result.uniq) * m), - .max_lcs_pos = 0, - }; - if (result.matches == NULL || result.uniq == NULL) - { - result.uniq = allocator.allocate(allocator.context, result.uniq, sizeof(*result.uniq) * m, 0); - result.matches = allocator.allocate(allocator.context, result.matches, sizeof(*result.matches) * m, 0); - allocator.allocate(allocator.context, fp, size * sizeof(*fp), 0); - return (GVA_Matches) {NULL}; - } // if - - size_t p = 0; - while ((size_t) fp[delta + offset] != n) - { - fp[-p - 1 + offset] = -1; - fp[delta + p + 1 + offset] = -1; - for (intmax_t k = -p; k <= delta - 1; ++k) - { - fp[k + offset] = onp_snake_matches(m, a, n, b, k, fp[k - 1 + offset] + 1, fp[k + 1 + offset], p, result); - } // for - for (intmax_t k = delta + p; k >= delta + 1; --k) - { - fp[k + offset] = onp_snake_matches(m, a, n, b, k, fp[k - 1 + offset] + 1, fp[k + 1 + offset], p, result); - } // for - fp[delta + offset] = onp_snake_matches(m, a, n, b, delta, fp[delta - 1 + offset] + 1, fp[delta + 1 + offset], p, result); - p += 1; - } // while - - allocator.allocate(allocator.context, fp, size * sizeof(*fp), 0); - result.distance = delta + 2 * (p - 1); - return result; -} // onp_compare_matches -*/ - - inline size_t gva_edit_distance(GVA_Allocator const allocator, size_t const len_ref, char const reference[static restrict len_ref], @@ -166,26 +75,3 @@ gva_edit_distance(GVA_Allocator const allocator, onp_compare(allocator, len_obs, observed, len_ref, reference) : onp_compare(allocator, len_ref, reference, len_obs, observed); } // gva_edit_distance - - -/* -inline GVA_Matches -gva_edit_distance_matches(GVA_Allocator const allocator, - size_t const len_ref, char const reference[static restrict len_ref], - size_t const len_obs, char const observed[static restrict len_obs]) -{ - if (len_ref > len_obs) - { - GVA_Matches result = onp_compare_matches(allocator, len_obs, observed, len_ref, reference); - for (size_t i = 0; i < result.max_lcs_pos; ++i) - { - gva_uint const temp = result.matches[i].row; - result.matches[i].row = result.matches[i].col; - result.matches[i].col = temp; - } // for - return result; - } // if - - return onp_compare_matches(allocator, len_ref, reference, len_obs, observed); -} // gva_edit_distance_matches -*/ diff --git a/src/edit_m.c b/src/edit_m.c deleted file mode 100644 index 2f4f62d..0000000 --- a/src/edit_m.c +++ /dev/null @@ -1,111 +0,0 @@ -#include // intmax_t -#include // bool, false, true -#include // NULL, size_t - - -#include "../include/allocator.h" // GVA_Allocator -#include "../include/edit_m.h" // gva_edit_distance_m -#include "common.h" // ABS, MAX - - -static inline size_t -onp_snake(size_t const m, char const a[static restrict m], - size_t const n, char const b[static restrict n], - intmax_t const k, intmax_t const lower, intmax_t const upper, - intmax_t const delta, size_t const p, bool const swapped, - GVA_Matches result[static restrict 1]) -{ - size_t col = MAX(lower, upper); - size_t row = col - k; - - intmax_t const d_row = m - row; - intmax_t const d_col = n - col; - - while (row < m && col < n && a[row] == b[col]) - { - row += 1; - col += 1; - size_t const lcs_pos = (row + col - ABS(delta) - 2 * p + ABS(d_row - d_col)) / 2; - result->uniq[lcs_pos - 1] = 0; - if (lcs_pos > result->max_lcs_pos) - { - result->max_lcs_pos = lcs_pos; - result->uniq[lcs_pos - 1] = 1; - if (swapped) - { - result->matches[lcs_pos - 1].row = col - 1; - result->matches[lcs_pos - 1].col = row - 1; - } // if - else - { - result->matches[lcs_pos - 1].row = row - 1; - result->matches[lcs_pos - 1].col = col - 1; - } // else - } // if - } // while - return col; -} // onp_snake - - -static GVA_Matches -onp_compare(GVA_Allocator const allocator, - size_t const m, char const a[static restrict m], - size_t const n, char const b[static restrict n], - bool const swapped) -{ - intmax_t const delta = n - m; - size_t const offset = m + 1; - size_t const size = m + n + 3; - - intmax_t* restrict fp = allocator.allocate(allocator.context, NULL, 0, size * sizeof(*fp)); - GVA_Matches result = - { - .matches = allocator.allocate(allocator.context, NULL, 0, sizeof(*result.matches) * m), - .uniq = allocator.allocate(allocator.context, NULL, 0, sizeof(*result.uniq) * m), - }; - if (fp == NULL || result.matches == NULL || result.uniq == NULL) - { - result.uniq = allocator.allocate(allocator.context, result.uniq, sizeof(*result.uniq) * m, 0); - result.matches = allocator.allocate(allocator.context, result.matches, sizeof(*result.matches) * m, 0); - fp = allocator.allocate(allocator.context, fp, size * sizeof(*fp), 0); - return (GVA_Matches) {NULL}; - } // if - - for (intmax_t i = -1; i <= delta; ++i) - { - fp[i + offset] = -1; - } // for - - size_t p = 0; - while ((size_t) fp[delta + offset] != n) - { - fp[-p - 1 + offset] = -1; - fp[delta + p + 1 + offset] = -1; - for (intmax_t k = -p; k <= delta - 1; ++k) - { - fp[k + offset] = onp_snake(m, a, n, b, k, fp[k - 1 + offset] + 1, fp[k + 1 + offset], delta, p, swapped, &result); - } // for - for (intmax_t k = delta + p; k >= delta + 1; --k) - { - fp[k + offset] = onp_snake(m, a, n, b, k, fp[k - 1 + offset] + 1, fp[k + 1 + offset], delta, p, swapped, &result); - } // for - fp[delta + offset] = onp_snake(m, a, n, b, delta, fp[delta - 1 + offset] + 1, fp[delta + 1 + offset], delta, p, swapped, &result); - p += 1; - } // while - - allocator.allocate(allocator.context, fp, size * sizeof(*fp), 0); - - result.distance = delta + 2 * (p - 1); - return result; -} // onp_compare - - -inline GVA_Matches -gva_edit_distance_m(GVA_Allocator const allocator, - size_t const len_ref, char const reference[static restrict len_ref], - size_t const len_obs, char const observed[static restrict len_obs]) -{ - return len_ref > len_obs ? - onp_compare(allocator, len_obs, observed, len_ref, reference, true) : - onp_compare(allocator, len_ref, reference, len_obs, observed, false); -} // gva_edit_distance_m diff --git a/src/lcs_graph.c b/src/lcs_graph.c index 36538f0..e6608b5 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -9,12 +9,141 @@ // GVA_Edge, GVA_Node, gva_lcs_graph_* #include "../include/string.h" // GVA_String, gva_string_* #include "../include/variant.h" // GVA_Variant, gva_variant_length -#include "align.h" // LCS_Alignment, lcs_align +#include "align.h" // LCS_Alignment, LCS_Matches, lcs_align* #include "array.h" // ARRAY_*, array_length #include "bitset.h" // bitset_add #include "common.h" // GVA_NULL, MAX, MIN, gva_uint +static void +merge(GVA_Allocator const allocator, + GVA_LCS_Graph* const lhs, GVA_LCS_Graph const rhs, + size_t const offset) +{ + size_t const offset_nodes = array_length(lhs->nodes); + size_t const offset_edges = array_length(lhs->edges); + + gva_uint sink_idx = GVA_NULL; + size_t offset_distance = 0; + if (offset_nodes > 0) + { + sink_idx = lhs->dom_nodes[array_length(lhs->dom_nodes) - 1].link; + offset_distance = lhs->dom_nodes[array_length(lhs->dom_nodes) - 1].distance; + + // merge the sink of lhs with the source of rhs + lhs->nodes[sink_idx].match.length += (rhs.nodes[rhs.source].match.row + rhs.nodes[rhs.source].match.length) - + (lhs->nodes[sink_idx].match.row + lhs->nodes[sink_idx].match.length); + lhs->nodes[sink_idx].edges = rhs.nodes[rhs.source].edges + offset_edges; + lhs->dom_nodes[array_length(lhs->dom_nodes) - 1].match.length += (rhs.dom_nodes[0].match.row + rhs.dom_nodes[0].match.length) - + (lhs->dom_nodes[array_length(lhs->dom_nodes) - 1].match.row + lhs->dom_nodes[array_length(lhs->dom_nodes) - 1].match.length); + } // if + else + { + lhs->source = rhs.source; + } // else + + for (size_t i = 0; i < array_length(rhs.nodes); ++i) + { + if (i != rhs.source || sink_idx == GVA_NULL) + { + ARRAY_APPEND(allocator, lhs->nodes, + ((GVA_Node) + { + .match = {rhs.nodes[i].match.row, rhs.nodes[i].match.col + offset, rhs.nodes[i].match.length}, + .edges = rhs.nodes[i].edges == GVA_NULL ? GVA_NULL : rhs.nodes[i].edges + offset_edges, + .lambda = rhs.nodes[i].lambda == GVA_NULL ? GVA_NULL : rhs.nodes[i].lambda + offset_nodes, + })); + } // if + } // for + + for (size_t i = 0; i < array_length(rhs.edges); ++i) + { + ARRAY_APPEND(allocator, lhs->edges, + ((GVA_Edge) + { + .tail = rhs.edges[i].tail + offset_nodes - (rhs.edges[i].tail > rhs.source && sink_idx != GVA_NULL), + .next = rhs.edges[i].next == GVA_NULL ? GVA_NULL : rhs.edges[i].next + offset_edges, + })); + } // for + + for (size_t i = (sink_idx != GVA_NULL); i < array_length(rhs.dom_nodes); ++i) + { + ARRAY_APPEND(allocator, lhs->dom_nodes, + ((GVA_Dom_Node) + { + .match = {rhs.dom_nodes[i].match.row, rhs.dom_nodes[i].match.col + offset, rhs.dom_nodes[i].match.length}, + .distance = rhs.dom_nodes[i].distance + offset_distance, + .link = rhs.dom_nodes[i].link + offset_nodes - (rhs.dom_nodes[i].link > rhs.source && sink_idx != GVA_NULL), + })); + } // for +} // merge + + +// FIXME: recursion! +static void +local_supremal(GVA_Allocator const allocator, + size_t const len_ref, char const reference[static len_ref], + size_t const len_obs, char const observed[static len_obs], + size_t const offset_row, size_t const offset_col, + GVA_LCS_Graph* const graph) +{ + if (len_ref == 0 || len_obs == 0) + { + GVA_LCS_Graph local = gva_lcs_graph_init(allocator, len_ref, reference, len_obs, observed, offset_row); + merge(allocator, graph, local, offset_col); + gva_lcs_graph_destroy(allocator, local, false); + return; + } // if + + LCS_Matches forward = lcs_align_one(allocator, len_ref, reference, len_obs, observed); + gva_string_reverse((GVA_String) {len_ref, reference}); + gva_string_reverse((GVA_String) {len_obs, observed}); + + LCS_Matches backward = lcs_align_one(allocator, len_ref, reference, len_obs, observed); + gva_string_reverse((GVA_String) {len_ref, reference}); + gva_string_reverse((GVA_String) {len_obs, observed}); + + size_t sum = 0; + size_t prev_row = -1; + size_t prev_col = -1; + for (size_t i = 0; i < forward.max_lcs_pos; ++i) + { + size_t const j = forward.max_lcs_pos - i - 1; + if (forward.match[i].row == len_ref - backward.match[j].row - 1 && + forward.match[i].col == len_obs - backward.match[j].col - 1 && + (forward.uniq[i] == 1 || backward.uniq[j] == 1)) + { + size_t const distance = forward.match[i].row + forward.match[i].col - 2 * i - sum; + if (distance > 0) + { + sum += distance; + local_supremal(allocator, + forward.match[i].row - prev_row - 1, reference + prev_row + 1, + forward.match[i].col - prev_col - 1, observed + prev_col + 1, + offset_row + prev_row + 1, offset_col + prev_col + 1, + graph); + } // if + + prev_row = forward.match[i].row; + prev_col = forward.match[i].col; + } // if + } // for + size_t const distance = len_ref + len_obs - 2 * forward.max_lcs_pos - sum; + if (distance > 0) + { + sum += distance; + GVA_LCS_Graph local = gva_lcs_graph_init(allocator, len_ref - prev_row - 1, reference + prev_row + 1, len_obs - prev_col - 1, observed + prev_col + 1, offset_row + prev_row + 1); + merge(allocator, graph, local, offset_col + prev_col + 1); + gva_lcs_graph_destroy(allocator, local, false); + } // if + + backward.match = allocator.allocate(allocator.context, backward.match, MIN(len_ref, len_obs), 0); + backward.uniq = allocator.allocate(allocator.context, backward.uniq, MIN(len_ref, len_obs), 0); + forward.match = allocator.allocate(allocator.context, forward.match, MIN(len_ref, len_obs), 0); + forward.uniq = allocator.allocate(allocator.context, forward.uniq, MIN(len_ref, len_obs), 0); +} // local_supremal + + GVA_LCS_Graph gva_lcs_graph_init(GVA_Allocator const allocator, size_t const len_ref, char const reference[static restrict len_ref], @@ -330,6 +459,21 @@ gva_lcs_graph_destroy(GVA_Allocator const allocator, } // gva_lcs_graph_destroy +inline GVA_LCS_Graph +gva_lcs_graph_from_allele(GVA_Allocator const allocator, + size_t const len_ref, char const reference[static restrict len_ref], + size_t const n, GVA_Variant const variants[static restrict n]) +{ + GVA_LCS_Graph graph = {.observed = gva_patch(allocator, len_ref, reference, n, variants)}; + local_supremal(allocator, len_ref, reference, graph.observed.len, graph.observed.str, 0, 0, &graph); + if (graph.nodes == NULL) + { + graph = gva_lcs_graph_init(allocator, len_ref, reference, graph.observed.len, graph.observed.str, 0); + } // if + return graph; +} // gva_lcs_graph_from_allele + + GVA_LCS_Graph gva_lcs_graph_from_variants(GVA_Allocator const allocator, size_t const len_ref, char const reference[static restrict len_ref], diff --git a/src/main.c b/src/main.c index 4135f5b..5de1f8f 100644 --- a/src/main.c +++ b/src/main.c @@ -5,7 +5,6 @@ #include // EXIT_*, atoll, qsort #include // strerror, strlen -#include "../include/edit.h" // gva_edit_distance #include "../include/index.h" // GVA_Index, gva_index_*, GVA_Query_Result #include "../include/lcs_graph.h" // GVA_LCS_Graph, gva_lcs_graph_* #include "../include/relations.h" // GVA_RELATION_LABELS @@ -17,14 +16,11 @@ #include "common.h" // MAX, MIN -#include "../include/edit_m.h" - - #define LINE_SIZE 8194 -// #define REFERENCE_ID "NC_000022.11" +#define REFERENCE_ID "NC_000022.11" // #define REFERENCE_ID "NC_000006.12" -#define REFERENCE_ID "NC_000001.11" +// #define REFERENCE_ID "NC_000001.11" // line: alphanumeric_id SPDI [distance] @@ -177,137 +173,6 @@ index_main(int argc, char* argv[static argc]) } // index_main -static void -merge(GVA_Allocator const allocator, - GVA_LCS_Graph* const lhs, GVA_LCS_Graph const rhs, - size_t const offset) -{ - size_t const offset_nodes = array_length(lhs->nodes); - size_t const offset_edges = array_length(lhs->edges); - - gva_uint sink_idx = GVA_NULL; - size_t offset_distance = 0; - if (offset_nodes > 0) - { - sink_idx = lhs->dom_nodes[array_length(lhs->dom_nodes) - 1].link; - offset_distance = lhs->dom_nodes[array_length(lhs->dom_nodes) - 1].distance; - - // merge the sink of lhs with the source of rhs - lhs->nodes[sink_idx].match.length += (rhs.nodes[rhs.source].match.row + rhs.nodes[rhs.source].match.length) - - (lhs->nodes[sink_idx].match.row + lhs->nodes[sink_idx].match.length); - lhs->nodes[sink_idx].edges = rhs.nodes[rhs.source].edges + offset_edges; - lhs->dom_nodes[array_length(lhs->dom_nodes) - 1].match.length += (rhs.dom_nodes[0].match.row + rhs.dom_nodes[0].match.length) - - (lhs->dom_nodes[array_length(lhs->dom_nodes) - 1].match.row + lhs->dom_nodes[array_length(lhs->dom_nodes) - 1].match.length); - } // if - else - { - lhs->source = rhs.source; - } // else - - for (size_t i = 0; i < array_length(rhs.nodes); ++i) - { - if (i != rhs.source || sink_idx == GVA_NULL) - { - ARRAY_APPEND(allocator, lhs->nodes, - ((GVA_Node) - { - .match = {rhs.nodes[i].match.row, rhs.nodes[i].match.col + offset, rhs.nodes[i].match.length}, - .edges = rhs.nodes[i].edges == GVA_NULL ? GVA_NULL : rhs.nodes[i].edges + offset_edges, - .lambda = rhs.nodes[i].lambda == GVA_NULL ? GVA_NULL : rhs.nodes[i].lambda + offset_nodes, - })); - } // if - } // for - - for (size_t i = 0; i < array_length(rhs.edges); ++i) - { - ARRAY_APPEND(allocator, lhs->edges, - ((GVA_Edge) - { - .tail = rhs.edges[i].tail + offset_nodes - (rhs.edges[i].tail > rhs.source && sink_idx != GVA_NULL), - .next = rhs.edges[i].next == GVA_NULL ? GVA_NULL : rhs.edges[i].next + offset_edges, - })); - } // for - - for (size_t i = (sink_idx != GVA_NULL); i < array_length(rhs.dom_nodes); ++i) - { - ARRAY_APPEND(allocator, lhs->dom_nodes, - ((GVA_Dom_Node) - { - .match = {rhs.dom_nodes[i].match.row, rhs.dom_nodes[i].match.col + offset, rhs.dom_nodes[i].match.length}, - .distance = rhs.dom_nodes[i].distance + offset_distance, - .link = rhs.dom_nodes[i].link + offset_nodes - (rhs.dom_nodes[i].link > rhs.source && sink_idx != GVA_NULL), - })); - } // for -} // merge - - -static void -local_supremal(GVA_Allocator const allocator, - size_t const len_ref, char const reference[static len_ref], - size_t const len_obs, char const observed[static len_obs], - size_t const offset_row, size_t const offset_col, - GVA_LCS_Graph* const graph) -{ - if (len_ref == 0 || len_obs == 0) - { - GVA_LCS_Graph local = gva_lcs_graph_init(allocator, len_ref, reference, len_obs, observed, offset_row); - merge(allocator, graph, local, offset_col); - gva_lcs_graph_destroy(allocator, local, false); - return; - } // if - - GVA_Matches forward = gva_edit_distance_m(allocator, len_ref, reference, len_obs, observed); - gva_string_reverse((GVA_String) {len_ref, reference}); - gva_string_reverse((GVA_String) {len_obs, observed}); - - GVA_Matches backward = gva_edit_distance_m(allocator, len_ref, reference, len_obs, observed); - gva_string_reverse((GVA_String) {len_ref, reference}); - gva_string_reverse((GVA_String) {len_obs, observed}); - - size_t sum = 0; - size_t prev_row = -1; - size_t prev_col = -1; - for (size_t i = 0; i < forward.max_lcs_pos; ++i) - { - size_t const j = forward.max_lcs_pos - i - 1; - if (forward.matches[i].row == len_ref - backward.matches[j].row - 1 && - forward.matches[i].col == len_obs - backward.matches[j].col - 1 && - (forward.uniq[i] == 1 || backward.uniq[j] == 1)) - { - size_t const distance = forward.matches[i].row + forward.matches[i].col - 2 * i - sum; - if (distance > 0) - { - sum += distance; - local_supremal(allocator, - forward.matches[i].row - prev_row - 1, reference + prev_row + 1, - forward.matches[i].col - prev_col - 1, observed + prev_col + 1, - offset_row + prev_row + 1, offset_col + prev_col + 1, - graph); - } // if - - prev_row = forward.matches[i].row; - prev_col = forward.matches[i].col; - } // if - } // for - size_t const distance = len_ref + len_obs - 2 * forward.max_lcs_pos - sum; - if (distance > 0) - { - sum += distance; - GVA_LCS_Graph local = gva_lcs_graph_init(allocator, len_ref - prev_row - 1, reference + prev_row + 1, len_obs - prev_col - 1, observed + prev_col + 1, offset_row + prev_row + 1); - merge(allocator, graph, local, offset_col + prev_col + 1); - gva_lcs_graph_destroy(allocator, local, false); - } // if - - backward.matches = allocator.allocate(allocator.context, backward.matches, MIN(len_ref, len_obs), 0); - backward.uniq = allocator.allocate(allocator.context, backward.uniq, MIN(len_ref, len_obs), 0); - forward.matches = allocator.allocate(allocator.context, forward.matches, MIN(len_ref, len_obs), 0); - forward.uniq = allocator.allocate(allocator.context, forward.uniq, MIN(len_ref, len_obs), 0); -} // local_supremal - - -//#define SMALL - - int allele_main(int argc, char* argv[static argc]) { @@ -317,26 +182,6 @@ allele_main(int argc, char* argv[static argc]) return EXIT_FAILURE; } // if -#ifdef SMALL - GVA_String reference = {strlen(argv[1]), argv[1]}; - GVA_String observed = {strlen(argv[2]), argv[2]}; - - GVA_LCS_Graph small = gva_lcs_graph_init(gva_std_allocator, reference.len, reference.str, observed.len, observed.str, 0); - for (size_t i = 0; i < array_length(small.dom_nodes) - 1; ++i) - { - fprintf(stderr, "(%u, %u, %u)\n", small.dom_nodes[i].match.row, small.dom_nodes[i].match.col, small.dom_nodes[i].match.length); - fprintf(stderr, GVA_VARIANT_FMT " %u\n", - GVA_VARIANT_PRINT(gva_lcs_graph_local_supremal(small, i, i + 1)), - small.dom_nodes[i + 1].distance - small.dom_nodes[i].distance); - } // for - fprintf(stderr, "(%u, %u, %u)\n\n", - small.dom_nodes[array_length(small.dom_nodes) - 1].match.row, - small.dom_nodes[array_length(small.dom_nodes) - 1].match.col, - small.dom_nodes[array_length(small.dom_nodes) - 1].match.length); - //gva_lcs_graph_dot(stderr, small); - gva_lcs_graph_destroy(gva_std_allocator, small, false); - -#else errno = 0; FILE* stream = fopen(argv[1], "r"); if (stream == NULL) @@ -386,50 +231,20 @@ allele_main(int argc, char* argv[static argc]) ARRAY_APPEND(gva_std_allocator, variants, gva_variant_dup(gva_std_allocator, trimmed)); } // while fclose(stream); - - fprintf(stderr, "===INPUT===\n"); fprintf(stderr, "#variants: %zu\n", array_length(variants)); fprintf(stderr, "#dropped: %zu\n", dropped); - GVA_String observed = gva_patch(gva_std_allocator, reference.len, reference.str, array_length(variants), variants); - fprintf(stderr, "observed length: %zu\n", observed.len); - - if (reference.str == NULL || observed.str == NULL) - { - gva_string_destroy(gva_std_allocator, observed); - gva_string_destroy(gva_std_allocator, reference); - return EXIT_FAILURE; - } // if -#endif - - GVA_LCS_Graph graph = {.observed = observed}; - local_supremal(gva_std_allocator, reference.len, reference.str, observed.len, observed.str, 0, 0, &graph); - if (graph.nodes == NULL) - { - graph = gva_lcs_graph_init(gva_std_allocator, reference.len, reference.str, observed.len, observed.str, 0); - } // if - + GVA_LCS_Graph graph = gva_lcs_graph_from_allele(gva_std_allocator, reference.len, reference.str, array_length(variants), variants); for (size_t i = 0; i < array_length(graph.dom_nodes) - 1; ++i) { - //fprintf(stderr, "(%u, %u, %u)\n", graph.dom_nodes[i].match.row, graph.dom_nodes[i].match.col, graph.dom_nodes[i].match.length); fprintf(stdout, GVA_VARIANT_FMT_SPDI " %u\n", GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, gva_lcs_graph_local_supremal(graph, i, i + 1)), graph.dom_nodes[i + 1].distance - graph.dom_nodes[i].distance); } // for - //fprintf(stderr, "(%u, %u, %u)\n\n", - // graph.dom_nodes[array_length(graph.dom_nodes) - 1].match.row, - // graph.dom_nodes[array_length(graph.dom_nodes) - 1].match.col, - // graph.dom_nodes[array_length(graph.dom_nodes) - 1].match.length); - //gva_lcs_graph_dot(stderr, graph); fprintf(stderr, "#nodes: %zu\n", array_length(graph.nodes)); fprintf(stderr, "#edges: %zu\n", array_length(graph.edges)); - gva_lcs_graph_destroy(gva_std_allocator, graph, false); - -#ifndef SMALL - gva_string_destroy(gva_std_allocator, observed); - gva_string_destroy(gva_std_allocator, reference); -#endif + gva_lcs_graph_destroy(gva_std_allocator, graph, true); return EXIT_SUCCESS; } // allele_main From 409cea3f6357feff6525b8c7536b3033c9ed64b8 Mon Sep 17 00:00:00 2001 From: jkvis Date: Sat, 28 Feb 2026 14:22:50 +0100 Subject: [PATCH 530/704] Test with fractional overlaps --- src/index.c | 33 +++++++++++++++++++++++++++++---- src/main.c | 8 ++++---- 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/src/index.c b/src/index.c index 1f64b7d..8250b6d 100644 --- a/src/index.c +++ b/src/index.c @@ -137,7 +137,8 @@ variants_distance(GVA_Allocator const allocator, static size_t variants_included(GVA_Allocator const allocator, size_t const len_ref, char const reference[static len_ref], - GVA_Variant const lhs, GVA_Variant const rhs) + GVA_Variant const lhs, GVA_Variant const rhs, + size_t* const excluded) { size_t const start = MIN(lhs.start, rhs.start); size_t const end = MAX(lhs.end, rhs.end); @@ -191,6 +192,18 @@ variants_included(GVA_Allocator const allocator, bitset_intersection_cnt(lhs_gs, rhs_gs) + bitset_intersection_cnt(lhs_ts, rhs_ts); + *excluded = + bitset_intersection_cnt(lhs_dels, lhs_dels) + + bitset_intersection_cnt(rhs_dels, rhs_dels) + + bitset_intersection_cnt(lhs_as, lhs_as) + + bitset_intersection_cnt(rhs_as, rhs_as) + + bitset_intersection_cnt(lhs_cs, lhs_cs) + + bitset_intersection_cnt(rhs_cs, rhs_cs) + + bitset_intersection_cnt(lhs_gs, lhs_gs) + + bitset_intersection_cnt(rhs_gs, rhs_gs) + + bitset_intersection_cnt(lhs_ts, lhs_ts) + + bitset_intersection_cnt(rhs_ts, rhs_ts); + rhs_ts = bitset_destroy(allocator, rhs_ts); rhs_gs = bitset_destroy(allocator, rhs_gs); rhs_cs = bitset_destroy(allocator, rhs_cs); @@ -206,7 +219,7 @@ variants_included(GVA_Allocator const allocator, gva_string_destroy(allocator, observed_rhs); gva_string_destroy(allocator, observed_lhs); - return included > 0 ? 1 : 0; + return included; } // variants_included @@ -227,7 +240,13 @@ variants_with_distance(GVA_Allocator const allocator, return distance_rhs; } // if - return variants_included(allocator, len_ref, reference, lhs, rhs); + size_t excluded = 0; + size_t const included = variants_included(allocator, len_ref, reference, lhs, rhs, &excluded); + if (included == 0) + { + return 0; // disjoint + } // if + return MAX(1, (double) included / excluded * MIN(distance_lhs, distance_rhs)); } // variants_with_distance @@ -497,9 +516,15 @@ gva_index_query(GVA_Allocator const allocator, // single hit for single query part, relation is not determined by the distances else if (ABS((intmax_t) self->intervals.nodes[node_idx].distance - (graph.dom_nodes[hits[i].query.end].distance - graph.dom_nodes[hits[i].query.start].distance)) != hits[i].included) { + size_t excluded = 0; hits[i].included = variants_included(allocator, self->reference.len, self->reference.str, variant_from_index(self, node_idx), - gva_lcs_graph_local_supremal(graph, hits[i].query.start, hits[i].query.end)); + gva_lcs_graph_local_supremal(graph, hits[i].query.start, hits[i].query.end), + &excluded); + if (hits[i].included > 0) + { + hits[i].included = MAX(1, (double) hits[i].included / excluded * MIN(self->intervals.nodes[node_idx].distance, graph.dom_nodes[hits[i].query.end].distance - graph.dom_nodes[hits[i].query.start].distance)); + } // if } // if // single hit for single query part, relation is already determined else diff --git a/src/main.c b/src/main.c index 5de1f8f..ed4508c 100644 --- a/src/main.c +++ b/src/main.c @@ -18,9 +18,9 @@ #define LINE_SIZE 8194 -#define REFERENCE_ID "NC_000022.11" +// #define REFERENCE_ID "NC_000022.11" // #define REFERENCE_ID "NC_000006.12" -// #define REFERENCE_ID "NC_000001.11" +#define REFERENCE_ID "NC_000001.11" // line: alphanumeric_id SPDI [distance] @@ -307,7 +307,7 @@ extract_main(int argc, char* argv[static argc]) int main(int argc, char* argv[static argc]) { - return allele_main(argc, argv); + // return allele_main(argc, argv); // return extract_main(argc, argv); - // return index_main(argc, argv); + return index_main(argc, argv); } // main From f490c8ed7fe5fea72f5ca4a105d7ccffd609b4c3 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Tue, 3 Mar 2026 10:50:43 +0100 Subject: [PATCH 531/704] White space. --- src/align.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/align.c b/src/align.c index 2fb383c..4cbace8 100644 --- a/src/align.c +++ b/src/align.c @@ -218,7 +218,6 @@ lcs_align(GVA_Allocator const allocator, } // lcs_align - static inline size_t onp_snake(size_t const m, char const a[static restrict m], size_t const n, char const b[static restrict n], From 74d622eb563262969a65e2ce6938ed85fba5a59c Mon Sep 17 00:00:00 2001 From: jkvis Date: Sat, 7 Mar 2026 16:22:06 +0100 Subject: [PATCH 532/704] Owned allocators for trie and interval tree --- src/index.c | 16 +++--- src/interval_tree.c | 12 +++-- src/interval_tree.h | 5 +- src/main.c | 58 ++++++++++++++++++++- src/trie.c | 119 ++++++++++++++++++++++++++++++++------------ src/trie.h | 13 ++--- 6 files changed, 168 insertions(+), 55 deletions(-) diff --git a/src/index.c b/src/index.c index 8250b6d..30d0dff 100644 --- a/src/index.c +++ b/src/index.c @@ -263,10 +263,10 @@ gva_index_init(GVA_Allocator const allocator, index->allocator = allocator; index->reference = (GVA_String) {len_ref, reference}; - index->intervals = interval_tree_init(); - index->inserted = trie_init(); + index->intervals = interval_tree_init(allocator); + index->inserted = trie_init(allocator); - index->ids = trie_init(); + index->ids = trie_init(allocator); index->alleles = NULL; index->join = NULL; @@ -283,9 +283,9 @@ gva_index_destroy(GVA_Index* const self) return NULL; } // if - interval_tree_destroy(self->allocator, &self->intervals); - trie_destroy(self->allocator, &self->inserted); - trie_destroy(self->allocator, &self->ids); + interval_tree_destroy(&self->intervals); + trie_destroy(&self->inserted); + trie_destroy(&self->ids); self->alleles = ARRAY_DESTROY(self->allocator, self->alleles); self->join = ARRAY_DESTROY(self->allocator, self->join); @@ -298,7 +298,7 @@ gva_index_insert(GVA_Index* restrict const self, size_t const len_id, char const id[static restrict len_id], GVA_Variant const variant, size_t const distance) { - size_t const id_idx = trie_insert(self->allocator, &self->ids, len_id, id); + size_t const id_idx = trie_insert(&self->ids, len_id, id); size_t allele_idx = array_length(self->alleles) - 1; // new allele @@ -314,7 +314,7 @@ gva_index_insert(GVA_Index* restrict const self, } // if // add variant - gva_uint const inserted_idx = trie_insert(self->allocator, &self->inserted, + gva_uint const inserted_idx = trie_insert(&self->inserted, variant.sequence.len, variant.sequence.str); gva_uint const tmp_idx = ARRAY_APPEND(self->allocator, self->intervals.nodes, ((Interval_Tree_Node) diff --git a/src/interval_tree.c b/src/interval_tree.c index aecba61..d7e5ca3 100644 --- a/src/interval_tree.c +++ b/src/interval_tree.c @@ -9,16 +9,20 @@ inline Interval_Tree -interval_tree_init(void) +interval_tree_init(GVA_Allocator const allocator) { - return (Interval_Tree) {.root = GVA_NULL}; + return (Interval_Tree) + { + .allocator = allocator, + .root = GVA_NULL, + }; } // interval_tree_init inline void -interval_tree_destroy(GVA_Allocator const allocator, Interval_Tree self[static 1]) +interval_tree_destroy(Interval_Tree self[static 1]) { - self->nodes = ARRAY_DESTROY(allocator, self->nodes); + self->nodes = ARRAY_DESTROY(self->allocator, self->nodes); self->root = GVA_NULL; } // interval_tree_destroy diff --git a/src/interval_tree.h b/src/interval_tree.h index 0b6a1f8..3199de4 100644 --- a/src/interval_tree.h +++ b/src/interval_tree.h @@ -29,16 +29,17 @@ typedef struct typedef struct { Interval_Tree_Node* nodes; + GVA_Allocator allocator; gva_uint root; } Interval_Tree; Interval_Tree -interval_tree_init(void); +interval_tree_init(GVA_Allocator const allocator); void -interval_tree_destroy(GVA_Allocator const allocator, Interval_Tree self[static 1]); +interval_tree_destroy(Interval_Tree self[static 1]); gva_uint diff --git a/src/main.c b/src/main.c index ed4508c..c616517 100644 --- a/src/main.c +++ b/src/main.c @@ -111,7 +111,7 @@ index_main(int argc, char* argv[static argc]) size_t distance = 0; if (!parse_line(line, &id, &variant, &distance)) { - fprintf(stderr, "parsing failed at line %zu: %s\n", line_count, line); + fprintf(stderr, "parsing failed at line %zu: %s", line_count, line); continue; } // if gva_index_insert(index, id.len, id.str, variant, distance); @@ -128,7 +128,7 @@ index_main(int argc, char* argv[static argc]) GVA_Variant variant = {0}; if (!parse_line(line, &id, &variant, &(size_t) {0})) { - fprintf(stderr, "parsing failed at line %zu: %s\n", line_count, line); + fprintf(stderr, "parsing failed at line %zu: %s", line_count, line); continue; } // if GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &variant); @@ -245,6 +245,7 @@ allele_main(int argc, char* argv[static argc]) fprintf(stderr, "#edges: %zu\n", array_length(graph.edges)); gva_lcs_graph_destroy(gva_std_allocator, graph, true); + gva_string_destroy(gva_std_allocator, reference); return EXIT_SUCCESS; } // allele_main @@ -304,10 +305,63 @@ extract_main(int argc, char* argv[static argc]) } // extract_main +int +supremal_main(int argc, char* argv[static argc]) +{ + if (argc < 2) + { + fprintf(stderr, "usage %s reference.blob\n", argv[0]); + return EXIT_FAILURE; + } // if + + errno = 0; + FILE* stream = fopen(argv[1], "r"); + if (stream == NULL) + { + fprintf(stderr, "error: %s\n", strerror(errno)); + return EXIT_FAILURE; + } // if + + GVA_String reference = {0}; + reference = gva_fasta_sequence_blob(gva_std_allocator, stream); + fclose(stream); + + fprintf(stderr, "reference length: %zu\n", reference.len); + + size_t line_count = 0; + static char line[LINE_SIZE] = {0}; + while (fgets(line, sizeof(line), stdin) != NULL) + { + line_count += 1; + GVA_String id = {0}; + GVA_Variant variant = {0}; + size_t distance = 0; + if (!parse_line(line, &id, &variant, &distance)) + { + fprintf(stderr, "parsing failed at line %zu: %s", line_count, line); + continue; + } // if + GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &variant); + + GVA_Variant supremal = gva_lcs_graph_supremal(graph); + + fprintf(stdout, GVA_STRING_FMT " " GVA_VARIANT_FMT_SPDI " %zu\n", + GVA_STRING_PRINT(id), GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, supremal), gva_lcs_graph_distance(graph)); + + gva_lcs_graph_destroy(gva_std_allocator, graph, true); + } // while + + gva_string_destroy(gva_std_allocator, reference); + + return EXIT_SUCCESS; +} // supremal_main + + int main(int argc, char* argv[static argc]) { // return allele_main(argc, argv); // return extract_main(argc, argv); return index_main(argc, argv); + // return supremal_main(argc, argv); } // main diff --git a/src/trie.c b/src/trie.c index 4f4be4d..5fdb078 100644 --- a/src/trie.c +++ b/src/trie.c @@ -1,25 +1,30 @@ #include // true #include // NULL, size_t +#include // memcpy #include "../include/allocator.h" // GVA_Allocator -#include "../include/string.h" // GVA_String, gva_string_* +#include "../include/string.h" // GVA_String #include "../include/types.h" // GVA_NULL, gva_uint -#include "array.h" // ARRAY_* +#include "array.h" // ARRAY_*, array_* #include "trie.h" // Trie, TrieNode, trie_* inline Trie -trie_init(void) +trie_init(GVA_Allocator const allocator) { - return (Trie) {.root = GVA_NULL}; + return (Trie) + { + .allocator = allocator, + .root = GVA_NULL, + }; } // trie_init inline void -trie_destroy(GVA_Allocator const allocator, Trie self[static 1]) +trie_destroy(Trie self[static 1]) { - gva_string_destroy(allocator, self->strings); - self->nodes = ARRAY_DESTROY(allocator, self->nodes); + self->strings = ARRAY_DESTROY(self->allocator, self->strings); + self->nodes = ARRAY_DESTROY(self->allocator, self->nodes); self->root = GVA_NULL; } // trie_destroy @@ -28,26 +33,43 @@ static inline size_t prefix_length(size_t const len_lhs, char const lhs[static restrict len_lhs], size_t const len_rhs, char const rhs[static restrict len_rhs]) { - for (size_t i = 0; i < len_lhs; ++i) + size_t i = 0; + while (i < len_lhs && i < len_rhs && lhs[i] == rhs[i]) { - if (i >= len_rhs || lhs[i] != rhs[i]) - { - return i; - } // if - } // for - return len_lhs; + i += 1; + } // while + return i; } // prefix_length +static inline size_t +concat(Trie self[static restrict 1], + size_t const len, char const key[static restrict len]) +{ + size_t const start = array_length(self->strings); + self->strings = array_ensure(self->allocator, self->strings, sizeof(*self->strings), len); + memcpy(self->strings + start, key, len); + array_header(self->strings)->length += len; + return start; +} // concat + + gva_uint -trie_insert(GVA_Allocator const allocator, Trie self[static restrict 1], +trie_insert(Trie self[static restrict 1], size_t const len, char const key[static restrict len]) { if (self->root == GVA_NULL) { - gva_uint const start = 0; - self->strings = gva_string_concat(allocator, self->strings, (GVA_String) {len, key}); - self->root = ARRAY_APPEND(allocator, self->nodes, ((TrieNode) {GVA_NULL, GVA_NULL, start, start, len})); + gva_uint const start = concat(self, len, key); + self->root = ARRAY_APPEND(self->allocator, self->nodes, + ((TrieNode) + { + .link = GVA_NULL, + .next = GVA_NULL, + .p_start = start, + .start = start, + .end = len, + })); return self->root; } // if @@ -57,7 +79,8 @@ trie_insert(GVA_Allocator const allocator, Trie self[static restrict 1], while (true) { gva_uint const p_len = self->nodes[idx].end - self->nodes[idx].p_start; - size_t const k = prefix_length(len - prefix, key + prefix, p_len, self->strings.str + self->nodes[idx].p_start); + size_t const k = prefix_length(len - prefix, key + prefix, + p_len, self->strings + self->nodes[idx].p_start); if (k == len - prefix && k == p_len) { return idx; // existing found @@ -67,10 +90,16 @@ trie_insert(GVA_Allocator const allocator, Trie self[static restrict 1], { if (self->nodes[idx].next == GVA_NULL) { - gva_uint const start = self->strings.len; - self->strings = gva_string_concat(allocator, self->strings, (GVA_String) {len, key}); - gva_uint const end = self->strings.len; - gva_uint const next = ARRAY_APPEND(allocator, self->nodes, ((TrieNode) {GVA_NULL, GVA_NULL, start + prefix, start, end})); + gva_uint const start = concat(self, len, key); + gva_uint const next = ARRAY_APPEND(self->allocator, self->nodes, + ((TrieNode) + { + .link = GVA_NULL, + .next = GVA_NULL, + .p_start = start + prefix, + .start = start, + .end = array_length(self->strings), + })); self->nodes[idx].next = next; return next; } // if @@ -82,10 +111,16 @@ trie_insert(GVA_Allocator const allocator, Trie self[static restrict 1], prefix += k; if (self->nodes[idx].link == GVA_NULL) { - gva_uint const start = self->strings.len; - self->strings = gva_string_concat(allocator, self->strings, (GVA_String) {len, key}); - gva_uint const end = self->strings.len; - gva_uint const link = ARRAY_APPEND(allocator, self->nodes, ((TrieNode) {GVA_NULL, GVA_NULL, start + prefix, start, end})); + gva_uint const start = concat(self, len, key); + gva_uint const link = ARRAY_APPEND(self->allocator, self->nodes, + ((TrieNode) + { + .link = GVA_NULL, + .next = GVA_NULL, + .p_start = start + prefix, + .start = start, + .end = array_length(self->strings), + })); self->nodes[idx].link = link; return link; } // if @@ -98,12 +133,26 @@ trie_insert(GVA_Allocator const allocator, Trie self[static restrict 1], gva_uint next = GVA_NULL; if (prefix < len) { - gva_uint const start = self->strings.len; - self->strings = gva_string_concat(allocator, self->strings, (GVA_String) {len, key}); - gva_uint const end = self->strings.len; - next = ARRAY_APPEND(allocator, self->nodes, ((TrieNode) {GVA_NULL, GVA_NULL, start + prefix, start, end})); + gva_uint const start = concat(self, len, key); + next = ARRAY_APPEND(self->allocator, self->nodes, + ((TrieNode) + { + .link = GVA_NULL, + .next = GVA_NULL, + .p_start = start + prefix, + .start = start, + .end = array_length(self->strings), + })); } // if - gva_uint const link = ARRAY_APPEND(allocator, self->nodes, ((TrieNode) {idx, self->nodes[idx].next, self->nodes[idx].p_start, self->nodes[idx].start, self->nodes[idx].p_start + k})); + gva_uint const link = ARRAY_APPEND(self->allocator, self->nodes, + ((TrieNode) + { + .link = idx, + .next = self->nodes[idx].next, + .p_start = self->nodes[idx].p_start, + .start = self->nodes[idx].start, + .end = self->nodes[idx].p_start + k, + })); self->nodes[idx].next = next; self->nodes[idx].p_start += k; if (prev != GVA_NULL) @@ -138,5 +187,9 @@ trie_string(Trie const self, size_t const idx) { return (GVA_String) {0}; } // if - return (GVA_String) {self.nodes[idx].end - self.nodes[idx].start, self.strings.str + self.nodes[idx].start}; + return (GVA_String) + { + .len = self.nodes[idx].end - self.nodes[idx].start, + .str = self.strings + self.nodes[idx].start, + }; } //trie_string diff --git a/src/trie.h b/src/trie.h index 5523050..e8392d7 100644 --- a/src/trie.h +++ b/src/trie.h @@ -21,22 +21,23 @@ typedef struct typedef struct { - GVA_String strings; - TrieNode* nodes; - gva_uint root; + char* restrict strings; + TrieNode* restrict nodes; + GVA_Allocator allocator; + gva_uint root; } Trie; Trie -trie_init(void); +trie_init(GVA_Allocator const allocator); void -trie_destroy(GVA_Allocator const allocator, Trie self[static 1]); +trie_destroy(Trie self[static 1]); gva_uint -trie_insert(GVA_Allocator const allocator, Trie self[static restrict 1], +trie_insert(Trie self[static restrict 1], size_t const len, char const key[static restrict len]); From b491ea52d7c19e246b04437151035f9160ab0e57 Mon Sep 17 00:00:00 2001 From: jkvis Date: Sun, 8 Mar 2026 10:24:37 +0100 Subject: [PATCH 533/704] Refactored duplicated code --- include/string.h | 5 +++-- src/lcs_graph.c | 8 ++++---- src/string.c | 31 ++++++++++++++++--------------- src/trie.c | 17 ++--------------- src/variant.c | 33 +++++++++++++++++++++++++-------- 5 files changed, 50 insertions(+), 44 deletions(-) diff --git a/include/string.h b/include/string.h index 18cf9c7..1c7c286 100644 --- a/include/string.h +++ b/include/string.h @@ -36,11 +36,12 @@ gva_string_dup(GVA_Allocator const allocator, GVA_String const self); void -gva_string_reverse(GVA_String self); +gva_string_reverse(size_t const len, char str[static len]); size_t -gva_string_prefix_length(GVA_String const lhs, GVA_String const rhs); +gva_prefix_length(size_t const len_lhs, char const lhs[static restrict len_lhs], + size_t const len_rhs, char const rhs[static restrict len_rhs]); #endif // GVA_STRING_H diff --git a/src/lcs_graph.c b/src/lcs_graph.c index e6608b5..a6bd238 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -96,12 +96,12 @@ local_supremal(GVA_Allocator const allocator, } // if LCS_Matches forward = lcs_align_one(allocator, len_ref, reference, len_obs, observed); - gva_string_reverse((GVA_String) {len_ref, reference}); - gva_string_reverse((GVA_String) {len_obs, observed}); + gva_string_reverse(len_ref, (char*) reference); + gva_string_reverse(len_obs, (char*) observed); LCS_Matches backward = lcs_align_one(allocator, len_ref, reference, len_obs, observed); - gva_string_reverse((GVA_String) {len_ref, reference}); - gva_string_reverse((GVA_String) {len_obs, observed}); + gva_string_reverse(len_ref, (char*) reference); + gva_string_reverse(len_obs, (char*) observed); size_t sum = 0; size_t prev_row = -1; diff --git a/src/string.c b/src/string.c index 2bc408b..aae0b6f 100644 --- a/src/string.c +++ b/src/string.c @@ -49,28 +49,29 @@ gva_string_dup(GVA_Allocator const allocator, GVA_String const self) inline void -gva_string_reverse(GVA_String self) +gva_string_reverse(size_t const len, char str[static len]) { - size_t i = self.len - 1; - size_t j = 0; - while (i > j) + size_t i = 0; + size_t j = len - 1; + while (i < j) { - char const ch = self.str[i]; - ((char*) self.str)[i] = self.str[j]; - ((char*) self.str)[j] = ch; - i -= 1; - j += 1; + char const ch = str[i]; + str[j] = str[i]; + str[i] = ch; + i += 1; + j -= 1; } // while } // gva_string_reverse inline size_t -gva_string_prefix_length(GVA_String const lhs, GVA_String const rhs) +gva_prefix_length(size_t const len_lhs, char const lhs[static restrict len_lhs], + size_t const len_rhs, char const rhs[static restrict len_rhs]) { - size_t idx = 0; - while (idx < lhs.len && idx < rhs.len && lhs.str[idx] == rhs.str[idx]) + size_t i = 0; + while (i < len_lhs && i < len_rhs && lhs[i] == rhs[i]) { - idx += 1; + i += 1; } // while - return idx; -} // gva_string_prefix_length + return i; +} // gva_prefix_length diff --git a/src/trie.c b/src/trie.c index 5fdb078..6d2d6f1 100644 --- a/src/trie.c +++ b/src/trie.c @@ -3,7 +3,7 @@ #include // memcpy #include "../include/allocator.h" // GVA_Allocator -#include "../include/string.h" // GVA_String +#include "../include/string.h" // GVA_String, gva_prefix_length #include "../include/types.h" // GVA_NULL, gva_uint #include "array.h" // ARRAY_*, array_* #include "trie.h" // Trie, TrieNode, trie_* @@ -29,19 +29,6 @@ trie_destroy(Trie self[static 1]) } // trie_destroy -static inline size_t -prefix_length(size_t const len_lhs, char const lhs[static restrict len_lhs], - size_t const len_rhs, char const rhs[static restrict len_rhs]) -{ - size_t i = 0; - while (i < len_lhs && i < len_rhs && lhs[i] == rhs[i]) - { - i += 1; - } // while - return i; -} // prefix_length - - static inline size_t concat(Trie self[static restrict 1], size_t const len, char const key[static restrict len]) @@ -79,7 +66,7 @@ trie_insert(Trie self[static restrict 1], while (true) { gva_uint const p_len = self->nodes[idx].end - self->nodes[idx].p_start; - size_t const k = prefix_length(len - prefix, key + prefix, + size_t const k = gva_prefix_length(len - prefix, key + prefix, p_len, self->strings + self->nodes[idx].p_start); if (k == len - prefix && k == p_len) { diff --git a/src/variant.c b/src/variant.c index e7ebc22..0df666e 100644 --- a/src/variant.c +++ b/src/variant.c @@ -1,10 +1,10 @@ #include // bool #include // NULL, size_t -#include // memcmp +#include // memcmp, mempcy #include "../include/allocator.h" // GVA_Allocator #include "../include/types.h" // gva_uint -#include "../include/string.h" // GVA_String, gva_string_* +#include "../include/string.h" // GVA_String, gva_string_*, gva_prefix_length #include "../include/variant.h" // gva_parse_spdi, gva_patch #include "common.h" // MIN @@ -138,7 +138,8 @@ inline GVA_Variant gva_variant_prefix_trimmed(size_t const len_ref, char const reference[static len_ref], GVA_Variant const variant) { - size_t const len = gva_string_prefix_length((GVA_String) {(variant.end - variant.start), reference + variant.start}, variant.sequence); + size_t const len = gva_prefix_length(variant.end - variant.start, reference + variant.start, + variant.sequence.len, variant.sequence.str); return (GVA_Variant) {variant.start + len, variant.end, {variant.sequence.len - len, variant.sequence.str + len}}; } // gva_variant_prefix_trimmed @@ -148,19 +149,35 @@ gva_patch(GVA_Allocator const allocator, size_t const len_ref, char const reference[static restrict len_ref], size_t const n, GVA_Variant const variants[static restrict n]) { - GVA_String observed = {0}; + size_t deleted = 0; + size_t inserted = 0; + for (size_t i = 0; i < n; ++i) + { + deleted += variants[i].end - variants[i].start; + inserted += variants[i].sequence.len; + } // for + + char* const restrict observed = allocator.allocate(allocator.context, NULL, 0, len_ref + inserted - deleted); + if (observed == NULL) + { + return (GVA_String) {0}; + } // if + size_t start = 0; + size_t len = 0; for (size_t i = 0; i < n; ++i) { - observed = gva_string_concat(allocator, observed, (GVA_String) {variants[i].start - start, reference + start}); - observed = gva_string_concat(allocator, observed, variants[i].sequence); + memcpy(observed + len, reference + start, variants[i].start - start); + len += variants[i].start - start; + memcpy(observed + len, variants[i].sequence.str, variants[i].sequence.len); + len += variants[i].sequence.len; start = variants[i].end; } // for if (start < len_ref) { - observed = gva_string_concat(allocator, observed, (GVA_String) {len_ref - start, reference + start}); + memcpy(observed + len, reference + start, len_ref - start); } // if - return observed; + return (GVA_String) {len, observed}; } // gva_patch From 9db63a3d75a969d56662849ade692b353ca50f2e Mon Sep 17 00:00:00 2001 From: jkvis Date: Sun, 8 Mar 2026 10:24:55 +0100 Subject: [PATCH 534/704] WIP: ONP domination --- src/align.c | 33 +++++++++++++++++++++++++++++++++ src/main.c | 19 +++++++++++++++++-- 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/src/align.c b/src/align.c index 4cbace8..5cc7bc8 100644 --- a/src/align.c +++ b/src/align.c @@ -10,6 +10,9 @@ #include "common.h" // ABS, MAX, MIN +#include // DEBUG + + typedef struct { GVA_Allocator const allocator; @@ -228,6 +231,15 @@ onp_snake(size_t const m, char const a[static restrict m], size_t col = MAX(lower, upper); size_t row = col - k; + if (swapped) + { + fprintf(stderr, " snake start: (%zu, %zu)\n", col, row); + } // if + else + { + fprintf(stderr, " snake start: (%zu, %zu)\n", row, col); + } // else + intmax_t const d_row = m - row; intmax_t const d_col = n - col; @@ -236,6 +248,16 @@ onp_snake(size_t const m, char const a[static restrict m], row += 1; col += 1; size_t const lcs_pos = (row + col - ABS(delta) - 2 * p + ABS(d_row - d_col)) / 2; + + if (swapped) + { + fprintf(stderr, " snake match @ %zu: (%zu, %zu)\n", lcs_pos, col - 1, row - 1); + } // if + else + { + fprintf(stderr, " snake match @ %zu: (%zu, %zu)\n", lcs_pos, row - 1, col - 1); + } // else + result->uniq[lcs_pos - 1] = 0; if (lcs_pos > result->max_lcs_pos) { @@ -253,6 +275,16 @@ onp_snake(size_t const m, char const a[static restrict m], } // else } // if } // while + + if (swapped) + { + fprintf(stderr, " snake end: (%zu, %zu)\n", col, row); + } // if + else + { + fprintf(stderr, " snake end: (%zu, %zu)\n", row, col); + } // else + return col; } // onp_snake @@ -289,6 +321,7 @@ onp_compare(GVA_Allocator const allocator, size_t p = 0; while ((size_t) fp[delta + offset] != n) { + fprintf(stderr, "p: %zu\n", p); fp[-p - 1 + offset] = -1; fp[delta + p + 1 + offset] = -1; for (intmax_t k = -p; k <= delta - 1; ++k) diff --git a/src/main.c b/src/main.c index c616517..e4ee228 100644 --- a/src/main.c +++ b/src/main.c @@ -12,6 +12,7 @@ #include "../include/string.h" // GVA_String, gva_string_destroy #include "../include/utils.h" // gva_fasta_sequence*, gva_lcs_graph_dot #include "../include/variant.h" // GVA_VARIANT_*, GVA_Variant, gva_parse_spdi, gva_variant_* +#include "align.h" // LCS_Matches, lcs_align_one #include "array.h" // ARRAY_*, array_length #include "common.h" // MAX, MIN @@ -255,6 +256,20 @@ allele_main(int argc, char* argv[static argc]) int extract_main(int argc, char* argv[static argc]) { + if (argc < 3) + { + fprintf(stderr, "usage: %s reference observed\n", argv[0]); + return EXIT_FAILURE; + } // if + + LCS_Matches align = lcs_align_one(gva_std_allocator, strlen(argv[1]), argv[1], strlen(argv[2]), argv[2]); + + + align.match = gva_std_allocator.allocate(gva_std_allocator.context, align.match, align.max_lcs_pos, 0); + align.uniq = gva_std_allocator.allocate(gva_std_allocator.context, align.uniq, align.max_lcs_pos, 0); + + return EXIT_SUCCESS; + (void) argv; size_t line_count = 0; @@ -361,7 +376,7 @@ int main(int argc, char* argv[static argc]) { // return allele_main(argc, argv); - // return extract_main(argc, argv); - return index_main(argc, argv); + return extract_main(argc, argv); + // return index_main(argc, argv); // return supremal_main(argc, argv); } // main From 8304d24490021254b10638b74664ae4136dec63e Mon Sep 17 00:00:00 2001 From: jkvis Date: Sun, 8 Mar 2026 19:07:22 +0100 Subject: [PATCH 535/704] WIP: ONP dominance --- src/align.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/align.c b/src/align.c index 5cc7bc8..15ded0f 100644 --- a/src/align.c +++ b/src/align.c @@ -251,11 +251,11 @@ onp_snake(size_t const m, char const a[static restrict m], if (swapped) { - fprintf(stderr, " snake match @ %zu: (%zu, %zu)\n", lcs_pos, col - 1, row - 1); + fprintf(stderr, " snake match @ %zu: (%zu, %zu)\n", lcs_pos - 1, col - 1, row - 1); } // if else { - fprintf(stderr, " snake match @ %zu: (%zu, %zu)\n", lcs_pos, row - 1, col - 1); + fprintf(stderr, " snake match @ %zu: (%zu, %zu)\n", lcs_pos - 1, row - 1, col - 1); } // else result->uniq[lcs_pos - 1] = 0; From 1b0029c48788e2954179098ce3e0871eb4303b18 Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 9 Mar 2026 20:07:54 +0100 Subject: [PATCH 536/704] Removed pointers --- src/lcs_graph.c | 8 ++++---- src/main.c | 1 - 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/lcs_graph.c b/src/lcs_graph.c index a6bd238..1c57ce2 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -17,7 +17,7 @@ static void merge(GVA_Allocator const allocator, - GVA_LCS_Graph* const lhs, GVA_LCS_Graph const rhs, + GVA_LCS_Graph lhs[static 1], GVA_LCS_Graph const rhs, size_t const offset) { size_t const offset_nodes = array_length(lhs->nodes); @@ -82,10 +82,10 @@ merge(GVA_Allocator const allocator, // FIXME: recursion! static void local_supremal(GVA_Allocator const allocator, - size_t const len_ref, char const reference[static len_ref], - size_t const len_obs, char const observed[static len_obs], + size_t const len_ref, char const reference[static restrict len_ref], + size_t const len_obs, char const observed[static restrict len_obs], size_t const offset_row, size_t const offset_col, - GVA_LCS_Graph* const graph) + GVA_LCS_Graph graph[static restrict 1]) { if (len_ref == 0 || len_obs == 0) { diff --git a/src/main.c b/src/main.c index e4ee228..0acd0c6 100644 --- a/src/main.c +++ b/src/main.c @@ -264,7 +264,6 @@ extract_main(int argc, char* argv[static argc]) LCS_Matches align = lcs_align_one(gva_std_allocator, strlen(argv[1]), argv[1], strlen(argv[2]), argv[2]); - align.match = gva_std_allocator.allocate(gva_std_allocator.context, align.match, align.max_lcs_pos, 0); align.uniq = gva_std_allocator.allocate(gva_std_allocator.context, align.uniq, align.max_lcs_pos, 0); From 9e62a531312750b1f4916e594e7ecf9aedc0a8da Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Tue, 10 Mar 2026 13:29:45 +0100 Subject: [PATCH 537/704] gva_index_variant: Construct variant from index. --- include/index.h | 4 ++++ src/index.c | 7 +++++++ src/main.c | 8 ++++++-- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/include/index.h b/include/index.h index 952758c..9f10858 100644 --- a/include/index.h +++ b/include/index.h @@ -60,4 +60,8 @@ GVA_String gva_index_id(GVA_Index const* const self, size_t const idx); +GVA_Variant +gva_index_variant(GVA_Index const* const self, gva_uint const allele_idx, gva_uint const variant_idx); + + #endif // GVA_INDEX_H diff --git a/src/index.c b/src/index.c index 8250b6d..7fae307 100644 --- a/src/index.c +++ b/src/index.c @@ -82,6 +82,13 @@ variant_from_index(GVA_Index const self[static 1], size_t const idx) } // variant_from_index +inline GVA_Variant +gva_index_variant(GVA_Index const* const self, gva_uint const allele_idx, gva_uint const variant_idx) +{ + return variant_from_index(self, self->join[variant_idx].link ^ allele_idx); +} // gva_variant_from_index + + static size_t variants_distance(GVA_Allocator const allocator, size_t const len_ref, char const reference[static len_ref], diff --git a/src/main.c b/src/main.c index ed4508c..2a87417 100644 --- a/src/main.c +++ b/src/main.c @@ -154,11 +154,15 @@ index_main(int argc, char* argv[static argc]) GVA_RELATION_LABELS[result.alleles[i].relation]); for (size_t j = result.alleles[i].hits.start; j < result.alleles[i].hits.end; ++j) { - fprintf(stderr, " [%u, %u) [%u, %u): %u %u %s\n", + // TODO: deal with multiple part hits + fprintf(stderr, " [%u, %u) [%u, %u): %u %u %s " GVA_VARIANT_FMT_SPDI " " GVA_VARIANT_FMT_SPDI "\n", result.hits[j].query.start, result.hits[j].query.end, result.hits[j].index.start, result.hits[j].index.end, result.hits[j].included, result.hits[j].excluded, - GVA_RELATION_LABELS[result.hits[j].relation]); + GVA_RELATION_LABELS[result.hits[j].relation], + GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, gva_lcs_graph_local_supremal(graph, result.hits[j].query.start, result.hits[j].query.end)), + GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, gva_index_variant(index, result.alleles[i].idx, result.hits[j].index.start)) + ); } // for } // for result.alleles = ARRAY_DESTROY(gva_std_allocator, result.alleles); From 7158201da44a016b2c15cccecb4c873840519cab Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Tue, 10 Mar 2026 13:34:13 +0100 Subject: [PATCH 538/704] Merge. --- src/main.c | 73 ++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 52 insertions(+), 21 deletions(-) diff --git a/src/main.c b/src/main.c index 7b98d79..0102cdb 100644 --- a/src/main.c +++ b/src/main.c @@ -17,11 +17,14 @@ #include "common.h" // MAX, MIN +#include + + #define LINE_SIZE 8194 // #define REFERENCE_ID "NC_000022.11" -// #define REFERENCE_ID "NC_000006.12" -#define REFERENCE_ID "NC_000001.11" +#define REFERENCE_ID "NC_000006.12" +// #define REFERENCE_ID "NC_000001.11" // line: alphanumeric_id SPDI [distance] @@ -292,30 +295,58 @@ extract_main(int argc, char* argv[static argc]) GVA_LCS_Graph graph = gva_lcs_graph_init(gva_std_allocator, reference.len, reference.str, observed.len, observed.str, 0); - fprintf(stdout, " distance: %zu\n", gva_lcs_graph_distance(graph)); - fprintf(stdout, " #nodes: %zu\n", array_length(graph.nodes)); - for (size_t i = 0; i < array_length(graph.nodes); ++i) + // fprintf(stdout, " distance: %zu\n", gva_lcs_graph_distance(graph)); + // fprintf(stdout, " #nodes: %zu\n", array_length(graph.nodes)); + // for (size_t i = 0; i < array_length(graph.nodes); ++i) + // { + // fprintf(stdout, " %zu: (%u, %u, %u)\n", i, + // graph.nodes[i].match.row, graph.nodes[i].match.col, graph.nodes[i].match.length); + // } // for + // fprintf(stdout, " #edges: %zu\n", array_length(graph.edges)); + // fprintf(stdout, " #dom_nodes: %zu\n", array_length(graph.dom_nodes)); + // if (array_length(graph.dom_nodes) < 3) + // { + // continue; + // } + + // for (size_t i = 0; i < array_length(graph.dom_nodes); ++i) + // { + // if (i > 0) + // { + // fprintf(stdout, " " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(gva_lcs_graph_local_supremal(graph, i - 1, i))); + // } // if + // fprintf(stdout, " %zu: (%u, %u, %u) %u\n", i, + // graph.dom_nodes[i].match.row, graph.dom_nodes[i].match.col, graph.dom_nodes[i].match.length, + // graph.dom_nodes[i].distance); + // } // for + + // fprintf(stdout, " supremal: " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(gva_lcs_graph_supremal(graph))); + + gva_lcs_graph_dot(stdout, graph); + GVA_Variant sup = gva_variant_dup(gva_std_allocator, gva_lcs_graph_supremal(graph)); + + GVA_LCS_Graph graph2 = gva_lcs_graph_from_allele(gva_std_allocator, reference.len, reference.str, 1, &sup); + gva_lcs_graph_dot(stdout, graph2); + + if (array_length(graph.dom_nodes) != array_length(graph2.dom_nodes)) { - fprintf(stdout, " %zu: (%u, %u, %u)\n", i, - graph.nodes[i].match.row, graph.nodes[i].match.col, graph.nodes[i].match.length); - } // for - fprintf(stdout, " #edges: %zu\n", array_length(graph.edges)); - fprintf(stdout, " #dom_nodes: %zu\n", array_length(graph.dom_nodes)); + fprintf(stderr, "length dom nodes mismatch\n"); + assert(0 == 1); + } + for (size_t i = 0; i < array_length(graph.dom_nodes); ++i) { - if (i > 0) + if (graph.dom_nodes[i].match.row != graph2.dom_nodes[i].match.row || + graph.dom_nodes[i].match.col != graph2.dom_nodes[i].match.col || + graph.dom_nodes[i].match.length != graph2.dom_nodes[i].match.length) { - fprintf(stdout, " " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(gva_lcs_graph_local_supremal(graph, i - 1, i))); - } // if - fprintf(stdout, " %zu: (%u, %u, %u) %u\n", i, - graph.dom_nodes[i].match.row, graph.dom_nodes[i].match.col, graph.dom_nodes[i].match.length, - graph.dom_nodes[i].distance); - } // for - - fprintf(stdout, " supremal: " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(gva_lcs_graph_supremal(graph))); - - gva_lcs_graph_dot(stdout, graph); + fprintf(stderr, "dom nodes mismatch\n"); + assert(0 == 1); + } + } + gva_string_destroy(gva_std_allocator, sup.sequence); + gva_lcs_graph_destroy(gva_std_allocator, graph2, true); gva_lcs_graph_destroy(gva_std_allocator, graph, false); } // while From e15b06b0e9c8904ccaf30f512d00cbd5bee60613 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 10 Mar 2026 13:59:31 +0100 Subject: [PATCH 539/704] Local supremals for hla --- src/main.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/main.c b/src/main.c index 0acd0c6..f288bae 100644 --- a/src/main.c +++ b/src/main.c @@ -20,8 +20,8 @@ #define LINE_SIZE 8194 // #define REFERENCE_ID "NC_000022.11" -// #define REFERENCE_ID "NC_000006.12" -#define REFERENCE_ID "NC_000001.11" +#define REFERENCE_ID "NC_000006.12" +// #define REFERENCE_ID "NC_000001.11" // line: alphanumeric_id SPDI [distance] @@ -357,10 +357,19 @@ supremal_main(int argc, char* argv[static argc]) } // if GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &variant); + /* GVA_Variant supremal = gva_lcs_graph_supremal(graph); fprintf(stdout, GVA_STRING_FMT " " GVA_VARIANT_FMT_SPDI " %zu\n", GVA_STRING_PRINT(id), GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, supremal), gva_lcs_graph_distance(graph)); + */ + + for (size_t i = 0; i < array_length(graph.dom_nodes) - 1; ++i) + { + fprintf(stdout, GVA_STRING_FMT " " GVA_VARIANT_FMT_SPDI " %u\n", + GVA_STRING_PRINT(id), GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, gva_lcs_graph_local_supremal(graph, i, i + 1)), graph.dom_nodes[i + 1].distance - graph.dom_nodes[i].distance); + } // for + gva_lcs_graph_destroy(gva_std_allocator, graph, true); } // while From e3c386cfc26263628608b52eadc8d628ff4553b6 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 10 Mar 2026 14:01:00 +0100 Subject: [PATCH 540/704] Removed debug --- src/align.c | 32 -------------------------------- 1 file changed, 32 deletions(-) diff --git a/src/align.c b/src/align.c index 15ded0f..c772ed7 100644 --- a/src/align.c +++ b/src/align.c @@ -10,9 +10,6 @@ #include "common.h" // ABS, MAX, MIN -#include // DEBUG - - typedef struct { GVA_Allocator const allocator; @@ -231,15 +228,6 @@ onp_snake(size_t const m, char const a[static restrict m], size_t col = MAX(lower, upper); size_t row = col - k; - if (swapped) - { - fprintf(stderr, " snake start: (%zu, %zu)\n", col, row); - } // if - else - { - fprintf(stderr, " snake start: (%zu, %zu)\n", row, col); - } // else - intmax_t const d_row = m - row; intmax_t const d_col = n - col; @@ -248,16 +236,6 @@ onp_snake(size_t const m, char const a[static restrict m], row += 1; col += 1; size_t const lcs_pos = (row + col - ABS(delta) - 2 * p + ABS(d_row - d_col)) / 2; - - if (swapped) - { - fprintf(stderr, " snake match @ %zu: (%zu, %zu)\n", lcs_pos - 1, col - 1, row - 1); - } // if - else - { - fprintf(stderr, " snake match @ %zu: (%zu, %zu)\n", lcs_pos - 1, row - 1, col - 1); - } // else - result->uniq[lcs_pos - 1] = 0; if (lcs_pos > result->max_lcs_pos) { @@ -276,15 +254,6 @@ onp_snake(size_t const m, char const a[static restrict m], } // if } // while - if (swapped) - { - fprintf(stderr, " snake end: (%zu, %zu)\n", col, row); - } // if - else - { - fprintf(stderr, " snake end: (%zu, %zu)\n", row, col); - } // else - return col; } // onp_snake @@ -321,7 +290,6 @@ onp_compare(GVA_Allocator const allocator, size_t p = 0; while ((size_t) fp[delta + offset] != n) { - fprintf(stderr, "p: %zu\n", p); fp[-p - 1 + offset] = -1; fp[delta + p + 1 + offset] = -1; for (intmax_t k = -p; k <= delta - 1; ++k) From 90e78f23854230e02e63887d59d4a55c2b774f73 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 10 Mar 2026 14:01:50 +0100 Subject: [PATCH 541/704] Removed more debug --- src/main.c | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/main.c b/src/main.c index 0d1a04b..dcbfe35 100644 --- a/src/main.c +++ b/src/main.c @@ -263,19 +263,6 @@ allele_main(int argc, char* argv[static argc]) int extract_main(int argc, char* argv[static argc]) { - if (argc < 3) - { - fprintf(stderr, "usage: %s reference observed\n", argv[0]); - return EXIT_FAILURE; - } // if - - LCS_Matches align = lcs_align_one(gva_std_allocator, strlen(argv[1]), argv[1], strlen(argv[2]), argv[2]); - - align.match = gva_std_allocator.allocate(gva_std_allocator.context, align.match, align.max_lcs_pos, 0); - align.uniq = gva_std_allocator.allocate(gva_std_allocator.context, align.uniq, align.max_lcs_pos, 0); - - return EXIT_SUCCESS; - (void) argv; size_t line_count = 0; From 529d1b2597c57a3d950ef776a8b8ce2b1efb89a9 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 10 Mar 2026 14:08:14 +0100 Subject: [PATCH 542/704] Revert "Refactored duplicated code" This reverts commit b491ea52d7c19e246b04437151035f9160ab0e57. --- include/string.h | 5 ++--- src/lcs_graph.c | 8 ++++---- src/string.c | 31 +++++++++++++++---------------- src/trie.c | 17 +++++++++++++++-- src/variant.c | 33 ++++++++------------------------- 5 files changed, 44 insertions(+), 50 deletions(-) diff --git a/include/string.h b/include/string.h index 1c7c286..18cf9c7 100644 --- a/include/string.h +++ b/include/string.h @@ -36,12 +36,11 @@ gva_string_dup(GVA_Allocator const allocator, GVA_String const self); void -gva_string_reverse(size_t const len, char str[static len]); +gva_string_reverse(GVA_String self); size_t -gva_prefix_length(size_t const len_lhs, char const lhs[static restrict len_lhs], - size_t const len_rhs, char const rhs[static restrict len_rhs]); +gva_string_prefix_length(GVA_String const lhs, GVA_String const rhs); #endif // GVA_STRING_H diff --git a/src/lcs_graph.c b/src/lcs_graph.c index 1c57ce2..efad035 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -96,12 +96,12 @@ local_supremal(GVA_Allocator const allocator, } // if LCS_Matches forward = lcs_align_one(allocator, len_ref, reference, len_obs, observed); - gva_string_reverse(len_ref, (char*) reference); - gva_string_reverse(len_obs, (char*) observed); + gva_string_reverse((GVA_String) {len_ref, reference}); + gva_string_reverse((GVA_String) {len_obs, observed}); LCS_Matches backward = lcs_align_one(allocator, len_ref, reference, len_obs, observed); - gva_string_reverse(len_ref, (char*) reference); - gva_string_reverse(len_obs, (char*) observed); + gva_string_reverse((GVA_String) {len_ref, reference}); + gva_string_reverse((GVA_String) {len_obs, observed}); size_t sum = 0; size_t prev_row = -1; diff --git a/src/string.c b/src/string.c index aae0b6f..2bc408b 100644 --- a/src/string.c +++ b/src/string.c @@ -49,29 +49,28 @@ gva_string_dup(GVA_Allocator const allocator, GVA_String const self) inline void -gva_string_reverse(size_t const len, char str[static len]) +gva_string_reverse(GVA_String self) { - size_t i = 0; - size_t j = len - 1; - while (i < j) + size_t i = self.len - 1; + size_t j = 0; + while (i > j) { - char const ch = str[i]; - str[j] = str[i]; - str[i] = ch; - i += 1; - j -= 1; + char const ch = self.str[i]; + ((char*) self.str)[i] = self.str[j]; + ((char*) self.str)[j] = ch; + i -= 1; + j += 1; } // while } // gva_string_reverse inline size_t -gva_prefix_length(size_t const len_lhs, char const lhs[static restrict len_lhs], - size_t const len_rhs, char const rhs[static restrict len_rhs]) +gva_string_prefix_length(GVA_String const lhs, GVA_String const rhs) { - size_t i = 0; - while (i < len_lhs && i < len_rhs && lhs[i] == rhs[i]) + size_t idx = 0; + while (idx < lhs.len && idx < rhs.len && lhs.str[idx] == rhs.str[idx]) { - i += 1; + idx += 1; } // while - return i; -} // gva_prefix_length + return idx; +} // gva_string_prefix_length diff --git a/src/trie.c b/src/trie.c index 6d2d6f1..5fdb078 100644 --- a/src/trie.c +++ b/src/trie.c @@ -3,7 +3,7 @@ #include // memcpy #include "../include/allocator.h" // GVA_Allocator -#include "../include/string.h" // GVA_String, gva_prefix_length +#include "../include/string.h" // GVA_String #include "../include/types.h" // GVA_NULL, gva_uint #include "array.h" // ARRAY_*, array_* #include "trie.h" // Trie, TrieNode, trie_* @@ -29,6 +29,19 @@ trie_destroy(Trie self[static 1]) } // trie_destroy +static inline size_t +prefix_length(size_t const len_lhs, char const lhs[static restrict len_lhs], + size_t const len_rhs, char const rhs[static restrict len_rhs]) +{ + size_t i = 0; + while (i < len_lhs && i < len_rhs && lhs[i] == rhs[i]) + { + i += 1; + } // while + return i; +} // prefix_length + + static inline size_t concat(Trie self[static restrict 1], size_t const len, char const key[static restrict len]) @@ -66,7 +79,7 @@ trie_insert(Trie self[static restrict 1], while (true) { gva_uint const p_len = self->nodes[idx].end - self->nodes[idx].p_start; - size_t const k = gva_prefix_length(len - prefix, key + prefix, + size_t const k = prefix_length(len - prefix, key + prefix, p_len, self->strings + self->nodes[idx].p_start); if (k == len - prefix && k == p_len) { diff --git a/src/variant.c b/src/variant.c index 0df666e..e7ebc22 100644 --- a/src/variant.c +++ b/src/variant.c @@ -1,10 +1,10 @@ #include // bool #include // NULL, size_t -#include // memcmp, mempcy +#include // memcmp #include "../include/allocator.h" // GVA_Allocator #include "../include/types.h" // gva_uint -#include "../include/string.h" // GVA_String, gva_string_*, gva_prefix_length +#include "../include/string.h" // GVA_String, gva_string_* #include "../include/variant.h" // gva_parse_spdi, gva_patch #include "common.h" // MIN @@ -138,8 +138,7 @@ inline GVA_Variant gva_variant_prefix_trimmed(size_t const len_ref, char const reference[static len_ref], GVA_Variant const variant) { - size_t const len = gva_prefix_length(variant.end - variant.start, reference + variant.start, - variant.sequence.len, variant.sequence.str); + size_t const len = gva_string_prefix_length((GVA_String) {(variant.end - variant.start), reference + variant.start}, variant.sequence); return (GVA_Variant) {variant.start + len, variant.end, {variant.sequence.len - len, variant.sequence.str + len}}; } // gva_variant_prefix_trimmed @@ -149,35 +148,19 @@ gva_patch(GVA_Allocator const allocator, size_t const len_ref, char const reference[static restrict len_ref], size_t const n, GVA_Variant const variants[static restrict n]) { - size_t deleted = 0; - size_t inserted = 0; - for (size_t i = 0; i < n; ++i) - { - deleted += variants[i].end - variants[i].start; - inserted += variants[i].sequence.len; - } // for - - char* const restrict observed = allocator.allocate(allocator.context, NULL, 0, len_ref + inserted - deleted); - if (observed == NULL) - { - return (GVA_String) {0}; - } // if - + GVA_String observed = {0}; size_t start = 0; - size_t len = 0; for (size_t i = 0; i < n; ++i) { - memcpy(observed + len, reference + start, variants[i].start - start); - len += variants[i].start - start; - memcpy(observed + len, variants[i].sequence.str, variants[i].sequence.len); - len += variants[i].sequence.len; + observed = gva_string_concat(allocator, observed, (GVA_String) {variants[i].start - start, reference + start}); + observed = gva_string_concat(allocator, observed, variants[i].sequence); start = variants[i].end; } // for if (start < len_ref) { - memcpy(observed + len, reference + start, len_ref - start); + observed = gva_string_concat(allocator, observed, (GVA_String) {len_ref - start, reference + start}); } // if - return (GVA_String) {len, observed}; + return observed; } // gva_patch From 0b4d688535ff07e8b36ba3db58de1bfce14c465a Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 10 Mar 2026 14:42:27 +0100 Subject: [PATCH 543/704] Bring back some of the refactoring --- include/string.h | 5 +++-- src/lcs_graph.c | 8 ++++---- src/string.c | 23 ++++++++++++----------- src/trie.c | 17 ++--------------- src/variant.c | 5 +++-- 5 files changed, 24 insertions(+), 34 deletions(-) diff --git a/include/string.h b/include/string.h index 18cf9c7..1c7c286 100644 --- a/include/string.h +++ b/include/string.h @@ -36,11 +36,12 @@ gva_string_dup(GVA_Allocator const allocator, GVA_String const self); void -gva_string_reverse(GVA_String self); +gva_string_reverse(size_t const len, char str[static len]); size_t -gva_string_prefix_length(GVA_String const lhs, GVA_String const rhs); +gva_prefix_length(size_t const len_lhs, char const lhs[static restrict len_lhs], + size_t const len_rhs, char const rhs[static restrict len_rhs]); #endif // GVA_STRING_H diff --git a/src/lcs_graph.c b/src/lcs_graph.c index efad035..1c57ce2 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -96,12 +96,12 @@ local_supremal(GVA_Allocator const allocator, } // if LCS_Matches forward = lcs_align_one(allocator, len_ref, reference, len_obs, observed); - gva_string_reverse((GVA_String) {len_ref, reference}); - gva_string_reverse((GVA_String) {len_obs, observed}); + gva_string_reverse(len_ref, (char*) reference); + gva_string_reverse(len_obs, (char*) observed); LCS_Matches backward = lcs_align_one(allocator, len_ref, reference, len_obs, observed); - gva_string_reverse((GVA_String) {len_ref, reference}); - gva_string_reverse((GVA_String) {len_obs, observed}); + gva_string_reverse(len_ref, (char*) reference); + gva_string_reverse(len_obs, (char*) observed); size_t sum = 0; size_t prev_row = -1; diff --git a/src/string.c b/src/string.c index 2bc408b..d9f8ba3 100644 --- a/src/string.c +++ b/src/string.c @@ -49,15 +49,15 @@ gva_string_dup(GVA_Allocator const allocator, GVA_String const self) inline void -gva_string_reverse(GVA_String self) +gva_string_reverse(size_t const len, char str[static len]) { - size_t i = self.len - 1; + size_t i = len - 1; size_t j = 0; while (i > j) { - char const ch = self.str[i]; - ((char*) self.str)[i] = self.str[j]; - ((char*) self.str)[j] = ch; + char const ch = str[i]; + str[i] = str[j]; + str[j] = ch; i -= 1; j += 1; } // while @@ -65,12 +65,13 @@ gva_string_reverse(GVA_String self) inline size_t -gva_string_prefix_length(GVA_String const lhs, GVA_String const rhs) +gva_prefix_length(size_t const len_lhs, char const lhs[static restrict len_lhs], + size_t const len_rhs, char const rhs[static restrict len_rhs]) { - size_t idx = 0; - while (idx < lhs.len && idx < rhs.len && lhs.str[idx] == rhs.str[idx]) + size_t i = 0; + while (i < len_lhs && i < len_rhs && lhs[i] == rhs[i]) { - idx += 1; + i += 1; } // while - return idx; -} // gva_string_prefix_length + return i; +} // gva_prefix_length diff --git a/src/trie.c b/src/trie.c index 5fdb078..6d2d6f1 100644 --- a/src/trie.c +++ b/src/trie.c @@ -3,7 +3,7 @@ #include // memcpy #include "../include/allocator.h" // GVA_Allocator -#include "../include/string.h" // GVA_String +#include "../include/string.h" // GVA_String, gva_prefix_length #include "../include/types.h" // GVA_NULL, gva_uint #include "array.h" // ARRAY_*, array_* #include "trie.h" // Trie, TrieNode, trie_* @@ -29,19 +29,6 @@ trie_destroy(Trie self[static 1]) } // trie_destroy -static inline size_t -prefix_length(size_t const len_lhs, char const lhs[static restrict len_lhs], - size_t const len_rhs, char const rhs[static restrict len_rhs]) -{ - size_t i = 0; - while (i < len_lhs && i < len_rhs && lhs[i] == rhs[i]) - { - i += 1; - } // while - return i; -} // prefix_length - - static inline size_t concat(Trie self[static restrict 1], size_t const len, char const key[static restrict len]) @@ -79,7 +66,7 @@ trie_insert(Trie self[static restrict 1], while (true) { gva_uint const p_len = self->nodes[idx].end - self->nodes[idx].p_start; - size_t const k = prefix_length(len - prefix, key + prefix, + size_t const k = gva_prefix_length(len - prefix, key + prefix, p_len, self->strings + self->nodes[idx].p_start); if (k == len - prefix && k == p_len) { diff --git a/src/variant.c b/src/variant.c index e7ebc22..ab09315 100644 --- a/src/variant.c +++ b/src/variant.c @@ -4,7 +4,7 @@ #include "../include/allocator.h" // GVA_Allocator #include "../include/types.h" // gva_uint -#include "../include/string.h" // GVA_String, gva_string_* +#include "../include/string.h" // GVA_String, gva_string_*, gva_prefix_length #include "../include/variant.h" // gva_parse_spdi, gva_patch #include "common.h" // MIN @@ -138,7 +138,8 @@ inline GVA_Variant gva_variant_prefix_trimmed(size_t const len_ref, char const reference[static len_ref], GVA_Variant const variant) { - size_t const len = gva_string_prefix_length((GVA_String) {(variant.end - variant.start), reference + variant.start}, variant.sequence); + size_t const len = gva_prefix_length(variant.end - variant.start, reference + variant.start, + variant.sequence.len, variant.sequence.str); return (GVA_Variant) {variant.start + len, variant.end, {variant.sequence.len - len, variant.sequence.str + len}}; } // gva_variant_prefix_trimmed From f4f598390137e12cc7bf2dc9fca1de0a2849c690 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 10 Mar 2026 16:17:28 +0100 Subject: [PATCH 544/704] Bring back patch with single alloc --- src/main.c | 32 ++++++++++++++++++++++---------- src/variant.c | 29 +++++++++++++++++++++++------ 2 files changed, 45 insertions(+), 16 deletions(-) diff --git a/src/main.c b/src/main.c index dcbfe35..d582a76 100644 --- a/src/main.c +++ b/src/main.c @@ -165,8 +165,7 @@ index_main(int argc, char* argv[static argc]) result.hits[j].included, result.hits[j].excluded, GVA_RELATION_LABELS[result.hits[j].relation], GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, gva_lcs_graph_local_supremal(graph, result.hits[j].query.start, result.hits[j].query.end)), - GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, gva_index_variant(index, result.alleles[i].idx, result.hits[j].index.start)) - ); + GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, gva_index_variant(index, result.alleles[i].idx, result.hits[j].index.start))); } // for } // for result.alleles = ARRAY_DESTROY(gva_std_allocator, result.alleles); @@ -253,6 +252,16 @@ allele_main(int argc, char* argv[static argc]) fprintf(stderr, "#edges: %zu\n", array_length(graph.edges)); gva_lcs_graph_destroy(gva_std_allocator, graph, true); + + if (variants != NULL) + { + for (size_t i = 0; i < array_length(variants); ++i) + { + gva_string_destroy(gva_std_allocator, variants[i].sequence); + } // for + variants = ARRAY_DESTROY(gva_std_allocator, variants); + } // if + gva_string_destroy(gva_std_allocator, reference); return EXIT_SUCCESS; @@ -318,8 +327,8 @@ extract_main(int argc, char* argv[static argc]) if (array_length(graph.dom_nodes) != array_length(graph2.dom_nodes)) { fprintf(stderr, "length dom nodes mismatch\n"); - assert(0 == 1); - } + assert(0); + } // if for (size_t i = 0; i < array_length(graph.dom_nodes); ++i) { @@ -328,9 +337,9 @@ extract_main(int argc, char* argv[static argc]) graph.dom_nodes[i].match.length != graph2.dom_nodes[i].match.length) { fprintf(stderr, "dom nodes mismatch\n"); - assert(0 == 1); - } - } + assert(0); + } // if + } // for gva_string_destroy(gva_std_allocator, sup.sequence); gva_lcs_graph_destroy(gva_std_allocator, graph2, true); @@ -383,16 +392,19 @@ supremal_main(int argc, char* argv[static argc]) GVA_Variant supremal = gva_lcs_graph_supremal(graph); fprintf(stdout, GVA_STRING_FMT " " GVA_VARIANT_FMT_SPDI " %zu\n", - GVA_STRING_PRINT(id), GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, supremal), gva_lcs_graph_distance(graph)); + GVA_STRING_PRINT(id), + GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, supremal), + gva_lcs_graph_distance(graph)); */ for (size_t i = 0; i < array_length(graph.dom_nodes) - 1; ++i) { fprintf(stdout, GVA_STRING_FMT " " GVA_VARIANT_FMT_SPDI " %u\n", - GVA_STRING_PRINT(id), GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, gva_lcs_graph_local_supremal(graph, i, i + 1)), graph.dom_nodes[i + 1].distance - graph.dom_nodes[i].distance); + GVA_STRING_PRINT(id), + GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, gva_lcs_graph_local_supremal(graph, i, i + 1)), + graph.dom_nodes[i + 1].distance - graph.dom_nodes[i].distance); } // for - gva_lcs_graph_destroy(gva_std_allocator, graph, true); } // while diff --git a/src/variant.c b/src/variant.c index ab09315..9c4f98f 100644 --- a/src/variant.c +++ b/src/variant.c @@ -1,6 +1,6 @@ #include // bool #include // NULL, size_t -#include // memcmp +#include // memcmp, memcpy #include "../include/allocator.h" // GVA_Allocator #include "../include/types.h" // gva_uint @@ -149,19 +149,36 @@ gva_patch(GVA_Allocator const allocator, size_t const len_ref, char const reference[static restrict len_ref], size_t const n, GVA_Variant const variants[static restrict n]) { - GVA_String observed = {0}; + size_t deleted = 0; + size_t inserted = 0; + for (size_t i = 0; i < n; ++i) + { + deleted += variants[i].end - variants[i].start; + inserted += variants[i].sequence.len; + } // for + + char* str = allocator.allocate(allocator.context, NULL, 0, len_ref + inserted - deleted); + if (str == NULL) + { + return (GVA_String) {0}; + } // if + + size_t len = 0; size_t start = 0; for (size_t i = 0; i < n; ++i) { - observed = gva_string_concat(allocator, observed, (GVA_String) {variants[i].start - start, reference + start}); - observed = gva_string_concat(allocator, observed, variants[i].sequence); + memcpy(str + len, reference + start, variants[i].start - start); + len += variants[i].start - start; + memcpy(str + len, variants[i].sequence.str, variants[i].sequence.len); + len += variants[i].sequence.len; start = variants[i].end; } // for if (start < len_ref) { - observed = gva_string_concat(allocator, observed, (GVA_String) {len_ref - start, reference + start}); + memcpy(str + len, reference + start, len_ref - start); + len += len_ref - start; } // if - return observed; + return (GVA_String) {len, str}; } // gva_patch From 45cae46890f9da059fbf917d1c37a5c33f89cbd9 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 10 Mar 2026 21:32:26 +0100 Subject: [PATCH 545/704] Reorder --- include/index.h | 3 ++- src/index.c | 15 ++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/include/index.h b/include/index.h index 9f10858..114944f 100644 --- a/include/index.h +++ b/include/index.h @@ -61,7 +61,8 @@ gva_index_id(GVA_Index const* const self, size_t const idx); GVA_Variant -gva_index_variant(GVA_Index const* const self, gva_uint const allele_idx, gva_uint const variant_idx); +gva_index_variant(GVA_Index const* const self, + size_t const allele_idx, size_t const variant_idx); #endif // GVA_INDEX_H diff --git a/src/index.c b/src/index.c index 284cb94..72cf608 100644 --- a/src/index.c +++ b/src/index.c @@ -82,13 +82,6 @@ variant_from_index(GVA_Index const self[static 1], size_t const idx) } // variant_from_index -inline GVA_Variant -gva_index_variant(GVA_Index const* const self, gva_uint const allele_idx, gva_uint const variant_idx) -{ - return variant_from_index(self, self->join[variant_idx].link ^ allele_idx); -} // gva_variant_from_index - - static size_t variants_distance(GVA_Allocator const allocator, size_t const len_ref, char const reference[static len_ref], @@ -607,3 +600,11 @@ gva_index_id(GVA_Index const* const self, size_t const idx) { return trie_string(self->ids, self->alleles[idx].id_idx); } // gva_index_id + + +inline GVA_Variant +gva_index_variant(GVA_Index const* const self, + size_t const allele_idx, size_t const variant_idx) +{ + return variant_from_index(self, self->join[variant_idx].link ^ allele_idx); +} // gva_variant_from_index From dd4eba3cb02e6323c5daf271bf3dab7a229fbe73 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Wed, 11 Mar 2026 11:32:46 +0100 Subject: [PATCH 546/704] Guard against adding initial empty sequence. --- src/trie.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/trie.c b/src/trie.c index 6d2d6f1..9039b06 100644 --- a/src/trie.c +++ b/src/trie.c @@ -35,6 +35,10 @@ concat(Trie self[static restrict 1], { size_t const start = array_length(self->strings); self->strings = array_ensure(self->allocator, self->strings, sizeof(*self->strings), len); + if (self->strings == NULL) + { + return start; + } // if memcpy(self->strings + start, key, len); array_header(self->strings)->length += len; return start; From 983e2a7058423f04599dda447397bb8d85e30482 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Thu, 12 Mar 2026 01:31:17 +0100 Subject: [PATCH 547/704] Expose node distance and allele start offset. --- include/index.h | 8 ++++++++ src/index.c | 16 +++++++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/include/index.h b/include/index.h index 114944f..8531e8b 100644 --- a/include/index.h +++ b/include/index.h @@ -65,4 +65,12 @@ gva_index_variant(GVA_Index const* const self, size_t const allele_idx, size_t const variant_idx); +gva_uint +gva_index_allele_start(GVA_Index const* const self, size_t const allele_idx); + + +gva_uint +gva_index_node_distance(GVA_Index const* const self, size_t const allele_idx, size_t const variant_idx); + + #endif // GVA_INDEX_H diff --git a/src/index.c b/src/index.c index 72cf608..818a531 100644 --- a/src/index.c +++ b/src/index.c @@ -607,4 +607,18 @@ gva_index_variant(GVA_Index const* const self, size_t const allele_idx, size_t const variant_idx) { return variant_from_index(self, self->join[variant_idx].link ^ allele_idx); -} // gva_variant_from_index +} // gva_index_variant + + +gva_uint +gva_index_allele_start(GVA_Index const* const self, size_t const allele_idx) +{ + return self->alleles[allele_idx].start; +} // gva_index_allele_start + + +gva_uint +gva_index_node_distance(GVA_Index const* const self, size_t const allele_idx, size_t const variant_idx) +{ + return self->intervals.nodes[self->join[variant_idx].link ^ allele_idx].distance; +} // gva_index_node_distance From 73cca6e21578d65c2613386300b8dc3a3a4e53e8 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Thu, 12 Mar 2026 01:31:36 +0100 Subject: [PATCH 548/704] Macros for allele parts. --- include/variant.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/variant.h b/include/variant.h index aba88ea..23b0100 100644 --- a/include/variant.h +++ b/include/variant.h @@ -16,6 +16,8 @@ #define GVA_VARIANT_PRINT_SPDI(ref_id, variant) ref_id, variant.start, (variant.end - variant.start), GVA_STRING_PRINT(variant.sequence) #define GVA_VARIANT_FMT_SPDI "%s:" GVA_UINT_FMT ":" GVA_UINT_FMT ":" GVA_STRING_FMT +#define GVA_VARIANT_PRINT_SPDI_ALLELE(variant) variant.start, (variant.end - variant.start), GVA_STRING_PRINT(variant.sequence) +#define GVA_VARIANT_FMT_SPDI_ALLELE GVA_UINT_FMT ":" GVA_UINT_FMT ":" GVA_STRING_FMT typedef struct { From 82f5dbc03ef59f84a50ea67419753091a6756e9d Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Thu, 12 Mar 2026 01:32:20 +0100 Subject: [PATCH 549/704] HLA style results output. --- src/main.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 68 insertions(+), 6 deletions(-) diff --git a/src/main.c b/src/main.c index d582a76..1484105 100644 --- a/src/main.c +++ b/src/main.c @@ -156,16 +156,78 @@ index_main(int argc, char* argv[static argc]) GVA_STRING_PRINT(gva_index_id(index, result.alleles[i].idx)), result.alleles[i].included, result.alleles[i].excluded, GVA_RELATION_LABELS[result.alleles[i].relation]); + + size_t last_q = -1; + size_t last_i = gva_index_allele_start(index, result.alleles[i].idx); + // TODO: also address trailing disjoints? for (size_t j = result.alleles[i].hits.start; j < result.alleles[i].hits.end; ++j) { - // TODO: deal with multiple part hits - fprintf(stderr, " [%u, %u) [%u, %u): %u %u %s " GVA_VARIANT_FMT_SPDI " " GVA_VARIANT_FMT_SPDI "\n", - result.hits[j].query.start, result.hits[j].query.end, + for (size_t k = last_q + 1; k < result.hits[j].query.start; ++k) + { + fprintf(stderr, " [) [%zu, %zu): 0 %u disjoint ", k, k + 1, + graph.dom_nodes[k + 1].distance - graph.dom_nodes[k].distance); + fprintf(stderr, "* " GVA_VARIANT_FMT_SPDI_ALLELE "\n", + GVA_VARIANT_PRINT_SPDI_ALLELE(gva_lcs_graph_local_supremal(graph, k, k + 1))); + } + last_q = result.hits[j].query.start; + + for (size_t k = last_i + 1; k < result.hits[j].index.start; ++k) + { + fprintf(stderr, " [%zu, %zu) [): 0 %u disjoint ", k, k + 1, gva_index_node_distance(index, result.alleles[i].idx, k)); + fprintf(stderr, GVA_VARIANT_FMT_SPDI_ALLELE " *\n", + GVA_VARIANT_PRINT_SPDI_ALLELE(gva_index_variant(index, result.alleles[i].idx, k))); + } + last_i = result.hits[j].index.start; + + fprintf(stderr, " [%u, %u) [%u, %u): %u %u %s ", result.hits[j].index.start, result.hits[j].index.end, + result.hits[j].query.start, result.hits[j].query.end, result.hits[j].included, result.hits[j].excluded, - GVA_RELATION_LABELS[result.hits[j].relation], - GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, gva_lcs_graph_local_supremal(graph, result.hits[j].query.start, result.hits[j].query.end)), - GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, gva_index_variant(index, result.alleles[i].idx, result.hits[j].index.start))); + GVA_RELATION_LABELS[result.hits[j].relation]); + + // print index allele + fprintf(stderr, REFERENCE_ID ":"); + if (result.hits[j].index.end - result.hits[j].index.start > 1) + { + fprintf(stderr, "["); + } + for (size_t k = result.hits[j].index.start; k < result.hits[j].index.end; ++k) + { + fprintf(stderr, GVA_VARIANT_FMT_SPDI_ALLELE, + GVA_VARIANT_PRINT_SPDI_ALLELE(gva_index_variant(index, result.alleles[i].idx, k))); + if (k + 1 < result.hits[j].index.end) + { + fprintf(stderr, "/"); + } + } + if (result.hits[j].index.end - result.hits[j].index.start > 1) + { + fprintf(stderr, "]"); + } + fprintf(stderr, " "); + + // print query allele + fprintf(stderr, REFERENCE_ID ":"); + + if (result.hits[j].query.end - result.hits[j].query.start > 1) + { + fprintf(stderr, "["); + } + for (size_t k = result.hits[j].query.start; k < result.hits[j].query.end; ++k) + { + fprintf(stderr, GVA_VARIANT_FMT_SPDI_ALLELE, + GVA_VARIANT_PRINT_SPDI_ALLELE(gva_lcs_graph_local_supremal(graph, k, k + 1))); + if (k + 1 < result.hits[j].query.end) + { + fprintf(stderr, "/"); + } + } + if (result.hits[j].query.end - result.hits[j].query.start > 1) + { + fprintf(stderr, "]"); + } + fprintf(stderr, "\n"); + } // for } // for result.alleles = ARRAY_DESTROY(gva_std_allocator, result.alleles); From 59c90329c0313ecf8e9b5e4326399dbf47157a45 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Thu, 12 Mar 2026 01:46:52 +0100 Subject: [PATCH 550/704] Break out result printing into function. --- src/main.c | 174 +++++++++++++++++++++++++++-------------------------- 1 file changed, 90 insertions(+), 84 deletions(-) diff --git a/src/main.c b/src/main.c index 1484105..f7c5b12 100644 --- a/src/main.c +++ b/src/main.c @@ -65,6 +65,95 @@ compare_query_alleles(void const* a, void const* b) } // compare_query_alleles +static void +hla_results_output(GVA_Index *index, GVA_LCS_Graph graph, GVA_String id, GVA_Query_Result const result) +{ + for (size_t i = 0; i < array_length(result.alleles); ++i) + { + fprintf(stdout, GVA_STRING_FMT " %s " GVA_STRING_FMT " %u %u %zu\n", + GVA_STRING_PRINT(gva_index_id(index, result.alleles[i].idx)), + GVA_RELATION_LABELS[result.alleles[i].relation], + GVA_STRING_PRINT(id), + result.alleles[i].included, result.alleles[i].excluded, array_length(graph.dom_nodes) - 1); + fprintf(stderr, " " GVA_STRING_FMT ": %u %u %s\n", + GVA_STRING_PRINT(gva_index_id(index, result.alleles[i].idx)), + result.alleles[i].included, result.alleles[i].excluded, + GVA_RELATION_LABELS[result.alleles[i].relation]); + + size_t last_q = -1; + size_t last_i = gva_index_allele_start(index, result.alleles[i].idx); + // TODO: also address trailing disjoints? + for (size_t j = result.alleles[i].hits.start; j < result.alleles[i].hits.end; ++j) + { + for (size_t k = last_q + 1; k < result.hits[j].query.start; ++k) + { + fprintf(stderr, " [) [%zu, %zu): 0 %u disjoint ", k, k + 1, + graph.dom_nodes[k + 1].distance - graph.dom_nodes[k].distance); + fprintf(stderr, "* " GVA_VARIANT_FMT_SPDI_ALLELE "\n", + GVA_VARIANT_PRINT_SPDI_ALLELE(gva_lcs_graph_local_supremal(graph, k, k + 1))); + } // for + last_q = result.hits[j].query.start; + + for (size_t k = last_i + 1; k < result.hits[j].index.start; ++k) + { + fprintf(stderr, " [%zu, %zu) [): 0 %u disjoint ", k, k + 1, gva_index_node_distance(index, result.alleles[i].idx, k)); + fprintf(stderr, GVA_VARIANT_FMT_SPDI_ALLELE " *\n", + GVA_VARIANT_PRINT_SPDI_ALLELE(gva_index_variant(index, result.alleles[i].idx, k))); + } // for + last_i = result.hits[j].index.start; + + fprintf(stderr, " [%u, %u) [%u, %u): %u %u %s ", + result.hits[j].index.start, result.hits[j].index.end, + result.hits[j].query.start, result.hits[j].query.end, + result.hits[j].included, result.hits[j].excluded, + GVA_RELATION_LABELS[result.hits[j].relation]); + + // print index allele + fprintf(stderr, REFERENCE_ID ":"); + if (result.hits[j].index.end - result.hits[j].index.start > 1) + { + fprintf(stderr, "["); + } // if + for (size_t k = result.hits[j].index.start; k < result.hits[j].index.end; ++k) + { + fprintf(stderr, GVA_VARIANT_FMT_SPDI_ALLELE, + GVA_VARIANT_PRINT_SPDI_ALLELE(gva_index_variant(index, result.alleles[i].idx, k))); + if (k + 1 < result.hits[j].index.end) + { + fprintf(stderr, ", "); + } // if + } // for + if (result.hits[j].index.end - result.hits[j].index.start > 1) + { + fprintf(stderr, "]"); + } // if + fprintf(stderr, " "); + + // print query allele + fprintf(stderr, REFERENCE_ID ":"); + if (result.hits[j].query.end - result.hits[j].query.start > 1) + { + fprintf(stderr, "["); + } // if + for (size_t k = result.hits[j].query.start; k < result.hits[j].query.end; ++k) + { + fprintf(stderr, GVA_VARIANT_FMT_SPDI_ALLELE, + GVA_VARIANT_PRINT_SPDI_ALLELE(gva_lcs_graph_local_supremal(graph, k, k + 1))); + if (k + 1 < result.hits[j].query.end) + { + fprintf(stderr, ", "); + } // if + } // for + if (result.hits[j].query.end - result.hits[j].query.start > 1) + { + fprintf(stderr, "]"); + } // if + fprintf(stderr, "\n"); + } // for + } // for +} // hla_results_output + + int index_main(int argc, char* argv[static argc]) { @@ -145,91 +234,8 @@ index_main(int argc, char* argv[static argc]) qsort(result.alleles, array_length(result.alleles), sizeof(*result.alleles), compare_query_alleles); } // if - for (size_t i = 0; i < array_length(result.alleles); ++i) - { - fprintf(stdout, GVA_STRING_FMT " %s " GVA_STRING_FMT " %u %u %zu\n", - GVA_STRING_PRINT(gva_index_id(index, result.alleles[i].idx)), - GVA_RELATION_LABELS[result.alleles[i].relation], - GVA_STRING_PRINT(id), - result.alleles[i].included, result.alleles[i].excluded, array_length(graph.dom_nodes) - 1); - fprintf(stderr, " " GVA_STRING_FMT ": %u %u %s\n", - GVA_STRING_PRINT(gva_index_id(index, result.alleles[i].idx)), - result.alleles[i].included, result.alleles[i].excluded, - GVA_RELATION_LABELS[result.alleles[i].relation]); - - size_t last_q = -1; - size_t last_i = gva_index_allele_start(index, result.alleles[i].idx); - // TODO: also address trailing disjoints? - for (size_t j = result.alleles[i].hits.start; j < result.alleles[i].hits.end; ++j) - { - for (size_t k = last_q + 1; k < result.hits[j].query.start; ++k) - { - fprintf(stderr, " [) [%zu, %zu): 0 %u disjoint ", k, k + 1, - graph.dom_nodes[k + 1].distance - graph.dom_nodes[k].distance); - fprintf(stderr, "* " GVA_VARIANT_FMT_SPDI_ALLELE "\n", - GVA_VARIANT_PRINT_SPDI_ALLELE(gva_lcs_graph_local_supremal(graph, k, k + 1))); - } - last_q = result.hits[j].query.start; - - for (size_t k = last_i + 1; k < result.hits[j].index.start; ++k) - { - fprintf(stderr, " [%zu, %zu) [): 0 %u disjoint ", k, k + 1, gva_index_node_distance(index, result.alleles[i].idx, k)); - fprintf(stderr, GVA_VARIANT_FMT_SPDI_ALLELE " *\n", - GVA_VARIANT_PRINT_SPDI_ALLELE(gva_index_variant(index, result.alleles[i].idx, k))); - } - last_i = result.hits[j].index.start; - - fprintf(stderr, " [%u, %u) [%u, %u): %u %u %s ", - result.hits[j].index.start, result.hits[j].index.end, - result.hits[j].query.start, result.hits[j].query.end, - result.hits[j].included, result.hits[j].excluded, - GVA_RELATION_LABELS[result.hits[j].relation]); - - // print index allele - fprintf(stderr, REFERENCE_ID ":"); - if (result.hits[j].index.end - result.hits[j].index.start > 1) - { - fprintf(stderr, "["); - } - for (size_t k = result.hits[j].index.start; k < result.hits[j].index.end; ++k) - { - fprintf(stderr, GVA_VARIANT_FMT_SPDI_ALLELE, - GVA_VARIANT_PRINT_SPDI_ALLELE(gva_index_variant(index, result.alleles[i].idx, k))); - if (k + 1 < result.hits[j].index.end) - { - fprintf(stderr, "/"); - } - } - if (result.hits[j].index.end - result.hits[j].index.start > 1) - { - fprintf(stderr, "]"); - } - fprintf(stderr, " "); - - // print query allele - fprintf(stderr, REFERENCE_ID ":"); + hla_results_output(index, graph, id, result); - if (result.hits[j].query.end - result.hits[j].query.start > 1) - { - fprintf(stderr, "["); - } - for (size_t k = result.hits[j].query.start; k < result.hits[j].query.end; ++k) - { - fprintf(stderr, GVA_VARIANT_FMT_SPDI_ALLELE, - GVA_VARIANT_PRINT_SPDI_ALLELE(gva_lcs_graph_local_supremal(graph, k, k + 1))); - if (k + 1 < result.hits[j].query.end) - { - fprintf(stderr, "/"); - } - } - if (result.hits[j].query.end - result.hits[j].query.start > 1) - { - fprintf(stderr, "]"); - } - fprintf(stderr, "\n"); - - } // for - } // for result.alleles = ARRAY_DESTROY(gva_std_allocator, result.alleles); result.hits = ARRAY_DESTROY(gva_std_allocator, result.hits); gva_lcs_graph_destroy(gva_std_allocator, graph, true); From 8fe3c9475c1c5e0787423f3cf080516159b5f108 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Thu, 12 Mar 2026 01:54:06 +0100 Subject: [PATCH 551/704] Make printing of implicit disjoints optional. --- src/main.c | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/src/main.c b/src/main.c index f7c5b12..6e83f6b 100644 --- a/src/main.c +++ b/src/main.c @@ -66,7 +66,7 @@ compare_query_alleles(void const* a, void const* b) static void -hla_results_output(GVA_Index *index, GVA_LCS_Graph graph, GVA_String id, GVA_Query_Result const result) +results_output(GVA_Index *index, GVA_LCS_Graph graph, GVA_String id, GVA_Query_Result const result, bool show_disjoints) { for (size_t i = 0; i < array_length(result.alleles); ++i) { @@ -85,22 +85,25 @@ hla_results_output(GVA_Index *index, GVA_LCS_Graph graph, GVA_String id, GVA_Que // TODO: also address trailing disjoints? for (size_t j = result.alleles[i].hits.start; j < result.alleles[i].hits.end; ++j) { - for (size_t k = last_q + 1; k < result.hits[j].query.start; ++k) + if (show_disjoints) { - fprintf(stderr, " [) [%zu, %zu): 0 %u disjoint ", k, k + 1, - graph.dom_nodes[k + 1].distance - graph.dom_nodes[k].distance); - fprintf(stderr, "* " GVA_VARIANT_FMT_SPDI_ALLELE "\n", - GVA_VARIANT_PRINT_SPDI_ALLELE(gva_lcs_graph_local_supremal(graph, k, k + 1))); - } // for - last_q = result.hits[j].query.start; - - for (size_t k = last_i + 1; k < result.hits[j].index.start; ++k) - { - fprintf(stderr, " [%zu, %zu) [): 0 %u disjoint ", k, k + 1, gva_index_node_distance(index, result.alleles[i].idx, k)); - fprintf(stderr, GVA_VARIANT_FMT_SPDI_ALLELE " *\n", - GVA_VARIANT_PRINT_SPDI_ALLELE(gva_index_variant(index, result.alleles[i].idx, k))); - } // for - last_i = result.hits[j].index.start; + for (size_t k = last_q + 1; k < result.hits[j].query.start; ++k) + { + fprintf(stderr, " [) [%zu, %zu): 0 %u disjoint ", k, k + 1, + graph.dom_nodes[k + 1].distance - graph.dom_nodes[k].distance); + fprintf(stderr, "* " GVA_VARIANT_FMT_SPDI_ALLELE "\n", + GVA_VARIANT_PRINT_SPDI_ALLELE(gva_lcs_graph_local_supremal(graph, k, k + 1))); + } // for + last_q = result.hits[j].query.start; + + for (size_t k = last_i + 1; k < result.hits[j].index.start; ++k) + { + fprintf(stderr, " [%zu, %zu) [): 0 %u disjoint ", k, k + 1, gva_index_node_distance(index, result.alleles[i].idx, k)); + fprintf(stderr, GVA_VARIANT_FMT_SPDI_ALLELE " *\n", + GVA_VARIANT_PRINT_SPDI_ALLELE(gva_index_variant(index, result.alleles[i].idx, k))); + } // for + last_i = result.hits[j].index.start; + } fprintf(stderr, " [%u, %u) [%u, %u): %u %u %s ", result.hits[j].index.start, result.hits[j].index.end, @@ -151,7 +154,7 @@ hla_results_output(GVA_Index *index, GVA_LCS_Graph graph, GVA_String id, GVA_Que fprintf(stderr, "\n"); } // for } // for -} // hla_results_output +} // results_output int @@ -234,7 +237,7 @@ index_main(int argc, char* argv[static argc]) qsort(result.alleles, array_length(result.alleles), sizeof(*result.alleles), compare_query_alleles); } // if - hla_results_output(index, graph, id, result); + results_output(index, graph, id, result, false); result.alleles = ARRAY_DESTROY(gva_std_allocator, result.alleles); result.hits = ARRAY_DESTROY(gva_std_allocator, result.hits); From 6e1cbddf4fd04302470480f4e94dabf0aef80899 Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 16 Mar 2026 19:19:08 +0100 Subject: [PATCH 552/704] Example with disjoint part --- test_alleles_supremal2.txt | 2 ++ truth/YR | 1 + truth/YS | 3 +++ 3 files changed, 6 insertions(+) create mode 100644 truth/YR create mode 100644 truth/YS diff --git a/test_alleles_supremal2.txt b/test_alleles_supremal2.txt index 152f9f4..78df43e 100644 --- a/test_alleles_supremal2.txt +++ b/test_alleles_supremal2.txt @@ -41,3 +41,5 @@ YN NC_000001.11:164871874:5:AC 3 YO NC_000001.11:164871870:9: 9 YP NC_000001.11:2656569:79:CCACCCACACCACCAGGCGATCATCCGCAG 53 YQ NC_000001.11:2656569:79:CAACCCACACCCCCAGGCGAGCATCTGAAG 49 +YR NC_000001.11:74362:4:CATAC 5 +YS NC_000001.11:74362:4:CAGAC 5 diff --git a/truth/YR b/truth/YR new file mode 100644 index 0000000..997230e --- /dev/null +++ b/truth/YR @@ -0,0 +1 @@ +YR NC_000001.11:74362:4:CATAC 5 diff --git a/truth/YS b/truth/YS new file mode 100644 index 0000000..5cc2817 --- /dev/null +++ b/truth/YS @@ -0,0 +1,3 @@ +YS NC_000001.11:74362:1:C 2 +YS NC_000001.11:74364:0:G 1 +YS NC_000001.11:74365:1:C 2 From 63f13ce4252eb95424bf37ed60a9924afdbbb6a5 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Tue, 17 Mar 2026 09:30:14 +0100 Subject: [PATCH 553/704] Reorder. --- src/index.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/index.c b/src/index.c index 818a531..b9b1bca 100644 --- a/src/index.c +++ b/src/index.c @@ -365,7 +365,7 @@ gva_index_query(GVA_Allocator const allocator, GVA_Interval join; // index into self->join gva_uint included; // double purpose: distance or included GVA_Interval query; // wrt local supremal parts in the query - gva_uint next; + gva_uint next; }* hits = NULL; // Phase 1: for every local supremal part: @@ -552,9 +552,6 @@ gva_index_query(GVA_Allocator const allocator, } // if size_t const start = array_length(result.hits); - size_t excluded = 0; - GVA_Relation const relation = relation_from_included(entries[idx].included, self->alleles[entries[idx].gva_key].distance, gva_lcs_graph_distance(graph), &excluded); - for (gva_uint i = entries[idx].head; i != GVA_NULL; i = hits[i].next) { size_t lhs_distance = 0; @@ -577,6 +574,9 @@ gva_index_query(GVA_Allocator const allocator, .query = hits[i].query, })); } // for + + size_t excluded = 0; + GVA_Relation const relation = relation_from_included(entries[idx].included, self->alleles[entries[idx].gva_key].distance, gva_lcs_graph_distance(graph), &excluded); ARRAY_APPEND(allocator, result.alleles, ((struct GVA_Query_Allele) { From 2c3d122231ee595bdd111449231bc1def6173022 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Tue, 17 Mar 2026 09:53:42 +0100 Subject: [PATCH 554/704] Increase guesstimate for overlap. --- src/index.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/index.c b/src/index.c index b9b1bca..6d0a322 100644 --- a/src/index.c +++ b/src/index.c @@ -246,7 +246,7 @@ variants_with_distance(GVA_Allocator const allocator, { return 0; // disjoint } // if - return MAX(1, (double) included / excluded * MIN(distance_lhs, distance_rhs)); + return MAX(1, (double) (2 * included - 1) / excluded * MIN(distance_lhs, distance_rhs)); } // variants_with_distance @@ -523,7 +523,7 @@ gva_index_query(GVA_Allocator const allocator, &excluded); if (hits[i].included > 0) { - hits[i].included = MAX(1, (double) hits[i].included / excluded * MIN(self->intervals.nodes[node_idx].distance, graph.dom_nodes[hits[i].query.end].distance - graph.dom_nodes[hits[i].query.start].distance)); + hits[i].included = MAX(1, (double) (2 * hits[i].included - 1) / excluded * MIN(self->intervals.nodes[node_idx].distance, graph.dom_nodes[hits[i].query.end].distance - graph.dom_nodes[hits[i].query.start].distance)); } // if } // if // single hit for single query part, relation is already determined From 7ed2d067460f106106fc9ce2444f97a9c27e3cc0 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Tue, 17 Mar 2026 16:59:31 +0100 Subject: [PATCH 555/704] Add example from "paper figure 1". --- test_alleles_supremal2.txt | 2 ++ truth/YT | 6 ++++++ truth/YU | 5 +++++ 3 files changed, 13 insertions(+) create mode 100644 truth/YT create mode 100644 truth/YU diff --git a/test_alleles_supremal2.txt b/test_alleles_supremal2.txt index 78df43e..ffe85f8 100644 --- a/test_alleles_supremal2.txt +++ b/test_alleles_supremal2.txt @@ -43,3 +43,5 @@ YP NC_000001.11:2656569:79:CCACCCACACCACCAGGCGATCATCCGCAG 53 YQ NC_000001.11:2656569:79:CAACCCACACCCCCAGGCGAGCATCTGAAG 49 YR NC_000001.11:74362:4:CATAC 5 YS NC_000001.11:74362:4:CAGAC 5 +YT NC_000001.11:74348:18:GCGTAGTAACCCAGCAGAC 9 +YU NC_000001.11:74349:17:CGCGTATAGACCCCAGCATAC 10 diff --git a/truth/YT b/truth/YT new file mode 100644 index 0000000..a7f8f6c --- /dev/null +++ b/truth/YT @@ -0,0 +1,6 @@ +YT NC_000001.11:74348:3:GCG 2 +YT NC_000001.11:74353:0:G 1 +YT NC_000001.11:74355:1: 1 +YT NC_000001.11:74362:1:C 2 +YT NC_000001.11:74364:0:G 1 +YT NC_000001.11:74365:1:C 2 diff --git a/truth/YU b/truth/YU new file mode 100644 index 0000000..82c567c --- /dev/null +++ b/truth/YU @@ -0,0 +1,5 @@ +YU NC_000001.11:74349:0:C 1 +YU NC_000001.11:74350:0:C 1 +YU NC_000001.11:74355:1:G 2 +YU NC_000001.11:74357:3:CCCC 1 +YU NC_000001.11:74362:4:CATAC 5 From ad6f9a11e431ce7900481afda203619e86ae2d85 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 19 Mar 2026 16:00:57 +0100 Subject: [PATCH 556/704] WIP: Query true included/excluded --- src/index.c | 292 +++++++++++++++++++++++++++++++--------------------- src/main.c | 4 +- 2 files changed, 175 insertions(+), 121 deletions(-) diff --git a/src/index.c b/src/index.c index 6d0a322..fd566d0 100644 --- a/src/index.c +++ b/src/index.c @@ -20,6 +20,9 @@ #include "trie.h" // Trie, trie_* +#include // DEBUG + + typedef struct { gva_uint link; // X-OR link between interval_idx and allele_idx @@ -51,7 +54,7 @@ struct GVA_Index static inline GVA_Relation relation_from_included(size_t const included, size_t const lhs_distance, size_t const rhs_distance, - size_t* const excluded) + gva_uint* const excluded) { *excluded = lhs_distance + rhs_distance - 2 * included; if (*excluded == 0) @@ -362,16 +365,18 @@ gva_index_query(GVA_Allocator const allocator, struct Hit { - GVA_Interval join; // index into self->join + GVA_Interval join; + GVA_Interval query; gva_uint included; // double purpose: distance or included - GVA_Interval query; // wrt local supremal parts in the query + gva_uint excluded; + GVA_Relation relation; gva_uint next; }* hits = NULL; // Phase 1: for every local supremal part: // - find candidates based on interval query // - calculate the distance with the candidates, - // and quickly eject disjoint candidates based on distance + // and discard disjoint candidates early based on distance for (size_t i = 0; i < array_length(graph.dom_nodes) - 1; ++i) { GVA_Variant const variant = gva_lcs_graph_local_supremal(graph, i, i + 1); @@ -391,22 +396,19 @@ gva_index_query(GVA_Allocator const allocator, for (gva_uint k = self->intervals.nodes[node_idx].alleles; k != GVA_NULL; k = self->join[k].next) { - gva_uint const allele_idx = self->join[k].link ^ node_idx; + gva_uint const tail = ARRAY_APPEND(allocator, hits, + ((struct Hit) + { + .join = {k, k + 1}, + .query = {i, i + 1}, + .included = distance, + .next = GVA_NULL, + })); + gva_uint const allele_idx = self->join[k].link ^ node_idx; size_t const idx = HASH_TABLE_INDEX(entries, allele_idx); - // The first time a hit is associated with this allele: - // - create a new allele entry - // - add this first hit for that allele if (entries[idx].gva_key != allele_idx) { - gva_uint const tail = ARRAY_APPEND(allocator, hits, - ((struct Hit) - { - .join = {k, k + 1}, - .included = distance, - .query = {i, i + 1}, - .next = GVA_NULL, - })); HASH_TABLE_SET(allocator, entries, allele_idx, ((struct Allele_Entry) { @@ -417,39 +419,16 @@ gva_index_query(GVA_Allocator const allocator, continue; } // if - // Add a new hit to an existing allele entry - // - only when this hit is with a different query part than before - if (hits[entries[idx].tail].join.start != k) - { - gva_uint const tail = ARRAY_APPEND(allocator, hits, - ((struct Hit) - { - .join = {k, k + 1}, - .included = distance, - .query = {i, i + 1}, - .next = GVA_NULL, - })); - // add to end of list - hits[entries[idx].tail].next = tail; - entries[idx].tail = tail; - } // if - // otherwise: update the hit for this query part - else - { - hits[entries[idx].tail].query.end = i + 1; - } // else + hits[entries[idx].tail].next = tail; + entries[idx].tail = tail; } // for } // for intervals = ARRAY_DESTROY(allocator, intervals); } // for - GVA_Query_Result result = {NULL}; + gva_uint* ranges = NULL; - // Phase 2: resolve 1:N and N:1 hits into 1:1 hits - // - calculate relations that could not be determined on distances - // - switch from distances to `included` perspective - // - aggregate `included` per allele - // - discard disjoint alleles + // Phase 2 for (size_t idx = 0; idx < array_header(entries)->capacity; ++idx) { if (entries[idx].gva_key == NOT_FOUND) @@ -457,42 +436,121 @@ gva_index_query(GVA_Allocator const allocator, continue; } // if + fprintf(stderr, GVA_STRING_FMT "\n", GVA_STRING_PRINT(gva_index_id(self, entries[idx].gva_key))); gva_uint prev = GVA_NULL; for (gva_uint i = entries[idx].head; i != GVA_NULL; i = hits[i].next) { - // Look ahead for the same local supremal part in the query - GVA_Variant lhs = {0}; + fprintf(stderr, " %2u %2u %2u\n", hits[i].join.start, hits[i].query.start, hits[i].included); + + // look aheads for multi hits: build new local supremal + size_t start_ranges = array_length(ranges); + GVA_Variant supremal = {0}; size_t distance = 0; - gva_uint start = GVA_NULL; - while (hits[i].next != GVA_NULL && hits[hits[i].next].query.start == hits[i].query.start) + + // check single join hit with multiple query hits + gva_uint start = hits[i].query.start; + gva_uint end = hits[i].query.end; + while (hits[i].next != GVA_NULL && hits[i].join.start == hits[hits[i].next].join.start) + { + if (start_ranges == array_length(ranges)) + { + ARRAY_APPEND(allocator, ranges, hits[i].query.start); + } // if + i = hits[i].next; + ARRAY_APPEND(allocator, ranges, hits[i].query.start); + if (hits[i].query.start > end) + { + GVA_Variant const variant = gva_lcs_graph_local_supremal(graph, start, end); + if (distance == 0) + { + supremal = gva_variant_dup(allocator, variant); + } // if + else + { + supremal.sequence = gva_string_concat(allocator, supremal.sequence, + (GVA_String) {variant.start - supremal.end, self->reference.str + supremal.end}); + supremal.sequence = gva_string_concat(allocator, supremal.sequence, variant.sequence); + supremal.end = variant.end; + } // else + distance += graph.dom_nodes[end].distance - graph.dom_nodes[start].distance; + start = hits[i].query.start; + } // if + end = hits[i].query.end; + fprintf(stderr, " \" %2u %2u (query)\n", hits[i].query.start, hits[i].included); + } // while + if (start_ranges < array_length(ranges)) + { + GVA_Variant const variant = gva_lcs_graph_local_supremal(graph, start, end); + if (distance == 0) + { + supremal = gva_variant_dup(allocator, variant); + } // if + else + { + supremal.sequence = gva_string_concat(allocator, supremal.sequence, + (GVA_String) {variant.start - supremal.end, self->reference.str + supremal.end}); + supremal.sequence = gva_string_concat(allocator, supremal.sequence, variant.sequence); + supremal.end = variant.end; + } // else + distance += (graph.dom_nodes[end].distance - graph.dom_nodes[start].distance); + fprintf(stderr, " SOLVE multiple query: " GVA_VARIANT_FMT_SPDI " (%zu)\n", GVA_VARIANT_PRINT_SPDI("NC_000001.11", supremal), distance); + gva_uint const node_idx = self->join[hits[i].join.start].link ^ entries[idx].gva_key; + hits[i].included = variants_with_distance(allocator, self->reference.len, self->reference.str, + variant_from_index(self, node_idx), self->intervals.nodes[node_idx].distance, + supremal, distance); + gva_string_destroy(allocator, supremal.sequence); + + hits[i].relation = relation_from_included(hits[i].included, self->intervals.nodes[node_idx].distance, distance, &hits[i].excluded); + hits[i].query.start = start_ranges; + hits[i].query.end = array_length(ranges); + + // disable aggregated hits except the last + if (prev != GVA_NULL) + { + hits[prev].next = i; + } // if + else + { + entries[idx].head = i; + } // else + prev = i; + + entries[idx].included += hits[i].included; + continue; + } // if + + // check single query hit with multiple join hits + while (hits[i].next != GVA_NULL && hits[i].query.start == hits[hits[i].next].query.start) { - if (start == GVA_NULL) + if (distance == 0) { - start = hits[i].join.start; + ARRAY_APPEND(allocator, ranges, hits[i].join.start); gva_uint const node_idx = self->join[hits[i].join.start].link ^ entries[idx].gva_key; - lhs = gva_variant_dup(allocator, variant_from_index(self, node_idx)); + supremal = gva_variant_dup(allocator, variant_from_index(self, node_idx)); distance = self->intervals.nodes[node_idx].distance; } // if i = hits[i].next; + ARRAY_APPEND(allocator, ranges, hits[i].join.start); gva_uint const node_idx = self->join[hits[i].join.start].link ^ entries[idx].gva_key; GVA_Variant const variant = variant_from_index(self, node_idx); - lhs.sequence = gva_string_concat(allocator, lhs.sequence, - (GVA_String) {variant.start - lhs.end, self->reference.str + lhs.end}); - lhs.sequence = gva_string_concat(allocator, lhs.sequence, variant.sequence); - lhs.end = variant.end; + supremal.sequence = gva_string_concat(allocator, supremal.sequence, + (GVA_String) {variant.start - supremal.end, self->reference.str + supremal.end}); + supremal.sequence = gva_string_concat(allocator, supremal.sequence, variant.sequence); + supremal.end = variant.end; distance += self->intervals.nodes[node_idx].distance; + fprintf(stderr, " %2u \" %2u (join)\n", hits[i].join.start, hits[i].included); } // while - - gva_uint const node_idx = self->join[hits[i].join.start].link ^ entries[idx].gva_key; - - // single query part has multiple hits - if (start != GVA_NULL) + if (start_ranges < array_length(ranges)) { - // aggregate hits in last hit - hits[i].join.start = start; + fprintf(stderr, " SOLVE multiple join: " GVA_VARIANT_FMT_SPDI " (%zu)\n", GVA_VARIANT_PRINT_SPDI("NC_000001.11", supremal), distance); hits[i].included = variants_with_distance(allocator, self->reference.len, self->reference.str, - lhs, distance, + supremal, distance, gva_lcs_graph_local_supremal(graph, hits[i].query.start, hits[i].query.end), graph.dom_nodes[hits[i].query.end].distance - graph.dom_nodes[hits[i].query.start].distance); + gva_string_destroy(allocator, supremal.sequence); + + hits[i].relation = relation_from_included(hits[i].included, distance, graph.dom_nodes[hits[i].query.end].distance - graph.dom_nodes[hits[i].query.start].distance, &hits[i].excluded); + hits[i].join.start = start_ranges; + hits[i].join.end = array_length(ranges); // disable aggregated hits except the last if (prev != GVA_NULL) @@ -503,19 +561,20 @@ gva_index_query(GVA_Allocator const allocator, { entries[idx].head = i; } // else + prev = i; - gva_string_destroy(allocator, lhs.sequence); - } // if - // single hit with multiple query parts - else if (hits[i].query.end - hits[i].query.start > 1) - { - hits[i].included = variants_with_distance(allocator, self->reference.len, self->reference.str, - variant_from_index(self, node_idx), self->intervals.nodes[node_idx].distance, - gva_lcs_graph_local_supremal(graph, hits[i].query.start, hits[i].query.end), graph.dom_nodes[hits[i].query.end].distance - graph.dom_nodes[hits[i].query.start].distance); + entries[idx].included += hits[i].included; + continue; } // if - // single hit for single query part, relation is not determined by the distances - else if (ABS((intmax_t) self->intervals.nodes[node_idx].distance - (graph.dom_nodes[hits[i].query.end].distance - graph.dom_nodes[hits[i].query.start].distance)) != hits[i].included) + + prev = i; + distance = graph.dom_nodes[hits[i].query.end].distance - graph.dom_nodes[hits[i].query.start].distance; + + gva_uint const node_idx = self->join[hits[i].join.start].link ^ entries[idx].gva_key; + // non-distance based + if (ABS((intmax_t) self->intervals.nodes[node_idx].distance - (intmax_t) distance) != hits[i].included) { + fprintf(stderr, " SOLVE non-distance based\n"); size_t excluded = 0; hits[i].included = variants_included(allocator, self->reference.len, self->reference.str, variant_from_index(self, node_idx), @@ -523,26 +582,27 @@ gva_index_query(GVA_Allocator const allocator, &excluded); if (hits[i].included > 0) { - hits[i].included = MAX(1, (double) (2 * hits[i].included - 1) / excluded * MIN(self->intervals.nodes[node_idx].distance, graph.dom_nodes[hits[i].query.end].distance - graph.dom_nodes[hits[i].query.start].distance)); + hits[i].included = MAX(1, (double) (2 * hits[i].included - 1) / excluded * MIN(self->intervals.nodes[node_idx].distance, distance)); } // if + hits[i].relation = relation_from_included(hits[i].included, self->intervals.nodes[node_idx].distance, distance, &hits[i].excluded); + + entries[idx].included += hits[i].included; + continue; } // if - // single hit for single query part, relation is already determined - else + + // equivalent or contains + if (self->intervals.nodes[node_idx].distance - distance == hits[i].included) { - gva_uint const distance = graph.dom_nodes[hits[i].query.end].distance - graph.dom_nodes[hits[i].query.start].distance; - // equivalent or contains - if (self->intervals.nodes[node_idx].distance - distance == hits[i].included) - { - hits[i].included = distance; - } // if - // is_contained - else if (distance - self->intervals.nodes[node_idx].distance == hits[i].included) - { - hits[i].included = self->intervals.nodes[node_idx].distance; - } // if - } // else + hits[i].included = distance; + } // if + // is_contained + else if (distance - self->intervals.nodes[node_idx].distance == hits[i].included) + { + hits[i].included = self->intervals.nodes[node_idx].distance; + } // if + hits[i].relation = relation_from_included(hits[i].included, self->intervals.nodes[node_idx].distance, distance, &hits[i].excluded); + entries[idx].included += hits[i].included; - prev = i; } // for if (entries[idx].included == 0) @@ -551,47 +611,41 @@ gva_index_query(GVA_Allocator const allocator, continue; } // if - size_t const start = array_length(result.hits); + gva_uint excluded = 0; + GVA_Relation const relation = relation_from_included(entries[idx].included, self->alleles[entries[idx].gva_key].distance, gva_lcs_graph_distance(graph), &excluded); + fprintf(stderr, GVA_STRING_FMT " %2u %2u %s\n", GVA_STRING_PRINT(gva_index_id(self, entries[idx].gva_key)), entries[idx].included, excluded, GVA_RELATION_LABELS[relation]); for (gva_uint i = entries[idx].head; i != GVA_NULL; i = hits[i].next) { - size_t lhs_distance = 0; - for (gva_uint j = hits[i].join.start; j < hits[i].join.end; ++j) + if (hits[i].join.end - hits[i].join.start > 1) { - gva_uint const node_idx = self->join[j].link ^ entries[idx].gva_key; - lhs_distance += self->intervals.nodes[node_idx].distance; - } // for - size_t const rhs_distance = graph.dom_nodes[hits[i].query.end].distance - graph.dom_nodes[hits[i].query.start].distance; - size_t excluded = 0; - GVA_Relation const relation = relation_from_included(hits[i].included, lhs_distance, rhs_distance, &excluded); - - ARRAY_APPEND(allocator, result.hits, - ((struct GVA_Query_Hit) + fprintf(stderr, " ["); + for (gva_uint j = hits[i].join.start; j < hits[i].join.end; ++j) { - .relation = relation, - .included = hits[i].included, - .excluded = excluded, - .index = hits[i].join, - .query = hits[i].query, - })); - } // for - - size_t excluded = 0; - GVA_Relation const relation = relation_from_included(entries[idx].included, self->alleles[entries[idx].gva_key].distance, gva_lcs_graph_distance(graph), &excluded); - ARRAY_APPEND(allocator, result.alleles, - ((struct GVA_Query_Allele) + fprintf(stderr, "%2u, ", ranges[j]); + } // for + fprintf(stderr, "] %2u %2u %2u %s\n", hits[i].query.start, hits[i].included, hits[i].excluded, GVA_RELATION_LABELS[hits[i].relation]); + } // if + else if (hits[i].query.end - hits[i].query.start > 1) { - .idx = entries[idx].gva_key, - .relation = relation, - .included = entries[idx].included, - .excluded = excluded, - .hits = {start, array_length(result.hits)}, - })); + fprintf(stderr, " %2u [", hits[i].join.start); + for (gva_uint j = hits[i].query.start; j < hits[i].query.end; ++j) + { + fprintf(stderr, "%2u, ", ranges[j]); + } // for + fprintf(stderr, "] %2u %2u %s\n", hits[i].included, hits[i].excluded, GVA_RELATION_LABELS[hits[i].relation]); + } // if + else if (hits[i].included > 0) + { + fprintf(stderr, " %2u %2u %2u %2u %s\n", hits[i].join.start, hits[i].query.start, hits[i].included, hits[i].excluded, GVA_RELATION_LABELS[hits[i].relation]); + } // if + } // for } // for + ranges = ARRAY_DESTROY(allocator, ranges); hits = ARRAY_DESTROY(allocator, hits); entries = HASH_TABLE_DESTROY(allocator, entries); - return result; + return (GVA_Query_Result) {NULL}; } // gva_index_query diff --git a/src/main.c b/src/main.c index 6e83f6b..020ad4b 100644 --- a/src/main.c +++ b/src/main.c @@ -489,7 +489,7 @@ int main(int argc, char* argv[static argc]) { // return allele_main(argc, argv); - return extract_main(argc, argv); - // return index_main(argc, argv); + // return extract_main(argc, argv); + return index_main(argc, argv); // return supremal_main(argc, argv); } // main From 0d83d9e0cd5f5867fa36edf1887cecb315d8456d Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 20 Mar 2026 14:22:43 +0100 Subject: [PATCH 557/704] WIP: included/excluded with disjoint --- src/index.c | 103 +++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 89 insertions(+), 14 deletions(-) diff --git a/src/index.c b/src/index.c index fd566d0..0aa45af 100644 --- a/src/index.c +++ b/src/index.c @@ -32,10 +32,9 @@ typedef struct typedef struct { - gva_uint id_idx; - gva_uint distance; - gva_uint start; // wrt to join - gva_uint end; + gva_uint id_idx; + gva_uint distance; + GVA_Interval join; } Allele; @@ -312,7 +311,7 @@ gva_index_insert(GVA_Index* restrict const self, ((Allele) { .id_idx = id_idx, - .start = array_length(self->join), + .join.start = array_length(self->join), })); } // if @@ -345,7 +344,7 @@ gva_index_insert(GVA_Index* restrict const self, // update allele self->alleles[allele_idx].distance += distance; - self->alleles[allele_idx].end = self->intervals.nodes[node_idx].alleles; + self->alleles[allele_idx].join.end = self->intervals.nodes[node_idx].alleles + 1; } // gva_index_insert @@ -436,11 +435,11 @@ gva_index_query(GVA_Allocator const allocator, continue; } // if - fprintf(stderr, GVA_STRING_FMT "\n", GVA_STRING_PRINT(gva_index_id(self, entries[idx].gva_key))); + //fprintf(stderr, GVA_STRING_FMT "\n", GVA_STRING_PRINT(gva_index_id(self, entries[idx].gva_key))); gva_uint prev = GVA_NULL; for (gva_uint i = entries[idx].head; i != GVA_NULL; i = hits[i].next) { - fprintf(stderr, " %2u %2u %2u\n", hits[i].join.start, hits[i].query.start, hits[i].included); + //fprintf(stderr, " %2u %2u %2u\n", hits[i].join.start, hits[i].query.start, hits[i].included); // look aheads for multi hits: build new local supremal size_t start_ranges = array_length(ranges); @@ -476,7 +475,7 @@ gva_index_query(GVA_Allocator const allocator, start = hits[i].query.start; } // if end = hits[i].query.end; - fprintf(stderr, " \" %2u %2u (query)\n", hits[i].query.start, hits[i].included); + //fprintf(stderr, " \" %2u %2u (query)\n", hits[i].query.start, hits[i].included); } // while if (start_ranges < array_length(ranges)) { @@ -493,7 +492,7 @@ gva_index_query(GVA_Allocator const allocator, supremal.end = variant.end; } // else distance += (graph.dom_nodes[end].distance - graph.dom_nodes[start].distance); - fprintf(stderr, " SOLVE multiple query: " GVA_VARIANT_FMT_SPDI " (%zu)\n", GVA_VARIANT_PRINT_SPDI("NC_000001.11", supremal), distance); + //fprintf(stderr, " SOLVE multiple query: " GVA_VARIANT_FMT_SPDI " (%zu)\n", GVA_VARIANT_PRINT_SPDI("NC_000001.11", supremal), distance); gva_uint const node_idx = self->join[hits[i].join.start].link ^ entries[idx].gva_key; hits[i].included = variants_with_distance(allocator, self->reference.len, self->reference.str, variant_from_index(self, node_idx), self->intervals.nodes[node_idx].distance, @@ -538,11 +537,11 @@ gva_index_query(GVA_Allocator const allocator, supremal.sequence = gva_string_concat(allocator, supremal.sequence, variant.sequence); supremal.end = variant.end; distance += self->intervals.nodes[node_idx].distance; - fprintf(stderr, " %2u \" %2u (join)\n", hits[i].join.start, hits[i].included); + //fprintf(stderr, " %2u \" %2u (join)\n", hits[i].join.start, hits[i].included); } // while if (start_ranges < array_length(ranges)) { - fprintf(stderr, " SOLVE multiple join: " GVA_VARIANT_FMT_SPDI " (%zu)\n", GVA_VARIANT_PRINT_SPDI("NC_000001.11", supremal), distance); + //fprintf(stderr, " SOLVE multiple join: " GVA_VARIANT_FMT_SPDI " (%zu)\n", GVA_VARIANT_PRINT_SPDI("NC_000001.11", supremal), distance); hits[i].included = variants_with_distance(allocator, self->reference.len, self->reference.str, supremal, distance, gva_lcs_graph_local_supremal(graph, hits[i].query.start, hits[i].query.end), graph.dom_nodes[hits[i].query.end].distance - graph.dom_nodes[hits[i].query.start].distance); @@ -574,7 +573,7 @@ gva_index_query(GVA_Allocator const allocator, // non-distance based if (ABS((intmax_t) self->intervals.nodes[node_idx].distance - (intmax_t) distance) != hits[i].included) { - fprintf(stderr, " SOLVE non-distance based\n"); + //fprintf(stderr, " SOLVE non-distance based\n"); size_t excluded = 0; hits[i].included = variants_included(allocator, self->reference.len, self->reference.str, variant_from_index(self, node_idx), @@ -611,6 +610,14 @@ gva_index_query(GVA_Allocator const allocator, continue; } // if + // disjoint alleles + gva_uint* join = NULL; + gva_uint prev_join = self->alleles[entries[idx].gva_key].join.start; + size_t distance_join = 0; + gva_uint* query = NULL; + gva_uint prev_query = 0; + size_t distance_query = 0; + gva_uint excluded = 0; GVA_Relation const relation = relation_from_included(entries[idx].included, self->alleles[entries[idx].gva_key].distance, gva_lcs_graph_distance(graph), &excluded); fprintf(stderr, GVA_STRING_FMT " %2u %2u %s\n", GVA_STRING_PRINT(gva_index_id(self, entries[idx].gva_key)), entries[idx].included, excluded, GVA_RELATION_LABELS[relation]); @@ -621,24 +628,92 @@ gva_index_query(GVA_Allocator const allocator, fprintf(stderr, " ["); for (gva_uint j = hits[i].join.start; j < hits[i].join.end; ++j) { + for (gva_uint k = prev_join; k < ranges[j]; ++k) + { + ARRAY_APPEND(allocator, join, k); + distance_join += self->intervals.nodes[self->join[k].link ^ entries[idx].gva_key].distance; + } // for + prev_join = ranges[j] + 1; fprintf(stderr, "%2u, ", ranges[j]); } // for fprintf(stderr, "] %2u %2u %2u %s\n", hits[i].query.start, hits[i].included, hits[i].excluded, GVA_RELATION_LABELS[hits[i].relation]); + for (gva_uint k = prev_query; k < hits[i].query.start; ++k) + { + ARRAY_APPEND(allocator, query, k); + } // for + distance_query += graph.dom_nodes[hits[i].query.start].distance - graph.dom_nodes[prev_query].distance; + prev_query = hits[i].query.start + 1; } // if else if (hits[i].query.end - hits[i].query.start > 1) { fprintf(stderr, " %2u [", hits[i].join.start); for (gva_uint j = hits[i].query.start; j < hits[i].query.end; ++j) { + for (gva_uint k = prev_query; k < ranges[j]; ++k) + { + ARRAY_APPEND(allocator, query, k); + } // for + distance_query += graph.dom_nodes[ranges[j]].distance - graph.dom_nodes[prev_query].distance; + prev_query = ranges[j] + 1; fprintf(stderr, "%2u, ", ranges[j]); } // for fprintf(stderr, "] %2u %2u %s\n", hits[i].included, hits[i].excluded, GVA_RELATION_LABELS[hits[i].relation]); + for (gva_uint k = prev_join; k < hits[i].join.start; ++k) + { + ARRAY_APPEND(allocator, join, k); + distance_join += self->intervals.nodes[self->join[k].link ^ entries[idx].gva_key].distance; + } // for + prev_join = hits[i].join.start + 1; } // if else if (hits[i].included > 0) { fprintf(stderr, " %2u %2u %2u %2u %s\n", hits[i].join.start, hits[i].query.start, hits[i].included, hits[i].excluded, GVA_RELATION_LABELS[hits[i].relation]); + for (gva_uint k = prev_join; k < hits[i].join.start; ++k) + { + ARRAY_APPEND(allocator, join, k); + distance_join += self->intervals.nodes[self->join[k].link ^ entries[idx].gva_key].distance; + } // for + prev_join = hits[i].join.start + 1; + for (gva_uint k = prev_query; k < hits[i].query.start; ++k) + { + ARRAY_APPEND(allocator, query, k); + } // for + distance_query += graph.dom_nodes[hits[i].query.start].distance - graph.dom_nodes[prev_query].distance; + prev_query = hits[i].query.start + 1; } // if } // for + for (gva_uint k = prev_join; k < self->alleles[entries[idx].gva_key].join.end; ++k) + { + ARRAY_APPEND(allocator, join, k); + distance_join += self->intervals.nodes[self->join[k].link ^ entries[idx].gva_key].distance; + } // for + for (gva_uint k = prev_query; k < array_length(graph.dom_nodes) - 1; ++k) + { + ARRAY_APPEND(allocator, query, k); + } // for + distance_query += graph.dom_nodes[array_length(graph.dom_nodes) - 1].distance - graph.dom_nodes[prev_query].distance; + + if (distance_join > 0) + { + fprintf(stderr, " ["); + for (size_t i = 0; i < array_length(join); ++i) + { + fprintf(stderr, "%2u, ", join[i]); + } // for + fprintf(stderr, "] * 0 %2zu disjoint\n", distance_join); + } // if + if (distance_query > 0) + { + fprintf(stderr, " * ["); + for (size_t i = 0; i < array_length(query); ++i) + { + fprintf(stderr, "%2u, ", query[i]); + } // for + fprintf(stderr, "] 0 %2zu disjoint\n", distance_query); + } // if + + join = ARRAY_DESTROY(allocator, join); + query = ARRAY_DESTROY(allocator, query); } // for ranges = ARRAY_DESTROY(allocator, ranges); @@ -667,7 +742,7 @@ gva_index_variant(GVA_Index const* const self, gva_uint gva_index_allele_start(GVA_Index const* const self, size_t const allele_idx) { - return self->alleles[allele_idx].start; + return self->alleles[allele_idx].join.start; } // gva_index_allele_start From a3170b3fde44ff12d7cb846a8035821ab357d5cd Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Mon, 23 Mar 2026 13:22:34 +0100 Subject: [PATCH 558/704] Specify that excluded should be non-null. --- src/index.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.c b/src/index.c index 0aa45af..8dfe4f5 100644 --- a/src/index.c +++ b/src/index.c @@ -53,7 +53,7 @@ struct GVA_Index static inline GVA_Relation relation_from_included(size_t const included, size_t const lhs_distance, size_t const rhs_distance, - gva_uint* const excluded) + gva_uint excluded[static 1]) { *excluded = lhs_distance + rhs_distance - 2 * included; if (*excluded == 0) From 8f05df682a0802f3f1f375b4b66233d7649b8559 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Mon, 23 Mar 2026 13:23:13 +0100 Subject: [PATCH 559/704] Use order from lhs -> rhs, + same order as header. --- src/index.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/index.c b/src/index.c index 8dfe4f5..a80ee3d 100644 --- a/src/index.c +++ b/src/index.c @@ -60,14 +60,14 @@ relation_from_included(size_t const included, { return GVA_EQUIVALENT; } // if - if (rhs_distance == included) - { - return GVA_CONTAINS; - } // if if (lhs_distance == included) { return GVA_IS_CONTAINED; } // if + if (rhs_distance == included) + { + return GVA_CONTAINS; + } // if return GVA_OVERLAP; } // relation_from_included From 519170238f2adbcda32966ae8ae603852c7ce021 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Mon, 23 Mar 2026 13:28:13 +0100 Subject: [PATCH 560/704] More static 1. --- src/index.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.c b/src/index.c index a80ee3d..ec9f7a4 100644 --- a/src/index.c +++ b/src/index.c @@ -140,7 +140,7 @@ static size_t variants_included(GVA_Allocator const allocator, size_t const len_ref, char const reference[static len_ref], GVA_Variant const lhs, GVA_Variant const rhs, - size_t* const excluded) + size_t excluded[static 1]) { size_t const start = MIN(lhs.start, rhs.start); size_t const end = MAX(lhs.end, rhs.end); From 07439d9a1101e7771fab1c8eb108c5dc098805f7 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 24 Mar 2026 10:59:23 +0100 Subject: [PATCH 561/704] WIP: External query results --- include/index.h | 12 +- src/index.c | 308 ++++++++++++++++-------------------------------- src/main.c | 160 +++++++++++++++---------- 3 files changed, 205 insertions(+), 275 deletions(-) diff --git a/include/index.h b/include/index.h index 8531e8b..a36a681 100644 --- a/include/index.h +++ b/include/index.h @@ -29,9 +29,10 @@ typedef struct GVA_Relation relation; gva_uint included; gva_uint excluded; - GVA_Interval index; - GVA_Interval query; + GVA_Interval index_parts; + GVA_Interval query_parts; }* hits; + gva_uint* parts; } GVA_Query_Result; @@ -66,11 +67,12 @@ gva_index_variant(GVA_Index const* const self, gva_uint -gva_index_allele_start(GVA_Index const* const self, size_t const allele_idx); +gva_index_variant_distance(GVA_Index const* const self, + size_t const allele_idx, size_t const variant_idx); -gva_uint -gva_index_node_distance(GVA_Index const* const self, size_t const allele_idx, size_t const variant_idx); +GVA_Interval +gva_index_allele_parts(GVA_Index const* const self, size_t const allele_idx); #endif // GVA_INDEX_H diff --git a/src/index.c b/src/index.c index ec9f7a4..a4cf33d 100644 --- a/src/index.c +++ b/src/index.c @@ -20,9 +20,6 @@ #include "trie.h" // Trie, trie_* -#include // DEBUG - - typedef struct { gva_uint link; // X-OR link between interval_idx and allele_idx @@ -53,7 +50,7 @@ struct GVA_Index static inline GVA_Relation relation_from_included(size_t const included, size_t const lhs_distance, size_t const rhs_distance, - gva_uint excluded[static 1]) + size_t excluded[static 1]) { *excluded = lhs_distance + rhs_distance - 2 * included; if (*excluded == 0) @@ -364,12 +361,10 @@ gva_index_query(GVA_Allocator const allocator, struct Hit { - GVA_Interval join; - GVA_Interval query; - gva_uint included; // double purpose: distance or included - gva_uint excluded; - GVA_Relation relation; - gva_uint next; + gva_uint join; + gva_uint query; + gva_uint distance; + gva_uint next; }* hits = NULL; // Phase 1: for every local supremal part: @@ -398,9 +393,9 @@ gva_index_query(GVA_Allocator const allocator, gva_uint const tail = ARRAY_APPEND(allocator, hits, ((struct Hit) { - .join = {k, k + 1}, - .query = {i, i + 1}, - .included = distance, + .join = k, + .query = i, + .distance = distance, .next = GVA_NULL, })); @@ -425,7 +420,7 @@ gva_index_query(GVA_Allocator const allocator, intervals = ARRAY_DESTROY(allocator, intervals); } // for - gva_uint* ranges = NULL; + GVA_Query_Result result = {NULL}; // Phase 2 for (size_t idx = 0; idx < array_header(entries)->capacity; ++idx) @@ -435,29 +430,26 @@ gva_index_query(GVA_Allocator const allocator, continue; } // if - //fprintf(stderr, GVA_STRING_FMT "\n", GVA_STRING_PRINT(gva_index_id(self, entries[idx].gva_key))); - gva_uint prev = GVA_NULL; + size_t const start_hits = array_length(result.hits); for (gva_uint i = entries[idx].head; i != GVA_NULL; i = hits[i].next) { - //fprintf(stderr, " %2u %2u %2u\n", hits[i].join.start, hits[i].query.start, hits[i].included); - // look aheads for multi hits: build new local supremal - size_t start_ranges = array_length(ranges); + size_t const start_parts = array_length(result.parts); GVA_Variant supremal = {0}; size_t distance = 0; // check single join hit with multiple query hits - gva_uint start = hits[i].query.start; - gva_uint end = hits[i].query.end; - while (hits[i].next != GVA_NULL && hits[i].join.start == hits[hits[i].next].join.start) + gva_uint start = hits[i].query; + gva_uint end = hits[i].query + 1; + while (hits[i].next != GVA_NULL && hits[i].join == hits[hits[i].next].join) { - if (start_ranges == array_length(ranges)) + if (start_parts == array_length(result.parts)) { - ARRAY_APPEND(allocator, ranges, hits[i].query.start); + ARRAY_APPEND(allocator, result.parts, hits[i].query); } // if i = hits[i].next; - ARRAY_APPEND(allocator, ranges, hits[i].query.start); - if (hits[i].query.start > end) + ARRAY_APPEND(allocator, result.parts, hits[i].query); + if (hits[i].query > end) { GVA_Variant const variant = gva_lcs_graph_local_supremal(graph, start, end); if (distance == 0) @@ -472,12 +464,11 @@ gva_index_query(GVA_Allocator const allocator, supremal.end = variant.end; } // else distance += graph.dom_nodes[end].distance - graph.dom_nodes[start].distance; - start = hits[i].query.start; + start = hits[i].query; } // if - end = hits[i].query.end; - //fprintf(stderr, " \" %2u %2u (query)\n", hits[i].query.start, hits[i].included); + end = hits[i].query + 1; } // while - if (start_ranges < array_length(ranges)) + if (start_parts < array_length(result.parts)) { GVA_Variant const variant = gva_lcs_graph_local_supremal(graph, start, end); if (distance == 0) @@ -491,236 +482,142 @@ gva_index_query(GVA_Allocator const allocator, supremal.sequence = gva_string_concat(allocator, supremal.sequence, variant.sequence); supremal.end = variant.end; } // else - distance += (graph.dom_nodes[end].distance - graph.dom_nodes[start].distance); - //fprintf(stderr, " SOLVE multiple query: " GVA_VARIANT_FMT_SPDI " (%zu)\n", GVA_VARIANT_PRINT_SPDI("NC_000001.11", supremal), distance); - gva_uint const node_idx = self->join[hits[i].join.start].link ^ entries[idx].gva_key; - hits[i].included = variants_with_distance(allocator, self->reference.len, self->reference.str, + distance += graph.dom_nodes[end].distance - graph.dom_nodes[start].distance; + gva_uint const node_idx = self->join[hits[i].join].link ^ entries[idx].gva_key; + size_t const included = variants_with_distance(allocator, self->reference.len, self->reference.str, variant_from_index(self, node_idx), self->intervals.nodes[node_idx].distance, supremal, distance); gva_string_destroy(allocator, supremal.sequence); - hits[i].relation = relation_from_included(hits[i].included, self->intervals.nodes[node_idx].distance, distance, &hits[i].excluded); - hits[i].query.start = start_ranges; - hits[i].query.end = array_length(ranges); - - // disable aggregated hits except the last - if (prev != GVA_NULL) - { - hits[prev].next = i; - } // if - else - { - entries[idx].head = i; - } // else - prev = i; + size_t excluded = 0; + GVA_Relation const relation = relation_from_included(included, self->intervals.nodes[node_idx].distance, distance, &excluded); + ARRAY_APPEND(allocator, result.hits, ((struct GVA_Query_Hit) + { + .relation = relation, + .included = included, + .excluded = excluded, + .query_parts = {start_parts, array_length(result.parts)}, + .index_parts = {hits[i].join, hits[i].join}, + })); - entries[idx].included += hits[i].included; + entries[idx].included += included; continue; } // if // check single query hit with multiple join hits - while (hits[i].next != GVA_NULL && hits[i].query.start == hits[hits[i].next].query.start) + while (hits[i].next != GVA_NULL && hits[i].query == hits[hits[i].next].query) { if (distance == 0) { - ARRAY_APPEND(allocator, ranges, hits[i].join.start); - gva_uint const node_idx = self->join[hits[i].join.start].link ^ entries[idx].gva_key; + ARRAY_APPEND(allocator, result.parts, hits[i].join); + gva_uint const node_idx = self->join[hits[i].join].link ^ entries[idx].gva_key; supremal = gva_variant_dup(allocator, variant_from_index(self, node_idx)); distance = self->intervals.nodes[node_idx].distance; } // if i = hits[i].next; - ARRAY_APPEND(allocator, ranges, hits[i].join.start); - gva_uint const node_idx = self->join[hits[i].join.start].link ^ entries[idx].gva_key; + ARRAY_APPEND(allocator, result.parts, hits[i].join); + gva_uint const node_idx = self->join[hits[i].join].link ^ entries[idx].gva_key; GVA_Variant const variant = variant_from_index(self, node_idx); supremal.sequence = gva_string_concat(allocator, supremal.sequence, (GVA_String) {variant.start - supremal.end, self->reference.str + supremal.end}); supremal.sequence = gva_string_concat(allocator, supremal.sequence, variant.sequence); supremal.end = variant.end; distance += self->intervals.nodes[node_idx].distance; - //fprintf(stderr, " %2u \" %2u (join)\n", hits[i].join.start, hits[i].included); } // while - if (start_ranges < array_length(ranges)) + if (start_parts < array_length(result.parts)) { - //fprintf(stderr, " SOLVE multiple join: " GVA_VARIANT_FMT_SPDI " (%zu)\n", GVA_VARIANT_PRINT_SPDI("NC_000001.11", supremal), distance); - hits[i].included = variants_with_distance(allocator, self->reference.len, self->reference.str, + size_t const included = variants_with_distance(allocator, self->reference.len, self->reference.str, supremal, distance, - gva_lcs_graph_local_supremal(graph, hits[i].query.start, hits[i].query.end), graph.dom_nodes[hits[i].query.end].distance - graph.dom_nodes[hits[i].query.start].distance); + gva_lcs_graph_local_supremal(graph, hits[i].query, hits[i].query + 1), graph.dom_nodes[hits[i].query + 1].distance - graph.dom_nodes[hits[i].query].distance); gva_string_destroy(allocator, supremal.sequence); - hits[i].relation = relation_from_included(hits[i].included, distance, graph.dom_nodes[hits[i].query.end].distance - graph.dom_nodes[hits[i].query.start].distance, &hits[i].excluded); - hits[i].join.start = start_ranges; - hits[i].join.end = array_length(ranges); + size_t excluded = 0; + GVA_Relation const relation = relation_from_included(included, distance, graph.dom_nodes[hits[i].query + 1].distance - graph.dom_nodes[hits[i].query].distance, &excluded); - // disable aggregated hits except the last - if (prev != GVA_NULL) - { - hits[prev].next = i; - } // if - else - { - entries[idx].head = i; - } // else - prev = i; + ARRAY_APPEND(allocator, result.hits, ((struct GVA_Query_Hit) + { + .relation = relation, + .included = included, + .excluded = excluded, + .query_parts = {hits[i].query, hits[i].query}, + .index_parts = {start_parts, array_length(result.parts)}, + })); - entries[idx].included += hits[i].included; + entries[idx].included += included; continue; } // if - prev = i; - distance = graph.dom_nodes[hits[i].query.end].distance - graph.dom_nodes[hits[i].query.start].distance; + distance = graph.dom_nodes[hits[i].query + 1].distance - graph.dom_nodes[hits[i].query].distance; - gva_uint const node_idx = self->join[hits[i].join.start].link ^ entries[idx].gva_key; + gva_uint const node_idx = self->join[hits[i].join].link ^ entries[idx].gva_key; // non-distance based - if (ABS((intmax_t) self->intervals.nodes[node_idx].distance - (intmax_t) distance) != hits[i].included) + if (ABS((intmax_t) self->intervals.nodes[node_idx].distance - (intmax_t) distance) != hits[i].distance) { - //fprintf(stderr, " SOLVE non-distance based\n"); size_t excluded = 0; - hits[i].included = variants_included(allocator, self->reference.len, self->reference.str, + size_t const included = variants_included(allocator, self->reference.len, self->reference.str, variant_from_index(self, node_idx), - gva_lcs_graph_local_supremal(graph, hits[i].query.start, hits[i].query.end), + gva_lcs_graph_local_supremal(graph, hits[i].query, hits[i].query + 1), &excluded); - if (hits[i].included > 0) + if (included > 0) { - hits[i].included = MAX(1, (double) (2 * hits[i].included - 1) / excluded * MIN(self->intervals.nodes[node_idx].distance, distance)); + ARRAY_APPEND(allocator, result.hits, ((struct GVA_Query_Hit) + { + .relation = GVA_OVERLAP, + .included = MAX(1, (double) (2 * included - 1) / excluded * MIN(self->intervals.nodes[node_idx].distance, distance)), + .excluded = excluded, + .query_parts = {hits[i].query, hits[i].query}, + .index_parts = {hits[i].join, hits[i].join}, + })); } // if - hits[i].relation = relation_from_included(hits[i].included, self->intervals.nodes[node_idx].distance, distance, &hits[i].excluded); - entries[idx].included += hits[i].included; + entries[idx].included += included; continue; } // if - // equivalent or contains - if (self->intervals.nodes[node_idx].distance - distance == hits[i].included) + size_t included = distance; // equivalent or contains + if (distance - self->intervals.nodes[node_idx].distance == hits[i].distance) { - hits[i].included = distance; + // is_contained + included = self->intervals.nodes[node_idx].distance; } // if - // is_contained - else if (distance - self->intervals.nodes[node_idx].distance == hits[i].included) - { - hits[i].included = self->intervals.nodes[node_idx].distance; - } // if - hits[i].relation = relation_from_included(hits[i].included, self->intervals.nodes[node_idx].distance, distance, &hits[i].excluded); - entries[idx].included += hits[i].included; + size_t excluded = 0; + GVA_Relation const relation = relation_from_included(included, self->intervals.nodes[node_idx].distance, distance, &excluded); + + ARRAY_APPEND(allocator, result.hits, ((struct GVA_Query_Hit) + { + .relation = relation, + .included = included, + .excluded = excluded, + .query_parts = {hits[i].query, hits[i].query}, + .index_parts = {hits[i].join, hits[i].join}, + })); + + entries[idx].included += included; } // for if (entries[idx].included == 0) { - entries[idx].gva_key = NOT_FOUND; continue; } // if - // disjoint alleles - gva_uint* join = NULL; - gva_uint prev_join = self->alleles[entries[idx].gva_key].join.start; - size_t distance_join = 0; - gva_uint* query = NULL; - gva_uint prev_query = 0; - size_t distance_query = 0; - - gva_uint excluded = 0; + size_t excluded = 0; GVA_Relation const relation = relation_from_included(entries[idx].included, self->alleles[entries[idx].gva_key].distance, gva_lcs_graph_distance(graph), &excluded); - fprintf(stderr, GVA_STRING_FMT " %2u %2u %s\n", GVA_STRING_PRINT(gva_index_id(self, entries[idx].gva_key)), entries[idx].included, excluded, GVA_RELATION_LABELS[relation]); - for (gva_uint i = entries[idx].head; i != GVA_NULL; i = hits[i].next) - { - if (hits[i].join.end - hits[i].join.start > 1) - { - fprintf(stderr, " ["); - for (gva_uint j = hits[i].join.start; j < hits[i].join.end; ++j) - { - for (gva_uint k = prev_join; k < ranges[j]; ++k) - { - ARRAY_APPEND(allocator, join, k); - distance_join += self->intervals.nodes[self->join[k].link ^ entries[idx].gva_key].distance; - } // for - prev_join = ranges[j] + 1; - fprintf(stderr, "%2u, ", ranges[j]); - } // for - fprintf(stderr, "] %2u %2u %2u %s\n", hits[i].query.start, hits[i].included, hits[i].excluded, GVA_RELATION_LABELS[hits[i].relation]); - for (gva_uint k = prev_query; k < hits[i].query.start; ++k) - { - ARRAY_APPEND(allocator, query, k); - } // for - distance_query += graph.dom_nodes[hits[i].query.start].distance - graph.dom_nodes[prev_query].distance; - prev_query = hits[i].query.start + 1; - } // if - else if (hits[i].query.end - hits[i].query.start > 1) - { - fprintf(stderr, " %2u [", hits[i].join.start); - for (gva_uint j = hits[i].query.start; j < hits[i].query.end; ++j) - { - for (gva_uint k = prev_query; k < ranges[j]; ++k) - { - ARRAY_APPEND(allocator, query, k); - } // for - distance_query += graph.dom_nodes[ranges[j]].distance - graph.dom_nodes[prev_query].distance; - prev_query = ranges[j] + 1; - fprintf(stderr, "%2u, ", ranges[j]); - } // for - fprintf(stderr, "] %2u %2u %s\n", hits[i].included, hits[i].excluded, GVA_RELATION_LABELS[hits[i].relation]); - for (gva_uint k = prev_join; k < hits[i].join.start; ++k) - { - ARRAY_APPEND(allocator, join, k); - distance_join += self->intervals.nodes[self->join[k].link ^ entries[idx].gva_key].distance; - } // for - prev_join = hits[i].join.start + 1; - } // if - else if (hits[i].included > 0) - { - fprintf(stderr, " %2u %2u %2u %2u %s\n", hits[i].join.start, hits[i].query.start, hits[i].included, hits[i].excluded, GVA_RELATION_LABELS[hits[i].relation]); - for (gva_uint k = prev_join; k < hits[i].join.start; ++k) - { - ARRAY_APPEND(allocator, join, k); - distance_join += self->intervals.nodes[self->join[k].link ^ entries[idx].gva_key].distance; - } // for - prev_join = hits[i].join.start + 1; - for (gva_uint k = prev_query; k < hits[i].query.start; ++k) - { - ARRAY_APPEND(allocator, query, k); - } // for - distance_query += graph.dom_nodes[hits[i].query.start].distance - graph.dom_nodes[prev_query].distance; - prev_query = hits[i].query.start + 1; - } // if - } // for - for (gva_uint k = prev_join; k < self->alleles[entries[idx].gva_key].join.end; ++k) - { - ARRAY_APPEND(allocator, join, k); - distance_join += self->intervals.nodes[self->join[k].link ^ entries[idx].gva_key].distance; - } // for - for (gva_uint k = prev_query; k < array_length(graph.dom_nodes) - 1; ++k) - { - ARRAY_APPEND(allocator, query, k); - } // for - distance_query += graph.dom_nodes[array_length(graph.dom_nodes) - 1].distance - graph.dom_nodes[prev_query].distance; - if (distance_join > 0) - { - fprintf(stderr, " ["); - for (size_t i = 0; i < array_length(join); ++i) - { - fprintf(stderr, "%2u, ", join[i]); - } // for - fprintf(stderr, "] * 0 %2zu disjoint\n", distance_join); - } // if - if (distance_query > 0) - { - fprintf(stderr, " * ["); - for (size_t i = 0; i < array_length(query); ++i) + ARRAY_APPEND(allocator, result.alleles, ((struct GVA_Query_Allele) { - fprintf(stderr, "%2u, ", query[i]); - } // for - fprintf(stderr, "] 0 %2zu disjoint\n", distance_query); - } // if - - join = ARRAY_DESTROY(allocator, join); - query = ARRAY_DESTROY(allocator, query); + .idx = entries[idx].gva_key, + .relation = relation, + .included = entries[idx].included, + .excluded = excluded, + .hits = {start_hits, array_length(result.hits)}, + })); } // for - ranges = ARRAY_DESTROY(allocator, ranges); hits = ARRAY_DESTROY(allocator, hits); entries = HASH_TABLE_DESTROY(allocator, entries); - return (GVA_Query_Result) {NULL}; + return result; } // gva_index_query @@ -740,14 +637,15 @@ gva_index_variant(GVA_Index const* const self, gva_uint -gva_index_allele_start(GVA_Index const* const self, size_t const allele_idx) +gva_index_variant_distance(GVA_Index const* const self, + size_t const allele_idx, size_t const variant_idx) { - return self->alleles[allele_idx].join.start; -} // gva_index_allele_start + return self->intervals.nodes[self->join[variant_idx].link ^ allele_idx].distance; +} // gva_index_variant_distance -gva_uint -gva_index_node_distance(GVA_Index const* const self, size_t const allele_idx, size_t const variant_idx) +GVA_Interval +gva_index_allele_parts(GVA_Index const* const self, size_t const allele_idx) { - return self->intervals.nodes[self->join[variant_idx].link ^ allele_idx].distance; -} // gva_index_node_distance + return self->alleles[allele_idx].join; +} // gva_index_allele_parts diff --git a/src/main.c b/src/main.c index 020ad4b..0cc8ff7 100644 --- a/src/main.c +++ b/src/main.c @@ -23,14 +23,14 @@ #define LINE_SIZE 8194 // #define REFERENCE_ID "NC_000022.11" -#define REFERENCE_ID "NC_000006.12" -// #define REFERENCE_ID "NC_000001.11" +// #define REFERENCE_ID "NC_000006.12" +#define REFERENCE_ID "NC_000001.11" // line: alphanumeric_id SPDI [distance] static bool -parse_line(char const line[static LINE_SIZE], - GVA_String* const id, GVA_Variant* const variant, size_t* const distance) +parse_line(char const line[static restrict LINE_SIZE], + GVA_String id[static restrict 1], GVA_Variant variant[static restrict 1], size_t distance[static restrict 1]) { id->len = strcspn(line, "\t "); if (id->len == 0) @@ -66,7 +66,8 @@ compare_query_alleles(void const* a, void const* b) static void -results_output(GVA_Index *index, GVA_LCS_Graph graph, GVA_String id, GVA_Query_Result const result, bool show_disjoints) +report_query_result(GVA_Index const* const index, GVA_LCS_Graph const graph, GVA_String const id, + GVA_Query_Result const result, bool const query_disjoint, bool const index_disjoint) { for (size_t i = 0; i < array_length(result.alleles); ++i) { @@ -75,86 +76,114 @@ results_output(GVA_Index *index, GVA_LCS_Graph graph, GVA_String id, GVA_Query_R GVA_RELATION_LABELS[result.alleles[i].relation], GVA_STRING_PRINT(id), result.alleles[i].included, result.alleles[i].excluded, array_length(graph.dom_nodes) - 1); - fprintf(stderr, " " GVA_STRING_FMT ": %u %u %s\n", + fprintf(stderr, GVA_STRING_FMT ": %u %u %s\n", GVA_STRING_PRINT(gva_index_id(index, result.alleles[i].idx)), result.alleles[i].included, result.alleles[i].excluded, GVA_RELATION_LABELS[result.alleles[i].relation]); - size_t last_q = -1; - size_t last_i = gva_index_allele_start(index, result.alleles[i].idx); - // TODO: also address trailing disjoints? + gva_uint* join = NULL; + gva_uint prev_join = gva_index_allele_parts(index, result.alleles[i].idx).start; + size_t distance_join = 0; + gva_uint* query = NULL; + gva_uint prev_query = 0; + size_t distance_query = 0; + for (size_t j = result.alleles[i].hits.start; j < result.alleles[i].hits.end; ++j) { - if (show_disjoints) + if (result.hits[j].index_parts.end - result.hits[j].index_parts.start > 1) { - for (size_t k = last_q + 1; k < result.hits[j].query.start; ++k) + fprintf(stderr, " ["); + for (gva_uint k = result.hits[j].index_parts.start; k < result.hits[j].index_parts.end; ++k) { - fprintf(stderr, " [) [%zu, %zu): 0 %u disjoint ", k, k + 1, - graph.dom_nodes[k + 1].distance - graph.dom_nodes[k].distance); - fprintf(stderr, "* " GVA_VARIANT_FMT_SPDI_ALLELE "\n", - GVA_VARIANT_PRINT_SPDI_ALLELE(gva_lcs_graph_local_supremal(graph, k, k + 1))); + for (gva_uint ii = prev_join; ii < result.parts[k]; ++ii) + { + ARRAY_APPEND(gva_std_allocator, join, ii); + distance_join += gva_index_variant_distance(index, result.alleles[i].idx, ii); + } // for + prev_join = result.parts[k] + 1; + fprintf(stderr, "%2u, ", result.parts[k]); } // for - last_q = result.hits[j].query.start; - - for (size_t k = last_i + 1; k < result.hits[j].index.start; ++k) + fprintf(stderr, "] %2u %2u %2u %s\n", result.hits[j].query_parts.start, result.hits[j].included, result.hits[j].excluded, GVA_RELATION_LABELS[result.hits[j].relation]); + for (gva_uint k = prev_query; k < result.hits[j].query_parts.start; ++k) { - fprintf(stderr, " [%zu, %zu) [): 0 %u disjoint ", k, k + 1, gva_index_node_distance(index, result.alleles[i].idx, k)); - fprintf(stderr, GVA_VARIANT_FMT_SPDI_ALLELE " *\n", - GVA_VARIANT_PRINT_SPDI_ALLELE(gva_index_variant(index, result.alleles[i].idx, k))); + ARRAY_APPEND(gva_std_allocator, query, k); } // for - last_i = result.hits[j].index.start; - } - - fprintf(stderr, " [%u, %u) [%u, %u): %u %u %s ", - result.hits[j].index.start, result.hits[j].index.end, - result.hits[j].query.start, result.hits[j].query.end, - result.hits[j].included, result.hits[j].excluded, - GVA_RELATION_LABELS[result.hits[j].relation]); - - // print index allele - fprintf(stderr, REFERENCE_ID ":"); - if (result.hits[j].index.end - result.hits[j].index.start > 1) - { - fprintf(stderr, "["); + distance_query += graph.dom_nodes[result.hits[j].query_parts.start].distance - graph.dom_nodes[prev_query].distance; + prev_query = result.hits[j].query_parts.start + 1; } // if - for (size_t k = result.hits[j].index.start; k < result.hits[j].index.end; ++k) + else if (result.hits[j].query_parts.end - result.hits[j].query_parts.start > 1) { - fprintf(stderr, GVA_VARIANT_FMT_SPDI_ALLELE, - GVA_VARIANT_PRINT_SPDI_ALLELE(gva_index_variant(index, result.alleles[i].idx, k))); - if (k + 1 < result.hits[j].index.end) + fprintf(stderr, " %2u [", result.hits[j].index_parts.start); + for (gva_uint k = result.hits[j].query_parts.start; k < result.hits[j].query_parts.end; ++k) { - fprintf(stderr, ", "); - } // if - } // for - if (result.hits[j].index.end - result.hits[j].index.start > 1) - { - fprintf(stderr, "]"); + for (gva_uint ii = prev_query; ii < result.parts[k]; ++ii) + { + ARRAY_APPEND(gva_std_allocator, query, ii); + } // for + distance_query += graph.dom_nodes[result.parts[k]].distance - graph.dom_nodes[prev_query].distance; + prev_query = result.parts[k] + 1; + fprintf(stderr, "%2u, ", result.parts[k]); + } // for + fprintf(stderr, "] %2u %2u %s\n", result.hits[j].included, result.hits[j].excluded, GVA_RELATION_LABELS[result.hits[j].relation]); + for (gva_uint k = prev_join; k < result.hits[j].index_parts.start; ++k) + { + ARRAY_APPEND(gva_std_allocator, join, k); + distance_join += gva_index_variant_distance(index, result.alleles[i].idx, k); + } // for + prev_join = result.hits[j].index_parts.start + 1; } // if - fprintf(stderr, " "); - - // print query allele - fprintf(stderr, REFERENCE_ID ":"); - if (result.hits[j].query.end - result.hits[j].query.start > 1) + else if (result.hits[j].included > 0) { - fprintf(stderr, "["); + fprintf(stderr, " %2u %2u %2u %2u %s\n", result.hits[j].index_parts.start, result.hits[j].query_parts.start, result.hits[j].included, result.hits[j].excluded, GVA_RELATION_LABELS[result.hits[j].relation]); + for (gva_uint k = prev_join; k < result.hits[j].index_parts.start; ++k) + { + ARRAY_APPEND(gva_std_allocator, join, k); + distance_join += gva_index_variant_distance(index, result.alleles[i].idx, k); + } // for + prev_join = result.hits[j].index_parts.start + 1; + for (gva_uint k = prev_query; k < result.hits[j].query_parts.start; ++k) + { + ARRAY_APPEND(gva_std_allocator, query, k); + } // for + distance_query += graph.dom_nodes[result.hits[j].query_parts.start].distance - graph.dom_nodes[prev_query].distance; + prev_query = result.hits[j].query_parts.start + 1; } // if - for (size_t k = result.hits[j].query.start; k < result.hits[j].query.end; ++k) + } // for + + for (gva_uint k = prev_join; k < gva_index_allele_parts(index, result.alleles[i].idx).end; ++k) + { + ARRAY_APPEND(gva_std_allocator, join, k); + distance_join += gva_index_variant_distance(index, result.alleles[i].idx, k); + } // for + for (gva_uint k = prev_query; k < array_length(graph.dom_nodes) - 1; ++k) + { + ARRAY_APPEND(gva_std_allocator, query, k); + } // for + distance_query += graph.dom_nodes[array_length(graph.dom_nodes) - 1].distance - graph.dom_nodes[prev_query].distance; + + if (join != NULL) + { + fprintf(stderr, " ["); + for (size_t i = 0; i < array_length(join); ++i) { - fprintf(stderr, GVA_VARIANT_FMT_SPDI_ALLELE, - GVA_VARIANT_PRINT_SPDI_ALLELE(gva_lcs_graph_local_supremal(graph, k, k + 1))); - if (k + 1 < result.hits[j].query.end) - { - fprintf(stderr, ", "); - } // if + fprintf(stderr, "%2u, ", join[i]); } // for - if (result.hits[j].query.end - result.hits[j].query.start > 1) + fprintf(stderr, "] * 0 %2zu disjoint\n", distance_join); + } // if + if (query != NULL) + { + fprintf(stderr, " * ["); + for (size_t i = 0; i < array_length(query); ++i) { - fprintf(stderr, "]"); - } // if - fprintf(stderr, "\n"); - } // for + fprintf(stderr, "%2u, ", query[i]); + } // for + fprintf(stderr, "] 0 %2zu disjoint\n", distance_query); + } // if + + join = ARRAY_DESTROY(gva_std_allocator, join); + query = ARRAY_DESTROY(gva_std_allocator, query); } // for -} // results_output +} // report_query_result int @@ -237,10 +266,11 @@ index_main(int argc, char* argv[static argc]) qsort(result.alleles, array_length(result.alleles), sizeof(*result.alleles), compare_query_alleles); } // if - results_output(index, graph, id, result, false); + report_query_result(index, graph, id, result, false, false); result.alleles = ARRAY_DESTROY(gva_std_allocator, result.alleles); result.hits = ARRAY_DESTROY(gva_std_allocator, result.hits); + result.parts = ARRAY_DESTROY(gva_std_allocator, result.parts); gva_lcs_graph_destroy(gva_std_allocator, graph, true); } // while From b639b699e8e2f5606619d0ddc71ca43b0b3606e1 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Tue, 24 Mar 2026 12:41:10 +0100 Subject: [PATCH 562/704] Properly calculate excluded. --- src/index.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/index.c b/src/index.c index a4cf33d..e16c234 100644 --- a/src/index.c +++ b/src/index.c @@ -554,17 +554,19 @@ gva_index_query(GVA_Allocator const allocator, if (ABS((intmax_t) self->intervals.nodes[node_idx].distance - (intmax_t) distance) != hits[i].distance) { size_t excluded = 0; - size_t const included = variants_included(allocator, self->reference.len, self->reference.str, + size_t included = variants_included(allocator, self->reference.len, self->reference.str, variant_from_index(self, node_idx), gva_lcs_graph_local_supremal(graph, hits[i].query, hits[i].query + 1), &excluded); + if (included > 0) { + included = MAX(1, (double) (2 * included - 1) / excluded * MIN(self->intervals.nodes[node_idx].distance, distance)); ARRAY_APPEND(allocator, result.hits, ((struct GVA_Query_Hit) { .relation = GVA_OVERLAP, - .included = MAX(1, (double) (2 * included - 1) / excluded * MIN(self->intervals.nodes[node_idx].distance, distance)), - .excluded = excluded, + .included = included, + .excluded = self->intervals.nodes[node_idx].distance + distance - 2 * included, .query_parts = {hits[i].query, hits[i].query}, .index_parts = {hits[i].join, hits[i].join}, })); From 658c0a5c1daca6284d9b289720782bcf485e4c4a Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 24 Mar 2026 15:20:48 +0100 Subject: [PATCH 563/704] Conditional reporting --- include/index.h | 10 +-- src/index.c | 20 ++--- src/main.c | 203 +++++++++++++++++++++++++++--------------------- 3 files changed, 131 insertions(+), 102 deletions(-) diff --git a/include/index.h b/include/index.h index a36a681..d0e3826 100644 --- a/include/index.h +++ b/include/index.h @@ -58,7 +58,11 @@ gva_index_query(GVA_Allocator const allocator, GVA_String -gva_index_id(GVA_Index const* const self, size_t const idx); +gva_index_allele_id(GVA_Index const* const self, size_t const idx); + + +GVA_Interval +gva_index_allele_parts(GVA_Index const* const self, size_t const idx); GVA_Variant @@ -71,8 +75,4 @@ gva_index_variant_distance(GVA_Index const* const self, size_t const allele_idx, size_t const variant_idx); -GVA_Interval -gva_index_allele_parts(GVA_Index const* const self, size_t const allele_idx); - - #endif // GVA_INDEX_H diff --git a/src/index.c b/src/index.c index e16c234..50cf40d 100644 --- a/src/index.c +++ b/src/index.c @@ -624,10 +624,17 @@ gva_index_query(GVA_Allocator const allocator, inline GVA_String -gva_index_id(GVA_Index const* const self, size_t const idx) +gva_index_allele_id(GVA_Index const* const self, size_t const idx) { return trie_string(self->ids, self->alleles[idx].id_idx); -} // gva_index_id +} // gva_index_allele_id + + +inline GVA_Interval +gva_index_allele_parts(GVA_Index const* const self, size_t const idx) +{ + return self->alleles[idx].join; +} // gva_index_allele_parts inline GVA_Variant @@ -638,16 +645,9 @@ gva_index_variant(GVA_Index const* const self, } // gva_index_variant -gva_uint +inline gva_uint gva_index_variant_distance(GVA_Index const* const self, size_t const allele_idx, size_t const variant_idx) { return self->intervals.nodes[self->join[variant_idx].link ^ allele_idx].distance; } // gva_index_variant_distance - - -GVA_Interval -gva_index_allele_parts(GVA_Index const* const self, size_t const allele_idx) -{ - return self->alleles[allele_idx].join; -} // gva_index_allele_parts diff --git a/src/main.c b/src/main.c index 0cc8ff7..9c387dd 100644 --- a/src/main.c +++ b/src/main.c @@ -67,121 +67,150 @@ compare_query_alleles(void const* a, void const* b) static void report_query_result(GVA_Index const* const index, GVA_LCS_Graph const graph, GVA_String const id, - GVA_Query_Result const result, bool const query_disjoint, bool const index_disjoint) + GVA_Query_Result const result, + bool const hits, bool const query_disjoint, bool const index_disjoint) { for (size_t i = 0; i < array_length(result.alleles); ++i) { fprintf(stdout, GVA_STRING_FMT " %s " GVA_STRING_FMT " %u %u %zu\n", - GVA_STRING_PRINT(gva_index_id(index, result.alleles[i].idx)), + GVA_STRING_PRINT(gva_index_allele_id(index, result.alleles[i].idx)), GVA_RELATION_LABELS[result.alleles[i].relation], GVA_STRING_PRINT(id), result.alleles[i].included, result.alleles[i].excluded, array_length(graph.dom_nodes) - 1); - fprintf(stderr, GVA_STRING_FMT ": %u %u %s\n", - GVA_STRING_PRINT(gva_index_id(index, result.alleles[i].idx)), - result.alleles[i].included, result.alleles[i].excluded, - GVA_RELATION_LABELS[result.alleles[i].relation]); - - gva_uint* join = NULL; - gva_uint prev_join = gva_index_allele_parts(index, result.alleles[i].idx).start; - size_t distance_join = 0; - gva_uint* query = NULL; - gva_uint prev_query = 0; - size_t distance_query = 0; - - for (size_t j = result.alleles[i].hits.start; j < result.alleles[i].hits.end; ++j) + + if (hits) { - if (result.hits[j].index_parts.end - result.hits[j].index_parts.start > 1) + fprintf(stderr, GVA_STRING_FMT ": %u %u %s\n", + GVA_STRING_PRINT(gva_index_allele_id(index, result.alleles[i].idx)), + result.alleles[i].included, result.alleles[i].excluded, + GVA_RELATION_LABELS[result.alleles[i].relation]); + + gva_uint* join = NULL; + gva_uint prev_join = gva_index_allele_parts(index, result.alleles[i].idx).start; + size_t distance_join = 0; + gva_uint* query = NULL; + gva_uint prev_query = 0; + size_t distance_query = 0; + + for (size_t j = result.alleles[i].hits.start; j < result.alleles[i].hits.end; ++j) { - fprintf(stderr, " ["); - for (gva_uint k = result.hits[j].index_parts.start; k < result.hits[j].index_parts.end; ++k) + if (result.hits[j].index_parts.end - result.hits[j].index_parts.start > 1) { - for (gva_uint ii = prev_join; ii < result.parts[k]; ++ii) + fprintf(stderr, " ["); + for (gva_uint k = result.hits[j].index_parts.start; k < result.hits[j].index_parts.end; ++k) { - ARRAY_APPEND(gva_std_allocator, join, ii); - distance_join += gva_index_variant_distance(index, result.alleles[i].idx, ii); + if (index_disjoint) + { + for (gva_uint ii = prev_join; ii < result.parts[k]; ++ii) + { + ARRAY_APPEND(gva_std_allocator, join, ii); + distance_join += gva_index_variant_distance(index, result.alleles[i].idx, ii); + } // for + prev_join = result.parts[k] + 1; + } // if + fprintf(stderr, "%2u, ", result.parts[k]); } // for - prev_join = result.parts[k] + 1; - fprintf(stderr, "%2u, ", result.parts[k]); - } // for - fprintf(stderr, "] %2u %2u %2u %s\n", result.hits[j].query_parts.start, result.hits[j].included, result.hits[j].excluded, GVA_RELATION_LABELS[result.hits[j].relation]); - for (gva_uint k = prev_query; k < result.hits[j].query_parts.start; ++k) - { - ARRAY_APPEND(gva_std_allocator, query, k); - } // for - distance_query += graph.dom_nodes[result.hits[j].query_parts.start].distance - graph.dom_nodes[prev_query].distance; - prev_query = result.hits[j].query_parts.start + 1; - } // if - else if (result.hits[j].query_parts.end - result.hits[j].query_parts.start > 1) - { - fprintf(stderr, " %2u [", result.hits[j].index_parts.start); - for (gva_uint k = result.hits[j].query_parts.start; k < result.hits[j].query_parts.end; ++k) + fprintf(stderr, "] %2u %2u %2u %s\n", result.hits[j].query_parts.start, result.hits[j].included, result.hits[j].excluded, GVA_RELATION_LABELS[result.hits[j].relation]); + if (query_disjoint) + { + for (gva_uint k = prev_query; k < result.hits[j].query_parts.start; ++k) + { + ARRAY_APPEND(gva_std_allocator, query, k); + } // for + distance_query += graph.dom_nodes[result.hits[j].query_parts.start].distance - graph.dom_nodes[prev_query].distance; + prev_query = result.hits[j].query_parts.start + 1; + } // if + } // if + else if (result.hits[j].query_parts.end - result.hits[j].query_parts.start > 1) { - for (gva_uint ii = prev_query; ii < result.parts[k]; ++ii) + fprintf(stderr, " %2u [", result.hits[j].index_parts.start); + for (gva_uint k = result.hits[j].query_parts.start; k < result.hits[j].query_parts.end; ++k) { - ARRAY_APPEND(gva_std_allocator, query, ii); + if (query_disjoint) + { + for (gva_uint ii = prev_query; ii < result.parts[k]; ++ii) + { + ARRAY_APPEND(gva_std_allocator, query, ii); + } // for + distance_query += graph.dom_nodes[result.parts[k]].distance - graph.dom_nodes[prev_query].distance; + prev_query = result.parts[k] + 1; + } // if + fprintf(stderr, "%2u, ", result.parts[k]); } // for - distance_query += graph.dom_nodes[result.parts[k]].distance - graph.dom_nodes[prev_query].distance; - prev_query = result.parts[k] + 1; - fprintf(stderr, "%2u, ", result.parts[k]); - } // for - fprintf(stderr, "] %2u %2u %s\n", result.hits[j].included, result.hits[j].excluded, GVA_RELATION_LABELS[result.hits[j].relation]); - for (gva_uint k = prev_join; k < result.hits[j].index_parts.start; ++k) + fprintf(stderr, "] %2u %2u %s\n", result.hits[j].included, result.hits[j].excluded, GVA_RELATION_LABELS[result.hits[j].relation]); + if (index_disjoint) + { + for (gva_uint k = prev_join; k < result.hits[j].index_parts.start; ++k) + { + ARRAY_APPEND(gva_std_allocator, join, k); + distance_join += gva_index_variant_distance(index, result.alleles[i].idx, k); + } // for + prev_join = result.hits[j].index_parts.start + 1; + } // if + } // if + else if (result.hits[j].included > 0) { - ARRAY_APPEND(gva_std_allocator, join, k); - distance_join += gva_index_variant_distance(index, result.alleles[i].idx, k); - } // for - prev_join = result.hits[j].index_parts.start + 1; - } // if - else if (result.hits[j].included > 0) + fprintf(stderr, " %2u %2u %2u %2u %s\n", result.hits[j].index_parts.start, result.hits[j].query_parts.start, result.hits[j].included, result.hits[j].excluded, GVA_RELATION_LABELS[result.hits[j].relation]); + if (index_disjoint) + { + for (gva_uint k = prev_join; k < result.hits[j].index_parts.start; ++k) + { + ARRAY_APPEND(gva_std_allocator, join, k); + distance_join += gva_index_variant_distance(index, result.alleles[i].idx, k); + } // for + prev_join = result.hits[j].index_parts.start + 1; + } // if + if (query_disjoint) + { + for (gva_uint k = prev_query; k < result.hits[j].query_parts.start; ++k) + { + ARRAY_APPEND(gva_std_allocator, query, k); + } // for + distance_query += graph.dom_nodes[result.hits[j].query_parts.start].distance - graph.dom_nodes[prev_query].distance; + prev_query = result.hits[j].query_parts.start + 1; + } // if + } // if + } // for + + if (index_disjoint) { - fprintf(stderr, " %2u %2u %2u %2u %s\n", result.hits[j].index_parts.start, result.hits[j].query_parts.start, result.hits[j].included, result.hits[j].excluded, GVA_RELATION_LABELS[result.hits[j].relation]); - for (gva_uint k = prev_join; k < result.hits[j].index_parts.start; ++k) + for (gva_uint k = prev_join; k < gva_index_allele_parts(index, result.alleles[i].idx).end; ++k) { ARRAY_APPEND(gva_std_allocator, join, k); distance_join += gva_index_variant_distance(index, result.alleles[i].idx, k); } // for - prev_join = result.hits[j].index_parts.start + 1; - for (gva_uint k = prev_query; k < result.hits[j].query_parts.start; ++k) + } // if + if (query_disjoint) + { + for (gva_uint k = prev_query; k < array_length(graph.dom_nodes) - 1; ++k) { ARRAY_APPEND(gva_std_allocator, query, k); } // for - distance_query += graph.dom_nodes[result.hits[j].query_parts.start].distance - graph.dom_nodes[prev_query].distance; - prev_query = result.hits[j].query_parts.start + 1; + distance_query += graph.dom_nodes[array_length(graph.dom_nodes) - 1].distance - graph.dom_nodes[prev_query].distance; } // if - } // for - - for (gva_uint k = prev_join; k < gva_index_allele_parts(index, result.alleles[i].idx).end; ++k) - { - ARRAY_APPEND(gva_std_allocator, join, k); - distance_join += gva_index_variant_distance(index, result.alleles[i].idx, k); - } // for - for (gva_uint k = prev_query; k < array_length(graph.dom_nodes) - 1; ++k) - { - ARRAY_APPEND(gva_std_allocator, query, k); - } // for - distance_query += graph.dom_nodes[array_length(graph.dom_nodes) - 1].distance - graph.dom_nodes[prev_query].distance; - if (join != NULL) - { - fprintf(stderr, " ["); - for (size_t i = 0; i < array_length(join); ++i) + if (join != NULL) { - fprintf(stderr, "%2u, ", join[i]); - } // for - fprintf(stderr, "] * 0 %2zu disjoint\n", distance_join); - } // if - if (query != NULL) - { - fprintf(stderr, " * ["); - for (size_t i = 0; i < array_length(query); ++i) + fprintf(stderr, " ["); + for (size_t i = 0; i < array_length(join); ++i) + { + fprintf(stderr, "%2u, ", join[i]); + } // for + fprintf(stderr, "] * 0 %2zu disjoint\n", distance_join); + } // if + if (query != NULL) { - fprintf(stderr, "%2u, ", query[i]); - } // for - fprintf(stderr, "] 0 %2zu disjoint\n", distance_query); - } // if + fprintf(stderr, " * ["); + for (size_t i = 0; i < array_length(query); ++i) + { + fprintf(stderr, "%2u, ", query[i]); + } // for + fprintf(stderr, "] 0 %2zu disjoint\n", distance_query); + } // if - join = ARRAY_DESTROY(gva_std_allocator, join); - query = ARRAY_DESTROY(gva_std_allocator, query); + join = ARRAY_DESTROY(gva_std_allocator, join); + query = ARRAY_DESTROY(gva_std_allocator, query); + } // if } // for } // report_query_result @@ -266,7 +295,7 @@ index_main(int argc, char* argv[static argc]) qsort(result.alleles, array_length(result.alleles), sizeof(*result.alleles), compare_query_alleles); } // if - report_query_result(index, graph, id, result, false, false); + report_query_result(index, graph, id, result, true, true, true); result.alleles = ARRAY_DESTROY(gva_std_allocator, result.alleles); result.hits = ARRAY_DESTROY(gva_std_allocator, result.hits); From 8aa7bab8270b456915cfd57bf750796069ed9496 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 24 Mar 2026 16:18:48 +0100 Subject: [PATCH 564/704] Added disjoint pair to tests --- include/variant.h | 1 + test_alleles_supremal2.txt | 2 ++ truth/YV | 1 + truth/YW | 1 + 4 files changed, 5 insertions(+) create mode 100644 truth/YV create mode 100644 truth/YW diff --git a/include/variant.h b/include/variant.h index 23b0100..606c9a8 100644 --- a/include/variant.h +++ b/include/variant.h @@ -19,6 +19,7 @@ #define GVA_VARIANT_PRINT_SPDI_ALLELE(variant) variant.start, (variant.end - variant.start), GVA_STRING_PRINT(variant.sequence) #define GVA_VARIANT_FMT_SPDI_ALLELE GVA_UINT_FMT ":" GVA_UINT_FMT ":" GVA_STRING_FMT + typedef struct { gva_uint start; diff --git a/test_alleles_supremal2.txt b/test_alleles_supremal2.txt index ffe85f8..0f067f8 100644 --- a/test_alleles_supremal2.txt +++ b/test_alleles_supremal2.txt @@ -45,3 +45,5 @@ YR NC_000001.11:74362:4:CATAC 5 YS NC_000001.11:74362:4:CAGAC 5 YT NC_000001.11:74348:18:GCGTAGTAACCCAGCAGAC 9 YU NC_000001.11:74349:17:CGCGTATAGACCCCAGCATAC 10 +YV NC_000001.11:102745133:0:GG 2 +YW NC_000001.11:102745130:6:GGGGTTTTT 3 diff --git a/truth/YV b/truth/YV new file mode 100644 index 0000000..8f241c1 --- /dev/null +++ b/truth/YV @@ -0,0 +1 @@ +YV NC_000001.11:102745133:0:GG 2 diff --git a/truth/YW b/truth/YW new file mode 100644 index 0000000..ab76449 --- /dev/null +++ b/truth/YW @@ -0,0 +1 @@ +YW NC_000001.11:102745130:6:GGGGTTTTT 3 From aee2ad321c67c66786bc09739a4eb6c1d0519281 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Tue, 24 Mar 2026 16:24:33 +0100 Subject: [PATCH 565/704] New tests. --- truth_2026.txt | 552 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 552 insertions(+) diff --git a/truth_2026.txt b/truth_2026.txt index 987a1de..7d395fe 100644 --- a/truth_2026.txt +++ b/truth_2026.txt @@ -41,6 +41,12 @@ XA disjoint YN XA disjoint YO XA disjoint YP XA disjoint YQ +XA disjoint YR +XA disjoint YS +XA disjoint YT +XA disjoint YU +XA disjoint YV +XA disjoint YW XB is_contained XA XB equivalent XB XB disjoint XC @@ -84,6 +90,12 @@ XB disjoint YN XB disjoint YO XB disjoint YP XB disjoint YQ +XB disjoint YR +XB disjoint YS +XB disjoint YT +XB disjoint YU +XB disjoint YV +XB disjoint YW XC disjoint XA XC disjoint XB XC equivalent XC @@ -127,6 +139,12 @@ XC disjoint YN XC disjoint YO XC disjoint YP XC disjoint YQ +XC disjoint YR +XC disjoint YS +XC disjoint YT +XC disjoint YU +XC disjoint YV +XC disjoint YW XD disjoint XA XD disjoint XB XD contains XC @@ -170,6 +188,12 @@ XD disjoint YN XD disjoint YO XD disjoint YP XD disjoint YQ +XD disjoint YR +XD disjoint YS +XD disjoint YT +XD disjoint YU +XD disjoint YV +XD disjoint YW XE overlap XA XE contains XB XE disjoint XC @@ -213,6 +237,12 @@ XE disjoint YN XE disjoint YO XE disjoint YP XE disjoint YQ +XE disjoint YR +XE disjoint YS +XE disjoint YT +XE disjoint YU +XE disjoint YV +XE disjoint YW XF disjoint XA XF disjoint XB XF disjoint XC @@ -256,6 +286,12 @@ XF disjoint YN XF disjoint YO XF disjoint YP XF disjoint YQ +XF disjoint YR +XF disjoint YS +XF disjoint YT +XF disjoint YU +XF disjoint YV +XF disjoint YW XG disjoint XA XG disjoint XB XG disjoint XC @@ -299,6 +335,12 @@ XG disjoint YN XG disjoint YO XG disjoint YP XG disjoint YQ +XG disjoint YR +XG disjoint YS +XG disjoint YT +XG disjoint YU +XG disjoint YV +XG disjoint YW XH disjoint XA XH disjoint XB XH disjoint XC @@ -342,6 +384,12 @@ XH disjoint YN XH disjoint YO XH disjoint YP XH disjoint YQ +XH disjoint YR +XH disjoint YS +XH disjoint YT +XH disjoint YU +XH disjoint YV +XH disjoint YW XI disjoint XA XI disjoint XB XI disjoint XC @@ -385,6 +433,12 @@ XI disjoint YN XI disjoint YO XI disjoint YP XI disjoint YQ +XI disjoint YR +XI disjoint YS +XI disjoint YT +XI disjoint YU +XI disjoint YV +XI disjoint YW XJ disjoint XA XJ disjoint XB XJ disjoint XC @@ -428,6 +482,12 @@ XJ disjoint YN XJ disjoint YO XJ disjoint YP XJ disjoint YQ +XJ disjoint YR +XJ disjoint YS +XJ disjoint YT +XJ disjoint YU +XJ disjoint YV +XJ disjoint YW XK disjoint XA XK disjoint XB XK disjoint XC @@ -471,6 +531,12 @@ XK disjoint YN XK disjoint YO XK disjoint YP XK disjoint YQ +XK disjoint YR +XK disjoint YS +XK disjoint YT +XK disjoint YU +XK disjoint YV +XK disjoint YW XL disjoint XA XL disjoint XB XL disjoint XC @@ -514,6 +580,12 @@ XL disjoint YN XL disjoint YO XL disjoint YP XL disjoint YQ +XL disjoint YR +XL disjoint YS +XL disjoint YT +XL disjoint YU +XL disjoint YV +XL disjoint YW XM disjoint XA XM disjoint XB XM disjoint XC @@ -557,6 +629,12 @@ XM disjoint YN XM disjoint YO XM disjoint YP XM disjoint YQ +XM disjoint YR +XM disjoint YS +XM disjoint YT +XM disjoint YU +XM disjoint YV +XM disjoint YW XN disjoint XA XN disjoint XB XN disjoint XC @@ -600,6 +678,12 @@ XN disjoint YN XN disjoint YO XN disjoint YP XN disjoint YQ +XN disjoint YR +XN disjoint YS +XN disjoint YT +XN disjoint YU +XN disjoint YV +XN disjoint YW XO disjoint XA XO disjoint XB XO disjoint XC @@ -643,6 +727,12 @@ XO disjoint YN XO disjoint YO XO disjoint YP XO disjoint YQ +XO disjoint YR +XO disjoint YS +XO disjoint YT +XO disjoint YU +XO disjoint YV +XO disjoint YW XP disjoint XA XP disjoint XB XP disjoint XC @@ -686,6 +776,12 @@ XP disjoint YN XP disjoint YO XP disjoint YP XP disjoint YQ +XP disjoint YR +XP disjoint YS +XP disjoint YT +XP disjoint YU +XP disjoint YV +XP disjoint YW XQ disjoint XA XQ disjoint XB XQ disjoint XC @@ -729,6 +825,12 @@ XQ disjoint YN XQ disjoint YO XQ disjoint YP XQ disjoint YQ +XQ disjoint YR +XQ disjoint YS +XQ disjoint YT +XQ disjoint YU +XQ disjoint YV +XQ disjoint YW XR disjoint XA XR disjoint XB XR disjoint XC @@ -772,6 +874,12 @@ XR disjoint YN XR disjoint YO XR disjoint YP XR disjoint YQ +XR disjoint YR +XR disjoint YS +XR disjoint YT +XR disjoint YU +XR disjoint YV +XR disjoint YW XS disjoint XA XS disjoint XB XS disjoint XC @@ -815,6 +923,12 @@ XS disjoint YN XS disjoint YO XS disjoint YP XS disjoint YQ +XS disjoint YR +XS disjoint YS +XS disjoint YT +XS disjoint YU +XS disjoint YV +XS disjoint YW XT disjoint XA XT disjoint XB XT disjoint XC @@ -858,6 +972,12 @@ XT disjoint YN XT disjoint YO XT disjoint YP XT disjoint YQ +XT disjoint YR +XT disjoint YS +XT disjoint YT +XT disjoint YU +XT disjoint YV +XT disjoint YW XU disjoint XA XU disjoint XB XU disjoint XC @@ -901,6 +1021,12 @@ XU disjoint YN XU disjoint YO XU disjoint YP XU disjoint YQ +XU disjoint YR +XU disjoint YS +XU disjoint YT +XU disjoint YU +XU disjoint YV +XU disjoint YW XV disjoint XA XV disjoint XB XV disjoint XC @@ -944,6 +1070,12 @@ XV disjoint YN XV disjoint YO XV disjoint YP XV disjoint YQ +XV disjoint YR +XV disjoint YS +XV disjoint YT +XV disjoint YU +XV disjoint YV +XV disjoint YW XW disjoint XA XW disjoint XB XW disjoint XC @@ -987,6 +1119,12 @@ XW disjoint YN XW disjoint YO XW disjoint YP XW disjoint YQ +XW disjoint YR +XW disjoint YS +XW disjoint YT +XW disjoint YU +XW disjoint YV +XW disjoint YW XX disjoint XA XX disjoint XB XX disjoint XC @@ -1030,6 +1168,12 @@ XX disjoint YN XX disjoint YO XX disjoint YP XX disjoint YQ +XX disjoint YR +XX disjoint YS +XX disjoint YT +XX disjoint YU +XX disjoint YV +XX disjoint YW XY disjoint XA XY disjoint XB XY disjoint XC @@ -1073,6 +1217,12 @@ XY disjoint YN XY disjoint YO XY disjoint YP XY disjoint YQ +XY disjoint YR +XY disjoint YS +XY disjoint YT +XY disjoint YU +XY disjoint YV +XY disjoint YW XZ disjoint XA XZ disjoint XB XZ disjoint XC @@ -1116,6 +1266,12 @@ XZ disjoint YN XZ disjoint YO XZ disjoint YP XZ disjoint YQ +XZ disjoint YR +XZ disjoint YS +XZ disjoint YT +XZ disjoint YU +XZ disjoint YV +XZ disjoint YW YA disjoint XA YA disjoint XB YA disjoint XC @@ -1159,6 +1315,12 @@ YA disjoint YN YA disjoint YO YA disjoint YP YA disjoint YQ +YA disjoint YR +YA disjoint YS +YA disjoint YT +YA disjoint YU +YA disjoint YV +YA disjoint YW YB disjoint XA YB disjoint XB YB disjoint XC @@ -1202,6 +1364,12 @@ YB disjoint YN YB disjoint YO YB disjoint YP YB disjoint YQ +YB disjoint YR +YB disjoint YS +YB disjoint YT +YB disjoint YU +YB disjoint YV +YB disjoint YW YC disjoint XA YC disjoint XB YC disjoint XC @@ -1245,6 +1413,12 @@ YC disjoint YN YC disjoint YO YC disjoint YP YC disjoint YQ +YC disjoint YR +YC disjoint YS +YC disjoint YT +YC disjoint YU +YC disjoint YV +YC disjoint YW YD disjoint XA YD disjoint XB YD disjoint XC @@ -1288,6 +1462,12 @@ YD disjoint YN YD disjoint YO YD disjoint YP YD disjoint YQ +YD disjoint YR +YD disjoint YS +YD disjoint YT +YD disjoint YU +YD disjoint YV +YD disjoint YW YE disjoint XA YE disjoint XB YE disjoint XC @@ -1331,6 +1511,12 @@ YE disjoint YN YE disjoint YO YE disjoint YP YE disjoint YQ +YE disjoint YR +YE disjoint YS +YE disjoint YT +YE disjoint YU +YE disjoint YV +YE disjoint YW YF disjoint XA YF disjoint XB YF disjoint XC @@ -1374,6 +1560,12 @@ YF disjoint YN YF disjoint YO YF disjoint YP YF disjoint YQ +YF disjoint YR +YF disjoint YS +YF disjoint YT +YF disjoint YU +YF disjoint YV +YF disjoint YW YG disjoint XA YG disjoint XB YG disjoint XC @@ -1417,6 +1609,12 @@ YG disjoint YN YG disjoint YO YG disjoint YP YG disjoint YQ +YG disjoint YR +YG disjoint YS +YG disjoint YT +YG disjoint YU +YG disjoint YV +YG disjoint YW YH disjoint XA YH disjoint XB YH disjoint XC @@ -1460,6 +1658,12 @@ YH disjoint YN YH disjoint YO YH disjoint YP YH disjoint YQ +YH disjoint YR +YH disjoint YS +YH disjoint YT +YH disjoint YU +YH disjoint YV +YH disjoint YW YI disjoint XA YI disjoint XB YI disjoint XC @@ -1503,6 +1707,12 @@ YI disjoint YN YI disjoint YO YI disjoint YP YI disjoint YQ +YI disjoint YR +YI disjoint YS +YI disjoint YT +YI disjoint YU +YI disjoint YV +YI disjoint YW YJ disjoint XA YJ disjoint XB YJ disjoint XC @@ -1546,6 +1756,12 @@ YJ disjoint YN YJ disjoint YO YJ disjoint YP YJ disjoint YQ +YJ disjoint YR +YJ disjoint YS +YJ disjoint YT +YJ disjoint YU +YJ disjoint YV +YJ disjoint YW YK disjoint XA YK disjoint XB YK disjoint XC @@ -1589,6 +1805,12 @@ YK disjoint YN YK disjoint YO YK disjoint YP YK disjoint YQ +YK disjoint YR +YK disjoint YS +YK disjoint YT +YK disjoint YU +YK disjoint YV +YK disjoint YW YL disjoint XA YL disjoint XB YL disjoint XC @@ -1632,6 +1854,12 @@ YL disjoint YN YL disjoint YO YL disjoint YP YL disjoint YQ +YL disjoint YR +YL disjoint YS +YL disjoint YT +YL disjoint YU +YL disjoint YV +YL disjoint YW YM disjoint XA YM disjoint XB YM disjoint XC @@ -1675,6 +1903,12 @@ YM disjoint YN YM disjoint YO YM disjoint YP YM disjoint YQ +YM disjoint YR +YM disjoint YS +YM disjoint YT +YM disjoint YU +YM disjoint YV +YM disjoint YW YN disjoint XA YN disjoint XB YN disjoint XC @@ -1718,6 +1952,12 @@ YN equivalent YN YN is_contained YO YN disjoint YP YN disjoint YQ +YN disjoint YR +YN disjoint YS +YN disjoint YT +YN disjoint YU +YN disjoint YV +YN disjoint YW YO disjoint XA YO disjoint XB YO disjoint XC @@ -1761,6 +2001,12 @@ YO contains YN YO equivalent YO YO disjoint YP YO disjoint YQ +YO disjoint YR +YO disjoint YS +YO disjoint YT +YO disjoint YU +YO disjoint YV +YO disjoint YW YP disjoint XA YP disjoint XB YP disjoint XC @@ -1804,6 +2050,12 @@ YP disjoint YN YP disjoint YO YP equivalent YP YP overlap YQ +YP disjoint YR +YP disjoint YS +YP disjoint YT +YP disjoint YU +YP disjoint YV +YP disjoint YW YQ disjoint XA YQ disjoint XB YQ disjoint XC @@ -1847,3 +2099,303 @@ YQ disjoint YN YQ disjoint YO YQ overlap YP YQ equivalent YQ +YQ disjoint YR +YQ disjoint YS +YQ disjoint YT +YQ disjoint YU +YQ disjoint YV +YQ disjoint YW +YR disjoint XA +YR disjoint XB +YR disjoint XC +YR disjoint XD +YR disjoint XE +YR disjoint XF +YR disjoint XG +YR disjoint XH +YR disjoint XI +YR disjoint XJ +YR disjoint XK +YR disjoint XL +YR disjoint XM +YR disjoint XN +YR disjoint XO +YR disjoint XP +YR disjoint XQ +YR disjoint XR +YR disjoint XS +YR disjoint XT +YR disjoint XU +YR disjoint XV +YR disjoint XW +YR disjoint XX +YR disjoint XY +YR disjoint XZ +YR disjoint YA +YR disjoint YB +YR disjoint YC +YR disjoint YD +YR disjoint YE +YR disjoint YF +YR disjoint YG +YR disjoint YH +YR disjoint YI +YR disjoint YJ +YR disjoint YK +YR disjoint YL +YR disjoint YM +YR disjoint YN +YR disjoint YO +YR disjoint YP +YR disjoint YQ +YR equivalent YR +YR overlap YS +YR overlap YT +YR is_contained YU +YR disjoint YV +YR disjoint YW +YS disjoint XA +YS disjoint XB +YS disjoint XC +YS disjoint XD +YS disjoint XE +YS disjoint XF +YS disjoint XG +YS disjoint XH +YS disjoint XI +YS disjoint XJ +YS disjoint XK +YS disjoint XL +YS disjoint XM +YS disjoint XN +YS disjoint XO +YS disjoint XP +YS disjoint XQ +YS disjoint XR +YS disjoint XS +YS disjoint XT +YS disjoint XU +YS disjoint XV +YS disjoint XW +YS disjoint XX +YS disjoint XY +YS disjoint XZ +YS disjoint YA +YS disjoint YB +YS disjoint YC +YS disjoint YD +YS disjoint YE +YS disjoint YF +YS disjoint YG +YS disjoint YH +YS disjoint YI +YS disjoint YJ +YS disjoint YK +YS disjoint YL +YS disjoint YM +YS disjoint YN +YS disjoint YO +YS disjoint YP +YS disjoint YQ +YS overlap YR +YS equivalent YS +YS is_contained YT +YS overlap YU +YS disjoint YV +YS disjoint YW +YT disjoint XA +YT disjoint XB +YT disjoint XC +YT disjoint XD +YT disjoint XE +YT disjoint XF +YT disjoint XG +YT disjoint XH +YT disjoint XI +YT disjoint XJ +YT disjoint XK +YT disjoint XL +YT disjoint XM +YT disjoint XN +YT disjoint XO +YT disjoint XP +YT disjoint XQ +YT disjoint XR +YT disjoint XS +YT disjoint XT +YT disjoint XU +YT disjoint XV +YT disjoint XW +YT disjoint XX +YT disjoint XY +YT disjoint XZ +YT disjoint YA +YT disjoint YB +YT disjoint YC +YT disjoint YD +YT disjoint YE +YT disjoint YF +YT disjoint YG +YT disjoint YH +YT disjoint YI +YT disjoint YJ +YT disjoint YK +YT disjoint YL +YT disjoint YM +YT disjoint YN +YT disjoint YO +YT disjoint YP +YT disjoint YQ +YT overlap YR +YT contains YS +YT equivalent YT +YT overlap YU +YT disjoint YV +YT disjoint YW +YU disjoint XA +YU disjoint XB +YU disjoint XC +YU disjoint XD +YU disjoint XE +YU disjoint XF +YU disjoint XG +YU disjoint XH +YU disjoint XI +YU disjoint XJ +YU disjoint XK +YU disjoint XL +YU disjoint XM +YU disjoint XN +YU disjoint XO +YU disjoint XP +YU disjoint XQ +YU disjoint XR +YU disjoint XS +YU disjoint XT +YU disjoint XU +YU disjoint XV +YU disjoint XW +YU disjoint XX +YU disjoint XY +YU disjoint XZ +YU disjoint YA +YU disjoint YB +YU disjoint YC +YU disjoint YD +YU disjoint YE +YU disjoint YF +YU disjoint YG +YU disjoint YH +YU disjoint YI +YU disjoint YJ +YU disjoint YK +YU disjoint YL +YU disjoint YM +YU disjoint YN +YU disjoint YO +YU disjoint YP +YU disjoint YQ +YU contains YR +YU overlap YS +YU overlap YT +YU equivalent YU +YU disjoint YV +YU disjoint YW +YV disjoint XA +YV disjoint XB +YV disjoint XC +YV disjoint XD +YV disjoint XE +YV disjoint XF +YV disjoint XG +YV disjoint XH +YV disjoint XI +YV disjoint XJ +YV disjoint XK +YV disjoint XL +YV disjoint XM +YV disjoint XN +YV disjoint XO +YV disjoint XP +YV disjoint XQ +YV disjoint XR +YV disjoint XS +YV disjoint XT +YV disjoint XU +YV disjoint XV +YV disjoint XW +YV disjoint XX +YV disjoint XY +YV disjoint XZ +YV disjoint YA +YV disjoint YB +YV disjoint YC +YV disjoint YD +YV disjoint YE +YV disjoint YF +YV disjoint YG +YV disjoint YH +YV disjoint YI +YV disjoint YJ +YV disjoint YK +YV disjoint YL +YV disjoint YM +YV disjoint YN +YV disjoint YO +YV disjoint YP +YV disjoint YQ +YV disjoint YR +YV disjoint YS +YV disjoint YT +YV disjoint YU +YV equivalent YV +YV disjoint YW +YW disjoint XA +YW disjoint XB +YW disjoint XC +YW disjoint XD +YW disjoint XE +YW disjoint XF +YW disjoint XG +YW disjoint XH +YW disjoint XI +YW disjoint XJ +YW disjoint XK +YW disjoint XL +YW disjoint XM +YW disjoint XN +YW disjoint XO +YW disjoint XP +YW disjoint XQ +YW disjoint XR +YW disjoint XS +YW disjoint XT +YW disjoint XU +YW disjoint XV +YW disjoint XW +YW disjoint XX +YW disjoint XY +YW disjoint XZ +YW disjoint YA +YW disjoint YB +YW disjoint YC +YW disjoint YD +YW disjoint YE +YW disjoint YF +YW disjoint YG +YW disjoint YH +YW disjoint YI +YW disjoint YJ +YW disjoint YK +YW disjoint YL +YW disjoint YM +YW disjoint YN +YW disjoint YO +YW disjoint YP +YW disjoint YQ +YW disjoint YR +YW disjoint YS +YW disjoint YT +YW disjoint YU +YW disjoint YV +YW equivalent YW From 0a85ab41b9d6567e83be8206101eb8eefb567ceb Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 25 Mar 2026 11:22:53 +0100 Subject: [PATCH 566/704] Interface improvements --- include/index.h | 42 ++++++++++++++++++++++++------------------ src/index.c | 12 ++++++------ src/main.c | 4 ++-- 3 files changed, 32 insertions(+), 26 deletions(-) diff --git a/include/index.h b/include/index.h index d0e3826..50783eb 100644 --- a/include/index.h +++ b/include/index.h @@ -16,23 +16,29 @@ typedef struct GVA_Index GVA_Index; // opaque typedef struct { - struct GVA_Query_Allele - { - gva_uint idx; - GVA_Relation relation; - gva_uint included; - gva_uint excluded; - GVA_Interval hits; - }* alleles; - struct GVA_Query_Hit - { - GVA_Relation relation; - gva_uint included; - gva_uint excluded; - GVA_Interval index_parts; - GVA_Interval query_parts; - }* hits; - gva_uint* parts; + gva_uint idx; + GVA_Relation relation; + gva_uint included; + gva_uint excluded; + GVA_Interval hits; +} GVA_Query_Allele; + + +typedef struct +{ + GVA_Relation relation; + gva_uint included; + gva_uint excluded; + GVA_Interval index_parts; + GVA_Interval query_parts; +} GVA_Query_Hit; + + +typedef struct +{ + GVA_Query_Allele* alleles; + GVA_Query_Hit* hits; + gva_uint* parts; } GVA_Query_Result; @@ -70,7 +76,7 @@ gva_index_variant(GVA_Index const* const self, size_t const allele_idx, size_t const variant_idx); -gva_uint +size_t gva_index_variant_distance(GVA_Index const* const self, size_t const allele_idx, size_t const variant_idx); diff --git a/src/index.c b/src/index.c index 50cf40d..6689c9c 100644 --- a/src/index.c +++ b/src/index.c @@ -491,7 +491,7 @@ gva_index_query(GVA_Allocator const allocator, size_t excluded = 0; GVA_Relation const relation = relation_from_included(included, self->intervals.nodes[node_idx].distance, distance, &excluded); - ARRAY_APPEND(allocator, result.hits, ((struct GVA_Query_Hit) + ARRAY_APPEND(allocator, result.hits, ((GVA_Query_Hit) { .relation = relation, .included = included, @@ -534,7 +534,7 @@ gva_index_query(GVA_Allocator const allocator, size_t excluded = 0; GVA_Relation const relation = relation_from_included(included, distance, graph.dom_nodes[hits[i].query + 1].distance - graph.dom_nodes[hits[i].query].distance, &excluded); - ARRAY_APPEND(allocator, result.hits, ((struct GVA_Query_Hit) + ARRAY_APPEND(allocator, result.hits, ((GVA_Query_Hit) { .relation = relation, .included = included, @@ -562,7 +562,7 @@ gva_index_query(GVA_Allocator const allocator, if (included > 0) { included = MAX(1, (double) (2 * included - 1) / excluded * MIN(self->intervals.nodes[node_idx].distance, distance)); - ARRAY_APPEND(allocator, result.hits, ((struct GVA_Query_Hit) + ARRAY_APPEND(allocator, result.hits, ((GVA_Query_Hit) { .relation = GVA_OVERLAP, .included = included, @@ -586,7 +586,7 @@ gva_index_query(GVA_Allocator const allocator, size_t excluded = 0; GVA_Relation const relation = relation_from_included(included, self->intervals.nodes[node_idx].distance, distance, &excluded); - ARRAY_APPEND(allocator, result.hits, ((struct GVA_Query_Hit) + ARRAY_APPEND(allocator, result.hits, ((GVA_Query_Hit) { .relation = relation, .included = included, @@ -606,7 +606,7 @@ gva_index_query(GVA_Allocator const allocator, size_t excluded = 0; GVA_Relation const relation = relation_from_included(entries[idx].included, self->alleles[entries[idx].gva_key].distance, gva_lcs_graph_distance(graph), &excluded); - ARRAY_APPEND(allocator, result.alleles, ((struct GVA_Query_Allele) + ARRAY_APPEND(allocator, result.alleles, ((GVA_Query_Allele) { .idx = entries[idx].gva_key, .relation = relation, @@ -645,7 +645,7 @@ gva_index_variant(GVA_Index const* const self, } // gva_index_variant -inline gva_uint +inline size_t gva_index_variant_distance(GVA_Index const* const self, size_t const allele_idx, size_t const variant_idx) { diff --git a/src/main.c b/src/main.c index 9c387dd..a0a313c 100644 --- a/src/main.c +++ b/src/main.c @@ -53,8 +53,8 @@ parse_line(char const line[static restrict LINE_SIZE], static int compare_query_alleles(void const* a, void const* b) { - struct GVA_Query_Allele const lhs = *(struct GVA_Query_Allele*) a; - struct GVA_Query_Allele const rhs = *(struct GVA_Query_Allele*) b; + GVA_Query_Allele const lhs = *(GVA_Query_Allele*) a; + GVA_Query_Allele const rhs = *(GVA_Query_Allele*) b; if (lhs.included > rhs.included || (lhs.included == rhs.included && lhs.excluded < rhs.excluded)) From c48db4f20cd6fe28eeac5cc77eb80f2f3248de64 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 26 Mar 2026 10:30:19 +0100 Subject: [PATCH 567/704] Reduce number of allocs in reporting --- src/main.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/src/main.c b/src/main.c index a0a313c..7a9c798 100644 --- a/src/main.c +++ b/src/main.c @@ -23,8 +23,8 @@ #define LINE_SIZE 8194 // #define REFERENCE_ID "NC_000022.11" -// #define REFERENCE_ID "NC_000006.12" -#define REFERENCE_ID "NC_000001.11" +#define REFERENCE_ID "NC_000006.12" +// #define REFERENCE_ID "NC_000001.11" // line: alphanumeric_id SPDI [distance] @@ -70,6 +70,9 @@ report_query_result(GVA_Index const* const index, GVA_LCS_Graph const graph, GVA GVA_Query_Result const result, bool const hits, bool const query_disjoint, bool const index_disjoint) { + gva_uint* join = NULL; + gva_uint* query = NULL; + for (size_t i = 0; i < array_length(result.alleles); ++i) { fprintf(stdout, GVA_STRING_FMT " %s " GVA_STRING_FMT " %u %u %zu\n", @@ -85,12 +88,18 @@ report_query_result(GVA_Index const* const index, GVA_LCS_Graph const graph, GVA result.alleles[i].included, result.alleles[i].excluded, GVA_RELATION_LABELS[result.alleles[i].relation]); - gva_uint* join = NULL; gva_uint prev_join = gva_index_allele_parts(index, result.alleles[i].idx).start; size_t distance_join = 0; - gva_uint* query = NULL; gva_uint prev_query = 0; size_t distance_query = 0; + if (join != NULL) + { + array_header(join)->length = 0; + } // if + if (query != NULL) + { + array_header(query)->length = 0; + } // if for (size_t j = result.alleles[i].hits.start; j < result.alleles[i].hits.end; ++j) { @@ -207,11 +216,11 @@ report_query_result(GVA_Index const* const index, GVA_LCS_Graph const graph, GVA } // for fprintf(stderr, "] 0 %2zu disjoint\n", distance_query); } // if - - join = ARRAY_DESTROY(gva_std_allocator, join); - query = ARRAY_DESTROY(gva_std_allocator, query); } // if } // for + + join = ARRAY_DESTROY(gva_std_allocator, join); + query = ARRAY_DESTROY(gva_std_allocator, query); } // report_query_result From 4900b2adc64a2c305e6a3db253a45993fbc80e34 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 26 Mar 2026 15:19:04 +0100 Subject: [PATCH 568/704] Report query result with variants --- src/main.c | 62 +++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 43 insertions(+), 19 deletions(-) diff --git a/src/main.c b/src/main.c index 7a9c798..a98d204 100644 --- a/src/main.c +++ b/src/main.c @@ -83,8 +83,9 @@ report_query_result(GVA_Index const* const index, GVA_LCS_Graph const graph, GVA if (hits) { - fprintf(stderr, GVA_STRING_FMT ": %u %u %s\n", + fprintf(stderr, GVA_STRING_FMT " " GVA_STRING_FMT " %u %u %s\n", GVA_STRING_PRINT(gva_index_allele_id(index, result.alleles[i].idx)), + GVA_STRING_PRINT(id), result.alleles[i].included, result.alleles[i].excluded, GVA_RELATION_LABELS[result.alleles[i].relation]); @@ -105,7 +106,8 @@ report_query_result(GVA_Index const* const index, GVA_LCS_Graph const graph, GVA { if (result.hits[j].index_parts.end - result.hits[j].index_parts.start > 1) { - fprintf(stderr, " ["); + fprintf(stderr, " " REFERENCE_ID ":["); + size_t sum = 0; for (gva_uint k = result.hits[j].index_parts.start; k < result.hits[j].index_parts.end; ++k) { if (index_disjoint) @@ -117,9 +119,16 @@ report_query_result(GVA_Index const* const index, GVA_LCS_Graph const graph, GVA } // for prev_join = result.parts[k] + 1; } // if - fprintf(stderr, "%2u, ", result.parts[k]); + fprintf(stderr, GVA_VARIANT_FMT_SPDI_ALLELE " (%zu), ", + GVA_VARIANT_PRINT_SPDI_ALLELE(gva_index_variant(index, result.alleles[i].idx, result.parts[k])), + gva_index_variant_distance(index, result.alleles[i].idx, result.parts[k])); + sum += gva_index_variant_distance(index, result.alleles[i].idx, result.parts[k]); } // for - fprintf(stderr, "] %2u %2u %2u %s\n", result.hits[j].query_parts.start, result.hits[j].included, result.hits[j].excluded, GVA_RELATION_LABELS[result.hits[j].relation]); + fprintf(stderr, "] (%zu) " GVA_VARIANT_FMT_SPDI " (%u) %u %u %s\n", + sum, + GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, gva_lcs_graph_local_supremal(graph, result.hits[j].query_parts.start, result.hits[j].query_parts.start + 1)), + graph.dom_nodes[result.hits[j].query_parts.start + 1].distance - graph.dom_nodes[result.hits[j].query_parts.start].distance, + result.hits[j].included, result.hits[j].excluded, GVA_RELATION_LABELS[result.hits[j].relation]); if (query_disjoint) { for (gva_uint k = prev_query; k < result.hits[j].query_parts.start; ++k) @@ -132,7 +141,10 @@ report_query_result(GVA_Index const* const index, GVA_LCS_Graph const graph, GVA } // if else if (result.hits[j].query_parts.end - result.hits[j].query_parts.start > 1) { - fprintf(stderr, " %2u [", result.hits[j].index_parts.start); + fprintf(stderr, " " GVA_VARIANT_FMT_SPDI " (%zu) " REFERENCE_ID ":[", + GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, gva_index_variant(index, result.alleles[i].idx, result.hits[j].index_parts.start)), + gva_index_variant_distance(index, result.alleles[i].idx, result.hits[j].index_parts.start)); + size_t sum = 0; for (gva_uint k = result.hits[j].query_parts.start; k < result.hits[j].query_parts.end; ++k) { if (query_disjoint) @@ -144,9 +156,12 @@ report_query_result(GVA_Index const* const index, GVA_LCS_Graph const graph, GVA distance_query += graph.dom_nodes[result.parts[k]].distance - graph.dom_nodes[prev_query].distance; prev_query = result.parts[k] + 1; } // if - fprintf(stderr, "%2u, ", result.parts[k]); + fprintf(stderr, GVA_VARIANT_FMT_SPDI_ALLELE " (%u), ", + GVA_VARIANT_PRINT_SPDI_ALLELE(gva_lcs_graph_local_supremal(graph, result.parts[k], result.parts[k] + 1)), + graph.dom_nodes[result.parts[k] + 1].distance - graph.dom_nodes[result.parts[k]].distance); + sum += graph.dom_nodes[result.parts[k] + 1].distance - graph.dom_nodes[result.parts[k]].distance; } // for - fprintf(stderr, "] %2u %2u %s\n", result.hits[j].included, result.hits[j].excluded, GVA_RELATION_LABELS[result.hits[j].relation]); + fprintf(stderr, "] (%zu) %u %u %s\n", sum, result.hits[j].included, result.hits[j].excluded, GVA_RELATION_LABELS[result.hits[j].relation]); if (index_disjoint) { for (gva_uint k = prev_join; k < result.hits[j].index_parts.start; ++k) @@ -159,7 +174,12 @@ report_query_result(GVA_Index const* const index, GVA_LCS_Graph const graph, GVA } // if else if (result.hits[j].included > 0) { - fprintf(stderr, " %2u %2u %2u %2u %s\n", result.hits[j].index_parts.start, result.hits[j].query_parts.start, result.hits[j].included, result.hits[j].excluded, GVA_RELATION_LABELS[result.hits[j].relation]); + fprintf(stderr, " " GVA_VARIANT_FMT_SPDI " (%u) " GVA_VARIANT_FMT_SPDI " (%zu) %u %u %s\n", + GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, gva_lcs_graph_local_supremal(graph, result.hits[j].query_parts.start, result.hits[j].query_parts.start + 1)), + graph.dom_nodes[result.hits[j].query_parts.start + 1].distance - graph.dom_nodes[result.hits[j].query_parts.start].distance, + GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, gva_index_variant(index, result.alleles[i].idx, result.hits[j].index_parts.start)), + gva_index_variant_distance(index, result.alleles[i].idx, result.hits[j].index_parts.start), + result.hits[j].included, result.hits[j].excluded, GVA_RELATION_LABELS[result.hits[j].relation]); if (index_disjoint) { for (gva_uint k = prev_join; k < result.hits[j].index_parts.start; ++k) @@ -198,23 +218,27 @@ report_query_result(GVA_Index const* const index, GVA_LCS_Graph const graph, GVA distance_query += graph.dom_nodes[array_length(graph.dom_nodes) - 1].distance - graph.dom_nodes[prev_query].distance; } // if - if (join != NULL) + if (index_disjoint && join != NULL) { - fprintf(stderr, " ["); - for (size_t i = 0; i < array_length(join); ++i) + fprintf(stderr, " " REFERENCE_ID ":["); + for (size_t j = 0; j < array_length(join); ++j) { - fprintf(stderr, "%2u, ", join[i]); + fprintf(stderr, GVA_VARIANT_FMT_SPDI_ALLELE " (%zu), ", + GVA_VARIANT_PRINT_SPDI_ALLELE(gva_index_variant(index, result.alleles[i].idx, join[j])), + gva_index_variant_distance(index, result.alleles[i].idx, join[j])); } // for - fprintf(stderr, "] * 0 %2zu disjoint\n", distance_join); + fprintf(stderr, "] * 0 %zu disjoint\n", distance_join); } // if - if (query != NULL) + if (query_disjoint && query != NULL) { - fprintf(stderr, " * ["); - for (size_t i = 0; i < array_length(query); ++i) + fprintf(stderr, " * " REFERENCE_ID ":["); + for (size_t j = 0; j < array_length(query); ++j) { - fprintf(stderr, "%2u, ", query[i]); + fprintf(stderr, GVA_VARIANT_FMT_SPDI_ALLELE " (%u), ", + GVA_VARIANT_PRINT_SPDI_ALLELE(gva_lcs_graph_local_supremal(graph, query[j], query[j] + 1)), + graph.dom_nodes[query[j] + 1].distance - graph.dom_nodes[query[j]].distance); } // for - fprintf(stderr, "] 0 %2zu disjoint\n", distance_query); + fprintf(stderr, "] 0 %zu disjoint\n", distance_query); } // if } // if } // for @@ -296,7 +320,7 @@ index_main(int argc, char* argv[static argc]) } // if GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &variant); - fprintf(stderr, "\nQuery (" GVA_STRING_FMT "): " GVA_VARIANT_FMT_SPDI " (%zu)\n", GVA_STRING_PRINT(id), GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, gva_lcs_graph_supremal(graph)), gva_lcs_graph_distance(graph)); + //fprintf(stderr, "\nQuery (" GVA_STRING_FMT "): " GVA_VARIANT_FMT_SPDI " (%zu)\n", GVA_STRING_PRINT(id), GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, gva_lcs_graph_supremal(graph)), gva_lcs_graph_distance(graph)); GVA_Query_Result result = gva_index_query(gva_std_allocator, index, graph); if (array_length(result.alleles) > 0) From 3e82ca9a80e9338896bfd1570b1bcc85b7c11bf1 Mon Sep 17 00:00:00 2001 From: jkvis Date: Sun, 29 Mar 2026 15:33:17 +0200 Subject: [PATCH 569/704] FIX: merge graphs correct lambda offset --- src/lcs_graph.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lcs_graph.c b/src/lcs_graph.c index 1c57ce2..f9a4c71 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -51,7 +51,7 @@ merge(GVA_Allocator const allocator, { .match = {rhs.nodes[i].match.row, rhs.nodes[i].match.col + offset, rhs.nodes[i].match.length}, .edges = rhs.nodes[i].edges == GVA_NULL ? GVA_NULL : rhs.nodes[i].edges + offset_edges, - .lambda = rhs.nodes[i].lambda == GVA_NULL ? GVA_NULL : rhs.nodes[i].lambda + offset_nodes, + .lambda = rhs.nodes[i].lambda == GVA_NULL ? GVA_NULL : rhs.nodes[i].lambda + offset_nodes - (rhs.dom_nodes[i].link > rhs.source && sink_idx != GVA_NULL), })); } // if } // for From b895a9def76cd53205956f87cc6dfa3845039c32 Mon Sep 17 00:00:00 2001 From: jkvis Date: Sun, 29 Mar 2026 15:45:00 +0200 Subject: [PATCH 570/704] FIX FIX merge graphs --- src/lcs_graph.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lcs_graph.c b/src/lcs_graph.c index f9a4c71..c61eb38 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -51,7 +51,7 @@ merge(GVA_Allocator const allocator, { .match = {rhs.nodes[i].match.row, rhs.nodes[i].match.col + offset, rhs.nodes[i].match.length}, .edges = rhs.nodes[i].edges == GVA_NULL ? GVA_NULL : rhs.nodes[i].edges + offset_edges, - .lambda = rhs.nodes[i].lambda == GVA_NULL ? GVA_NULL : rhs.nodes[i].lambda + offset_nodes - (rhs.dom_nodes[i].link > rhs.source && sink_idx != GVA_NULL), + .lambda = rhs.nodes[i].lambda == GVA_NULL ? GVA_NULL : rhs.nodes[i].lambda + offset_nodes - (sink_idx != GVA_NULL), })); } // if } // for From bc139c49edeb1a77f9d2097b6b017112dd22572e Mon Sep 17 00:00:00 2001 From: jkvis Date: Sun, 29 Mar 2026 17:43:30 +0200 Subject: [PATCH 571/704] FIX FIX FIX? --- src/lcs_graph.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lcs_graph.c b/src/lcs_graph.c index c61eb38..ca1a89e 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -51,7 +51,7 @@ merge(GVA_Allocator const allocator, { .match = {rhs.nodes[i].match.row, rhs.nodes[i].match.col + offset, rhs.nodes[i].match.length}, .edges = rhs.nodes[i].edges == GVA_NULL ? GVA_NULL : rhs.nodes[i].edges + offset_edges, - .lambda = rhs.nodes[i].lambda == GVA_NULL ? GVA_NULL : rhs.nodes[i].lambda + offset_nodes - (sink_idx != GVA_NULL), + .lambda = rhs.nodes[i].lambda == GVA_NULL ? GVA_NULL : rhs.nodes[i].lambda + offset_nodes - (i > rhs.source), })); } // if } // for From 7e633365d1e4fa8bc2a995e8f264aaf79473cb9d Mon Sep 17 00:00:00 2001 From: jkvis Date: Sun, 29 Mar 2026 21:03:37 +0200 Subject: [PATCH 572/704] This? --- src/lcs_graph.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lcs_graph.c b/src/lcs_graph.c index ca1a89e..07137dc 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -51,7 +51,7 @@ merge(GVA_Allocator const allocator, { .match = {rhs.nodes[i].match.row, rhs.nodes[i].match.col + offset, rhs.nodes[i].match.length}, .edges = rhs.nodes[i].edges == GVA_NULL ? GVA_NULL : rhs.nodes[i].edges + offset_edges, - .lambda = rhs.nodes[i].lambda == GVA_NULL ? GVA_NULL : rhs.nodes[i].lambda + offset_nodes - (i > rhs.source), + .lambda = rhs.nodes[i].lambda == GVA_NULL ? GVA_NULL : rhs.nodes[i].lambda + offset_nodes - (rhs.nodes[i].lambda > rhs.source && sink_idx != GVA_NULL), })); } // if } // for From 12681bb95fc5d405743a5f7999dc45b40f180108 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 2 Apr 2026 17:00:52 +0200 Subject: [PATCH 573/704] Whitespace --- src/edit.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/edit.c b/src/edit.c index 3da7534..8da31c8 100644 --- a/src/edit.c +++ b/src/edit.c @@ -2,7 +2,6 @@ #include // bool, false, true #include // NULL, size_t - #include "../include/allocator.h" // GVA_Allocator #include "../include/edit.h" // gva_edit_distance #include "common.h" // ABS, MAX From 1d8bd419a93605938346fc5091a1df8ad6cb1f26 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 2 Apr 2026 17:01:31 +0200 Subject: [PATCH 574/704] Node number in dot --- src/utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils.c b/src/utils.c index 1c94c62..ca04145 100644 --- a/src/utils.c +++ b/src/utils.c @@ -88,7 +88,7 @@ gva_lcs_graph_dot(FILE* const stream, GVA_LCS_Graph const graph) fprintf(stream, "strict digraph{\nrankdir=LR\nedge[fontname=monospace]\nnode[fixedsize=true,fontname=serif,shape=circle,width=1]\ni[label=\"\",shape=none,width=0]\ni->%u\n", graph.source); for (size_t i = 0; i < array_length(graph.nodes); ++i) { - fprintf(stream, "%zu[label=\"(%u, %u, %u)\"%s]\n", i, graph.nodes[i].match.row, graph.nodes[i].match.col, graph.nodes[i].match.length, graph.nodes[i].edges == GVA_NULL ? ",peripheries=2" : ""); + fprintf(stream, "%zu[label=\"%zu\n(%u, %u, %u)\"%s]\n", i, i, graph.nodes[i].match.row, graph.nodes[i].match.col, graph.nodes[i].match.length, graph.nodes[i].edges == GVA_NULL ? ",peripheries=2" : ""); if (graph.nodes[i].lambda != GVA_NULL) { fprintf(stream, "%zu->%u[label=\"λ\",style=dashed]\n", i, graph.nodes[i].lambda); From 880400ef9635ae64d2c56147d609dad297a615af Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 2 Apr 2026 17:02:12 +0200 Subject: [PATCH 575/704] WIP: overlap --- src/main.c | 273 ++++++++++++++++++++++++++++++++++++++++++- src/priority_queue.c | 142 ++++++++++++++++++++++ src/priority_queue.h | 56 +++++++++ 3 files changed, 466 insertions(+), 5 deletions(-) create mode 100644 src/priority_queue.c create mode 100644 src/priority_queue.h diff --git a/src/main.c b/src/main.c index a98d204..4a60b54 100644 --- a/src/main.c +++ b/src/main.c @@ -5,6 +5,7 @@ #include // EXIT_*, atoll, qsort #include // strerror, strlen +#include "../include/edit.h" // gva_edit_distance #include "../include/index.h" // GVA_Index, gva_index_*, GVA_Query_Result #include "../include/lcs_graph.h" // GVA_LCS_Graph, gva_lcs_graph_* #include "../include/relations.h" // GVA_RELATION_LABELS @@ -15,6 +16,7 @@ #include "align.h" // LCS_Matches, lcs_align_one #include "array.h" // ARRAY_*, array_length #include "common.h" // MAX, MIN +#include "priority_queue.h" // Priority_Queue, priority_queue_* #include @@ -27,6 +29,41 @@ // #define REFERENCE_ID "NC_000001.11" +static void +pq_dot_traverse(Priority_Queue const self, size_t const i, size_t const rhs_length) +{ + size_t const len = array_length(self.heap); + size_t const lhs_idx = self.states[self.heap[i]].gva_key / rhs_length; + size_t const rhs_idx = self.states[self.heap[i]].gva_key % rhs_length; + fprintf(stderr, "%zu[label=\"{%zu, %zu}\\n%u %u\\n%u@%u\"]\n", + i, lhs_idx, rhs_idx, + self.states[self.heap[i]].included, self.states[self.heap[i]].excluded, + self.states[self.heap[i]].gva_key, self.heap[i]); + if (2 * i + 1 < len) + { + fprintf(stderr, "%zu->%zu\n", i, 2 * i + 1); + pq_dot_traverse(self, 2 * i + 1, rhs_length); + if (2 * i + 2 < len) + { + fprintf(stderr, "%zu->%zu\n", i, 2 * i + 2); + pq_dot_traverse(self, 2 * i + 2, rhs_length); + } // if + } // if +} // pq_dot_traverse + + +static inline void +pq_dot(Priority_Queue const self, size_t const rhs_length) +{ + fprintf(stderr, "strict digraph{\nnode[fixedsize=true,shape=circle,width=1]\n"); + if (array_length(self.heap) > 0) + { + pq_dot_traverse(self, 0, rhs_length); + } // if + fprintf(stderr, "}\n"); +} // pq_dot + + // line: alphanumeric_id SPDI [distance] static bool parse_line(char const line[static restrict LINE_SIZE], @@ -75,11 +112,29 @@ report_query_result(GVA_Index const* const index, GVA_LCS_Graph const graph, GVA for (size_t i = 0; i < array_length(result.alleles); ++i) { + + if (result.alleles[i].relation == GVA_OVERLAP && + result.alleles[i].hits.end - result.alleles[i].hits.start > 1) + { + bool overlap = false; + for (size_t j = result.alleles[i].hits.start; j < result.alleles[i].hits.end; ++j) + { + if (result.hits[j].relation == GVA_OVERLAP) + { + overlap = true; + break; + } // if + } // for + if (!overlap) + { fprintf(stdout, GVA_STRING_FMT " %s " GVA_STRING_FMT " %u %u %zu\n", GVA_STRING_PRINT(gva_index_allele_id(index, result.alleles[i].idx)), GVA_RELATION_LABELS[result.alleles[i].relation], GVA_STRING_PRINT(id), result.alleles[i].included, result.alleles[i].excluded, array_length(graph.dom_nodes) - 1); + } // if + } // if + if (hits) { @@ -328,7 +383,7 @@ index_main(int argc, char* argv[static argc]) qsort(result.alleles, array_length(result.alleles), sizeof(*result.alleles), compare_query_alleles); } // if - report_query_result(index, graph, id, result, true, true, true); + report_query_result(index, graph, id, result, false, true, true); result.alleles = ARRAY_DESTROY(gva_std_allocator, result.alleles); result.hits = ARRAY_DESTROY(gva_std_allocator, result.hits); @@ -551,15 +606,14 @@ supremal_main(int argc, char* argv[static argc]) } // if GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &variant); - /* GVA_Variant supremal = gva_lcs_graph_supremal(graph); fprintf(stdout, GVA_STRING_FMT " " GVA_VARIANT_FMT_SPDI " %zu\n", GVA_STRING_PRINT(id), GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, supremal), gva_lcs_graph_distance(graph)); - */ + /* for (size_t i = 0; i < array_length(graph.dom_nodes) - 1; ++i) { fprintf(stdout, GVA_STRING_FMT " " GVA_VARIANT_FMT_SPDI " %u\n", @@ -567,6 +621,7 @@ supremal_main(int argc, char* argv[static argc]) GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, gva_lcs_graph_local_supremal(graph, i, i + 1)), graph.dom_nodes[i + 1].distance - graph.dom_nodes[i].distance); } // for + */ gva_lcs_graph_destroy(gva_std_allocator, graph, true); } // while @@ -577,11 +632,219 @@ supremal_main(int argc, char* argv[static argc]) } // supremal_main +static size_t +variant_included(size_t const lhs_count, GVA_Variant const lhs, + size_t const rhs_count, GVA_Variant const rhs) +{ + if (rhs.start > lhs.end + lhs_count - 1 || lhs.start > rhs.end + rhs_count - 1) + { + return 0; + } // if + + size_t const length = gva_variant_length(lhs) + gva_variant_length(rhs); + + size_t max_included = 0; + for (size_t i = 0; i < lhs_count; ++i) + { + GVA_Variant const lhs_variant = + { + .start = lhs.start + i, + .end = lhs.end + i, + .sequence = {lhs.sequence.len, lhs.sequence.str + i}, + }; + + for (size_t j = 0; j < rhs_count; ++j) + { + GVA_Variant const rhs_variant = + { + .start = rhs.start + j, + .end = rhs.end + j, + .sequence = {rhs.sequence.len, rhs.sequence.str + j}, + }; + + if (rhs_variant.start > lhs_variant.end || lhs_variant.start > rhs_variant.end) + { + continue; + } // if + + size_t const start = MAX(lhs_variant.start, rhs_variant.start); + size_t const end = MIN(lhs_variant.end, rhs_variant.end); + size_t const lcs = (length - gva_edit_distance(gva_std_allocator, lhs_variant.sequence.len, lhs_variant.sequence.str, rhs_variant.sequence.len, rhs_variant.sequence.str)) / 2; + + size_t const included = (end - start) + lcs; + if (included > max_included) + { + max_included = included; + if (included == gva_variant_length(lhs) || included == gva_variant_length(rhs)) + { + return max_included; + } // if + } // if + } // for + } // for + + return max_included; +} // variant_included + + +int +overlap_main(int argc, char* argv[static argc]) +{ + (void) argv; + + size_t line_count = 0; + static char line[LINE_SIZE] = {0}; + while (fgets(line, sizeof(line), stdin) != NULL) + { + line_count += 1; + size_t start = 0; + size_t end = 0; + + end = strcspn(line, "\t "); + GVA_String reference = {end, line + start}; + + start += end + 1; + end = strcspn(line + start, "\t "); + + GVA_Variant lhs_variant = {0}; + if (gva_parse_spdi(end, line + start, &lhs_variant) == 0) + { + fprintf(stderr, "Error parsing LHS SPDI at line %zu: %s", line_count, line); + continue; + } // if + + start += end + 1; + end = strcspn(line + start, "\n\t "); + + GVA_Variant rhs_variant = {0}; + if (gva_parse_spdi(end, line + start, &rhs_variant) == 0) + { + fprintf(stderr, "Error parsing RHS SPDI at line %zu: %s", line_count, line); + continue; + } // if + + GVA_LCS_Graph lhs = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &lhs_variant); + GVA_LCS_Graph rhs = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &rhs_variant); + + static char filename[128] = {0}; + snprintf(filename, 128, "overlap/graph_%zu.dot", line_count); + FILE* stream = fopen(filename, "w"); + gva_lcs_graph_dot(stream, lhs); + gva_lcs_graph_dot(stream, rhs); + fclose(stream); + + Priority_Queue fringe = priority_queue_init(gva_std_allocator, 1024); + priority_queue_update(&fringe, lhs.source * array_length(rhs.nodes) + rhs.source, 0, 0); + pq_dot(fringe, array_length(rhs.nodes)); + + while (!priority_queue_empty(fringe)) + { + State const head = priority_queue_peek(fringe); + priority_queue_remove(&fringe); + + size_t const lhs_idx = head.gva_key / array_length(rhs.nodes); + size_t const rhs_idx = head.gva_key / array_length(rhs.nodes); + fprintf(stderr, "{%zu, %zu} :: %u %u\n", lhs_idx, rhs_idx, head.included, head.excluded); + + for (gva_uint i = lhs.nodes[lhs_idx].edges; i != GVA_NULL; i = lhs.edges[i].next) + { + GVA_Variant lhs_variant = {0}; + size_t const lhs_count = gva_edges(lhs.observed.str, + lhs.nodes[lhs_idx].match, lhs.nodes[lhs.edges[i].tail].match, + lhs_idx == lhs.source, lhs.nodes[lhs.edges[i].tail].edges == GVA_NULL, + &lhs_variant); + + for (gva_uint j = rhs.nodes[rhs_idx].edges; j != GVA_NULL; j = rhs.edges[j].next) + { + GVA_Variant rhs_variant = {0}; + size_t const rhs_count = gva_edges(rhs.observed.str, + rhs.nodes[rhs_idx].match, rhs.nodes[rhs.edges[j].tail].match, + rhs_idx == rhs.source, rhs.nodes[rhs.edges[j].tail].edges == GVA_NULL, + &rhs_variant); + + size_t const included = variant_included(lhs_count, lhs_variant, rhs_count, rhs_variant); + size_t const excluded = gva_variant_length(lhs_variant) + gva_variant_length(rhs_variant) - 2 * included; + + // follow two edges + priority_queue_update(&fringe, lhs.edges[i].tail * array_length(rhs.nodes) + rhs.edges[j].tail, + head.included + included, head.excluded + excluded); + } // for + + // follow only one edge + priority_queue_update(&fringe, lhs.edges[i].tail * array_length(rhs.nodes) + rhs_idx, head.included, head.excluded + gva_variant_length(lhs_variant)); + if (i == lhs.nodes[lhs_idx].edges) + { + for (gva_uint j = rhs.nodes[rhs_idx].edges; j != GVA_NULL; j = rhs.edges[j].next) + { + priority_queue_update(&fringe, lhs_idx * array_length(rhs.nodes) + rhs.edges[j].tail, head.included, head.excluded + gva_variant_length(rhs_variant)); + } // for + } // if + + } // for + pq_dot(fringe, array_length(rhs.nodes)); + break; + + } // while + + + /* + size_t const lhs_idx = heap[0] / array_length(rhs.nodes); + size_t const rhs_idx = heap[0] % array_length(rhs.nodes); + + fprintf(stdout, "%zu[label=\"%zu\\n{%zu,%zu}\\n%u %u\"]\n", heap[0], heap[0], lhs_idx, rhs_idx, states[heap[0]].included, states[heap[0]].excluded); + + for (gva_uint i = lhs.nodes[lhs_idx].edges; i != GVA_NULL; i = lhs.edges[i].next) + { + GVA_Variant lhs_variant = {0}; + size_t const lhs_count = gva_edges(lhs.observed.str, + lhs.nodes[lhs_idx].match, lhs.nodes[lhs.edges[i].tail].match, + lhs_idx == lhs.source, lhs.nodes[lhs.edges[i].tail].edges == GVA_NULL, + &lhs_variant); + + for (gva_uint j = rhs.nodes[rhs_idx].edges; j != GVA_NULL; j = rhs.edges[j].next) + { + GVA_Variant rhs_variant = {0}; + size_t const rhs_count = gva_edges(rhs.observed.str, + rhs.nodes[rhs_idx].match, rhs.nodes[rhs.edges[j].tail].match, + rhs_idx == rhs.source, rhs.nodes[rhs.edges[j].tail].edges == GVA_NULL, + &rhs_variant); + + size_t const included = variant_included(lhs_count, lhs_variant, rhs_count, rhs_variant); + size_t const excluded = gva_variant_length(lhs_variant) + gva_variant_length(rhs_variant) - 2 * included; + + // follow two edges + tail = expand(states, heap, array_length(rhs.nodes), lhs.edges[i].tail, rhs.edges[j].tail, included, excluded, tail); + } // for + + // follow only one edge + tail = expand(states, heap, array_length(rhs.nodes), lhs.edges[i].tail, rhs_idx, 0, gva_variant_length(lhs_variant), tail); + if (i == lhs.nodes[lhs_idx].edges) + { + for (gva_uint j = rhs.nodes[rhs_idx].edges; j != GVA_NULL; j = rhs.edges[j].next) + { + tail = expand(states, heap, array_length(rhs.nodes), lhs_idx, rhs.edges[j].tail, 0, gva_variant_length(lhs_variant), tail); + } // for + } // if + } // for + } // while + */ + + priority_queue_destroy(&fringe); + + gva_lcs_graph_destroy(gva_std_allocator, rhs, true); + gva_lcs_graph_destroy(gva_std_allocator, lhs, true); + } // while + + return EXIT_SUCCESS; +} // overlap_main + + int main(int argc, char* argv[static argc]) { // return allele_main(argc, argv); // return extract_main(argc, argv); - return index_main(argc, argv); - // return supremal_main(argc, argv); + // return index_main(argc, argv); + return overlap_main(argc, argv); + // return dot_main(argc, argv); } // main diff --git a/src/priority_queue.c b/src/priority_queue.c new file mode 100644 index 0000000..49700b6 --- /dev/null +++ b/src/priority_queue.c @@ -0,0 +1,142 @@ +#include // bool +#include // size_t + +#include "../include/allocator.h" // GVA_Allocator +#include "../include/types.h" // GVA_NULL, gva_uint + +#include "array.h" // ARRAY_* +#include "hash_table.h" // HASH_TABLE_*, NOT_FOUND, hash_table_init +#include "priority_queue.h" // Priority_Queue, priority_queue_*, State + + +static inline bool +greater_than(size_t const lhs_included, size_t const lhs_excluded, + size_t const rhs_included, size_t const rhs_excluded) +{ + return lhs_included > rhs_included || + (lhs_included == rhs_included && lhs_excluded < rhs_excluded); +} // greater_than + + +static inline void +swap(gva_uint lhs[static restrict 1], gva_uint rhs[static restrict 1]) +{ + gva_uint const temp = *lhs; + *lhs = *rhs; + *rhs = temp; +} // swap + + +inline Priority_Queue +priority_queue_init(GVA_Allocator const allocator, size_t const capacity) +{ + return (Priority_Queue) + { + .states = hash_table_init(allocator, capacity, sizeof(State)), + .allocator = allocator, + }; +} // priority_queue_init + + +inline void +priority_queue_destroy(Priority_Queue self[static 1]) +{ + self->states = HASH_TABLE_DESTROY(self->allocator, self->states); + self->heap = ARRAY_DESTROY(self->allocator, self->heap); +} // priority_queue_destroy + + +inline bool +priority_queue_empty(Priority_Queue const self) +{ + return array_length(self.heap) == 0; +} // priority_queue_empty + + +inline State +priority_queue_peek(Priority_Queue const self) +{ + return self.states[self.heap[0]]; +} // priority_queue_peek + + +inline void +priority_queue_update(Priority_Queue self[static 1], size_t const key, + size_t const included, size_t const excluded) +{ + size_t i = 0; + + size_t idx = HASH_TABLE_INDEX(self->states, key); + if (self->states[idx].gva_key == NOT_FOUND) + { + HASH_TABLE_SET(self->allocator, self->states, key, + ((State) + { + .gva_key = key, + .included = included, + .excluded = excluded, + })); + idx = HASH_TABLE_INDEX(self->states, key); + i = ARRAY_APPEND(self->allocator, self->heap, idx); + self->states[idx].idx = i; + } // if + else + { + if (greater_than(self->states[idx].included, self->states[idx].excluded, included, excluded)) + { + return; + } // if + self->states[idx].included = included; + self->states[idx].excluded = excluded; + i = self->states[idx].idx; + } // else + + while (i > 0) + { + size_t const parent = (i - 1) / 2; + if (greater_than(self->states[self->heap[parent]].included, self->states[self->heap[parent]].excluded, included, excluded)) + { + break; + } // if + swap(&self->states[self->heap[i]].idx, &self->states[self->heap[parent]].idx); + swap(&self->heap[i], &self->heap[parent]); + i = parent; + } // while +} // priority_queue_update + + +inline void +priority_queue_remove(Priority_Queue self[static 1]) +{ + if (array_length(self->heap) == 0) + { + return; + } // if + + self->states[self->heap[0]].idx = GVA_NULL; + size_t const len = array_header(self->heap)->length -= 1; + self->heap[0] = self->heap[len]; + if (len > 0) + { + self->states[self->heap[0]].idx = 0; + } // if + + size_t i = 0; + while (i < len / 2) + { + size_t child = 2 * i + 1; // left child + if (child + 1 < len && greater_than(self->states[self->heap[child + 1]].included, self->states[self->heap[child + 1]].excluded, + self->states[self->heap[child]].included, self->states[self->heap[child]].excluded)) + { + child += 1; // right child + } // if + if (greater_than(self->states[self->heap[i]].included, self->states[self->heap[i]].excluded, + self->states[self->heap[child]].included, self->states[self->heap[child]].excluded)) + { + break; + } // if + swap(&self->states[self->heap[i]].idx, &self->states[self->heap[child]].idx); + swap(&self->heap[i], &self->heap[child]); + i = child; + } // while +} // priority_queue_remove diff --git a/src/priority_queue.h b/src/priority_queue.h new file mode 100644 index 0000000..0a79e0b --- /dev/null +++ b/src/priority_queue.h @@ -0,0 +1,56 @@ +#ifndef GVA_PRIORITY_QUEUE_H +#define GVA_PRIORITY_QUEUE_H + + +#include // bool +#include // size_t + +#include "../include/allocator.h" // GVA_Allocator +#include "../include/types.h" // gva_uint + +#include "hash_table.h" // HASH_TABLE_KEY + + +typedef struct +{ + HASH_TABLE_KEY; + gva_uint included; + gva_uint excluded; + gva_uint idx; +} State; + + +typedef struct +{ + gva_uint* heap; + State* states; + GVA_Allocator allocator; +} Priority_Queue; + + +Priority_Queue +priority_queue_init(GVA_Allocator const allocator, size_t const capacity); + + +void +priority_queue_destroy(Priority_Queue self[static 1]); + + +bool +priority_queue_empty(Priority_Queue const self); + + +State +priority_queue_peek(Priority_Queue const self); + + +void +priority_queue_update(Priority_Queue self[static 1], size_t const key, + size_t const included, size_t const excluded); + + +void +priority_queue_remove(Priority_Queue self[static 1]); + + +#endif // GVA_PRIORITY_QUEUE_H From 46d143baa191b762333e13df6199ab5fe31892a9 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 2 Apr 2026 17:12:09 +0200 Subject: [PATCH 576/704] WIP: overlap more debug --- src/main.c | 55 +++++++++++------------------------------------------- 1 file changed, 11 insertions(+), 44 deletions(-) diff --git a/src/main.c b/src/main.c index 4a60b54..41c7568 100644 --- a/src/main.c +++ b/src/main.c @@ -771,63 +771,30 @@ overlap_main(int argc, char* argv[static argc]) } // for // follow only one edge - priority_queue_update(&fringe, lhs.edges[i].tail * array_length(rhs.nodes) + rhs_idx, head.included, head.excluded + gva_variant_length(lhs_variant)); + priority_queue_update(&fringe, lhs.edges[i].tail * array_length(rhs.nodes) + rhs_idx, + head.included, head.excluded + gva_variant_length(lhs_variant)); if (i == lhs.nodes[lhs_idx].edges) { for (gva_uint j = rhs.nodes[rhs_idx].edges; j != GVA_NULL; j = rhs.edges[j].next) { - priority_queue_update(&fringe, lhs_idx * array_length(rhs.nodes) + rhs.edges[j].tail, head.included, head.excluded + gva_variant_length(rhs_variant)); + priority_queue_update(&fringe, lhs_idx * array_length(rhs.nodes) + rhs.edges[j].tail, + head.included, head.excluded + gva_variant_length(rhs_variant)); } // for } // if - } // for - pq_dot(fringe, array_length(rhs.nodes)); - break; - - } // while - - /* - size_t const lhs_idx = heap[0] / array_length(rhs.nodes); - size_t const rhs_idx = heap[0] % array_length(rhs.nodes); - - fprintf(stdout, "%zu[label=\"%zu\\n{%zu,%zu}\\n%u %u\"]\n", heap[0], heap[0], lhs_idx, rhs_idx, states[heap[0]].included, states[heap[0]].excluded); - - for (gva_uint i = lhs.nodes[lhs_idx].edges; i != GVA_NULL; i = lhs.edges[i].next) + pq_dot(fringe, array_length(rhs.nodes)); + for (size_t i = 0; i < array_header(fringe.states)->capacity; ++i) { - GVA_Variant lhs_variant = {0}; - size_t const lhs_count = gva_edges(lhs.observed.str, - lhs.nodes[lhs_idx].match, lhs.nodes[lhs.edges[i].tail].match, - lhs_idx == lhs.source, lhs.nodes[lhs.edges[i].tail].edges == GVA_NULL, - &lhs_variant); - - for (gva_uint j = rhs.nodes[rhs_idx].edges; j != GVA_NULL; j = rhs.edges[j].next) - { - GVA_Variant rhs_variant = {0}; - size_t const rhs_count = gva_edges(rhs.observed.str, - rhs.nodes[rhs_idx].match, rhs.nodes[rhs.edges[j].tail].match, - rhs_idx == rhs.source, rhs.nodes[rhs.edges[j].tail].edges == GVA_NULL, - &rhs_variant); - - size_t const included = variant_included(lhs_count, lhs_variant, rhs_count, rhs_variant); - size_t const excluded = gva_variant_length(lhs_variant) + gva_variant_length(rhs_variant) - 2 * included; - - // follow two edges - tail = expand(states, heap, array_length(rhs.nodes), lhs.edges[i].tail, rhs.edges[j].tail, included, excluded, tail); - } // for - - // follow only one edge - tail = expand(states, heap, array_length(rhs.nodes), lhs.edges[i].tail, rhs_idx, 0, gva_variant_length(lhs_variant), tail); - if (i == lhs.nodes[lhs_idx].edges) + if (fringe.states[i].gva_key != NOT_FOUND) { - for (gva_uint j = rhs.nodes[rhs_idx].edges; j != GVA_NULL; j = rhs.edges[j].next) - { - tail = expand(states, heap, array_length(rhs.nodes), lhs_idx, rhs.edges[j].tail, 0, gva_variant_length(lhs_variant), tail); - } // for + size_t const lhs_idx = fringe.states[i].gva_key / array_length(rhs.nodes); + size_t const rhs_idx = fringe.states[i].gva_key % array_length(rhs.nodes); + fprintf(stderr, "%4zu: {%zu, %zu} (%4u) :: %2u %2u %2d\n", i, lhs_idx, rhs_idx, fringe.states[i].gva_key, fringe.states[i].included, fringe.states[i].excluded, fringe.states[i].idx); } // if } // for + break; } // while - */ priority_queue_destroy(&fringe); From 424bb043d0ce827fd9063e00da44bcfd251af1d2 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 2 Apr 2026 17:12:43 +0200 Subject: [PATCH 577/704] WIP: overlap examples --- overlap.txt | 134 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 overlap.txt diff --git a/overlap.txt b/overlap.txt new file mode 100644 index 0000000..96b0f1d --- /dev/null +++ b/overlap.txt @@ -0,0 +1,134 @@ +TCTCTGG ref:0:7:TCTCTGTCTGG ref:0:7:TCTCTGCCTGG +TCTCTGG ref:0:7:TCTCTGTCTGG ref:0:7:TCTCTGCATGG +TCTCTGG ref:0:7:TCTCTGTCTGG ref:0:7:TCTCTGCGTGG +TCTCTGG ref:0:7:TCTCTGTCTGG ref:0:7:TCTCTGCTTGG +TCTCTGG ref:0:7:TCTCTGTCTGG ref:4:3:TGTATGG +TCTCTGG ref:0:7:TCTCTGTCTGG ref:4:3:TGTTTGG +TCTCTGG ref:0:7:TCTCTGTCTGG ref:5:2:GCAGGG +TCTCTGG ref:0:7:TCTCTGTCTGG ref:5:2:GCCAGG +TCTCTGG ref:0:7:TCTCTGTCTGG ref:5:2:GCCGGG +TCTCTGG ref:0:7:TCTCTGTCTGG ref:4:3:TGTCGGG +TCTCTGG ref:0:7:TCTCTGTCTGG ref:4:3:TGTTCGG +TCTCTGG ref:0:7:TCTCTGTCTGG ref:2:5:TTTGTCAGG +TCTCTGG ref:0:7:TCTCTGTCTGG ref:4:3:ATTCGGG +TCTCTGGC ref:0:7:TCTCTGTCTGG ref:6:2:CCGCGG +TCTCTGG ref:0:7:TCTCTGCCTGG ref:0:7:TCTCTGCATGG +TCTCTGG ref:0:7:TCTCTGCCTGG ref:0:7:TCTCTGCGTGG +TCTCTGG ref:0:7:TCTCTGCCTGG ref:0:7:TCTCTGCTTGG +TCTCTGG ref:0:7:TCTCTGCCTGG ref:4:3:TGTATGG +TCTCTGG ref:0:7:TCTCTGCCTGG ref:4:3:TGTTTGG +TCTCTGG ref:0:7:TCTCTGCCTGG ref:5:2:GCAGGG +TCTCTGG ref:0:7:TCTCTGCCTGG ref:5:2:GCCAGG +TCTCTGG ref:0:7:TCTCTGCCTGG ref:5:2:GCCGGG +TCTCTGG ref:0:7:TCTCTGCCTGG ref:4:3:TGTCGGG +TCTCTGG ref:0:7:TCTCTGCCTGG ref:4:3:TGTTCGG +TCTCTGG ref:0:7:TCTCTGCCTGG ref:2:5:TTTGTCAGG +TCTCTGG ref:0:7:TCTCTGCCTGG ref:4:3:ATTCGGG +TCTCTGGC ref:0:7:TCTCTGCCTGG ref:6:2:CCGCGG +TCTCTGG ref:0:7:TCTCTGCATGG ref:0:7:TCTCTGCGTGG +TCTCTGG ref:0:7:TCTCTGCATGG ref:0:7:TCTCTGCTTGG +TCTCTGG ref:0:7:TCTCTGCATGG ref:4:3:TGTATGG +TCTCTGG ref:0:7:TCTCTGCATGG ref:4:3:TGTTTGG +TCTCTGG ref:0:7:TCTCTGCATGG ref:5:2:GCAGGG +TCTCTGG ref:0:7:TCTCTGCATGG ref:5:2:GCCAGG +TCTCTGG ref:0:7:TCTCTGCATGG ref:5:2:GCCGGG +TCTCTGG ref:0:7:TCTCTGCATGG ref:4:3:TGTCGGG +TCTCTGG ref:0:7:TCTCTGCATGG ref:4:3:TGTTCGG +TCTCTGG ref:0:7:TCTCTGCATGG ref:2:5:TTTGTCAGG +TCTCTGG ref:0:7:TCTCTGCATGG ref:4:3:ATTCGGG +TCTCTGGC ref:0:7:TCTCTGCATGG ref:6:2:CCGCGG +TCTCTGG ref:0:7:TCTCTGCGTGG ref:0:7:TCTCTGCTTGG +TCTCTGG ref:0:7:TCTCTGCGTGG ref:4:3:TGTATGG +TCTCTGG ref:0:7:TCTCTGCGTGG ref:4:3:TGTTTGG +TCTCTGG ref:0:7:TCTCTGCGTGG ref:5:2:GCAGGG +TCTCTGG ref:0:7:TCTCTGCGTGG ref:5:2:GCCAGG +TCTCTGG ref:0:7:TCTCTGCGTGG ref:5:2:GCCGGG +TCTCTGG ref:0:7:TCTCTGCGTGG ref:4:3:TGTCGGG +TCTCTGG ref:0:7:TCTCTGCGTGG ref:4:3:TGTTCGG +TCTCTGG ref:0:7:TCTCTGCGTGG ref:2:5:TTTGTCAGG +TCTCTGG ref:0:7:TCTCTGCGTGG ref:4:3:ATTCGGG +TCTCTGGC ref:0:7:TCTCTGCGTGG ref:6:2:CCGCGG +TCTCTGG ref:0:7:TCTCTGCTTGG ref:4:3:TGTATGG +TCTCTGG ref:0:7:TCTCTGCTTGG ref:4:3:TGTTTGG +TCTCTGG ref:0:7:TCTCTGCTTGG ref:5:2:GCAGGG +TCTCTGG ref:0:7:TCTCTGCTTGG ref:5:2:GCCAGG +TCTCTGG ref:0:7:TCTCTGCTTGG ref:5:2:GCCGGG +TCTCTGG ref:0:7:TCTCTGCTTGG ref:4:3:TGTCGGG +TCTCTGG ref:0:7:TCTCTGCTTGG ref:4:3:TGTTCGG +TCTCTGG ref:0:7:TCTCTGCTTGG ref:2:5:TTTGTCAGG +TCTCTGG ref:0:7:TCTCTGCTTGG ref:4:3:ATTCGGG +TCTCTGGC ref:0:7:TCTCTGCTTGG ref:6:2:CCGCGG +TGG ref:0:3:TGTATGG ref:0:3:TGTTTGG +TGG ref:0:3:TGTATGG ref:1:2:GCAGGG +TGG ref:0:3:TGTATGG ref:1:2:GCCAGG +TGG ref:0:3:TGTATGG ref:1:2:GCCGGG +TGG ref:0:3:TGTATGG ref:0:3:TGTCGGG +TGG ref:0:3:TGTATGG ref:0:3:TGTTCGG +TCTGG ref:2:3:TGTATGG ref:0:5:TTTGTCAGG +TGG ref:0:3:TGTATGG ref:0:3:ATTCGGG +TGG ref:0:3:TGTTTGG ref:1:2:GCAGGG +TGG ref:0:3:TGTTTGG ref:1:2:GCCAGG +TGG ref:0:3:TGTTTGG ref:1:2:GCCGGG +TGG ref:0:3:TGTTTGG ref:0:3:TGTCGGG +TGG ref:0:3:TGTTTGG ref:0:3:TGTTCGG +TCTGG ref:2:3:TGTTTGG ref:0:5:TTTGTCAGG +TGG ref:0:3:TGTTTGG ref:0:3:ATTCGGG +GG ref:0:2:GCAGGG ref:0:2:GCCAGG +GG ref:0:2:GCAGGG ref:0:2:GCCGGG +TGG ref:1:2:GCAGGG ref:0:3:TGTCGGG +TGG ref:1:2:GCAGGG ref:0:3:TGTTCGG +TCTGG ref:3:2:GCAGGG ref:0:5:TTTGTCAGG +TGG ref:1:2:GCAGGG ref:0:3:ATTCGGG +GGC ref:0:2:GCAGGG ref:1:2:CCGCGG +GG ref:0:2:GCCAGG ref:0:2:GCCGGG +TGG ref:1:2:GCCAGG ref:0:3:TGTCGGG +TGG ref:1:2:GCCAGG ref:0:3:TGTTCGG +TCTGG ref:3:2:GCCAGG ref:0:5:TTTGTCAGG +TGG ref:1:2:GCCAGG ref:0:3:ATTCGGG +GGC ref:0:2:GCCAGG ref:1:2:CCGCGG +TGG ref:1:2:GCCGGG ref:0:3:TGTCGGG +TGG ref:1:2:GCCGGG ref:0:3:TGTTCGG +TCTGG ref:3:2:GCCGGG ref:0:5:TTTGTCAGG +TGG ref:1:2:GCCGGG ref:0:3:ATTCGGG +GGC ref:0:2:GCCGGG ref:1:2:CCGCGG +TGG ref:0:3:TGTCGGG ref:0:3:TGTTCGG +TCTGG ref:2:3:TGTCGGG ref:0:5:TTTGTCAGG +TGG ref:0:3:TGTCGGG ref:0:3:ATTCGGG +TGGC ref:0:3:TGTCGGG ref:2:2:CCGCGG +TCTGG ref:2:3:TGTTCGG ref:0:5:TTTGTCAGG +TGG ref:0:3:TGTTCGG ref:0:3:ATTCGGG +TGGC ref:0:3:TGTTCGG ref:2:2:CCGCGG +GCAG ref:2:2:AGAGGA ref:0:2:CCGCGG +AGTGGAGG ref:0:2:AGAGGA ref:0:8:AAAGGTTAGCGG +AGTGG ref:0:2:AGAGGA ref:1:4:GCGATTTG +AGTGGA ref:0:2:AGAGGA ref:1:5:GCGATTCCA +TGGAGGAA ref:0:8:TCCCTTTCCCAA ref:0:8:TCTTTCTCCCAA +AGTGGAGGAA ref:2:8:TCCCTTTCCCAA ref:0:8:AAAGGTTAGCGG +GTGGAGGAA ref:1:8:TCCCTTTCCCAA ref:0:4:GCGATTTG +GTGGAGGAA ref:1:8:TCCCTTTCCCAA ref:0:5:GCGATTCCA +TGGAGGAA ref:0:8:TCCCTTTCCCAA ref:0:8:TCCCTGGAGAAA +TGGAGGAA ref:0:8:TCCCTTTCCCAA ref:0:8:TCTCTTGCCCAA +AGTGGAGGAA ref:2:8:TCTTTCTCCCAA ref:0:8:AAAGGTTAGCGG +GTGGAGGAA ref:1:8:TCTTTCTCCCAA ref:0:4:GCGATTTG +GTGGAGGAA ref:1:8:TCTTTCTCCCAA ref:0:5:GCGATTCCA +TGGAGGAA ref:0:8:TCTTTCTCCCAA ref:0:8:TCCCTGGAGAAA +TGGAGGAA ref:0:8:TCTTTCTCCCAA ref:0:6:TCCCTGTCGA +TGGAGGAA ref:0:8:TCTTTCTCCCAA ref:0:8:TCTCTTGCCCAA +TCTGG ref:0:5:TTTGTCAGG ref:2:3:ATTCGGG +TCTGGC ref:0:5:TTTGTCAGG ref:4:2:CCGCGG +AGTGGAGG ref:0:8:AAAGGTTAGCGG ref:1:4:GCGATTTG +AGTGGAGG ref:0:8:AAAGGTTAGCGG ref:1:5:GCGATTCCA +AGTGGAGGAA ref:0:8:AAAGGTTAGCGG ref:2:8:TCCCTGGAGAAA +AGTGGAGG ref:0:8:AAAGGTTAGCGG ref:2:6:TCCCTGTCGA +AGTGGAGGAA ref:0:8:AAAGGTTAGCGG ref:2:8:TCTCTTGCCCAA +GTGGA ref:0:4:GCGATTTG ref:0:5:GCGATTCCA +GTGGAGGAA ref:0:4:GCGATTTG ref:1:8:TCCCTGGAGAAA +GTGGAGG ref:0:4:GCGATTTG ref:1:6:TCCCTGTCGA +GTGGAGGAA ref:0:4:GCGATTTG ref:1:8:TCTCTTGCCCAA +GTGGAGGAA ref:0:5:GCGATTCCA ref:1:8:TCCCTGGAGAAA +GTGGAGG ref:0:5:GCGATTCCA ref:1:6:TCCCTGTCGA +GTGGAGGAA ref:0:5:GCGATTCCA ref:1:8:TCTCTTGCCCAA +TGGAGGAA ref:0:8:TCCCTGGAGAAA ref:0:6:TCCCTGTCGA +TGGAGGAA ref:0:8:TCCCTGGAGAAA ref:0:8:TCTCTTGCCCAA +TGGAGGAA ref:0:6:TCCCTGTCGA ref:0:8:TCTCTTGCCCAA +CCCCACACCCCCAGGTGAG ref:0:19:CAACCCA ref:0:19:CCACCCA From d6f9f44855655e07d95478403910f44d08a06571 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 2 Apr 2026 19:32:26 +0200 Subject: [PATCH 578/704] WIP: overlap: is this correct? --- src/main.c | 15 +-------------- src/priority_queue.c | 3 ++- 2 files changed, 3 insertions(+), 15 deletions(-) diff --git a/src/main.c b/src/main.c index 41c7568..a759f08 100644 --- a/src/main.c +++ b/src/main.c @@ -735,7 +735,6 @@ overlap_main(int argc, char* argv[static argc]) Priority_Queue fringe = priority_queue_init(gva_std_allocator, 1024); priority_queue_update(&fringe, lhs.source * array_length(rhs.nodes) + rhs.source, 0, 0); - pq_dot(fringe, array_length(rhs.nodes)); while (!priority_queue_empty(fringe)) { @@ -743,7 +742,7 @@ overlap_main(int argc, char* argv[static argc]) priority_queue_remove(&fringe); size_t const lhs_idx = head.gva_key / array_length(rhs.nodes); - size_t const rhs_idx = head.gva_key / array_length(rhs.nodes); + size_t const rhs_idx = head.gva_key % array_length(rhs.nodes); fprintf(stderr, "{%zu, %zu} :: %u %u\n", lhs_idx, rhs_idx, head.included, head.excluded); for (gva_uint i = lhs.nodes[lhs_idx].edges; i != GVA_NULL; i = lhs.edges[i].next) @@ -782,18 +781,6 @@ overlap_main(int argc, char* argv[static argc]) } // for } // if } // for - - pq_dot(fringe, array_length(rhs.nodes)); - for (size_t i = 0; i < array_header(fringe.states)->capacity; ++i) - { - if (fringe.states[i].gva_key != NOT_FOUND) - { - size_t const lhs_idx = fringe.states[i].gva_key / array_length(rhs.nodes); - size_t const rhs_idx = fringe.states[i].gva_key % array_length(rhs.nodes); - fprintf(stderr, "%4zu: {%zu, %zu} (%4u) :: %2u %2u %2d\n", i, lhs_idx, rhs_idx, fringe.states[i].gva_key, fringe.states[i].included, fringe.states[i].excluded, fringe.states[i].idx); - } // if - } // for - break; } // while priority_queue_destroy(&fringe); diff --git a/src/priority_queue.c b/src/priority_queue.c index 49700b6..9bd531b 100644 --- a/src/priority_queue.c +++ b/src/priority_queue.c @@ -82,7 +82,8 @@ priority_queue_update(Priority_Queue self[static 1], size_t const key, } // if else { - if (greater_than(self->states[idx].included, self->states[idx].excluded, included, excluded)) + if (self->states[idx].idx == GVA_NULL || + greater_than(self->states[idx].included, self->states[idx].excluded, included, excluded)) { return; } // if From 14961d5185b07703abb1f1fc029a1f79019f5374 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 2 Apr 2026 19:40:12 +0200 Subject: [PATCH 579/704] WIP: overlap: this seems better --- src/priority_queue.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/priority_queue.c b/src/priority_queue.c index 9bd531b..e275851 100644 --- a/src/priority_queue.c +++ b/src/priority_queue.c @@ -14,7 +14,7 @@ greater_than(size_t const lhs_included, size_t const lhs_excluded, size_t const rhs_included, size_t const rhs_excluded) { return lhs_included > rhs_included || - (lhs_included == rhs_included && lhs_excluded < rhs_excluded); + (lhs_included == rhs_included && lhs_excluded <= rhs_excluded); } // greater_than @@ -82,8 +82,7 @@ priority_queue_update(Priority_Queue self[static 1], size_t const key, } // if else { - if (self->states[idx].idx == GVA_NULL || - greater_than(self->states[idx].included, self->states[idx].excluded, included, excluded)) + if (greater_than(self->states[idx].included, self->states[idx].excluded, included, excluded)) { return; } // if From 0c72c68abb88f568a4f943b5810bcd844e6d9ace Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 3 Apr 2026 16:31:50 +0200 Subject: [PATCH 580/704] WIP: overlap: checking/debugging --- src/main.c | 58 +++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 47 insertions(+), 11 deletions(-) diff --git a/src/main.c b/src/main.c index a759f08..a03426d 100644 --- a/src/main.c +++ b/src/main.c @@ -641,8 +641,6 @@ variant_included(size_t const lhs_count, GVA_Variant const lhs, return 0; } // if - size_t const length = gva_variant_length(lhs) + gva_variant_length(rhs); - size_t max_included = 0; for (size_t i = 0; i < lhs_count; ++i) { @@ -669,7 +667,7 @@ variant_included(size_t const lhs_count, GVA_Variant const lhs, size_t const start = MAX(lhs_variant.start, rhs_variant.start); size_t const end = MIN(lhs_variant.end, rhs_variant.end); - size_t const lcs = (length - gva_edit_distance(gva_std_allocator, lhs_variant.sequence.len, lhs_variant.sequence.str, rhs_variant.sequence.len, rhs_variant.sequence.str)) / 2; + size_t const lcs = (lhs_variant.sequence.len + rhs_variant.sequence.len - gva_edit_distance(gva_std_allocator, lhs_variant.sequence.len, lhs_variant.sequence.str, rhs_variant.sequence.len, rhs_variant.sequence.str)) / 2; size_t const included = (end - start) + lcs; if (included > max_included) @@ -733,6 +731,9 @@ overlap_main(int argc, char* argv[static argc]) gva_lcs_graph_dot(stream, rhs); fclose(stream); + fprintf(stderr, "%sdistances lhs: %zu rhs: %zu\n", line, gva_lcs_graph_distance(lhs), gva_lcs_graph_distance(rhs)); + fprintf(stderr, "nodes lhs: %zu rhs %zu\n", array_length(lhs.nodes), array_length(rhs.nodes)); + size_t const distance = gva_lcs_graph_distance(lhs) + gva_lcs_graph_distance(rhs); Priority_Queue fringe = priority_queue_init(gva_std_allocator, 1024); priority_queue_update(&fringe, lhs.source * array_length(rhs.nodes) + rhs.source, 0, 0); @@ -743,7 +744,26 @@ overlap_main(int argc, char* argv[static argc]) size_t const lhs_idx = head.gva_key / array_length(rhs.nodes); size_t const rhs_idx = head.gva_key % array_length(rhs.nodes); - fprintf(stderr, "{%zu, %zu} :: %u %u\n", lhs_idx, rhs_idx, head.included, head.excluded); + + size_t const missing = distance - 2 * head.included - head.excluded; + fprintf(stderr, "{%zu, %zu} :: %u %u %zu\n", lhs_idx, rhs_idx, head.included, head.excluded, missing); + + if (missing == 0) + { + break; + } // if + + if (lhs.nodes[lhs_idx].lambda != GVA_NULL) + { + priority_queue_update(&fringe, lhs.nodes[lhs_idx].lambda * array_length(rhs.nodes) + rhs_idx, + head.included, head.excluded); + } // if + + if (rhs.nodes[rhs_idx].lambda != GVA_NULL) + { + priority_queue_update(&fringe, lhs_idx * array_length(rhs.nodes) + rhs.nodes[rhs_idx].lambda, + head.included, head.excluded); + } // if for (gva_uint i = lhs.nodes[lhs_idx].edges; i != GVA_NULL; i = lhs.edges[i].next) { @@ -763,24 +783,40 @@ overlap_main(int argc, char* argv[static argc]) size_t const included = variant_included(lhs_count, lhs_variant, rhs_count, rhs_variant); size_t const excluded = gva_variant_length(lhs_variant) + gva_variant_length(rhs_variant) - 2 * included; - +/* + fprintf(stderr, "{%u, %u}\n", lhs.edges[i].tail, rhs.edges[j].tail); + fprintf(stderr, GVA_VARIANT_FMT " x %zu (%zu) vs " GVA_VARIANT_FMT " x %zu (%zu)\n", GVA_VARIANT_PRINT(lhs_variant), lhs_count, gva_variant_length(lhs_variant), GVA_VARIANT_PRINT(rhs_variant), rhs_count, gva_variant_length(rhs_variant)); + fprintf(stderr, "+ %zu %zu\n", included, excluded); +*/ // follow two edges priority_queue_update(&fringe, lhs.edges[i].tail * array_length(rhs.nodes) + rhs.edges[j].tail, head.included + included, head.excluded + excluded); + + // follow only one edge + if (i == lhs.nodes[lhs_idx].edges) + { + priority_queue_update(&fringe, lhs_idx * array_length(rhs.nodes) + rhs.edges[j].tail, + head.included, head.excluded + gva_variant_length(rhs_variant)); + } // if } // for // follow only one edge priority_queue_update(&fringe, lhs.edges[i].tail * array_length(rhs.nodes) + rhs_idx, head.included, head.excluded + gva_variant_length(lhs_variant)); - if (i == lhs.nodes[lhs_idx].edges) + } // for + +/* + pq_dot(fringe, array_length(rhs.nodes)); + for (size_t i = 0; i < array_header(fringe.states)->capacity; ++i) + { + if (fringe.states[i].gva_key != NOT_FOUND) { - for (gva_uint j = rhs.nodes[rhs_idx].edges; j != GVA_NULL; j = rhs.edges[j].next) - { - priority_queue_update(&fringe, lhs_idx * array_length(rhs.nodes) + rhs.edges[j].tail, - head.included, head.excluded + gva_variant_length(rhs_variant)); - } // for + size_t const lhs_idx = fringe.states[i].gva_key / array_length(rhs.nodes); + size_t const rhs_idx = fringe.states[i].gva_key % array_length(rhs.nodes); + fprintf(stderr, "%4zu: {%zu, %zu} (%4u) :: %2u %2u %2d\n", i, lhs_idx, rhs_idx, fringe.states[i].gva_key, fringe.states[i].included, fringe.states[i].excluded, fringe.states[i].idx); } // if } // for +*/ } // while priority_queue_destroy(&fringe); From 019f5b157a4bc107580396730eb7d04397c9df87 Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 6 Apr 2026 17:20:17 +0200 Subject: [PATCH 581/704] WIP: overlap --- src/hash_table.c | 19 ++++---- src/hash_table.h | 9 ++-- src/index.c | 4 +- src/main.c | 106 ++++++++++++++++++++----------------------- src/priority_queue.c | 79 ++++++++++++++------------------ src/priority_queue.h | 8 +--- 6 files changed, 102 insertions(+), 123 deletions(-) diff --git a/src/hash_table.c b/src/hash_table.c index 45e02b9..204476d 100644 --- a/src/hash_table.c +++ b/src/hash_table.c @@ -1,8 +1,9 @@ #include // true #include // NULL, size_t -#include // uint32_t, uintmax_t +#include // uintmax_t #include // memcpy +#include "../include/types.h" // GVA_NULL, gva_uint #include "array.h" // ARRAY_DESTROY, Array, array_* #include "hash_table.h" // hash_table_* @@ -13,15 +14,15 @@ hash_table_init(GVA_Allocator const allocator, size_t const capacity, size_t con void* hash_table = array_init(allocator, capacity, item_size); for (size_t i = 0; i < capacity; ++i) { - *(uint32_t*) ((uintmax_t) hash_table + i * item_size) = -1; + *(gva_uint*) ((uintmax_t) hash_table + i * item_size) = GVA_NULL; } // if return hash_table; } // hash_table_init // Jenkins hash -static inline uint32_t -hash(uint32_t key) +static inline gva_uint +hash(gva_uint key) { key = (key + 0x7ed55d16) + (key << 12); key = (key ^ 0xc761c23c) ^ (key >> 19); @@ -34,15 +35,15 @@ hash(uint32_t key) size_t -hash_table_index(void* const self, size_t const item_size, uint32_t const key) +hash_table_index(void* const self, size_t const item_size, size_t const key) { size_t probe = 0; while (true) { // Quadratic probing with c1 and c2 1/2. size_t const idx = (hash(key) + (probe + probe * probe) / 2) % array_header(self)->capacity; - if (*(uint32_t*) ((uintmax_t) self + idx * item_size) == (uint32_t) -1 || - *(uint32_t*) ((uintmax_t) self + idx * item_size) == key) + if (*(gva_uint*) ((uintmax_t) self + idx * item_size) == GVA_NULL || + *(gva_uint*) ((uintmax_t) self + idx * item_size) == key) { return idx; } // if @@ -67,11 +68,11 @@ hash_table_ensure(GVA_Allocator const allocator, void* const self, size_t const for (size_t i = 0; i < old_capacity; ++i) { void const* const src = (void*) ((uintmax_t) self + i * item_size); - if (*(uint32_t*) src != (uint32_t) -1) + if (*(gva_uint*) src != GVA_NULL) { array_header(new_table)->length += 1; memcpy( - (void*) ((uintmax_t) new_table + hash_table_index(new_table, item_size, *(uint32_t*) src) * item_size), + (void*) ((uintmax_t) new_table + hash_table_index(new_table, item_size, *(gva_uint*) src) * item_size), src, item_size); } // if } // for diff --git a/src/hash_table.h b/src/hash_table.h index 865671b..c536398 100644 --- a/src/hash_table.h +++ b/src/hash_table.h @@ -3,16 +3,13 @@ #include // size_t -#include // UINT32_MAX, uint32_t #include "../include/allocator.h" // GVA_Allocator +#include "../include/types.h" // gva_uint #include "array.h" // ARRAY_DESTROY, array_header -#define HASH_TABLE_KEY uint32_t gva_key - - -static uint32_t const NOT_FOUND = UINT32_MAX; +#define HASH_TABLE_KEY gva_uint gva_key void* @@ -20,7 +17,7 @@ hash_table_init(GVA_Allocator const allocator, size_t const capacity, size_t con size_t -hash_table_index(void* const self, size_t const item_size, uint32_t const key); +hash_table_index(void* const self, size_t const item_size, size_t const key); void* diff --git a/src/index.c b/src/index.c index 6689c9c..eb0804f 100644 --- a/src/index.c +++ b/src/index.c @@ -15,7 +15,7 @@ #include "array.h" // ARRAY_*, array_length #include "bitset.h" // bitset_* #include "common.h" // ABS, MAX, MIN -#include "hash_table.h" // NOT_FOUND, HASH_TABLE_*, hash_table_* +#include "hash_table.h" // HASH_TABLE_*, hash_table_* #include "interval_tree.h" // Interval_Tree, interval_tree_* #include "trie.h" // Trie, trie_* @@ -425,7 +425,7 @@ gva_index_query(GVA_Allocator const allocator, // Phase 2 for (size_t idx = 0; idx < array_header(entries)->capacity; ++idx) { - if (entries[idx].gva_key == NOT_FOUND) + if (entries[idx].gva_key == GVA_NULL) { continue; } // if diff --git a/src/main.c b/src/main.c index a03426d..c250438 100644 --- a/src/main.c +++ b/src/main.c @@ -632,56 +632,43 @@ supremal_main(int argc, char* argv[static argc]) } // supremal_main -static size_t +static inline size_t variant_included(size_t const lhs_count, GVA_Variant const lhs, size_t const rhs_count, GVA_Variant const rhs) { - if (rhs.start > lhs.end + lhs_count - 1 || lhs.start > rhs.end + rhs_count - 1) + if (rhs.start > lhs.end + lhs_count - 1 || + lhs.start > rhs.end + rhs_count - 1) { return 0; } // if - size_t max_included = 0; - for (size_t i = 0; i < lhs_count; ++i) + size_t lhs_offset = 0; + size_t rhs_offset = 0; + if (rhs.start > lhs.start) { - GVA_Variant const lhs_variant = - { - .start = lhs.start + i, - .end = lhs.end + i, - .sequence = {lhs.sequence.len, lhs.sequence.str + i}, - }; - - for (size_t j = 0; j < rhs_count; ++j) - { - GVA_Variant const rhs_variant = - { - .start = rhs.start + j, - .end = rhs.end + j, - .sequence = {rhs.sequence.len, rhs.sequence.str + j}, - }; - - if (rhs_variant.start > lhs_variant.end || lhs_variant.start > rhs_variant.end) - { - continue; - } // if + lhs_offset = MIN(rhs.start - lhs.start, lhs_count - 1); + } // if + else if (lhs.start > rhs.start) + { + rhs_offset = MIN(lhs.start - rhs.start, rhs_count - 1); + } // if - size_t const start = MAX(lhs_variant.start, rhs_variant.start); - size_t const end = MIN(lhs_variant.end, rhs_variant.end); - size_t const lcs = (lhs_variant.sequence.len + rhs_variant.sequence.len - gva_edit_distance(gva_std_allocator, lhs_variant.sequence.len, lhs_variant.sequence.str, rhs_variant.sequence.len, rhs_variant.sequence.str)) / 2; + size_t const start = MAX(lhs.start + lhs_offset, rhs.start + rhs_offset); + size_t const end = MIN(lhs.end + lhs_offset, rhs.end + rhs_offset); - size_t const included = (end - start) + lcs; - if (included > max_included) - { - max_included = included; - if (included == gva_variant_length(lhs) || included == gva_variant_length(rhs)) - { - return max_included; - } // if - } // if - } // for - } // for + if (lhs.sequence.len == 0 || rhs.sequence.len == 0) + { + return end - start; + } // if + if (lhs.sequence.len == 1 && rhs.sequence.len == 1) + { + return (lhs.sequence.str[0] == rhs.sequence.str[0]) + end - start; + } // if - return max_included; + size_t const lcs = (lhs.sequence.len + rhs.sequence.len - + gva_edit_distance(gva_std_allocator, lhs.sequence.len, lhs.sequence.str + lhs_offset, + rhs.sequence.len, rhs.sequence.str + rhs_offset)) / 2; + return lcs + end - start; } // variant_included @@ -731,37 +718,43 @@ overlap_main(int argc, char* argv[static argc]) gva_lcs_graph_dot(stream, rhs); fclose(stream); - fprintf(stderr, "%sdistances lhs: %zu rhs: %zu\n", line, gva_lcs_graph_distance(lhs), gva_lcs_graph_distance(rhs)); - fprintf(stderr, "nodes lhs: %zu rhs %zu\n", array_length(lhs.nodes), array_length(rhs.nodes)); + fprintf(stderr, "%sdistances lhs: %zu rhs: %zu :: ", line, gva_lcs_graph_distance(lhs), gva_lcs_graph_distance(rhs)); + { + size_t const distance = gva_edit_distance(gva_std_allocator, + gva_lcs_graph_supremal(lhs).sequence.len, gva_lcs_graph_supremal(lhs).sequence.str, + gva_lcs_graph_supremal(rhs).sequence.len, gva_lcs_graph_supremal(rhs).sequence.str); + fprintf(stderr, "%zu\n", distance); + } // empty + fprintf(stderr, "nodes lhs: %zu rhs %zu :: %zu\n", array_length(lhs.nodes), array_length(rhs.nodes), array_length(lhs.nodes) * array_length(rhs.nodes)); + size_t const distance = gva_lcs_graph_distance(lhs) + gva_lcs_graph_distance(rhs); Priority_Queue fringe = priority_queue_init(gva_std_allocator, 1024); - priority_queue_update(&fringe, lhs.source * array_length(rhs.nodes) + rhs.source, 0, 0); + priority_queue_push(&fringe, lhs.source * array_length(rhs.nodes) + rhs.source, 0, 0); + size_t steps = 0; while (!priority_queue_empty(fringe)) { - State const head = priority_queue_peek(fringe); - priority_queue_remove(&fringe); + steps += 1; + State const head = priority_queue_pop(&fringe); size_t const lhs_idx = head.gva_key / array_length(rhs.nodes); size_t const rhs_idx = head.gva_key % array_length(rhs.nodes); - size_t const missing = distance - 2 * head.included - head.excluded; - fprintf(stderr, "{%zu, %zu} :: %u %u %zu\n", lhs_idx, rhs_idx, head.included, head.excluded, missing); - - if (missing == 0) + fprintf(stderr, "{%zu, %zu} :: %u %u %zu\n", lhs_idx, rhs_idx, head.included, head.excluded, distance - 2 * head.included - head.excluded); + if (distance - 2 * head.included - head.excluded == 0) { break; } // if if (lhs.nodes[lhs_idx].lambda != GVA_NULL) { - priority_queue_update(&fringe, lhs.nodes[lhs_idx].lambda * array_length(rhs.nodes) + rhs_idx, + priority_queue_push(&fringe, lhs.nodes[lhs_idx].lambda * array_length(rhs.nodes) + rhs_idx, head.included, head.excluded); } // if if (rhs.nodes[rhs_idx].lambda != GVA_NULL) { - priority_queue_update(&fringe, lhs_idx * array_length(rhs.nodes) + rhs.nodes[rhs_idx].lambda, + priority_queue_push(&fringe, lhs_idx * array_length(rhs.nodes) + rhs.nodes[rhs_idx].lambda, head.included, head.excluded); } // if @@ -783,28 +776,28 @@ overlap_main(int argc, char* argv[static argc]) size_t const included = variant_included(lhs_count, lhs_variant, rhs_count, rhs_variant); size_t const excluded = gva_variant_length(lhs_variant) + gva_variant_length(rhs_variant) - 2 * included; + /* - fprintf(stderr, "{%u, %u}\n", lhs.edges[i].tail, rhs.edges[j].tail); - fprintf(stderr, GVA_VARIANT_FMT " x %zu (%zu) vs " GVA_VARIANT_FMT " x %zu (%zu)\n", GVA_VARIANT_PRINT(lhs_variant), lhs_count, gva_variant_length(lhs_variant), GVA_VARIANT_PRINT(rhs_variant), rhs_count, gva_variant_length(rhs_variant)); + fprintf(stderr, " {%u, %u} ", lhs.edges[i].tail, rhs.edges[j].tail); + fprintf(stderr, GVA_VARIANT_FMT " x %zu (%zu) vs " GVA_VARIANT_FMT " x %zu (%zu) ", GVA_VARIANT_PRINT(lhs_variant), lhs_count, gva_variant_length(lhs_variant), GVA_VARIANT_PRINT(rhs_variant), rhs_count, gva_variant_length(rhs_variant)); fprintf(stderr, "+ %zu %zu\n", included, excluded); */ // follow two edges - priority_queue_update(&fringe, lhs.edges[i].tail * array_length(rhs.nodes) + rhs.edges[j].tail, + priority_queue_push(&fringe, lhs.edges[i].tail * array_length(rhs.nodes) + rhs.edges[j].tail, head.included + included, head.excluded + excluded); // follow only one edge if (i == lhs.nodes[lhs_idx].edges) { - priority_queue_update(&fringe, lhs_idx * array_length(rhs.nodes) + rhs.edges[j].tail, + priority_queue_push(&fringe, lhs_idx * array_length(rhs.nodes) + rhs.edges[j].tail, head.included, head.excluded + gva_variant_length(rhs_variant)); } // if } // for // follow only one edge - priority_queue_update(&fringe, lhs.edges[i].tail * array_length(rhs.nodes) + rhs_idx, + priority_queue_push(&fringe, lhs.edges[i].tail * array_length(rhs.nodes) + rhs_idx, head.included, head.excluded + gva_variant_length(lhs_variant)); } // for - /* pq_dot(fringe, array_length(rhs.nodes)); for (size_t i = 0; i < array_header(fringe.states)->capacity; ++i) @@ -818,6 +811,7 @@ overlap_main(int argc, char* argv[static argc]) } // for */ } // while + fprintf(stderr, "steps: %zu\nin queue: %zu\n", steps, array_length(fringe.heap)); priority_queue_destroy(&fringe); diff --git a/src/priority_queue.c b/src/priority_queue.c index e275851..e9f5f70 100644 --- a/src/priority_queue.c +++ b/src/priority_queue.c @@ -5,7 +5,7 @@ #include "../include/types.h" // GVA_NULL, gva_uint #include "array.h" // ARRAY_* -#include "hash_table.h" // HASH_TABLE_*, NOT_FOUND, hash_table_init +#include "hash_table.h" // HASH_TABLE_*, hash_table_init #include "priority_queue.h" // Priority_Queue, priority_queue_*, State @@ -54,20 +54,48 @@ priority_queue_empty(Priority_Queue const self) inline State -priority_queue_peek(Priority_Queue const self) +priority_queue_pop(Priority_Queue self[static 1]) { - return self.states[self.heap[0]]; -} // priority_queue_peek + size_t const idx = self->heap[0]; + self->states[self->heap[0]].idx = GVA_NULL; + size_t const len = array_header(self->heap)->length -= 1; + self->heap[0] = self->heap[len]; + if (len > 0) + { + self->states[self->heap[0]].idx = 0; + } // if + + size_t i = 0; + while (i < len / 2) + { + size_t child = 2 * i + 1; // left child + if (child + 1 < len && greater_than(self->states[self->heap[child + 1]].included, self->states[self->heap[child + 1]].excluded, + self->states[self->heap[child]].included, self->states[self->heap[child]].excluded)) + { + child += 1; // right child + } // if + if (greater_than(self->states[self->heap[i]].included, self->states[self->heap[i]].excluded, + self->states[self->heap[child]].included, self->states[self->heap[child]].excluded)) + { + break; + } // if + swap(&self->states[self->heap[i]].idx, &self->states[self->heap[child]].idx); + swap(&self->heap[i], &self->heap[child]); + i = child; + } // while + + return self->states[idx]; +} // priority_queue_pop inline void -priority_queue_update(Priority_Queue self[static 1], size_t const key, +priority_queue_push(Priority_Queue self[static 1], size_t const key, size_t const included, size_t const excluded) { size_t i = 0; size_t idx = HASH_TABLE_INDEX(self->states, key); - if (self->states[idx].gva_key == NOT_FOUND) + if (self->states[idx].gva_key == GVA_NULL) { HASH_TABLE_SET(self->allocator, self->states, key, ((State) @@ -102,41 +130,4 @@ priority_queue_update(Priority_Queue self[static 1], size_t const key, swap(&self->heap[i], &self->heap[parent]); i = parent; } // while -} // priority_queue_update - - -inline void -priority_queue_remove(Priority_Queue self[static 1]) -{ - if (array_length(self->heap) == 0) - { - return; - } // if - - self->states[self->heap[0]].idx = GVA_NULL; - size_t const len = array_header(self->heap)->length -= 1; - self->heap[0] = self->heap[len]; - if (len > 0) - { - self->states[self->heap[0]].idx = 0; - } // if - - size_t i = 0; - while (i < len / 2) - { - size_t child = 2 * i + 1; // left child - if (child + 1 < len && greater_than(self->states[self->heap[child + 1]].included, self->states[self->heap[child + 1]].excluded, - self->states[self->heap[child]].included, self->states[self->heap[child]].excluded)) - { - child += 1; // right child - } // if - if (greater_than(self->states[self->heap[i]].included, self->states[self->heap[i]].excluded, - self->states[self->heap[child]].included, self->states[self->heap[child]].excluded)) - { - break; - } // if - swap(&self->states[self->heap[i]].idx, &self->states[self->heap[child]].idx); - swap(&self->heap[i], &self->heap[child]); - i = child; - } // while -} // priority_queue_remove +} // priority_queue_push diff --git a/src/priority_queue.h b/src/priority_queue.h index 0a79e0b..2148975 100644 --- a/src/priority_queue.h +++ b/src/priority_queue.h @@ -41,16 +41,12 @@ priority_queue_empty(Priority_Queue const self); State -priority_queue_peek(Priority_Queue const self); +priority_queue_pop(Priority_Queue self[static 1]); void -priority_queue_update(Priority_Queue self[static 1], size_t const key, +priority_queue_push(Priority_Queue self[static 1], size_t const key, size_t const included, size_t const excluded); -void -priority_queue_remove(Priority_Queue self[static 1]); - - #endif // GVA_PRIORITY_QUEUE_H From 13cdb72745af973ff8894132d91b5ca2c9f35cd7 Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 6 Apr 2026 18:57:02 +0200 Subject: [PATCH 582/704] Some interface inconsistencies --- include/lcs_graph.h | 6 +++--- src/lcs_graph.c | 14 +++++++------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/include/lcs_graph.h b/include/lcs_graph.h index 3e88a85..c265849 100644 --- a/include/lcs_graph.h +++ b/include/lcs_graph.h @@ -79,8 +79,8 @@ gva_lcs_graph_from_variants(GVA_Allocator const allocator, void gva_lcs_graph_uniq_atomics(GVA_LCS_Graph const self, - gva_uint const offset, - gva_uint const start, gva_uint const end, + size_t const offset, + size_t const start, size_t const end, size_t dels[static restrict 1], size_t as[static restrict 1], size_t cs[static restrict 1], @@ -101,7 +101,7 @@ GVA_Variant gva_lcs_graph_supremal(GVA_LCS_Graph const self); -gva_uint +size_t gva_edges(char const observed[static restrict 1], GVA_Match const head, GVA_Match const tail, bool const is_source, bool const is_sink, diff --git a/src/lcs_graph.c b/src/lcs_graph.c index 07137dc..4e45ede 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -16,7 +16,7 @@ static void -merge(GVA_Allocator const allocator, +concat(GVA_Allocator const allocator, GVA_LCS_Graph lhs[static 1], GVA_LCS_Graph const rhs, size_t const offset) { @@ -76,7 +76,7 @@ merge(GVA_Allocator const allocator, .link = rhs.dom_nodes[i].link + offset_nodes - (rhs.dom_nodes[i].link > rhs.source && sink_idx != GVA_NULL), })); } // for -} // merge +} // concat // FIXME: recursion! @@ -90,7 +90,7 @@ local_supremal(GVA_Allocator const allocator, if (len_ref == 0 || len_obs == 0) { GVA_LCS_Graph local = gva_lcs_graph_init(allocator, len_ref, reference, len_obs, observed, offset_row); - merge(allocator, graph, local, offset_col); + concat(allocator, graph, local, offset_col); gva_lcs_graph_destroy(allocator, local, false); return; } // if @@ -133,7 +133,7 @@ local_supremal(GVA_Allocator const allocator, { sum += distance; GVA_LCS_Graph local = gva_lcs_graph_init(allocator, len_ref - prev_row - 1, reference + prev_row + 1, len_obs - prev_col - 1, observed + prev_col + 1, offset_row + prev_row + 1); - merge(allocator, graph, local, offset_col + prev_col + 1); + concat(allocator, graph, local, offset_col + prev_col + 1); gva_lcs_graph_destroy(allocator, local, false); } // if @@ -556,8 +556,8 @@ nucleotides(size_t const len, char const sequence[static len]) void gva_lcs_graph_uniq_atomics(GVA_LCS_Graph const self, - gva_uint const offset, - gva_uint const start, gva_uint const end, + size_t const offset, + size_t const start, size_t const end, size_t dels[static restrict 1], size_t as[static restrict 1], size_t cs[static restrict 1], @@ -638,7 +638,7 @@ gva_lcs_graph_supremal(GVA_LCS_Graph const self) } // gva_lcs_graph_supremal -gva_uint +inline size_t gva_edges(char const observed[static restrict 1], GVA_Match const head, GVA_Match const tail, bool const is_source, bool const is_sink, From d2c973227f302f30537d6b74242ff189ba28d11f Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 8 Apr 2026 10:59:32 +0200 Subject: [PATCH 583/704] Larger deletions --- overlap.txt | 1 + src/main.c | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/overlap.txt b/overlap.txt index 96b0f1d..9d4dd99 100644 --- a/overlap.txt +++ b/overlap.txt @@ -132,3 +132,4 @@ TGGAGGAA ref:0:8:TCCCTGGAGAAA ref:0:6:TCCCTGTCGA TGGAGGAA ref:0:8:TCCCTGGAGAAA ref:0:8:TCTCTTGCCCAA TGGAGGAA ref:0:6:TCCCTGTCGA ref:0:8:TCTCTTGCCCAA CCCCACACCCCCAGGTGAG ref:0:19:CAACCCA ref:0:19:CCACCCA +CCGAGGGGCGAGAGGTCACCACTGCCATAGAGAGGCGGCCACCACTGCCATCGGAGGGGGGGG ref:13:50:GGTCACCACTGCCATCGGAGGGGGGGG ref:0:45:CCGAGGGGCGAGAGGCCACCAC diff --git a/src/main.c b/src/main.c index c250438..464af7c 100644 --- a/src/main.c +++ b/src/main.c @@ -728,7 +728,7 @@ overlap_main(int argc, char* argv[static argc]) fprintf(stderr, "nodes lhs: %zu rhs %zu :: %zu\n", array_length(lhs.nodes), array_length(rhs.nodes), array_length(lhs.nodes) * array_length(rhs.nodes)); size_t const distance = gva_lcs_graph_distance(lhs) + gva_lcs_graph_distance(rhs); - Priority_Queue fringe = priority_queue_init(gva_std_allocator, 1024); + Priority_Queue fringe = priority_queue_init(gva_std_allocator, 2 * array_length(lhs.nodes) * array_length(rhs.nodes) + 1); priority_queue_push(&fringe, lhs.source * array_length(rhs.nodes) + rhs.source, 0, 0); size_t steps = 0; @@ -776,7 +776,6 @@ overlap_main(int argc, char* argv[static argc]) size_t const included = variant_included(lhs_count, lhs_variant, rhs_count, rhs_variant); size_t const excluded = gva_variant_length(lhs_variant) + gva_variant_length(rhs_variant) - 2 * included; - /* fprintf(stderr, " {%u, %u} ", lhs.edges[i].tail, rhs.edges[j].tail); fprintf(stderr, GVA_VARIANT_FMT " x %zu (%zu) vs " GVA_VARIANT_FMT " x %zu (%zu) ", GVA_VARIANT_PRINT(lhs_variant), lhs_count, gva_variant_length(lhs_variant), GVA_VARIANT_PRINT(rhs_variant), rhs_count, gva_variant_length(rhs_variant)); From bb869950dc31395f08e0609c8f6e10676c0920d1 Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 8 Apr 2026 22:19:56 +0200 Subject: [PATCH 584/704] WIP: overlap removed hash table from priority queue --- src/main.c | 42 +++++++++++++++++++----------------- src/priority_queue.c | 51 ++++++++++++++++++++++++-------------------- src/priority_queue.h | 8 +++---- 3 files changed, 53 insertions(+), 48 deletions(-) diff --git a/src/main.c b/src/main.c index 464af7c..83a371c 100644 --- a/src/main.c +++ b/src/main.c @@ -33,12 +33,12 @@ static void pq_dot_traverse(Priority_Queue const self, size_t const i, size_t const rhs_length) { size_t const len = array_length(self.heap); - size_t const lhs_idx = self.states[self.heap[i]].gva_key / rhs_length; - size_t const rhs_idx = self.states[self.heap[i]].gva_key % rhs_length; - fprintf(stderr, "%zu[label=\"{%zu, %zu}\\n%u %u\\n%u@%u\"]\n", + size_t const lhs_idx = self.heap[i] / rhs_length; + size_t const rhs_idx = self.heap[i] % rhs_length; + fprintf(stderr, "%zu[label=\"{%zu, %zu}\\n%u %u\\n%u\"]\n", i, lhs_idx, rhs_idx, self.states[self.heap[i]].included, self.states[self.heap[i]].excluded, - self.states[self.heap[i]].gva_key, self.heap[i]); + self.heap[i]); if (2 * i + 1 < len) { fprintf(stderr, "%zu->%zu\n", i, 2 * i + 1); @@ -728,20 +728,20 @@ overlap_main(int argc, char* argv[static argc]) fprintf(stderr, "nodes lhs: %zu rhs %zu :: %zu\n", array_length(lhs.nodes), array_length(rhs.nodes), array_length(lhs.nodes) * array_length(rhs.nodes)); size_t const distance = gva_lcs_graph_distance(lhs) + gva_lcs_graph_distance(rhs); - Priority_Queue fringe = priority_queue_init(gva_std_allocator, 2 * array_length(lhs.nodes) * array_length(rhs.nodes) + 1); + Priority_Queue fringe = priority_queue_init(gva_std_allocator, array_length(lhs.nodes) * array_length(rhs.nodes)); priority_queue_push(&fringe, lhs.source * array_length(rhs.nodes) + rhs.source, 0, 0); size_t steps = 0; while (!priority_queue_empty(fringe)) { steps += 1; - State const head = priority_queue_pop(&fringe); + size_t const head = priority_queue_pop(&fringe); - size_t const lhs_idx = head.gva_key / array_length(rhs.nodes); - size_t const rhs_idx = head.gva_key % array_length(rhs.nodes); + size_t const lhs_idx = head / array_length(rhs.nodes); + size_t const rhs_idx = head % array_length(rhs.nodes); - fprintf(stderr, "{%zu, %zu} :: %u %u %zu\n", lhs_idx, rhs_idx, head.included, head.excluded, distance - 2 * head.included - head.excluded); - if (distance - 2 * head.included - head.excluded == 0) + fprintf(stderr, "{%zu, %zu} :: %u %u %zu\n", lhs_idx, rhs_idx, fringe.states[head].included, fringe.states[head].excluded, distance - 2 * fringe.states[head].included - fringe.states[head].excluded); + if (distance - 2 * fringe.states[head].included - fringe.states[head].excluded == 0) { break; } // if @@ -749,13 +749,13 @@ overlap_main(int argc, char* argv[static argc]) if (lhs.nodes[lhs_idx].lambda != GVA_NULL) { priority_queue_push(&fringe, lhs.nodes[lhs_idx].lambda * array_length(rhs.nodes) + rhs_idx, - head.included, head.excluded); + fringe.states[head].included, fringe.states[head].excluded); } // if if (rhs.nodes[rhs_idx].lambda != GVA_NULL) { priority_queue_push(&fringe, lhs_idx * array_length(rhs.nodes) + rhs.nodes[rhs_idx].lambda, - head.included, head.excluded); + fringe.states[head].included, fringe.states[head].excluded); } // if for (gva_uint i = lhs.nodes[lhs_idx].edges; i != GVA_NULL; i = lhs.edges[i].next) @@ -776,36 +776,38 @@ overlap_main(int argc, char* argv[static argc]) size_t const included = variant_included(lhs_count, lhs_variant, rhs_count, rhs_variant); size_t const excluded = gva_variant_length(lhs_variant) + gva_variant_length(rhs_variant) - 2 * included; + /* fprintf(stderr, " {%u, %u} ", lhs.edges[i].tail, rhs.edges[j].tail); fprintf(stderr, GVA_VARIANT_FMT " x %zu (%zu) vs " GVA_VARIANT_FMT " x %zu (%zu) ", GVA_VARIANT_PRINT(lhs_variant), lhs_count, gva_variant_length(lhs_variant), GVA_VARIANT_PRINT(rhs_variant), rhs_count, gva_variant_length(rhs_variant)); fprintf(stderr, "+ %zu %zu\n", included, excluded); */ + // follow two edges priority_queue_push(&fringe, lhs.edges[i].tail * array_length(rhs.nodes) + rhs.edges[j].tail, - head.included + included, head.excluded + excluded); + fringe.states[head].included + included, fringe.states[head].excluded + excluded); // follow only one edge if (i == lhs.nodes[lhs_idx].edges) { priority_queue_push(&fringe, lhs_idx * array_length(rhs.nodes) + rhs.edges[j].tail, - head.included, head.excluded + gva_variant_length(rhs_variant)); + fringe.states[head].included, fringe.states[head].excluded + gva_variant_length(rhs_variant)); } // if } // for // follow only one edge priority_queue_push(&fringe, lhs.edges[i].tail * array_length(rhs.nodes) + rhs_idx, - head.included, head.excluded + gva_variant_length(lhs_variant)); + fringe.states[head].included, fringe.states[head].excluded + gva_variant_length(lhs_variant)); } // for /* pq_dot(fringe, array_length(rhs.nodes)); - for (size_t i = 0; i < array_header(fringe.states)->capacity; ++i) + for (size_t i = 0; i < fringe.capacity; ++i) { - if (fringe.states[i].gva_key != NOT_FOUND) + if (fringe.states[i].idx != GVA_NULL) { - size_t const lhs_idx = fringe.states[i].gva_key / array_length(rhs.nodes); - size_t const rhs_idx = fringe.states[i].gva_key % array_length(rhs.nodes); - fprintf(stderr, "%4zu: {%zu, %zu} (%4u) :: %2u %2u %2d\n", i, lhs_idx, rhs_idx, fringe.states[i].gva_key, fringe.states[i].included, fringe.states[i].excluded, fringe.states[i].idx); + size_t const lhs_idx = i / array_length(rhs.nodes); + size_t const rhs_idx = i % array_length(rhs.nodes); + fprintf(stderr, "%4zu: {%zu, %zu} :: %2u %2u %2d\n", i, lhs_idx, rhs_idx, fringe.states[i].included, fringe.states[i].excluded, fringe.states[i].idx); } // if } // for */ diff --git a/src/priority_queue.c b/src/priority_queue.c index e9f5f70..25d48c8 100644 --- a/src/priority_queue.c +++ b/src/priority_queue.c @@ -5,7 +5,6 @@ #include "../include/types.h" // GVA_NULL, gva_uint #include "array.h" // ARRAY_* -#include "hash_table.h" // HASH_TABLE_*, hash_table_init #include "priority_queue.h" // Priority_Queue, priority_queue_*, State @@ -30,9 +29,21 @@ swap(gva_uint lhs[static restrict 1], gva_uint rhs[static restrict 1]) inline Priority_Queue priority_queue_init(GVA_Allocator const allocator, size_t const capacity) { + State* const states = allocator.allocate(allocator.context, NULL, 0, capacity * sizeof(*states)); + if (states == NULL) + { + return (Priority_Queue) {NULL}; + } // if + + for (size_t i = 0; i < capacity; ++i) + { + states[i].idx = GVA_NULL; + } // for + return (Priority_Queue) { - .states = hash_table_init(allocator, capacity, sizeof(State)), + .states = states, + .capacity = capacity, .allocator = allocator, }; } // priority_queue_init @@ -41,8 +52,9 @@ priority_queue_init(GVA_Allocator const allocator, size_t const capacity) inline void priority_queue_destroy(Priority_Queue self[static 1]) { - self->states = HASH_TABLE_DESTROY(self->allocator, self->states); self->heap = ARRAY_DESTROY(self->allocator, self->heap); + self->states = self->allocator.allocate(self->allocator.context, self->states, self->capacity * sizeof(State), 0); + self->capacity = 0; } // priority_queue_destroy @@ -53,7 +65,7 @@ priority_queue_empty(Priority_Queue const self) } // priority_queue_empty -inline State +inline size_t priority_queue_pop(Priority_Queue self[static 1]) { size_t const idx = self->heap[0]; @@ -84,7 +96,7 @@ priority_queue_pop(Priority_Queue self[static 1]) i = child; } // while - return self->states[idx]; + return idx; } // priority_queue_pop @@ -92,33 +104,26 @@ inline void priority_queue_push(Priority_Queue self[static 1], size_t const key, size_t const included, size_t const excluded) { - size_t i = 0; - - size_t idx = HASH_TABLE_INDEX(self->states, key); - if (self->states[idx].gva_key == GVA_NULL) + if (self->states[key].idx == GVA_NULL) { - HASH_TABLE_SET(self->allocator, self->states, key, - ((State) - { - .gva_key = key, - .included = included, - .excluded = excluded, - })); - idx = HASH_TABLE_INDEX(self->states, key); - i = ARRAY_APPEND(self->allocator, self->heap, idx); - self->states[idx].idx = i; + self->states[key] = (State) + { + .idx = ARRAY_APPEND(self->allocator, self->heap, key), + .included = included, + .excluded = excluded, + }; } // if else { - if (greater_than(self->states[idx].included, self->states[idx].excluded, included, excluded)) + if (greater_than(self->states[key].included, self->states[key].excluded, included, excluded)) { return; } // if - self->states[idx].included = included; - self->states[idx].excluded = excluded; - i = self->states[idx].idx; + self->states[key].included = included; + self->states[key].excluded = excluded; } // else + size_t i = self->states[key].idx; while (i > 0) { size_t const parent = (i - 1) / 2; diff --git a/src/priority_queue.h b/src/priority_queue.h index 2148975..1ac0761 100644 --- a/src/priority_queue.h +++ b/src/priority_queue.h @@ -8,15 +8,12 @@ #include "../include/allocator.h" // GVA_Allocator #include "../include/types.h" // gva_uint -#include "hash_table.h" // HASH_TABLE_KEY - typedef struct { - HASH_TABLE_KEY; + gva_uint idx; gva_uint included; gva_uint excluded; - gva_uint idx; } State; @@ -24,6 +21,7 @@ typedef struct { gva_uint* heap; State* states; + size_t capacity; GVA_Allocator allocator; } Priority_Queue; @@ -40,7 +38,7 @@ bool priority_queue_empty(Priority_Queue const self); -State +size_t priority_queue_pop(Priority_Queue self[static 1]); From c86ec63ac452a6e5e2e1c2dccd2a8503909ec75b Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 9 Apr 2026 07:43:00 +0200 Subject: [PATCH 585/704] WIP: overlap: single steps first --- src/main.c | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/src/main.c b/src/main.c index 83a371c..2bf139c 100644 --- a/src/main.c +++ b/src/main.c @@ -725,7 +725,8 @@ overlap_main(int argc, char* argv[static argc]) gva_lcs_graph_supremal(rhs).sequence.len, gva_lcs_graph_supremal(rhs).sequence.str); fprintf(stderr, "%zu\n", distance); } // empty - fprintf(stderr, "nodes lhs: %zu rhs %zu :: %zu\n", array_length(lhs.nodes), array_length(rhs.nodes), array_length(lhs.nodes) * array_length(rhs.nodes)); + fprintf(stderr, "#nodes lhs: %zu rhs %zu :: %zu\n", array_length(lhs.nodes), array_length(rhs.nodes), array_length(lhs.nodes) * array_length(rhs.nodes)); + fprintf(stderr, "#edges lhs: %zu rhs %zu :: %zu\n", array_length(lhs.edges), array_length(rhs.edges), array_length(lhs.edges) * array_length(rhs.edges)); size_t const distance = gva_lcs_graph_distance(lhs) + gva_lcs_graph_distance(rhs); Priority_Queue fringe = priority_queue_init(gva_std_allocator, array_length(lhs.nodes) * array_length(rhs.nodes)); @@ -751,12 +752,30 @@ overlap_main(int argc, char* argv[static argc]) priority_queue_push(&fringe, lhs.nodes[lhs_idx].lambda * array_length(rhs.nodes) + rhs_idx, fringe.states[head].included, fringe.states[head].excluded); } // if + for (gva_uint i = lhs.nodes[lhs_idx].edges; i != GVA_NULL; i = lhs.edges[i].next) + { + GVA_Variant lhs_variant = {0}; + gva_edges(lhs.observed.str, lhs.nodes[lhs_idx].match, lhs.nodes[lhs.edges[i].tail].match, + lhs_idx == lhs.source, lhs.nodes[lhs.edges[i].tail].edges == GVA_NULL, + &lhs_variant); + priority_queue_push(&fringe, lhs.edges[i].tail * array_length(rhs.nodes) + rhs_idx, + fringe.states[head].included, fringe.states[head].excluded + gva_variant_length(lhs_variant)); + } // for if (rhs.nodes[rhs_idx].lambda != GVA_NULL) { priority_queue_push(&fringe, lhs_idx * array_length(rhs.nodes) + rhs.nodes[rhs_idx].lambda, fringe.states[head].included, fringe.states[head].excluded); } // if + for (gva_uint i = rhs.nodes[rhs_idx].edges; i != GVA_NULL; i = rhs.edges[i].next) + { + GVA_Variant rhs_variant = {0}; + gva_edges(rhs.observed.str, rhs.nodes[rhs_idx].match, rhs.nodes[rhs.edges[i].tail].match, + rhs_idx == rhs.source, rhs.nodes[rhs.edges[i].tail].edges == GVA_NULL, + &rhs_variant); + priority_queue_push(&fringe, lhs_idx * array_length(rhs.nodes) + rhs.edges[i].tail, + fringe.states[head].included, fringe.states[head].excluded + gva_variant_length(rhs_variant)); + } // for for (gva_uint i = lhs.nodes[lhs_idx].edges; i != GVA_NULL; i = lhs.edges[i].next) { @@ -776,28 +795,15 @@ overlap_main(int argc, char* argv[static argc]) size_t const included = variant_included(lhs_count, lhs_variant, rhs_count, rhs_variant); size_t const excluded = gva_variant_length(lhs_variant) + gva_variant_length(rhs_variant) - 2 * included; - /* fprintf(stderr, " {%u, %u} ", lhs.edges[i].tail, rhs.edges[j].tail); fprintf(stderr, GVA_VARIANT_FMT " x %zu (%zu) vs " GVA_VARIANT_FMT " x %zu (%zu) ", GVA_VARIANT_PRINT(lhs_variant), lhs_count, gva_variant_length(lhs_variant), GVA_VARIANT_PRINT(rhs_variant), rhs_count, gva_variant_length(rhs_variant)); fprintf(stderr, "+ %zu %zu\n", included, excluded); */ - // follow two edges priority_queue_push(&fringe, lhs.edges[i].tail * array_length(rhs.nodes) + rhs.edges[j].tail, fringe.states[head].included + included, fringe.states[head].excluded + excluded); - - // follow only one edge - if (i == lhs.nodes[lhs_idx].edges) - { - priority_queue_push(&fringe, lhs_idx * array_length(rhs.nodes) + rhs.edges[j].tail, - fringe.states[head].included, fringe.states[head].excluded + gva_variant_length(rhs_variant)); - } // if } // for - - // follow only one edge - priority_queue_push(&fringe, lhs.edges[i].tail * array_length(rhs.nodes) + rhs_idx, - fringe.states[head].included, fringe.states[head].excluded + gva_variant_length(lhs_variant)); } // for /* pq_dot(fringe, array_length(rhs.nodes)); From c585f16e38f9857027de67534cd774b265b2a347 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 9 Apr 2026 22:09:00 +0200 Subject: [PATCH 586/704] WIP: overlap is sync with Python --- src/main.c | 28 +++++++++++++++------------- src/priority_queue.c | 23 ++++++++++++----------- 2 files changed, 27 insertions(+), 24 deletions(-) diff --git a/src/main.c b/src/main.c index 2bf139c..8575df4 100644 --- a/src/main.c +++ b/src/main.c @@ -35,7 +35,7 @@ pq_dot_traverse(Priority_Queue const self, size_t const i, size_t const rhs_leng size_t const len = array_length(self.heap); size_t const lhs_idx = self.heap[i] / rhs_length; size_t const rhs_idx = self.heap[i] % rhs_length; - fprintf(stderr, "%zu[label=\"{%zu, %zu}\\n%u %u\\n%u\"]\n", + fprintf(stderr, "%zu[label=\"{%zu, %zu}\\n%u %u\\n %u\"]\n", i, lhs_idx, rhs_idx, self.states[self.heap[i]].included, self.states[self.heap[i]].excluded, self.heap[i]); @@ -736,21 +736,23 @@ overlap_main(int argc, char* argv[static argc]) while (!priority_queue_empty(fringe)) { steps += 1; - size_t const head = priority_queue_pop(&fringe); + size_t const idx = priority_queue_pop(&fringe); - size_t const lhs_idx = head / array_length(rhs.nodes); - size_t const rhs_idx = head % array_length(rhs.nodes); + size_t const lhs_idx = idx / array_length(rhs.nodes); + size_t const rhs_idx = idx % array_length(rhs.nodes); - fprintf(stderr, "{%zu, %zu} :: %u %u %zu\n", lhs_idx, rhs_idx, fringe.states[head].included, fringe.states[head].excluded, distance - 2 * fringe.states[head].included - fringe.states[head].excluded); - if (distance - 2 * fringe.states[head].included - fringe.states[head].excluded == 0) + fprintf(stderr, "{%zu, %zu} (%zu) :: %u %u\n", lhs_idx, rhs_idx, idx, + fringe.states[idx].included, fringe.states[idx].excluded); + if (distance == 2 * fringe.states[idx].included + fringe.states[idx].excluded) { + fprintf(stdout, "%u\n", fringe.states[idx].included); break; } // if if (lhs.nodes[lhs_idx].lambda != GVA_NULL) { priority_queue_push(&fringe, lhs.nodes[lhs_idx].lambda * array_length(rhs.nodes) + rhs_idx, - fringe.states[head].included, fringe.states[head].excluded); + fringe.states[idx].included, fringe.states[idx].excluded); } // if for (gva_uint i = lhs.nodes[lhs_idx].edges; i != GVA_NULL; i = lhs.edges[i].next) { @@ -759,13 +761,13 @@ overlap_main(int argc, char* argv[static argc]) lhs_idx == lhs.source, lhs.nodes[lhs.edges[i].tail].edges == GVA_NULL, &lhs_variant); priority_queue_push(&fringe, lhs.edges[i].tail * array_length(rhs.nodes) + rhs_idx, - fringe.states[head].included, fringe.states[head].excluded + gva_variant_length(lhs_variant)); + fringe.states[idx].included, fringe.states[idx].excluded + gva_variant_length(lhs_variant)); } // for if (rhs.nodes[rhs_idx].lambda != GVA_NULL) { priority_queue_push(&fringe, lhs_idx * array_length(rhs.nodes) + rhs.nodes[rhs_idx].lambda, - fringe.states[head].included, fringe.states[head].excluded); + fringe.states[idx].included, fringe.states[idx].excluded); } // if for (gva_uint i = rhs.nodes[rhs_idx].edges; i != GVA_NULL; i = rhs.edges[i].next) { @@ -774,7 +776,7 @@ overlap_main(int argc, char* argv[static argc]) rhs_idx == rhs.source, rhs.nodes[rhs.edges[i].tail].edges == GVA_NULL, &rhs_variant); priority_queue_push(&fringe, lhs_idx * array_length(rhs.nodes) + rhs.edges[i].tail, - fringe.states[head].included, fringe.states[head].excluded + gva_variant_length(rhs_variant)); + fringe.states[idx].included, fringe.states[idx].excluded + gva_variant_length(rhs_variant)); } // for for (gva_uint i = lhs.nodes[lhs_idx].edges; i != GVA_NULL; i = lhs.edges[i].next) @@ -800,9 +802,8 @@ overlap_main(int argc, char* argv[static argc]) fprintf(stderr, GVA_VARIANT_FMT " x %zu (%zu) vs " GVA_VARIANT_FMT " x %zu (%zu) ", GVA_VARIANT_PRINT(lhs_variant), lhs_count, gva_variant_length(lhs_variant), GVA_VARIANT_PRINT(rhs_variant), rhs_count, gva_variant_length(rhs_variant)); fprintf(stderr, "+ %zu %zu\n", included, excluded); */ - priority_queue_push(&fringe, lhs.edges[i].tail * array_length(rhs.nodes) + rhs.edges[j].tail, - fringe.states[head].included + included, fringe.states[head].excluded + excluded); + fringe.states[idx].included + included, fringe.states[idx].excluded + excluded); } // for } // for /* @@ -813,7 +814,8 @@ overlap_main(int argc, char* argv[static argc]) { size_t const lhs_idx = i / array_length(rhs.nodes); size_t const rhs_idx = i % array_length(rhs.nodes); - fprintf(stderr, "%4zu: {%zu, %zu} :: %2u %2u %2d\n", i, lhs_idx, rhs_idx, fringe.states[i].included, fringe.states[i].excluded, fringe.states[i].idx); + fprintf(stderr, "%4zu: {%zu, %zu} :: %2u %2u %2d\n", i, lhs_idx, rhs_idx, + fringe.states[i].included, fringe.states[i].excluded, fringe.states[i].idx); } // if } // for */ diff --git a/src/priority_queue.c b/src/priority_queue.c index 25d48c8..e75669f 100644 --- a/src/priority_queue.c +++ b/src/priority_queue.c @@ -9,12 +9,12 @@ static inline bool -greater_than(size_t const lhs_included, size_t const lhs_excluded, +less_than(size_t const lhs_included, size_t const lhs_excluded, size_t const rhs_included, size_t const rhs_excluded) { - return lhs_included > rhs_included || - (lhs_included == rhs_included && lhs_excluded <= rhs_excluded); -} // greater_than + return lhs_excluded < rhs_excluded || + (lhs_excluded == rhs_excluded && lhs_included >= rhs_included); +} // less_than static inline void @@ -69,7 +69,7 @@ inline size_t priority_queue_pop(Priority_Queue self[static 1]) { size_t const idx = self->heap[0]; - self->states[self->heap[0]].idx = GVA_NULL; + self->states[self->heap[0]].idx = array_length(self->heap); size_t const len = array_header(self->heap)->length -= 1; self->heap[0] = self->heap[len]; if (len > 0) @@ -81,13 +81,14 @@ priority_queue_pop(Priority_Queue self[static 1]) while (i < len / 2) { size_t child = 2 * i + 1; // left child - if (child + 1 < len && greater_than(self->states[self->heap[child + 1]].included, self->states[self->heap[child + 1]].excluded, - self->states[self->heap[child]].included, self->states[self->heap[child]].excluded)) + if (child + 1 < len && + less_than(self->states[self->heap[child + 1]].included, self->states[self->heap[child + 1]].excluded, + self->states[self->heap[child]].included, self->states[self->heap[child]].excluded)) { child += 1; // right child } // if - if (greater_than(self->states[self->heap[i]].included, self->states[self->heap[i]].excluded, - self->states[self->heap[child]].included, self->states[self->heap[child]].excluded)) + if (less_than(self->states[self->heap[i]].included, self->states[self->heap[i]].excluded, + self->states[self->heap[child]].included, self->states[self->heap[child]].excluded)) { break; } // if @@ -115,7 +116,7 @@ priority_queue_push(Priority_Queue self[static 1], size_t const key, } // if else { - if (greater_than(self->states[key].included, self->states[key].excluded, included, excluded)) + if (less_than(self->states[key].included, self->states[key].excluded, included, excluded)) { return; } // if @@ -127,7 +128,7 @@ priority_queue_push(Priority_Queue self[static 1], size_t const key, while (i > 0) { size_t const parent = (i - 1) / 2; - if (greater_than(self->states[self->heap[parent]].included, self->states[self->heap[parent]].excluded, included, excluded)) + if (less_than(self->states[self->heap[parent]].included, self->states[self->heap[parent]].excluded, included, excluded)) { break; } // if From 407b48f9dc997511e3cba296c79ed4e5fd083134 Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 10 Apr 2026 00:06:26 +0200 Subject: [PATCH 587/704] WIP: overlap: slightly better --- src/main.c | 63 +++++++++++++++++++++++++++--------------------------- 1 file changed, 31 insertions(+), 32 deletions(-) diff --git a/src/main.c b/src/main.c index 8575df4..9da4a31 100644 --- a/src/main.c +++ b/src/main.c @@ -745,40 +745,10 @@ overlap_main(int argc, char* argv[static argc]) fringe.states[idx].included, fringe.states[idx].excluded); if (distance == 2 * fringe.states[idx].included + fringe.states[idx].excluded) { - fprintf(stdout, "%u\n", fringe.states[idx].included); + fprintf(stdout, "%u %zu %zu\n", fringe.states[idx].included, steps, array_length(fringe.heap)); break; } // if - if (lhs.nodes[lhs_idx].lambda != GVA_NULL) - { - priority_queue_push(&fringe, lhs.nodes[lhs_idx].lambda * array_length(rhs.nodes) + rhs_idx, - fringe.states[idx].included, fringe.states[idx].excluded); - } // if - for (gva_uint i = lhs.nodes[lhs_idx].edges; i != GVA_NULL; i = lhs.edges[i].next) - { - GVA_Variant lhs_variant = {0}; - gva_edges(lhs.observed.str, lhs.nodes[lhs_idx].match, lhs.nodes[lhs.edges[i].tail].match, - lhs_idx == lhs.source, lhs.nodes[lhs.edges[i].tail].edges == GVA_NULL, - &lhs_variant); - priority_queue_push(&fringe, lhs.edges[i].tail * array_length(rhs.nodes) + rhs_idx, - fringe.states[idx].included, fringe.states[idx].excluded + gva_variant_length(lhs_variant)); - } // for - - if (rhs.nodes[rhs_idx].lambda != GVA_NULL) - { - priority_queue_push(&fringe, lhs_idx * array_length(rhs.nodes) + rhs.nodes[rhs_idx].lambda, - fringe.states[idx].included, fringe.states[idx].excluded); - } // if - for (gva_uint i = rhs.nodes[rhs_idx].edges; i != GVA_NULL; i = rhs.edges[i].next) - { - GVA_Variant rhs_variant = {0}; - gva_edges(rhs.observed.str, rhs.nodes[rhs_idx].match, rhs.nodes[rhs.edges[i].tail].match, - rhs_idx == rhs.source, rhs.nodes[rhs.edges[i].tail].edges == GVA_NULL, - &rhs_variant); - priority_queue_push(&fringe, lhs_idx * array_length(rhs.nodes) + rhs.edges[i].tail, - fringe.states[idx].included, fringe.states[idx].excluded + gva_variant_length(rhs_variant)); - } // for - for (gva_uint i = lhs.nodes[lhs_idx].edges; i != GVA_NULL; i = lhs.edges[i].next) { GVA_Variant lhs_variant = {0}; @@ -806,6 +776,36 @@ overlap_main(int argc, char* argv[static argc]) fringe.states[idx].included + included, fringe.states[idx].excluded + excluded); } // for } // for + + if (lhs.nodes[lhs_idx].lambda != GVA_NULL) + { + priority_queue_push(&fringe, lhs.nodes[lhs_idx].lambda * array_length(rhs.nodes) + rhs_idx, + fringe.states[idx].included, fringe.states[idx].excluded); + } // if + if (rhs.nodes[rhs_idx].lambda != GVA_NULL) + { + priority_queue_push(&fringe, lhs_idx * array_length(rhs.nodes) + rhs.nodes[rhs_idx].lambda, + fringe.states[idx].included, fringe.states[idx].excluded); + } // if + + for (gva_uint i = lhs.nodes[lhs_idx].edges; i != GVA_NULL; i = lhs.edges[i].next) + { + GVA_Variant lhs_variant = {0}; + gva_edges(lhs.observed.str, lhs.nodes[lhs_idx].match, lhs.nodes[lhs.edges[i].tail].match, + lhs_idx == lhs.source, lhs.nodes[lhs.edges[i].tail].edges == GVA_NULL, + &lhs_variant); + priority_queue_push(&fringe, lhs.edges[i].tail * array_length(rhs.nodes) + rhs_idx, + fringe.states[idx].included, fringe.states[idx].excluded + gva_variant_length(lhs_variant)); + } // for + for (gva_uint i = rhs.nodes[rhs_idx].edges; i != GVA_NULL; i = rhs.edges[i].next) + { + GVA_Variant rhs_variant = {0}; + gva_edges(rhs.observed.str, rhs.nodes[rhs_idx].match, rhs.nodes[rhs.edges[i].tail].match, + rhs_idx == rhs.source, rhs.nodes[rhs.edges[i].tail].edges == GVA_NULL, + &rhs_variant); + priority_queue_push(&fringe, lhs_idx * array_length(rhs.nodes) + rhs.edges[i].tail, + fringe.states[idx].included, fringe.states[idx].excluded + gva_variant_length(rhs_variant)); + } // for /* pq_dot(fringe, array_length(rhs.nodes)); for (size_t i = 0; i < fringe.capacity; ++i) @@ -820,7 +820,6 @@ overlap_main(int argc, char* argv[static argc]) } // for */ } // while - fprintf(stderr, "steps: %zu\nin queue: %zu\n", steps, array_length(fringe.heap)); priority_queue_destroy(&fringe); From e3408e242f1846b756f74d35682a6433cd144da7 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 16 Apr 2026 11:17:14 +0200 Subject: [PATCH 588/704] Docs --- src/array.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/array.h b/src/array.h index 29be138..b26c302 100644 --- a/src/array.h +++ b/src/array.h @@ -64,8 +64,8 @@ array_ensure(GVA_Allocator const allocator, void* const self, ) -// Adds an element at the end of the array. Returns the new length of the -// array. -1 if (re)allocation failed. +// Adds an element at the end of the array. Returns the index of the new +// element. -1 if (re)allocation failed. // Warning: `self` is evaluated multiple times. #define ARRAY_APPEND(allocator, self, value) ( \ (self) = array_ensure((allocator), (self), sizeof(*(self)), 1), \ From bca21ebb108ee2b45eead757efc66d5cbe5f23e4 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 16 Apr 2026 11:17:53 +0200 Subject: [PATCH 589/704] Newline in dot --- src/utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils.c b/src/utils.c index ca04145..8e0f6e2 100644 --- a/src/utils.c +++ b/src/utils.c @@ -88,7 +88,7 @@ gva_lcs_graph_dot(FILE* const stream, GVA_LCS_Graph const graph) fprintf(stream, "strict digraph{\nrankdir=LR\nedge[fontname=monospace]\nnode[fixedsize=true,fontname=serif,shape=circle,width=1]\ni[label=\"\",shape=none,width=0]\ni->%u\n", graph.source); for (size_t i = 0; i < array_length(graph.nodes); ++i) { - fprintf(stream, "%zu[label=\"%zu\n(%u, %u, %u)\"%s]\n", i, i, graph.nodes[i].match.row, graph.nodes[i].match.col, graph.nodes[i].match.length, graph.nodes[i].edges == GVA_NULL ? ",peripheries=2" : ""); + fprintf(stream, "%zu[label=\"%zu\\n(%u, %u, %u)\"%s]\n", i, i, graph.nodes[i].match.row, graph.nodes[i].match.col, graph.nodes[i].match.length, graph.nodes[i].edges == GVA_NULL ? ",peripheries=2" : ""); if (graph.nodes[i].lambda != GVA_NULL) { fprintf(stream, "%zu->%u[label=\"λ\",style=dashed]\n", i, graph.nodes[i].lambda); From ff8c8c2acf316bcec29fad840fb8cad742d4afd6 Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 17 Apr 2026 09:53:54 +0200 Subject: [PATCH 590/704] Added NFA construction --- src/nfa.c | 134 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/nfa.h | 44 ++++++++++++++++++ 2 files changed, 178 insertions(+) create mode 100644 src/nfa.c create mode 100644 src/nfa.h diff --git a/src/nfa.c b/src/nfa.c new file mode 100644 index 0000000..420d481 --- /dev/null +++ b/src/nfa.c @@ -0,0 +1,134 @@ +#include // size_t +#include // stderr, fprintf FIXME: DEBUG + +#include "../include/allocator.h" // GVA_Allocator +#include "../include/lcs_graph.h" // GVA_LCS_Graph, gva_edges +#include "../include/types.h" // GVA_NULL, gva_uint +#include "../include/variant.h" // GVA_Variant +#include "array.h" // ARRAY_*, array_length +#include "nfa.h" // NFA*, nfa_* + + +static void +nfa_edge(GVA_Allocator const allocator, + NFA self[static 1], GVA_Variant const variant) +{ + for (size_t i = variant.start; i <= variant.end; ++i) + { + for (size_t j = 0; j <= variant.sequence.len; ++j) + { + size_t const tail = ARRAY_APPEND(allocator, self->states, GVA_NULL); + if (i > variant.start) + { + size_t const head = tail - variant.sequence.len - 1; + self->states[head] = ARRAY_APPEND(allocator, self->transitions, + ((NFA_Transition) + { + .symbol = NFA_DELETE, + .tail = tail, + .next = self->states[head], + })); + } // if + if (j > 0) + { + size_t const head = tail - 1; + self->states[head] = ARRAY_APPEND(allocator, self->transitions, + ((NFA_Transition) + { + .symbol = variant.sequence.str[j - 1], + .tail = tail, + .next = self->states[head], + })); + } // if + } // for + } // for +} // nfa_edge + + +NFA +nfa_from_lcs_graph(GVA_Allocator const allocator, GVA_LCS_Graph const graph) +{ + NFA nfa = {.source = graph.source}; + for (size_t i = 0; i < array_length(graph.nodes); ++i) + { + size_t const idx = ARRAY_APPEND(allocator, nfa.states, GVA_NULL); + if (graph.nodes[i].edges == GVA_NULL) + { + nfa.sink = idx; + } // if + } // for + + for (size_t i = 0; i < array_length(graph.nodes); ++i) + { + for (gva_uint j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) + { + GVA_Variant variant = {0}; + size_t const count = gva_edges(graph.observed.str, + graph.nodes[i].match, graph.nodes[graph.edges[j].tail].match, + i == graph.source, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, + &variant); + for (size_t k = 0; k < count; ++k) + { + nfa.states[i] = ARRAY_APPEND(allocator, nfa.transitions, + ((NFA_Transition) + { + .symbol = NFA_LAMBDA, + .tail = array_length(nfa.states), + .next = nfa.states[i], + })); + nfa_edge(allocator, &nfa, + (GVA_Variant) + { + .start = variant.start + k, + .end = variant.end + k, + .sequence.len = variant.sequence.len, + .sequence.str = variant.sequence.str + k, + }); + size_t const head = array_length(nfa.states) - 1; + nfa.states[head] = ARRAY_APPEND(allocator, nfa.transitions, + ((NFA_Transition) + { + .symbol = NFA_LAMBDA, + .tail = graph.edges[j].tail, + .next = nfa.states[head], + })); + } // for + } // for + } // for + + return nfa; +} // nfa_from_lcs_graph + + +inline void +nfa_destroy(GVA_Allocator const allocator, NFA self[static 1]) +{ + self->transitions = ARRAY_DESTROY(allocator, self->transitions); + self->states = ARRAY_DESTROY(allocator, self->states); +} // nfa_destroy + + +void +nfa_dot(NFA const self) +{ + fprintf(stderr, "strict digraph{\nrankdir=LR\nnode[fixedsize=true,label=\"\",shape=circle,width=1]\ni[shape=none,width=0]\ni->%u\n", self.source); + for (size_t i = 0; i < array_length(self.states); ++i) + { + for (gva_uint j = self.states[i]; j != GVA_NULL; j = self.transitions[j].next) + { + if (self.transitions[j].symbol == NFA_DELETE) + { + fprintf(stderr, "%zu->%u[label=\"Δ\"]\n", i, self.transitions[j].tail); + } // if + else if (self.transitions[j].symbol == NFA_LAMBDA) + { + fprintf(stderr, "%zu->%u[label=\"λ\"]\n", i, self.transitions[j].tail); + } // if + else + { + fprintf(stderr, "%zu->%u[label=\"%c\"]\n", i, self.transitions[j].tail, self.transitions[j].symbol); + } // else + } // for + } // for + fprintf(stderr, "%u[peripheries=2]\n}\n", self.sink); +} // nfa_dot diff --git a/src/nfa.h b/src/nfa.h new file mode 100644 index 0000000..5562781 --- /dev/null +++ b/src/nfa.h @@ -0,0 +1,44 @@ +#ifndef GVA_NFA_H +#define GVA_NFA_H + + +#include "../include/allocator.h" // GVA_Allocator +#include "../include/lcs_graph.h" // GVA_LCS_Graph +#include "../include/types.h" // gva_uint + + +static char const NFA_DELETE = 127; +static char const NFA_LAMBDA = (char) 235; + + +typedef struct +{ + char symbol; + gva_uint tail; + gva_uint next; +} NFA_Transition; + + +typedef struct +{ + gva_uint* states; + NFA_Transition* transitions; + gva_uint source; + gva_uint sink; +} NFA; + + +NFA +nfa_from_lcs_graph(GVA_Allocator const allocator, GVA_LCS_Graph const graph); + + +void +nfa_destroy(GVA_Allocator const allocator, NFA self[static 1]); + + +// FIXME: DEBUG +void +nfa_dot(NFA const self); + + +#endif // GVA_NFA_H From c9931bda0704981a9ea361daf5b86e7506cd108a Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 17 Apr 2026 09:56:11 +0200 Subject: [PATCH 591/704] dbSNP all to all --- src/main.c | 312 ++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 275 insertions(+), 37 deletions(-) diff --git a/src/main.c b/src/main.c index 9da4a31..03892a0 100644 --- a/src/main.c +++ b/src/main.c @@ -15,8 +15,10 @@ #include "../include/variant.h" // GVA_VARIANT_*, GVA_Variant, gva_parse_spdi, gva_variant_* #include "align.h" // LCS_Matches, lcs_align_one #include "array.h" // ARRAY_*, array_length +#include "bitset.h" // bitset_* #include "common.h" // MAX, MIN #include "priority_queue.h" // Priority_Queue, priority_queue_* +#include "trie.h" // Trie, trie_* #include @@ -25,43 +27,8 @@ #define LINE_SIZE 8194 // #define REFERENCE_ID "NC_000022.11" -#define REFERENCE_ID "NC_000006.12" -// #define REFERENCE_ID "NC_000001.11" - - -static void -pq_dot_traverse(Priority_Queue const self, size_t const i, size_t const rhs_length) -{ - size_t const len = array_length(self.heap); - size_t const lhs_idx = self.heap[i] / rhs_length; - size_t const rhs_idx = self.heap[i] % rhs_length; - fprintf(stderr, "%zu[label=\"{%zu, %zu}\\n%u %u\\n %u\"]\n", - i, lhs_idx, rhs_idx, - self.states[self.heap[i]].included, self.states[self.heap[i]].excluded, - self.heap[i]); - if (2 * i + 1 < len) - { - fprintf(stderr, "%zu->%zu\n", i, 2 * i + 1); - pq_dot_traverse(self, 2 * i + 1, rhs_length); - if (2 * i + 2 < len) - { - fprintf(stderr, "%zu->%zu\n", i, 2 * i + 2); - pq_dot_traverse(self, 2 * i + 2, rhs_length); - } // if - } // if -} // pq_dot_traverse - - -static inline void -pq_dot(Priority_Queue const self, size_t const rhs_length) -{ - fprintf(stderr, "strict digraph{\nnode[fixedsize=true,shape=circle,width=1]\n"); - if (array_length(self.heap) > 0) - { - pq_dot_traverse(self, 0, rhs_length); - } // if - fprintf(stderr, "}\n"); -} // pq_dot +// #define REFERENCE_ID "NC_000006.12" +#define REFERENCE_ID "NC_000001.11" // line: alphanumeric_id SPDI [distance] @@ -831,6 +798,276 @@ overlap_main(int argc, char* argv[static argc]) } // overlap_main +typedef struct +{ + gva_uint start; + gva_uint end; + gva_uint inserted; + gva_uint distance; + gva_uint label; +} Entry; + + +static inline int +entry_cmp(void const* a, void const* b) +{ + Entry const* const lhs = a; + Entry const* const rhs = b; + + if (lhs->start < rhs->start) + { + return -1; + } // if + if (lhs->start > rhs->start) + { + return 1; + } // if + if (lhs->distance > rhs->distance) + { + return -1; + } // if + if (lhs->distance < rhs->distance) + { + return 1; + } // if + return 0; +} // entry_cmp + + +int +all_main(int argc, char* argv[static argc]) +{ + if (argc < 3) + { + fprintf(stderr, "usage %s reference.blob data\n", argv[0]); + return EXIT_FAILURE; + } // if + + errno = 0; + FILE* stream = fopen(argv[1], "r"); + if (stream == NULL) + { + fprintf(stderr, "error: %s\n", strerror(errno)); + return EXIT_FAILURE; + } // if + + GVA_String reference = {0}; + reference = gva_fasta_sequence_blob(gva_std_allocator, stream); + fclose(stream); + + fprintf(stderr, "reference length: %zu\n", reference.len); + + errno = 0; + stream = fopen(argv[2], "r"); + if (stream == NULL) + { + fprintf(stderr, "error: %s\n", strerror(errno)); + gva_string_destroy(gva_std_allocator, reference); + return EXIT_FAILURE; + } // if + + Trie labels = trie_init(gva_std_allocator); + Trie sequences = trie_init(gva_std_allocator); + Entry* entries = NULL; + + size_t line_count = 0; + static char line[LINE_SIZE] = {0}; + while (fgets(line, sizeof(line), stream) != NULL) + { + line_count += 1; + GVA_String id = {0}; + GVA_Variant variant = {0}; + size_t distance = 0; + if (!parse_line(line, &id, &variant, &distance)) + { + fprintf(stderr, "parsing failed at line %zu: %s", line_count, line); + continue; + } // if + + if (distance == 0) + { + fprintf(stderr, "ERROR: DISTANCE\n"); + } // if + + ARRAY_APPEND(gva_std_allocator, entries, + ((Entry) + { + .start = variant.start, + .end = variant.end, + .inserted = trie_insert(&sequences, variant.sequence.len, variant.sequence.str), + .distance = distance, + .label = trie_insert(&labels, id.len, id.str), + })); + } // while + fclose(stream); + + fprintf(stderr, "#lines: %zu\n", line_count); + + if (entries != NULL) + { + qsort(entries, array_length(entries), sizeof(*entries), entry_cmp); + fprintf(stderr, "#entries: %zu\n", array_length(entries)); + + size_t count = 0; + for (size_t i = 0; i < array_length(entries); ++i) + { + GVA_Variant const lhs = { entries[i].start, entries[i].end, trie_string(sequences, entries[i].inserted) }; + + GVA_LCS_Graph lhs_graph = {NULL}; + size_t* lhs_dels = NULL; + size_t* lhs_as = NULL; + size_t* lhs_cs = NULL; + size_t* lhs_gs = NULL; + size_t* lhs_ts = NULL; + + for (size_t j = i + 1; j < array_length(entries); ++j) + { + if (entries[i].end < entries[j].start) + { + break; + } // if + count += 1; + + if (entries[i].start == entries[j].start && entries[i].end == entries[j].end && entries[i].inserted == entries[j].inserted) + { + fprintf(stdout, GVA_STRING_FMT " equivalent " GVA_STRING_FMT "\n", + GVA_STRING_PRINT(trie_string(labels, entries[i].label)), + GVA_STRING_PRINT(trie_string(labels, entries[j].label))); + continue; // equivalent + } // if + + GVA_Variant const rhs = { entries[j].start, entries[j].end, trie_string(sequences, entries[j].inserted) }; + + size_t const start = MIN(lhs.start, rhs.start); + size_t const end = MAX(lhs.end, rhs.end); + + size_t const len_lhs = (lhs.start - start) + lhs.sequence.len + (end - lhs.end); + size_t const len_rhs = (rhs.start - start) + rhs.sequence.len + (end - rhs.end); + + size_t distance = 0; + if (len_lhs == 0) + { + distance = len_rhs; + } // if + else if (len_rhs == 0) + { + distance = len_lhs; + } // if + else + { + GVA_String observed_lhs = gva_string_init(gva_std_allocator, len_lhs); + GVA_String observed_rhs = gva_string_init(gva_std_allocator, len_rhs); + if (observed_lhs.str == NULL || observed_rhs.str == NULL) + { + return EXIT_FAILURE; // FIXME: OOM + } // if + + memcpy((char*) observed_lhs.str, reference.str + start, lhs.start - start); + memcpy((char*) observed_lhs.str + lhs.start - start, lhs.sequence.str, lhs.sequence.len); + memcpy((char*) observed_lhs.str + lhs.start - start + lhs.sequence.len, reference.str + lhs.end, end - lhs.end); + + memcpy((char*) observed_rhs.str, reference.str + start, rhs.start - start); + memcpy((char*) observed_rhs.str + rhs.start - start, rhs.sequence.str, rhs.sequence.len); + memcpy((char*) observed_rhs.str + rhs.start - start + rhs.sequence.len, reference.str + rhs.end, end - rhs.end); + + distance = gva_edit_distance(gva_std_allocator, observed_lhs.len, observed_lhs.str, observed_rhs.len, observed_rhs.str); + gva_string_destroy(gva_std_allocator, observed_rhs); + gva_string_destroy(gva_std_allocator, observed_lhs); + } // else + + if (entries[i].distance + entries[j].distance == distance) + { + continue; // disjoint + } // if + + if (entries[i].distance - entries[j].distance == distance) + { + fprintf(stdout, GVA_STRING_FMT " contains " GVA_STRING_FMT "\n", + GVA_STRING_PRINT(trie_string(labels, entries[i].label)), + GVA_STRING_PRINT(trie_string(labels, entries[j].label))); + continue; // contains + } // if + + if (entries[j].distance - entries[i].distance == distance) + { + fprintf(stdout, GVA_STRING_FMT " is_contained " GVA_STRING_FMT "\n", + GVA_STRING_PRINT(trie_string(labels, entries[i].label)), + GVA_STRING_PRINT(trie_string(labels, entries[j].label))); + continue; // is_contained + } // if + + if (lhs_graph.nodes == NULL) + { + lhs_graph = gva_lcs_graph_init(gva_std_allocator, lhs.end - lhs.start, reference.str + lhs.start, lhs.sequence.len, lhs.sequence.str, lhs.start); + size_t const len = end - start + 1; + lhs_dels = bitset_init(gva_std_allocator, len); + lhs_as = bitset_init(gva_std_allocator, len); + lhs_cs = bitset_init(gva_std_allocator, len); + lhs_gs = bitset_init(gva_std_allocator, len); + lhs_ts = bitset_init(gva_std_allocator, len); + gva_lcs_graph_uniq_atomics(lhs_graph, lhs.start, lhs.start, lhs.end, lhs_dels, lhs_as, lhs_cs, lhs_gs, lhs_ts); + } // if + + GVA_LCS_Graph rhs_graph = gva_lcs_graph_init(gva_std_allocator, rhs.end - rhs.start, reference.str + rhs.start, rhs.sequence.len, rhs.sequence.str, rhs.start); + + size_t const len = end - start + 1; + size_t* rhs_dels = bitset_init(gva_std_allocator, len); + size_t* rhs_as = bitset_init(gva_std_allocator, len); + size_t* rhs_cs = bitset_init(gva_std_allocator, len); + size_t* rhs_gs = bitset_init(gva_std_allocator, len); + size_t* rhs_ts = bitset_init(gva_std_allocator, len); + + gva_lcs_graph_uniq_atomics(rhs_graph, lhs.start, rhs.start, rhs.end, rhs_dels, rhs_as, rhs_cs, rhs_gs, rhs_ts); + + bool const overlap = bitset_intersection_cnt(lhs_dels, rhs_dels) > 0 || + bitset_intersection_cnt(lhs_as, rhs_as) > 0 || + bitset_intersection_cnt(lhs_cs, rhs_cs) > 0 || + bitset_intersection_cnt(lhs_gs, rhs_gs) > 0 || + bitset_intersection_cnt(lhs_ts, rhs_ts) > 0; + + rhs_ts = bitset_destroy(gva_std_allocator, rhs_ts); + rhs_gs = bitset_destroy(gva_std_allocator, rhs_gs); + rhs_cs = bitset_destroy(gva_std_allocator, rhs_cs); + rhs_as = bitset_destroy(gva_std_allocator, rhs_as); + rhs_dels = bitset_destroy(gva_std_allocator, rhs_dels); + + gva_lcs_graph_destroy(gva_std_allocator, rhs_graph, false); + + if (overlap) + { + fprintf(stdout, GVA_STRING_FMT " overlap " GVA_STRING_FMT " %zu\n", + GVA_STRING_PRINT(trie_string(labels, entries[i].label)), + GVA_STRING_PRINT(trie_string(labels, entries[j].label)), + (entries[i].distance + entries[j].distance - distance) / 2); + } // if + else + { + fprintf(stdout, GVA_STRING_FMT " disjoint " GVA_STRING_FMT "\n", + GVA_STRING_PRINT(trie_string(labels, entries[i].label)), + GVA_STRING_PRINT(trie_string(labels, entries[j].label))); + } // else + } // for + lhs_ts = bitset_destroy(gva_std_allocator, lhs_ts); + lhs_gs = bitset_destroy(gva_std_allocator, lhs_gs); + lhs_cs = bitset_destroy(gva_std_allocator, lhs_cs); + lhs_as = bitset_destroy(gva_std_allocator, lhs_as); + lhs_dels = bitset_destroy(gva_std_allocator, lhs_dels); + gva_lcs_graph_destroy(gva_std_allocator, lhs_graph, false); + } // for + + fprintf(stderr, "#combos: %zu\n", count); + } // if + + entries = ARRAY_DESTROY(gva_std_allocator, entries); + trie_destroy(&labels); + trie_destroy(&sequences); + + gva_string_destroy(gva_std_allocator, reference); + + return EXIT_SUCCESS; +} // all_main + + int main(int argc, char* argv[static argc]) { @@ -839,4 +1076,5 @@ main(int argc, char* argv[static argc]) // return index_main(argc, argv); return overlap_main(argc, argv); // return dot_main(argc, argv); + // return all_main(argc, argv); } // main From b0d1faab68e994d221677caca0d999e4ed5e7963 Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 17 Apr 2026 09:57:29 +0200 Subject: [PATCH 592/704] Snapshot with graph walks --- src/main.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main.c b/src/main.c index 03892a0..9165c9b 100644 --- a/src/main.c +++ b/src/main.c @@ -5,6 +5,7 @@ #include // EXIT_*, atoll, qsort #include // strerror, strlen +#include "../include/compare.h" // gva_compare_graphs #include "../include/edit.h" // gva_edit_distance #include "../include/index.h" // GVA_Index, gva_index_*, GVA_Query_Result #include "../include/lcs_graph.h" // GVA_LCS_Graph, gva_lcs_graph_* @@ -102,7 +103,6 @@ report_query_result(GVA_Index const* const index, GVA_LCS_Graph const graph, GVA } // if } // if - if (hits) { fprintf(stderr, GVA_STRING_FMT " " GVA_STRING_FMT " %u %u %s\n", @@ -678,6 +678,8 @@ overlap_main(int argc, char* argv[static argc]) GVA_LCS_Graph lhs = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &lhs_variant); GVA_LCS_Graph rhs = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &rhs_variant); + fprintf(stderr, "%s\n", GVA_RELATION_LABELS[gva_compare_graphs(gva_std_allocator, reference.len, reference.str, lhs, rhs)]); + static char filename[128] = {0}; snprintf(filename, 128, "overlap/graph_%zu.dot", line_count); FILE* stream = fopen(filename, "w"); @@ -688,10 +690,10 @@ overlap_main(int argc, char* argv[static argc]) fprintf(stderr, "%sdistances lhs: %zu rhs: %zu :: ", line, gva_lcs_graph_distance(lhs), gva_lcs_graph_distance(rhs)); { size_t const distance = gva_edit_distance(gva_std_allocator, - gva_lcs_graph_supremal(lhs).sequence.len, gva_lcs_graph_supremal(lhs).sequence.str, - gva_lcs_graph_supremal(rhs).sequence.len, gva_lcs_graph_supremal(rhs).sequence.str); + lhs_variant.sequence.len, lhs_variant.sequence.str, + rhs_variant.sequence.len, rhs_variant.sequence.str); fprintf(stderr, "%zu\n", distance); - } // empty + } fprintf(stderr, "#nodes lhs: %zu rhs %zu :: %zu\n", array_length(lhs.nodes), array_length(rhs.nodes), array_length(lhs.nodes) * array_length(rhs.nodes)); fprintf(stderr, "#edges lhs: %zu rhs %zu :: %zu\n", array_length(lhs.edges), array_length(rhs.edges), array_length(lhs.edges) * array_length(rhs.edges)); From a609521338e297fe398cceb9ea83014452240e64 Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 17 Apr 2026 16:08:02 +0200 Subject: [PATCH 593/704] WIP: detect overlap with graph traversal --- src/main.c | 368 +++++++++++++++++++++-------------------------------- 1 file changed, 146 insertions(+), 222 deletions(-) diff --git a/src/main.c b/src/main.c index 9165c9b..3207b09 100644 --- a/src/main.c +++ b/src/main.c @@ -18,7 +18,6 @@ #include "array.h" // ARRAY_*, array_length #include "bitset.h" // bitset_* #include "common.h" // MAX, MIN -#include "priority_queue.h" // Priority_Queue, priority_queue_* #include "trie.h" // Trie, trie_* @@ -32,6 +31,148 @@ #define REFERENCE_ID "NC_000001.11" +static inline bool +variant_disjoint(size_t const lhs_count, GVA_Variant const lhs, + size_t const rhs_count, GVA_Variant const rhs) +{ + if (rhs.start > lhs.end + lhs_count - 1 || + lhs.start > rhs.end + rhs_count - 1) + { + return true; + } // if + + size_t lhs_offset = 0; + size_t rhs_offset = 0; + if (rhs.start > lhs.start) + { + lhs_offset = MIN(rhs.start - lhs.start, lhs_count - 1); + } // if + else if (lhs.start > rhs.start) + { + rhs_offset = MIN(lhs.start - rhs.start, rhs_count - 1); + } // if + + size_t const start = MAX(lhs.start + lhs_offset, rhs.start + rhs_offset); + size_t const end = MIN(lhs.end + lhs_offset, rhs.end + rhs_offset); + + if (end > start) + { + return false; + } // if + + unsigned __int128 lhs_seq = 0; + for (size_t i = 0; i < lhs.sequence.len; ++i) + { + lhs_seq |= 1 << (lhs.sequence.str[lhs_offset + i] & 0x7f); + } // for + unsigned __int128 rhs_seq = 0; + for (size_t i = 0; i < rhs.sequence.len; ++i) + { + rhs_seq |= 1 << (rhs.sequence.str[rhs_offset + i] & 0x7f); + } // for + + return (lhs_seq & rhs_seq) == 0; +} // variant_disjoint + + +static bool +is_disjoint(GVA_Allocator const allocator, + GVA_LCS_Graph const lhs, GVA_LCS_Graph const rhs) +{ + size_t const rhs_nodes = array_length(rhs.nodes); + size_t const length = array_length(lhs.nodes) * rhs_nodes; + gva_uint* queue = allocator.allocate(allocator.context, NULL, 0, length * sizeof(*queue)); + if (queue == NULL) + { + return true; // FIXME: OOM + } // if + + for (size_t i = 0; i < length; ++i) + { + queue[i] = GVA_NULL; + } // for + + gva_uint tail = lhs.source * rhs_nodes + rhs.source; + for (gva_uint head = tail; head != GVA_NULL; head = queue[head]) + { + size_t const lhs_idx = head / rhs_nodes; + size_t const rhs_idx = head % rhs_nodes; + + fprintf(stderr, "{%zu, %zu}\n", lhs_idx, rhs_idx); + + if (lhs.nodes[lhs_idx].match.row + lhs.nodes[lhs_idx].match.length < + rhs.nodes[rhs_idx].match.row) + { + for (gva_uint i = lhs.nodes[lhs_idx].edges; i != GVA_NULL; i = lhs.edges[i].next) + { + fprintf(stderr, " LHS {%u, %zu}\n", lhs.edges[i].tail, rhs_idx); + size_t const next = lhs.edges[i].tail * rhs_nodes + rhs_idx; + if (lhs.nodes[lhs.edges[i].tail].edges != GVA_NULL) + { + queue[tail] = next; + tail = next; + } // if + } // for + continue; + } // if + + if (rhs.nodes[rhs_idx].match.row + rhs.nodes[rhs_idx].match.length < + lhs.nodes[lhs_idx].match.row) + { + for (gva_uint i = rhs.nodes[rhs_idx].edges; i != GVA_NULL; i = rhs.edges[i].next) + { + fprintf(stderr, " RHS {%zu, %u}\n", lhs_idx, rhs.edges[i].tail); + size_t const next = lhs_idx * rhs_nodes + rhs.edges[i].tail; + if (rhs.nodes[rhs.edges[i].tail].edges != GVA_NULL) + { + queue[tail] = next; + tail = next; + } // if + } // for + continue; + } // if + + for (gva_uint i = lhs.nodes[lhs_idx].edges; i != GVA_NULL; i = lhs.edges[i].next) + { + GVA_Variant lhs_variant = {0}; + size_t const lhs_count = gva_edges(lhs.observed.str, + lhs.nodes[lhs_idx].match, lhs.nodes[lhs.edges[i].tail].match, + lhs_idx == lhs.source, lhs.nodes[lhs.edges[i].tail].edges == GVA_NULL, + &lhs_variant); + + for (gva_uint j = rhs.nodes[rhs_idx].edges; j != GVA_NULL; j = rhs.edges[j].next) + { + GVA_Variant rhs_variant = {0}; + size_t const rhs_count = gva_edges(rhs.observed.str, + rhs.nodes[rhs_idx].match, rhs.nodes[rhs.edges[j].tail].match, + rhs_idx == rhs.source, rhs.nodes[rhs.edges[j].tail].edges == GVA_NULL, + &rhs_variant); + + fprintf(stderr, " " GVA_VARIANT_FMT " x %zu vs " GVA_VARIANT_FMT " x %zu\n", + GVA_VARIANT_PRINT(lhs_variant), lhs_count, GVA_VARIANT_PRINT(rhs_variant), rhs_count); + + if (!variant_disjoint(lhs_count, lhs_variant, rhs_count, rhs_variant)) + { + queue = allocator.allocate(allocator.context, queue, length * sizeof(*queue), 0); + return false; + } // if + + size_t const next = lhs.edges[i].tail * rhs_nodes + rhs.edges[j].tail; + if (lhs.nodes[lhs.edges[i].tail].edges != GVA_NULL && + rhs.nodes[rhs.edges[j].tail].edges != GVA_NULL) + { + queue[tail] = next; + tail = next; + } // if + } // for + } // for + } // for + + queue = allocator.allocate(allocator.context, queue, length * sizeof(*queue), 0); + return true; +} // is_disjoint + + // line: alphanumeric_id SPDI [distance] static bool parse_line(char const line[static restrict LINE_SIZE], @@ -453,88 +594,6 @@ allele_main(int argc, char* argv[static argc]) } // allele_main -// DEBUG / check -int -extract_main(int argc, char* argv[static argc]) -{ - (void) argv; - - size_t line_count = 0; - static char line[LINE_SIZE] = {0}; - while (fgets(line, sizeof(line), stdin) != NULL) - { - line_count += 1; - - size_t const len_ref = strcspn(line, "\t "); - GVA_String const reference = {len_ref, line}; - size_t const len_obs = strcspn(line + len_ref + 1, "\n\t "); - GVA_String const observed = {len_obs, line + len_ref + 1}; - - fprintf(stdout, "%zu: " GVA_STRING_FMT " (%zu) " GVA_STRING_FMT " (%zu)\n", line_count, - GVA_STRING_PRINT(reference), reference.len, GVA_STRING_PRINT(observed), observed.len); - - GVA_LCS_Graph graph = gva_lcs_graph_init(gva_std_allocator, - reference.len, reference.str, observed.len, observed.str, 0); - - // fprintf(stdout, " distance: %zu\n", gva_lcs_graph_distance(graph)); - // fprintf(stdout, " #nodes: %zu\n", array_length(graph.nodes)); - // for (size_t i = 0; i < array_length(graph.nodes); ++i) - // { - // fprintf(stdout, " %zu: (%u, %u, %u)\n", i, - // graph.nodes[i].match.row, graph.nodes[i].match.col, graph.nodes[i].match.length); - // } // for - // fprintf(stdout, " #edges: %zu\n", array_length(graph.edges)); - // fprintf(stdout, " #dom_nodes: %zu\n", array_length(graph.dom_nodes)); - // if (array_length(graph.dom_nodes) < 3) - // { - // continue; - // } - - // for (size_t i = 0; i < array_length(graph.dom_nodes); ++i) - // { - // if (i > 0) - // { - // fprintf(stdout, " " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(gva_lcs_graph_local_supremal(graph, i - 1, i))); - // } // if - // fprintf(stdout, " %zu: (%u, %u, %u) %u\n", i, - // graph.dom_nodes[i].match.row, graph.dom_nodes[i].match.col, graph.dom_nodes[i].match.length, - // graph.dom_nodes[i].distance); - // } // for - - // fprintf(stdout, " supremal: " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(gva_lcs_graph_supremal(graph))); - - gva_lcs_graph_dot(stdout, graph); - GVA_Variant sup = gva_variant_dup(gva_std_allocator, gva_lcs_graph_supremal(graph)); - - GVA_LCS_Graph graph2 = gva_lcs_graph_from_allele(gva_std_allocator, reference.len, reference.str, 1, &sup); - gva_lcs_graph_dot(stdout, graph2); - - if (array_length(graph.dom_nodes) != array_length(graph2.dom_nodes)) - { - fprintf(stderr, "length dom nodes mismatch\n"); - assert(0); - } // if - - for (size_t i = 0; i < array_length(graph.dom_nodes); ++i) - { - if (graph.dom_nodes[i].match.row != graph2.dom_nodes[i].match.row || - graph.dom_nodes[i].match.col != graph2.dom_nodes[i].match.col || - graph.dom_nodes[i].match.length != graph2.dom_nodes[i].match.length) - { - fprintf(stderr, "dom nodes mismatch\n"); - assert(0); - } // if - } // for - - gva_string_destroy(gva_std_allocator, sup.sequence); - gva_lcs_graph_destroy(gva_std_allocator, graph2, true); - gva_lcs_graph_destroy(gva_std_allocator, graph, false); - } // while - - return EXIT_SUCCESS; -} // extract_main - - int supremal_main(int argc, char* argv[static argc]) { @@ -599,46 +658,6 @@ supremal_main(int argc, char* argv[static argc]) } // supremal_main -static inline size_t -variant_included(size_t const lhs_count, GVA_Variant const lhs, - size_t const rhs_count, GVA_Variant const rhs) -{ - if (rhs.start > lhs.end + lhs_count - 1 || - lhs.start > rhs.end + rhs_count - 1) - { - return 0; - } // if - - size_t lhs_offset = 0; - size_t rhs_offset = 0; - if (rhs.start > lhs.start) - { - lhs_offset = MIN(rhs.start - lhs.start, lhs_count - 1); - } // if - else if (lhs.start > rhs.start) - { - rhs_offset = MIN(lhs.start - rhs.start, rhs_count - 1); - } // if - - size_t const start = MAX(lhs.start + lhs_offset, rhs.start + rhs_offset); - size_t const end = MIN(lhs.end + lhs_offset, rhs.end + rhs_offset); - - if (lhs.sequence.len == 0 || rhs.sequence.len == 0) - { - return end - start; - } // if - if (lhs.sequence.len == 1 && rhs.sequence.len == 1) - { - return (lhs.sequence.str[0] == rhs.sequence.str[0]) + end - start; - } // if - - size_t const lcs = (lhs.sequence.len + rhs.sequence.len - - gva_edit_distance(gva_std_allocator, lhs.sequence.len, lhs.sequence.str + lhs_offset, - rhs.sequence.len, rhs.sequence.str + rhs_offset)) / 2; - return lcs + end - start; -} // variant_included - - int overlap_main(int argc, char* argv[static argc]) { @@ -697,100 +716,7 @@ overlap_main(int argc, char* argv[static argc]) fprintf(stderr, "#nodes lhs: %zu rhs %zu :: %zu\n", array_length(lhs.nodes), array_length(rhs.nodes), array_length(lhs.nodes) * array_length(rhs.nodes)); fprintf(stderr, "#edges lhs: %zu rhs %zu :: %zu\n", array_length(lhs.edges), array_length(rhs.edges), array_length(lhs.edges) * array_length(rhs.edges)); - size_t const distance = gva_lcs_graph_distance(lhs) + gva_lcs_graph_distance(rhs); - Priority_Queue fringe = priority_queue_init(gva_std_allocator, array_length(lhs.nodes) * array_length(rhs.nodes)); - priority_queue_push(&fringe, lhs.source * array_length(rhs.nodes) + rhs.source, 0, 0); - - size_t steps = 0; - while (!priority_queue_empty(fringe)) - { - steps += 1; - size_t const idx = priority_queue_pop(&fringe); - - size_t const lhs_idx = idx / array_length(rhs.nodes); - size_t const rhs_idx = idx % array_length(rhs.nodes); - - fprintf(stderr, "{%zu, %zu} (%zu) :: %u %u\n", lhs_idx, rhs_idx, idx, - fringe.states[idx].included, fringe.states[idx].excluded); - if (distance == 2 * fringe.states[idx].included + fringe.states[idx].excluded) - { - fprintf(stdout, "%u %zu %zu\n", fringe.states[idx].included, steps, array_length(fringe.heap)); - break; - } // if - - for (gva_uint i = lhs.nodes[lhs_idx].edges; i != GVA_NULL; i = lhs.edges[i].next) - { - GVA_Variant lhs_variant = {0}; - size_t const lhs_count = gva_edges(lhs.observed.str, - lhs.nodes[lhs_idx].match, lhs.nodes[lhs.edges[i].tail].match, - lhs_idx == lhs.source, lhs.nodes[lhs.edges[i].tail].edges == GVA_NULL, - &lhs_variant); - - for (gva_uint j = rhs.nodes[rhs_idx].edges; j != GVA_NULL; j = rhs.edges[j].next) - { - GVA_Variant rhs_variant = {0}; - size_t const rhs_count = gva_edges(rhs.observed.str, - rhs.nodes[rhs_idx].match, rhs.nodes[rhs.edges[j].tail].match, - rhs_idx == rhs.source, rhs.nodes[rhs.edges[j].tail].edges == GVA_NULL, - &rhs_variant); - - size_t const included = variant_included(lhs_count, lhs_variant, rhs_count, rhs_variant); - size_t const excluded = gva_variant_length(lhs_variant) + gva_variant_length(rhs_variant) - 2 * included; -/* - fprintf(stderr, " {%u, %u} ", lhs.edges[i].tail, rhs.edges[j].tail); - fprintf(stderr, GVA_VARIANT_FMT " x %zu (%zu) vs " GVA_VARIANT_FMT " x %zu (%zu) ", GVA_VARIANT_PRINT(lhs_variant), lhs_count, gva_variant_length(lhs_variant), GVA_VARIANT_PRINT(rhs_variant), rhs_count, gva_variant_length(rhs_variant)); - fprintf(stderr, "+ %zu %zu\n", included, excluded); -*/ - priority_queue_push(&fringe, lhs.edges[i].tail * array_length(rhs.nodes) + rhs.edges[j].tail, - fringe.states[idx].included + included, fringe.states[idx].excluded + excluded); - } // for - } // for - - if (lhs.nodes[lhs_idx].lambda != GVA_NULL) - { - priority_queue_push(&fringe, lhs.nodes[lhs_idx].lambda * array_length(rhs.nodes) + rhs_idx, - fringe.states[idx].included, fringe.states[idx].excluded); - } // if - if (rhs.nodes[rhs_idx].lambda != GVA_NULL) - { - priority_queue_push(&fringe, lhs_idx * array_length(rhs.nodes) + rhs.nodes[rhs_idx].lambda, - fringe.states[idx].included, fringe.states[idx].excluded); - } // if - - for (gva_uint i = lhs.nodes[lhs_idx].edges; i != GVA_NULL; i = lhs.edges[i].next) - { - GVA_Variant lhs_variant = {0}; - gva_edges(lhs.observed.str, lhs.nodes[lhs_idx].match, lhs.nodes[lhs.edges[i].tail].match, - lhs_idx == lhs.source, lhs.nodes[lhs.edges[i].tail].edges == GVA_NULL, - &lhs_variant); - priority_queue_push(&fringe, lhs.edges[i].tail * array_length(rhs.nodes) + rhs_idx, - fringe.states[idx].included, fringe.states[idx].excluded + gva_variant_length(lhs_variant)); - } // for - for (gva_uint i = rhs.nodes[rhs_idx].edges; i != GVA_NULL; i = rhs.edges[i].next) - { - GVA_Variant rhs_variant = {0}; - gva_edges(rhs.observed.str, rhs.nodes[rhs_idx].match, rhs.nodes[rhs.edges[i].tail].match, - rhs_idx == rhs.source, rhs.nodes[rhs.edges[i].tail].edges == GVA_NULL, - &rhs_variant); - priority_queue_push(&fringe, lhs_idx * array_length(rhs.nodes) + rhs.edges[i].tail, - fringe.states[idx].included, fringe.states[idx].excluded + gva_variant_length(rhs_variant)); - } // for -/* - pq_dot(fringe, array_length(rhs.nodes)); - for (size_t i = 0; i < fringe.capacity; ++i) - { - if (fringe.states[i].idx != GVA_NULL) - { - size_t const lhs_idx = i / array_length(rhs.nodes); - size_t const rhs_idx = i % array_length(rhs.nodes); - fprintf(stderr, "%4zu: {%zu, %zu} :: %2u %2u %2d\n", i, lhs_idx, rhs_idx, - fringe.states[i].included, fringe.states[i].excluded, fringe.states[i].idx); - } // if - } // for -*/ - } // while - - priority_queue_destroy(&fringe); + fprintf(stderr, "disjoint: %d\n", is_disjoint(gva_std_allocator, lhs, rhs)); gva_lcs_graph_destroy(gva_std_allocator, rhs, true); gva_lcs_graph_destroy(gva_std_allocator, lhs, true); @@ -811,7 +737,7 @@ typedef struct static inline int -entry_cmp(void const* a, void const* b) +compare_entries(void const* a, void const* b) { Entry const* const lhs = a; Entry const* const rhs = b; @@ -833,7 +759,7 @@ entry_cmp(void const* a, void const* b) return 1; } // if return 0; -} // entry_cmp +} // compare_entries int @@ -907,7 +833,7 @@ all_main(int argc, char* argv[static argc]) if (entries != NULL) { - qsort(entries, array_length(entries), sizeof(*entries), entry_cmp); + qsort(entries, array_length(entries), sizeof(*entries), compare_entries); fprintf(stderr, "#entries: %zu\n", array_length(entries)); size_t count = 0; @@ -1074,9 +1000,7 @@ int main(int argc, char* argv[static argc]) { // return allele_main(argc, argv); - // return extract_main(argc, argv); // return index_main(argc, argv); return overlap_main(argc, argv); - // return dot_main(argc, argv); // return all_main(argc, argv); } // main From 0e99372b33c0464d568f2dc08103a35427876250 Mon Sep 17 00:00:00 2001 From: jkvis Date: Sat, 18 Apr 2026 11:29:33 +0200 Subject: [PATCH 594/704] DFA construction --- src/nfa.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- src/nfa.h | 34 +++++++++++++++++- 2 files changed, 133 insertions(+), 3 deletions(-) diff --git a/src/nfa.c b/src/nfa.c index 420d481..d337f22 100644 --- a/src/nfa.c +++ b/src/nfa.c @@ -1,12 +1,110 @@ -#include // size_t +#include // NULL, size_t #include // stderr, fprintf FIXME: DEBUG +#include // memset #include "../include/allocator.h" // GVA_Allocator #include "../include/lcs_graph.h" // GVA_LCS_Graph, gva_edges +#include "../include/string.h" // GVA_String, gva_string_* #include "../include/types.h" // GVA_NULL, gva_uint #include "../include/variant.h" // GVA_Variant #include "array.h" // ARRAY_*, array_length -#include "nfa.h" // NFA*, nfa_* +#include "nfa.h" // DFA, dfa*, NFA*, nfa_* + + +static inline void +dfa_edge(DFA self[static 1], size_t const width, + size_t const start, size_t const end, + size_t const len, size_t const offset) +{ + for (size_t i = start; i <= end; ++i) + { + for (size_t j = 0; j <= len; ++j) + { + self->states[i * width + offset + j].present = 1; + } // for + } // for +} // dfa_edge + + +DFA +dfa_from_lcs_graph(GVA_Allocator const allocator, GVA_LCS_Graph const graph) +{ + GVA_Variant const supremal = gva_lcs_graph_supremal(graph); + size_t const size = (supremal.end - supremal.start + 1) * (supremal.sequence.len + 1); + DFA dfa = + { + .observed = supremal.sequence, + .states = allocator.allocate(allocator.context, NULL, 0, size), + }; + if (dfa.states == NULL) + { + dfa.size = 0; + return dfa; // OOM + } // if + + dfa.size = size; + memset(dfa.states, 0, dfa.size); + + size_t const width = dfa.observed.len + 1; + for (size_t i = 0; i < array_length(graph.nodes); ++i) + { + dfa.states[graph.nodes[i].match.row * width + graph.nodes[i].match.col].present = 1; + for (size_t j = 0; j < graph.nodes[i].match.length; ++j) + { + dfa.states[(graph.nodes[i].match.row + j) * width + graph.nodes[i].match.col + j].present = 1; + dfa.states[(graph.nodes[i].match.row + j) * width + graph.nodes[i].match.col + j].match = 1; + } // for + for (gva_uint j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) + { + GVA_Variant variant = {0}; + size_t const count = gva_edges(graph.observed.str, + graph.nodes[i].match, graph.nodes[graph.edges[j].tail].match, + i == graph.source, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, + &variant); + for (size_t k = 0; k < count; ++k) + { + dfa_edge(&dfa, width, variant.start + k, variant.end + k, variant.sequence.len, variant.sequence.str - dfa.observed.str + k); + } // for + } // for + } // for + + return dfa; +} // dfa_from_lcs_graph + + +inline void +dfa_destroy(GVA_Allocator const allocator, DFA self[static 1]) +{ + self->states = allocator.allocate(allocator.context, self->states, self->size * sizeof(*self->states), 0); + self->size = 0; +} // dfa_destroy + + +void +dfa_dot(DFA const self) +{ + size_t const width = self.observed.len + 1; + fprintf(stderr, "strict digraph{\nrankdir=LR\nnode[fixedsize=true,label=\"\",shape=circle,width=1]\ni[shape=none,width=0]\ni->0\n"); + for (size_t i = 0; i < self.size; ++i) + { + if (self.states[i].present) + { + if (i < self.size - 1 && self.states[i + 1].present) + { + fprintf(stderr, "%zu->%zu[label=\"%c\"]\n", i, i + 1, self.observed.str[i % width]); + } // if + if (i < self.size - width && self.states[i + width].present) + { + fprintf(stderr, "%zu->%zu[label=\"Δ\"]\n", i, i + width); + } // if + if (self.states[i].match) + { + fprintf(stderr, "%zu->%zu[label=\"Μ\"]\n", i, i + width + 1); + } // if + } // if + } // for + fprintf(stderr, "%zu[peripheries=2]\n}\n", self.size - 1); +} // dfa_dot static void diff --git a/src/nfa.h b/src/nfa.h index 5562781..6acf7d8 100644 --- a/src/nfa.h +++ b/src/nfa.h @@ -2,13 +2,45 @@ #define GVA_NFA_H +#include // size_t +#include // uint8_t + #include "../include/allocator.h" // GVA_Allocator #include "../include/lcs_graph.h" // GVA_LCS_Graph +#include "../include/string.h" // GVA_String #include "../include/types.h" // gva_uint +typedef struct +{ + uint8_t present : 1; + uint8_t match : 1; +} DFA_State; // FIXME: could realy be 2 bits + + +typedef struct +{ + size_t size; + GVA_String observed; + DFA_State* states; +} DFA; + + +DFA +dfa_from_lcs_graph(GVA_Allocator const allocator, GVA_LCS_Graph const graph); + + +void +dfa_destroy(GVA_Allocator const allocator, DFA self[static 1]); + + +// FIXME: DEBUG +void +dfa_dot(DFA const self); + + +static char const NFA_LAMBDA = 0; static char const NFA_DELETE = 127; -static char const NFA_LAMBDA = (char) 235; typedef struct From 05d37a05c93a92884ddfa7b39ca512f96b13cfc3 Mon Sep 17 00:00:00 2001 From: jkvis Date: Sat, 18 Apr 2026 12:05:02 +0200 Subject: [PATCH 595/704] WIP: graph traversal overlap: seems correct, but slow --- src/main.c | 130 +++++++++++++++++++++++++++++++++++------------------ 1 file changed, 87 insertions(+), 43 deletions(-) diff --git a/src/main.c b/src/main.c index 3207b09..e082cce 100644 --- a/src/main.c +++ b/src/main.c @@ -18,6 +18,7 @@ #include "array.h" // ARRAY_*, array_length #include "bitset.h" // bitset_* #include "common.h" // MAX, MIN +#include "nfa.h" // DFA, dfa_* #include "trie.h" // Trie, trie_* @@ -81,7 +82,11 @@ is_disjoint(GVA_Allocator const allocator, { size_t const rhs_nodes = array_length(rhs.nodes); size_t const length = array_length(lhs.nodes) * rhs_nodes; - gva_uint* queue = allocator.allocate(allocator.context, NULL, 0, length * sizeof(*queue)); + struct + { + gva_uint seen; + gva_uint next; + }* queue = allocator.allocate(allocator.context, NULL, 0, length * sizeof(*queue)); if (queue == NULL) { return true; // FIXME: OOM @@ -89,49 +94,18 @@ is_disjoint(GVA_Allocator const allocator, for (size_t i = 0; i < length; ++i) { - queue[i] = GVA_NULL; + queue[i].seen = false; + queue[i].next = GVA_NULL; } // for - gva_uint tail = lhs.source * rhs_nodes + rhs.source; - for (gva_uint head = tail; head != GVA_NULL; head = queue[head]) + gva_uint tail = lhs.source * rhs_nodes + rhs.source; + for (gva_uint head = tail; head != GVA_NULL; head = queue[head].next) { size_t const lhs_idx = head / rhs_nodes; size_t const rhs_idx = head % rhs_nodes; fprintf(stderr, "{%zu, %zu}\n", lhs_idx, rhs_idx); - if (lhs.nodes[lhs_idx].match.row + lhs.nodes[lhs_idx].match.length < - rhs.nodes[rhs_idx].match.row) - { - for (gva_uint i = lhs.nodes[lhs_idx].edges; i != GVA_NULL; i = lhs.edges[i].next) - { - fprintf(stderr, " LHS {%u, %zu}\n", lhs.edges[i].tail, rhs_idx); - size_t const next = lhs.edges[i].tail * rhs_nodes + rhs_idx; - if (lhs.nodes[lhs.edges[i].tail].edges != GVA_NULL) - { - queue[tail] = next; - tail = next; - } // if - } // for - continue; - } // if - - if (rhs.nodes[rhs_idx].match.row + rhs.nodes[rhs_idx].match.length < - lhs.nodes[lhs_idx].match.row) - { - for (gva_uint i = rhs.nodes[rhs_idx].edges; i != GVA_NULL; i = rhs.edges[i].next) - { - fprintf(stderr, " RHS {%zu, %u}\n", lhs_idx, rhs.edges[i].tail); - size_t const next = lhs_idx * rhs_nodes + rhs.edges[i].tail; - if (rhs.nodes[rhs.edges[i].tail].edges != GVA_NULL) - { - queue[tail] = next; - tail = next; - } // if - } // for - continue; - } // if - for (gva_uint i = lhs.nodes[lhs_idx].edges; i != GVA_NULL; i = lhs.edges[i].next) { GVA_Variant lhs_variant = {0}; @@ -148,8 +122,8 @@ is_disjoint(GVA_Allocator const allocator, rhs_idx == rhs.source, rhs.nodes[rhs.edges[j].tail].edges == GVA_NULL, &rhs_variant); - fprintf(stderr, " " GVA_VARIANT_FMT " x %zu vs " GVA_VARIANT_FMT " x %zu\n", - GVA_VARIANT_PRINT(lhs_variant), lhs_count, GVA_VARIANT_PRINT(rhs_variant), rhs_count); + //fprintf(stderr, " " GVA_VARIANT_FMT " x %zu vs " GVA_VARIANT_FMT " x %zu\n", + // GVA_VARIANT_PRINT(lhs_variant), lhs_count, GVA_VARIANT_PRINT(rhs_variant), rhs_count); if (!variant_disjoint(lhs_count, lhs_variant, rhs_count, rhs_variant)) { @@ -159,13 +133,62 @@ is_disjoint(GVA_Allocator const allocator, size_t const next = lhs.edges[i].tail * rhs_nodes + rhs.edges[j].tail; if (lhs.nodes[lhs.edges[i].tail].edges != GVA_NULL && - rhs.nodes[rhs.edges[j].tail].edges != GVA_NULL) + rhs.nodes[rhs.edges[j].tail].edges != GVA_NULL && + !queue[next].seen) { - queue[tail] = next; + queue[tail].next = next; tail = next; + queue[next].seen = true; } // if } // for } // for + + if (lhs.nodes[lhs_idx].lambda != GVA_NULL) + { + size_t const next = lhs.nodes[lhs_idx].lambda * rhs_nodes + rhs_idx; + if (!queue[next].seen) + { + //fprintf(stderr, " lambda lhs: {%u, %zu}\n", lhs.nodes[lhs_idx].lambda, rhs_idx); + queue[tail].next = next; + tail = next; + queue[next].seen = true; + } // if + } // if + if (rhs.nodes[rhs_idx].lambda != GVA_NULL) + { + size_t const next = lhs_idx * rhs_nodes + rhs.nodes[rhs_idx].lambda; + if (!queue[next].seen) + { + //fprintf(stderr, " lambda rhs: {%zu, %u}\n", lhs_idx, rhs.nodes[rhs_idx].lambda); + queue[tail].next = next; + tail = next; + queue[next].seen = true; + } // if + } // if + + for (gva_uint i = lhs.nodes[lhs_idx].edges; i != GVA_NULL; i = lhs.edges[i].next) + { + size_t const next = lhs.edges[i].tail * rhs_nodes + rhs_idx; + if (lhs.nodes[lhs.edges[i].tail].edges != GVA_NULL && !queue[next].seen) + { + //fprintf(stderr, " advance lhs: {%u, %zu}\n", lhs.edges[i].tail, rhs_idx); + queue[tail].next = next; + tail = next; + queue[next].seen = true; + } // if + } // for + for (gva_uint i = rhs.nodes[rhs_idx].edges; i != GVA_NULL; i = rhs.edges[i].next) + { + size_t const next = lhs_idx * rhs_nodes + rhs.edges[i].tail; + if (rhs.nodes[rhs.edges[i].tail].edges != GVA_NULL && !queue[next].seen) + { + //fprintf(stderr, " advance rhs: {%zu, %u}\n", lhs_idx, rhs.edges[i].tail); + queue[tail].next = next; + tail = next; + queue[next].seen = true; + } // if + } // for + } // for queue = allocator.allocate(allocator.context, queue, length * sizeof(*queue), 0); @@ -697,6 +720,12 @@ overlap_main(int argc, char* argv[static argc]) GVA_LCS_Graph lhs = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &lhs_variant); GVA_LCS_Graph rhs = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &rhs_variant); + DFA dfa = dfa_from_lcs_graph(gva_std_allocator, lhs); + + dfa_dot(dfa); + + dfa_destroy(gva_std_allocator, &dfa); + fprintf(stderr, "%s\n", GVA_RELATION_LABELS[gva_compare_graphs(gva_std_allocator, reference.len, reference.str, lhs, rhs)]); static char filename[128] = {0}; @@ -716,7 +745,7 @@ overlap_main(int argc, char* argv[static argc]) fprintf(stderr, "#nodes lhs: %zu rhs %zu :: %zu\n", array_length(lhs.nodes), array_length(rhs.nodes), array_length(lhs.nodes) * array_length(rhs.nodes)); fprintf(stderr, "#edges lhs: %zu rhs %zu :: %zu\n", array_length(lhs.edges), array_length(rhs.edges), array_length(lhs.edges) * array_length(rhs.edges)); - fprintf(stderr, "disjoint: %d\n", is_disjoint(gva_std_allocator, lhs, rhs)); + //fprintf(stderr, "disjoint: %d\n", is_disjoint(gva_std_allocator, lhs, rhs)); gva_lcs_graph_destroy(gva_std_allocator, rhs, true); gva_lcs_graph_destroy(gva_std_allocator, lhs, true); @@ -959,6 +988,21 @@ all_main(int argc, char* argv[static argc]) rhs_as = bitset_destroy(gva_std_allocator, rhs_as); rhs_dels = bitset_destroy(gva_std_allocator, rhs_dels); + fprintf(stderr, GVA_STRING_FMT " vs " GVA_STRING_FMT "\n", + GVA_STRING_PRINT(trie_string(labels, entries[i].label)), + GVA_STRING_PRINT(trie_string(labels, entries[j].label))); + bool const disjoint = is_disjoint(gva_std_allocator, lhs_graph, rhs_graph); + + if (disjoint == overlap) + { + fprintf(stderr, "ERROR: %d\n", disjoint); + fprintf(stderr, GVA_STRING_FMT " overlap " GVA_STRING_FMT " %zu\n", + GVA_STRING_PRINT(trie_string(labels, entries[i].label)), + GVA_STRING_PRINT(trie_string(labels, entries[j].label)), + (entries[i].distance + entries[j].distance - distance) / 2); + return EXIT_FAILURE; + } // if + gva_lcs_graph_destroy(gva_std_allocator, rhs_graph, false); if (overlap) @@ -1001,6 +1045,6 @@ main(int argc, char* argv[static argc]) { // return allele_main(argc, argv); // return index_main(argc, argv); - return overlap_main(argc, argv); - // return all_main(argc, argv); + // return overlap_main(argc, argv); + return all_main(argc, argv); } // main From ee216c37e70863c30249e4ab46fb95924752c6ba Mon Sep 17 00:00:00 2001 From: jkvis Date: Sat, 18 Apr 2026 18:29:35 +0200 Subject: [PATCH 596/704] More DFAs --- src/main.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/main.c b/src/main.c index e082cce..ffd1e78 100644 --- a/src/main.c +++ b/src/main.c @@ -720,11 +720,12 @@ overlap_main(int argc, char* argv[static argc]) GVA_LCS_Graph lhs = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &lhs_variant); GVA_LCS_Graph rhs = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &rhs_variant); - DFA dfa = dfa_from_lcs_graph(gva_std_allocator, lhs); - - dfa_dot(dfa); - - dfa_destroy(gva_std_allocator, &dfa); + DFA lhs_dfa = dfa_from_lcs_graph(gva_std_allocator, lhs); + DFA rhs_dfa = dfa_from_lcs_graph(gva_std_allocator, rhs); + dfa_dot(lhs_dfa); + dfa_dot(rhs_dfa); + dfa_destroy(gva_std_allocator, &rhs_dfa); + dfa_destroy(gva_std_allocator, &lhs_dfa); fprintf(stderr, "%s\n", GVA_RELATION_LABELS[gva_compare_graphs(gva_std_allocator, reference.len, reference.str, lhs, rhs)]); @@ -1045,6 +1046,6 @@ main(int argc, char* argv[static argc]) { // return allele_main(argc, argv); // return index_main(argc, argv); - // return overlap_main(argc, argv); - return all_main(argc, argv); + return overlap_main(argc, argv); + // return all_main(argc, argv); } // main From e1d92a9f623770699b9f964b0c8340538fb369cb Mon Sep 17 00:00:00 2001 From: jkvis Date: Sun, 19 Apr 2026 10:49:35 +0200 Subject: [PATCH 597/704] WIP: max overlap on DFAs --- src/main.c | 3 + src/nfa.c | 136 +++++++++++++++++++++++++++++++++++++------ src/nfa.h | 11 +++- src/priority_queue.c | 8 +-- src/priority_queue.h | 4 +- 5 files changed, 136 insertions(+), 26 deletions(-) diff --git a/src/main.c b/src/main.c index ffd1e78..524533c 100644 --- a/src/main.c +++ b/src/main.c @@ -724,6 +724,9 @@ overlap_main(int argc, char* argv[static argc]) DFA rhs_dfa = dfa_from_lcs_graph(gva_std_allocator, rhs); dfa_dot(lhs_dfa); dfa_dot(rhs_dfa); + + fprintf(stderr, "OVERLAP: %zu\n", dfa_max_overlap(gva_std_allocator, lhs_dfa, rhs_dfa)); + dfa_destroy(gva_std_allocator, &rhs_dfa); dfa_destroy(gva_std_allocator, &lhs_dfa); diff --git a/src/nfa.c b/src/nfa.c index d337f22..428ca32 100644 --- a/src/nfa.c +++ b/src/nfa.c @@ -7,8 +7,9 @@ #include "../include/string.h" // GVA_String, gva_string_* #include "../include/types.h" // GVA_NULL, gva_uint #include "../include/variant.h" // GVA_Variant -#include "array.h" // ARRAY_*, array_length -#include "nfa.h" // DFA, dfa*, NFA*, nfa_* +#include "array.h" // ARRAY_*, array_length +#include "nfa.h" // DFA, dfa*, NFA*, nfa_* +#include "priority_queue.h" // Priority_Queue, priority_queue_* static inline void @@ -20,7 +21,14 @@ dfa_edge(DFA self[static 1], size_t const width, { for (size_t j = 0; j <= len; ++j) { - self->states[i * width + offset + j].present = 1; + if (i < end) + { + self->states[i * width + offset + j].deletion = 1; + } // if + if (j < len) + { + self->states[i * width + offset + j].insertion = 1; + } // if } // for } // for } // dfa_edge @@ -48,10 +56,8 @@ dfa_from_lcs_graph(GVA_Allocator const allocator, GVA_LCS_Graph const graph) size_t const width = dfa.observed.len + 1; for (size_t i = 0; i < array_length(graph.nodes); ++i) { - dfa.states[graph.nodes[i].match.row * width + graph.nodes[i].match.col].present = 1; for (size_t j = 0; j < graph.nodes[i].match.length; ++j) { - dfa.states[(graph.nodes[i].match.row + j) * width + graph.nodes[i].match.col + j].present = 1; dfa.states[(graph.nodes[i].match.row + j) * width + graph.nodes[i].match.col + j].match = 1; } // for for (gva_uint j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) @@ -80,28 +86,124 @@ dfa_destroy(GVA_Allocator const allocator, DFA self[static 1]) } // dfa_destroy -void -dfa_dot(DFA const self) +size_t +dfa_max_overlap(GVA_Allocator const allocator, DFA const lhs, DFA const rhs) { - size_t const width = self.observed.len + 1; - fprintf(stderr, "strict digraph{\nrankdir=LR\nnode[fixedsize=true,label=\"\",shape=circle,width=1]\ni[shape=none,width=0]\ni->0\n"); - for (size_t i = 0; i < self.size; ++i) + size_t const lhs_width = lhs.observed.len + 1; + size_t const rhs_width = rhs.observed.len + 1; + + Priority_Queue fringe = priority_queue_init(allocator, lhs.size * rhs.size); + priority_queue_push(&fringe, 0, 0, 0); + + size_t count = 0; + while (!priority_queue_empty(fringe)) { - if (self.states[i].present) + count += 1; + size_t const idx = priority_queue_pop(&fringe); + + size_t const lhs_idx = idx / rhs.size; + size_t const rhs_idx = idx % rhs.size; + + fprintf(stderr, "{%zu, %zu} (%zu) :: %u %u\n", lhs_idx, rhs_idx, idx, + fringe.states[idx].included, fringe.states[idx].excluded); + + if (lhs_idx == lhs.size - 1 && rhs_idx == rhs.size - 1) + { + fprintf(stderr, "%u %zu %zu\n", fringe.states[idx].included, count, array_length(fringe.heap)); + break; + } // if + + if (lhs.states[lhs_idx].deletion) + { + if (rhs.states[rhs_idx].deletion) + { + priority_queue_push(&fringe, (lhs_idx + lhs_width) * rhs.size + rhs_idx + rhs_width, + fringe.states[idx].included + 1, fringe.states[idx].excluded); + } // if + if (rhs.states[rhs_idx].insertion) + { + priority_queue_push(&fringe, (lhs_idx + lhs_width) * rhs.size + rhs_idx + 1, + fringe.states[idx].included, fringe.states[idx].excluded + 2); + } // if + if (rhs.states[rhs_idx].match) + { + priority_queue_push(&fringe, (lhs_idx + lhs_width) * rhs.size + rhs_idx + rhs_width + 1, + fringe.states[idx].included, fringe.states[idx].excluded + 1); + } // if + } // if + + if (lhs.states[lhs_idx].insertion) { - if (i < self.size - 1 && self.states[i + 1].present) + if (rhs.states[rhs_idx].deletion) { - fprintf(stderr, "%zu->%zu[label=\"%c\"]\n", i, i + 1, self.observed.str[i % width]); + priority_queue_push(&fringe, (lhs_idx + 1) * rhs.size + rhs_idx + rhs_width, + fringe.states[idx].included, fringe.states[idx].excluded + 2); } // if - if (i < self.size - width && self.states[i + width].present) + if (rhs.states[rhs_idx].insertion) { - fprintf(stderr, "%zu->%zu[label=\"Δ\"]\n", i, i + width); + if (lhs.observed.str[lhs_idx % lhs_width] == rhs.observed.str[rhs_idx % rhs_width]) + { + priority_queue_push(&fringe, (lhs_idx + 1) * rhs.size + rhs_idx + 1, + fringe.states[idx].included + 1, fringe.states[idx].excluded); + } // if + else + { + priority_queue_push(&fringe, (lhs_idx + 1) * rhs.size + rhs_idx + 1, + fringe.states[idx].included, fringe.states[idx].excluded + 2); + } // else } // if - if (self.states[i].match) + if (rhs.states[rhs_idx].match) { - fprintf(stderr, "%zu->%zu[label=\"Μ\"]\n", i, i + width + 1); + priority_queue_push(&fringe, (lhs_idx + 1) * rhs.size + rhs_idx + rhs_width + 1, + fringe.states[idx].included, fringe.states[idx].excluded + 1); } // if } // if + + if (lhs.states[lhs_idx].match) + { + if (rhs.states[rhs_idx].deletion) + { + priority_queue_push(&fringe, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx + rhs_width, + fringe.states[idx].included, fringe.states[idx].excluded + 1); + } // if + if (rhs.states[rhs_idx].insertion) + { + priority_queue_push(&fringe, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx + 1, + fringe.states[idx].included, fringe.states[idx].excluded + 1); + } // if + if (rhs.states[rhs_idx].match) + { + priority_queue_push(&fringe, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx + rhs_width + 1, + fringe.states[idx].included, fringe.states[idx].excluded); + } // if + } // if + } // while + + priority_queue_destroy(&fringe); + + return 0; +} // dfa_max_overlap + + +void +dfa_dot(DFA const self) +{ + size_t const width = self.observed.len + 1; + fprintf(stderr, "strict digraph{\nrankdir=LR\nnode[fixedsize=true,label=\"\",shape=circle,width=1]\ni[shape=none,width=0]\ni->0\n"); + for (size_t i = 0; i < self.size; ++i) + { + if (self.states[i].deletion) + { + fprintf(stderr, "%zu->%zu[label=\"Δ\"]\n", i, i + width); + } // if + if (self.states[i].insertion) + { + fprintf(stderr, "%zu->%zu[label=\"%c\"]\n", i, i + 1, self.observed.str[i % width]); + } // if + if (self.states[i].match) + { + fprintf(stderr, "%zu->%zu[label=\"Μ\"]\n", i, i + width + 1); + } // if } // for fprintf(stderr, "%zu[peripheries=2]\n}\n", self.size - 1); } // dfa_dot diff --git a/src/nfa.h b/src/nfa.h index 6acf7d8..4c7b2ac 100644 --- a/src/nfa.h +++ b/src/nfa.h @@ -13,9 +13,10 @@ typedef struct { - uint8_t present : 1; - uint8_t match : 1; -} DFA_State; // FIXME: could realy be 2 bits + uint8_t deletion : 1; + uint8_t insertion : 1; + uint8_t match : 1; +} DFA_State; // FIXME: could realy be 3 bits typedef struct @@ -34,6 +35,10 @@ void dfa_destroy(GVA_Allocator const allocator, DFA self[static 1]); +size_t +dfa_max_overlap(GVA_Allocator const allocator, DFA const lhs, DFA const rhs); + + // FIXME: DEBUG void dfa_dot(DFA const self); diff --git a/src/priority_queue.c b/src/priority_queue.c index e75669f..91fa3ef 100644 --- a/src/priority_queue.c +++ b/src/priority_queue.c @@ -5,7 +5,7 @@ #include "../include/types.h" // GVA_NULL, gva_uint #include "array.h" // ARRAY_* -#include "priority_queue.h" // Priority_Queue, priority_queue_*, State +#include "priority_queue.h" // Priority_Queue*, priority_queue_* static inline bool @@ -29,7 +29,7 @@ swap(gva_uint lhs[static restrict 1], gva_uint rhs[static restrict 1]) inline Priority_Queue priority_queue_init(GVA_Allocator const allocator, size_t const capacity) { - State* const states = allocator.allocate(allocator.context, NULL, 0, capacity * sizeof(*states)); + Priority_Queue_State* const states = allocator.allocate(allocator.context, NULL, 0, capacity * sizeof(*states)); if (states == NULL) { return (Priority_Queue) {NULL}; @@ -53,7 +53,7 @@ inline void priority_queue_destroy(Priority_Queue self[static 1]) { self->heap = ARRAY_DESTROY(self->allocator, self->heap); - self->states = self->allocator.allocate(self->allocator.context, self->states, self->capacity * sizeof(State), 0); + self->states = self->allocator.allocate(self->allocator.context, self->states, self->capacity * sizeof(*self->states), 0); self->capacity = 0; } // priority_queue_destroy @@ -107,7 +107,7 @@ priority_queue_push(Priority_Queue self[static 1], size_t const key, { if (self->states[key].idx == GVA_NULL) { - self->states[key] = (State) + self->states[key] = (Priority_Queue_State) { .idx = ARRAY_APPEND(self->allocator, self->heap, key), .included = included, diff --git a/src/priority_queue.h b/src/priority_queue.h index 1ac0761..45439f7 100644 --- a/src/priority_queue.h +++ b/src/priority_queue.h @@ -14,13 +14,13 @@ typedef struct gva_uint idx; gva_uint included; gva_uint excluded; -} State; +} Priority_Queue_State; typedef struct { + Priority_Queue_State* states; gva_uint* heap; - State* states; size_t capacity; GVA_Allocator allocator; } Priority_Queue; From 09204d0765d186d1abd3f2e15b2064499383b280 Mon Sep 17 00:00:00 2001 From: jkvis Date: Sun, 19 Apr 2026 13:01:23 +0200 Subject: [PATCH 598/704] FIX end condition --- src/nfa.c | 2 +- src/nfa.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/nfa.c b/src/nfa.c index 428ca32..e661a33 100644 --- a/src/nfa.c +++ b/src/nfa.c @@ -107,7 +107,7 @@ dfa_max_overlap(GVA_Allocator const allocator, DFA const lhs, DFA const rhs) fprintf(stderr, "{%zu, %zu} (%zu) :: %u %u\n", lhs_idx, rhs_idx, idx, fringe.states[idx].included, fringe.states[idx].excluded); - if (lhs_idx == lhs.size - 1 && rhs_idx == rhs.size - 1) + if (lhs_idx == lhs.size - 1 || rhs_idx == rhs.size - 1) { fprintf(stderr, "%u %zu %zu\n", fringe.states[idx].included, count, array_length(fringe.heap)); break; diff --git a/src/nfa.h b/src/nfa.h index 4c7b2ac..e09e6fe 100644 --- a/src/nfa.h +++ b/src/nfa.h @@ -17,6 +17,7 @@ typedef struct uint8_t insertion : 1; uint8_t match : 1; } DFA_State; // FIXME: could realy be 3 bits +// Thm. each state has a maximum of two outgoing transitions. typedef struct From f0c7b4d5f835116e8dfcad52b8cb5efc4ac2c52b Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 20 Apr 2026 16:38:01 +0200 Subject: [PATCH 599/704] WIP: rethinking max overlap --- src/nfa.c | 71 ++++--------------------------------------------------- src/nfa.h | 1 - 2 files changed, 4 insertions(+), 68 deletions(-) diff --git a/src/nfa.c b/src/nfa.c index e661a33..ba98808 100644 --- a/src/nfa.c +++ b/src/nfa.c @@ -38,6 +38,7 @@ DFA dfa_from_lcs_graph(GVA_Allocator const allocator, GVA_LCS_Graph const graph) { GVA_Variant const supremal = gva_lcs_graph_supremal(graph); + size_t const offset = supremal.start; size_t const size = (supremal.end - supremal.start + 1) * (supremal.sequence.len + 1); DFA dfa = { @@ -58,7 +59,7 @@ dfa_from_lcs_graph(GVA_Allocator const allocator, GVA_LCS_Graph const graph) { for (size_t j = 0; j < graph.nodes[i].match.length; ++j) { - dfa.states[(graph.nodes[i].match.row + j) * width + graph.nodes[i].match.col + j].match = 1; + dfa.states[(graph.nodes[i].match.row + j - offset) * width + graph.nodes[i].match.col + j - offset].match = 1; } // for for (gva_uint j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) { @@ -69,7 +70,7 @@ dfa_from_lcs_graph(GVA_Allocator const allocator, GVA_LCS_Graph const graph) &variant); for (size_t k = 0; k < count; ++k) { - dfa_edge(&dfa, width, variant.start + k, variant.end + k, variant.sequence.len, variant.sequence.str - dfa.observed.str + k); + dfa_edge(&dfa, width, variant.start + k - offset, variant.end + k - offset, variant.sequence.len, variant.sequence.str - dfa.observed.str + k); } // for } // for } // for @@ -107,76 +108,12 @@ dfa_max_overlap(GVA_Allocator const allocator, DFA const lhs, DFA const rhs) fprintf(stderr, "{%zu, %zu} (%zu) :: %u %u\n", lhs_idx, rhs_idx, idx, fringe.states[idx].included, fringe.states[idx].excluded); - if (lhs_idx == lhs.size - 1 || rhs_idx == rhs.size - 1) + if (lhs_idx == lhs.size - 1 && rhs_idx == rhs.size - 1) { fprintf(stderr, "%u %zu %zu\n", fringe.states[idx].included, count, array_length(fringe.heap)); break; } // if - if (lhs.states[lhs_idx].deletion) - { - if (rhs.states[rhs_idx].deletion) - { - priority_queue_push(&fringe, (lhs_idx + lhs_width) * rhs.size + rhs_idx + rhs_width, - fringe.states[idx].included + 1, fringe.states[idx].excluded); - } // if - if (rhs.states[rhs_idx].insertion) - { - priority_queue_push(&fringe, (lhs_idx + lhs_width) * rhs.size + rhs_idx + 1, - fringe.states[idx].included, fringe.states[idx].excluded + 2); - } // if - if (rhs.states[rhs_idx].match) - { - priority_queue_push(&fringe, (lhs_idx + lhs_width) * rhs.size + rhs_idx + rhs_width + 1, - fringe.states[idx].included, fringe.states[idx].excluded + 1); - } // if - } // if - - if (lhs.states[lhs_idx].insertion) - { - if (rhs.states[rhs_idx].deletion) - { - priority_queue_push(&fringe, (lhs_idx + 1) * rhs.size + rhs_idx + rhs_width, - fringe.states[idx].included, fringe.states[idx].excluded + 2); - } // if - if (rhs.states[rhs_idx].insertion) - { - if (lhs.observed.str[lhs_idx % lhs_width] == rhs.observed.str[rhs_idx % rhs_width]) - { - priority_queue_push(&fringe, (lhs_idx + 1) * rhs.size + rhs_idx + 1, - fringe.states[idx].included + 1, fringe.states[idx].excluded); - } // if - else - { - priority_queue_push(&fringe, (lhs_idx + 1) * rhs.size + rhs_idx + 1, - fringe.states[idx].included, fringe.states[idx].excluded + 2); - } // else - } // if - if (rhs.states[rhs_idx].match) - { - priority_queue_push(&fringe, (lhs_idx + 1) * rhs.size + rhs_idx + rhs_width + 1, - fringe.states[idx].included, fringe.states[idx].excluded + 1); - } // if - } // if - - if (lhs.states[lhs_idx].match) - { - if (rhs.states[rhs_idx].deletion) - { - priority_queue_push(&fringe, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx + rhs_width, - fringe.states[idx].included, fringe.states[idx].excluded + 1); - } // if - if (rhs.states[rhs_idx].insertion) - { - priority_queue_push(&fringe, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx + 1, - fringe.states[idx].included, fringe.states[idx].excluded + 1); - } // if - if (rhs.states[rhs_idx].match) - { - priority_queue_push(&fringe, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx + rhs_width + 1, - fringe.states[idx].included, fringe.states[idx].excluded); - } // if - } // if } // while priority_queue_destroy(&fringe); diff --git a/src/nfa.h b/src/nfa.h index e09e6fe..4c7b2ac 100644 --- a/src/nfa.h +++ b/src/nfa.h @@ -17,7 +17,6 @@ typedef struct uint8_t insertion : 1; uint8_t match : 1; } DFA_State; // FIXME: could realy be 3 bits -// Thm. each state has a maximum of two outgoing transitions. typedef struct From 5d2cd137e3eb442df8454b3cdfca0b826e9b7f27 Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 20 Apr 2026 17:01:21 +0200 Subject: [PATCH 600/704] WIP: some traversal --- src/nfa.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/src/nfa.c b/src/nfa.c index ba98808..1dad319 100644 --- a/src/nfa.c +++ b/src/nfa.c @@ -114,6 +114,74 @@ dfa_max_overlap(GVA_Allocator const allocator, DFA const lhs, DFA const rhs) break; } // if + if (lhs.states[lhs_idx].deletion) + { + // altijd stilstaan in rhs + priority_queue_push(&fringe, (lhs_idx + lhs_width) * rhs.size + rhs_idx, + fringe.states[idx].included, fringe.states[idx].excluded + 1); + + if (rhs.states[rhs_idx].deletion) + { + priority_queue_push(&fringe, (lhs_idx + lhs_width) * rhs.size + rhs_idx + rhs_width, + fringe.states[idx].included + 1, fringe.states[idx].excluded); + } // if + + // ook de andere combo's? + } // if + + if (lhs.states[lhs_idx].insertion) + { + // altijd stilstaan in rhs + priority_queue_push(&fringe, (lhs_idx + 1) * rhs.size + rhs_idx, + fringe.states[idx].included, fringe.states[idx].excluded + 1); + + if (rhs.states[rhs_idx].insertion && + lhs.observed.str[lhs_idx % lhs_width] == rhs.observed.str[rhs_idx % rhs_width]) + { + priority_queue_push(&fringe, (lhs_idx + 1) * rhs.size + rhs_idx + 1, + fringe.states[idx].included + 1, fringe.states[idx].excluded); + } // if + // ook else? + + // ook de andere combo's? + } // if + + if (lhs.states[lhs_idx].match) + { + // altijd stilstaan in rhs + priority_queue_push(&fringe, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx, + fringe.states[idx].included, fringe.states[idx].excluded); + + if (rhs.states[rhs_idx].match) + { + priority_queue_push(&fringe, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx + rhs_width + 1, + fringe.states[idx].included, fringe.states[idx].excluded); + } // if + + // ook de andere combo's? + } // if + + if (rhs.states[rhs_idx].deletion) + { + // altijd stilstaan in lhs + priority_queue_push(&fringe, lhs_idx * rhs.size + rhs_idx + rhs_width, + fringe.states[idx].included, fringe.states[idx].excluded + 1); + } // if + + if (rhs.states[rhs_idx].insertion) + { + // altijd stilstaan in lhs + priority_queue_push(&fringe, lhs_idx * rhs.size + rhs_idx + 1, + fringe.states[idx].included, fringe.states[idx].excluded + 1); + } // if + + if (rhs.states[rhs_idx].match) + { + // altijd stilstaan in lhs + priority_queue_push(&fringe, lhs_idx * rhs.size + rhs_idx + rhs_width + 1, + fringe.states[idx].included, fringe.states[idx].excluded); + } // if + } // while priority_queue_destroy(&fringe); From 8ae4deaeecb84743b1c2757825e5e7fa511a8113 Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 22 Apr 2026 17:29:49 +0200 Subject: [PATCH 601/704] WIP: synced DFA traversal --- src/nfa.c | 156 ++++++++++++++++++++++++++++++++++-------------------- src/nfa.h | 1 + 2 files changed, 101 insertions(+), 56 deletions(-) diff --git a/src/nfa.c b/src/nfa.c index 1dad319..1eae4e6 100644 --- a/src/nfa.c +++ b/src/nfa.c @@ -38,10 +38,10 @@ DFA dfa_from_lcs_graph(GVA_Allocator const allocator, GVA_LCS_Graph const graph) { GVA_Variant const supremal = gva_lcs_graph_supremal(graph); - size_t const offset = supremal.start; size_t const size = (supremal.end - supremal.start + 1) * (supremal.sequence.len + 1); DFA dfa = { + .start = supremal.start, .observed = supremal.sequence, .states = allocator.allocate(allocator.context, NULL, 0, size), }; @@ -59,7 +59,7 @@ dfa_from_lcs_graph(GVA_Allocator const allocator, GVA_LCS_Graph const graph) { for (size_t j = 0; j < graph.nodes[i].match.length; ++j) { - dfa.states[(graph.nodes[i].match.row + j - offset) * width + graph.nodes[i].match.col + j - offset].match = 1; + dfa.states[(graph.nodes[i].match.row + j - dfa.start) * width + graph.nodes[i].match.col + j - dfa.start].match = 1; } // for for (gva_uint j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) { @@ -70,7 +70,8 @@ dfa_from_lcs_graph(GVA_Allocator const allocator, GVA_LCS_Graph const graph) &variant); for (size_t k = 0; k < count; ++k) { - dfa_edge(&dfa, width, variant.start + k - offset, variant.end + k - offset, variant.sequence.len, variant.sequence.str - dfa.observed.str + k); + dfa_edge(&dfa, width, variant.start + k - dfa.start, variant.end + k - dfa.start, + variant.sequence.len, variant.sequence.str - dfa.observed.str + k); } // for } // for } // for @@ -108,80 +109,123 @@ dfa_max_overlap(GVA_Allocator const allocator, DFA const lhs, DFA const rhs) fprintf(stderr, "{%zu, %zu} (%zu) :: %u %u\n", lhs_idx, rhs_idx, idx, fringe.states[idx].included, fringe.states[idx].excluded); - if (lhs_idx == lhs.size - 1 && rhs_idx == rhs.size - 1) + if (lhs_idx == lhs.size - 1 || rhs_idx == rhs.size - 1) { fprintf(stderr, "%u %zu %zu\n", fringe.states[idx].included, count, array_length(fringe.heap)); break; } // if - if (lhs.states[lhs_idx].deletion) + size_t const lhs_ref = lhs_idx / lhs_width + lhs.start; + size_t const rhs_ref = rhs_idx / rhs_width + rhs.start; + + if (lhs_ref < rhs_ref) { - // altijd stilstaan in rhs - priority_queue_push(&fringe, (lhs_idx + lhs_width) * rhs.size + rhs_idx, - fringe.states[idx].included, fringe.states[idx].excluded + 1); + fprintf(stderr, " LHS behind\n"); - if (rhs.states[rhs_idx].deletion) + if (lhs.states[lhs_idx].deletion) { - priority_queue_push(&fringe, (lhs_idx + lhs_width) * rhs.size + rhs_idx + rhs_width, - fringe.states[idx].included + 1, fringe.states[idx].excluded); + fprintf(stderr, " push (%zu DELTA) {%zu, %zu} (%zu)\n", lhs_ref, lhs_idx + lhs_width, rhs_idx, (lhs_idx + lhs_width) * rhs.size + rhs_idx); + priority_queue_push(&fringe, (lhs_idx + lhs_width) * rhs.size + rhs_idx, + fringe.states[idx].included, fringe.states[idx].excluded + 1); } // if - - // ook de andere combo's? - } // if - - if (lhs.states[lhs_idx].insertion) - { - // altijd stilstaan in rhs - priority_queue_push(&fringe, (lhs_idx + 1) * rhs.size + rhs_idx, - fringe.states[idx].included, fringe.states[idx].excluded + 1); - - if (rhs.states[rhs_idx].insertion && - lhs.observed.str[lhs_idx % lhs_width] == rhs.observed.str[rhs_idx % rhs_width]) + if (lhs.states[lhs_idx].match) { - priority_queue_push(&fringe, (lhs_idx + 1) * rhs.size + rhs_idx + 1, - fringe.states[idx].included + 1, fringe.states[idx].excluded); + fprintf(stderr, " push (%zu MU) {%zu, %zu} (%zu)\n", lhs_ref, lhs_idx + lhs_width + 1, rhs_idx, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx); + priority_queue_push(&fringe, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx, + fringe.states[idx].included, fringe.states[idx].excluded); } // if - // ook else? - // ook de andere combo's? + if (lhs.states[lhs_idx].insertion && !lhs.states[lhs_idx].deletion && !lhs.states[lhs_idx].match) + { + fprintf(stderr, " push (%zu %c) {%zu, %zu} (%zu)\n", lhs_ref, lhs.observed.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx, (lhs_idx + 1) * rhs.size + rhs_idx); + priority_queue_push(&fringe, (lhs_idx + 1) * rhs.size + rhs_idx, + fringe.states[idx].included, fringe.states[idx].excluded + 1); + } // if } // if - - if (lhs.states[lhs_idx].match) + else if (lhs_ref > rhs_ref) { - // altijd stilstaan in rhs - priority_queue_push(&fringe, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx, - fringe.states[idx].included, fringe.states[idx].excluded); + fprintf(stderr, " RHS behind\n"); + if (rhs.states[rhs_idx].deletion) + { + fprintf(stderr, " push (%zu DELTA) {%zu, %zu} (%zu)\n", rhs_ref, lhs_idx, rhs_idx + rhs_width, lhs_idx * rhs.size + rhs_idx + rhs_width); + priority_queue_push(&fringe, lhs_idx * rhs.size + rhs_idx + rhs_width, + fringe.states[idx].included, fringe.states[idx].excluded + 1); + } // if if (rhs.states[rhs_idx].match) { - priority_queue_push(&fringe, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx + rhs_width + 1, + fprintf(stderr, " push (%zu MU) {%zu, %zu} (%zu)\n", rhs_ref, lhs_idx, rhs_idx + rhs_width + 1, lhs_idx * rhs.size + rhs_idx + rhs_width + 1); + priority_queue_push(&fringe, lhs_idx * rhs.size + rhs_idx + rhs_width + 1, fringe.states[idx].included, fringe.states[idx].excluded); } // if - // ook de andere combo's? + if (rhs.states[rhs_idx].insertion && !rhs.states[rhs_idx].deletion && !rhs.states[rhs_idx].match) + { + fprintf(stderr, " push (%zu %c) {%zu, %zu} (%zu)\n", rhs_ref, rhs.observed.str[rhs_idx % rhs_width], lhs_idx, rhs_idx + 1, lhs_idx * rhs.size + rhs_idx + 1); + priority_queue_push(&fringe, lhs_idx * rhs.size + rhs_idx + 1, + fringe.states[idx].included, fringe.states[idx].excluded + 1); + } // if } // if - - if (rhs.states[rhs_idx].deletion) + else { - // altijd stilstaan in lhs - priority_queue_push(&fringe, lhs_idx * rhs.size + rhs_idx + rhs_width, - fringe.states[idx].included, fringe.states[idx].excluded + 1); - } // if + fprintf(stderr, " SYNCed\n"); - if (rhs.states[rhs_idx].insertion) - { - // altijd stilstaan in lhs - priority_queue_push(&fringe, lhs_idx * rhs.size + rhs_idx + 1, - fringe.states[idx].included, fringe.states[idx].excluded + 1); - } // if + if (lhs.states[lhs_idx].deletion) + { + if (rhs.states[rhs_idx].deletion) + { + fprintf(stderr, " push (%zu DELTA) {%zu, %zu} (%zu)\n", lhs_ref, lhs_idx + lhs_width, rhs_idx + rhs_width, (lhs_idx + lhs_width) * rhs.size + rhs_idx + rhs_width); + priority_queue_push(&fringe, (lhs_idx + lhs_width) * rhs.size + rhs_idx + rhs_width, + fringe.states[idx].included + 1, fringe.states[idx].excluded); + } // if + if (rhs.states[rhs_idx].match) + { + fprintf(stderr, " push (%zu DELTA vs %zu MU) {%zu, %zu} (%zu)\n", lhs_ref, rhs_ref, lhs_idx + lhs_width, rhs_idx + rhs_width + 1, (lhs_idx + lhs_width) * rhs.size + rhs_idx + rhs_width + 1); + priority_queue_push(&fringe, (lhs_idx + lhs_width) * rhs.size + rhs_idx + rhs_width + 1, + fringe.states[idx].included, fringe.states[idx].excluded + 1); + } // if + } // if - if (rhs.states[rhs_idx].match) - { - // altijd stilstaan in lhs - priority_queue_push(&fringe, lhs_idx * rhs.size + rhs_idx + rhs_width + 1, - fringe.states[idx].included, fringe.states[idx].excluded); - } // if + bool insertion = false; + if (lhs.states[lhs_idx].insertion && rhs.states[rhs_idx].insertion && + lhs.observed.str[lhs_idx % lhs_width] == rhs.observed.str[rhs_idx % rhs_width]) + { + insertion = true; + fprintf(stderr, " push (%zu %c) {%zu, %zu} (%zu)\n", lhs_ref, lhs.observed.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx + 1, (lhs_idx + 1) * rhs.size + rhs_idx + 1); + priority_queue_push(&fringe, (lhs_idx + 1) * rhs.size + rhs_idx + 1, + fringe.states[idx].included + 1, fringe.states[idx].excluded); + } // if + + if (!insertion && lhs.states[lhs_idx].insertion) + { + fprintf(stderr, " push (%zu %c vs .) {%zu, %zu} (%zu)\n", lhs_ref, lhs.observed.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx, (lhs_idx + 1) * rhs.size + rhs_idx); + priority_queue_push(&fringe, (lhs_idx + 1) * rhs.size + rhs_idx, + fringe.states[idx].included, fringe.states[idx].excluded + 1); + } // if + if (!insertion && rhs.states[rhs_idx].insertion) + { + fprintf(stderr, " push (. vs %zu %c) {%zu, %zu} (%zu)\n", rhs_ref, rhs.observed.str[rhs_idx % rhs_width], lhs_idx, rhs_idx + 1, lhs_idx * rhs.size + rhs_idx + 1); + priority_queue_push(&fringe, lhs_idx * rhs.size + rhs_idx + 1, + fringe.states[idx].included, fringe.states[idx].excluded + 1); + } // if + + if (lhs.states[lhs_idx].match) + { + if (rhs.states[rhs_idx].deletion) + { + fprintf(stderr, " push (%zu MU vs %zu DELTA) {%zu, %zu} (%zu)\n", lhs_ref, rhs_ref, lhs_idx + lhs_width + 1, rhs_idx + rhs_width, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx + rhs_width); + priority_queue_push(&fringe, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx + rhs_width, + fringe.states[idx].included, fringe.states[idx].excluded + 1); + } // if + if (rhs.states[rhs_idx].match) + { + fprintf(stderr, " push (%zu MU) {%zu, %zu} (%zu)\n", lhs_ref, lhs_idx + lhs_width + 1, rhs_idx + rhs_width + 1, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx + rhs_width + 1); + priority_queue_push(&fringe, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx + rhs_width + 1, + fringe.states[idx].included, fringe.states[idx].excluded); + } // if + } // if + } // else } // while priority_queue_destroy(&fringe); @@ -194,20 +238,20 @@ void dfa_dot(DFA const self) { size_t const width = self.observed.len + 1; - fprintf(stderr, "strict digraph{\nrankdir=LR\nnode[fixedsize=true,label=\"\",shape=circle,width=1]\ni[shape=none,width=0]\ni->0\n"); + fprintf(stderr, "strict digraph{\nrankdir=LR\nnode[fixedsize=true,label=\"\",shape=circle,width=1]\ni[label=\"\",shape=none,width=0]\ni->0\n"); for (size_t i = 0; i < self.size; ++i) { if (self.states[i].deletion) { - fprintf(stderr, "%zu->%zu[label=\"Δ\"]\n", i, i + width); + fprintf(stderr, "%zu->%zu[label=\"%zu Δ\"]\n", i, i + width, self.start + i / width); } // if if (self.states[i].insertion) { - fprintf(stderr, "%zu->%zu[label=\"%c\"]\n", i, i + 1, self.observed.str[i % width]); + fprintf(stderr, "%zu->%zu[label=\"%zu %c\"]\n", i, i + 1, self.start + i / width, self.observed.str[i % width]); } // if if (self.states[i].match) { - fprintf(stderr, "%zu->%zu[label=\"Μ\"]\n", i, i + width + 1); + fprintf(stderr, "%zu->%zu[label=\"%zu Μ\"]\n", i, i + width + 1, self.start + i / width); } // if } // for fprintf(stderr, "%zu[peripheries=2]\n}\n", self.size - 1); diff --git a/src/nfa.h b/src/nfa.h index 4c7b2ac..f65f033 100644 --- a/src/nfa.h +++ b/src/nfa.h @@ -21,6 +21,7 @@ typedef struct typedef struct { + size_t start; size_t size; GVA_String observed; DFA_State* states; From 7572124c3f0ec68d1cfdfbeb992d58ab05d1c232 Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 22 Apr 2026 18:03:04 +0200 Subject: [PATCH 602/704] WIP: less states --- src/nfa.c | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/nfa.c b/src/nfa.c index 1eae4e6..b4421e5 100644 --- a/src/nfa.c +++ b/src/nfa.c @@ -178,7 +178,7 @@ dfa_max_overlap(GVA_Allocator const allocator, DFA const lhs, DFA const rhs) priority_queue_push(&fringe, (lhs_idx + lhs_width) * rhs.size + rhs_idx + rhs_width, fringe.states[idx].included + 1, fringe.states[idx].excluded); } // if - if (rhs.states[rhs_idx].match) + else if (rhs.states[rhs_idx].match) { fprintf(stderr, " push (%zu DELTA vs %zu MU) {%zu, %zu} (%zu)\n", lhs_ref, rhs_ref, lhs_idx + lhs_width, rhs_idx + rhs_width + 1, (lhs_idx + lhs_width) * rhs.size + rhs_idx + rhs_width + 1); priority_queue_push(&fringe, (lhs_idx + lhs_width) * rhs.size + rhs_idx + rhs_width + 1, @@ -186,44 +186,44 @@ dfa_max_overlap(GVA_Allocator const allocator, DFA const lhs, DFA const rhs) } // if } // if - bool insertion = false; if (lhs.states[lhs_idx].insertion && rhs.states[rhs_idx].insertion && lhs.observed.str[lhs_idx % lhs_width] == rhs.observed.str[rhs_idx % rhs_width]) { - insertion = true; fprintf(stderr, " push (%zu %c) {%zu, %zu} (%zu)\n", lhs_ref, lhs.observed.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx + 1, (lhs_idx + 1) * rhs.size + rhs_idx + 1); priority_queue_push(&fringe, (lhs_idx + 1) * rhs.size + rhs_idx + 1, fringe.states[idx].included + 1, fringe.states[idx].excluded); } // if - - if (!insertion && lhs.states[lhs_idx].insertion) - { - fprintf(stderr, " push (%zu %c vs .) {%zu, %zu} (%zu)\n", lhs_ref, lhs.observed.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx, (lhs_idx + 1) * rhs.size + rhs_idx); - priority_queue_push(&fringe, (lhs_idx + 1) * rhs.size + rhs_idx, - fringe.states[idx].included, fringe.states[idx].excluded + 1); - } // if - - if (!insertion && rhs.states[rhs_idx].insertion) + else { - fprintf(stderr, " push (. vs %zu %c) {%zu, %zu} (%zu)\n", rhs_ref, rhs.observed.str[rhs_idx % rhs_width], lhs_idx, rhs_idx + 1, lhs_idx * rhs.size + rhs_idx + 1); - priority_queue_push(&fringe, lhs_idx * rhs.size + rhs_idx + 1, - fringe.states[idx].included, fringe.states[idx].excluded + 1); - } // if + if (lhs.states[lhs_idx].insertion) + { + fprintf(stderr, " push (%zu %c vs .) {%zu, %zu} (%zu)\n", lhs_ref, lhs.observed.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx, (lhs_idx + 1) * rhs.size + rhs_idx); + priority_queue_push(&fringe, (lhs_idx + 1) * rhs.size + rhs_idx, + fringe.states[idx].included, fringe.states[idx].excluded + 1); + } // if - if (lhs.states[lhs_idx].match) - { - if (rhs.states[rhs_idx].deletion) + if (rhs.states[rhs_idx].insertion) { - fprintf(stderr, " push (%zu MU vs %zu DELTA) {%zu, %zu} (%zu)\n", lhs_ref, rhs_ref, lhs_idx + lhs_width + 1, rhs_idx + rhs_width, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx + rhs_width); - priority_queue_push(&fringe, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx + rhs_width, + fprintf(stderr, " push (. vs %zu %c) {%zu, %zu} (%zu)\n", rhs_ref, rhs.observed.str[rhs_idx % rhs_width], lhs_idx, rhs_idx + 1, lhs_idx * rhs.size + rhs_idx + 1); + priority_queue_push(&fringe, lhs_idx * rhs.size + rhs_idx + 1, fringe.states[idx].included, fringe.states[idx].excluded + 1); } // if + } // else + + if (lhs.states[lhs_idx].match) + { if (rhs.states[rhs_idx].match) { fprintf(stderr, " push (%zu MU) {%zu, %zu} (%zu)\n", lhs_ref, lhs_idx + lhs_width + 1, rhs_idx + rhs_width + 1, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx + rhs_width + 1); priority_queue_push(&fringe, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx + rhs_width + 1, fringe.states[idx].included, fringe.states[idx].excluded); } // if + else if (rhs.states[rhs_idx].deletion) + { + fprintf(stderr, " push (%zu MU vs %zu DELTA) {%zu, %zu} (%zu)\n", lhs_ref, rhs_ref, lhs_idx + lhs_width + 1, rhs_idx + rhs_width, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx + rhs_width); + priority_queue_push(&fringe, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx + rhs_width, + fringe.states[idx].included, fringe.states[idx].excluded + 1); + } // if } // if } // else } // while From a1c7213ee976dfe3f121c565173f7b18cfc65066 Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 22 Apr 2026 18:08:03 +0200 Subject: [PATCH 603/704] WIP: 1 path in unsynced --- src/nfa.c | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/src/nfa.c b/src/nfa.c index b4421e5..ec2b0cd 100644 --- a/src/nfa.c +++ b/src/nfa.c @@ -122,20 +122,19 @@ dfa_max_overlap(GVA_Allocator const allocator, DFA const lhs, DFA const rhs) { fprintf(stderr, " LHS behind\n"); - if (lhs.states[lhs_idx].deletion) - { - fprintf(stderr, " push (%zu DELTA) {%zu, %zu} (%zu)\n", lhs_ref, lhs_idx + lhs_width, rhs_idx, (lhs_idx + lhs_width) * rhs.size + rhs_idx); - priority_queue_push(&fringe, (lhs_idx + lhs_width) * rhs.size + rhs_idx, - fringe.states[idx].included, fringe.states[idx].excluded + 1); - } // if if (lhs.states[lhs_idx].match) { fprintf(stderr, " push (%zu MU) {%zu, %zu} (%zu)\n", lhs_ref, lhs_idx + lhs_width + 1, rhs_idx, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx); priority_queue_push(&fringe, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx, fringe.states[idx].included, fringe.states[idx].excluded); } // if - - if (lhs.states[lhs_idx].insertion && !lhs.states[lhs_idx].deletion && !lhs.states[lhs_idx].match) + else if (lhs.states[lhs_idx].deletion) + { + fprintf(stderr, " push (%zu DELTA) {%zu, %zu} (%zu)\n", lhs_ref, lhs_idx + lhs_width, rhs_idx, (lhs_idx + lhs_width) * rhs.size + rhs_idx); + priority_queue_push(&fringe, (lhs_idx + lhs_width) * rhs.size + rhs_idx, + fringe.states[idx].included, fringe.states[idx].excluded + 1); + } // if + else if (lhs.states[lhs_idx].insertion) { fprintf(stderr, " push (%zu %c) {%zu, %zu} (%zu)\n", lhs_ref, lhs.observed.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx, (lhs_idx + 1) * rhs.size + rhs_idx); priority_queue_push(&fringe, (lhs_idx + 1) * rhs.size + rhs_idx, @@ -146,20 +145,19 @@ dfa_max_overlap(GVA_Allocator const allocator, DFA const lhs, DFA const rhs) { fprintf(stderr, " RHS behind\n"); - if (rhs.states[rhs_idx].deletion) - { - fprintf(stderr, " push (%zu DELTA) {%zu, %zu} (%zu)\n", rhs_ref, lhs_idx, rhs_idx + rhs_width, lhs_idx * rhs.size + rhs_idx + rhs_width); - priority_queue_push(&fringe, lhs_idx * rhs.size + rhs_idx + rhs_width, - fringe.states[idx].included, fringe.states[idx].excluded + 1); - } // if if (rhs.states[rhs_idx].match) { fprintf(stderr, " push (%zu MU) {%zu, %zu} (%zu)\n", rhs_ref, lhs_idx, rhs_idx + rhs_width + 1, lhs_idx * rhs.size + rhs_idx + rhs_width + 1); priority_queue_push(&fringe, lhs_idx * rhs.size + rhs_idx + rhs_width + 1, fringe.states[idx].included, fringe.states[idx].excluded); } // if - - if (rhs.states[rhs_idx].insertion && !rhs.states[rhs_idx].deletion && !rhs.states[rhs_idx].match) + else if (rhs.states[rhs_idx].deletion) + { + fprintf(stderr, " push (%zu DELTA) {%zu, %zu} (%zu)\n", rhs_ref, lhs_idx, rhs_idx + rhs_width, lhs_idx * rhs.size + rhs_idx + rhs_width); + priority_queue_push(&fringe, lhs_idx * rhs.size + rhs_idx + rhs_width, + fringe.states[idx].included, fringe.states[idx].excluded + 1); + } // if + else if (rhs.states[rhs_idx].insertion) { fprintf(stderr, " push (%zu %c) {%zu, %zu} (%zu)\n", rhs_ref, rhs.observed.str[rhs_idx % rhs_width], lhs_idx, rhs_idx + 1, lhs_idx * rhs.size + rhs_idx + 1); priority_queue_push(&fringe, lhs_idx * rhs.size + rhs_idx + 1, From 0d6ee513e8242f4155908678b1f1a07f6304171f Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 22 Apr 2026 22:10:46 +0200 Subject: [PATCH 604/704] WIP: syncing outside PQ --- src/nfa.c | 174 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 89 insertions(+), 85 deletions(-) diff --git a/src/nfa.c b/src/nfa.c index ec2b0cd..bd4e534 100644 --- a/src/nfa.c +++ b/src/nfa.c @@ -94,8 +94,63 @@ dfa_max_overlap(GVA_Allocator const allocator, DFA const lhs, DFA const rhs) size_t const lhs_width = lhs.observed.len + 1; size_t const rhs_width = rhs.observed.len + 1; + size_t idx = 0; + size_t lhs_ref = lhs.start; + size_t rhs_ref = rhs.start; + size_t excluded = 0; + while (lhs_ref < rhs_ref) + { + size_t const lhs_idx = idx / rhs.size; + size_t const rhs_idx = idx % rhs.size; + if (lhs.states[lhs_idx].match) + { + idx = (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx; + fprintf(stderr, " LHS advance (%zu MU) {%zu, %zu} +0 +0 (%zu)\n", lhs_ref, lhs_idx + lhs_width + 1, rhs_idx, idx); + lhs_ref += 1; + } // if + else if (lhs.states[lhs_idx].deletion) + { + idx = (lhs_idx + lhs_width) * rhs.size + rhs_idx; + fprintf(stderr, " LHS advance (%zu DELTA) {%zu, %zu} +0 +1 (%zu)\n", lhs_ref, lhs_idx + lhs_width, rhs_idx, idx); + lhs_ref += 1; + excluded += 1; + } // if + else // insertion + { + idx = (lhs_idx + 1) * rhs.size + rhs_idx; + fprintf(stderr, " LHS advance (%zu %c) {%zu, %zu} +0 +1 (%zu)\n", lhs_ref, lhs.observed.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx, idx); + excluded += 1; + } // else + } // while + while (rhs_ref < lhs_ref) + { + size_t const lhs_idx = idx / rhs.size; + size_t const rhs_idx = idx % rhs.size; + if (rhs.states[rhs_idx].match) + { + idx = lhs_idx * rhs.size + rhs_idx + rhs_width + 1; + fprintf(stderr, " RHS advance (%zu MU) {%zu, %zu} +0 +0 (%zu)\n", rhs_ref, lhs_idx, rhs_idx + rhs_width + 1, idx); + rhs_ref += 1; + } // if + else if (rhs.states[rhs_idx].deletion) + { + idx = lhs_idx * rhs.size + rhs_idx + rhs_width; + fprintf(stderr, " RHS advance (%zu DELTA) {%zu, %zu} +0 +0 (%zu)\n", rhs_ref, lhs_idx, rhs_idx + rhs_width, idx); + rhs_ref += 1; + excluded += 1; + } // if + else // insertion + { + idx = lhs_idx * rhs.size + rhs_idx + 1; + fprintf(stderr, " RHS advance (%zu %c) {%zu, %zu} +0 +0 (%zu)\n", rhs_ref, rhs.observed.str[rhs_idx % rhs_width], lhs_idx, rhs_idx + 1, idx); + excluded += 1; + } // else + } // while + Priority_Queue fringe = priority_queue_init(allocator, lhs.size * rhs.size); - priority_queue_push(&fringe, 0, 0, 0); + priority_queue_push(&fringe, idx, 0, excluded); + + fprintf(stderr, "SYNCed @ %zu: %zu\n", idx, excluded); size_t count = 0; while (!priority_queue_empty(fringe)) @@ -115,115 +170,64 @@ dfa_max_overlap(GVA_Allocator const allocator, DFA const lhs, DFA const rhs) break; } // if - size_t const lhs_ref = lhs_idx / lhs_width + lhs.start; - size_t const rhs_ref = rhs_idx / rhs_width + rhs.start; - - if (lhs_ref < rhs_ref) + bool matched_deletion = false; + if (lhs.states[lhs_idx].deletion && rhs.states[rhs_idx].deletion) { - fprintf(stderr, " LHS behind\n"); - - if (lhs.states[lhs_idx].match) - { - fprintf(stderr, " push (%zu MU) {%zu, %zu} (%zu)\n", lhs_ref, lhs_idx + lhs_width + 1, rhs_idx, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx); - priority_queue_push(&fringe, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx, - fringe.states[idx].included, fringe.states[idx].excluded); - } // if - else if (lhs.states[lhs_idx].deletion) - { - fprintf(stderr, " push (%zu DELTA) {%zu, %zu} (%zu)\n", lhs_ref, lhs_idx + lhs_width, rhs_idx, (lhs_idx + lhs_width) * rhs.size + rhs_idx); - priority_queue_push(&fringe, (lhs_idx + lhs_width) * rhs.size + rhs_idx, - fringe.states[idx].included, fringe.states[idx].excluded + 1); - } // if - else if (lhs.states[lhs_idx].insertion) - { - fprintf(stderr, " push (%zu %c) {%zu, %zu} (%zu)\n", lhs_ref, lhs.observed.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx, (lhs_idx + 1) * rhs.size + rhs_idx); - priority_queue_push(&fringe, (lhs_idx + 1) * rhs.size + rhs_idx, - fringe.states[idx].included, fringe.states[idx].excluded + 1); - } // if + matched_deletion = true; + fprintf(stderr, " push (%zu DELTA) {%zu, %zu} +1 +0 (%zu)\n", lhs_ref, lhs_idx + lhs_width, rhs_idx + rhs_width, (lhs_idx + lhs_width) * rhs.size + rhs_idx + rhs_width); + priority_queue_push(&fringe, (lhs_idx + lhs_width) * rhs.size + rhs_idx + rhs_width, + fringe.states[idx].included + 1, fringe.states[idx].excluded); } // if - else if (lhs_ref > rhs_ref) + + bool matched_insertion = false; + if (lhs.states[lhs_idx].insertion && rhs.states[rhs_idx].insertion && + lhs.observed.str[lhs_idx % lhs_width] == rhs.observed.str[rhs_idx % rhs_width]) { - fprintf(stderr, " RHS behind\n"); + matched_insertion = true; + fprintf(stderr, " push (%zu %c) {%zu, %zu} +1 +0 (%zu)\n", lhs_ref, lhs.observed.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx + 1, (lhs_idx + 1) * rhs.size + rhs_idx + 1); + priority_queue_push(&fringe, (lhs_idx + 1) * rhs.size + rhs_idx + 1, + fringe.states[idx].included + 1, fringe.states[idx].excluded); + } // if - if (rhs.states[rhs_idx].match) - { - fprintf(stderr, " push (%zu MU) {%zu, %zu} (%zu)\n", rhs_ref, lhs_idx, rhs_idx + rhs_width + 1, lhs_idx * rhs.size + rhs_idx + rhs_width + 1); - priority_queue_push(&fringe, lhs_idx * rhs.size + rhs_idx + rhs_width + 1, - fringe.states[idx].included, fringe.states[idx].excluded); - } // if - else if (rhs.states[rhs_idx].deletion) - { - fprintf(stderr, " push (%zu DELTA) {%zu, %zu} (%zu)\n", rhs_ref, lhs_idx, rhs_idx + rhs_width, lhs_idx * rhs.size + rhs_idx + rhs_width); - priority_queue_push(&fringe, lhs_idx * rhs.size + rhs_idx + rhs_width, - fringe.states[idx].included, fringe.states[idx].excluded + 1); - } // if - else if (rhs.states[rhs_idx].insertion) - { - fprintf(stderr, " push (%zu %c) {%zu, %zu} (%zu)\n", rhs_ref, rhs.observed.str[rhs_idx % rhs_width], lhs_idx, rhs_idx + 1, lhs_idx * rhs.size + rhs_idx + 1); - priority_queue_push(&fringe, lhs_idx * rhs.size + rhs_idx + 1, - fringe.states[idx].included, fringe.states[idx].excluded + 1); - } // if + if (!matched_deletion && !matched_insertion && lhs.states[lhs_idx].match && rhs.states[rhs_idx].match) + { + fprintf(stderr, " push (%zu MU) {%zu, %zu} +0 +0 (%zu)\n", lhs_ref, lhs_idx + lhs_width + 1, rhs_idx + rhs_width + 1, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx + rhs_width + 1); + priority_queue_push(&fringe, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx + rhs_width + 1, + fringe.states[idx].included, fringe.states[idx].excluded); } // if - else + else if (!matched_deletion && !matched_insertion) { - fprintf(stderr, " SYNCed\n"); - - if (lhs.states[lhs_idx].deletion) + if (!matched_deletion) { - if (rhs.states[rhs_idx].deletion) + if (lhs.states[lhs_idx].deletion && rhs.states[rhs_idx].match) { - fprintf(stderr, " push (%zu DELTA) {%zu, %zu} (%zu)\n", lhs_ref, lhs_idx + lhs_width, rhs_idx + rhs_width, (lhs_idx + lhs_width) * rhs.size + rhs_idx + rhs_width); - priority_queue_push(&fringe, (lhs_idx + lhs_width) * rhs.size + rhs_idx + rhs_width, - fringe.states[idx].included + 1, fringe.states[idx].excluded); + fprintf(stderr, " push (%zu DELTA vs %zu MU) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, rhs_ref, lhs_idx + lhs_width, rhs_idx + rhs_width + 1, (lhs_idx + lhs_width) * rhs.size + rhs_idx + rhs_width + 1); + priority_queue_push(&fringe, (lhs_idx + lhs_width) * rhs.size + rhs_idx + rhs_width + 1, + fringe.states[idx].included, fringe.states[idx].excluded + 1); } // if - else if (rhs.states[rhs_idx].match) + else if (lhs.states[lhs_idx].match && rhs.states[rhs_idx].deletion) { - fprintf(stderr, " push (%zu DELTA vs %zu MU) {%zu, %zu} (%zu)\n", lhs_ref, rhs_ref, lhs_idx + lhs_width, rhs_idx + rhs_width + 1, (lhs_idx + lhs_width) * rhs.size + rhs_idx + rhs_width + 1); - priority_queue_push(&fringe, (lhs_idx + lhs_width) * rhs.size + rhs_idx + rhs_width + 1, + fprintf(stderr, " push (%zu MU vs %zu DELTA) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, rhs_ref, lhs_idx + lhs_width + 1, rhs_idx + rhs_width, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx + rhs_width); + priority_queue_push(&fringe, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx + rhs_width, fringe.states[idx].included, fringe.states[idx].excluded + 1); } // if } // if - - if (lhs.states[lhs_idx].insertion && rhs.states[rhs_idx].insertion && - lhs.observed.str[lhs_idx % lhs_width] == rhs.observed.str[rhs_idx % rhs_width]) - { - fprintf(stderr, " push (%zu %c) {%zu, %zu} (%zu)\n", lhs_ref, lhs.observed.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx + 1, (lhs_idx + 1) * rhs.size + rhs_idx + 1); - priority_queue_push(&fringe, (lhs_idx + 1) * rhs.size + rhs_idx + 1, - fringe.states[idx].included + 1, fringe.states[idx].excluded); - } // if - else + if (!matched_insertion) { if (lhs.states[lhs_idx].insertion) { - fprintf(stderr, " push (%zu %c vs .) {%zu, %zu} (%zu)\n", lhs_ref, lhs.observed.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx, (lhs_idx + 1) * rhs.size + rhs_idx); + fprintf(stderr, " push (%zu %c vs .) {%zu, %zu} +0 +1 (%zu)\n", lhs_ref, lhs.observed.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx, (lhs_idx + 1) * rhs.size + rhs_idx); priority_queue_push(&fringe, (lhs_idx + 1) * rhs.size + rhs_idx, fringe.states[idx].included, fringe.states[idx].excluded + 1); } // if - if (rhs.states[rhs_idx].insertion) { - fprintf(stderr, " push (. vs %zu %c) {%zu, %zu} (%zu)\n", rhs_ref, rhs.observed.str[rhs_idx % rhs_width], lhs_idx, rhs_idx + 1, lhs_idx * rhs.size + rhs_idx + 1); + fprintf(stderr, " push (. vs %zu %c) {%zu, %zu} +0 +1 (%zu)\n", rhs_ref, rhs.observed.str[rhs_idx % rhs_width], lhs_idx, rhs_idx + 1, lhs_idx * rhs.size + rhs_idx + 1); priority_queue_push(&fringe, lhs_idx * rhs.size + rhs_idx + 1, fringe.states[idx].included, fringe.states[idx].excluded + 1); } // if - } // else - - if (lhs.states[lhs_idx].match) - { - if (rhs.states[rhs_idx].match) - { - fprintf(stderr, " push (%zu MU) {%zu, %zu} (%zu)\n", lhs_ref, lhs_idx + lhs_width + 1, rhs_idx + rhs_width + 1, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx + rhs_width + 1); - priority_queue_push(&fringe, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx + rhs_width + 1, - fringe.states[idx].included, fringe.states[idx].excluded); - } // if - else if (rhs.states[rhs_idx].deletion) - { - fprintf(stderr, " push (%zu MU vs %zu DELTA) {%zu, %zu} (%zu)\n", lhs_ref, rhs_ref, lhs_idx + lhs_width + 1, rhs_idx + rhs_width, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx + rhs_width); - priority_queue_push(&fringe, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx + rhs_width, - fringe.states[idx].included, fringe.states[idx].excluded + 1); - } // if } // if - } // else + } // if } // while priority_queue_destroy(&fringe); From f31da740e1ada00d403535ea5ce411a919308746 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 23 Apr 2026 10:54:03 +0200 Subject: [PATCH 605/704] WIP: bringing in sync with Python --- src/nfa.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/nfa.c b/src/nfa.c index bd4e534..e4cc7f1 100644 --- a/src/nfa.c +++ b/src/nfa.c @@ -105,20 +105,20 @@ dfa_max_overlap(GVA_Allocator const allocator, DFA const lhs, DFA const rhs) if (lhs.states[lhs_idx].match) { idx = (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx; - fprintf(stderr, " LHS advance (%zu MU) {%zu, %zu} +0 +0 (%zu)\n", lhs_ref, lhs_idx + lhs_width + 1, rhs_idx, idx); + fprintf(stderr, "LHS advance (%zu MU) {%zu, %zu} +0 +0 (%zu)\n", lhs_ref, lhs_idx + lhs_width + 1, rhs_idx, idx); lhs_ref += 1; } // if else if (lhs.states[lhs_idx].deletion) { idx = (lhs_idx + lhs_width) * rhs.size + rhs_idx; - fprintf(stderr, " LHS advance (%zu DELTA) {%zu, %zu} +0 +1 (%zu)\n", lhs_ref, lhs_idx + lhs_width, rhs_idx, idx); + fprintf(stderr, "LHS advance (%zu DELTA) {%zu, %zu} +0 +1 (%zu)\n", lhs_ref, lhs_idx + lhs_width, rhs_idx, idx); lhs_ref += 1; excluded += 1; } // if else // insertion { idx = (lhs_idx + 1) * rhs.size + rhs_idx; - fprintf(stderr, " LHS advance (%zu %c) {%zu, %zu} +0 +1 (%zu)\n", lhs_ref, lhs.observed.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx, idx); + fprintf(stderr, "LHS advance (%zu %c) {%zu, %zu} +0 +1 (%zu)\n", lhs_ref, lhs.observed.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx, idx); excluded += 1; } // else } // while @@ -129,20 +129,20 @@ dfa_max_overlap(GVA_Allocator const allocator, DFA const lhs, DFA const rhs) if (rhs.states[rhs_idx].match) { idx = lhs_idx * rhs.size + rhs_idx + rhs_width + 1; - fprintf(stderr, " RHS advance (%zu MU) {%zu, %zu} +0 +0 (%zu)\n", rhs_ref, lhs_idx, rhs_idx + rhs_width + 1, idx); + fprintf(stderr, "RHS advance (%zu MU) {%zu, %zu} +0 +0 (%zu)\n", rhs_ref, lhs_idx, rhs_idx + rhs_width + 1, idx); rhs_ref += 1; } // if else if (rhs.states[rhs_idx].deletion) { idx = lhs_idx * rhs.size + rhs_idx + rhs_width; - fprintf(stderr, " RHS advance (%zu DELTA) {%zu, %zu} +0 +0 (%zu)\n", rhs_ref, lhs_idx, rhs_idx + rhs_width, idx); + fprintf(stderr, "RHS advance (%zu DELTA) {%zu, %zu} +0 +0 (%zu)\n", rhs_ref, lhs_idx, rhs_idx + rhs_width, idx); rhs_ref += 1; excluded += 1; } // if else // insertion { idx = lhs_idx * rhs.size + rhs_idx + 1; - fprintf(stderr, " RHS advance (%zu %c) {%zu, %zu} +0 +0 (%zu)\n", rhs_ref, rhs.observed.str[rhs_idx % rhs_width], lhs_idx, rhs_idx + 1, idx); + fprintf(stderr, "RHS advance (%zu %c) {%zu, %zu} +0 +0 (%zu)\n", rhs_ref, rhs.observed.str[rhs_idx % rhs_width], lhs_idx, rhs_idx + 1, idx); excluded += 1; } // else } // while @@ -166,7 +166,7 @@ dfa_max_overlap(GVA_Allocator const allocator, DFA const lhs, DFA const rhs) if (lhs_idx == lhs.size - 1 || rhs_idx == rhs.size - 1) { - fprintf(stderr, "%u %zu %zu\n", fringe.states[idx].included, count, array_length(fringe.heap)); + fprintf(stdout, "%u %zu %zu\n", fringe.states[idx].included, count, array_length(fringe.heap)); break; } // if @@ -189,7 +189,7 @@ dfa_max_overlap(GVA_Allocator const allocator, DFA const lhs, DFA const rhs) fringe.states[idx].included + 1, fringe.states[idx].excluded); } // if - if (!matched_deletion && !matched_insertion && lhs.states[lhs_idx].match && rhs.states[rhs_idx].match) + if (lhs.states[lhs_idx].match && rhs.states[rhs_idx].match) { fprintf(stderr, " push (%zu MU) {%zu, %zu} +0 +0 (%zu)\n", lhs_ref, lhs_idx + lhs_width + 1, rhs_idx + rhs_width + 1, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx + rhs_width + 1); priority_queue_push(&fringe, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx + rhs_width + 1, @@ -240,7 +240,7 @@ void dfa_dot(DFA const self) { size_t const width = self.observed.len + 1; - fprintf(stderr, "strict digraph{\nrankdir=LR\nnode[fixedsize=true,label=\"\",shape=circle,width=1]\ni[label=\"\",shape=none,width=0]\ni->0\n"); + fprintf(stderr, "strict digraph{\nrankdir=LR\nnode[fixedsize=true,shape=circle,width=1]\ni[label=\"\",shape=none,width=0]\ni->0\n"); for (size_t i = 0; i < self.size; ++i) { if (self.states[i].deletion) From 834bae13609534fba6cb432523a951ec0c7218c4 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Thu, 23 Apr 2026 15:32:16 +0200 Subject: [PATCH 606/704] WIP: DFA matching. --- src/nfa.c | 211 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 208 insertions(+), 3 deletions(-) diff --git a/src/nfa.c b/src/nfa.c index e4cc7f1..98761fc 100644 --- a/src/nfa.c +++ b/src/nfa.c @@ -94,10 +94,12 @@ dfa_max_overlap(GVA_Allocator const allocator, DFA const lhs, DFA const rhs) size_t const lhs_width = lhs.observed.len + 1; size_t const rhs_width = rhs.observed.len + 1; + /* size_t idx = 0; size_t lhs_ref = lhs.start; size_t rhs_ref = rhs.start; size_t excluded = 0; + while (lhs_ref < rhs_ref) { size_t const lhs_idx = idx / rhs.size; @@ -146,11 +148,12 @@ dfa_max_overlap(GVA_Allocator const allocator, DFA const lhs, DFA const rhs) excluded += 1; } // else } // while + */ Priority_Queue fringe = priority_queue_init(allocator, lhs.size * rhs.size); - priority_queue_push(&fringe, idx, 0, excluded); + priority_queue_push(&fringe, 0, 0, 0); - fprintf(stderr, "SYNCed @ %zu: %zu\n", idx, excluded); + // fprintf(stderr, "SYNCed @ %zu: %zu\n", idx, excluded); size_t count = 0; while (!priority_queue_empty(fringe)) @@ -161,15 +164,216 @@ dfa_max_overlap(GVA_Allocator const allocator, DFA const lhs, DFA const rhs) size_t const lhs_idx = idx / rhs.size; size_t const rhs_idx = idx % rhs.size; + size_t const lhs_ref = lhs_idx / lhs_width + lhs.start; + size_t const rhs_ref = rhs_idx / rhs_width + rhs.start; + fprintf(stderr, "{%zu, %zu} (%zu) :: %u %u\n", lhs_idx, rhs_idx, idx, fringe.states[idx].included, fringe.states[idx].excluded); - if (lhs_idx == lhs.size - 1 || rhs_idx == rhs.size - 1) + if (lhs_idx == lhs.size - 1 && rhs_idx == rhs.size - 1) { fprintf(stdout, "%u %zu %zu\n", fringe.states[idx].included, count, array_length(fringe.heap)); break; } // if + if (lhs_idx == 0 && rhs_ref < lhs_ref) + { + fprintf(stderr, "lhs_ref < rhs_ref: %zu, %zu\n", lhs_ref, rhs_ref); + if (rhs.states[rhs_idx].deletion) + { + fprintf(stderr, " push (. vs %zu DELTA) +0 +1 {%zu, %zu} (%zu)\n", rhs_ref, lhs_idx, rhs_idx + rhs_width, lhs_idx * rhs.size + rhs_idx + rhs_width); + priority_queue_push(&fringe, lhs_idx * rhs.size + rhs_idx + rhs_width, + fringe.states[idx].included, fringe.states[idx].excluded + 1); + } + + if (rhs.states[rhs_idx].match) + { + fprintf(stderr, " push (. vs %zu MU) +0 +0 {%zu, %zu} (%zu)\n", rhs_ref, lhs_idx, rhs_idx + rhs_width + 1, lhs_idx * rhs.size + rhs_idx + rhs_width + 1); + priority_queue_push(&fringe, lhs_idx * rhs.size + rhs_idx + rhs_width + 1, + fringe.states[idx].included, fringe.states[idx].excluded); + } + + if (rhs.states[rhs_idx].insertion) + { + fprintf(stderr, " push (. vs %zu %c) +0 +1 {%zu, %zu} (%zu)\n", rhs_ref, rhs.observed.str[rhs_idx % rhs_width], lhs_idx, rhs_idx + 1, lhs_idx * rhs.size + rhs_idx + 1); + + priority_queue_push(&fringe, lhs_idx * rhs.size + rhs_idx + 1, + fringe.states[idx].included, fringe.states[idx].excluded + 1); + } + continue; + } + + if (rhs_idx == 0 && lhs_ref < rhs_ref) + { + fprintf(stderr, "rhs_ref < lhs_ref: %zu, %zu\n", rhs_ref, lhs_ref); + if (lhs.states[lhs_idx].deletion) + { + fprintf(stderr, " push (%zu DELTA vs .) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, lhs_idx + lhs_width, rhs_idx, (lhs_idx + lhs_width) * rhs.size + rhs_idx); + priority_queue_push(&fringe, (lhs_idx + lhs_width) * rhs.size + rhs_idx, + fringe.states[idx].included, fringe.states[idx].excluded + 1); + } + if (lhs.states[lhs_idx].match) + { + fprintf(stderr, " push (%zu MU vs .) +0 +0 {%zu, %zu} (%zu)\n", lhs_ref, lhs_idx + lhs_width + 1, rhs_idx, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx); + priority_queue_push(&fringe, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx, + fringe.states[idx].included, fringe.states[idx].excluded); + } + + if (lhs.states[lhs_idx].insertion) + { + fprintf(stderr, " push (%zu %c vs .) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, lhs.observed.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx, (lhs_idx + 1) * rhs.size + rhs_idx); + + priority_queue_push(&fringe, (lhs_idx + 1) * rhs.size + rhs_idx, + fringe.states[idx].included, fringe.states[idx].excluded + 1); + } + continue; + } + fprintf(stderr, "SYNCed @ %zu: \n", idx); + + if (lhs.states[lhs_idx].deletion) + { + if (rhs.states[rhs_idx].deletion) + { + fprintf(stderr, " push (%zu DELTA) {%zu, %zu} +1 +0 (%zu)\n", lhs_ref, lhs_idx + lhs_width, rhs_idx + rhs_width, (lhs_idx + lhs_width) * rhs.size + rhs_idx + rhs_width); + priority_queue_push(&fringe, (lhs_idx + lhs_width) * rhs.size + rhs_idx + rhs_width, + fringe.states[idx].included + 1, fringe.states[idx].excluded); + } + + if (rhs.states[rhs_idx].match) + { + fprintf(stderr, " push (%zu DELTA vs %zu MU) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, rhs_ref, lhs_idx + lhs_width, rhs_idx + rhs_width + 1, (lhs_idx + lhs_width) * rhs.size + rhs_idx + rhs_width + 1); + priority_queue_push(&fringe, (lhs_idx + lhs_width) * rhs.size + rhs_idx + rhs_width + 1, + fringe.states[idx].included, fringe.states[idx].excluded + 1); + } + + if (rhs.states[rhs_idx].insertion) + { + fprintf(stderr, " push (. vs %zu %c) {%zu, %zu} +0 +1 (%zu)\n", rhs_ref, rhs.observed.str[rhs_idx % rhs_width], lhs_idx, rhs_idx + 1, lhs_idx * rhs.size + rhs_idx + 1); + priority_queue_push(&fringe, lhs_idx * rhs.size + rhs_idx + 1, + fringe.states[idx].included, fringe.states[idx].excluded + 1); + } + + if (rhs_idx == rhs.size - 1) + { + fprintf(stderr, " push (%zu DELTA vs .) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, lhs_idx + lhs_width, rhs_idx, (lhs_idx + lhs_width) * rhs.size + rhs_idx); + priority_queue_push(&fringe, (lhs_idx + lhs_width) * rhs.size + rhs_idx, + fringe.states[idx].included, fringe.states[idx].excluded + 1); + } + + } + + if (lhs.states[lhs_idx].match) + { + if (rhs.states[rhs_idx].deletion) + { + fprintf(stderr, " push (%zu MU vs %zu DELTA) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, rhs_ref, lhs_idx + lhs_width + 1, rhs_idx + rhs_width, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx + rhs_width); + priority_queue_push(&fringe, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx + rhs_width, + fringe.states[idx].included, fringe.states[idx].excluded + 1); + } + + if (rhs.states[rhs_idx].match) + { + fprintf(stderr, " push (%zu MU) {%zu, %zu} +0 +0 (%zu)\n", lhs_ref, lhs_idx + lhs_width + 1, rhs_idx + rhs_width + 1, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx + rhs_width + 1); + priority_queue_push(&fringe, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx + rhs_width + 1, + fringe.states[idx].included, fringe.states[idx].excluded); + } + + if (rhs.states[rhs_idx].insertion) + { + fprintf(stderr, " push (. vs %zu %c) {%zu, %zu} +0 +1 (%zu)\n", rhs_ref, rhs.observed.str[rhs_idx % rhs_width], lhs_idx, rhs_idx + 1, lhs_idx * rhs.size + rhs_idx + 1); + priority_queue_push(&fringe, lhs_idx * rhs.size + rhs_idx + 1, + fringe.states[idx].included, fringe.states[idx].excluded + 1); + } + + if (rhs_idx == rhs.size - 1) + { + fprintf(stderr, " push (%zu MU vs .) +0 +0 {%zu, %zu} (%zu)\n", lhs_ref, lhs_idx + lhs_width + 1, rhs_idx, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx); + priority_queue_push(&fringe, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx, + fringe.states[idx].included, fringe.states[idx].excluded); + } + } + + if (lhs.states[lhs_idx].insertion) + { + if (rhs.states[rhs_idx].deletion) + { + fprintf(stderr, " push (%zu %c vs .) {%zu, %zu} +0 +1 (%zu)\n", lhs_ref, lhs.observed.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx, (lhs_idx + 1) * rhs.size + rhs_idx); + priority_queue_push(&fringe, (lhs_idx + 1) * rhs.size + rhs_idx, + fringe.states[idx].included, fringe.states[idx].excluded + 1); + } + + if (rhs.states[rhs_idx].match) + { + fprintf(stderr, " push (%zu %c vs .) {%zu, %zu} +0 +1 (%zu)\n", lhs_ref, lhs.observed.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx, (lhs_idx + 1) * rhs.size + rhs_idx); + priority_queue_push(&fringe, (lhs_idx + 1) * rhs.size + rhs_idx, + fringe.states[idx].included, fringe.states[idx].excluded + 1); + + } + + if (rhs.states[rhs_idx].insertion) + { + + if (lhs.observed.str[lhs_idx % lhs_width] == rhs.observed.str[rhs_idx % rhs_width]) + { + fprintf(stderr, " push (%zu %c) {%zu, %zu} +1 +0 (%zu)\n", lhs_ref, lhs.observed.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx + 1, (lhs_idx + 1) * rhs.size + rhs_idx + 1); + priority_queue_push(&fringe, (lhs_idx + 1) * rhs.size + rhs_idx + 1, + fringe.states[idx].included + 1, fringe.states[idx].excluded); + } + else + { + fprintf(stderr, " push (%zu %c vs .) {%zu, %zu} +0 +1 (%zu)\n", lhs_ref, lhs.observed.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx, (lhs_idx + 1) * rhs.size + rhs_idx); + priority_queue_push(&fringe, (lhs_idx + 1) * rhs.size + rhs_idx, + fringe.states[idx].included, fringe.states[idx].excluded + 1); + + fprintf(stderr, " push (. vs %zu %c) {%zu, %zu} +0 +1 (%zu)\n", rhs_ref, rhs.observed.str[rhs_idx % rhs_width], lhs_idx, rhs_idx + 1, lhs_idx * rhs.size + rhs_idx + 1); + priority_queue_push(&fringe, lhs_idx * rhs.size + rhs_idx + 1, + fringe.states[idx].included, fringe.states[idx].excluded + 1); + } + } + + if (rhs_idx == rhs.size - 1) + { + fprintf(stderr, " push (%zu %c vs .) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, lhs.observed.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx, (lhs_idx + 1) * rhs.size + rhs_idx); + + priority_queue_push(&fringe, (lhs_idx + 1) * rhs.size + rhs_idx, + fringe.states[idx].included, fringe.states[idx].excluded + 1); + } + } + + + if (lhs_idx == lhs.size - 1) + { + if (rhs.states[rhs_idx].deletion) + { + fprintf(stderr, " push (. vs %zu DELTA) +0 +1 {%zu, %zu} (%zu)\n", rhs_ref, lhs_idx, rhs_idx + rhs_width, lhs_idx * rhs.size + rhs_idx + rhs_width); + priority_queue_push(&fringe, lhs_idx * rhs.size + rhs_idx + rhs_width, + fringe.states[idx].included, fringe.states[idx].excluded + 1); + } + + if (rhs.states[rhs_idx].match) + { + fprintf(stderr, " push (. vs %zu MU) +0 +0 {%zu, %zu} (%zu)\n", rhs_ref, lhs_idx, rhs_idx + rhs_width + 1, lhs_idx * rhs.size + rhs_idx + rhs_width + 1); + priority_queue_push(&fringe, lhs_idx * rhs.size + rhs_idx + rhs_width + 1, + fringe.states[idx].included, fringe.states[idx].excluded); + } + + if (rhs.states[rhs_idx].insertion) + { + fprintf(stderr, " push (. vs %zu %c) +0 +1 {%zu, %zu} (%zu)\n", rhs_ref, rhs.observed.str[rhs_idx % rhs_width], lhs_idx, rhs_idx + 1, lhs_idx * rhs.size + rhs_idx + 1); + + priority_queue_push(&fringe, lhs_idx * rhs.size + rhs_idx + 1, + fringe.states[idx].included, fringe.states[idx].excluded + 1); + } + + } + +/* + if (lhs_idx == lhs.size - 1 || rhs_idx == rhs.size - 1) + { + // fprintf(stdout, "%u %zu %zu\n", fringe.states[idx].included, count, array_length(fringe.heap)); + // break; + } // if + bool matched_deletion = false; if (lhs.states[lhs_idx].deletion && rhs.states[rhs_idx].deletion) { @@ -228,6 +432,7 @@ dfa_max_overlap(GVA_Allocator const allocator, DFA const lhs, DFA const rhs) } // if } // if } // if + */ } // while priority_queue_destroy(&fringe); From ea1a839659652b9ea42a769eec60e02f484cd78b Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 23 Apr 2026 15:41:55 +0200 Subject: [PATCH 607/704] Cleanup --- src/nfa.c | 191 +++++++++--------------------------------------------- 1 file changed, 30 insertions(+), 161 deletions(-) diff --git a/src/nfa.c b/src/nfa.c index 98761fc..98e2dc6 100644 --- a/src/nfa.c +++ b/src/nfa.c @@ -94,67 +94,9 @@ dfa_max_overlap(GVA_Allocator const allocator, DFA const lhs, DFA const rhs) size_t const lhs_width = lhs.observed.len + 1; size_t const rhs_width = rhs.observed.len + 1; - /* - size_t idx = 0; - size_t lhs_ref = lhs.start; - size_t rhs_ref = rhs.start; - size_t excluded = 0; - - while (lhs_ref < rhs_ref) - { - size_t const lhs_idx = idx / rhs.size; - size_t const rhs_idx = idx % rhs.size; - if (lhs.states[lhs_idx].match) - { - idx = (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx; - fprintf(stderr, "LHS advance (%zu MU) {%zu, %zu} +0 +0 (%zu)\n", lhs_ref, lhs_idx + lhs_width + 1, rhs_idx, idx); - lhs_ref += 1; - } // if - else if (lhs.states[lhs_idx].deletion) - { - idx = (lhs_idx + lhs_width) * rhs.size + rhs_idx; - fprintf(stderr, "LHS advance (%zu DELTA) {%zu, %zu} +0 +1 (%zu)\n", lhs_ref, lhs_idx + lhs_width, rhs_idx, idx); - lhs_ref += 1; - excluded += 1; - } // if - else // insertion - { - idx = (lhs_idx + 1) * rhs.size + rhs_idx; - fprintf(stderr, "LHS advance (%zu %c) {%zu, %zu} +0 +1 (%zu)\n", lhs_ref, lhs.observed.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx, idx); - excluded += 1; - } // else - } // while - while (rhs_ref < lhs_ref) - { - size_t const lhs_idx = idx / rhs.size; - size_t const rhs_idx = idx % rhs.size; - if (rhs.states[rhs_idx].match) - { - idx = lhs_idx * rhs.size + rhs_idx + rhs_width + 1; - fprintf(stderr, "RHS advance (%zu MU) {%zu, %zu} +0 +0 (%zu)\n", rhs_ref, lhs_idx, rhs_idx + rhs_width + 1, idx); - rhs_ref += 1; - } // if - else if (rhs.states[rhs_idx].deletion) - { - idx = lhs_idx * rhs.size + rhs_idx + rhs_width; - fprintf(stderr, "RHS advance (%zu DELTA) {%zu, %zu} +0 +0 (%zu)\n", rhs_ref, lhs_idx, rhs_idx + rhs_width, idx); - rhs_ref += 1; - excluded += 1; - } // if - else // insertion - { - idx = lhs_idx * rhs.size + rhs_idx + 1; - fprintf(stderr, "RHS advance (%zu %c) {%zu, %zu} +0 +0 (%zu)\n", rhs_ref, rhs.observed.str[rhs_idx % rhs_width], lhs_idx, rhs_idx + 1, idx); - excluded += 1; - } // else - } // while - */ - Priority_Queue fringe = priority_queue_init(allocator, lhs.size * rhs.size); priority_queue_push(&fringe, 0, 0, 0); - // fprintf(stderr, "SYNCed @ %zu: %zu\n", idx, excluded); - size_t count = 0; while (!priority_queue_empty(fringe)) { @@ -184,24 +126,23 @@ dfa_max_overlap(GVA_Allocator const allocator, DFA const lhs, DFA const rhs) fprintf(stderr, " push (. vs %zu DELTA) +0 +1 {%zu, %zu} (%zu)\n", rhs_ref, lhs_idx, rhs_idx + rhs_width, lhs_idx * rhs.size + rhs_idx + rhs_width); priority_queue_push(&fringe, lhs_idx * rhs.size + rhs_idx + rhs_width, fringe.states[idx].included, fringe.states[idx].excluded + 1); - } + } // if if (rhs.states[rhs_idx].match) { fprintf(stderr, " push (. vs %zu MU) +0 +0 {%zu, %zu} (%zu)\n", rhs_ref, lhs_idx, rhs_idx + rhs_width + 1, lhs_idx * rhs.size + rhs_idx + rhs_width + 1); priority_queue_push(&fringe, lhs_idx * rhs.size + rhs_idx + rhs_width + 1, fringe.states[idx].included, fringe.states[idx].excluded); - } + } // if if (rhs.states[rhs_idx].insertion) { fprintf(stderr, " push (. vs %zu %c) +0 +1 {%zu, %zu} (%zu)\n", rhs_ref, rhs.observed.str[rhs_idx % rhs_width], lhs_idx, rhs_idx + 1, lhs_idx * rhs.size + rhs_idx + 1); - priority_queue_push(&fringe, lhs_idx * rhs.size + rhs_idx + 1, fringe.states[idx].included, fringe.states[idx].excluded + 1); - } + } // if continue; - } + } // if if (rhs_idx == 0 && lhs_ref < rhs_ref) { @@ -211,13 +152,14 @@ dfa_max_overlap(GVA_Allocator const allocator, DFA const lhs, DFA const rhs) fprintf(stderr, " push (%zu DELTA vs .) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, lhs_idx + lhs_width, rhs_idx, (lhs_idx + lhs_width) * rhs.size + rhs_idx); priority_queue_push(&fringe, (lhs_idx + lhs_width) * rhs.size + rhs_idx, fringe.states[idx].included, fringe.states[idx].excluded + 1); - } + } // if + if (lhs.states[lhs_idx].match) { fprintf(stderr, " push (%zu MU vs .) +0 +0 {%zu, %zu} (%zu)\n", lhs_ref, lhs_idx + lhs_width + 1, rhs_idx, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx); priority_queue_push(&fringe, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx, fringe.states[idx].included, fringe.states[idx].excluded); - } + } // if if (lhs.states[lhs_idx].insertion) { @@ -225,10 +167,11 @@ dfa_max_overlap(GVA_Allocator const allocator, DFA const lhs, DFA const rhs) priority_queue_push(&fringe, (lhs_idx + 1) * rhs.size + rhs_idx, fringe.states[idx].included, fringe.states[idx].excluded + 1); - } + } // if continue; - } - fprintf(stderr, "SYNCed @ %zu: \n", idx); + } // if + + fprintf(stderr, "SYNCed @ %zu\n", idx); if (lhs.states[lhs_idx].deletion) { @@ -237,30 +180,29 @@ dfa_max_overlap(GVA_Allocator const allocator, DFA const lhs, DFA const rhs) fprintf(stderr, " push (%zu DELTA) {%zu, %zu} +1 +0 (%zu)\n", lhs_ref, lhs_idx + lhs_width, rhs_idx + rhs_width, (lhs_idx + lhs_width) * rhs.size + rhs_idx + rhs_width); priority_queue_push(&fringe, (lhs_idx + lhs_width) * rhs.size + rhs_idx + rhs_width, fringe.states[idx].included + 1, fringe.states[idx].excluded); - } + } // if if (rhs.states[rhs_idx].match) { fprintf(stderr, " push (%zu DELTA vs %zu MU) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, rhs_ref, lhs_idx + lhs_width, rhs_idx + rhs_width + 1, (lhs_idx + lhs_width) * rhs.size + rhs_idx + rhs_width + 1); priority_queue_push(&fringe, (lhs_idx + lhs_width) * rhs.size + rhs_idx + rhs_width + 1, fringe.states[idx].included, fringe.states[idx].excluded + 1); - } + } // if if (rhs.states[rhs_idx].insertion) { fprintf(stderr, " push (. vs %zu %c) {%zu, %zu} +0 +1 (%zu)\n", rhs_ref, rhs.observed.str[rhs_idx % rhs_width], lhs_idx, rhs_idx + 1, lhs_idx * rhs.size + rhs_idx + 1); priority_queue_push(&fringe, lhs_idx * rhs.size + rhs_idx + 1, fringe.states[idx].included, fringe.states[idx].excluded + 1); - } + } // if if (rhs_idx == rhs.size - 1) { fprintf(stderr, " push (%zu DELTA vs .) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, lhs_idx + lhs_width, rhs_idx, (lhs_idx + lhs_width) * rhs.size + rhs_idx); priority_queue_push(&fringe, (lhs_idx + lhs_width) * rhs.size + rhs_idx, fringe.states[idx].included, fringe.states[idx].excluded + 1); - } - - } + } // if + } // if if (lhs.states[lhs_idx].match) { @@ -269,29 +211,29 @@ dfa_max_overlap(GVA_Allocator const allocator, DFA const lhs, DFA const rhs) fprintf(stderr, " push (%zu MU vs %zu DELTA) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, rhs_ref, lhs_idx + lhs_width + 1, rhs_idx + rhs_width, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx + rhs_width); priority_queue_push(&fringe, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx + rhs_width, fringe.states[idx].included, fringe.states[idx].excluded + 1); - } + } // if if (rhs.states[rhs_idx].match) { fprintf(stderr, " push (%zu MU) {%zu, %zu} +0 +0 (%zu)\n", lhs_ref, lhs_idx + lhs_width + 1, rhs_idx + rhs_width + 1, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx + rhs_width + 1); priority_queue_push(&fringe, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx + rhs_width + 1, fringe.states[idx].included, fringe.states[idx].excluded); - } + } // if if (rhs.states[rhs_idx].insertion) { fprintf(stderr, " push (. vs %zu %c) {%zu, %zu} +0 +1 (%zu)\n", rhs_ref, rhs.observed.str[rhs_idx % rhs_width], lhs_idx, rhs_idx + 1, lhs_idx * rhs.size + rhs_idx + 1); priority_queue_push(&fringe, lhs_idx * rhs.size + rhs_idx + 1, fringe.states[idx].included, fringe.states[idx].excluded + 1); - } + } // if if (rhs_idx == rhs.size - 1) { fprintf(stderr, " push (%zu MU vs .) +0 +0 {%zu, %zu} (%zu)\n", lhs_ref, lhs_idx + lhs_width + 1, rhs_idx, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx); priority_queue_push(&fringe, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx, fringe.states[idx].included, fringe.states[idx].excluded); - } - } + } // if + } // if if (lhs.states[lhs_idx].insertion) { @@ -300,25 +242,23 @@ dfa_max_overlap(GVA_Allocator const allocator, DFA const lhs, DFA const rhs) fprintf(stderr, " push (%zu %c vs .) {%zu, %zu} +0 +1 (%zu)\n", lhs_ref, lhs.observed.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx, (lhs_idx + 1) * rhs.size + rhs_idx); priority_queue_push(&fringe, (lhs_idx + 1) * rhs.size + rhs_idx, fringe.states[idx].included, fringe.states[idx].excluded + 1); - } + } // if if (rhs.states[rhs_idx].match) { fprintf(stderr, " push (%zu %c vs .) {%zu, %zu} +0 +1 (%zu)\n", lhs_ref, lhs.observed.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx, (lhs_idx + 1) * rhs.size + rhs_idx); priority_queue_push(&fringe, (lhs_idx + 1) * rhs.size + rhs_idx, fringe.states[idx].included, fringe.states[idx].excluded + 1); - - } + } // if if (rhs.states[rhs_idx].insertion) { - if (lhs.observed.str[lhs_idx % lhs_width] == rhs.observed.str[rhs_idx % rhs_width]) { fprintf(stderr, " push (%zu %c) {%zu, %zu} +1 +0 (%zu)\n", lhs_ref, lhs.observed.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx + 1, (lhs_idx + 1) * rhs.size + rhs_idx + 1); priority_queue_push(&fringe, (lhs_idx + 1) * rhs.size + rhs_idx + 1, fringe.states[idx].included + 1, fringe.states[idx].excluded); - } + } // if else { fprintf(stderr, " push (%zu %c vs .) {%zu, %zu} +0 +1 (%zu)\n", lhs_ref, lhs.observed.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx, (lhs_idx + 1) * rhs.size + rhs_idx); @@ -328,18 +268,16 @@ dfa_max_overlap(GVA_Allocator const allocator, DFA const lhs, DFA const rhs) fprintf(stderr, " push (. vs %zu %c) {%zu, %zu} +0 +1 (%zu)\n", rhs_ref, rhs.observed.str[rhs_idx % rhs_width], lhs_idx, rhs_idx + 1, lhs_idx * rhs.size + rhs_idx + 1); priority_queue_push(&fringe, lhs_idx * rhs.size + rhs_idx + 1, fringe.states[idx].included, fringe.states[idx].excluded + 1); - } - } + } // else + } // if if (rhs_idx == rhs.size - 1) { fprintf(stderr, " push (%zu %c vs .) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, lhs.observed.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx, (lhs_idx + 1) * rhs.size + rhs_idx); - priority_queue_push(&fringe, (lhs_idx + 1) * rhs.size + rhs_idx, fringe.states[idx].included, fringe.states[idx].excluded + 1); - } - } - + } // if + } // if if (lhs_idx == lhs.size - 1) { @@ -348,91 +286,22 @@ dfa_max_overlap(GVA_Allocator const allocator, DFA const lhs, DFA const rhs) fprintf(stderr, " push (. vs %zu DELTA) +0 +1 {%zu, %zu} (%zu)\n", rhs_ref, lhs_idx, rhs_idx + rhs_width, lhs_idx * rhs.size + rhs_idx + rhs_width); priority_queue_push(&fringe, lhs_idx * rhs.size + rhs_idx + rhs_width, fringe.states[idx].included, fringe.states[idx].excluded + 1); - } + } // if if (rhs.states[rhs_idx].match) { fprintf(stderr, " push (. vs %zu MU) +0 +0 {%zu, %zu} (%zu)\n", rhs_ref, lhs_idx, rhs_idx + rhs_width + 1, lhs_idx * rhs.size + rhs_idx + rhs_width + 1); priority_queue_push(&fringe, lhs_idx * rhs.size + rhs_idx + rhs_width + 1, fringe.states[idx].included, fringe.states[idx].excluded); - } + } // if if (rhs.states[rhs_idx].insertion) { fprintf(stderr, " push (. vs %zu %c) +0 +1 {%zu, %zu} (%zu)\n", rhs_ref, rhs.observed.str[rhs_idx % rhs_width], lhs_idx, rhs_idx + 1, lhs_idx * rhs.size + rhs_idx + 1); - priority_queue_push(&fringe, lhs_idx * rhs.size + rhs_idx + 1, fringe.states[idx].included, fringe.states[idx].excluded + 1); - } - - } - -/* - if (lhs_idx == lhs.size - 1 || rhs_idx == rhs.size - 1) - { - // fprintf(stdout, "%u %zu %zu\n", fringe.states[idx].included, count, array_length(fringe.heap)); - // break; - } // if - - bool matched_deletion = false; - if (lhs.states[lhs_idx].deletion && rhs.states[rhs_idx].deletion) - { - matched_deletion = true; - fprintf(stderr, " push (%zu DELTA) {%zu, %zu} +1 +0 (%zu)\n", lhs_ref, lhs_idx + lhs_width, rhs_idx + rhs_width, (lhs_idx + lhs_width) * rhs.size + rhs_idx + rhs_width); - priority_queue_push(&fringe, (lhs_idx + lhs_width) * rhs.size + rhs_idx + rhs_width, - fringe.states[idx].included + 1, fringe.states[idx].excluded); - } // if - - bool matched_insertion = false; - if (lhs.states[lhs_idx].insertion && rhs.states[rhs_idx].insertion && - lhs.observed.str[lhs_idx % lhs_width] == rhs.observed.str[rhs_idx % rhs_width]) - { - matched_insertion = true; - fprintf(stderr, " push (%zu %c) {%zu, %zu} +1 +0 (%zu)\n", lhs_ref, lhs.observed.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx + 1, (lhs_idx + 1) * rhs.size + rhs_idx + 1); - priority_queue_push(&fringe, (lhs_idx + 1) * rhs.size + rhs_idx + 1, - fringe.states[idx].included + 1, fringe.states[idx].excluded); - } // if - - if (lhs.states[lhs_idx].match && rhs.states[rhs_idx].match) - { - fprintf(stderr, " push (%zu MU) {%zu, %zu} +0 +0 (%zu)\n", lhs_ref, lhs_idx + lhs_width + 1, rhs_idx + rhs_width + 1, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx + rhs_width + 1); - priority_queue_push(&fringe, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx + rhs_width + 1, - fringe.states[idx].included, fringe.states[idx].excluded); - } // if - else if (!matched_deletion && !matched_insertion) - { - if (!matched_deletion) - { - if (lhs.states[lhs_idx].deletion && rhs.states[rhs_idx].match) - { - fprintf(stderr, " push (%zu DELTA vs %zu MU) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, rhs_ref, lhs_idx + lhs_width, rhs_idx + rhs_width + 1, (lhs_idx + lhs_width) * rhs.size + rhs_idx + rhs_width + 1); - priority_queue_push(&fringe, (lhs_idx + lhs_width) * rhs.size + rhs_idx + rhs_width + 1, - fringe.states[idx].included, fringe.states[idx].excluded + 1); - } // if - else if (lhs.states[lhs_idx].match && rhs.states[rhs_idx].deletion) - { - fprintf(stderr, " push (%zu MU vs %zu DELTA) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, rhs_ref, lhs_idx + lhs_width + 1, rhs_idx + rhs_width, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx + rhs_width); - priority_queue_push(&fringe, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx + rhs_width, - fringe.states[idx].included, fringe.states[idx].excluded + 1); - } // if - } // if - if (!matched_insertion) - { - if (lhs.states[lhs_idx].insertion) - { - fprintf(stderr, " push (%zu %c vs .) {%zu, %zu} +0 +1 (%zu)\n", lhs_ref, lhs.observed.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx, (lhs_idx + 1) * rhs.size + rhs_idx); - priority_queue_push(&fringe, (lhs_idx + 1) * rhs.size + rhs_idx, - fringe.states[idx].included, fringe.states[idx].excluded + 1); - } // if - if (rhs.states[rhs_idx].insertion) - { - fprintf(stderr, " push (. vs %zu %c) {%zu, %zu} +0 +1 (%zu)\n", rhs_ref, rhs.observed.str[rhs_idx % rhs_width], lhs_idx, rhs_idx + 1, lhs_idx * rhs.size + rhs_idx + 1); - priority_queue_push(&fringe, lhs_idx * rhs.size + rhs_idx + 1, - fringe.states[idx].included, fringe.states[idx].excluded + 1); - } // if } // if } // if - */ } // while priority_queue_destroy(&fringe); From 0a925250d2c7330082db429b805533502e260cac Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 23 Apr 2026 21:56:14 +0200 Subject: [PATCH 608/704] WIP: DFA overlap: no diff with Python --- src/nfa.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/nfa.c b/src/nfa.c index 98e2dc6..685ea71 100644 --- a/src/nfa.c +++ b/src/nfa.c @@ -120,7 +120,6 @@ dfa_max_overlap(GVA_Allocator const allocator, DFA const lhs, DFA const rhs) if (lhs_idx == 0 && rhs_ref < lhs_ref) { - fprintf(stderr, "lhs_ref < rhs_ref: %zu, %zu\n", lhs_ref, rhs_ref); if (rhs.states[rhs_idx].deletion) { fprintf(stderr, " push (. vs %zu DELTA) +0 +1 {%zu, %zu} (%zu)\n", rhs_ref, lhs_idx, rhs_idx + rhs_width, lhs_idx * rhs.size + rhs_idx + rhs_width); @@ -146,7 +145,6 @@ dfa_max_overlap(GVA_Allocator const allocator, DFA const lhs, DFA const rhs) if (rhs_idx == 0 && lhs_ref < rhs_ref) { - fprintf(stderr, "rhs_ref < lhs_ref: %zu, %zu\n", rhs_ref, lhs_ref); if (lhs.states[lhs_idx].deletion) { fprintf(stderr, " push (%zu DELTA vs .) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, lhs_idx + lhs_width, rhs_idx, (lhs_idx + lhs_width) * rhs.size + rhs_idx); @@ -164,15 +162,12 @@ dfa_max_overlap(GVA_Allocator const allocator, DFA const lhs, DFA const rhs) if (lhs.states[lhs_idx].insertion) { fprintf(stderr, " push (%zu %c vs .) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, lhs.observed.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx, (lhs_idx + 1) * rhs.size + rhs_idx); - priority_queue_push(&fringe, (lhs_idx + 1) * rhs.size + rhs_idx, fringe.states[idx].included, fringe.states[idx].excluded + 1); } // if continue; } // if - fprintf(stderr, "SYNCed @ %zu\n", idx); - if (lhs.states[lhs_idx].deletion) { if (rhs.states[rhs_idx].deletion) From a06089833036beecf9f218c8cf578104389d4e88 Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 24 Apr 2026 23:08:39 +0200 Subject: [PATCH 609/704] WIP: testing 2bit DFAs --- src/main.c | 201 ++++++----------------------------------------------- src/nfa.c | 112 ++++++++++++++++++++++++++++- src/nfa.h | 19 +++++ 3 files changed, 151 insertions(+), 181 deletions(-) diff --git a/src/main.c b/src/main.c index 524533c..0591cfa 100644 --- a/src/main.c +++ b/src/main.c @@ -32,170 +32,6 @@ #define REFERENCE_ID "NC_000001.11" -static inline bool -variant_disjoint(size_t const lhs_count, GVA_Variant const lhs, - size_t const rhs_count, GVA_Variant const rhs) -{ - if (rhs.start > lhs.end + lhs_count - 1 || - lhs.start > rhs.end + rhs_count - 1) - { - return true; - } // if - - size_t lhs_offset = 0; - size_t rhs_offset = 0; - if (rhs.start > lhs.start) - { - lhs_offset = MIN(rhs.start - lhs.start, lhs_count - 1); - } // if - else if (lhs.start > rhs.start) - { - rhs_offset = MIN(lhs.start - rhs.start, rhs_count - 1); - } // if - - size_t const start = MAX(lhs.start + lhs_offset, rhs.start + rhs_offset); - size_t const end = MIN(lhs.end + lhs_offset, rhs.end + rhs_offset); - - if (end > start) - { - return false; - } // if - - unsigned __int128 lhs_seq = 0; - for (size_t i = 0; i < lhs.sequence.len; ++i) - { - lhs_seq |= 1 << (lhs.sequence.str[lhs_offset + i] & 0x7f); - } // for - unsigned __int128 rhs_seq = 0; - for (size_t i = 0; i < rhs.sequence.len; ++i) - { - rhs_seq |= 1 << (rhs.sequence.str[rhs_offset + i] & 0x7f); - } // for - - return (lhs_seq & rhs_seq) == 0; -} // variant_disjoint - - -static bool -is_disjoint(GVA_Allocator const allocator, - GVA_LCS_Graph const lhs, GVA_LCS_Graph const rhs) -{ - size_t const rhs_nodes = array_length(rhs.nodes); - size_t const length = array_length(lhs.nodes) * rhs_nodes; - struct - { - gva_uint seen; - gva_uint next; - }* queue = allocator.allocate(allocator.context, NULL, 0, length * sizeof(*queue)); - if (queue == NULL) - { - return true; // FIXME: OOM - } // if - - for (size_t i = 0; i < length; ++i) - { - queue[i].seen = false; - queue[i].next = GVA_NULL; - } // for - - gva_uint tail = lhs.source * rhs_nodes + rhs.source; - for (gva_uint head = tail; head != GVA_NULL; head = queue[head].next) - { - size_t const lhs_idx = head / rhs_nodes; - size_t const rhs_idx = head % rhs_nodes; - - fprintf(stderr, "{%zu, %zu}\n", lhs_idx, rhs_idx); - - for (gva_uint i = lhs.nodes[lhs_idx].edges; i != GVA_NULL; i = lhs.edges[i].next) - { - GVA_Variant lhs_variant = {0}; - size_t const lhs_count = gva_edges(lhs.observed.str, - lhs.nodes[lhs_idx].match, lhs.nodes[lhs.edges[i].tail].match, - lhs_idx == lhs.source, lhs.nodes[lhs.edges[i].tail].edges == GVA_NULL, - &lhs_variant); - - for (gva_uint j = rhs.nodes[rhs_idx].edges; j != GVA_NULL; j = rhs.edges[j].next) - { - GVA_Variant rhs_variant = {0}; - size_t const rhs_count = gva_edges(rhs.observed.str, - rhs.nodes[rhs_idx].match, rhs.nodes[rhs.edges[j].tail].match, - rhs_idx == rhs.source, rhs.nodes[rhs.edges[j].tail].edges == GVA_NULL, - &rhs_variant); - - //fprintf(stderr, " " GVA_VARIANT_FMT " x %zu vs " GVA_VARIANT_FMT " x %zu\n", - // GVA_VARIANT_PRINT(lhs_variant), lhs_count, GVA_VARIANT_PRINT(rhs_variant), rhs_count); - - if (!variant_disjoint(lhs_count, lhs_variant, rhs_count, rhs_variant)) - { - queue = allocator.allocate(allocator.context, queue, length * sizeof(*queue), 0); - return false; - } // if - - size_t const next = lhs.edges[i].tail * rhs_nodes + rhs.edges[j].tail; - if (lhs.nodes[lhs.edges[i].tail].edges != GVA_NULL && - rhs.nodes[rhs.edges[j].tail].edges != GVA_NULL && - !queue[next].seen) - { - queue[tail].next = next; - tail = next; - queue[next].seen = true; - } // if - } // for - } // for - - if (lhs.nodes[lhs_idx].lambda != GVA_NULL) - { - size_t const next = lhs.nodes[lhs_idx].lambda * rhs_nodes + rhs_idx; - if (!queue[next].seen) - { - //fprintf(stderr, " lambda lhs: {%u, %zu}\n", lhs.nodes[lhs_idx].lambda, rhs_idx); - queue[tail].next = next; - tail = next; - queue[next].seen = true; - } // if - } // if - if (rhs.nodes[rhs_idx].lambda != GVA_NULL) - { - size_t const next = lhs_idx * rhs_nodes + rhs.nodes[rhs_idx].lambda; - if (!queue[next].seen) - { - //fprintf(stderr, " lambda rhs: {%zu, %u}\n", lhs_idx, rhs.nodes[rhs_idx].lambda); - queue[tail].next = next; - tail = next; - queue[next].seen = true; - } // if - } // if - - for (gva_uint i = lhs.nodes[lhs_idx].edges; i != GVA_NULL; i = lhs.edges[i].next) - { - size_t const next = lhs.edges[i].tail * rhs_nodes + rhs_idx; - if (lhs.nodes[lhs.edges[i].tail].edges != GVA_NULL && !queue[next].seen) - { - //fprintf(stderr, " advance lhs: {%u, %zu}\n", lhs.edges[i].tail, rhs_idx); - queue[tail].next = next; - tail = next; - queue[next].seen = true; - } // if - } // for - for (gva_uint i = rhs.nodes[rhs_idx].edges; i != GVA_NULL; i = rhs.edges[i].next) - { - size_t const next = lhs_idx * rhs_nodes + rhs.edges[i].tail; - if (rhs.nodes[rhs.edges[i].tail].edges != GVA_NULL && !queue[next].seen) - { - //fprintf(stderr, " advance rhs: {%zu, %u}\n", lhs_idx, rhs.edges[i].tail); - queue[tail].next = next; - tail = next; - queue[next].seen = true; - } // if - } // for - - } // for - - queue = allocator.allocate(allocator.context, queue, length * sizeof(*queue), 0); - return true; -} // is_disjoint - - // line: alphanumeric_id SPDI [distance] static bool parse_line(char const line[static restrict LINE_SIZE], @@ -992,21 +828,6 @@ all_main(int argc, char* argv[static argc]) rhs_as = bitset_destroy(gva_std_allocator, rhs_as); rhs_dels = bitset_destroy(gva_std_allocator, rhs_dels); - fprintf(stderr, GVA_STRING_FMT " vs " GVA_STRING_FMT "\n", - GVA_STRING_PRINT(trie_string(labels, entries[i].label)), - GVA_STRING_PRINT(trie_string(labels, entries[j].label))); - bool const disjoint = is_disjoint(gva_std_allocator, lhs_graph, rhs_graph); - - if (disjoint == overlap) - { - fprintf(stderr, "ERROR: %d\n", disjoint); - fprintf(stderr, GVA_STRING_FMT " overlap " GVA_STRING_FMT " %zu\n", - GVA_STRING_PRINT(trie_string(labels, entries[i].label)), - GVA_STRING_PRINT(trie_string(labels, entries[j].label)), - (entries[i].distance + entries[j].distance - distance) / 2); - return EXIT_FAILURE; - } // if - gva_lcs_graph_destroy(gva_std_allocator, rhs_graph, false); if (overlap) @@ -1047,8 +868,28 @@ all_main(int argc, char* argv[static argc]) int main(int argc, char* argv[static argc]) { + (void) argv; + char const* const reference = "TCTGGC"; + size_t const len_ref = strlen(reference); + char const* const observed = "TTTGTCAGGC"; + size_t const len_obs = strlen(observed); + + GVA_LCS_Graph graph = gva_lcs_graph_init(gva_std_allocator, len_ref, reference, len_obs, observed, 0); + uint8_t* dfa = dfa2_from_lcs_graph(gva_std_allocator, NULL, graph); + + DFA old = dfa_from_lcs_graph(gva_std_allocator, graph); + + dfa_dot(old); + + dfa2_dot(len_ref, reference, gva_lcs_graph_supremal(graph), dfa); + + dfa_destroy(gva_std_allocator, &old); + + dfa = ARRAY_DESTROY(gva_std_allocator, dfa); + gva_lcs_graph_destroy(gva_std_allocator, graph, false); + // return allele_main(argc, argv); // return index_main(argc, argv); - return overlap_main(argc, argv); + // return overlap_main(argc, argv); // return all_main(argc, argv); } // main diff --git a/src/nfa.c b/src/nfa.c index 685ea71..d7516c4 100644 --- a/src/nfa.c +++ b/src/nfa.c @@ -12,6 +12,117 @@ #include "priority_queue.h" // Priority_Queue, priority_queue_* +static inline void +set(uint8_t dfa[static 1], size_t const idx, uint8_t const value) +{ + dfa[idx / 4] |= value << (2 * (idx % 4)); +} // set + + +static inline uint8_t +get(uint8_t const dfa[static 1], size_t const idx) +{ + return (dfa[idx / 4] >> (2 * (idx % 4)) & 0x3); +} // get + + +static inline void +edge(uint8_t dfa[static 1], size_t const width, + size_t const start, size_t const end, + size_t const len, size_t const offset) +{ + for (size_t i = start; i <= end; ++i) + { + for (size_t j = 0; j <= len; ++j) + { + set(dfa, i * width + offset + j, + (i < end) * DFA2_DELETION | (j < len) * DFA2_INSERTION); + } // for + } // for +} // edge + + +uint8_t* +dfa2_from_lcs_graph(GVA_Allocator const allocator, + uint8_t* dfa, GVA_LCS_Graph const graph) +{ + GVA_Variant const supremal = gva_lcs_graph_supremal(graph); + size_t const width = supremal.sequence.len + 1; + size_t const size = (supremal.end - supremal.start + 1) * width; + dfa = array_ensure(allocator, dfa, 1, (size + 1) / 4); + if (dfa == NULL) + { + return NULL; // OOM + } // if + + array_header(dfa)->length += (size + 1) / 4; + memset(dfa, 0, array_length(dfa)); + + for (size_t i = 0; i < array_length(graph.nodes); ++i) + { + for (gva_uint j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) + { + GVA_Variant variant = {0}; + size_t const count = gva_edges(graph.observed.str, + graph.nodes[i].match, graph.nodes[graph.edges[j].tail].match, + i == graph.source, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, + &variant); + for (size_t k = 0; k < count; ++k) + { + edge(dfa, width, variant.start + k - supremal.start, variant.end + k - supremal.start, + variant.sequence.len, variant.sequence.str - graph.observed.str + k); + } // for + } // for + } // for + + return dfa; +} // dfa2_from_lcs_graph + + +void +dfa2_dot_traverse(size_t const len, char const reference[static len], + GVA_Variant const supremal, uint8_t const dfa[static 1], size_t const idx) +{ + size_t const width = supremal.sequence.len + 1; + size_t const size = (supremal.end - supremal.start + 1) * width; + + if (idx == size - 1) + { + return; + } // if + + uint8_t const value = get(dfa, idx); + if (value & DFA2_DELETION) + { + fprintf(stderr, "%zu->%zu[label=\"%zu Δ\"]\n", idx, idx + width, supremal.start + idx / width); + dfa2_dot_traverse(len, reference, supremal, dfa, idx + width); + } // if + if (value & DFA2_INSERTION) + { + fprintf(stderr, "%zu->%zu[label=\"%zu %c\"]\n", idx, idx + 1, supremal.start + idx / width, supremal.sequence.str[idx % width]); + dfa2_dot_traverse(len, reference, supremal, dfa, idx + 1); + } // if + if (reference[idx / width] == supremal.sequence.str[idx % width]) + { + fprintf(stderr, "%zu->%zu[label=\"%zu Μ\"]\n", idx, idx + width + 1, supremal.start + idx / width); + dfa2_dot_traverse(len, reference, supremal, dfa, idx + width + 1); + } // if +} // dfa2_dot_traverse + + +void +dfa2_dot(size_t const len, char const reference[static len], + GVA_Variant const supremal, uint8_t const dfa[static 1]) +{ + size_t const width = supremal.sequence.len + 1; + size_t const size = (supremal.end - supremal.start + 1) * width; + + fprintf(stderr, "strict digraph{\nrankdir=LR\nnode[fixedsize=true,shape=circle,width=1]\ni[label=\"\",shape=none,width=0]\ni->0\n"); + dfa2_dot_traverse(len, reference, supremal, dfa, 0); + fprintf(stderr, "%zu[peripheries=2]\n}\n", size - 1); +} // dfa2_dot + + static inline void dfa_edge(DFA self[static 1], size_t const width, size_t const start, size_t const end, @@ -75,7 +186,6 @@ dfa_from_lcs_graph(GVA_Allocator const allocator, GVA_LCS_Graph const graph) } // for } // for } // for - return dfa; } // dfa_from_lcs_graph diff --git a/src/nfa.h b/src/nfa.h index f65f033..5a6d28e 100644 --- a/src/nfa.h +++ b/src/nfa.h @@ -8,9 +8,28 @@ #include "../include/allocator.h" // GVA_Allocator #include "../include/lcs_graph.h" // GVA_LCS_Graph #include "../include/string.h" // GVA_String +#include "../include/variant.h" // GVA_Variant #include "../include/types.h" // gva_uint +enum +{ + DFA2_FINAL, + DFA2_DELETION, + DFA2_INSERTION, +}; + + +uint8_t* +dfa2_from_lcs_graph(GVA_Allocator const allocator, + uint8_t* dfa, GVA_LCS_Graph const graph); + + +void +dfa2_dot(size_t const len, char const reference[static len], + GVA_Variant const supremal, uint8_t const dfa[static 1]); + + typedef struct { uint8_t deletion : 1; From a9a0cfd7bb3db9f4e8b33e360e171f82fda7565f Mon Sep 17 00:00:00 2001 From: jkvis Date: Sat, 25 Apr 2026 17:03:47 +0200 Subject: [PATCH 610/704] WIP: 2bit DFAs max overlap --- src/dfa.c | 320 ++++++++++++++++++++++++++++++ src/dfa.h | 31 +++ src/main.c | 91 +++------ src/nfa.c | 564 ----------------------------------------------------- src/nfa.h | 101 ---------- 5 files changed, 377 insertions(+), 730 deletions(-) create mode 100644 src/dfa.c create mode 100644 src/dfa.h delete mode 100644 src/nfa.c delete mode 100644 src/nfa.h diff --git a/src/dfa.c b/src/dfa.c new file mode 100644 index 0000000..52e8c97 --- /dev/null +++ b/src/dfa.c @@ -0,0 +1,320 @@ +#include // NULL, size_t +#include // uint8_t +#include // memset + +#include "../include/allocator.h" // GVA_Allocator +#include "../include/lcs_graph.h" // GVA_LCS_Graph, gva_edges +#include "../include/types.h" // GVA_NULL, gva_uint +#include "../include/variant.h" // GVA_Variant +#include "array.h" // ARRAY_*, array_* +#include "dfa.h" // dfa* +#include "priority_queue.h" // Priority_Queue, priority_queue_* + + +#include // DEBUG + + +static uint8_t const DFA_DELETION = 0x1; +static uint8_t const DFA_INSERTION = 0x2; + + +static inline void +set(uint8_t dfa[static 1], size_t const idx, uint8_t const value) +{ + dfa[idx / 4] |= value << (2 * (idx % 4)); +} // set + + +static inline uint8_t +get(uint8_t const dfa[static 1], size_t const idx) +{ + return (dfa[idx / 4] >> (2 * (idx % 4)) & 0x3); +} // get + + +static inline void +edge(uint8_t dfa[static 1], size_t const width, + size_t const start, size_t const end, + size_t const len, size_t const offset) +{ + for (size_t i = start; i <= end; ++i) + { + for (size_t j = 0; j <= len; ++j) + { + set(dfa, i * width + offset + j, + (i < end) * DFA_DELETION | (j < len) * DFA_INSERTION); + } // for + } // for +} // edge + + +uint8_t* +dfa_from_lcs_graph(GVA_Allocator const allocator, uint8_t* dfas, + GVA_LCS_Graph const graph) +{ + GVA_Variant const supremal = gva_lcs_graph_supremal(graph); + size_t const width = supremal.sequence.len + 1; + size_t const size = (supremal.end - supremal.start + 1) * width; + size_t const len = (size + 3) / 4; + + dfas = array_ensure(allocator, dfas, 1, len); + if (dfas == NULL) + { + return NULL; // OOM + } // if + + memset(dfas + array_length(dfas), 0, len); + for (size_t i = 0; i < array_length(graph.nodes); ++i) + { + for (gva_uint j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) + { + GVA_Variant variant = {0}; + size_t const count = gva_edges(graph.observed.str, + graph.nodes[i].match, graph.nodes[graph.edges[j].tail].match, + i == graph.source, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, + &variant); + for (size_t k = 0; k < count; ++k) + { + edge(dfas + array_length(dfas), width, variant.start + k - supremal.start, variant.end + k - supremal.start, + variant.sequence.len, variant.sequence.str - supremal.sequence.str + k); + } // for + } // for + } // for + array_header(dfas)->length += len; + + return dfas; +} // dfa_from_lcs_graph + + +size_t +dfa_max_overlap(GVA_Allocator const allocator, + size_t const len, char const reference[static restrict len], + GVA_Variant const lhs_supremal, uint8_t const lhs_dfa[static restrict 1], + GVA_Variant const rhs_supremal, uint8_t const rhs_dfa[static restrict 1]) +{ + size_t const lhs_width = lhs_supremal.sequence.len + 1; + size_t const rhs_width = rhs_supremal.sequence.len + 1; + size_t const lhs_size = (lhs_supremal.end - lhs_supremal.start + 1) * lhs_width; + size_t const rhs_size = (rhs_supremal.end - rhs_supremal.start + 1) * rhs_width; + + Priority_Queue fringe = priority_queue_init(allocator, lhs_size * rhs_size); + priority_queue_push(&fringe, 0, 0, 0); + + size_t count = 0; + while (!priority_queue_empty(fringe)) + { + count += 1; + size_t const idx = priority_queue_pop(&fringe); + + size_t const lhs_idx = idx / rhs_size; + size_t const rhs_idx = idx % rhs_size; + + size_t const lhs_ref = lhs_idx / lhs_width + lhs_supremal.start; + size_t const rhs_ref = rhs_idx / rhs_width + rhs_supremal.start; + + fprintf(stderr, "{%zu, %zu} (%zu) :: %u %u\n", lhs_idx, rhs_idx, idx, + fringe.states[idx].included, fringe.states[idx].excluded); + + if (lhs_idx == lhs_size - 1 && rhs_idx == rhs_size - 1) + { + fprintf(stdout, "%u %zu %zu\n", fringe.states[idx].included, count, array_length(fringe.heap)); + break; + } // if + + if ((lhs_idx == 0 && rhs_ref < lhs_ref) || lhs_idx == lhs_size - 1) + { + uint8_t const value = get(rhs_dfa, rhs_idx); + + if (value & DFA_DELETION) + { + fprintf(stderr, " push (. vs %zu DELTA) +0 +1 {%zu, %zu} (%zu)\n", rhs_ref, lhs_idx, rhs_idx + rhs_width, lhs_idx * rhs_size + rhs_idx + rhs_width); + priority_queue_push(&fringe, lhs_idx * rhs_size + rhs_idx + rhs_width, + fringe.states[idx].included, fringe.states[idx].excluded + 1); + } // if + + if (rhs_idx % rhs_width < rhs_width - 1 && + reference[rhs_supremal.start + rhs_idx / rhs_width] == rhs_supremal.sequence.str[rhs_idx % rhs_width]) + { + fprintf(stderr, " push (. vs %zu MU) +0 +0 {%zu, %zu} (%zu)\n", rhs_ref, lhs_idx, rhs_idx + rhs_width + 1, lhs_idx * rhs_size + rhs_idx + rhs_width + 1); + priority_queue_push(&fringe, lhs_idx * rhs_size + rhs_idx + rhs_width + 1, + fringe.states[idx].included, fringe.states[idx].excluded); + } // if + + if (value & DFA_INSERTION) + { + fprintf(stderr, " push (. vs %zu %c) +0 +1 {%zu, %zu} (%zu)\n", rhs_ref, rhs_supremal.sequence.str[rhs_idx % rhs_width], lhs_idx, rhs_idx + 1, lhs_idx * rhs_size + rhs_idx + 1); + priority_queue_push(&fringe, lhs_idx * rhs_size + rhs_idx + 1, + fringe.states[idx].included, fringe.states[idx].excluded + 1); + } // if + continue; + } // if + + if ((rhs_idx == 0 && lhs_ref < rhs_ref) || rhs_idx == rhs_size - 1) + { + uint8_t const value = get(lhs_dfa, lhs_idx); + + if (value & DFA_DELETION) + { + fprintf(stderr, " push (%zu DELTA vs .) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, lhs_idx + lhs_width, rhs_idx, (lhs_idx + lhs_width) * rhs_size + rhs_idx); + priority_queue_push(&fringe, (lhs_idx + lhs_width) * rhs_size + rhs_idx, + fringe.states[idx].included, fringe.states[idx].excluded + 1); + } // if + + if (lhs_idx % lhs_width < lhs_width - 1 && + reference[lhs_supremal.start + lhs_idx / lhs_width] == lhs_supremal.sequence.str[lhs_idx % lhs_width]) + { + fprintf(stderr, " push (%zu MU vs .) +0 +0 {%zu, %zu} (%zu)\n", lhs_ref, lhs_idx + lhs_width + 1, rhs_idx, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx); + priority_queue_push(&fringe, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx, + fringe.states[idx].included, fringe.states[idx].excluded); + } // if + + if (value & DFA_INSERTION) + { + fprintf(stderr, " push (%zu %c vs .) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, lhs_supremal.sequence.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx, (lhs_idx + 1) * rhs_size + rhs_idx); + priority_queue_push(&fringe, (lhs_idx + 1) * rhs_size + rhs_idx, + fringe.states[idx].included, fringe.states[idx].excluded + 1); + } // if + continue; + } // if + + uint8_t const lhs_value = get(lhs_dfa, lhs_idx); + uint8_t const rhs_value = get(rhs_dfa, rhs_idx); + + if (lhs_value & DFA_DELETION) + { + if (rhs_value & DFA_DELETION) + { + fprintf(stderr, " push (%zu DELTA) {%zu, %zu} +1 +0 (%zu)\n", lhs_ref, lhs_idx + lhs_width, rhs_idx + rhs_width, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width); + priority_queue_push(&fringe, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width, + fringe.states[idx].included + 1, fringe.states[idx].excluded); + } // if + + if (rhs_idx % rhs_width < rhs_width - 1 && + reference[rhs_supremal.start + rhs_idx / rhs_width] == rhs_supremal.sequence.str[rhs_idx % rhs_width]) + { + fprintf(stderr, " push (%zu DELTA vs %zu MU) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, rhs_ref, lhs_idx + lhs_width, rhs_idx + rhs_width + 1, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width + 1); + priority_queue_push(&fringe, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width + 1, + fringe.states[idx].included, fringe.states[idx].excluded + 1); + } // if + + if (rhs_value & DFA_INSERTION) + { + fprintf(stderr, " push (. vs %zu %c) {%zu, %zu} +0 +1 (%zu)\n", rhs_ref, rhs_supremal.sequence.str[rhs_idx % rhs_width], lhs_idx, rhs_idx + 1, lhs_idx * rhs_size + rhs_idx + 1); + priority_queue_push(&fringe, lhs_idx * rhs_size + rhs_idx + 1, + fringe.states[idx].included, fringe.states[idx].excluded + 1); + } // if + } // if + + if (lhs_idx % lhs_width < lhs_width - 1 && + reference[lhs_supremal.start + lhs_idx / lhs_width] == lhs_supremal.sequence.str[lhs_idx % lhs_width]) + { + if (rhs_value & DFA_DELETION) + { + fprintf(stderr, " push (%zu MU vs %zu DELTA) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, rhs_ref, lhs_idx + lhs_width + 1, rhs_idx + rhs_width, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx + rhs_width); + priority_queue_push(&fringe, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx + rhs_width, + fringe.states[idx].included, fringe.states[idx].excluded + 1); + } // if + + if (rhs_idx % rhs_width < rhs_width - 1 && + reference[rhs_supremal.start + rhs_idx / rhs_width] == rhs_supremal.sequence.str[rhs_idx % rhs_width]) + { + fprintf(stderr, " push (%zu MU) {%zu, %zu} +0 +0 (%zu)\n", lhs_ref, lhs_idx + lhs_width + 1, rhs_idx + rhs_width + 1, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx + rhs_width + 1); + priority_queue_push(&fringe, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx + rhs_width + 1, + fringe.states[idx].included, fringe.states[idx].excluded); + } // if + + if (rhs_value & DFA_INSERTION) + { + fprintf(stderr, " push (. vs %zu %c) {%zu, %zu} +0 +1 (%zu)\n", rhs_ref, rhs_supremal.sequence.str[rhs_idx % rhs_width], lhs_idx, rhs_idx + 1, lhs_idx * rhs_size + rhs_idx + 1); + priority_queue_push(&fringe, lhs_idx * rhs_size + rhs_idx + 1, + fringe.states[idx].included, fringe.states[idx].excluded + 1); + } // if + } // if + + if (lhs_value & DFA_INSERTION) + { + if (rhs_value & DFA_DELETION) + { + fprintf(stderr, " push (%zu %c vs .) {%zu, %zu} +0 +1 (%zu)\n", lhs_ref, lhs_supremal.sequence.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx, (lhs_idx + 1) * rhs_size + rhs_idx); + priority_queue_push(&fringe, (lhs_idx + 1) * rhs_size + rhs_idx, + fringe.states[idx].included, fringe.states[idx].excluded + 1); + } // if + + if (rhs_idx % rhs_width < rhs_width - 1 && + reference[rhs_supremal.start + rhs_idx / rhs_width] == rhs_supremal.sequence.str[rhs_idx % rhs_width]) + { + fprintf(stderr, " push (%zu %c vs .) {%zu, %zu} +0 +1 (%zu)\n", lhs_ref, lhs_supremal.sequence.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx, (lhs_idx + 1) * rhs_size + rhs_idx); + priority_queue_push(&fringe, (lhs_idx + 1) * rhs_size + rhs_idx, + fringe.states[idx].included, fringe.states[idx].excluded + 1); + } // if + + if (rhs_value & DFA_INSERTION) + { + if (lhs_supremal.sequence.str[lhs_idx % lhs_width] == rhs_supremal.sequence.str[rhs_idx % rhs_width]) + { + fprintf(stderr, " push (%zu %c) {%zu, %zu} +1 +0 (%zu)\n", lhs_ref, lhs_supremal.sequence.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx + 1, (lhs_idx + 1) * rhs_size + rhs_idx + 1); + priority_queue_push(&fringe, (lhs_idx + 1) * rhs_size + rhs_idx + 1, + fringe.states[idx].included + 1, fringe.states[idx].excluded); + } // if + else + { + fprintf(stderr, " push (%zu %c vs .) {%zu, %zu} +0 +1 (%zu)\n", lhs_ref, lhs_supremal.sequence.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx, (lhs_idx + 1) * rhs_size + rhs_idx); + priority_queue_push(&fringe, (lhs_idx + 1) * rhs_size + rhs_idx, + fringe.states[idx].included, fringe.states[idx].excluded + 1); + + fprintf(stderr, " push (. vs %zu %c) {%zu, %zu} +0 +1 (%zu)\n", rhs_ref, rhs_supremal.sequence.str[rhs_idx % rhs_width], lhs_idx, rhs_idx + 1, lhs_idx * rhs_size + rhs_idx + 1); + priority_queue_push(&fringe, lhs_idx * rhs_size + rhs_idx + 1, + fringe.states[idx].included, fringe.states[idx].excluded + 1); + } // else + } // if + } // if + } // while + + priority_queue_destroy(&fringe); + + return 0; +} // dfa_max_overlap + + +void +dfa_dot_traverse(size_t const len, char const reference[static len], + GVA_Variant const supremal, uint8_t const dfa[static 1], size_t const idx) +{ + size_t const width = supremal.sequence.len + 1; + size_t const size = (supremal.end - supremal.start + 1) * width; + + if (idx == size - 1) + { + return; + } // if + + uint8_t const value = get(dfa, idx); + if (value & DFA_DELETION) + { + fprintf(stderr, "%zu->%zu[label=\"%zu Δ\"]\n", idx, idx + width, supremal.start + idx / width); + dfa_dot_traverse(len, reference, supremal, dfa, idx + width); + } // if + if (value & DFA_INSERTION) + { + fprintf(stderr, "%zu->%zu[label=\"%zu %c\"]\n", idx, idx + 1, supremal.start + idx / width, supremal.sequence.str[idx % width]); + dfa_dot_traverse(len, reference, supremal, dfa, idx + 1); + } // if + if (reference[supremal.start + idx / width] == supremal.sequence.str[idx % width]) + { + fprintf(stderr, "%zu->%zu[label=\"%zu Μ\"]\n", idx, idx + width + 1, supremal.start + idx / width); + dfa_dot_traverse(len, reference, supremal, dfa, idx + width + 1); + } // if +} // dfa_dot_traverse + + +void +dfa_dot(size_t const len, char const reference[static len], + GVA_Variant const supremal, uint8_t const dfa[static 1]) +{ + size_t const width = supremal.sequence.len + 1; + size_t const size = (supremal.end - supremal.start + 1) * width; + + fprintf(stderr, "strict digraph{\nrankdir=LR\nnode[fixedsize=true,shape=circle,width=1]\ni[label=\"\",shape=none,width=0]\ni->0\n"); + dfa_dot_traverse(len, reference, supremal, dfa, 0); + fprintf(stderr, "%zu[peripheries=2]\n}\n", size - 1); +} // dfa_dot diff --git a/src/dfa.h b/src/dfa.h new file mode 100644 index 0000000..c168ec8 --- /dev/null +++ b/src/dfa.h @@ -0,0 +1,31 @@ +#ifndef GVA_DFA_H +#define GVA_DFA_H + + +#include // size_t +#include // uint8_t + +#include "../include/allocator.h" // GVA_Allocator +#include "../include/lcs_graph.h" // GVA_LCS_Graph +#include "../include/variant.h" // GVA_Variant + + +uint8_t* +dfa_from_lcs_graph(GVA_Allocator const allocator, uint8_t* dfas, + GVA_LCS_Graph const graph); + + +size_t +dfa_max_overlap(GVA_Allocator const allocator, + size_t const len, char const reference[static restrict len], + GVA_Variant const lhs_supremal, uint8_t const lhs_dfa[static restrict 1], + GVA_Variant const rhs_supremal, uint8_t const rhs_dfa[static restrict 1]); + + +// FIXME: DEBUG +void +dfa_dot(size_t const len, char const reference[static len], + GVA_Variant const supremal, uint8_t const dfa[static 1]); + + +#endif // GVA_DFA_H diff --git a/src/main.c b/src/main.c index 0591cfa..83d69ad 100644 --- a/src/main.c +++ b/src/main.c @@ -1,6 +1,7 @@ #include // errno #include // bool, false, true #include // NULL, size_t +#include // uint8_t #include // FILE, stderr, stdout, fclose, fopen, fprintf #include // EXIT_*, atoll, qsort #include // strerror, strlen @@ -18,7 +19,7 @@ #include "array.h" // ARRAY_*, array_length #include "bitset.h" // bitset_* #include "common.h" // MAX, MIN -#include "nfa.h" // DFA, dfa_* +#include "dfa.h" // dfa_* #include "trie.h" // Trie, trie_* @@ -476,6 +477,8 @@ supremal_main(int argc, char* argv[static argc]) fprintf(stderr, "reference length: %zu\n", reference.len); + uint8_t* dfas = NULL; + size_t line_count = 0; static char line[LINE_SIZE] = {0}; while (fgets(line, sizeof(line), stdin) != NULL) @@ -490,27 +493,16 @@ supremal_main(int argc, char* argv[static argc]) continue; } // if GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &variant); - - GVA_Variant supremal = gva_lcs_graph_supremal(graph); - - fprintf(stdout, GVA_STRING_FMT " " GVA_VARIANT_FMT_SPDI " %zu\n", - GVA_STRING_PRINT(id), - GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, supremal), - gva_lcs_graph_distance(graph)); - - /* - for (size_t i = 0; i < array_length(graph.dom_nodes) - 1; ++i) - { - fprintf(stdout, GVA_STRING_FMT " " GVA_VARIANT_FMT_SPDI " %u\n", - GVA_STRING_PRINT(id), - GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, gva_lcs_graph_local_supremal(graph, i, i + 1)), - graph.dom_nodes[i + 1].distance - graph.dom_nodes[i].distance); - } // for - */ - + //size_t const start = array_length(dfas); + dfas = dfa_from_lcs_graph(gva_std_allocator, dfas, graph); + //dfa_dot(reference.len, reference.str, gva_lcs_graph_supremal(graph), dfas + start); gva_lcs_graph_destroy(gva_std_allocator, graph, true); } // while + fprintf(stderr, "#variants: %zu\n", line_count); + fprintf(stderr, "%zu bytes\n", array_length(dfas)); + dfas = ARRAY_DESTROY(gva_std_allocator, dfas); + gva_string_destroy(gva_std_allocator, reference); return EXIT_SUCCESS; @@ -556,36 +548,24 @@ overlap_main(int argc, char* argv[static argc]) GVA_LCS_Graph lhs = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &lhs_variant); GVA_LCS_Graph rhs = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &rhs_variant); - DFA lhs_dfa = dfa_from_lcs_graph(gva_std_allocator, lhs); - DFA rhs_dfa = dfa_from_lcs_graph(gva_std_allocator, rhs); - dfa_dot(lhs_dfa); - dfa_dot(rhs_dfa); + uint8_t* lhs_dfa = dfa_from_lcs_graph(gva_std_allocator, NULL, lhs); + uint8_t* rhs_dfa = dfa_from_lcs_graph(gva_std_allocator, NULL, rhs); - fprintf(stderr, "OVERLAP: %zu\n", dfa_max_overlap(gva_std_allocator, lhs_dfa, rhs_dfa)); + GVA_Variant const lhs_supremal = gva_lcs_graph_supremal(lhs); + GVA_Variant const rhs_supremal = gva_lcs_graph_supremal(rhs); - dfa_destroy(gva_std_allocator, &rhs_dfa); - dfa_destroy(gva_std_allocator, &lhs_dfa); + //dfa_dot(reference.len, reference.str, lhs_supremal, lhs_dfa); + //dfa_dot(reference.len, reference.str, rhs_supremal, rhs_dfa); - fprintf(stderr, "%s\n", GVA_RELATION_LABELS[gva_compare_graphs(gva_std_allocator, reference.len, reference.str, lhs, rhs)]); + size_t const overlap = dfa_max_overlap(gva_std_allocator, + reference.len, reference.str, + lhs_supremal, lhs_dfa, + rhs_supremal, rhs_dfa); - static char filename[128] = {0}; - snprintf(filename, 128, "overlap/graph_%zu.dot", line_count); - FILE* stream = fopen(filename, "w"); - gva_lcs_graph_dot(stream, lhs); - gva_lcs_graph_dot(stream, rhs); - fclose(stream); + fprintf(stderr, "OVERLAP: %zu\n", overlap); - fprintf(stderr, "%sdistances lhs: %zu rhs: %zu :: ", line, gva_lcs_graph_distance(lhs), gva_lcs_graph_distance(rhs)); - { - size_t const distance = gva_edit_distance(gva_std_allocator, - lhs_variant.sequence.len, lhs_variant.sequence.str, - rhs_variant.sequence.len, rhs_variant.sequence.str); - fprintf(stderr, "%zu\n", distance); - } - fprintf(stderr, "#nodes lhs: %zu rhs %zu :: %zu\n", array_length(lhs.nodes), array_length(rhs.nodes), array_length(lhs.nodes) * array_length(rhs.nodes)); - fprintf(stderr, "#edges lhs: %zu rhs %zu :: %zu\n", array_length(lhs.edges), array_length(rhs.edges), array_length(lhs.edges) * array_length(rhs.edges)); - - //fprintf(stderr, "disjoint: %d\n", is_disjoint(gva_std_allocator, lhs, rhs)); + rhs_dfa = ARRAY_DESTROY(gva_std_allocator, rhs_dfa); + lhs_dfa = ARRAY_DESTROY(gva_std_allocator, lhs_dfa); gva_lcs_graph_destroy(gva_std_allocator, rhs, true); gva_lcs_graph_destroy(gva_std_allocator, lhs, true); @@ -868,28 +848,9 @@ all_main(int argc, char* argv[static argc]) int main(int argc, char* argv[static argc]) { - (void) argv; - char const* const reference = "TCTGGC"; - size_t const len_ref = strlen(reference); - char const* const observed = "TTTGTCAGGC"; - size_t const len_obs = strlen(observed); - - GVA_LCS_Graph graph = gva_lcs_graph_init(gva_std_allocator, len_ref, reference, len_obs, observed, 0); - uint8_t* dfa = dfa2_from_lcs_graph(gva_std_allocator, NULL, graph); - - DFA old = dfa_from_lcs_graph(gva_std_allocator, graph); - - dfa_dot(old); - - dfa2_dot(len_ref, reference, gva_lcs_graph_supremal(graph), dfa); - - dfa_destroy(gva_std_allocator, &old); - - dfa = ARRAY_DESTROY(gva_std_allocator, dfa); - gva_lcs_graph_destroy(gva_std_allocator, graph, false); - // return allele_main(argc, argv); // return index_main(argc, argv); - // return overlap_main(argc, argv); + // return supremal_main(argc, argv); + return overlap_main(argc, argv); // return all_main(argc, argv); } // main diff --git a/src/nfa.c b/src/nfa.c deleted file mode 100644 index d7516c4..0000000 --- a/src/nfa.c +++ /dev/null @@ -1,564 +0,0 @@ -#include // NULL, size_t -#include // stderr, fprintf FIXME: DEBUG -#include // memset - -#include "../include/allocator.h" // GVA_Allocator -#include "../include/lcs_graph.h" // GVA_LCS_Graph, gva_edges -#include "../include/string.h" // GVA_String, gva_string_* -#include "../include/types.h" // GVA_NULL, gva_uint -#include "../include/variant.h" // GVA_Variant -#include "array.h" // ARRAY_*, array_length -#include "nfa.h" // DFA, dfa*, NFA*, nfa_* -#include "priority_queue.h" // Priority_Queue, priority_queue_* - - -static inline void -set(uint8_t dfa[static 1], size_t const idx, uint8_t const value) -{ - dfa[idx / 4] |= value << (2 * (idx % 4)); -} // set - - -static inline uint8_t -get(uint8_t const dfa[static 1], size_t const idx) -{ - return (dfa[idx / 4] >> (2 * (idx % 4)) & 0x3); -} // get - - -static inline void -edge(uint8_t dfa[static 1], size_t const width, - size_t const start, size_t const end, - size_t const len, size_t const offset) -{ - for (size_t i = start; i <= end; ++i) - { - for (size_t j = 0; j <= len; ++j) - { - set(dfa, i * width + offset + j, - (i < end) * DFA2_DELETION | (j < len) * DFA2_INSERTION); - } // for - } // for -} // edge - - -uint8_t* -dfa2_from_lcs_graph(GVA_Allocator const allocator, - uint8_t* dfa, GVA_LCS_Graph const graph) -{ - GVA_Variant const supremal = gva_lcs_graph_supremal(graph); - size_t const width = supremal.sequence.len + 1; - size_t const size = (supremal.end - supremal.start + 1) * width; - dfa = array_ensure(allocator, dfa, 1, (size + 1) / 4); - if (dfa == NULL) - { - return NULL; // OOM - } // if - - array_header(dfa)->length += (size + 1) / 4; - memset(dfa, 0, array_length(dfa)); - - for (size_t i = 0; i < array_length(graph.nodes); ++i) - { - for (gva_uint j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) - { - GVA_Variant variant = {0}; - size_t const count = gva_edges(graph.observed.str, - graph.nodes[i].match, graph.nodes[graph.edges[j].tail].match, - i == graph.source, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, - &variant); - for (size_t k = 0; k < count; ++k) - { - edge(dfa, width, variant.start + k - supremal.start, variant.end + k - supremal.start, - variant.sequence.len, variant.sequence.str - graph.observed.str + k); - } // for - } // for - } // for - - return dfa; -} // dfa2_from_lcs_graph - - -void -dfa2_dot_traverse(size_t const len, char const reference[static len], - GVA_Variant const supremal, uint8_t const dfa[static 1], size_t const idx) -{ - size_t const width = supremal.sequence.len + 1; - size_t const size = (supremal.end - supremal.start + 1) * width; - - if (idx == size - 1) - { - return; - } // if - - uint8_t const value = get(dfa, idx); - if (value & DFA2_DELETION) - { - fprintf(stderr, "%zu->%zu[label=\"%zu Δ\"]\n", idx, idx + width, supremal.start + idx / width); - dfa2_dot_traverse(len, reference, supremal, dfa, idx + width); - } // if - if (value & DFA2_INSERTION) - { - fprintf(stderr, "%zu->%zu[label=\"%zu %c\"]\n", idx, idx + 1, supremal.start + idx / width, supremal.sequence.str[idx % width]); - dfa2_dot_traverse(len, reference, supremal, dfa, idx + 1); - } // if - if (reference[idx / width] == supremal.sequence.str[idx % width]) - { - fprintf(stderr, "%zu->%zu[label=\"%zu Μ\"]\n", idx, idx + width + 1, supremal.start + idx / width); - dfa2_dot_traverse(len, reference, supremal, dfa, idx + width + 1); - } // if -} // dfa2_dot_traverse - - -void -dfa2_dot(size_t const len, char const reference[static len], - GVA_Variant const supremal, uint8_t const dfa[static 1]) -{ - size_t const width = supremal.sequence.len + 1; - size_t const size = (supremal.end - supremal.start + 1) * width; - - fprintf(stderr, "strict digraph{\nrankdir=LR\nnode[fixedsize=true,shape=circle,width=1]\ni[label=\"\",shape=none,width=0]\ni->0\n"); - dfa2_dot_traverse(len, reference, supremal, dfa, 0); - fprintf(stderr, "%zu[peripheries=2]\n}\n", size - 1); -} // dfa2_dot - - -static inline void -dfa_edge(DFA self[static 1], size_t const width, - size_t const start, size_t const end, - size_t const len, size_t const offset) -{ - for (size_t i = start; i <= end; ++i) - { - for (size_t j = 0; j <= len; ++j) - { - if (i < end) - { - self->states[i * width + offset + j].deletion = 1; - } // if - if (j < len) - { - self->states[i * width + offset + j].insertion = 1; - } // if - } // for - } // for -} // dfa_edge - - -DFA -dfa_from_lcs_graph(GVA_Allocator const allocator, GVA_LCS_Graph const graph) -{ - GVA_Variant const supremal = gva_lcs_graph_supremal(graph); - size_t const size = (supremal.end - supremal.start + 1) * (supremal.sequence.len + 1); - DFA dfa = - { - .start = supremal.start, - .observed = supremal.sequence, - .states = allocator.allocate(allocator.context, NULL, 0, size), - }; - if (dfa.states == NULL) - { - dfa.size = 0; - return dfa; // OOM - } // if - - dfa.size = size; - memset(dfa.states, 0, dfa.size); - - size_t const width = dfa.observed.len + 1; - for (size_t i = 0; i < array_length(graph.nodes); ++i) - { - for (size_t j = 0; j < graph.nodes[i].match.length; ++j) - { - dfa.states[(graph.nodes[i].match.row + j - dfa.start) * width + graph.nodes[i].match.col + j - dfa.start].match = 1; - } // for - for (gva_uint j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) - { - GVA_Variant variant = {0}; - size_t const count = gva_edges(graph.observed.str, - graph.nodes[i].match, graph.nodes[graph.edges[j].tail].match, - i == graph.source, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, - &variant); - for (size_t k = 0; k < count; ++k) - { - dfa_edge(&dfa, width, variant.start + k - dfa.start, variant.end + k - dfa.start, - variant.sequence.len, variant.sequence.str - dfa.observed.str + k); - } // for - } // for - } // for - return dfa; -} // dfa_from_lcs_graph - - -inline void -dfa_destroy(GVA_Allocator const allocator, DFA self[static 1]) -{ - self->states = allocator.allocate(allocator.context, self->states, self->size * sizeof(*self->states), 0); - self->size = 0; -} // dfa_destroy - - -size_t -dfa_max_overlap(GVA_Allocator const allocator, DFA const lhs, DFA const rhs) -{ - size_t const lhs_width = lhs.observed.len + 1; - size_t const rhs_width = rhs.observed.len + 1; - - Priority_Queue fringe = priority_queue_init(allocator, lhs.size * rhs.size); - priority_queue_push(&fringe, 0, 0, 0); - - size_t count = 0; - while (!priority_queue_empty(fringe)) - { - count += 1; - size_t const idx = priority_queue_pop(&fringe); - - size_t const lhs_idx = idx / rhs.size; - size_t const rhs_idx = idx % rhs.size; - - size_t const lhs_ref = lhs_idx / lhs_width + lhs.start; - size_t const rhs_ref = rhs_idx / rhs_width + rhs.start; - - fprintf(stderr, "{%zu, %zu} (%zu) :: %u %u\n", lhs_idx, rhs_idx, idx, - fringe.states[idx].included, fringe.states[idx].excluded); - - if (lhs_idx == lhs.size - 1 && rhs_idx == rhs.size - 1) - { - fprintf(stdout, "%u %zu %zu\n", fringe.states[idx].included, count, array_length(fringe.heap)); - break; - } // if - - if (lhs_idx == 0 && rhs_ref < lhs_ref) - { - if (rhs.states[rhs_idx].deletion) - { - fprintf(stderr, " push (. vs %zu DELTA) +0 +1 {%zu, %zu} (%zu)\n", rhs_ref, lhs_idx, rhs_idx + rhs_width, lhs_idx * rhs.size + rhs_idx + rhs_width); - priority_queue_push(&fringe, lhs_idx * rhs.size + rhs_idx + rhs_width, - fringe.states[idx].included, fringe.states[idx].excluded + 1); - } // if - - if (rhs.states[rhs_idx].match) - { - fprintf(stderr, " push (. vs %zu MU) +0 +0 {%zu, %zu} (%zu)\n", rhs_ref, lhs_idx, rhs_idx + rhs_width + 1, lhs_idx * rhs.size + rhs_idx + rhs_width + 1); - priority_queue_push(&fringe, lhs_idx * rhs.size + rhs_idx + rhs_width + 1, - fringe.states[idx].included, fringe.states[idx].excluded); - } // if - - if (rhs.states[rhs_idx].insertion) - { - fprintf(stderr, " push (. vs %zu %c) +0 +1 {%zu, %zu} (%zu)\n", rhs_ref, rhs.observed.str[rhs_idx % rhs_width], lhs_idx, rhs_idx + 1, lhs_idx * rhs.size + rhs_idx + 1); - priority_queue_push(&fringe, lhs_idx * rhs.size + rhs_idx + 1, - fringe.states[idx].included, fringe.states[idx].excluded + 1); - } // if - continue; - } // if - - if (rhs_idx == 0 && lhs_ref < rhs_ref) - { - if (lhs.states[lhs_idx].deletion) - { - fprintf(stderr, " push (%zu DELTA vs .) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, lhs_idx + lhs_width, rhs_idx, (lhs_idx + lhs_width) * rhs.size + rhs_idx); - priority_queue_push(&fringe, (lhs_idx + lhs_width) * rhs.size + rhs_idx, - fringe.states[idx].included, fringe.states[idx].excluded + 1); - } // if - - if (lhs.states[lhs_idx].match) - { - fprintf(stderr, " push (%zu MU vs .) +0 +0 {%zu, %zu} (%zu)\n", lhs_ref, lhs_idx + lhs_width + 1, rhs_idx, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx); - priority_queue_push(&fringe, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx, - fringe.states[idx].included, fringe.states[idx].excluded); - } // if - - if (lhs.states[lhs_idx].insertion) - { - fprintf(stderr, " push (%zu %c vs .) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, lhs.observed.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx, (lhs_idx + 1) * rhs.size + rhs_idx); - priority_queue_push(&fringe, (lhs_idx + 1) * rhs.size + rhs_idx, - fringe.states[idx].included, fringe.states[idx].excluded + 1); - } // if - continue; - } // if - - if (lhs.states[lhs_idx].deletion) - { - if (rhs.states[rhs_idx].deletion) - { - fprintf(stderr, " push (%zu DELTA) {%zu, %zu} +1 +0 (%zu)\n", lhs_ref, lhs_idx + lhs_width, rhs_idx + rhs_width, (lhs_idx + lhs_width) * rhs.size + rhs_idx + rhs_width); - priority_queue_push(&fringe, (lhs_idx + lhs_width) * rhs.size + rhs_idx + rhs_width, - fringe.states[idx].included + 1, fringe.states[idx].excluded); - } // if - - if (rhs.states[rhs_idx].match) - { - fprintf(stderr, " push (%zu DELTA vs %zu MU) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, rhs_ref, lhs_idx + lhs_width, rhs_idx + rhs_width + 1, (lhs_idx + lhs_width) * rhs.size + rhs_idx + rhs_width + 1); - priority_queue_push(&fringe, (lhs_idx + lhs_width) * rhs.size + rhs_idx + rhs_width + 1, - fringe.states[idx].included, fringe.states[idx].excluded + 1); - } // if - - if (rhs.states[rhs_idx].insertion) - { - fprintf(stderr, " push (. vs %zu %c) {%zu, %zu} +0 +1 (%zu)\n", rhs_ref, rhs.observed.str[rhs_idx % rhs_width], lhs_idx, rhs_idx + 1, lhs_idx * rhs.size + rhs_idx + 1); - priority_queue_push(&fringe, lhs_idx * rhs.size + rhs_idx + 1, - fringe.states[idx].included, fringe.states[idx].excluded + 1); - } // if - - if (rhs_idx == rhs.size - 1) - { - fprintf(stderr, " push (%zu DELTA vs .) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, lhs_idx + lhs_width, rhs_idx, (lhs_idx + lhs_width) * rhs.size + rhs_idx); - priority_queue_push(&fringe, (lhs_idx + lhs_width) * rhs.size + rhs_idx, - fringe.states[idx].included, fringe.states[idx].excluded + 1); - } // if - } // if - - if (lhs.states[lhs_idx].match) - { - if (rhs.states[rhs_idx].deletion) - { - fprintf(stderr, " push (%zu MU vs %zu DELTA) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, rhs_ref, lhs_idx + lhs_width + 1, rhs_idx + rhs_width, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx + rhs_width); - priority_queue_push(&fringe, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx + rhs_width, - fringe.states[idx].included, fringe.states[idx].excluded + 1); - } // if - - if (rhs.states[rhs_idx].match) - { - fprintf(stderr, " push (%zu MU) {%zu, %zu} +0 +0 (%zu)\n", lhs_ref, lhs_idx + lhs_width + 1, rhs_idx + rhs_width + 1, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx + rhs_width + 1); - priority_queue_push(&fringe, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx + rhs_width + 1, - fringe.states[idx].included, fringe.states[idx].excluded); - } // if - - if (rhs.states[rhs_idx].insertion) - { - fprintf(stderr, " push (. vs %zu %c) {%zu, %zu} +0 +1 (%zu)\n", rhs_ref, rhs.observed.str[rhs_idx % rhs_width], lhs_idx, rhs_idx + 1, lhs_idx * rhs.size + rhs_idx + 1); - priority_queue_push(&fringe, lhs_idx * rhs.size + rhs_idx + 1, - fringe.states[idx].included, fringe.states[idx].excluded + 1); - } // if - - if (rhs_idx == rhs.size - 1) - { - fprintf(stderr, " push (%zu MU vs .) +0 +0 {%zu, %zu} (%zu)\n", lhs_ref, lhs_idx + lhs_width + 1, rhs_idx, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx); - priority_queue_push(&fringe, (lhs_idx + lhs_width + 1) * rhs.size + rhs_idx, - fringe.states[idx].included, fringe.states[idx].excluded); - } // if - } // if - - if (lhs.states[lhs_idx].insertion) - { - if (rhs.states[rhs_idx].deletion) - { - fprintf(stderr, " push (%zu %c vs .) {%zu, %zu} +0 +1 (%zu)\n", lhs_ref, lhs.observed.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx, (lhs_idx + 1) * rhs.size + rhs_idx); - priority_queue_push(&fringe, (lhs_idx + 1) * rhs.size + rhs_idx, - fringe.states[idx].included, fringe.states[idx].excluded + 1); - } // if - - if (rhs.states[rhs_idx].match) - { - fprintf(stderr, " push (%zu %c vs .) {%zu, %zu} +0 +1 (%zu)\n", lhs_ref, lhs.observed.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx, (lhs_idx + 1) * rhs.size + rhs_idx); - priority_queue_push(&fringe, (lhs_idx + 1) * rhs.size + rhs_idx, - fringe.states[idx].included, fringe.states[idx].excluded + 1); - } // if - - if (rhs.states[rhs_idx].insertion) - { - if (lhs.observed.str[lhs_idx % lhs_width] == rhs.observed.str[rhs_idx % rhs_width]) - { - fprintf(stderr, " push (%zu %c) {%zu, %zu} +1 +0 (%zu)\n", lhs_ref, lhs.observed.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx + 1, (lhs_idx + 1) * rhs.size + rhs_idx + 1); - priority_queue_push(&fringe, (lhs_idx + 1) * rhs.size + rhs_idx + 1, - fringe.states[idx].included + 1, fringe.states[idx].excluded); - } // if - else - { - fprintf(stderr, " push (%zu %c vs .) {%zu, %zu} +0 +1 (%zu)\n", lhs_ref, lhs.observed.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx, (lhs_idx + 1) * rhs.size + rhs_idx); - priority_queue_push(&fringe, (lhs_idx + 1) * rhs.size + rhs_idx, - fringe.states[idx].included, fringe.states[idx].excluded + 1); - - fprintf(stderr, " push (. vs %zu %c) {%zu, %zu} +0 +1 (%zu)\n", rhs_ref, rhs.observed.str[rhs_idx % rhs_width], lhs_idx, rhs_idx + 1, lhs_idx * rhs.size + rhs_idx + 1); - priority_queue_push(&fringe, lhs_idx * rhs.size + rhs_idx + 1, - fringe.states[idx].included, fringe.states[idx].excluded + 1); - } // else - } // if - - if (rhs_idx == rhs.size - 1) - { - fprintf(stderr, " push (%zu %c vs .) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, lhs.observed.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx, (lhs_idx + 1) * rhs.size + rhs_idx); - priority_queue_push(&fringe, (lhs_idx + 1) * rhs.size + rhs_idx, - fringe.states[idx].included, fringe.states[idx].excluded + 1); - } // if - } // if - - if (lhs_idx == lhs.size - 1) - { - if (rhs.states[rhs_idx].deletion) - { - fprintf(stderr, " push (. vs %zu DELTA) +0 +1 {%zu, %zu} (%zu)\n", rhs_ref, lhs_idx, rhs_idx + rhs_width, lhs_idx * rhs.size + rhs_idx + rhs_width); - priority_queue_push(&fringe, lhs_idx * rhs.size + rhs_idx + rhs_width, - fringe.states[idx].included, fringe.states[idx].excluded + 1); - } // if - - if (rhs.states[rhs_idx].match) - { - fprintf(stderr, " push (. vs %zu MU) +0 +0 {%zu, %zu} (%zu)\n", rhs_ref, lhs_idx, rhs_idx + rhs_width + 1, lhs_idx * rhs.size + rhs_idx + rhs_width + 1); - priority_queue_push(&fringe, lhs_idx * rhs.size + rhs_idx + rhs_width + 1, - fringe.states[idx].included, fringe.states[idx].excluded); - } // if - - if (rhs.states[rhs_idx].insertion) - { - fprintf(stderr, " push (. vs %zu %c) +0 +1 {%zu, %zu} (%zu)\n", rhs_ref, rhs.observed.str[rhs_idx % rhs_width], lhs_idx, rhs_idx + 1, lhs_idx * rhs.size + rhs_idx + 1); - priority_queue_push(&fringe, lhs_idx * rhs.size + rhs_idx + 1, - fringe.states[idx].included, fringe.states[idx].excluded + 1); - } // if - } // if - } // while - - priority_queue_destroy(&fringe); - - return 0; -} // dfa_max_overlap - - -void -dfa_dot(DFA const self) -{ - size_t const width = self.observed.len + 1; - fprintf(stderr, "strict digraph{\nrankdir=LR\nnode[fixedsize=true,shape=circle,width=1]\ni[label=\"\",shape=none,width=0]\ni->0\n"); - for (size_t i = 0; i < self.size; ++i) - { - if (self.states[i].deletion) - { - fprintf(stderr, "%zu->%zu[label=\"%zu Δ\"]\n", i, i + width, self.start + i / width); - } // if - if (self.states[i].insertion) - { - fprintf(stderr, "%zu->%zu[label=\"%zu %c\"]\n", i, i + 1, self.start + i / width, self.observed.str[i % width]); - } // if - if (self.states[i].match) - { - fprintf(stderr, "%zu->%zu[label=\"%zu Μ\"]\n", i, i + width + 1, self.start + i / width); - } // if - } // for - fprintf(stderr, "%zu[peripheries=2]\n}\n", self.size - 1); -} // dfa_dot - - -static void -nfa_edge(GVA_Allocator const allocator, - NFA self[static 1], GVA_Variant const variant) -{ - for (size_t i = variant.start; i <= variant.end; ++i) - { - for (size_t j = 0; j <= variant.sequence.len; ++j) - { - size_t const tail = ARRAY_APPEND(allocator, self->states, GVA_NULL); - if (i > variant.start) - { - size_t const head = tail - variant.sequence.len - 1; - self->states[head] = ARRAY_APPEND(allocator, self->transitions, - ((NFA_Transition) - { - .symbol = NFA_DELETE, - .tail = tail, - .next = self->states[head], - })); - } // if - if (j > 0) - { - size_t const head = tail - 1; - self->states[head] = ARRAY_APPEND(allocator, self->transitions, - ((NFA_Transition) - { - .symbol = variant.sequence.str[j - 1], - .tail = tail, - .next = self->states[head], - })); - } // if - } // for - } // for -} // nfa_edge - - -NFA -nfa_from_lcs_graph(GVA_Allocator const allocator, GVA_LCS_Graph const graph) -{ - NFA nfa = {.source = graph.source}; - for (size_t i = 0; i < array_length(graph.nodes); ++i) - { - size_t const idx = ARRAY_APPEND(allocator, nfa.states, GVA_NULL); - if (graph.nodes[i].edges == GVA_NULL) - { - nfa.sink = idx; - } // if - } // for - - for (size_t i = 0; i < array_length(graph.nodes); ++i) - { - for (gva_uint j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) - { - GVA_Variant variant = {0}; - size_t const count = gva_edges(graph.observed.str, - graph.nodes[i].match, graph.nodes[graph.edges[j].tail].match, - i == graph.source, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, - &variant); - for (size_t k = 0; k < count; ++k) - { - nfa.states[i] = ARRAY_APPEND(allocator, nfa.transitions, - ((NFA_Transition) - { - .symbol = NFA_LAMBDA, - .tail = array_length(nfa.states), - .next = nfa.states[i], - })); - nfa_edge(allocator, &nfa, - (GVA_Variant) - { - .start = variant.start + k, - .end = variant.end + k, - .sequence.len = variant.sequence.len, - .sequence.str = variant.sequence.str + k, - }); - size_t const head = array_length(nfa.states) - 1; - nfa.states[head] = ARRAY_APPEND(allocator, nfa.transitions, - ((NFA_Transition) - { - .symbol = NFA_LAMBDA, - .tail = graph.edges[j].tail, - .next = nfa.states[head], - })); - } // for - } // for - } // for - - return nfa; -} // nfa_from_lcs_graph - - -inline void -nfa_destroy(GVA_Allocator const allocator, NFA self[static 1]) -{ - self->transitions = ARRAY_DESTROY(allocator, self->transitions); - self->states = ARRAY_DESTROY(allocator, self->states); -} // nfa_destroy - - -void -nfa_dot(NFA const self) -{ - fprintf(stderr, "strict digraph{\nrankdir=LR\nnode[fixedsize=true,label=\"\",shape=circle,width=1]\ni[shape=none,width=0]\ni->%u\n", self.source); - for (size_t i = 0; i < array_length(self.states); ++i) - { - for (gva_uint j = self.states[i]; j != GVA_NULL; j = self.transitions[j].next) - { - if (self.transitions[j].symbol == NFA_DELETE) - { - fprintf(stderr, "%zu->%u[label=\"Δ\"]\n", i, self.transitions[j].tail); - } // if - else if (self.transitions[j].symbol == NFA_LAMBDA) - { - fprintf(stderr, "%zu->%u[label=\"λ\"]\n", i, self.transitions[j].tail); - } // if - else - { - fprintf(stderr, "%zu->%u[label=\"%c\"]\n", i, self.transitions[j].tail, self.transitions[j].symbol); - } // else - } // for - } // for - fprintf(stderr, "%u[peripheries=2]\n}\n", self.sink); -} // nfa_dot diff --git a/src/nfa.h b/src/nfa.h deleted file mode 100644 index 5a6d28e..0000000 --- a/src/nfa.h +++ /dev/null @@ -1,101 +0,0 @@ -#ifndef GVA_NFA_H -#define GVA_NFA_H - - -#include // size_t -#include // uint8_t - -#include "../include/allocator.h" // GVA_Allocator -#include "../include/lcs_graph.h" // GVA_LCS_Graph -#include "../include/string.h" // GVA_String -#include "../include/variant.h" // GVA_Variant -#include "../include/types.h" // gva_uint - - -enum -{ - DFA2_FINAL, - DFA2_DELETION, - DFA2_INSERTION, -}; - - -uint8_t* -dfa2_from_lcs_graph(GVA_Allocator const allocator, - uint8_t* dfa, GVA_LCS_Graph const graph); - - -void -dfa2_dot(size_t const len, char const reference[static len], - GVA_Variant const supremal, uint8_t const dfa[static 1]); - - -typedef struct -{ - uint8_t deletion : 1; - uint8_t insertion : 1; - uint8_t match : 1; -} DFA_State; // FIXME: could realy be 3 bits - - -typedef struct -{ - size_t start; - size_t size; - GVA_String observed; - DFA_State* states; -} DFA; - - -DFA -dfa_from_lcs_graph(GVA_Allocator const allocator, GVA_LCS_Graph const graph); - - -void -dfa_destroy(GVA_Allocator const allocator, DFA self[static 1]); - - -size_t -dfa_max_overlap(GVA_Allocator const allocator, DFA const lhs, DFA const rhs); - - -// FIXME: DEBUG -void -dfa_dot(DFA const self); - - -static char const NFA_LAMBDA = 0; -static char const NFA_DELETE = 127; - - -typedef struct -{ - char symbol; - gva_uint tail; - gva_uint next; -} NFA_Transition; - - -typedef struct -{ - gva_uint* states; - NFA_Transition* transitions; - gva_uint source; - gva_uint sink; -} NFA; - - -NFA -nfa_from_lcs_graph(GVA_Allocator const allocator, GVA_LCS_Graph const graph); - - -void -nfa_destroy(GVA_Allocator const allocator, NFA self[static 1]); - - -// FIXME: DEBUG -void -nfa_dot(NFA const self); - - -#endif // GVA_NFA_H From a7d59b41cc797e4557b7b2b886cee829bfc6517d Mon Sep 17 00:00:00 2001 From: jkvis Date: Sat, 25 Apr 2026 17:05:09 +0200 Subject: [PATCH 611/704] Restrict for char --- src/dfa.c | 4 ++-- src/dfa.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/dfa.c b/src/dfa.c index 52e8c97..c81a503 100644 --- a/src/dfa.c +++ b/src/dfa.c @@ -308,8 +308,8 @@ dfa_dot_traverse(size_t const len, char const reference[static len], void -dfa_dot(size_t const len, char const reference[static len], - GVA_Variant const supremal, uint8_t const dfa[static 1]) +dfa_dot(size_t const len, char const reference[static restrict len], + GVA_Variant const supremal, uint8_t const dfa[static restrict 1]) { size_t const width = supremal.sequence.len + 1; size_t const size = (supremal.end - supremal.start + 1) * width; diff --git a/src/dfa.h b/src/dfa.h index c168ec8..f39ce61 100644 --- a/src/dfa.h +++ b/src/dfa.h @@ -24,8 +24,8 @@ dfa_max_overlap(GVA_Allocator const allocator, // FIXME: DEBUG void -dfa_dot(size_t const len, char const reference[static len], - GVA_Variant const supremal, uint8_t const dfa[static 1]); +dfa_dot(size_t const len, char const reference[static restrict len], + GVA_Variant const supremal, uint8_t const dfa[static restrict 1]); #endif // GVA_DFA_H From 474cb6e8c1fdfbcb3318c879cc888e82ca4830f9 Mon Sep 17 00:00:00 2001 From: jkvis Date: Sat, 25 Apr 2026 17:09:51 +0200 Subject: [PATCH 612/704] Snapshot: 2bit DFAs working on 12k random examples --- src/dfa.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/dfa.c b/src/dfa.c index c81a503..4af763d 100644 --- a/src/dfa.c +++ b/src/dfa.c @@ -276,9 +276,10 @@ dfa_max_overlap(GVA_Allocator const allocator, } // dfa_max_overlap -void -dfa_dot_traverse(size_t const len, char const reference[static len], - GVA_Variant const supremal, uint8_t const dfa[static 1], size_t const idx) +// FIXME: DEBUG only; very inefficient +static void +dfa_dot_traverse(size_t const len, char const reference[static restrict len], + GVA_Variant const supremal, uint8_t const dfa[static restrict 1], size_t const idx) { size_t const width = supremal.sequence.len + 1; size_t const size = (supremal.end - supremal.start + 1) * width; From 293d7f605b3b6587cab4ce25470aee87952e112c Mon Sep 17 00:00:00 2001 From: jkvis Date: Sat, 25 Apr 2026 22:48:01 +0200 Subject: [PATCH 613/704] Reordering and merging common successors --- src/dfa.c | 129 +++++++++++++++++++++++------------------------------ src/main.c | 2 +- 2 files changed, 56 insertions(+), 75 deletions(-) diff --git a/src/dfa.c b/src/dfa.c index 4af763d..6a49fc4 100644 --- a/src/dfa.c +++ b/src/dfa.c @@ -1,3 +1,4 @@ +#include // bool #include // NULL, size_t #include // uint8_t #include // memset @@ -123,151 +124,131 @@ dfa_max_overlap(GVA_Allocator const allocator, if ((lhs_idx == 0 && rhs_ref < lhs_ref) || lhs_idx == lhs_size - 1) { - uint8_t const value = get(rhs_dfa, rhs_idx); + uint8_t const rhs_value = get(rhs_dfa, rhs_idx); + bool const rhs_deletion = rhs_value & DFA_DELETION; + bool const rhs_insertion = rhs_value & DFA_INSERTION; + bool const rhs_match = rhs_idx % rhs_width < rhs_width - 1 && + reference[rhs_supremal.start + rhs_idx / rhs_width] == rhs_supremal.sequence.str[rhs_idx % rhs_width]; - if (value & DFA_DELETION) + if (rhs_deletion) { fprintf(stderr, " push (. vs %zu DELTA) +0 +1 {%zu, %zu} (%zu)\n", rhs_ref, lhs_idx, rhs_idx + rhs_width, lhs_idx * rhs_size + rhs_idx + rhs_width); priority_queue_push(&fringe, lhs_idx * rhs_size + rhs_idx + rhs_width, fringe.states[idx].included, fringe.states[idx].excluded + 1); } // if - if (rhs_idx % rhs_width < rhs_width - 1 && - reference[rhs_supremal.start + rhs_idx / rhs_width] == rhs_supremal.sequence.str[rhs_idx % rhs_width]) + if (rhs_match) { fprintf(stderr, " push (. vs %zu MU) +0 +0 {%zu, %zu} (%zu)\n", rhs_ref, lhs_idx, rhs_idx + rhs_width + 1, lhs_idx * rhs_size + rhs_idx + rhs_width + 1); priority_queue_push(&fringe, lhs_idx * rhs_size + rhs_idx + rhs_width + 1, fringe.states[idx].included, fringe.states[idx].excluded); } // if - if (value & DFA_INSERTION) + if (rhs_insertion) { fprintf(stderr, " push (. vs %zu %c) +0 +1 {%zu, %zu} (%zu)\n", rhs_ref, rhs_supremal.sequence.str[rhs_idx % rhs_width], lhs_idx, rhs_idx + 1, lhs_idx * rhs_size + rhs_idx + 1); priority_queue_push(&fringe, lhs_idx * rhs_size + rhs_idx + 1, fringe.states[idx].included, fringe.states[idx].excluded + 1); } // if - continue; } // if - - if ((rhs_idx == 0 && lhs_ref < rhs_ref) || rhs_idx == rhs_size - 1) + else if ((rhs_idx == 0 && lhs_ref < rhs_ref) || rhs_idx == rhs_size - 1) { - uint8_t const value = get(lhs_dfa, lhs_idx); + uint8_t const lhs_value = get(lhs_dfa, lhs_idx); + bool const lhs_deletion = lhs_value & DFA_DELETION; + bool const lhs_insertion = lhs_value & DFA_INSERTION; + bool const lhs_match = lhs_idx % lhs_width < lhs_width - 1 && + reference[lhs_supremal.start + lhs_idx / lhs_width] == lhs_supremal.sequence.str[lhs_idx % lhs_width]; - if (value & DFA_DELETION) + if (lhs_deletion) { fprintf(stderr, " push (%zu DELTA vs .) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, lhs_idx + lhs_width, rhs_idx, (lhs_idx + lhs_width) * rhs_size + rhs_idx); priority_queue_push(&fringe, (lhs_idx + lhs_width) * rhs_size + rhs_idx, fringe.states[idx].included, fringe.states[idx].excluded + 1); } // if - if (lhs_idx % lhs_width < lhs_width - 1 && - reference[lhs_supremal.start + lhs_idx / lhs_width] == lhs_supremal.sequence.str[lhs_idx % lhs_width]) + if (lhs_match) { fprintf(stderr, " push (%zu MU vs .) +0 +0 {%zu, %zu} (%zu)\n", lhs_ref, lhs_idx + lhs_width + 1, rhs_idx, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx); priority_queue_push(&fringe, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx, fringe.states[idx].included, fringe.states[idx].excluded); } // if - if (value & DFA_INSERTION) + if (lhs_insertion) { fprintf(stderr, " push (%zu %c vs .) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, lhs_supremal.sequence.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx, (lhs_idx + 1) * rhs_size + rhs_idx); priority_queue_push(&fringe, (lhs_idx + 1) * rhs_size + rhs_idx, fringe.states[idx].included, fringe.states[idx].excluded + 1); } // if - continue; } // if - - uint8_t const lhs_value = get(lhs_dfa, lhs_idx); - uint8_t const rhs_value = get(rhs_dfa, rhs_idx); - - if (lhs_value & DFA_DELETION) + else { - if (rhs_value & DFA_DELETION) + uint8_t const lhs_value = get(lhs_dfa, lhs_idx); + uint8_t const rhs_value = get(rhs_dfa, rhs_idx); + bool const lhs_deletion = lhs_value & DFA_DELETION; + bool const rhs_deletion = rhs_value & DFA_DELETION; + bool const lhs_insertion = lhs_value & DFA_INSERTION; + bool const rhs_insertion = rhs_value & DFA_INSERTION; + bool const lhs_match = lhs_idx % lhs_width < lhs_width - 1 && + reference[lhs_supremal.start + lhs_idx / lhs_width] == lhs_supremal.sequence.str[lhs_idx % lhs_width]; + bool const rhs_match = rhs_idx % rhs_width < rhs_width - 1 && + reference[rhs_supremal.start + rhs_idx / rhs_width] == rhs_supremal.sequence.str[rhs_idx % rhs_width]; + + if (lhs_deletion && rhs_deletion) { + // DD fprintf(stderr, " push (%zu DELTA) {%zu, %zu} +1 +0 (%zu)\n", lhs_ref, lhs_idx + lhs_width, rhs_idx + rhs_width, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width); priority_queue_push(&fringe, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width, fringe.states[idx].included + 1, fringe.states[idx].excluded); } // if - if (rhs_idx % rhs_width < rhs_width - 1 && - reference[rhs_supremal.start + rhs_idx / rhs_width] == rhs_supremal.sequence.str[rhs_idx % rhs_width]) - { - fprintf(stderr, " push (%zu DELTA vs %zu MU) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, rhs_ref, lhs_idx + lhs_width, rhs_idx + rhs_width + 1, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width + 1); - priority_queue_push(&fringe, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width + 1, - fringe.states[idx].included, fringe.states[idx].excluded + 1); - } // if - - if (rhs_value & DFA_INSERTION) + if (lhs_insertion && rhs_insertion && lhs_supremal.sequence.str[lhs_idx % lhs_width] == rhs_supremal.sequence.str[rhs_idx % rhs_width]) { - fprintf(stderr, " push (. vs %zu %c) {%zu, %zu} +0 +1 (%zu)\n", rhs_ref, rhs_supremal.sequence.str[rhs_idx % rhs_width], lhs_idx, rhs_idx + 1, lhs_idx * rhs_size + rhs_idx + 1); - priority_queue_push(&fringe, lhs_idx * rhs_size + rhs_idx + 1, - fringe.states[idx].included, fringe.states[idx].excluded + 1); - } // if - } // if - - if (lhs_idx % lhs_width < lhs_width - 1 && - reference[lhs_supremal.start + lhs_idx / lhs_width] == lhs_supremal.sequence.str[lhs_idx % lhs_width]) - { - if (rhs_value & DFA_DELETION) - { - fprintf(stderr, " push (%zu MU vs %zu DELTA) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, rhs_ref, lhs_idx + lhs_width + 1, rhs_idx + rhs_width, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx + rhs_width); - priority_queue_push(&fringe, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx + rhs_width, - fringe.states[idx].included, fringe.states[idx].excluded + 1); + // II + fprintf(stderr, " push (%zu %c) {%zu, %zu} +1 +0 (%zu)\n", lhs_ref, lhs_supremal.sequence.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx + 1, (lhs_idx + 1) * rhs_size + rhs_idx + 1); + priority_queue_push(&fringe, (lhs_idx + 1) * rhs_size + rhs_idx + 1, + fringe.states[idx].included + 1, fringe.states[idx].excluded); } // if - if (rhs_idx % rhs_width < rhs_width - 1 && - reference[rhs_supremal.start + rhs_idx / rhs_width] == rhs_supremal.sequence.str[rhs_idx % rhs_width]) + if (lhs_match && rhs_match) { + // .. fprintf(stderr, " push (%zu MU) {%zu, %zu} +0 +0 (%zu)\n", lhs_ref, lhs_idx + lhs_width + 1, rhs_idx + rhs_width + 1, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx + rhs_width + 1); priority_queue_push(&fringe, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx + rhs_width + 1, fringe.states[idx].included, fringe.states[idx].excluded); } // if - if (rhs_value & DFA_INSERTION) + if (lhs_deletion && rhs_match) { - fprintf(stderr, " push (. vs %zu %c) {%zu, %zu} +0 +1 (%zu)\n", rhs_ref, rhs_supremal.sequence.str[rhs_idx % rhs_width], lhs_idx, rhs_idx + 1, lhs_idx * rhs_size + rhs_idx + 1); - priority_queue_push(&fringe, lhs_idx * rhs_size + rhs_idx + 1, + // D. + fprintf(stderr, " push (%zu DELTA vs %zu MU) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, rhs_ref, lhs_idx + lhs_width, rhs_idx + rhs_width + 1, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width + 1); + priority_queue_push(&fringe, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width + 1, fringe.states[idx].included, fringe.states[idx].excluded + 1); } // if - } // if - if (lhs_value & DFA_INSERTION) - { - if (rhs_value & DFA_DELETION) + if (lhs_match && rhs_deletion) { - fprintf(stderr, " push (%zu %c vs .) {%zu, %zu} +0 +1 (%zu)\n", lhs_ref, lhs_supremal.sequence.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx, (lhs_idx + 1) * rhs_size + rhs_idx); - priority_queue_push(&fringe, (lhs_idx + 1) * rhs_size + rhs_idx, + // .D + fprintf(stderr, " push (%zu MU vs %zu DELTA) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, rhs_ref, lhs_idx + lhs_width + 1, rhs_idx + rhs_width, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx + rhs_width); + priority_queue_push(&fringe, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx + rhs_width, fringe.states[idx].included, fringe.states[idx].excluded + 1); } // if - if (rhs_idx % rhs_width < rhs_width - 1 && - reference[rhs_supremal.start + rhs_idx / rhs_width] == rhs_supremal.sequence.str[rhs_idx % rhs_width]) + if (lhs_insertion && (rhs_deletion || rhs_match || (rhs_insertion && lhs_supremal.sequence.str[lhs_idx % lhs_width] != rhs_supremal.sequence.str[rhs_idx % rhs_width]))) { + // I. fprintf(stderr, " push (%zu %c vs .) {%zu, %zu} +0 +1 (%zu)\n", lhs_ref, lhs_supremal.sequence.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx, (lhs_idx + 1) * rhs_size + rhs_idx); priority_queue_push(&fringe, (lhs_idx + 1) * rhs_size + rhs_idx, fringe.states[idx].included, fringe.states[idx].excluded + 1); } // if - if (rhs_value & DFA_INSERTION) + if (rhs_insertion && (lhs_deletion || lhs_match || (lhs_insertion && lhs_supremal.sequence.str[lhs_idx % lhs_width] != rhs_supremal.sequence.str[rhs_idx % rhs_width]))) { - if (lhs_supremal.sequence.str[lhs_idx % lhs_width] == rhs_supremal.sequence.str[rhs_idx % rhs_width]) - { - fprintf(stderr, " push (%zu %c) {%zu, %zu} +1 +0 (%zu)\n", lhs_ref, lhs_supremal.sequence.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx + 1, (lhs_idx + 1) * rhs_size + rhs_idx + 1); - priority_queue_push(&fringe, (lhs_idx + 1) * rhs_size + rhs_idx + 1, - fringe.states[idx].included + 1, fringe.states[idx].excluded); - } // if - else - { - fprintf(stderr, " push (%zu %c vs .) {%zu, %zu} +0 +1 (%zu)\n", lhs_ref, lhs_supremal.sequence.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx, (lhs_idx + 1) * rhs_size + rhs_idx); - priority_queue_push(&fringe, (lhs_idx + 1) * rhs_size + rhs_idx, - fringe.states[idx].included, fringe.states[idx].excluded + 1); - - fprintf(stderr, " push (. vs %zu %c) {%zu, %zu} +0 +1 (%zu)\n", rhs_ref, rhs_supremal.sequence.str[rhs_idx % rhs_width], lhs_idx, rhs_idx + 1, lhs_idx * rhs_size + rhs_idx + 1); - priority_queue_push(&fringe, lhs_idx * rhs_size + rhs_idx + 1, - fringe.states[idx].included, fringe.states[idx].excluded + 1); - } // else + // .I + fprintf(stderr, " push (. vs %zu %c) {%zu, %zu} +0 +1 (%zu)\n", rhs_ref, rhs_supremal.sequence.str[rhs_idx % rhs_width], lhs_idx, rhs_idx + 1, lhs_idx * rhs_size + rhs_idx + 1); + priority_queue_push(&fringe, lhs_idx * rhs_size + rhs_idx + 1, + fringe.states[idx].included, fringe.states[idx].excluded + 1); } // if - } // if + } // else } // while priority_queue_destroy(&fringe); diff --git a/src/main.c b/src/main.c index 83d69ad..745b74d 100644 --- a/src/main.c +++ b/src/main.c @@ -501,8 +501,8 @@ supremal_main(int argc, char* argv[static argc]) fprintf(stderr, "#variants: %zu\n", line_count); fprintf(stderr, "%zu bytes\n", array_length(dfas)); - dfas = ARRAY_DESTROY(gva_std_allocator, dfas); + dfas = ARRAY_DESTROY(gva_std_allocator, dfas); gva_string_destroy(gva_std_allocator, reference); return EXIT_SUCCESS; From 1f33ca41a1b7dde18acb84c4f352315415a3db73 Mon Sep 17 00:00:00 2001 From: jkvis Date: Sun, 26 Apr 2026 09:07:04 +0200 Subject: [PATCH 614/704] Snapshot before PQ removal --- src/dfa.c | 62 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 36 insertions(+), 26 deletions(-) diff --git a/src/dfa.c b/src/dfa.c index 6a49fc4..bb165a5 100644 --- a/src/dfa.c +++ b/src/dfa.c @@ -1,3 +1,4 @@ +#include // CHAR_BIT #include // bool #include // NULL, size_t #include // uint8_t @@ -19,6 +20,13 @@ static uint8_t const DFA_DELETION = 0x1; static uint8_t const DFA_INSERTION = 0x2; +static inline uint8_t +get(uint8_t const dfa[static 1], size_t const idx) +{ + return dfa[idx / 4] >> (2 * (idx % 4)); +} // get + + static inline void set(uint8_t dfa[static 1], size_t const idx, uint8_t const value) { @@ -26,13 +34,6 @@ set(uint8_t dfa[static 1], size_t const idx, uint8_t const value) } // set -static inline uint8_t -get(uint8_t const dfa[static 1], size_t const idx) -{ - return (dfa[idx / 4] >> (2 * (idx % 4)) & 0x3); -} // get - - static inline void edge(uint8_t dfa[static 1], size_t const width, size_t const start, size_t const end, @@ -130,22 +131,25 @@ dfa_max_overlap(GVA_Allocator const allocator, bool const rhs_match = rhs_idx % rhs_width < rhs_width - 1 && reference[rhs_supremal.start + rhs_idx / rhs_width] == rhs_supremal.sequence.str[rhs_idx % rhs_width]; - if (rhs_deletion) - { - fprintf(stderr, " push (. vs %zu DELTA) +0 +1 {%zu, %zu} (%zu)\n", rhs_ref, lhs_idx, rhs_idx + rhs_width, lhs_idx * rhs_size + rhs_idx + rhs_width); - priority_queue_push(&fringe, lhs_idx * rhs_size + rhs_idx + rhs_width, - fringe.states[idx].included, fringe.states[idx].excluded + 1); - } // if - if (rhs_match) { + // .. fprintf(stderr, " push (. vs %zu MU) +0 +0 {%zu, %zu} (%zu)\n", rhs_ref, lhs_idx, rhs_idx + rhs_width + 1, lhs_idx * rhs_size + rhs_idx + rhs_width + 1); priority_queue_push(&fringe, lhs_idx * rhs_size + rhs_idx + rhs_width + 1, fringe.states[idx].included, fringe.states[idx].excluded); } // if + if (rhs_deletion) + { + // .D + fprintf(stderr, " push (. vs %zu DELTA) +0 +1 {%zu, %zu} (%zu)\n", rhs_ref, lhs_idx, rhs_idx + rhs_width, lhs_idx * rhs_size + rhs_idx + rhs_width); + priority_queue_push(&fringe, lhs_idx * rhs_size + rhs_idx + rhs_width, + fringe.states[idx].included, fringe.states[idx].excluded + 1); + } // if + if (rhs_insertion) { + // .I fprintf(stderr, " push (. vs %zu %c) +0 +1 {%zu, %zu} (%zu)\n", rhs_ref, rhs_supremal.sequence.str[rhs_idx % rhs_width], lhs_idx, rhs_idx + 1, lhs_idx * rhs_size + rhs_idx + 1); priority_queue_push(&fringe, lhs_idx * rhs_size + rhs_idx + 1, fringe.states[idx].included, fringe.states[idx].excluded + 1); @@ -159,22 +163,25 @@ dfa_max_overlap(GVA_Allocator const allocator, bool const lhs_match = lhs_idx % lhs_width < lhs_width - 1 && reference[lhs_supremal.start + lhs_idx / lhs_width] == lhs_supremal.sequence.str[lhs_idx % lhs_width]; - if (lhs_deletion) - { - fprintf(stderr, " push (%zu DELTA vs .) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, lhs_idx + lhs_width, rhs_idx, (lhs_idx + lhs_width) * rhs_size + rhs_idx); - priority_queue_push(&fringe, (lhs_idx + lhs_width) * rhs_size + rhs_idx, - fringe.states[idx].included, fringe.states[idx].excluded + 1); - } // if - if (lhs_match) { + // .. fprintf(stderr, " push (%zu MU vs .) +0 +0 {%zu, %zu} (%zu)\n", lhs_ref, lhs_idx + lhs_width + 1, rhs_idx, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx); priority_queue_push(&fringe, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx, fringe.states[idx].included, fringe.states[idx].excluded); } // if + if (lhs_deletion) + { + // D. + fprintf(stderr, " push (%zu DELTA vs .) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, lhs_idx + lhs_width, rhs_idx, (lhs_idx + lhs_width) * rhs_size + rhs_idx); + priority_queue_push(&fringe, (lhs_idx + lhs_width) * rhs_size + rhs_idx, + fringe.states[idx].included, fringe.states[idx].excluded + 1); + } // if + if (lhs_insertion) { + // I. fprintf(stderr, " push (%zu %c vs .) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, lhs_supremal.sequence.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx, (lhs_idx + 1) * rhs_size + rhs_idx); priority_queue_push(&fringe, (lhs_idx + 1) * rhs_size + rhs_idx, fringe.states[idx].included, fringe.states[idx].excluded + 1); @@ -183,13 +190,14 @@ dfa_max_overlap(GVA_Allocator const allocator, else { uint8_t const lhs_value = get(lhs_dfa, lhs_idx); - uint8_t const rhs_value = get(rhs_dfa, rhs_idx); bool const lhs_deletion = lhs_value & DFA_DELETION; - bool const rhs_deletion = rhs_value & DFA_DELETION; bool const lhs_insertion = lhs_value & DFA_INSERTION; - bool const rhs_insertion = rhs_value & DFA_INSERTION; bool const lhs_match = lhs_idx % lhs_width < lhs_width - 1 && reference[lhs_supremal.start + lhs_idx / lhs_width] == lhs_supremal.sequence.str[lhs_idx % lhs_width]; + + uint8_t const rhs_value = get(rhs_dfa, rhs_idx); + bool const rhs_deletion = rhs_value & DFA_DELETION; + bool const rhs_insertion = rhs_value & DFA_INSERTION; bool const rhs_match = rhs_idx % rhs_width < rhs_width - 1 && reference[rhs_supremal.start + rhs_idx / rhs_width] == rhs_supremal.sequence.str[rhs_idx % rhs_width]; @@ -233,7 +241,8 @@ dfa_max_overlap(GVA_Allocator const allocator, fringe.states[idx].included, fringe.states[idx].excluded + 1); } // if - if (lhs_insertion && (rhs_deletion || rhs_match || (rhs_insertion && lhs_supremal.sequence.str[lhs_idx % lhs_width] != rhs_supremal.sequence.str[rhs_idx % rhs_width]))) + if (lhs_insertion && (rhs_deletion || rhs_match || (rhs_insertion && + lhs_supremal.sequence.str[lhs_idx % lhs_width] != rhs_supremal.sequence.str[rhs_idx % rhs_width]))) { // I. fprintf(stderr, " push (%zu %c vs .) {%zu, %zu} +0 +1 (%zu)\n", lhs_ref, lhs_supremal.sequence.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx, (lhs_idx + 1) * rhs_size + rhs_idx); @@ -241,7 +250,8 @@ dfa_max_overlap(GVA_Allocator const allocator, fringe.states[idx].included, fringe.states[idx].excluded + 1); } // if - if (rhs_insertion && (lhs_deletion || lhs_match || (lhs_insertion && lhs_supremal.sequence.str[lhs_idx % lhs_width] != rhs_supremal.sequence.str[rhs_idx % rhs_width]))) + if (rhs_insertion && (lhs_deletion || lhs_match || (lhs_insertion && + lhs_supremal.sequence.str[lhs_idx % lhs_width] != rhs_supremal.sequence.str[rhs_idx % rhs_width]))) { // .I fprintf(stderr, " push (. vs %zu %c) {%zu, %zu} +0 +1 (%zu)\n", rhs_ref, rhs_supremal.sequence.str[rhs_idx % rhs_width], lhs_idx, rhs_idx + 1, lhs_idx * rhs_size + rhs_idx + 1); From f00c8822b2138616720854d79fb961b4804efc15 Mon Sep 17 00:00:00 2001 From: jkvis Date: Sun, 26 Apr 2026 13:18:18 +0200 Subject: [PATCH 615/704] WIP: max overlap with regular queue --- src/dfa.c | 203 +++++++++++++++++++++++++++++++++---------- src/priority_queue.c | 139 ----------------------------- src/priority_queue.h | 50 ----------- 3 files changed, 159 insertions(+), 233 deletions(-) delete mode 100644 src/priority_queue.c delete mode 100644 src/priority_queue.h diff --git a/src/dfa.c b/src/dfa.c index bb165a5..783c2a6 100644 --- a/src/dfa.c +++ b/src/dfa.c @@ -10,7 +10,6 @@ #include "../include/variant.h" // GVA_Variant #include "array.h" // ARRAY_*, array_* #include "dfa.h" // dfa* -#include "priority_queue.h" // Priority_Queue, priority_queue_* #include // DEBUG @@ -88,6 +87,128 @@ dfa_from_lcs_graph(GVA_Allocator const allocator, uint8_t* dfas, } // dfa_from_lcs_graph +typedef struct +{ + gva_uint seen : 1; + gva_uint included : sizeof(gva_uint) * CHAR_BIT - 1; + gva_uint next; +} Queue_Entry; + + +typedef struct +{ + Queue_Entry* entries; + size_t size; + gva_uint head; + gva_uint tail; +} Queue; + + +static inline Queue +queue_init(GVA_Allocator const allocator, size_t const size) +{ + Queue queue = + { + .entries = allocator.allocate(allocator.context, NULL, 0, sizeof(*queue.entries) * size), + .size = size, + .head = GVA_NULL, + .tail = GVA_NULL, + }; + + memset(queue.entries, 0, sizeof(*queue.entries) * size); + return queue; +} // queue_init + + +static inline void +queue_destroy(GVA_Allocator const allocator, Queue self[static 1]) +{ + self->entries = allocator.allocate(allocator.context, self->entries, sizeof(*self->entries) * self->size, 0); + self->head = GVA_NULL; + self->tail = GVA_NULL; +} // queue_destroy + + +static inline bool +queue_empty(Queue const self[static 1]) +{ + return self->head == GVA_NULL; +} // queue_empty + + +static inline gva_uint +queue_pop(Queue self[static 1]) +{ + gva_uint const idx = self->head; + self->head = self->entries[idx].next; + if (self->head == GVA_NULL) + { + self->tail = GVA_NULL; + } // if + return idx; +} // queue_pop + + +static inline void +queue_push_back(Queue self[static 1], gva_uint const idx, gva_uint const included) +{ + if (self->entries[idx].seen) + { + return; + } // if + + self->entries[idx] = (Queue_Entry) + { + .seen = true, + .included = included, + .next = GVA_NULL, + }; + if (self->tail == GVA_NULL) + { + self->head = idx; + } // if + else + { + self->entries[self->tail].next = idx; + } // else + self->tail = idx; +} // queue_push_back + + +static inline void +queue_push_front(Queue self[static 1], gva_uint const idx, gva_uint const included) +{ + if (self->entries[idx].seen) + { + return; + } // if + + self->entries[idx] = (Queue_Entry) + { + .seen = true, + .included = included, + .next = self->head, + }; + if (self->head == GVA_NULL) + { + self->tail = idx; + } // if + self->head = idx; +} // queue_push_front + + +static inline void +queue_print(Queue const self[static 1]) +{ + gva_uint idx = self->head; + while (idx != GVA_NULL) + { + fprintf(stderr, "%u: %d %d\n", idx, self->entries[idx].seen, self->entries[idx].next); + idx = self->entries[idx].next; + } // if +} // queue_print + + size_t dfa_max_overlap(GVA_Allocator const allocator, size_t const len, char const reference[static restrict len], @@ -99,30 +220,34 @@ dfa_max_overlap(GVA_Allocator const allocator, size_t const lhs_size = (lhs_supremal.end - lhs_supremal.start + 1) * lhs_width; size_t const rhs_size = (rhs_supremal.end - rhs_supremal.start + 1) * rhs_width; - Priority_Queue fringe = priority_queue_init(allocator, lhs_size * rhs_size); - priority_queue_push(&fringe, 0, 0, 0); + Queue queue = queue_init(allocator, lhs_size * rhs_size); + if (queue.entries == NULL) + { + return 0; // OOM + } // if + + queue_push_front(&queue, 0, 0); size_t count = 0; - while (!priority_queue_empty(fringe)) + while (!queue_empty(&queue)) { count += 1; - size_t const idx = priority_queue_pop(&fringe); + size_t const idx = queue_pop(&queue); size_t const lhs_idx = idx / rhs_size; size_t const rhs_idx = idx % rhs_size; - size_t const lhs_ref = lhs_idx / lhs_width + lhs_supremal.start; - size_t const rhs_ref = rhs_idx / rhs_width + rhs_supremal.start; - - fprintf(stderr, "{%zu, %zu} (%zu) :: %u %u\n", lhs_idx, rhs_idx, idx, - fringe.states[idx].included, fringe.states[idx].excluded); + fprintf(stderr, "{%zu, %zu} (%zu): %u\n", lhs_idx, rhs_idx, idx, queue.entries[idx].included); if (lhs_idx == lhs_size - 1 && rhs_idx == rhs_size - 1) { - fprintf(stdout, "%u %zu %zu\n", fringe.states[idx].included, count, array_length(fringe.heap)); + fprintf(stdout, "%u %zu\n", queue.entries[idx].included, count); break; } // if + size_t const lhs_ref = lhs_idx / lhs_width + lhs_supremal.start; + size_t const rhs_ref = rhs_idx / rhs_width + rhs_supremal.start; + if ((lhs_idx == 0 && rhs_ref < lhs_ref) || lhs_idx == lhs_size - 1) { uint8_t const rhs_value = get(rhs_dfa, rhs_idx); @@ -135,24 +260,21 @@ dfa_max_overlap(GVA_Allocator const allocator, { // .. fprintf(stderr, " push (. vs %zu MU) +0 +0 {%zu, %zu} (%zu)\n", rhs_ref, lhs_idx, rhs_idx + rhs_width + 1, lhs_idx * rhs_size + rhs_idx + rhs_width + 1); - priority_queue_push(&fringe, lhs_idx * rhs_size + rhs_idx + rhs_width + 1, - fringe.states[idx].included, fringe.states[idx].excluded); + queue_push_front(&queue, lhs_idx * rhs_size + rhs_idx + rhs_width + 1, queue.entries[idx].included); } // if if (rhs_deletion) { // .D fprintf(stderr, " push (. vs %zu DELTA) +0 +1 {%zu, %zu} (%zu)\n", rhs_ref, lhs_idx, rhs_idx + rhs_width, lhs_idx * rhs_size + rhs_idx + rhs_width); - priority_queue_push(&fringe, lhs_idx * rhs_size + rhs_idx + rhs_width, - fringe.states[idx].included, fringe.states[idx].excluded + 1); + queue_push_back(&queue, lhs_idx * rhs_size + rhs_idx + rhs_width, queue.entries[idx].included); } // if if (rhs_insertion) { // .I fprintf(stderr, " push (. vs %zu %c) +0 +1 {%zu, %zu} (%zu)\n", rhs_ref, rhs_supremal.sequence.str[rhs_idx % rhs_width], lhs_idx, rhs_idx + 1, lhs_idx * rhs_size + rhs_idx + 1); - priority_queue_push(&fringe, lhs_idx * rhs_size + rhs_idx + 1, - fringe.states[idx].included, fringe.states[idx].excluded + 1); + queue_push_back(&queue, lhs_idx * rhs_size + rhs_idx + 1, queue.entries[idx].included); } // if } // if else if ((rhs_idx == 0 && lhs_ref < rhs_ref) || rhs_idx == rhs_size - 1) @@ -167,24 +289,21 @@ dfa_max_overlap(GVA_Allocator const allocator, { // .. fprintf(stderr, " push (%zu MU vs .) +0 +0 {%zu, %zu} (%zu)\n", lhs_ref, lhs_idx + lhs_width + 1, rhs_idx, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx); - priority_queue_push(&fringe, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx, - fringe.states[idx].included, fringe.states[idx].excluded); + queue_push_front(&queue, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx, queue.entries[idx].included); } // if if (lhs_deletion) { // D. fprintf(stderr, " push (%zu DELTA vs .) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, lhs_idx + lhs_width, rhs_idx, (lhs_idx + lhs_width) * rhs_size + rhs_idx); - priority_queue_push(&fringe, (lhs_idx + lhs_width) * rhs_size + rhs_idx, - fringe.states[idx].included, fringe.states[idx].excluded + 1); + queue_push_back(&queue, (lhs_idx + lhs_width) * rhs_size + rhs_idx, queue.entries[idx].included); } // if if (lhs_insertion) { // I. fprintf(stderr, " push (%zu %c vs .) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, lhs_supremal.sequence.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx, (lhs_idx + 1) * rhs_size + rhs_idx); - priority_queue_push(&fringe, (lhs_idx + 1) * rhs_size + rhs_idx, - fringe.states[idx].included, fringe.states[idx].excluded + 1); + queue_push_back(&queue, (lhs_idx + 1) * rhs_size + rhs_idx, queue.entries[idx].included); } // if } // if else @@ -201,44 +320,39 @@ dfa_max_overlap(GVA_Allocator const allocator, bool const rhs_match = rhs_idx % rhs_width < rhs_width - 1 && reference[rhs_supremal.start + rhs_idx / rhs_width] == rhs_supremal.sequence.str[rhs_idx % rhs_width]; + if (lhs_match && rhs_match) + { + // .. + fprintf(stderr, " push (%zu MU) {%zu, %zu} +0 +0 (%zu)\n", lhs_ref, lhs_idx + lhs_width + 1, rhs_idx + rhs_width + 1, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx + rhs_width + 1); + queue_push_front(&queue, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx + rhs_width + 1, queue.entries[idx].included); + } // if + if (lhs_deletion && rhs_deletion) { // DD fprintf(stderr, " push (%zu DELTA) {%zu, %zu} +1 +0 (%zu)\n", lhs_ref, lhs_idx + lhs_width, rhs_idx + rhs_width, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width); - priority_queue_push(&fringe, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width, - fringe.states[idx].included + 1, fringe.states[idx].excluded); + queue_push_front(&queue, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width, queue.entries[idx].included + 1); } // if if (lhs_insertion && rhs_insertion && lhs_supremal.sequence.str[lhs_idx % lhs_width] == rhs_supremal.sequence.str[rhs_idx % rhs_width]) { // II fprintf(stderr, " push (%zu %c) {%zu, %zu} +1 +0 (%zu)\n", lhs_ref, lhs_supremal.sequence.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx + 1, (lhs_idx + 1) * rhs_size + rhs_idx + 1); - priority_queue_push(&fringe, (lhs_idx + 1) * rhs_size + rhs_idx + 1, - fringe.states[idx].included + 1, fringe.states[idx].excluded); - } // if - - if (lhs_match && rhs_match) - { - // .. - fprintf(stderr, " push (%zu MU) {%zu, %zu} +0 +0 (%zu)\n", lhs_ref, lhs_idx + lhs_width + 1, rhs_idx + rhs_width + 1, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx + rhs_width + 1); - priority_queue_push(&fringe, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx + rhs_width + 1, - fringe.states[idx].included, fringe.states[idx].excluded); + queue_push_front(&queue, (lhs_idx + 1) * rhs_size + rhs_idx + 1, queue.entries[idx].included + 1); } // if if (lhs_deletion && rhs_match) { // D. fprintf(stderr, " push (%zu DELTA vs %zu MU) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, rhs_ref, lhs_idx + lhs_width, rhs_idx + rhs_width + 1, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width + 1); - priority_queue_push(&fringe, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width + 1, - fringe.states[idx].included, fringe.states[idx].excluded + 1); + queue_push_back(&queue, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width + 1, queue.entries[idx].included); } // if if (lhs_match && rhs_deletion) { // .D fprintf(stderr, " push (%zu MU vs %zu DELTA) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, rhs_ref, lhs_idx + lhs_width + 1, rhs_idx + rhs_width, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx + rhs_width); - priority_queue_push(&fringe, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx + rhs_width, - fringe.states[idx].included, fringe.states[idx].excluded + 1); + queue_push_back(&queue, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx + rhs_width, queue.entries[idx].included); } // if if (lhs_insertion && (rhs_deletion || rhs_match || (rhs_insertion && @@ -246,8 +360,7 @@ dfa_max_overlap(GVA_Allocator const allocator, { // I. fprintf(stderr, " push (%zu %c vs .) {%zu, %zu} +0 +1 (%zu)\n", lhs_ref, lhs_supremal.sequence.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx, (lhs_idx + 1) * rhs_size + rhs_idx); - priority_queue_push(&fringe, (lhs_idx + 1) * rhs_size + rhs_idx, - fringe.states[idx].included, fringe.states[idx].excluded + 1); + queue_push_back(&queue, (lhs_idx + 1) * rhs_size + rhs_idx, queue.entries[idx].included); } // if if (rhs_insertion && (lhs_deletion || lhs_match || (lhs_insertion && @@ -255,13 +368,15 @@ dfa_max_overlap(GVA_Allocator const allocator, { // .I fprintf(stderr, " push (. vs %zu %c) {%zu, %zu} +0 +1 (%zu)\n", rhs_ref, rhs_supremal.sequence.str[rhs_idx % rhs_width], lhs_idx, rhs_idx + 1, lhs_idx * rhs_size + rhs_idx + 1); - priority_queue_push(&fringe, lhs_idx * rhs_size + rhs_idx + 1, - fringe.states[idx].included, fringe.states[idx].excluded + 1); + queue_push_back(&queue, lhs_idx * rhs_size + rhs_idx + 1, queue.entries[idx].included); } // if } // else + + //queue_print(&queue); + } // while - priority_queue_destroy(&fringe); + queue_destroy(allocator, &queue); return 0; } // dfa_max_overlap diff --git a/src/priority_queue.c b/src/priority_queue.c deleted file mode 100644 index 91fa3ef..0000000 --- a/src/priority_queue.c +++ /dev/null @@ -1,139 +0,0 @@ -#include // bool -#include // size_t - -#include "../include/allocator.h" // GVA_Allocator -#include "../include/types.h" // GVA_NULL, gva_uint - -#include "array.h" // ARRAY_* -#include "priority_queue.h" // Priority_Queue*, priority_queue_* - - -static inline bool -less_than(size_t const lhs_included, size_t const lhs_excluded, - size_t const rhs_included, size_t const rhs_excluded) -{ - return lhs_excluded < rhs_excluded || - (lhs_excluded == rhs_excluded && lhs_included >= rhs_included); -} // less_than - - -static inline void -swap(gva_uint lhs[static restrict 1], gva_uint rhs[static restrict 1]) -{ - gva_uint const temp = *lhs; - *lhs = *rhs; - *rhs = temp; -} // swap - - -inline Priority_Queue -priority_queue_init(GVA_Allocator const allocator, size_t const capacity) -{ - Priority_Queue_State* const states = allocator.allocate(allocator.context, NULL, 0, capacity * sizeof(*states)); - if (states == NULL) - { - return (Priority_Queue) {NULL}; - } // if - - for (size_t i = 0; i < capacity; ++i) - { - states[i].idx = GVA_NULL; - } // for - - return (Priority_Queue) - { - .states = states, - .capacity = capacity, - .allocator = allocator, - }; -} // priority_queue_init - - -inline void -priority_queue_destroy(Priority_Queue self[static 1]) -{ - self->heap = ARRAY_DESTROY(self->allocator, self->heap); - self->states = self->allocator.allocate(self->allocator.context, self->states, self->capacity * sizeof(*self->states), 0); - self->capacity = 0; -} // priority_queue_destroy - - -inline bool -priority_queue_empty(Priority_Queue const self) -{ - return array_length(self.heap) == 0; -} // priority_queue_empty - - -inline size_t -priority_queue_pop(Priority_Queue self[static 1]) -{ - size_t const idx = self->heap[0]; - self->states[self->heap[0]].idx = array_length(self->heap); - size_t const len = array_header(self->heap)->length -= 1; - self->heap[0] = self->heap[len]; - if (len > 0) - { - self->states[self->heap[0]].idx = 0; - } // if - - size_t i = 0; - while (i < len / 2) - { - size_t child = 2 * i + 1; // left child - if (child + 1 < len && - less_than(self->states[self->heap[child + 1]].included, self->states[self->heap[child + 1]].excluded, - self->states[self->heap[child]].included, self->states[self->heap[child]].excluded)) - { - child += 1; // right child - } // if - if (less_than(self->states[self->heap[i]].included, self->states[self->heap[i]].excluded, - self->states[self->heap[child]].included, self->states[self->heap[child]].excluded)) - { - break; - } // if - swap(&self->states[self->heap[i]].idx, &self->states[self->heap[child]].idx); - swap(&self->heap[i], &self->heap[child]); - i = child; - } // while - - return idx; -} // priority_queue_pop - - -inline void -priority_queue_push(Priority_Queue self[static 1], size_t const key, - size_t const included, size_t const excluded) -{ - if (self->states[key].idx == GVA_NULL) - { - self->states[key] = (Priority_Queue_State) - { - .idx = ARRAY_APPEND(self->allocator, self->heap, key), - .included = included, - .excluded = excluded, - }; - } // if - else - { - if (less_than(self->states[key].included, self->states[key].excluded, included, excluded)) - { - return; - } // if - self->states[key].included = included; - self->states[key].excluded = excluded; - } // else - - size_t i = self->states[key].idx; - while (i > 0) - { - size_t const parent = (i - 1) / 2; - if (less_than(self->states[self->heap[parent]].included, self->states[self->heap[parent]].excluded, included, excluded)) - { - break; - } // if - swap(&self->states[self->heap[i]].idx, &self->states[self->heap[parent]].idx); - swap(&self->heap[i], &self->heap[parent]); - i = parent; - } // while -} // priority_queue_push diff --git a/src/priority_queue.h b/src/priority_queue.h deleted file mode 100644 index 45439f7..0000000 --- a/src/priority_queue.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef GVA_PRIORITY_QUEUE_H -#define GVA_PRIORITY_QUEUE_H - - -#include // bool -#include // size_t - -#include "../include/allocator.h" // GVA_Allocator -#include "../include/types.h" // gva_uint - - -typedef struct -{ - gva_uint idx; - gva_uint included; - gva_uint excluded; -} Priority_Queue_State; - - -typedef struct -{ - Priority_Queue_State* states; - gva_uint* heap; - size_t capacity; - GVA_Allocator allocator; -} Priority_Queue; - - -Priority_Queue -priority_queue_init(GVA_Allocator const allocator, size_t const capacity); - - -void -priority_queue_destroy(Priority_Queue self[static 1]); - - -bool -priority_queue_empty(Priority_Queue const self); - - -size_t -priority_queue_pop(Priority_Queue self[static 1]); - - -void -priority_queue_push(Priority_Queue self[static 1], size_t const key, - size_t const included, size_t const excluded); - - -#endif // GVA_PRIORITY_QUEUE_H From 635adaa8c876580b6d87d9f8721a710618538119 Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 27 Apr 2026 10:01:57 +0200 Subject: [PATCH 616/704] WIP: DFA directly from alignments --- src/dfa.c | 167 +++++++++++++++++++++++++++++++++++++++++++++++------ src/dfa.h | 7 +++ src/main.c | 14 +++-- 3 files changed, 166 insertions(+), 22 deletions(-) diff --git a/src/dfa.c b/src/dfa.c index 783c2a6..44d132c 100644 --- a/src/dfa.c +++ b/src/dfa.c @@ -8,6 +8,7 @@ #include "../include/lcs_graph.h" // GVA_LCS_Graph, gva_edges #include "../include/types.h" // GVA_NULL, gva_uint #include "../include/variant.h" // GVA_Variant +#include "align.h" // LCS_Alignment, lcs_align #include "array.h" // ARRAY_*, array_* #include "dfa.h" // dfa* @@ -49,6 +50,149 @@ edge(uint8_t dfa[static 1], size_t const width, } // edge +uint8_t* +dfa_from_alignment(GVA_Allocator const allocator, uint8_t* dfas, + size_t const len_ref, char const reference[static restrict len_ref], + size_t const len_obs, char const observed[static restrict len_obs], + size_t const offset) +{ + LCS_Alignment lcs = lcs_align(allocator, len_ref, reference, len_obs, observed, offset); + size_t const distance = len_ref + len_obs - 2 * lcs.length; + + if (distance == 0) + { + return dfas; + } // if + + size_t const width = len_obs + 1; + size_t const size = (len_ref + 1) * width; + size_t const len = (size + 3) / 4; + + dfas = array_ensure(allocator, dfas, 1, len); + if (dfas == NULL) + { + lcs.index = allocator.allocate(allocator.context, lcs.index, lcs.length * sizeof(*lcs.index), 0); + lcs.nodes = ARRAY_DESTROY(allocator, lcs.nodes); + return NULL; // OOM + } // if + + size_t const start = array_length(dfas); + memset(dfas + start, 0, len); + array_header(dfas)->length += len; + + if (lcs.nodes == NULL) + { + edge(dfas + start, width, 0, len_ref, len_obs, 0); + return dfas; + } // if + + gva_uint tail_idx = lcs.index[lcs.length - 1].tail; + LCS_Node sink = lcs.nodes[tail_idx]; + if (sink.match.row + sink.match.length == len_ref + offset && + sink.match.col + sink.match.length == len_obs) + { + lcs.nodes[tail_idx].moved = true; + sink = lcs.nodes[tail_idx]; + } // if + else + { + sink = (LCS_Node) {.match = {len_ref + offset, len_obs}}; + tail_idx = GVA_NULL; + } // else + + for (gva_uint i = lcs.index[lcs.length - 1].head; i != tail_idx; i = lcs.nodes[i].next) + { + edge(dfas + start, width, + lcs.nodes[i].match.row + lcs.nodes[i].match.length - offset, + sink.match.row + sink.match.length - offset, + sink.match.col + sink.match.length - (lcs.nodes[i].match.col + lcs.nodes[i].match.length), + lcs.nodes[i].match.col + lcs.nodes[i].match.length); + lcs.nodes[i].moved = true; + } // for + + for (gva_uint i = lcs.length - 1; i >= 1; --i) + { + gva_uint next = GVA_NULL; + for (gva_uint j = lcs.index[i].head; j != GVA_NULL; j = next) + { + LCS_Node* const restrict tail = &lcs.nodes[j]; + next = tail->next; + if (!tail->moved) + { + continue; + } // if + + gva_uint here = GVA_NULL; + for (gva_uint k = lcs.index[i - 1].head; k != GVA_NULL; k = lcs.nodes[k].next) + { + LCS_Node* const restrict head = &lcs.nodes[k]; + + if (k >= j || + head->match.row + head->match.length >= tail->match.row + tail->match.length || + head->match.col + head->match.length >= tail->match.col + tail->match.length) + { + continue; + } // if + + edge(dfas + start, width, + head->match.row + head->match.length - offset, + tail->match.row + tail->match.length - offset - 1, + tail->match.col + tail->match.length - (head->match.col + head->match.length) - 1, + head->match.col + head->match.length); + head->moved = true; + + here = k; + } // for + + if (tail->match.length > 1) + { + tail->match.length -= 1; + if (here != GVA_NULL) + { + tail->next = lcs.nodes[here].next; + lcs.nodes[here].next = j; + } // if + else + { + tail->next = lcs.index[i - 1].head; + lcs.index[i - 1].head = j; + } // else + } // if + } // for + } // for + + gva_uint head_idx = lcs.index[0].head; + LCS_Node source = lcs.nodes[head_idx]; + if (source.match.row == offset && source.match.col == 0) + { + head_idx = source.next; + } // if + else + { + source = (LCS_Node) {.match.row = offset}; + } // else + for (gva_uint i = head_idx; i != GVA_NULL; i = lcs.nodes[i].next) + { + if (!lcs.nodes[i].moved) + { + continue; + } // if + + if (source.match.length == 0) + { + edge(dfas + start, width, + source.match.row - offset, lcs.nodes[i].match.row - offset, + lcs.nodes[i].match.col - source.match.col, 0); + } // if + } // for + + lcs.index = allocator.allocate(allocator.context, lcs.index, lcs.length * sizeof(*lcs.index), 0); + lcs.nodes = ARRAY_DESTROY(allocator, lcs.nodes); + + return dfas; +} // dfa_from_alignment + + uint8_t* dfa_from_lcs_graph(GVA_Allocator const allocator, uint8_t* dfas, GVA_LCS_Graph const graph) @@ -64,7 +208,10 @@ dfa_from_lcs_graph(GVA_Allocator const allocator, uint8_t* dfas, return NULL; // OOM } // if - memset(dfas + array_length(dfas), 0, len); + size_t const start = array_length(dfas); + memset(dfas + start, 0, len); + array_header(dfas)->length += len; + for (size_t i = 0; i < array_length(graph.nodes); ++i) { for (gva_uint j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) @@ -76,12 +223,11 @@ dfa_from_lcs_graph(GVA_Allocator const allocator, uint8_t* dfas, &variant); for (size_t k = 0; k < count; ++k) { - edge(dfas + array_length(dfas), width, variant.start + k - supremal.start, variant.end + k - supremal.start, + edge(dfas + start, width, variant.start + k - supremal.start, variant.end + k - supremal.start, variant.sequence.len, variant.sequence.str - supremal.sequence.str + k); } // for } // for } // for - array_header(dfas)->length += len; return dfas; } // dfa_from_lcs_graph @@ -197,18 +343,6 @@ queue_push_front(Queue self[static 1], gva_uint const idx, gva_uint const includ } // queue_push_front -static inline void -queue_print(Queue const self[static 1]) -{ - gva_uint idx = self->head; - while (idx != GVA_NULL) - { - fprintf(stderr, "%u: %d %d\n", idx, self->entries[idx].seen, self->entries[idx].next); - idx = self->entries[idx].next; - } // if -} // queue_print - - size_t dfa_max_overlap(GVA_Allocator const allocator, size_t const len, char const reference[static restrict len], @@ -371,9 +505,6 @@ dfa_max_overlap(GVA_Allocator const allocator, queue_push_back(&queue, lhs_idx * rhs_size + rhs_idx + 1, queue.entries[idx].included); } // if } // else - - //queue_print(&queue); - } // while queue_destroy(allocator, &queue); diff --git a/src/dfa.h b/src/dfa.h index f39ce61..67df336 100644 --- a/src/dfa.h +++ b/src/dfa.h @@ -10,6 +10,13 @@ #include "../include/variant.h" // GVA_Variant +uint8_t* +dfa_from_alignment(GVA_Allocator const allocator, uint8_t* dfas, + size_t const len_ref, char const reference[static restrict len_ref], + size_t const len_obs, char const observed[static restrict len_obs], + size_t const offset); + + uint8_t* dfa_from_lcs_graph(GVA_Allocator const allocator, uint8_t* dfas, GVA_LCS_Graph const graph); diff --git a/src/main.c b/src/main.c index 745b74d..c20c8a2 100644 --- a/src/main.c +++ b/src/main.c @@ -493,10 +493,16 @@ supremal_main(int argc, char* argv[static argc]) continue; } // if GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &variant); - //size_t const start = array_length(dfas); + size_t const start = array_length(dfas); dfas = dfa_from_lcs_graph(gva_std_allocator, dfas, graph); - //dfa_dot(reference.len, reference.str, gva_lcs_graph_supremal(graph), dfas + start); + dfa_dot(reference.len, reference.str, gva_lcs_graph_supremal(graph), dfas + start); gva_lcs_graph_destroy(gva_std_allocator, graph, true); + + uint8_t* dir = dfa_from_alignment(gva_std_allocator, NULL, variant.end - variant.start, reference.str + variant.start, variant.sequence.len, variant.sequence.str, variant.start); + + dfa_dot(reference.len, reference.str, variant, dir); + + dir = ARRAY_DESTROY(gva_std_allocator, dir); } // while fprintf(stderr, "#variants: %zu\n", line_count); @@ -850,7 +856,7 @@ main(int argc, char* argv[static argc]) { // return allele_main(argc, argv); // return index_main(argc, argv); - // return supremal_main(argc, argv); - return overlap_main(argc, argv); + return supremal_main(argc, argv); + // return overlap_main(argc, argv); // return all_main(argc, argv); } // main From 41afd12a3b37407a1b70c51801ae49d9938445a1 Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 27 Apr 2026 13:07:10 +0200 Subject: [PATCH 617/704] FIX unguarded source edges --- src/dfa.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/dfa.c b/src/dfa.c index 44d132c..88fabb8 100644 --- a/src/dfa.c +++ b/src/dfa.c @@ -99,7 +99,6 @@ dfa_from_alignment(GVA_Allocator const allocator, uint8_t* dfas, sink = (LCS_Node) {.match = {len_ref + offset, len_obs}}; tail_idx = GVA_NULL; } // else - for (gva_uint i = lcs.index[lcs.length - 1].head; i != tail_idx; i = lcs.nodes[i].next) { edge(dfas + start, width, @@ -178,12 +177,9 @@ dfa_from_alignment(GVA_Allocator const allocator, uint8_t* dfas, continue; } // if - if (source.match.length == 0) - { - edge(dfas + start, width, - source.match.row - offset, lcs.nodes[i].match.row - offset, - lcs.nodes[i].match.col - source.match.col, 0); - } // if + edge(dfas + start, width, + source.match.row - offset, lcs.nodes[i].match.row - offset, + lcs.nodes[i].match.col - source.match.col, 0); } // for lcs.index = allocator.allocate(allocator.context, lcs.index, lcs.length * sizeof(*lcs.index), 0); From 43c36049195ebd4f2671b2c4687b7a0be5f62a64 Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 27 Apr 2026 22:19:11 +0200 Subject: [PATCH 618/704] All DFAs for dbsnp --- src/dfa.c | 6 +++--- src/main.c | 22 ++++++++-------------- src/trie.c | 2 +- 3 files changed, 12 insertions(+), 18 deletions(-) diff --git a/src/dfa.c b/src/dfa.c index 88fabb8..7165eab 100644 --- a/src/dfa.c +++ b/src/dfa.c @@ -240,9 +240,9 @@ typedef struct typedef struct { Queue_Entry* entries; - size_t size; - gva_uint head; - gva_uint tail; + size_t size; + gva_uint head; + gva_uint tail; } Queue; diff --git a/src/main.c b/src/main.c index c20c8a2..7fac75e 100644 --- a/src/main.c +++ b/src/main.c @@ -477,7 +477,7 @@ supremal_main(int argc, char* argv[static argc]) fprintf(stderr, "reference length: %zu\n", reference.len); - uint8_t* dfas = NULL; + Trie dfas = trie_init(gva_std_allocator); size_t line_count = 0; static char line[LINE_SIZE] = {0}; @@ -492,23 +492,17 @@ supremal_main(int argc, char* argv[static argc]) fprintf(stderr, "parsing failed at line %zu: %s", line_count, line); continue; } // if - GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &variant); - size_t const start = array_length(dfas); - dfas = dfa_from_lcs_graph(gva_std_allocator, dfas, graph); - dfa_dot(reference.len, reference.str, gva_lcs_graph_supremal(graph), dfas + start); - gva_lcs_graph_destroy(gva_std_allocator, graph, true); - - uint8_t* dir = dfa_from_alignment(gva_std_allocator, NULL, variant.end - variant.start, reference.str + variant.start, variant.sequence.len, variant.sequence.str, variant.start); - dfa_dot(reference.len, reference.str, variant, dir); - - dir = ARRAY_DESTROY(gva_std_allocator, dir); + uint8_t* dfa = dfa_from_alignment(gva_std_allocator, NULL, variant.end - variant.start, reference.str + variant.start, variant.sequence.len, variant.sequence.str, variant.start); + trie_insert(&dfas, array_length(dfa), (char*) dfa); + dfa = ARRAY_DESTROY(gva_std_allocator, dfa); } // while - fprintf(stderr, "#variants: %zu\n", line_count); - fprintf(stderr, "%zu bytes\n", array_length(dfas)); + fprintf(stderr, "string len: %zu\n", array_length(dfas.strings)); + fprintf(stderr, "#nodes: %zu\n", array_length(dfas.nodes)); + + trie_destroy(&dfas); - dfas = ARRAY_DESTROY(gva_std_allocator, dfas); gva_string_destroy(gva_std_allocator, reference); return EXIT_SUCCESS; diff --git a/src/trie.c b/src/trie.c index 9039b06..9160efb 100644 --- a/src/trie.c +++ b/src/trie.c @@ -37,7 +37,7 @@ concat(Trie self[static restrict 1], self->strings = array_ensure(self->allocator, self->strings, sizeof(*self->strings), len); if (self->strings == NULL) { - return start; + return start; // OOM } // if memcpy(self->strings + start, key, len); array_header(self->strings)->length += len; From 8d3939349296dcb9e22c67dca14c6bbd605b6964 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 28 Apr 2026 11:38:10 +0200 Subject: [PATCH 619/704] Clean up --- src/dfa.c | 67 +++++++++++++++++++++++------------------------------- src/dfa.h | 3 +-- src/main.c | 29 ++++++++--------------- 3 files changed, 40 insertions(+), 59 deletions(-) diff --git a/src/dfa.c b/src/dfa.c index 7165eab..598fa76 100644 --- a/src/dfa.c +++ b/src/dfa.c @@ -53,10 +53,9 @@ edge(uint8_t dfa[static 1], size_t const width, uint8_t* dfa_from_alignment(GVA_Allocator const allocator, uint8_t* dfas, size_t const len_ref, char const reference[static restrict len_ref], - size_t const len_obs, char const observed[static restrict len_obs], - size_t const offset) + size_t const len_obs, char const observed[static restrict len_obs]) { - LCS_Alignment lcs = lcs_align(allocator, len_ref, reference, len_obs, observed, offset); + LCS_Alignment lcs = lcs_align(allocator, len_ref, reference, len_obs, observed, 0); size_t const distance = len_ref + len_obs - 2 * lcs.length; if (distance == 0) @@ -88,7 +87,7 @@ dfa_from_alignment(GVA_Allocator const allocator, uint8_t* dfas, gva_uint tail_idx = lcs.index[lcs.length - 1].tail; LCS_Node sink = lcs.nodes[tail_idx]; - if (sink.match.row + sink.match.length == len_ref + offset && + if (sink.match.row + sink.match.length == len_ref && sink.match.col + sink.match.length == len_obs) { lcs.nodes[tail_idx].moved = true; @@ -96,14 +95,13 @@ dfa_from_alignment(GVA_Allocator const allocator, uint8_t* dfas, } // if else { - sink = (LCS_Node) {.match = {len_ref + offset, len_obs}}; + sink = (LCS_Node) {.match = {len_ref, len_obs}}; tail_idx = GVA_NULL; } // else for (gva_uint i = lcs.index[lcs.length - 1].head; i != tail_idx; i = lcs.nodes[i].next) { edge(dfas + start, width, - lcs.nodes[i].match.row + lcs.nodes[i].match.length - offset, - sink.match.row + sink.match.length - offset, + lcs.nodes[i].match.row + lcs.nodes[i].match.length, sink.match.row + sink.match.length, sink.match.col + sink.match.length - (lcs.nodes[i].match.col + lcs.nodes[i].match.length), lcs.nodes[i].match.col + lcs.nodes[i].match.length); lcs.nodes[i].moved = true; @@ -134,8 +132,7 @@ dfa_from_alignment(GVA_Allocator const allocator, uint8_t* dfas, } // if edge(dfas + start, width, - head->match.row + head->match.length - offset, - tail->match.row + tail->match.length - offset - 1, + head->match.row + head->match.length, tail->match.row + tail->match.length - 1, tail->match.col + tail->match.length - (head->match.col + head->match.length) - 1, head->match.col + head->match.length); head->moved = true; @@ -162,13 +159,13 @@ dfa_from_alignment(GVA_Allocator const allocator, uint8_t* dfas, gva_uint head_idx = lcs.index[0].head; LCS_Node source = lcs.nodes[head_idx]; - if (source.match.row == offset && source.match.col == 0) + if (source.match.row == 0 && source.match.col == 0) { head_idx = source.next; } // if else { - source = (LCS_Node) {.match.row = offset}; + source = (LCS_Node) {0}; } // else for (gva_uint i = head_idx; i != GVA_NULL; i = lcs.nodes[i].next) { @@ -177,8 +174,7 @@ dfa_from_alignment(GVA_Allocator const allocator, uint8_t* dfas, continue; } // if - edge(dfas + start, width, - source.match.row - offset, lcs.nodes[i].match.row - offset, + edge(dfas + start, width, source.match.row, lcs.nodes[i].match.row, lcs.nodes[i].match.col - source.match.col, 0); } // for @@ -357,27 +353,21 @@ dfa_max_overlap(GVA_Allocator const allocator, } // if queue_push_front(&queue, 0, 0); - - size_t count = 0; while (!queue_empty(&queue)) { - count += 1; - size_t const idx = queue_pop(&queue); - size_t const lhs_idx = idx / rhs_size; - size_t const rhs_idx = idx % rhs_size; - - fprintf(stderr, "{%zu, %zu} (%zu): %u\n", lhs_idx, rhs_idx, idx, queue.entries[idx].included); - - if (lhs_idx == lhs_size - 1 && rhs_idx == rhs_size - 1) + if (idx == lhs_size * rhs_size - 1) { - fprintf(stdout, "%u %zu\n", queue.entries[idx].included, count); break; } // if + size_t const lhs_idx = idx / rhs_size; + size_t const rhs_idx = idx % rhs_size; size_t const lhs_ref = lhs_idx / lhs_width + lhs_supremal.start; size_t const rhs_ref = rhs_idx / rhs_width + rhs_supremal.start; + // fprintf(stderr, "{%zu, %zu} (%zu): %u\n", lhs_idx, rhs_idx, idx, queue.entries[idx].included); + if ((lhs_idx == 0 && rhs_ref < lhs_ref) || lhs_idx == lhs_size - 1) { uint8_t const rhs_value = get(rhs_dfa, rhs_idx); @@ -389,21 +379,21 @@ dfa_max_overlap(GVA_Allocator const allocator, if (rhs_match) { // .. - fprintf(stderr, " push (. vs %zu MU) +0 +0 {%zu, %zu} (%zu)\n", rhs_ref, lhs_idx, rhs_idx + rhs_width + 1, lhs_idx * rhs_size + rhs_idx + rhs_width + 1); + // fprintf(stderr, " push (. vs %zu MU) +0 +0 {%zu, %zu} (%zu)\n", rhs_ref, lhs_idx, rhs_idx + rhs_width + 1, lhs_idx * rhs_size + rhs_idx + rhs_width + 1); queue_push_front(&queue, lhs_idx * rhs_size + rhs_idx + rhs_width + 1, queue.entries[idx].included); } // if if (rhs_deletion) { // .D - fprintf(stderr, " push (. vs %zu DELTA) +0 +1 {%zu, %zu} (%zu)\n", rhs_ref, lhs_idx, rhs_idx + rhs_width, lhs_idx * rhs_size + rhs_idx + rhs_width); + // fprintf(stderr, " push (. vs %zu DELTA) +0 +1 {%zu, %zu} (%zu)\n", rhs_ref, lhs_idx, rhs_idx + rhs_width, lhs_idx * rhs_size + rhs_idx + rhs_width); queue_push_back(&queue, lhs_idx * rhs_size + rhs_idx + rhs_width, queue.entries[idx].included); } // if if (rhs_insertion) { // .I - fprintf(stderr, " push (. vs %zu %c) +0 +1 {%zu, %zu} (%zu)\n", rhs_ref, rhs_supremal.sequence.str[rhs_idx % rhs_width], lhs_idx, rhs_idx + 1, lhs_idx * rhs_size + rhs_idx + 1); + // fprintf(stderr, " push (. vs %zu %c) +0 +1 {%zu, %zu} (%zu)\n", rhs_ref, rhs_supremal.sequence.str[rhs_idx % rhs_width], lhs_idx, rhs_idx + 1, lhs_idx * rhs_size + rhs_idx + 1); queue_push_back(&queue, lhs_idx * rhs_size + rhs_idx + 1, queue.entries[idx].included); } // if } // if @@ -418,21 +408,21 @@ dfa_max_overlap(GVA_Allocator const allocator, if (lhs_match) { // .. - fprintf(stderr, " push (%zu MU vs .) +0 +0 {%zu, %zu} (%zu)\n", lhs_ref, lhs_idx + lhs_width + 1, rhs_idx, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx); + // fprintf(stderr, " push (%zu MU vs .) +0 +0 {%zu, %zu} (%zu)\n", lhs_ref, lhs_idx + lhs_width + 1, rhs_idx, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx); queue_push_front(&queue, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx, queue.entries[idx].included); } // if if (lhs_deletion) { // D. - fprintf(stderr, " push (%zu DELTA vs .) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, lhs_idx + lhs_width, rhs_idx, (lhs_idx + lhs_width) * rhs_size + rhs_idx); + // fprintf(stderr, " push (%zu DELTA vs .) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, lhs_idx + lhs_width, rhs_idx, (lhs_idx + lhs_width) * rhs_size + rhs_idx); queue_push_back(&queue, (lhs_idx + lhs_width) * rhs_size + rhs_idx, queue.entries[idx].included); } // if if (lhs_insertion) { // I. - fprintf(stderr, " push (%zu %c vs .) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, lhs_supremal.sequence.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx, (lhs_idx + 1) * rhs_size + rhs_idx); + // fprintf(stderr, " push (%zu %c vs .) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, lhs_supremal.sequence.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx, (lhs_idx + 1) * rhs_size + rhs_idx); queue_push_back(&queue, (lhs_idx + 1) * rhs_size + rhs_idx, queue.entries[idx].included); } // if } // if @@ -453,35 +443,35 @@ dfa_max_overlap(GVA_Allocator const allocator, if (lhs_match && rhs_match) { // .. - fprintf(stderr, " push (%zu MU) {%zu, %zu} +0 +0 (%zu)\n", lhs_ref, lhs_idx + lhs_width + 1, rhs_idx + rhs_width + 1, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx + rhs_width + 1); + // fprintf(stderr, " push (%zu MU) {%zu, %zu} +0 +0 (%zu)\n", lhs_ref, lhs_idx + lhs_width + 1, rhs_idx + rhs_width + 1, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx + rhs_width + 1); queue_push_front(&queue, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx + rhs_width + 1, queue.entries[idx].included); } // if if (lhs_deletion && rhs_deletion) { // DD - fprintf(stderr, " push (%zu DELTA) {%zu, %zu} +1 +0 (%zu)\n", lhs_ref, lhs_idx + lhs_width, rhs_idx + rhs_width, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width); + // fprintf(stderr, " push (%zu DELTA) {%zu, %zu} +1 +0 (%zu)\n", lhs_ref, lhs_idx + lhs_width, rhs_idx + rhs_width, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width); queue_push_front(&queue, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width, queue.entries[idx].included + 1); } // if if (lhs_insertion && rhs_insertion && lhs_supremal.sequence.str[lhs_idx % lhs_width] == rhs_supremal.sequence.str[rhs_idx % rhs_width]) { // II - fprintf(stderr, " push (%zu %c) {%zu, %zu} +1 +0 (%zu)\n", lhs_ref, lhs_supremal.sequence.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx + 1, (lhs_idx + 1) * rhs_size + rhs_idx + 1); + // fprintf(stderr, " push (%zu %c) {%zu, %zu} +1 +0 (%zu)\n", lhs_ref, lhs_supremal.sequence.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx + 1, (lhs_idx + 1) * rhs_size + rhs_idx + 1); queue_push_front(&queue, (lhs_idx + 1) * rhs_size + rhs_idx + 1, queue.entries[idx].included + 1); } // if if (lhs_deletion && rhs_match) { // D. - fprintf(stderr, " push (%zu DELTA vs %zu MU) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, rhs_ref, lhs_idx + lhs_width, rhs_idx + rhs_width + 1, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width + 1); + // fprintf(stderr, " push (%zu DELTA vs %zu MU) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, rhs_ref, lhs_idx + lhs_width, rhs_idx + rhs_width + 1, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width + 1); queue_push_back(&queue, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width + 1, queue.entries[idx].included); } // if if (lhs_match && rhs_deletion) { // .D - fprintf(stderr, " push (%zu MU vs %zu DELTA) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, rhs_ref, lhs_idx + lhs_width + 1, rhs_idx + rhs_width, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx + rhs_width); + // fprintf(stderr, " push (%zu MU vs %zu DELTA) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, rhs_ref, lhs_idx + lhs_width + 1, rhs_idx + rhs_width, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx + rhs_width); queue_push_back(&queue, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx + rhs_width, queue.entries[idx].included); } // if @@ -489,7 +479,7 @@ dfa_max_overlap(GVA_Allocator const allocator, lhs_supremal.sequence.str[lhs_idx % lhs_width] != rhs_supremal.sequence.str[rhs_idx % rhs_width]))) { // I. - fprintf(stderr, " push (%zu %c vs .) {%zu, %zu} +0 +1 (%zu)\n", lhs_ref, lhs_supremal.sequence.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx, (lhs_idx + 1) * rhs_size + rhs_idx); + // fprintf(stderr, " push (%zu %c vs .) {%zu, %zu} +0 +1 (%zu)\n", lhs_ref, lhs_supremal.sequence.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx, (lhs_idx + 1) * rhs_size + rhs_idx); queue_push_back(&queue, (lhs_idx + 1) * rhs_size + rhs_idx, queue.entries[idx].included); } // if @@ -497,15 +487,16 @@ dfa_max_overlap(GVA_Allocator const allocator, lhs_supremal.sequence.str[lhs_idx % lhs_width] != rhs_supremal.sequence.str[rhs_idx % rhs_width]))) { // .I - fprintf(stderr, " push (. vs %zu %c) {%zu, %zu} +0 +1 (%zu)\n", rhs_ref, rhs_supremal.sequence.str[rhs_idx % rhs_width], lhs_idx, rhs_idx + 1, lhs_idx * rhs_size + rhs_idx + 1); + // fprintf(stderr, " push (. vs %zu %c) {%zu, %zu} +0 +1 (%zu)\n", rhs_ref, rhs_supremal.sequence.str[rhs_idx % rhs_width], lhs_idx, rhs_idx + 1, lhs_idx * rhs_size + rhs_idx + 1); queue_push_back(&queue, lhs_idx * rhs_size + rhs_idx + 1, queue.entries[idx].included); } // if } // else } // while + size_t const included = queue.entries[lhs_size * rhs_size - 1].included; queue_destroy(allocator, &queue); - return 0; + return included; } // dfa_max_overlap diff --git a/src/dfa.h b/src/dfa.h index 67df336..2adaeb3 100644 --- a/src/dfa.h +++ b/src/dfa.h @@ -13,8 +13,7 @@ uint8_t* dfa_from_alignment(GVA_Allocator const allocator, uint8_t* dfas, size_t const len_ref, char const reference[static restrict len_ref], - size_t const len_obs, char const observed[static restrict len_obs], - size_t const offset); + size_t const len_obs, char const observed[static restrict len_obs]); uint8_t* diff --git a/src/main.c b/src/main.c index 7fac75e..d6572a5 100644 --- a/src/main.c +++ b/src/main.c @@ -493,7 +493,7 @@ supremal_main(int argc, char* argv[static argc]) continue; } // if - uint8_t* dfa = dfa_from_alignment(gva_std_allocator, NULL, variant.end - variant.start, reference.str + variant.start, variant.sequence.len, variant.sequence.str, variant.start); + uint8_t* dfa = dfa_from_alignment(gva_std_allocator, NULL, variant.end - variant.start, reference.str + variant.start, variant.sequence.len, variant.sequence.str); trie_insert(&dfas, array_length(dfa), (char*) dfa); dfa = ARRAY_DESTROY(gva_std_allocator, dfa); } // while @@ -545,30 +545,21 @@ overlap_main(int argc, char* argv[static argc]) continue; } // if - GVA_LCS_Graph lhs = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &lhs_variant); - GVA_LCS_Graph rhs = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &rhs_variant); + uint8_t* lhs_dfa = dfa_from_alignment(gva_std_allocator, NULL, lhs_variant.end - lhs_variant.start, reference.str + lhs_variant.start, lhs_variant.sequence.len, lhs_variant.sequence.str); + uint8_t* rhs_dfa = dfa_from_alignment(gva_std_allocator, NULL, rhs_variant.end - rhs_variant.start, reference.str + rhs_variant.start, rhs_variant.sequence.len, rhs_variant.sequence.str); - uint8_t* lhs_dfa = dfa_from_lcs_graph(gva_std_allocator, NULL, lhs); - uint8_t* rhs_dfa = dfa_from_lcs_graph(gva_std_allocator, NULL, rhs); - - GVA_Variant const lhs_supremal = gva_lcs_graph_supremal(lhs); - GVA_Variant const rhs_supremal = gva_lcs_graph_supremal(rhs); - - //dfa_dot(reference.len, reference.str, lhs_supremal, lhs_dfa); - //dfa_dot(reference.len, reference.str, rhs_supremal, rhs_dfa); + //dfa_dot(reference.len, reference.str, lhs_variant, lhs_dfa); + //dfa_dot(reference.len, reference.str, rhs_variant, rhs_dfa); size_t const overlap = dfa_max_overlap(gva_std_allocator, reference.len, reference.str, - lhs_supremal, lhs_dfa, - rhs_supremal, rhs_dfa); + lhs_variant, lhs_dfa, + rhs_variant, rhs_dfa); - fprintf(stderr, "OVERLAP: %zu\n", overlap); + fprintf(stdout, "%zu\n", overlap); rhs_dfa = ARRAY_DESTROY(gva_std_allocator, rhs_dfa); lhs_dfa = ARRAY_DESTROY(gva_std_allocator, lhs_dfa); - - gva_lcs_graph_destroy(gva_std_allocator, rhs, true); - gva_lcs_graph_destroy(gva_std_allocator, lhs, true); } // while return EXIT_SUCCESS; @@ -850,7 +841,7 @@ main(int argc, char* argv[static argc]) { // return allele_main(argc, argv); // return index_main(argc, argv); - return supremal_main(argc, argv); - // return overlap_main(argc, argv); + // return supremal_main(argc, argv); + return overlap_main(argc, argv); // return all_main(argc, argv); } // main From d961d20c2d773683084f14aa663116ce55c469ba Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 28 Apr 2026 14:46:42 +0200 Subject: [PATCH 620/704] WIP: hash table backed queue: fails on dbsnp --- src/dfa.c | 107 ++++++++++++++++++++++++++++------------------------- src/main.c | 22 ++++++++++- 2 files changed, 78 insertions(+), 51 deletions(-) diff --git a/src/dfa.c b/src/dfa.c index 598fa76..3203ab8 100644 --- a/src/dfa.c +++ b/src/dfa.c @@ -1,4 +1,3 @@ -#include // CHAR_BIT #include // bool #include // NULL, size_t #include // uint8_t @@ -11,6 +10,7 @@ #include "align.h" // LCS_Alignment, lcs_align #include "array.h" // ARRAY_*, array_* #include "dfa.h" // dfa* +#include "hash_table.h" // HASH_TABLE_*, hash_table_* #include // DEBUG @@ -227,41 +227,38 @@ dfa_from_lcs_graph(GVA_Allocator const allocator, uint8_t* dfas, typedef struct { - gva_uint seen : 1; - gva_uint included : sizeof(gva_uint) * CHAR_BIT - 1; + HASH_TABLE_KEY; + gva_uint included; gva_uint next; -} Queue_Entry; +} Entry; typedef struct { - Queue_Entry* entries; - size_t size; - gva_uint head; - gva_uint tail; + Entry* entries; + GVA_Allocator allocator; + gva_uint head; + gva_uint tail; } Queue; static inline Queue -queue_init(GVA_Allocator const allocator, size_t const size) +queue_init(GVA_Allocator const allocator, size_t const capacity) { - Queue queue = + return (Queue) { - .entries = allocator.allocate(allocator.context, NULL, 0, sizeof(*queue.entries) * size), - .size = size, + .entries = hash_table_init(allocator, capacity, sizeof(Entry)), + .allocator = allocator, .head = GVA_NULL, .tail = GVA_NULL, }; - - memset(queue.entries, 0, sizeof(*queue.entries) * size); - return queue; } // queue_init static inline void -queue_destroy(GVA_Allocator const allocator, Queue self[static 1]) +queue_destroy(Queue self[static 1]) { - self->entries = allocator.allocate(allocator.context, self->entries, sizeof(*self->entries) * self->size, 0); + self->entries = HASH_TABLE_DESTROY(self->allocator, self->entries); self->head = GVA_NULL; self->tail = GVA_NULL; } // queue_destroy @@ -277,8 +274,9 @@ queue_empty(Queue const self[static 1]) static inline gva_uint queue_pop(Queue self[static 1]) { - gva_uint const idx = self->head; - self->head = self->entries[idx].next; + size_t const hash_idx = HASH_TABLE_INDEX(self->entries, self->head); + gva_uint const idx = self->entries[hash_idx].gva_key; + self->head = self->entries[hash_idx].next; if (self->head == GVA_NULL) { self->tail = GVA_NULL; @@ -290,24 +288,27 @@ queue_pop(Queue self[static 1]) static inline void queue_push_back(Queue self[static 1], gva_uint const idx, gva_uint const included) { - if (self->entries[idx].seen) + size_t const hash_idx = HASH_TABLE_INDEX(self->entries, idx); + if (self->entries[hash_idx].gva_key == idx) { return; } // if - self->entries[idx] = (Queue_Entry) - { - .seen = true, - .included = included, - .next = GVA_NULL, - }; + HASH_TABLE_SET(self->allocator, self->entries, idx, + ((Entry) + { + .gva_key = idx, + .included = included, + .next = GVA_NULL, + })); + if (self->tail == GVA_NULL) { self->head = idx; } // if else { - self->entries[self->tail].next = idx; + self->entries[HASH_TABLE_INDEX(self->entries, self->tail)].next = idx; } // else self->tail = idx; } // queue_push_back @@ -316,17 +317,20 @@ queue_push_back(Queue self[static 1], gva_uint const idx, gva_uint const include static inline void queue_push_front(Queue self[static 1], gva_uint const idx, gva_uint const included) { - if (self->entries[idx].seen) + size_t const hash_idx = HASH_TABLE_INDEX(self->entries, idx); + if (self->entries[hash_idx].gva_key == idx) { return; } // if - self->entries[idx] = (Queue_Entry) - { - .seen = true, - .included = included, - .next = self->head, - }; + HASH_TABLE_SET(self->allocator, self->entries, idx, + ((Entry) + { + .gva_key = idx, + .included = included, + .next = self->head, + })); + if (self->head == GVA_NULL) { self->tail = idx; @@ -341,12 +345,14 @@ dfa_max_overlap(GVA_Allocator const allocator, GVA_Variant const lhs_supremal, uint8_t const lhs_dfa[static restrict 1], GVA_Variant const rhs_supremal, uint8_t const rhs_dfa[static restrict 1]) { + static size_t const INITIAL_SIZE = 40; + size_t const lhs_width = lhs_supremal.sequence.len + 1; size_t const rhs_width = rhs_supremal.sequence.len + 1; size_t const lhs_size = (lhs_supremal.end - lhs_supremal.start + 1) * lhs_width; size_t const rhs_size = (rhs_supremal.end - rhs_supremal.start + 1) * rhs_width; - Queue queue = queue_init(allocator, lhs_size * rhs_size); + Queue queue = queue_init(allocator, INITIAL_SIZE); if (queue.entries == NULL) { return 0; // OOM @@ -365,6 +371,7 @@ dfa_max_overlap(GVA_Allocator const allocator, size_t const rhs_idx = idx % rhs_size; size_t const lhs_ref = lhs_idx / lhs_width + lhs_supremal.start; size_t const rhs_ref = rhs_idx / rhs_width + rhs_supremal.start; + size_t const included = queue.entries[HASH_TABLE_INDEX(queue.entries, idx)].included; // fprintf(stderr, "{%zu, %zu} (%zu): %u\n", lhs_idx, rhs_idx, idx, queue.entries[idx].included); @@ -380,21 +387,21 @@ dfa_max_overlap(GVA_Allocator const allocator, { // .. // fprintf(stderr, " push (. vs %zu MU) +0 +0 {%zu, %zu} (%zu)\n", rhs_ref, lhs_idx, rhs_idx + rhs_width + 1, lhs_idx * rhs_size + rhs_idx + rhs_width + 1); - queue_push_front(&queue, lhs_idx * rhs_size + rhs_idx + rhs_width + 1, queue.entries[idx].included); + queue_push_front(&queue, lhs_idx * rhs_size + rhs_idx + rhs_width + 1, included); } // if if (rhs_deletion) { // .D // fprintf(stderr, " push (. vs %zu DELTA) +0 +1 {%zu, %zu} (%zu)\n", rhs_ref, lhs_idx, rhs_idx + rhs_width, lhs_idx * rhs_size + rhs_idx + rhs_width); - queue_push_back(&queue, lhs_idx * rhs_size + rhs_idx + rhs_width, queue.entries[idx].included); + queue_push_back(&queue, lhs_idx * rhs_size + rhs_idx + rhs_width, included); } // if if (rhs_insertion) { // .I // fprintf(stderr, " push (. vs %zu %c) +0 +1 {%zu, %zu} (%zu)\n", rhs_ref, rhs_supremal.sequence.str[rhs_idx % rhs_width], lhs_idx, rhs_idx + 1, lhs_idx * rhs_size + rhs_idx + 1); - queue_push_back(&queue, lhs_idx * rhs_size + rhs_idx + 1, queue.entries[idx].included); + queue_push_back(&queue, lhs_idx * rhs_size + rhs_idx + 1, included); } // if } // if else if ((rhs_idx == 0 && lhs_ref < rhs_ref) || rhs_idx == rhs_size - 1) @@ -409,21 +416,21 @@ dfa_max_overlap(GVA_Allocator const allocator, { // .. // fprintf(stderr, " push (%zu MU vs .) +0 +0 {%zu, %zu} (%zu)\n", lhs_ref, lhs_idx + lhs_width + 1, rhs_idx, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx); - queue_push_front(&queue, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx, queue.entries[idx].included); + queue_push_front(&queue, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx, included); } // if if (lhs_deletion) { // D. // fprintf(stderr, " push (%zu DELTA vs .) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, lhs_idx + lhs_width, rhs_idx, (lhs_idx + lhs_width) * rhs_size + rhs_idx); - queue_push_back(&queue, (lhs_idx + lhs_width) * rhs_size + rhs_idx, queue.entries[idx].included); + queue_push_back(&queue, (lhs_idx + lhs_width) * rhs_size + rhs_idx, included); } // if if (lhs_insertion) { // I. // fprintf(stderr, " push (%zu %c vs .) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, lhs_supremal.sequence.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx, (lhs_idx + 1) * rhs_size + rhs_idx); - queue_push_back(&queue, (lhs_idx + 1) * rhs_size + rhs_idx, queue.entries[idx].included); + queue_push_back(&queue, (lhs_idx + 1) * rhs_size + rhs_idx, included); } // if } // if else @@ -444,35 +451,35 @@ dfa_max_overlap(GVA_Allocator const allocator, { // .. // fprintf(stderr, " push (%zu MU) {%zu, %zu} +0 +0 (%zu)\n", lhs_ref, lhs_idx + lhs_width + 1, rhs_idx + rhs_width + 1, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx + rhs_width + 1); - queue_push_front(&queue, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx + rhs_width + 1, queue.entries[idx].included); + queue_push_front(&queue, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx + rhs_width + 1, included); } // if if (lhs_deletion && rhs_deletion) { // DD // fprintf(stderr, " push (%zu DELTA) {%zu, %zu} +1 +0 (%zu)\n", lhs_ref, lhs_idx + lhs_width, rhs_idx + rhs_width, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width); - queue_push_front(&queue, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width, queue.entries[idx].included + 1); + queue_push_front(&queue, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width, included + 1); } // if if (lhs_insertion && rhs_insertion && lhs_supremal.sequence.str[lhs_idx % lhs_width] == rhs_supremal.sequence.str[rhs_idx % rhs_width]) { // II // fprintf(stderr, " push (%zu %c) {%zu, %zu} +1 +0 (%zu)\n", lhs_ref, lhs_supremal.sequence.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx + 1, (lhs_idx + 1) * rhs_size + rhs_idx + 1); - queue_push_front(&queue, (lhs_idx + 1) * rhs_size + rhs_idx + 1, queue.entries[idx].included + 1); + queue_push_front(&queue, (lhs_idx + 1) * rhs_size + rhs_idx + 1, included + 1); } // if if (lhs_deletion && rhs_match) { // D. // fprintf(stderr, " push (%zu DELTA vs %zu MU) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, rhs_ref, lhs_idx + lhs_width, rhs_idx + rhs_width + 1, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width + 1); - queue_push_back(&queue, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width + 1, queue.entries[idx].included); + queue_push_back(&queue, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width + 1, included); } // if if (lhs_match && rhs_deletion) { // .D // fprintf(stderr, " push (%zu MU vs %zu DELTA) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, rhs_ref, lhs_idx + lhs_width + 1, rhs_idx + rhs_width, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx + rhs_width); - queue_push_back(&queue, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx + rhs_width, queue.entries[idx].included); + queue_push_back(&queue, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx + rhs_width, included); } // if if (lhs_insertion && (rhs_deletion || rhs_match || (rhs_insertion && @@ -480,7 +487,7 @@ dfa_max_overlap(GVA_Allocator const allocator, { // I. // fprintf(stderr, " push (%zu %c vs .) {%zu, %zu} +0 +1 (%zu)\n", lhs_ref, lhs_supremal.sequence.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx, (lhs_idx + 1) * rhs_size + rhs_idx); - queue_push_back(&queue, (lhs_idx + 1) * rhs_size + rhs_idx, queue.entries[idx].included); + queue_push_back(&queue, (lhs_idx + 1) * rhs_size + rhs_idx, included); } // if if (rhs_insertion && (lhs_deletion || lhs_match || (lhs_insertion && @@ -488,13 +495,13 @@ dfa_max_overlap(GVA_Allocator const allocator, { // .I // fprintf(stderr, " push (. vs %zu %c) {%zu, %zu} +0 +1 (%zu)\n", rhs_ref, rhs_supremal.sequence.str[rhs_idx % rhs_width], lhs_idx, rhs_idx + 1, lhs_idx * rhs_size + rhs_idx + 1); - queue_push_back(&queue, lhs_idx * rhs_size + rhs_idx + 1, queue.entries[idx].included); + queue_push_back(&queue, lhs_idx * rhs_size + rhs_idx + 1, included); } // if } // else } // while - size_t const included = queue.entries[lhs_size * rhs_size - 1].included; + size_t const included = queue.entries[HASH_TABLE_INDEX(queue.entries, lhs_size * rhs_size - 1)].included; - queue_destroy(allocator, &queue); + queue_destroy(&queue); return included; } // dfa_max_overlap diff --git a/src/main.c b/src/main.c index d6572a5..ab189bb 100644 --- a/src/main.c +++ b/src/main.c @@ -688,6 +688,8 @@ all_main(int argc, char* argv[static argc]) size_t* lhs_gs = NULL; size_t* lhs_ts = NULL; + uint8_t* lhs_dfa = NULL; + for (size_t j = i + 1; j < array_length(entries); ++j) { if (entries[i].end < entries[j].start) @@ -776,7 +778,13 @@ all_main(int argc, char* argv[static argc]) gva_lcs_graph_uniq_atomics(lhs_graph, lhs.start, lhs.start, lhs.end, lhs_dels, lhs_as, lhs_cs, lhs_gs, lhs_ts); } // if + if (lhs_dfa == NULL) + { + lhs_dfa = dfa_from_alignment(gva_std_allocator, NULL, lhs.end - lhs.start, reference.str + lhs.start, lhs.sequence.len, lhs.sequence.str); + } // if + GVA_LCS_Graph rhs_graph = gva_lcs_graph_init(gva_std_allocator, rhs.end - rhs.start, reference.str + rhs.start, rhs.sequence.len, rhs.sequence.str, rhs.start); + uint8_t* rhs_dfa = dfa_from_alignment(gva_std_allocator, NULL, rhs.end - rhs.start, reference.str + rhs.start, rhs.sequence.len, rhs.sequence.str); size_t const len = end - start + 1; size_t* rhs_dels = bitset_init(gva_std_allocator, len); @@ -787,6 +795,10 @@ all_main(int argc, char* argv[static argc]) gva_lcs_graph_uniq_atomics(rhs_graph, lhs.start, rhs.start, rhs.end, rhs_dels, rhs_as, rhs_cs, rhs_gs, rhs_ts); + fprintf(stderr, GVA_VARIANT_FMT " vs " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(lhs), GVA_VARIANT_PRINT(rhs)); + fprintf(stderr, "%zu x %zu\n", array_length(lhs_dfa), array_length(rhs_dfa)); + size_t const dfa_overlap = dfa_max_overlap(gva_std_allocator, reference.len, reference.str, lhs, lhs_dfa, rhs, rhs_dfa); + bool const overlap = bitset_intersection_cnt(lhs_dels, rhs_dels) > 0 || bitset_intersection_cnt(lhs_as, rhs_as) > 0 || bitset_intersection_cnt(lhs_cs, rhs_cs) > 0 || @@ -800,6 +812,13 @@ all_main(int argc, char* argv[static argc]) rhs_dels = bitset_destroy(gva_std_allocator, rhs_dels); gva_lcs_graph_destroy(gva_std_allocator, rhs_graph, false); + rhs_dfa = ARRAY_DESTROY(gva_std_allocator, rhs_dfa); + + if (overlap != (dfa_overlap > 0)) + { + fprintf(stderr, "ERROR: %zu\n", dfa_overlap); + return EXIT_FAILURE; + } // if if (overlap) { @@ -821,6 +840,7 @@ all_main(int argc, char* argv[static argc]) lhs_as = bitset_destroy(gva_std_allocator, lhs_as); lhs_dels = bitset_destroy(gva_std_allocator, lhs_dels); gva_lcs_graph_destroy(gva_std_allocator, lhs_graph, false); + lhs_dfa = ARRAY_DESTROY(gva_std_allocator, lhs_dfa); } // for fprintf(stderr, "#combos: %zu\n", count); @@ -843,5 +863,5 @@ main(int argc, char* argv[static argc]) // return index_main(argc, argv); // return supremal_main(argc, argv); return overlap_main(argc, argv); - // return all_main(argc, argv); + //return all_main(argc, argv); } // main From 183c676f95343e01b2d538aef3be240c5936a3b0 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 28 Apr 2026 16:14:54 +0200 Subject: [PATCH 621/704] WIP: debugging --- src/dfa.c | 99 +++++++++++++++++++++++++++++++++++------------------- src/dfa.h | 6 +++- src/main.c | 37 +++++++++++++++++--- 3 files changed, 102 insertions(+), 40 deletions(-) diff --git a/src/dfa.c b/src/dfa.c index 3203ab8..60c6c30 100644 --- a/src/dfa.c +++ b/src/dfa.c @@ -1,4 +1,4 @@ -#include // bool +#include // bool, true #include // NULL, size_t #include // uint8_t #include // memset @@ -345,7 +345,7 @@ dfa_max_overlap(GVA_Allocator const allocator, GVA_Variant const lhs_supremal, uint8_t const lhs_dfa[static restrict 1], GVA_Variant const rhs_supremal, uint8_t const rhs_dfa[static restrict 1]) { - static size_t const INITIAL_SIZE = 40; + static size_t const INITIAL_SIZE = 2048; size_t const lhs_width = lhs_supremal.sequence.len + 1; size_t const rhs_width = rhs_supremal.sequence.len + 1; @@ -364,6 +364,7 @@ dfa_max_overlap(GVA_Allocator const allocator, size_t const idx = queue_pop(&queue); if (idx == lhs_size * rhs_size - 1) { + fprintf(stderr, "BREAK\n"); break; } // if @@ -373,7 +374,7 @@ dfa_max_overlap(GVA_Allocator const allocator, size_t const rhs_ref = rhs_idx / rhs_width + rhs_supremal.start; size_t const included = queue.entries[HASH_TABLE_INDEX(queue.entries, idx)].included; - // fprintf(stderr, "{%zu, %zu} (%zu): %u\n", lhs_idx, rhs_idx, idx, queue.entries[idx].included); + fprintf(stderr, "{%zu, %zu} (%zu): %zu\n", lhs_idx, rhs_idx, idx, included); if ((lhs_idx == 0 && rhs_ref < lhs_ref) || lhs_idx == lhs_size - 1) { @@ -507,46 +508,74 @@ dfa_max_overlap(GVA_Allocator const allocator, } // dfa_max_overlap -// FIXME: DEBUG only; very inefficient -static void -dfa_dot_traverse(size_t const len, char const reference[static restrict len], - GVA_Variant const supremal, uint8_t const dfa[static restrict 1], size_t const idx) +// FIXME: DEBUG +void +dfa_dot(GVA_Allocator const allocator, FILE* const stream, + size_t const len, char const reference[static restrict len], + GVA_Variant const supremal, uint8_t const dfa[static restrict 1]) { size_t const width = supremal.sequence.len + 1; size_t const size = (supremal.end - supremal.start + 1) * width; - if (idx == size - 1) - { - return; - } // if - - uint8_t const value = get(dfa, idx); - if (value & DFA_DELETION) - { - fprintf(stderr, "%zu->%zu[label=\"%zu Δ\"]\n", idx, idx + width, supremal.start + idx / width); - dfa_dot_traverse(len, reference, supremal, dfa, idx + width); - } // if - if (value & DFA_INSERTION) + struct { - fprintf(stderr, "%zu->%zu[label=\"%zu %c\"]\n", idx, idx + 1, supremal.start + idx / width, supremal.sequence.str[idx % width]); - dfa_dot_traverse(len, reference, supremal, dfa, idx + 1); - } // if - if (reference[supremal.start + idx / width] == supremal.sequence.str[idx % width]) + char seen; + gva_uint next; + }* queue = allocator.allocate(allocator.context, NULL, 0, sizeof(*queue) * size); + if (queue == NULL) { - fprintf(stderr, "%zu->%zu[label=\"%zu Μ\"]\n", idx, idx + width + 1, supremal.start + idx / width); - dfa_dot_traverse(len, reference, supremal, dfa, idx + width + 1); + return; // OOM } // if -} // dfa_dot_traverse + memset(queue, 0, sizeof(*queue) * size); -void -dfa_dot(size_t const len, char const reference[static restrict len], - GVA_Variant const supremal, uint8_t const dfa[static restrict 1]) -{ - size_t const width = supremal.sequence.len + 1; - size_t const size = (supremal.end - supremal.start + 1) * width; + fprintf(stream, "strict digraph{\nrankdir=LR\nnode[fixedsize=true,shape=circle,width=1]\ni[label=\"\",shape=none,width=0]\ni->0\n"); + + gva_uint head = 0; + gva_uint tail = head; + queue[head].seen = true; + queue[head].next = GVA_NULL; + while (head != GVA_NULL) + { + uint8_t const value = get(dfa, head); + if (value & DFA_DELETION) + { + fprintf(stream, "%u->%zu[label=\"%zu Δ\"]\n", head, head + width, supremal.start + head / width); + if (!queue[head + width].seen) + { + queue[head + width].seen = true; + queue[head + width].next = GVA_NULL; + queue[tail].next = head + width; + tail = head + width; + } // if + } // if + if (value & DFA_INSERTION) + { + fprintf(stream, "%u->%u[label=\"%zu %c\"]\n", head, head + 1, supremal.start + head / width, supremal.sequence.str[head % width]); + if (!queue[head + 1].seen) + { + queue[head + 1].seen = true; + queue[head + 1].next = GVA_NULL; + queue[tail].next = head + 1; + tail = head + 1; + } // if + } // if + if (head % width < width - 1 && + reference[supremal.start + head / width] == supremal.sequence.str[head % width]) + { + fprintf(stream, "%u->%zu[label=\"%zu Μ\"]\n", head, head + width + 1, supremal.start + head / width); + if (!queue[head + width + 1].seen) + { + queue[head + width + 1].seen = true; + queue[head + width + 1].next = GVA_NULL; + queue[tail].next = head + width + 1; + tail = head + width + 1; + } // if + } // if + head = queue[head].next; + } // while + + queue = allocator.allocate(allocator.context, queue, sizeof(*queue) * size, 0); - fprintf(stderr, "strict digraph{\nrankdir=LR\nnode[fixedsize=true,shape=circle,width=1]\ni[label=\"\",shape=none,width=0]\ni->0\n"); - dfa_dot_traverse(len, reference, supremal, dfa, 0); - fprintf(stderr, "%zu[peripheries=2]\n}\n", size - 1); + fprintf(stream, "%zu[peripheries=2]\n}\n", size - 1); } // dfa_dot diff --git a/src/dfa.h b/src/dfa.h index 2adaeb3..d3b98b9 100644 --- a/src/dfa.h +++ b/src/dfa.h @@ -10,6 +10,9 @@ #include "../include/variant.h" // GVA_Variant +#include // FIXME: DEBUG + + uint8_t* dfa_from_alignment(GVA_Allocator const allocator, uint8_t* dfas, size_t const len_ref, char const reference[static restrict len_ref], @@ -30,7 +33,8 @@ dfa_max_overlap(GVA_Allocator const allocator, // FIXME: DEBUG void -dfa_dot(size_t const len, char const reference[static restrict len], +dfa_dot(GVA_Allocator const allocator, FILE* const stream, + size_t const len, char const reference[static restrict len], GVA_Variant const supremal, uint8_t const dfa[static restrict 1]); diff --git a/src/main.c b/src/main.c index ab189bb..165c632 100644 --- a/src/main.c +++ b/src/main.c @@ -548,8 +548,8 @@ overlap_main(int argc, char* argv[static argc]) uint8_t* lhs_dfa = dfa_from_alignment(gva_std_allocator, NULL, lhs_variant.end - lhs_variant.start, reference.str + lhs_variant.start, lhs_variant.sequence.len, lhs_variant.sequence.str); uint8_t* rhs_dfa = dfa_from_alignment(gva_std_allocator, NULL, rhs_variant.end - rhs_variant.start, reference.str + rhs_variant.start, rhs_variant.sequence.len, rhs_variant.sequence.str); - //dfa_dot(reference.len, reference.str, lhs_variant, lhs_dfa); - //dfa_dot(reference.len, reference.str, rhs_variant, rhs_dfa); + //dfa_dot(gva_std_allocator, reference.len, reference.str, lhs_variant, lhs_dfa); + //dfa_dot(gva_std_allocator, reference.len, reference.str, rhs_variant, rhs_dfa); size_t const overlap = dfa_max_overlap(gva_std_allocator, reference.len, reference.str, @@ -625,6 +625,30 @@ all_main(int argc, char* argv[static argc]) fprintf(stderr, "reference length: %zu\n", reference.len); + char const* const lhs_obs = "TAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCCTAACCCTAACCCTAACCCTAACCCTAACCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCCTAACCCTAACCCTAACCCTC"; + char const* const rhs_obs = "TAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCCTAACCCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCCTAACCCTAACCCTAACCCTAACCCTC"; + + GVA_Variant const lhs = {10000, 10469, {strlen(lhs_obs), lhs_obs}}; + GVA_Variant const rhs = {10000, 10469, {strlen(rhs_obs), rhs_obs}}; + + uint8_t* lhs_dfa = dfa_from_alignment(gva_std_allocator, NULL, lhs.end - lhs.start, reference.str + lhs.start, lhs.sequence.len, lhs.sequence.str); + //uint8_t* rhs_dfa = dfa_from_alignment(gva_std_allocator, NULL, rhs.end - rhs.start, reference.str + rhs.start, rhs.sequence.len, rhs.sequence.str); + + fprintf(stderr, "lhs size: %zu\n", array_length(lhs_dfa)); + //fprintf(stderr, "rhs size: %zu\n", array_length(rhs_dfa)); + + dfa_dot(gva_std_allocator, stdout, reference.len, reference.str, lhs, lhs_dfa); + + + + //size_t const o = dfa_max_overlap(gva_std_allocator, reference.len, reference.str, lhs, lhs_dfa, rhs, rhs_dfa); + //fprintf(stderr, "overlap: %zu\n", o); + + + + return EXIT_SUCCESS; + + errno = 0; stream = fopen(argv[2], "r"); if (stream == NULL) @@ -780,6 +804,7 @@ all_main(int argc, char* argv[static argc]) if (lhs_dfa == NULL) { + fprintf(stderr, "NEW LHS\n"); lhs_dfa = dfa_from_alignment(gva_std_allocator, NULL, lhs.end - lhs.start, reference.str + lhs.start, lhs.sequence.len, lhs.sequence.str); } // if @@ -795,6 +820,9 @@ all_main(int argc, char* argv[static argc]) gva_lcs_graph_uniq_atomics(rhs_graph, lhs.start, rhs.start, rhs.end, rhs_dels, rhs_as, rhs_cs, rhs_gs, rhs_ts); + fprintf(stderr, GVA_STRING_FMT " vs " GVA_STRING_FMT "\n", + GVA_STRING_PRINT(trie_string(labels, entries[i].label)), + GVA_STRING_PRINT(trie_string(labels, entries[j].label))); fprintf(stderr, GVA_VARIANT_FMT " vs " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(lhs), GVA_VARIANT_PRINT(rhs)); fprintf(stderr, "%zu x %zu\n", array_length(lhs_dfa), array_length(rhs_dfa)); size_t const dfa_overlap = dfa_max_overlap(gva_std_allocator, reference.len, reference.str, lhs, lhs_dfa, rhs, rhs_dfa); @@ -859,9 +887,10 @@ all_main(int argc, char* argv[static argc]) int main(int argc, char* argv[static argc]) { + // return allele_main(argc, argv); // return index_main(argc, argv); // return supremal_main(argc, argv); - return overlap_main(argc, argv); - //return all_main(argc, argv); + // return overlap_main(argc, argv); + return all_main(argc, argv); } // main From 6df7233002e35f449cea62f2739873ce4862e5ac Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 29 Apr 2026 09:48:20 +0200 Subject: [PATCH 622/704] WIP: 64bits hash table --- src/dfa.c | 53 ++++++++++++++++++++++++------------------------ src/hash_table.c | 33 ++++++++++++++---------------- src/hash_table.h | 7 +++++-- src/index.c | 2 +- src/main.c | 33 +++--------------------------- 5 files changed, 50 insertions(+), 78 deletions(-) diff --git a/src/dfa.c b/src/dfa.c index 60c6c30..9ef4af5 100644 --- a/src/dfa.c +++ b/src/dfa.c @@ -1,6 +1,6 @@ #include // bool, true #include // NULL, size_t -#include // uint8_t +#include // uint8_t, SIZE_MAX #include // memset #include "../include/allocator.h" // GVA_Allocator @@ -229,7 +229,7 @@ typedef struct { HASH_TABLE_KEY; gva_uint included; - gva_uint next; + size_t next; } Entry; @@ -237,8 +237,8 @@ typedef struct { Entry* entries; GVA_Allocator allocator; - gva_uint head; - gva_uint tail; + size_t head; + size_t tail; } Queue; @@ -249,8 +249,8 @@ queue_init(GVA_Allocator const allocator, size_t const capacity) { .entries = hash_table_init(allocator, capacity, sizeof(Entry)), .allocator = allocator, - .head = GVA_NULL, - .tail = GVA_NULL, + .head = SIZE_MAX, + .tail = SIZE_MAX, }; } // queue_init @@ -259,34 +259,34 @@ static inline void queue_destroy(Queue self[static 1]) { self->entries = HASH_TABLE_DESTROY(self->allocator, self->entries); - self->head = GVA_NULL; - self->tail = GVA_NULL; + self->head = SIZE_MAX; + self->tail = SIZE_MAX; } // queue_destroy static inline bool queue_empty(Queue const self[static 1]) { - return self->head == GVA_NULL; + return self->head == SIZE_MAX; } // queue_empty -static inline gva_uint +static inline size_t queue_pop(Queue self[static 1]) { size_t const hash_idx = HASH_TABLE_INDEX(self->entries, self->head); - gva_uint const idx = self->entries[hash_idx].gva_key; + size_t const idx = self->entries[hash_idx].gva_key; self->head = self->entries[hash_idx].next; - if (self->head == GVA_NULL) + if (self->head == SIZE_MAX) { - self->tail = GVA_NULL; + self->tail = SIZE_MAX; } // if return idx; } // queue_pop static inline void -queue_push_back(Queue self[static 1], gva_uint const idx, gva_uint const included) +queue_push_back(Queue self[static 1], size_t const idx, size_t const included) { size_t const hash_idx = HASH_TABLE_INDEX(self->entries, idx); if (self->entries[hash_idx].gva_key == idx) @@ -299,10 +299,10 @@ queue_push_back(Queue self[static 1], gva_uint const idx, gva_uint const include { .gva_key = idx, .included = included, - .next = GVA_NULL, + .next = SIZE_MAX, })); - if (self->tail == GVA_NULL) + if (self->tail == SIZE_MAX) { self->head = idx; } // if @@ -315,7 +315,7 @@ queue_push_back(Queue self[static 1], gva_uint const idx, gva_uint const include static inline void -queue_push_front(Queue self[static 1], gva_uint const idx, gva_uint const included) +queue_push_front(Queue self[static 1], size_t const idx, size_t const included) { size_t const hash_idx = HASH_TABLE_INDEX(self->entries, idx); if (self->entries[hash_idx].gva_key == idx) @@ -331,7 +331,7 @@ queue_push_front(Queue self[static 1], gva_uint const idx, gva_uint const includ .next = self->head, })); - if (self->head == GVA_NULL) + if (self->head == SIZE_MAX) { self->tail = idx; } // if @@ -345,7 +345,7 @@ dfa_max_overlap(GVA_Allocator const allocator, GVA_Variant const lhs_supremal, uint8_t const lhs_dfa[static restrict 1], GVA_Variant const rhs_supremal, uint8_t const rhs_dfa[static restrict 1]) { - static size_t const INITIAL_SIZE = 2048; + static size_t const INITIAL_SIZE = 4096; size_t const lhs_width = lhs_supremal.sequence.len + 1; size_t const rhs_width = rhs_supremal.sequence.len + 1; @@ -362,9 +362,8 @@ dfa_max_overlap(GVA_Allocator const allocator, while (!queue_empty(&queue)) { size_t const idx = queue_pop(&queue); - if (idx == lhs_size * rhs_size - 1) + if (idx == lhs_size * rhs_size - 1) // OVERFLOW { - fprintf(stderr, "BREAK\n"); break; } // if @@ -374,7 +373,7 @@ dfa_max_overlap(GVA_Allocator const allocator, size_t const rhs_ref = rhs_idx / rhs_width + rhs_supremal.start; size_t const included = queue.entries[HASH_TABLE_INDEX(queue.entries, idx)].included; - fprintf(stderr, "{%zu, %zu} (%zu): %zu\n", lhs_idx, rhs_idx, idx, included); + //fprintf(stderr, "{%zu, %zu} (%zu): %zu\n", lhs_idx, rhs_idx, idx, included); if ((lhs_idx == 0 && rhs_ref < lhs_ref) || lhs_idx == lhs_size - 1) { @@ -531,8 +530,8 @@ dfa_dot(GVA_Allocator const allocator, FILE* const stream, fprintf(stream, "strict digraph{\nrankdir=LR\nnode[fixedsize=true,shape=circle,width=1]\ni[label=\"\",shape=none,width=0]\ni->0\n"); - gva_uint head = 0; - gva_uint tail = head; + size_t head = 0; + size_t tail = head; queue[head].seen = true; queue[head].next = GVA_NULL; while (head != GVA_NULL) @@ -540,7 +539,7 @@ dfa_dot(GVA_Allocator const allocator, FILE* const stream, uint8_t const value = get(dfa, head); if (value & DFA_DELETION) { - fprintf(stream, "%u->%zu[label=\"%zu Δ\"]\n", head, head + width, supremal.start + head / width); + fprintf(stream, "%zu->%zu[label=\"%zu Δ\"]\n", head, head + width, supremal.start + head / width); if (!queue[head + width].seen) { queue[head + width].seen = true; @@ -551,7 +550,7 @@ dfa_dot(GVA_Allocator const allocator, FILE* const stream, } // if if (value & DFA_INSERTION) { - fprintf(stream, "%u->%u[label=\"%zu %c\"]\n", head, head + 1, supremal.start + head / width, supremal.sequence.str[head % width]); + fprintf(stream, "%zu->%zu[label=\"%zu %c\"]\n", head, head + 1, supremal.start + head / width, supremal.sequence.str[head % width]); if (!queue[head + 1].seen) { queue[head + 1].seen = true; @@ -563,7 +562,7 @@ dfa_dot(GVA_Allocator const allocator, FILE* const stream, if (head % width < width - 1 && reference[supremal.start + head / width] == supremal.sequence.str[head % width]) { - fprintf(stream, "%u->%zu[label=\"%zu Μ\"]\n", head, head + width + 1, supremal.start + head / width); + fprintf(stream, "%zu->%zu[label=\"%zu Μ\"]\n", head, head + width + 1, supremal.start + head / width); if (!queue[head + width + 1].seen) { queue[head + width + 1].seen = true; diff --git a/src/hash_table.c b/src/hash_table.c index 204476d..a9c451d 100644 --- a/src/hash_table.c +++ b/src/hash_table.c @@ -1,11 +1,10 @@ #include // true #include // NULL, size_t -#include // uintmax_t +#include // uint64_t, uintmax_t, UINT64_C #include // memcpy -#include "../include/types.h" // GVA_NULL, gva_uint #include "array.h" // ARRAY_DESTROY, Array, array_* -#include "hash_table.h" // hash_table_* +#include "hash_table.h" // HASH_TABLE_NOT_FOUND, hash_table_* void* @@ -14,22 +13,21 @@ hash_table_init(GVA_Allocator const allocator, size_t const capacity, size_t con void* hash_table = array_init(allocator, capacity, item_size); for (size_t i = 0; i < capacity; ++i) { - *(gva_uint*) ((uintmax_t) hash_table + i * item_size) = GVA_NULL; + *(uint64_t*) ((uintmax_t) hash_table + i * item_size) = HASH_TABLE_NOT_FOUND; } // if return hash_table; } // hash_table_init -// Jenkins hash -static inline gva_uint -hash(gva_uint key) +// murmur +static inline uint64_t +hash(uint64_t key) { - key = (key + 0x7ed55d16) + (key << 12); - key = (key ^ 0xc761c23c) ^ (key >> 19); - key = (key + 0x165667b1) + (key << 5); - key = (key + 0xd3a2646c) ^ (key << 9); - key = (key + 0xfd7046c5) + (key << 3); - key = (key ^ 0xb55a4f09) ^ (key >> 16); + key ^= key >> 33; + key *= UINT64_C(0xff51afd7ed558ccd); + key ^= key >> 33; + key *= UINT64_C(0xc4ceb9fe1a85ec53); + key ^= key >> 33; return key; } // hash @@ -42,8 +40,8 @@ hash_table_index(void* const self, size_t const item_size, size_t const key) { // Quadratic probing with c1 and c2 1/2. size_t const idx = (hash(key) + (probe + probe * probe) / 2) % array_header(self)->capacity; - if (*(gva_uint*) ((uintmax_t) self + idx * item_size) == GVA_NULL || - *(gva_uint*) ((uintmax_t) self + idx * item_size) == key) + if (*(uint64_t*) ((uintmax_t) self + idx * item_size) == HASH_TABLE_NOT_FOUND || + *(uint64_t*) ((uintmax_t) self + idx * item_size) == key) { return idx; } // if @@ -68,11 +66,10 @@ hash_table_ensure(GVA_Allocator const allocator, void* const self, size_t const for (size_t i = 0; i < old_capacity; ++i) { void const* const src = (void*) ((uintmax_t) self + i * item_size); - if (*(gva_uint*) src != GVA_NULL) + if (*(uint64_t*) src != HASH_TABLE_NOT_FOUND) { array_header(new_table)->length += 1; - memcpy( - (void*) ((uintmax_t) new_table + hash_table_index(new_table, item_size, *(gva_uint*) src) * item_size), + memcpy((void*) ((uintmax_t) new_table + hash_table_index(new_table, item_size, *(uint64_t*) src) * item_size), src, item_size); } // if } // for diff --git a/src/hash_table.h b/src/hash_table.h index c536398..3757c53 100644 --- a/src/hash_table.h +++ b/src/hash_table.h @@ -3,13 +3,16 @@ #include // size_t +#include // uint64_t, UINT64_MAX #include "../include/allocator.h" // GVA_Allocator -#include "../include/types.h" // gva_uint #include "array.h" // ARRAY_DESTROY, array_header -#define HASH_TABLE_KEY gva_uint gva_key +#define HASH_TABLE_KEY uint64_t gva_key + + +static uint64_t const HASH_TABLE_NOT_FOUND = UINT64_MAX; void* diff --git a/src/index.c b/src/index.c index eb0804f..b405367 100644 --- a/src/index.c +++ b/src/index.c @@ -425,7 +425,7 @@ gva_index_query(GVA_Allocator const allocator, // Phase 2 for (size_t idx = 0; idx < array_header(entries)->capacity; ++idx) { - if (entries[idx].gva_key == GVA_NULL) + if (entries[idx].gva_key == HASH_TABLE_NOT_FOUND) { continue; } // if diff --git a/src/main.c b/src/main.c index 165c632..60b0408 100644 --- a/src/main.c +++ b/src/main.c @@ -625,30 +625,6 @@ all_main(int argc, char* argv[static argc]) fprintf(stderr, "reference length: %zu\n", reference.len); - char const* const lhs_obs = "TAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCCTAACCCTAACCCTAACCCTAACCCTAACCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCCTAACCCTAACCCTAACCCTC"; - char const* const rhs_obs = "TAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCCTAACCCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCCTAACCCTAACCCTAACCCTAACCCTC"; - - GVA_Variant const lhs = {10000, 10469, {strlen(lhs_obs), lhs_obs}}; - GVA_Variant const rhs = {10000, 10469, {strlen(rhs_obs), rhs_obs}}; - - uint8_t* lhs_dfa = dfa_from_alignment(gva_std_allocator, NULL, lhs.end - lhs.start, reference.str + lhs.start, lhs.sequence.len, lhs.sequence.str); - //uint8_t* rhs_dfa = dfa_from_alignment(gva_std_allocator, NULL, rhs.end - rhs.start, reference.str + rhs.start, rhs.sequence.len, rhs.sequence.str); - - fprintf(stderr, "lhs size: %zu\n", array_length(lhs_dfa)); - //fprintf(stderr, "rhs size: %zu\n", array_length(rhs_dfa)); - - dfa_dot(gva_std_allocator, stdout, reference.len, reference.str, lhs, lhs_dfa); - - - - //size_t const o = dfa_max_overlap(gva_std_allocator, reference.len, reference.str, lhs, lhs_dfa, rhs, rhs_dfa); - //fprintf(stderr, "overlap: %zu\n", o); - - - - return EXIT_SUCCESS; - - errno = 0; stream = fopen(argv[2], "r"); if (stream == NULL) @@ -804,7 +780,6 @@ all_main(int argc, char* argv[static argc]) if (lhs_dfa == NULL) { - fprintf(stderr, "NEW LHS\n"); lhs_dfa = dfa_from_alignment(gva_std_allocator, NULL, lhs.end - lhs.start, reference.str + lhs.start, lhs.sequence.len, lhs.sequence.str); } // if @@ -820,11 +795,6 @@ all_main(int argc, char* argv[static argc]) gva_lcs_graph_uniq_atomics(rhs_graph, lhs.start, rhs.start, rhs.end, rhs_dels, rhs_as, rhs_cs, rhs_gs, rhs_ts); - fprintf(stderr, GVA_STRING_FMT " vs " GVA_STRING_FMT "\n", - GVA_STRING_PRINT(trie_string(labels, entries[i].label)), - GVA_STRING_PRINT(trie_string(labels, entries[j].label))); - fprintf(stderr, GVA_VARIANT_FMT " vs " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(lhs), GVA_VARIANT_PRINT(rhs)); - fprintf(stderr, "%zu x %zu\n", array_length(lhs_dfa), array_length(rhs_dfa)); size_t const dfa_overlap = dfa_max_overlap(gva_std_allocator, reference.len, reference.str, lhs, lhs_dfa, rhs, rhs_dfa); bool const overlap = bitset_intersection_cnt(lhs_dels, rhs_dels) > 0 || @@ -844,6 +814,9 @@ all_main(int argc, char* argv[static argc]) if (overlap != (dfa_overlap > 0)) { + fprintf(stderr, GVA_STRING_FMT " vs " GVA_STRING_FMT "\n", + GVA_STRING_PRINT(trie_string(labels, entries[i].label)), + GVA_STRING_PRINT(trie_string(labels, entries[j].label))); fprintf(stderr, "ERROR: %zu\n", dfa_overlap); return EXIT_FAILURE; } // if From 43e854aff68384da5a123100083bf12f9f20eddc Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 30 Apr 2026 16:04:54 +0200 Subject: [PATCH 623/704] WIP: better DFA traversal; SVG output; uniq_atomics --- src/dfa.c | 298 ++++++++++++++++++++++++++++++++++++++++------------- src/dfa.h | 23 ++++- src/main.c | 24 +++-- 3 files changed, 261 insertions(+), 84 deletions(-) diff --git a/src/dfa.c b/src/dfa.c index 9ef4af5..81db151 100644 --- a/src/dfa.c +++ b/src/dfa.c @@ -1,6 +1,6 @@ #include // bool, true #include // NULL, size_t -#include // uint8_t, SIZE_MAX +#include // uint8_t, uint64_t, SIZE_MAX, UINT64_C #include // memset #include "../include/allocator.h" // GVA_Allocator @@ -9,11 +9,13 @@ #include "../include/variant.h" // GVA_Variant #include "align.h" // LCS_Alignment, lcs_align #include "array.h" // ARRAY_*, array_* +#include "common.h" // MAX, MIN #include "dfa.h" // dfa* #include "hash_table.h" // HASH_TABLE_*, hash_table_* -#include // DEBUG +// FIXME: DEBUG +#include static uint8_t const DFA_DELETION = 0x1; @@ -342,15 +344,16 @@ queue_push_front(Queue self[static 1], size_t const idx, size_t const included) size_t dfa_max_overlap(GVA_Allocator const allocator, size_t const len, char const reference[static restrict len], - GVA_Variant const lhs_supremal, uint8_t const lhs_dfa[static restrict 1], - GVA_Variant const rhs_supremal, uint8_t const rhs_dfa[static restrict 1]) + GVA_Variant const lhs_variant, uint8_t const lhs_dfa[static restrict 1], + GVA_Variant const rhs_variant, uint8_t const rhs_dfa[static restrict 1], + size_t const limit) { static size_t const INITIAL_SIZE = 4096; - size_t const lhs_width = lhs_supremal.sequence.len + 1; - size_t const rhs_width = rhs_supremal.sequence.len + 1; - size_t const lhs_size = (lhs_supremal.end - lhs_supremal.start + 1) * lhs_width; - size_t const rhs_size = (rhs_supremal.end - rhs_supremal.start + 1) * rhs_width; + size_t const lhs_width = lhs_variant.sequence.len + 1; + size_t const rhs_width = rhs_variant.sequence.len + 1; + size_t const lhs_size = (lhs_variant.end - lhs_variant.start + 1) * lhs_width; + size_t const rhs_size = (rhs_variant.end - rhs_variant.start + 1) * rhs_width; Queue queue = queue_init(allocator, INITIAL_SIZE); if (queue.entries == NULL) @@ -369,8 +372,8 @@ dfa_max_overlap(GVA_Allocator const allocator, size_t const lhs_idx = idx / rhs_size; size_t const rhs_idx = idx % rhs_size; - size_t const lhs_ref = lhs_idx / lhs_width + lhs_supremal.start; - size_t const rhs_ref = rhs_idx / rhs_width + rhs_supremal.start; + size_t const lhs_ref = lhs_idx / lhs_width + lhs_variant.start; + size_t const rhs_ref = rhs_idx / rhs_width + rhs_variant.start; size_t const included = queue.entries[HASH_TABLE_INDEX(queue.entries, idx)].included; //fprintf(stderr, "{%zu, %zu} (%zu): %zu\n", lhs_idx, rhs_idx, idx, included); @@ -381,7 +384,7 @@ dfa_max_overlap(GVA_Allocator const allocator, bool const rhs_deletion = rhs_value & DFA_DELETION; bool const rhs_insertion = rhs_value & DFA_INSERTION; bool const rhs_match = rhs_idx % rhs_width < rhs_width - 1 && - reference[rhs_supremal.start + rhs_idx / rhs_width] == rhs_supremal.sequence.str[rhs_idx % rhs_width]; + reference[rhs_variant.start + rhs_idx / rhs_width] == rhs_variant.sequence.str[rhs_idx % rhs_width]; if (rhs_match) { @@ -400,7 +403,7 @@ dfa_max_overlap(GVA_Allocator const allocator, if (rhs_insertion) { // .I - // fprintf(stderr, " push (. vs %zu %c) +0 +1 {%zu, %zu} (%zu)\n", rhs_ref, rhs_supremal.sequence.str[rhs_idx % rhs_width], lhs_idx, rhs_idx + 1, lhs_idx * rhs_size + rhs_idx + 1); + // fprintf(stderr, " push (. vs %zu %c) +0 +1 {%zu, %zu} (%zu)\n", rhs_ref, rhs_variant.sequence.str[rhs_idx % rhs_width], lhs_idx, rhs_idx + 1, lhs_idx * rhs_size + rhs_idx + 1); queue_push_back(&queue, lhs_idx * rhs_size + rhs_idx + 1, included); } // if } // if @@ -410,7 +413,7 @@ dfa_max_overlap(GVA_Allocator const allocator, bool const lhs_deletion = lhs_value & DFA_DELETION; bool const lhs_insertion = lhs_value & DFA_INSERTION; bool const lhs_match = lhs_idx % lhs_width < lhs_width - 1 && - reference[lhs_supremal.start + lhs_idx / lhs_width] == lhs_supremal.sequence.str[lhs_idx % lhs_width]; + reference[lhs_variant.start + lhs_idx / lhs_width] == lhs_variant.sequence.str[lhs_idx % lhs_width]; if (lhs_match) { @@ -429,7 +432,7 @@ dfa_max_overlap(GVA_Allocator const allocator, if (lhs_insertion) { // I. - // fprintf(stderr, " push (%zu %c vs .) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, lhs_supremal.sequence.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx, (lhs_idx + 1) * rhs_size + rhs_idx); + // fprintf(stderr, " push (%zu %c vs .) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, lhs_variant.sequence.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx, (lhs_idx + 1) * rhs_size + rhs_idx); queue_push_back(&queue, (lhs_idx + 1) * rhs_size + rhs_idx, included); } // if } // if @@ -439,13 +442,13 @@ dfa_max_overlap(GVA_Allocator const allocator, bool const lhs_deletion = lhs_value & DFA_DELETION; bool const lhs_insertion = lhs_value & DFA_INSERTION; bool const lhs_match = lhs_idx % lhs_width < lhs_width - 1 && - reference[lhs_supremal.start + lhs_idx / lhs_width] == lhs_supremal.sequence.str[lhs_idx % lhs_width]; + reference[lhs_variant.start + lhs_idx / lhs_width] == lhs_variant.sequence.str[lhs_idx % lhs_width]; uint8_t const rhs_value = get(rhs_dfa, rhs_idx); bool const rhs_deletion = rhs_value & DFA_DELETION; bool const rhs_insertion = rhs_value & DFA_INSERTION; bool const rhs_match = rhs_idx % rhs_width < rhs_width - 1 && - reference[rhs_supremal.start + rhs_idx / rhs_width] == rhs_supremal.sequence.str[rhs_idx % rhs_width]; + reference[rhs_variant.start + rhs_idx / rhs_width] == rhs_variant.sequence.str[rhs_idx % rhs_width]; if (lhs_match && rhs_match) { @@ -458,13 +461,21 @@ dfa_max_overlap(GVA_Allocator const allocator, { // DD // fprintf(stderr, " push (%zu DELTA) {%zu, %zu} +1 +0 (%zu)\n", lhs_ref, lhs_idx + lhs_width, rhs_idx + rhs_width, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width); + if (limit > 0 && included + 1 >= limit) + { + break; + } // if queue_push_front(&queue, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width, included + 1); } // if - if (lhs_insertion && rhs_insertion && lhs_supremal.sequence.str[lhs_idx % lhs_width] == rhs_supremal.sequence.str[rhs_idx % rhs_width]) + if (lhs_insertion && rhs_insertion && lhs_variant.sequence.str[lhs_idx % lhs_width] == rhs_variant.sequence.str[rhs_idx % rhs_width]) { // II - // fprintf(stderr, " push (%zu %c) {%zu, %zu} +1 +0 (%zu)\n", lhs_ref, lhs_supremal.sequence.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx + 1, (lhs_idx + 1) * rhs_size + rhs_idx + 1); + // fprintf(stderr, " push (%zu %c) {%zu, %zu} +1 +0 (%zu)\n", lhs_ref, lhs_variant.sequence.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx + 1, (lhs_idx + 1) * rhs_size + rhs_idx + 1); + if (limit > 0 && included + 1 >= limit) + { + break; + } // if queue_push_front(&queue, (lhs_idx + 1) * rhs_size + rhs_idx + 1, included + 1); } // if @@ -483,23 +494,29 @@ dfa_max_overlap(GVA_Allocator const allocator, } // if if (lhs_insertion && (rhs_deletion || rhs_match || (rhs_insertion && - lhs_supremal.sequence.str[lhs_idx % lhs_width] != rhs_supremal.sequence.str[rhs_idx % rhs_width]))) + lhs_variant.sequence.str[lhs_idx % lhs_width] != rhs_variant.sequence.str[rhs_idx % rhs_width]))) { // I. - // fprintf(stderr, " push (%zu %c vs .) {%zu, %zu} +0 +1 (%zu)\n", lhs_ref, lhs_supremal.sequence.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx, (lhs_idx + 1) * rhs_size + rhs_idx); + // fprintf(stderr, " push (%zu %c vs .) {%zu, %zu} +0 +1 (%zu)\n", lhs_ref, lhs_variant.sequence.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx, (lhs_idx + 1) * rhs_size + rhs_idx); queue_push_back(&queue, (lhs_idx + 1) * rhs_size + rhs_idx, included); } // if if (rhs_insertion && (lhs_deletion || lhs_match || (lhs_insertion && - lhs_supremal.sequence.str[lhs_idx % lhs_width] != rhs_supremal.sequence.str[rhs_idx % rhs_width]))) + lhs_variant.sequence.str[lhs_idx % lhs_width] != rhs_variant.sequence.str[rhs_idx % rhs_width]))) { // .I - // fprintf(stderr, " push (. vs %zu %c) {%zu, %zu} +0 +1 (%zu)\n", rhs_ref, rhs_supremal.sequence.str[rhs_idx % rhs_width], lhs_idx, rhs_idx + 1, lhs_idx * rhs_size + rhs_idx + 1); + // fprintf(stderr, " push (. vs %zu %c) {%zu, %zu} +0 +1 (%zu)\n", rhs_ref, rhs_variant.sequence.str[rhs_idx % rhs_width], lhs_idx, rhs_idx + 1, lhs_idx * rhs_size + rhs_idx + 1); queue_push_back(&queue, lhs_idx * rhs_size + rhs_idx + 1, included); } // if } // else } // while - size_t const included = queue.entries[HASH_TABLE_INDEX(queue.entries, lhs_size * rhs_size - 1)].included; + + size_t included = limit; + size_t const idx = HASH_TABLE_INDEX(queue.entries, lhs_size * rhs_size - 1); + if (queue.entries[idx].gva_key == lhs_size * rhs_size - 1) + { + included = queue.entries[idx].included; + } // if queue_destroy(&queue); @@ -507,74 +524,211 @@ dfa_max_overlap(GVA_Allocator const allocator, } // dfa_max_overlap -// FIXME: DEBUG -void -dfa_dot(GVA_Allocator const allocator, FILE* const stream, +static uint64_t* +uniq_atomics(GVA_Allocator const allocator, + size_t const start, size_t const end, size_t const len, char const reference[static restrict len], - GVA_Variant const supremal, uint8_t const dfa[static restrict 1]) + GVA_Variant const variant, uint8_t const dfa[static restrict 1]) { - size_t const width = supremal.sequence.len + 1; - size_t const size = (supremal.end - supremal.start + 1) * width; + size_t const width = variant.sequence.len + 1; - struct + uint64_t* restrict atomics = allocator.allocate(allocator.context, NULL, 0, sizeof(*atomics) * (end - start)); + if (atomics == NULL) { - char seen; - gva_uint next; - }* queue = allocator.allocate(allocator.context, NULL, 0, sizeof(*queue) * size); - if (queue == NULL) + return NULL; // OOM + } // if + + memset(atomics, 0, sizeof(*atomics) * (end - start)); + + size_t row_end = 0; + size_t j = 0; + for (size_t i = 0; i <= variant.end - variant.start; ++i) { - return; // OOM + size_t row_start = width; + size_t next_end = row_end; + uint8_t value = 0; + while (j <= row_end || value & DFA_INSERTION) + { + value = get(dfa, i * width + j); + + if (value & DFA_DELETION) + { + if (variant.start + i >= start && variant.start + i < end) + { + atomics[i - (start - variant.start)] |= UINT64_C(1) << 63; + } // if + row_start = MIN(row_start, j); + } // if + + if (value & DFA_INSERTION) + { + if (variant.start + i >= start && variant.start + i < end) + { + atomics[i - (start - variant.start)] |= UINT64_C(1) << (variant.sequence.str[j] % 64); + } // if + next_end = MAX(next_end, j); + } // if + + if (reference[variant.start + i] == variant.sequence.str[j]) + { + row_start = MIN(row_start, j + 1); + next_end = MAX(next_end, j + 1); + } // if + + j += 1; + } // while + row_end = next_end; + j = row_start; + } // for + + return atomics; +} // uniq_atomics + + +bool +dfa_disjoint(GVA_Allocator const allocator, + size_t const len, char const reference[static restrict len], + GVA_Variant const lhs_variant, uint8_t const lhs_dfa[static restrict 1], + GVA_Variant const rhs_variant, uint8_t const rhs_dfa[static restrict 1]) +{ + size_t const start = MAX(lhs_variant.start, rhs_variant.start); + size_t const end = MIN(lhs_variant.end, rhs_variant.end); + + uint64_t* restrict lhs_atomics = uniq_atomics(allocator, start, end, len, reference, lhs_variant, lhs_dfa); + uint64_t* restrict rhs_atomics = uniq_atomics(allocator, start, end, len, reference, rhs_variant, rhs_dfa); + if (lhs_atomics == NULL || rhs_atomics == NULL) + { + rhs_atomics = allocator.allocate(allocator.context, rhs_atomics, sizeof(*rhs_atomics) * (end - start), 0); + lhs_atomics = allocator.allocate(allocator.context, lhs_atomics, sizeof(*lhs_atomics) * (end - start), 0); + return true; // OOM } // if - memset(queue, 0, sizeof(*queue) * size); + bool disjoint = true; + for (size_t i = 0; i < (end - start); ++i) + { + if (lhs_atomics[i] & rhs_atomics[i]) + { + disjoint = false; + break; + } // if + } // for + + rhs_atomics = allocator.allocate(allocator.context, rhs_atomics, sizeof(*rhs_atomics) * (end - start), 0); + lhs_atomics = allocator.allocate(allocator.context, lhs_atomics, sizeof(*lhs_atomics) * (end - start), 0); + return disjoint; +} // dfa_disjoint + + +// FIXME: DEBUG +void +dfa_dot(FILE* restrict const stream, + size_t const len, char const reference[static restrict len], + GVA_Variant const variant, uint8_t const dfa[static restrict 1]) +{ + size_t const width = variant.sequence.len + 1; + size_t const size = (variant.end - variant.start + 1) * width; fprintf(stream, "strict digraph{\nrankdir=LR\nnode[fixedsize=true,shape=circle,width=1]\ni[label=\"\",shape=none,width=0]\ni->0\n"); - size_t head = 0; - size_t tail = head; - queue[head].seen = true; - queue[head].next = GVA_NULL; - while (head != GVA_NULL) + size_t end = 0; + size_t j = 0; + for (size_t i = 0; i <= variant.end - variant.start; ++i) { - uint8_t const value = get(dfa, head); - if (value & DFA_DELETION) + size_t start = width; + size_t next_end = end; + uint8_t value = 0; + while (j <= end || value & DFA_INSERTION) { - fprintf(stream, "%zu->%zu[label=\"%zu Δ\"]\n", head, head + width, supremal.start + head / width); - if (!queue[head + width].seen) + value = get(dfa, i * width + j); + + if (value & DFA_DELETION) { - queue[head + width].seen = true; - queue[head + width].next = GVA_NULL; - queue[tail].next = head + width; - tail = head + width; + fprintf(stream, "%zu->%zu[label=\"%zu Δ\"]\n", i * width + j, i * width + j + width, variant.start + i); + start = MIN(start, j); } // if - } // if - if (value & DFA_INSERTION) - { - fprintf(stream, "%zu->%zu[label=\"%zu %c\"]\n", head, head + 1, supremal.start + head / width, supremal.sequence.str[head % width]); - if (!queue[head + 1].seen) + + if (value & DFA_INSERTION) { - queue[head + 1].seen = true; - queue[head + 1].next = GVA_NULL; - queue[tail].next = head + 1; - tail = head + 1; + fprintf(stream, "%zu->%zu[label=\"%zu %c\"]\n", i * width + j, i * width + j + 1, variant.start + i, variant.sequence.str[j]); + next_end = MAX(next_end, j); } // if - } // if - if (head % width < width - 1 && - reference[supremal.start + head / width] == supremal.sequence.str[head % width]) - { - fprintf(stream, "%zu->%zu[label=\"%zu Μ\"]\n", head, head + width + 1, supremal.start + head / width); - if (!queue[head + width + 1].seen) + + if (reference[variant.start + i] == variant.sequence.str[j]) { - queue[head + width + 1].seen = true; - queue[head + width + 1].next = GVA_NULL; - queue[tail].next = head + width + 1; - tail = head + width + 1; + fprintf(stream, "%zu->%zu[label=\"%zu Μ\"]\n", i * width + j, i * width + j + width + 1, variant.start + i); + start = MIN(start, j + 1); + next_end = MAX(next_end, j + 1); } // if - } // if - head = queue[head].next; - } // while - queue = allocator.allocate(allocator.context, queue, sizeof(*queue) * size, 0); + j += 1; + } // while + end = next_end; + j = start; + } // for fprintf(stream, "%zu[peripheries=2]\n}\n", size - 1); } // dfa_dot + + +void +dfa_svg(FILE* restrict const stream, + size_t const len, char const reference[static restrict len], + GVA_Variant const variant, uint8_t const dfa[static restrict 1]) +{ + size_t const width = variant.sequence.len + 1; + size_t const size = (variant.end - variant.start + 1) * width; + + fprintf(stream, "\n"); + fprintf(stream, "\n\n\n\n\n"); + fprintf(stream, "\n"); + fprintf(stream, "\n"); + fprintf(stream, "%u\n", variant.start); + for (size_t i = 0; i < width - 1; ++i) + { + fprintf(stream, "%c\n", (i + 1) * 100, variant.sequence.str[i]); + } // for + fprintf(stream, "\n"); + + size_t end = 0; + size_t j = 0; + for (size_t i = 0; i <= variant.end - variant.start; ++i) + { + size_t start = width; + size_t next_end = end; + uint8_t value = 0; + while (j <= end || value & DFA_INSERTION) + { + fprintf(stream, "\n", j * 100 + 50, i * 100 + 50); + fprintf(stream, "%zu\n", j * 100 + 50, i * 100 + 50, i * width + j); + + value = get(dfa, i * width + j); + + if (value & DFA_DELETION) + { + fprintf(stream, "\n", j * 100 + 50, i * 100 + 50 + 25, j * 100 + 50, i * 100 + 100 + 16); + start = MIN(start, j); + } // if + + if (value & DFA_INSERTION) + { + fprintf(stream, "\n", j * 100 + 50 + 25, i * 100 + 50, j * 100 + 100 + 16, i * 100 + 50); + next_end = MAX(next_end, j); + } // if + + if (reference[variant.start + i] == variant.sequence.str[j]) + { + fprintf(stream, "\n", j * 100 + 50 + 17, i * 100 + 50 + 17, j * 100 + 100 + 50 - 24, i * 100 + 100 + 50 - 24); + start = MIN(start, j + 1); + next_end = MAX(next_end, j + 1); + } // if + + j += 1; + } // while + end = next_end; + j = start; + } // for + + fprintf(stream, "\n"); + fprintf(stream, "\n", ((size - 1) % width) * 100 + 50, ((size - 1) / width) * 100 + 50); + fprintf(stream, "\n"); +} // dfa_svg diff --git a/src/dfa.h b/src/dfa.h index d3b98b9..0fe5e8f 100644 --- a/src/dfa.h +++ b/src/dfa.h @@ -2,6 +2,7 @@ #define GVA_DFA_H +#include // bool #include // size_t #include // uint8_t @@ -27,15 +28,29 @@ dfa_from_lcs_graph(GVA_Allocator const allocator, uint8_t* dfas, size_t dfa_max_overlap(GVA_Allocator const allocator, size_t const len, char const reference[static restrict len], - GVA_Variant const lhs_supremal, uint8_t const lhs_dfa[static restrict 1], - GVA_Variant const rhs_supremal, uint8_t const rhs_dfa[static restrict 1]); + GVA_Variant const lhs_variant, uint8_t const lhs_dfa[static restrict 1], + GVA_Variant const rhs_variant, uint8_t const rhs_dfa[static restrict 1], + size_t const limit); + + +bool +dfa_disjoint(GVA_Allocator const allocator, + size_t const len, char const reference[static restrict len], + GVA_Variant const lhs_variant, uint8_t const lhs_dfa[static restrict 1], + GVA_Variant const rhs_variant, uint8_t const rhs_dfa[static restrict 1]); // FIXME: DEBUG void -dfa_dot(GVA_Allocator const allocator, FILE* const stream, +dfa_dot(FILE* restrict const stream, + size_t const len, char const reference[static restrict len], + GVA_Variant const variant, uint8_t const dfa[static restrict 1]); + + +void +dfa_svg(FILE* restrict const stream, size_t const len, char const reference[static restrict len], - GVA_Variant const supremal, uint8_t const dfa[static restrict 1]); + GVA_Variant const variant, uint8_t const dfa[static restrict 1]); #endif // GVA_DFA_H diff --git a/src/main.c b/src/main.c index 60b0408..068c626 100644 --- a/src/main.c +++ b/src/main.c @@ -548,16 +548,25 @@ overlap_main(int argc, char* argv[static argc]) uint8_t* lhs_dfa = dfa_from_alignment(gva_std_allocator, NULL, lhs_variant.end - lhs_variant.start, reference.str + lhs_variant.start, lhs_variant.sequence.len, lhs_variant.sequence.str); uint8_t* rhs_dfa = dfa_from_alignment(gva_std_allocator, NULL, rhs_variant.end - rhs_variant.start, reference.str + rhs_variant.start, rhs_variant.sequence.len, rhs_variant.sequence.str); - //dfa_dot(gva_std_allocator, reference.len, reference.str, lhs_variant, lhs_dfa); - //dfa_dot(gva_std_allocator, reference.len, reference.str, rhs_variant, rhs_dfa); + //dfa_dot(stdout, reference.len, reference.str, lhs_variant, lhs_dfa); + //dfa_svg(stdout, reference.len, reference.str, lhs_variant, lhs_dfa); + + fprintf(stderr, "disjoint: %d\n", dfa_disjoint(gva_std_allocator, reference.len, reference.str, lhs_variant, lhs_dfa, rhs_variant, rhs_dfa)); + +/* + dfa_dot(stdout, reference.len, reference.str, lhs_variant, lhs_dfa); + // dfa_dot(stdout, reference.len, reference.str, rhs_variant, rhs_dfa); + + //dfa_svg(stdout, reference.len, reference.str, lhs_variant, lhs_dfa); + //dfa_svg(stdout, reference.len, reference.str, rhs_variant, rhs_dfa); size_t const overlap = dfa_max_overlap(gva_std_allocator, reference.len, reference.str, lhs_variant, lhs_dfa, - rhs_variant, rhs_dfa); + rhs_variant, rhs_dfa, 0); fprintf(stdout, "%zu\n", overlap); - +*/ rhs_dfa = ARRAY_DESTROY(gva_std_allocator, rhs_dfa); lhs_dfa = ARRAY_DESTROY(gva_std_allocator, lhs_dfa); } // while @@ -795,7 +804,7 @@ all_main(int argc, char* argv[static argc]) gva_lcs_graph_uniq_atomics(rhs_graph, lhs.start, rhs.start, rhs.end, rhs_dels, rhs_as, rhs_cs, rhs_gs, rhs_ts); - size_t const dfa_overlap = dfa_max_overlap(gva_std_allocator, reference.len, reference.str, lhs, lhs_dfa, rhs, rhs_dfa); + size_t const dfa_overlap = dfa_max_overlap(gva_std_allocator, reference.len, reference.str, lhs, lhs_dfa, rhs, rhs_dfa, 1); bool const overlap = bitset_intersection_cnt(lhs_dels, rhs_dels) > 0 || bitset_intersection_cnt(lhs_as, rhs_as) > 0 || @@ -860,10 +869,9 @@ all_main(int argc, char* argv[static argc]) int main(int argc, char* argv[static argc]) { - // return allele_main(argc, argv); // return index_main(argc, argv); // return supremal_main(argc, argv); - // return overlap_main(argc, argv); - return all_main(argc, argv); + return overlap_main(argc, argv); + // return all_main(argc, argv); } // main From 00781c9b54398c244e9d2201f30cc9380fd00f74 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 30 Apr 2026 16:16:24 +0200 Subject: [PATCH 624/704] WIP: skip nodes without edges in SVG --- src/dfa.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/dfa.c b/src/dfa.c index 81db151..bcebb17 100644 --- a/src/dfa.c +++ b/src/dfa.c @@ -1,4 +1,4 @@ -#include // bool, true +#include // bool, false, true #include // NULL, size_t #include // uint8_t, uint64_t, SIZE_MAX, UINT64_C #include // memset @@ -698,21 +698,21 @@ dfa_svg(FILE* restrict const stream, uint8_t value = 0; while (j <= end || value & DFA_INSERTION) { - fprintf(stream, "\n", j * 100 + 50, i * 100 + 50); - fprintf(stream, "%zu\n", j * 100 + 50, i * 100 + 50, i * width + j); - value = get(dfa, i * width + j); + bool edge = false; if (value & DFA_DELETION) { fprintf(stream, "\n", j * 100 + 50, i * 100 + 50 + 25, j * 100 + 50, i * 100 + 100 + 16); start = MIN(start, j); + edge = true; } // if if (value & DFA_INSERTION) { fprintf(stream, "\n", j * 100 + 50 + 25, i * 100 + 50, j * 100 + 100 + 16, i * 100 + 50); next_end = MAX(next_end, j); + edge = true; } // if if (reference[variant.start + i] == variant.sequence.str[j]) @@ -720,6 +720,13 @@ dfa_svg(FILE* restrict const stream, fprintf(stream, "\n", j * 100 + 50 + 17, i * 100 + 50 + 17, j * 100 + 100 + 50 - 24, i * 100 + 100 + 50 - 24); start = MIN(start, j + 1); next_end = MAX(next_end, j + 1); + edge = true; + } // if + + if (edge) + { + fprintf(stream, "\n", j * 100 + 50, i * 100 + 50); + fprintf(stream, "%zu\n", j * 100 + 50, i * 100 + 50, i * width + j); } // if j += 1; @@ -729,6 +736,8 @@ dfa_svg(FILE* restrict const stream, } // for fprintf(stream, "\n"); + fprintf(stream, "\n", ((size - 1) % width) * 100 + 50, ((size - 1) / width) * 100 + 50); fprintf(stream, "\n", ((size - 1) % width) * 100 + 50, ((size - 1) / width) * 100 + 50); + fprintf(stream, "%zu\n", ((size - 1) % width) * 100 + 50, ((size - 1) / width) * 100 + 50, size - 1); fprintf(stream, "\n"); } // dfa_svg From 88999031005e8865213e3e538e25b960f1aa538c Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 30 Apr 2026 22:10:22 +0200 Subject: [PATCH 625/704] FIX sink node --- src/dfa.c | 10 ++++++---- src/main.c | 20 ++++++-------------- 2 files changed, 12 insertions(+), 18 deletions(-) diff --git a/src/dfa.c b/src/dfa.c index bcebb17..36d3289 100644 --- a/src/dfa.c +++ b/src/dfa.c @@ -10,7 +10,7 @@ #include "align.h" // LCS_Alignment, lcs_align #include "array.h" // ARRAY_*, array_* #include "common.h" // MAX, MIN -#include "dfa.h" // dfa* +#include "dfa.h" // dfa_* #include "hash_table.h" // HASH_TABLE_*, hash_table_* @@ -653,7 +653,8 @@ dfa_dot(FILE* restrict const stream, next_end = MAX(next_end, j); } // if - if (reference[variant.start + i] == variant.sequence.str[j]) + if (i < variant.end - variant.start && + reference[variant.start + i] == variant.sequence.str[j]) { fprintf(stream, "%zu->%zu[label=\"%zu Μ\"]\n", i * width + j, i * width + j + width + 1, variant.start + i); start = MIN(start, j + 1); @@ -678,7 +679,7 @@ dfa_svg(FILE* restrict const stream, size_t const width = variant.sequence.len + 1; size_t const size = (variant.end - variant.start + 1) * width; - fprintf(stream, "\n"); + fprintf(stream, "\n", width * 100, (variant.end - variant.start + 1) * 100); fprintf(stream, "\n\n\n\n\n"); fprintf(stream, "\n"); fprintf(stream, "\n"); @@ -715,7 +716,8 @@ dfa_svg(FILE* restrict const stream, edge = true; } // if - if (reference[variant.start + i] == variant.sequence.str[j]) + if (i < variant.end - variant.start && + reference[variant.start + i] == variant.sequence.str[j]) { fprintf(stream, "\n", j * 100 + 50 + 17, i * 100 + 50 + 17, j * 100 + 100 + 50 - 24, i * 100 + 100 + 50 - 24); start = MIN(start, j + 1); diff --git a/src/main.c b/src/main.c index 068c626..7221667 100644 --- a/src/main.c +++ b/src/main.c @@ -548,25 +548,17 @@ overlap_main(int argc, char* argv[static argc]) uint8_t* lhs_dfa = dfa_from_alignment(gva_std_allocator, NULL, lhs_variant.end - lhs_variant.start, reference.str + lhs_variant.start, lhs_variant.sequence.len, lhs_variant.sequence.str); uint8_t* rhs_dfa = dfa_from_alignment(gva_std_allocator, NULL, rhs_variant.end - rhs_variant.start, reference.str + rhs_variant.start, rhs_variant.sequence.len, rhs_variant.sequence.str); - //dfa_dot(stdout, reference.len, reference.str, lhs_variant, lhs_dfa); - //dfa_svg(stdout, reference.len, reference.str, lhs_variant, lhs_dfa); - - fprintf(stderr, "disjoint: %d\n", dfa_disjoint(gva_std_allocator, reference.len, reference.str, lhs_variant, lhs_dfa, rhs_variant, rhs_dfa)); - -/* dfa_dot(stdout, reference.len, reference.str, lhs_variant, lhs_dfa); - // dfa_dot(stdout, reference.len, reference.str, rhs_variant, rhs_dfa); + dfa_dot(stdout, reference.len, reference.str, rhs_variant, rhs_dfa); + dfa_svg(stdout, reference.len, reference.str, lhs_variant, lhs_dfa); + dfa_svg(stdout, reference.len, reference.str, rhs_variant, rhs_dfa); - //dfa_svg(stdout, reference.len, reference.str, lhs_variant, lhs_dfa); - //dfa_svg(stdout, reference.len, reference.str, rhs_variant, rhs_dfa); - - size_t const overlap = dfa_max_overlap(gva_std_allocator, + fprintf(stderr, "disjoint: %d\n", dfa_disjoint(gva_std_allocator, reference.len, reference.str, lhs_variant, lhs_dfa, rhs_variant, rhs_dfa)); + fprintf(stderr, "max_overlap: %zu\n", dfa_max_overlap(gva_std_allocator, reference.len, reference.str, lhs_variant, lhs_dfa, - rhs_variant, rhs_dfa, 0); + rhs_variant, rhs_dfa, 0)); - fprintf(stdout, "%zu\n", overlap); -*/ rhs_dfa = ARRAY_DESTROY(gva_std_allocator, rhs_dfa); lhs_dfa = ARRAY_DESTROY(gva_std_allocator, lhs_dfa); } // while From 1ca8d3537733a8ddad5b0be2820a43ab63e490b5 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 30 Apr 2026 22:19:29 +0200 Subject: [PATCH 626/704] Harmonize --- src/dfa.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/dfa.c b/src/dfa.c index 36d3289..c12d273 100644 --- a/src/dfa.c +++ b/src/dfa.c @@ -569,7 +569,8 @@ uniq_atomics(GVA_Allocator const allocator, next_end = MAX(next_end, j); } // if - if (reference[variant.start + i] == variant.sequence.str[j]) + if (i < variant.end - variant.start && + reference[variant.start + i] == variant.sequence.str[j]) { row_start = MIN(row_start, j + 1); next_end = MAX(next_end, j + 1); From 4185b3a51d8700be4495eda653b2019674301368 Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 1 May 2026 13:26:50 +0200 Subject: [PATCH 627/704] WIP: overlap set construction on DFAs --- src/dfa.c | 12 ++++++++---- src/main.c | 11 ++++++----- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/dfa.c b/src/dfa.c index c12d273..dfa8754 100644 --- a/src/dfa.c +++ b/src/dfa.c @@ -569,7 +569,7 @@ uniq_atomics(GVA_Allocator const allocator, next_end = MAX(next_end, j); } // if - if (i < variant.end - variant.start && + if (i < variant.end - variant.start && j < variant.sequence.len && reference[variant.start + i] == variant.sequence.str[j]) { row_start = MIN(row_start, j + 1); @@ -593,7 +593,11 @@ dfa_disjoint(GVA_Allocator const allocator, GVA_Variant const rhs_variant, uint8_t const rhs_dfa[static restrict 1]) { size_t const start = MAX(lhs_variant.start, rhs_variant.start); - size_t const end = MIN(lhs_variant.end, rhs_variant.end); + size_t const end = MIN(lhs_variant.end + 1, rhs_variant.end + 1); + if (end <= start) + { + return true; + } // if uint64_t* restrict lhs_atomics = uniq_atomics(allocator, start, end, len, reference, lhs_variant, lhs_dfa); uint64_t* restrict rhs_atomics = uniq_atomics(allocator, start, end, len, reference, rhs_variant, rhs_dfa); @@ -720,7 +724,7 @@ dfa_svg(FILE* restrict const stream, if (i < variant.end - variant.start && reference[variant.start + i] == variant.sequence.str[j]) { - fprintf(stream, "\n", j * 100 + 50 + 17, i * 100 + 50 + 17, j * 100 + 100 + 50 - 24, i * 100 + 100 + 50 - 24); + fprintf(stream, "\n", j * 100 + 50 + 18, i * 100 + 50 + 18, j * 100 + 100 + 50 - 24, i * 100 + 100 + 50 - 24); start = MIN(start, j + 1); next_end = MAX(next_end, j + 1); edge = true; @@ -740,7 +744,7 @@ dfa_svg(FILE* restrict const stream, fprintf(stream, "\n"); fprintf(stream, "\n", ((size - 1) % width) * 100 + 50, ((size - 1) / width) * 100 + 50); - fprintf(stream, "\n", ((size - 1) % width) * 100 + 50, ((size - 1) / width) * 100 + 50); + fprintf(stream, "\n", ((size - 1) % width) * 100 + 50, ((size - 1) / width) * 100 + 50); fprintf(stream, "%zu\n", ((size - 1) % width) * 100 + 50, ((size - 1) / width) * 100 + 50, size - 1); fprintf(stream, "\n"); } // dfa_svg diff --git a/src/main.c b/src/main.c index 7221667..5ff423e 100644 --- a/src/main.c +++ b/src/main.c @@ -796,7 +796,8 @@ all_main(int argc, char* argv[static argc]) gva_lcs_graph_uniq_atomics(rhs_graph, lhs.start, rhs.start, rhs.end, rhs_dels, rhs_as, rhs_cs, rhs_gs, rhs_ts); - size_t const dfa_overlap = dfa_max_overlap(gva_std_allocator, reference.len, reference.str, lhs, lhs_dfa, rhs, rhs_dfa, 1); + //size_t const dfa_overlap = dfa_max_overlap(gva_std_allocator, reference.len, reference.str, lhs, lhs_dfa, rhs, rhs_dfa, 1); + bool const disjoint = dfa_disjoint(gva_std_allocator, reference.len, reference.str, lhs, lhs_dfa, rhs, rhs_dfa); bool const overlap = bitset_intersection_cnt(lhs_dels, rhs_dels) > 0 || bitset_intersection_cnt(lhs_as, rhs_as) > 0 || @@ -813,12 +814,12 @@ all_main(int argc, char* argv[static argc]) gva_lcs_graph_destroy(gva_std_allocator, rhs_graph, false); rhs_dfa = ARRAY_DESTROY(gva_std_allocator, rhs_dfa); - if (overlap != (dfa_overlap > 0)) + if (overlap == disjoint) { fprintf(stderr, GVA_STRING_FMT " vs " GVA_STRING_FMT "\n", GVA_STRING_PRINT(trie_string(labels, entries[i].label)), GVA_STRING_PRINT(trie_string(labels, entries[j].label))); - fprintf(stderr, "ERROR: %zu\n", dfa_overlap); + fprintf(stderr, "ERROR\n"); return EXIT_FAILURE; } // if @@ -864,6 +865,6 @@ main(int argc, char* argv[static argc]) // return allele_main(argc, argv); // return index_main(argc, argv); // return supremal_main(argc, argv); - return overlap_main(argc, argv); - // return all_main(argc, argv); + // return overlap_main(argc, argv); + return all_main(argc, argv); } // main From 7fbded421fb0da212e3e3442742442ca8fd80fd0 Mon Sep 17 00:00:00 2001 From: jkvis Date: Sat, 2 May 2026 10:35:27 +0200 Subject: [PATCH 628/704] DFA disjoint without sets --- src/dfa.c | 110 +++++++++++++---------------------------------------- src/dfa.h | 4 +- src/main.c | 24 +++++++++++- 3 files changed, 49 insertions(+), 89 deletions(-) diff --git a/src/dfa.c b/src/dfa.c index dfa8754..5bd3593 100644 --- a/src/dfa.c +++ b/src/dfa.c @@ -1,6 +1,6 @@ #include // bool, false, true #include // NULL, size_t -#include // uint8_t, uint64_t, SIZE_MAX, UINT64_C +#include // uint8_t, SIZE_MAX #include // memset #include "../include/allocator.h" // GVA_Allocator @@ -524,103 +524,45 @@ dfa_max_overlap(GVA_Allocator const allocator, } // dfa_max_overlap -static uint64_t* -uniq_atomics(GVA_Allocator const allocator, - size_t const start, size_t const end, - size_t const len, char const reference[static restrict len], - GVA_Variant const variant, uint8_t const dfa[static restrict 1]) +bool +dfa_disjoint(GVA_Variant const lhs_variant, uint8_t const lhs_dfa[static restrict 1], + GVA_Variant const rhs_variant, uint8_t const rhs_dfa[static restrict 1]) { - size_t const width = variant.sequence.len + 1; - - uint64_t* restrict atomics = allocator.allocate(allocator.context, NULL, 0, sizeof(*atomics) * (end - start)); - if (atomics == NULL) - { - return NULL; // OOM - } // if + size_t const lhs_width = lhs_variant.sequence.len + 1; + size_t const rhs_width = rhs_variant.sequence.len + 1; - memset(atomics, 0, sizeof(*atomics) * (end - start)); + size_t const start = MAX(lhs_variant.start, rhs_variant.start); + size_t const end = MIN(lhs_variant.end + 1, rhs_variant.end + 1); - size_t row_end = 0; - size_t j = 0; - for (size_t i = 0; i <= variant.end - variant.start; ++i) + for (size_t i = start; i < end; ++i) { - size_t row_start = width; - size_t next_end = row_end; - uint8_t value = 0; - while (j <= row_end || value & DFA_INSERTION) + for (size_t j = 0; j < lhs_width; ++j) { - value = get(dfa, i * width + j); - - if (value & DFA_DELETION) + uint8_t const lhs_value = get(lhs_dfa, (i - lhs_variant.start) * lhs_width + j) & 0x3; + if (lhs_value == 0) { - if (variant.start + i >= start && variant.start + i < end) - { - atomics[i - (start - variant.start)] |= UINT64_C(1) << 63; - } // if - row_start = MIN(row_start, j); + continue; } // if - if (value & DFA_INSERTION) + for (size_t k = 0; k < rhs_width; ++k) { - if (variant.start + i >= start && variant.start + i < end) + uint8_t const rhs_value = get(rhs_dfa, (i - rhs_variant.start) * rhs_width + k) & 0x3; + if (rhs_value == 0) { - atomics[i - (start - variant.start)] |= UINT64_C(1) << (variant.sequence.str[j] % 64); + continue; } // if - next_end = MAX(next_end, j); - } // if - if (i < variant.end - variant.start && j < variant.sequence.len && - reference[variant.start + i] == variant.sequence.str[j]) - { - row_start = MIN(row_start, j + 1); - next_end = MAX(next_end, j + 1); - } // if - - j += 1; - } // while - row_end = next_end; - j = row_start; - } // for - - return atomics; -} // uniq_atomics - - -bool -dfa_disjoint(GVA_Allocator const allocator, - size_t const len, char const reference[static restrict len], - GVA_Variant const lhs_variant, uint8_t const lhs_dfa[static restrict 1], - GVA_Variant const rhs_variant, uint8_t const rhs_dfa[static restrict 1]) -{ - size_t const start = MAX(lhs_variant.start, rhs_variant.start); - size_t const end = MIN(lhs_variant.end + 1, rhs_variant.end + 1); - if (end <= start) - { - return true; - } // if - - uint64_t* restrict lhs_atomics = uniq_atomics(allocator, start, end, len, reference, lhs_variant, lhs_dfa); - uint64_t* restrict rhs_atomics = uniq_atomics(allocator, start, end, len, reference, rhs_variant, rhs_dfa); - if (lhs_atomics == NULL || rhs_atomics == NULL) - { - rhs_atomics = allocator.allocate(allocator.context, rhs_atomics, sizeof(*rhs_atomics) * (end - start), 0); - lhs_atomics = allocator.allocate(allocator.context, lhs_atomics, sizeof(*lhs_atomics) * (end - start), 0); - return true; // OOM - } // if - - bool disjoint = true; - for (size_t i = 0; i < (end - start); ++i) - { - if (lhs_atomics[i] & rhs_atomics[i]) - { - disjoint = false; - break; - } // if + if ((lhs_value & DFA_DELETION && rhs_value & DFA_DELETION) || + (lhs_value & DFA_INSERTION && rhs_value & DFA_INSERTION && + lhs_variant.sequence.str[j] == rhs_variant.sequence.str[k])) + { + return false; + } // if + } // for + } // for } // for - rhs_atomics = allocator.allocate(allocator.context, rhs_atomics, sizeof(*rhs_atomics) * (end - start), 0); - lhs_atomics = allocator.allocate(allocator.context, lhs_atomics, sizeof(*lhs_atomics) * (end - start), 0); - return disjoint; + return true; } // dfa_disjoint diff --git a/src/dfa.h b/src/dfa.h index 0fe5e8f..81cd214 100644 --- a/src/dfa.h +++ b/src/dfa.h @@ -34,9 +34,7 @@ dfa_max_overlap(GVA_Allocator const allocator, bool -dfa_disjoint(GVA_Allocator const allocator, - size_t const len, char const reference[static restrict len], - GVA_Variant const lhs_variant, uint8_t const lhs_dfa[static restrict 1], +dfa_disjoint(GVA_Variant const lhs_variant, uint8_t const lhs_dfa[static restrict 1], GVA_Variant const rhs_variant, uint8_t const rhs_dfa[static restrict 1]); diff --git a/src/main.c b/src/main.c index 5ff423e..73a9c58 100644 --- a/src/main.c +++ b/src/main.c @@ -553,7 +553,7 @@ overlap_main(int argc, char* argv[static argc]) dfa_svg(stdout, reference.len, reference.str, lhs_variant, lhs_dfa); dfa_svg(stdout, reference.len, reference.str, rhs_variant, rhs_dfa); - fprintf(stderr, "disjoint: %d\n", dfa_disjoint(gva_std_allocator, reference.len, reference.str, lhs_variant, lhs_dfa, rhs_variant, rhs_dfa)); + fprintf(stderr, "disjoint: %d\n", dfa_disjoint(lhs_variant, lhs_dfa, rhs_variant, rhs_dfa)); fprintf(stderr, "max_overlap: %zu\n", dfa_max_overlap(gva_std_allocator, reference.len, reference.str, lhs_variant, lhs_dfa, @@ -626,6 +626,26 @@ all_main(int argc, char* argv[static argc]) fprintf(stderr, "reference length: %zu\n", reference.len); +/* + GVA_Variant const lhs = {6100895, 6100898, {3, "GGG"}}; + GVA_Variant const rhs = {6100897, 6100899, {2, "CC"}}; + + uint8_t* lhs_dfa = dfa_from_alignment(gva_std_allocator, NULL, lhs.end - lhs.start, reference.str + lhs.start, lhs.sequence.len, lhs.sequence.str); + uint8_t* rhs_dfa = dfa_from_alignment(gva_std_allocator, NULL, rhs.end - rhs.start, reference.str + rhs.start, rhs.sequence.len, rhs.sequence.str); + + dfa_dot(stderr, reference.len, reference.str, lhs, lhs_dfa); + dfa_dot(stderr, reference.len, reference.str, rhs, rhs_dfa); + + fprintf(stderr, "disjoint: %d\n", dfa_disjoint(gva_std_allocator, reference.len, reference.str, lhs, lhs_dfa, rhs, rhs_dfa)); + + rhs_dfa = ARRAY_DESTROY(gva_std_allocator, rhs_dfa); + lhs_dfa = ARRAY_DESTROY(gva_std_allocator, lhs_dfa); + + gva_string_destroy(gva_std_allocator, reference); + + return EXIT_SUCCESS; +*/ + errno = 0; stream = fopen(argv[2], "r"); if (stream == NULL) @@ -797,7 +817,7 @@ all_main(int argc, char* argv[static argc]) gva_lcs_graph_uniq_atomics(rhs_graph, lhs.start, rhs.start, rhs.end, rhs_dels, rhs_as, rhs_cs, rhs_gs, rhs_ts); //size_t const dfa_overlap = dfa_max_overlap(gva_std_allocator, reference.len, reference.str, lhs, lhs_dfa, rhs, rhs_dfa, 1); - bool const disjoint = dfa_disjoint(gva_std_allocator, reference.len, reference.str, lhs, lhs_dfa, rhs, rhs_dfa); + bool const disjoint = dfa_disjoint(lhs, lhs_dfa, rhs, rhs_dfa); bool const overlap = bitset_intersection_cnt(lhs_dels, rhs_dels) > 0 || bitset_intersection_cnt(lhs_as, rhs_as) > 0 || From 629f4a355c2aafb0a2c17adcc19136e297835914 Mon Sep 17 00:00:00 2001 From: jkvis Date: Sat, 2 May 2026 13:39:30 +0200 Subject: [PATCH 629/704] Simpler seems faster --- src/dfa.c | 12 ++---------- src/main.c | 12 +++++++----- 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/src/dfa.c b/src/dfa.c index 5bd3593..a54f304 100644 --- a/src/dfa.c +++ b/src/dfa.c @@ -538,19 +538,11 @@ dfa_disjoint(GVA_Variant const lhs_variant, uint8_t const lhs_dfa[static restric { for (size_t j = 0; j < lhs_width; ++j) { - uint8_t const lhs_value = get(lhs_dfa, (i - lhs_variant.start) * lhs_width + j) & 0x3; - if (lhs_value == 0) - { - continue; - } // if + uint8_t const lhs_value = get(lhs_dfa, (i - lhs_variant.start) * lhs_width + j); for (size_t k = 0; k < rhs_width; ++k) { - uint8_t const rhs_value = get(rhs_dfa, (i - rhs_variant.start) * rhs_width + k) & 0x3; - if (rhs_value == 0) - { - continue; - } // if + uint8_t const rhs_value = get(rhs_dfa, (i - rhs_variant.start) * rhs_width + k); if ((lhs_value & DFA_DELETION && rhs_value & DFA_DELETION) || (lhs_value & DFA_INSERTION && rhs_value & DFA_INSERTION && diff --git a/src/main.c b/src/main.c index 73a9c58..2e605c3 100644 --- a/src/main.c +++ b/src/main.c @@ -627,16 +627,18 @@ all_main(int argc, char* argv[static argc]) fprintf(stderr, "reference length: %zu\n", reference.len); /* - GVA_Variant const lhs = {6100895, 6100898, {3, "GGG"}}; - GVA_Variant const rhs = {6100897, 6100899, {2, "CC"}}; + // 1505253:29:AGAGAGGGAGGGAGAGAGAGAGA + // 1505254:3:GGG + GVA_Variant const lhs = {1505253, 1505282, {23, "AGAGAGGGAGGGAGAGAGAGAGA"}}; + GVA_Variant const rhs = {1505254, 1505257, {3, "GGG"}}; uint8_t* lhs_dfa = dfa_from_alignment(gva_std_allocator, NULL, lhs.end - lhs.start, reference.str + lhs.start, lhs.sequence.len, lhs.sequence.str); uint8_t* rhs_dfa = dfa_from_alignment(gva_std_allocator, NULL, rhs.end - rhs.start, reference.str + rhs.start, rhs.sequence.len, rhs.sequence.str); - dfa_dot(stderr, reference.len, reference.str, lhs, lhs_dfa); - dfa_dot(stderr, reference.len, reference.str, rhs, rhs_dfa); + dfa_svg(stderr, reference.len, reference.str, lhs, lhs_dfa); + dfa_svg(stderr, reference.len, reference.str, rhs, rhs_dfa); - fprintf(stderr, "disjoint: %d\n", dfa_disjoint(gva_std_allocator, reference.len, reference.str, lhs, lhs_dfa, rhs, rhs_dfa)); + fprintf(stderr, "disjoint: %d\n", dfa_disjoint(lhs, lhs_dfa, rhs, rhs_dfa)); rhs_dfa = ARRAY_DESTROY(gva_std_allocator, rhs_dfa); lhs_dfa = ARRAY_DESTROY(gva_std_allocator, lhs_dfa); From 2df3636a4b1e02969bfeff2e61788005ace505c6 Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 4 May 2026 14:01:58 +0200 Subject: [PATCH 630/704] Sanity check --- src/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main.c b/src/main.c index 2e605c3..c0da81d 100644 --- a/src/main.c +++ b/src/main.c @@ -836,6 +836,7 @@ all_main(int argc, char* argv[static argc]) gva_lcs_graph_destroy(gva_std_allocator, rhs_graph, false); rhs_dfa = ARRAY_DESTROY(gva_std_allocator, rhs_dfa); + //if (overlap != (dfa_overlap > 0)) if (overlap == disjoint) { fprintf(stderr, GVA_STRING_FMT " vs " GVA_STRING_FMT "\n", From fbd191b4728868d912b786370d1fa11c8d69273d Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 4 May 2026 17:12:52 +0200 Subject: [PATCH 631/704] Suspicious --- src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.c b/src/main.c index c0da81d..4f54083 100644 --- a/src/main.c +++ b/src/main.c @@ -26,7 +26,7 @@ #include -#define LINE_SIZE 8194 +#define LINE_SIZE 4096 // #define REFERENCE_ID "NC_000022.11" // #define REFERENCE_ID "NC_000006.12" From b25a8a0bfcf54fb5afa18ff2d79d6cf381a63b4d Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 6 May 2026 15:34:31 +0200 Subject: [PATCH 632/704] Less states --- overlap.txt | 13116 +++++++++++++++++++++++++++++++++++++++++++++++++- src/dfa.c | 63 +- src/main.c | 10 +- 3 files changed, 13029 insertions(+), 160 deletions(-) diff --git a/overlap.txt b/overlap.txt index 9d4dd99..359faf6 100644 --- a/overlap.txt +++ b/overlap.txt @@ -1,135 +1,12981 @@ -TCTCTGG ref:0:7:TCTCTGTCTGG ref:0:7:TCTCTGCCTGG -TCTCTGG ref:0:7:TCTCTGTCTGG ref:0:7:TCTCTGCATGG -TCTCTGG ref:0:7:TCTCTGTCTGG ref:0:7:TCTCTGCGTGG -TCTCTGG ref:0:7:TCTCTGTCTGG ref:0:7:TCTCTGCTTGG -TCTCTGG ref:0:7:TCTCTGTCTGG ref:4:3:TGTATGG -TCTCTGG ref:0:7:TCTCTGTCTGG ref:4:3:TGTTTGG -TCTCTGG ref:0:7:TCTCTGTCTGG ref:5:2:GCAGGG -TCTCTGG ref:0:7:TCTCTGTCTGG ref:5:2:GCCAGG -TCTCTGG ref:0:7:TCTCTGTCTGG ref:5:2:GCCGGG -TCTCTGG ref:0:7:TCTCTGTCTGG ref:4:3:TGTCGGG -TCTCTGG ref:0:7:TCTCTGTCTGG ref:4:3:TGTTCGG -TCTCTGG ref:0:7:TCTCTGTCTGG ref:2:5:TTTGTCAGG -TCTCTGG ref:0:7:TCTCTGTCTGG ref:4:3:ATTCGGG -TCTCTGGC ref:0:7:TCTCTGTCTGG ref:6:2:CCGCGG -TCTCTGG ref:0:7:TCTCTGCCTGG ref:0:7:TCTCTGCATGG -TCTCTGG ref:0:7:TCTCTGCCTGG ref:0:7:TCTCTGCGTGG -TCTCTGG ref:0:7:TCTCTGCCTGG ref:0:7:TCTCTGCTTGG -TCTCTGG ref:0:7:TCTCTGCCTGG ref:4:3:TGTATGG -TCTCTGG ref:0:7:TCTCTGCCTGG ref:4:3:TGTTTGG -TCTCTGG ref:0:7:TCTCTGCCTGG ref:5:2:GCAGGG -TCTCTGG ref:0:7:TCTCTGCCTGG ref:5:2:GCCAGG -TCTCTGG ref:0:7:TCTCTGCCTGG ref:5:2:GCCGGG -TCTCTGG ref:0:7:TCTCTGCCTGG ref:4:3:TGTCGGG -TCTCTGG ref:0:7:TCTCTGCCTGG ref:4:3:TGTTCGG -TCTCTGG ref:0:7:TCTCTGCCTGG ref:2:5:TTTGTCAGG -TCTCTGG ref:0:7:TCTCTGCCTGG ref:4:3:ATTCGGG -TCTCTGGC ref:0:7:TCTCTGCCTGG ref:6:2:CCGCGG -TCTCTGG ref:0:7:TCTCTGCATGG ref:0:7:TCTCTGCGTGG -TCTCTGG ref:0:7:TCTCTGCATGG ref:0:7:TCTCTGCTTGG -TCTCTGG ref:0:7:TCTCTGCATGG ref:4:3:TGTATGG -TCTCTGG ref:0:7:TCTCTGCATGG ref:4:3:TGTTTGG -TCTCTGG ref:0:7:TCTCTGCATGG ref:5:2:GCAGGG -TCTCTGG ref:0:7:TCTCTGCATGG ref:5:2:GCCAGG -TCTCTGG ref:0:7:TCTCTGCATGG ref:5:2:GCCGGG -TCTCTGG ref:0:7:TCTCTGCATGG ref:4:3:TGTCGGG -TCTCTGG ref:0:7:TCTCTGCATGG ref:4:3:TGTTCGG -TCTCTGG ref:0:7:TCTCTGCATGG ref:2:5:TTTGTCAGG -TCTCTGG ref:0:7:TCTCTGCATGG ref:4:3:ATTCGGG -TCTCTGGC ref:0:7:TCTCTGCATGG ref:6:2:CCGCGG -TCTCTGG ref:0:7:TCTCTGCGTGG ref:0:7:TCTCTGCTTGG -TCTCTGG ref:0:7:TCTCTGCGTGG ref:4:3:TGTATGG -TCTCTGG ref:0:7:TCTCTGCGTGG ref:4:3:TGTTTGG -TCTCTGG ref:0:7:TCTCTGCGTGG ref:5:2:GCAGGG -TCTCTGG ref:0:7:TCTCTGCGTGG ref:5:2:GCCAGG -TCTCTGG ref:0:7:TCTCTGCGTGG ref:5:2:GCCGGG -TCTCTGG ref:0:7:TCTCTGCGTGG ref:4:3:TGTCGGG -TCTCTGG ref:0:7:TCTCTGCGTGG ref:4:3:TGTTCGG -TCTCTGG ref:0:7:TCTCTGCGTGG ref:2:5:TTTGTCAGG -TCTCTGG ref:0:7:TCTCTGCGTGG ref:4:3:ATTCGGG -TCTCTGGC ref:0:7:TCTCTGCGTGG ref:6:2:CCGCGG -TCTCTGG ref:0:7:TCTCTGCTTGG ref:4:3:TGTATGG -TCTCTGG ref:0:7:TCTCTGCTTGG ref:4:3:TGTTTGG -TCTCTGG ref:0:7:TCTCTGCTTGG ref:5:2:GCAGGG -TCTCTGG ref:0:7:TCTCTGCTTGG ref:5:2:GCCAGG -TCTCTGG ref:0:7:TCTCTGCTTGG ref:5:2:GCCGGG -TCTCTGG ref:0:7:TCTCTGCTTGG ref:4:3:TGTCGGG -TCTCTGG ref:0:7:TCTCTGCTTGG ref:4:3:TGTTCGG -TCTCTGG ref:0:7:TCTCTGCTTGG ref:2:5:TTTGTCAGG -TCTCTGG ref:0:7:TCTCTGCTTGG ref:4:3:ATTCGGG -TCTCTGGC ref:0:7:TCTCTGCTTGG ref:6:2:CCGCGG -TGG ref:0:3:TGTATGG ref:0:3:TGTTTGG -TGG ref:0:3:TGTATGG ref:1:2:GCAGGG -TGG ref:0:3:TGTATGG ref:1:2:GCCAGG -TGG ref:0:3:TGTATGG ref:1:2:GCCGGG -TGG ref:0:3:TGTATGG ref:0:3:TGTCGGG -TGG ref:0:3:TGTATGG ref:0:3:TGTTCGG -TCTGG ref:2:3:TGTATGG ref:0:5:TTTGTCAGG -TGG ref:0:3:TGTATGG ref:0:3:ATTCGGG -TGG ref:0:3:TGTTTGG ref:1:2:GCAGGG -TGG ref:0:3:TGTTTGG ref:1:2:GCCAGG -TGG ref:0:3:TGTTTGG ref:1:2:GCCGGG -TGG ref:0:3:TGTTTGG ref:0:3:TGTCGGG -TGG ref:0:3:TGTTTGG ref:0:3:TGTTCGG -TCTGG ref:2:3:TGTTTGG ref:0:5:TTTGTCAGG -TGG ref:0:3:TGTTTGG ref:0:3:ATTCGGG -GG ref:0:2:GCAGGG ref:0:2:GCCAGG -GG ref:0:2:GCAGGG ref:0:2:GCCGGG -TGG ref:1:2:GCAGGG ref:0:3:TGTCGGG -TGG ref:1:2:GCAGGG ref:0:3:TGTTCGG -TCTGG ref:3:2:GCAGGG ref:0:5:TTTGTCAGG -TGG ref:1:2:GCAGGG ref:0:3:ATTCGGG -GGC ref:0:2:GCAGGG ref:1:2:CCGCGG -GG ref:0:2:GCCAGG ref:0:2:GCCGGG -TGG ref:1:2:GCCAGG ref:0:3:TGTCGGG -TGG ref:1:2:GCCAGG ref:0:3:TGTTCGG -TCTGG ref:3:2:GCCAGG ref:0:5:TTTGTCAGG -TGG ref:1:2:GCCAGG ref:0:3:ATTCGGG -GGC ref:0:2:GCCAGG ref:1:2:CCGCGG -TGG ref:1:2:GCCGGG ref:0:3:TGTCGGG -TGG ref:1:2:GCCGGG ref:0:3:TGTTCGG -TCTGG ref:3:2:GCCGGG ref:0:5:TTTGTCAGG -TGG ref:1:2:GCCGGG ref:0:3:ATTCGGG -GGC ref:0:2:GCCGGG ref:1:2:CCGCGG -TGG ref:0:3:TGTCGGG ref:0:3:TGTTCGG -TCTGG ref:2:3:TGTCGGG ref:0:5:TTTGTCAGG -TGG ref:0:3:TGTCGGG ref:0:3:ATTCGGG -TGGC ref:0:3:TGTCGGG ref:2:2:CCGCGG -TCTGG ref:2:3:TGTTCGG ref:0:5:TTTGTCAGG -TGG ref:0:3:TGTTCGG ref:0:3:ATTCGGG -TGGC ref:0:3:TGTTCGG ref:2:2:CCGCGG -GCAG ref:2:2:AGAGGA ref:0:2:CCGCGG -AGTGGAGG ref:0:2:AGAGGA ref:0:8:AAAGGTTAGCGG -AGTGG ref:0:2:AGAGGA ref:1:4:GCGATTTG -AGTGGA ref:0:2:AGAGGA ref:1:5:GCGATTCCA -TGGAGGAA ref:0:8:TCCCTTTCCCAA ref:0:8:TCTTTCTCCCAA -AGTGGAGGAA ref:2:8:TCCCTTTCCCAA ref:0:8:AAAGGTTAGCGG -GTGGAGGAA ref:1:8:TCCCTTTCCCAA ref:0:4:GCGATTTG -GTGGAGGAA ref:1:8:TCCCTTTCCCAA ref:0:5:GCGATTCCA -TGGAGGAA ref:0:8:TCCCTTTCCCAA ref:0:8:TCCCTGGAGAAA -TGGAGGAA ref:0:8:TCCCTTTCCCAA ref:0:8:TCTCTTGCCCAA -AGTGGAGGAA ref:2:8:TCTTTCTCCCAA ref:0:8:AAAGGTTAGCGG -GTGGAGGAA ref:1:8:TCTTTCTCCCAA ref:0:4:GCGATTTG -GTGGAGGAA ref:1:8:TCTTTCTCCCAA ref:0:5:GCGATTCCA -TGGAGGAA ref:0:8:TCTTTCTCCCAA ref:0:8:TCCCTGGAGAAA -TGGAGGAA ref:0:8:TCTTTCTCCCAA ref:0:6:TCCCTGTCGA -TGGAGGAA ref:0:8:TCTTTCTCCCAA ref:0:8:TCTCTTGCCCAA -TCTGG ref:0:5:TTTGTCAGG ref:2:3:ATTCGGG -TCTGGC ref:0:5:TTTGTCAGG ref:4:2:CCGCGG -AGTGGAGG ref:0:8:AAAGGTTAGCGG ref:1:4:GCGATTTG -AGTGGAGG ref:0:8:AAAGGTTAGCGG ref:1:5:GCGATTCCA -AGTGGAGGAA ref:0:8:AAAGGTTAGCGG ref:2:8:TCCCTGGAGAAA -AGTGGAGG ref:0:8:AAAGGTTAGCGG ref:2:6:TCCCTGTCGA -AGTGGAGGAA ref:0:8:AAAGGTTAGCGG ref:2:8:TCTCTTGCCCAA -GTGGA ref:0:4:GCGATTTG ref:0:5:GCGATTCCA -GTGGAGGAA ref:0:4:GCGATTTG ref:1:8:TCCCTGGAGAAA -GTGGAGG ref:0:4:GCGATTTG ref:1:6:TCCCTGTCGA -GTGGAGGAA ref:0:4:GCGATTTG ref:1:8:TCTCTTGCCCAA -GTGGAGGAA ref:0:5:GCGATTCCA ref:1:8:TCCCTGGAGAAA -GTGGAGG ref:0:5:GCGATTCCA ref:1:6:TCCCTGTCGA -GTGGAGGAA ref:0:5:GCGATTCCA ref:1:8:TCTCTTGCCCAA -TGGAGGAA ref:0:8:TCCCTGGAGAAA ref:0:6:TCCCTGTCGA -TGGAGGAA ref:0:8:TCCCTGGAGAAA ref:0:8:TCTCTTGCCCAA -TGGAGGAA ref:0:6:TCCCTGTCGA ref:0:8:TCTCTTGCCCAA -CCCCACACCCCCAGGTGAG ref:0:19:CAACCCA ref:0:19:CCACCCA -CCGAGGGGCGAGAGGTCACCACTGCCATAGAGAGGCGGCCACCACTGCCATCGGAGGGGGGGG ref:13:50:GGTCACCACTGCCATCGGAGGGGGGGG ref:0:45:CCGAGGGGCGAGAGGCCACCAC +TCTCTGG ref:0:7:TCTCTGTCTGG ref:0:7:TCTCTGCCTGG 3 144 +TCTCTGG ref:0:7:TCTCTGTCTGG ref:0:7:TCTCTGCATGG 3 96 +TCTCTGG ref:0:7:TCTCTGTCTGG ref:0:7:TCTCTGCGTGG 3 132 +TCTCTGG ref:0:7:TCTCTGTCTGG ref:0:7:TCTCTGCTTGG 3 156 +TCTCTGG ref:0:7:TCTCTGTCTGG ref:4:3:TGTATGG 3 60 +TCTCTGG ref:0:7:TCTCTGTCTGG ref:4:3:TGTTTGG 3 72 +TCTCTGG ref:0:7:TCTCTGTCTGG ref:5:2:GCAGGG 2 72 +TCTCTGG ref:0:7:TCTCTGTCTGG ref:5:2:GCCAGG 2 36 +TCTCTGG ref:0:7:TCTCTGTCTGG ref:5:2:GCCGGG 2 72 +TCTCTGG ref:0:7:TCTCTGTCTGG ref:4:3:TGTCGGG 3 108 +TCTCTGG ref:0:7:TCTCTGTCTGG ref:4:3:TGTTCGG 3 60 +TCTCTGG ref:0:7:TCTCTGTCTGG ref:2:5:TTTGTCAGG 3 348 +TCTCTGG ref:0:7:TCTCTGTCTGG ref:4:3:ATTCGGG 2 72 +TCTCTGGC ref:0:7:TCTCTGTCTGG ref:6:2:CCGCGG 1 12 +TCTCTGG ref:0:7:TCTCTGCCTGG ref:0:7:TCTCTGCATGG 3 96 +TCTCTGG ref:0:7:TCTCTGCCTGG ref:0:7:TCTCTGCGTGG 3 132 +TCTCTGG ref:0:7:TCTCTGCCTGG ref:0:7:TCTCTGCTTGG 3 156 +TCTCTGG ref:0:7:TCTCTGCCTGG ref:4:3:TGTATGG 2 60 +TCTCTGG ref:0:7:TCTCTGCCTGG ref:4:3:TGTTTGG 2 72 +TCTCTGG ref:0:7:TCTCTGCCTGG ref:5:2:GCAGGG 2 72 +TCTCTGG ref:0:7:TCTCTGCCTGG ref:5:2:GCCAGG 3 36 +TCTCTGG ref:0:7:TCTCTGCCTGG ref:5:2:GCCGGG 3 72 +TCTCTGG ref:0:7:TCTCTGCCTGG ref:4:3:TGTCGGG 2 108 +TCTCTGG ref:0:7:TCTCTGCCTGG ref:4:3:TGTTCGG 2 60 +TCTCTGG ref:0:7:TCTCTGCCTGG ref:2:5:TTTGTCAGG 2 348 +TCTCTGG ref:0:7:TCTCTGCCTGG ref:4:3:ATTCGGG 1 72 +TCTCTGGC ref:0:7:TCTCTGCCTGG ref:6:2:CCGCGG 2 12 +TCTCTGG ref:0:7:TCTCTGCATGG ref:0:7:TCTCTGCGTGG 3 88 +TCTCTGG ref:0:7:TCTCTGCATGG ref:0:7:TCTCTGCTTGG 3 104 +TCTCTGG ref:0:7:TCTCTGCATGG ref:4:3:TGTATGG 3 40 +TCTCTGG ref:0:7:TCTCTGCATGG ref:4:3:TGTTTGG 2 48 +TCTCTGG ref:0:7:TCTCTGCATGG ref:5:2:GCAGGG 3 48 +TCTCTGG ref:0:7:TCTCTGCATGG ref:5:2:GCCAGG 3 24 +TCTCTGG ref:0:7:TCTCTGCATGG ref:5:2:GCCGGG 2 48 +TCTCTGG ref:0:7:TCTCTGCATGG ref:4:3:TGTCGGG 2 72 +TCTCTGG ref:0:7:TCTCTGCATGG ref:4:3:TGTTCGG 2 40 +TCTCTGG ref:0:7:TCTCTGCATGG ref:2:5:TTTGTCAGG 3 232 +TCTCTGG ref:0:7:TCTCTGCATGG ref:4:3:ATTCGGG 1 48 +TCTCTGGC ref:0:7:TCTCTGCATGG ref:6:2:CCGCGG 1 8 +TCTCTGG ref:0:7:TCTCTGCGTGG ref:0:7:TCTCTGCTTGG 3 143 +TCTCTGG ref:0:7:TCTCTGCGTGG ref:4:3:TGTATGG 2 55 +TCTCTGG ref:0:7:TCTCTGCGTGG ref:4:3:TGTTTGG 2 66 +TCTCTGG ref:0:7:TCTCTGCGTGG ref:5:2:GCAGGG 3 66 +TCTCTGG ref:0:7:TCTCTGCGTGG ref:5:2:GCCAGG 2 33 +TCTCTGG ref:0:7:TCTCTGCGTGG ref:5:2:GCCGGG 3 66 +TCTCTGG ref:0:7:TCTCTGCGTGG ref:4:3:TGTCGGG 3 99 +TCTCTGG ref:0:7:TCTCTGCGTGG ref:4:3:TGTTCGG 2 55 +TCTCTGG ref:0:7:TCTCTGCGTGG ref:2:5:TTTGTCAGG 2 319 +TCTCTGG ref:0:7:TCTCTGCGTGG ref:4:3:ATTCGGG 2 66 +TCTCTGGC ref:0:7:TCTCTGCGTGG ref:6:2:CCGCGG 1 11 +TCTCTGG ref:0:7:TCTCTGCTTGG ref:4:3:TGTATGG 3 65 +TCTCTGG ref:0:7:TCTCTGCTTGG ref:4:3:TGTTTGG 3 78 +TCTCTGG ref:0:7:TCTCTGCTTGG ref:5:2:GCAGGG 2 78 +TCTCTGG ref:0:7:TCTCTGCTTGG ref:5:2:GCCAGG 2 39 +TCTCTGG ref:0:7:TCTCTGCTTGG ref:5:2:GCCGGG 2 78 +TCTCTGG ref:0:7:TCTCTGCTTGG ref:4:3:TGTCGGG 2 117 +TCTCTGG ref:0:7:TCTCTGCTTGG ref:4:3:TGTTCGG 3 65 +TCTCTGG ref:0:7:TCTCTGCTTGG ref:2:5:TTTGTCAGG 2 377 +TCTCTGG ref:0:7:TCTCTGCTTGG ref:4:3:ATTCGGG 1 78 +TCTCTGGC ref:0:7:TCTCTGCTTGG ref:6:2:CCGCGG 1 13 +TGG ref:0:3:TGTATGG ref:0:3:TGTTTGG 3 30 +TGG ref:0:3:TGTATGG ref:1:2:GCAGGG 2 30 +TGG ref:0:3:TGTATGG ref:1:2:GCCAGG 2 15 +TGG ref:0:3:TGTATGG ref:1:2:GCCGGG 1 30 +TGG ref:0:3:TGTATGG ref:0:3:TGTCGGG 2 45 +TGG ref:0:3:TGTATGG ref:0:3:TGTTCGG 3 25 +TCTGG ref:2:3:TGTATGG ref:0:5:TTTGTCAGG 3 145 +TGG ref:0:3:TGTATGG ref:0:3:ATTCGGG 1 30 +TGG ref:0:3:TGTTTGG ref:1:2:GCAGGG 1 36 +TGG ref:0:3:TGTTTGG ref:1:2:GCCAGG 1 18 +TGG ref:0:3:TGTTTGG ref:1:2:GCCGGG 1 36 +TGG ref:0:3:TGTTTGG ref:0:3:TGTCGGG 2 54 +TGG ref:0:3:TGTTTGG ref:0:3:TGTTCGG 3 30 +TCTGG ref:2:3:TGTTTGG ref:0:5:TTTGTCAGG 2 174 +TGG ref:0:3:TGTTTGG ref:0:3:ATTCGGG 1 36 +GG ref:0:2:GCAGGG ref:0:2:GCCAGG 3 18 +GG ref:0:2:GCAGGG ref:0:2:GCCGGG 3 36 +TGG ref:1:2:GCAGGG ref:0:3:TGTCGGG 3 54 +TGG ref:1:2:GCAGGG ref:0:3:TGTTCGG 2 30 +TCTGG ref:3:2:GCAGGG ref:0:5:TTTGTCAGG 3 174 +TGG ref:1:2:GCAGGG ref:0:3:ATTCGGG 2 36 +GGC ref:0:2:GCAGGG ref:1:2:CCGCGG 1 6 +GG ref:0:2:GCCAGG ref:0:2:GCCGGG 3 18 +TGG ref:1:2:GCCAGG ref:0:3:TGTCGGG 2 27 +TGG ref:1:2:GCCAGG ref:0:3:TGTTCGG 2 15 +TCTGG ref:3:2:GCCAGG ref:0:5:TTTGTCAGG 3 87 +TGG ref:1:2:GCCAGG ref:0:3:ATTCGGG 1 18 +GGC ref:0:2:GCCAGG ref:1:2:CCGCGG 2 3 +TGG ref:1:2:GCCGGG ref:0:3:TGTCGGG 3 54 +TGG ref:1:2:GCCGGG ref:0:3:TGTTCGG 2 30 +TCTGG ref:3:2:GCCGGG ref:0:5:TTTGTCAGG 2 174 +TGG ref:1:2:GCCGGG ref:0:3:ATTCGGG 2 36 +GGC ref:0:2:GCCGGG ref:1:2:CCGCGG 2 6 +TGG ref:0:3:TGTCGGG ref:0:3:TGTTCGG 3 45 +TCTGG ref:2:3:TGTCGGG ref:0:5:TTTGTCAGG 3 261 +TGG ref:0:3:TGTCGGG ref:0:3:ATTCGGG 3 54 +TGGC ref:0:3:TGTCGGG ref:2:2:CCGCGG 1 9 +TCTGG ref:2:3:TGTTCGG ref:0:5:TTTGTCAGG 3 145 +TGG ref:0:3:TGTTCGG ref:0:3:ATTCGGG 2 30 +TGGC ref:0:3:TGTTCGG ref:2:2:CCGCGG 1 5 +GCAG ref:2:2:AGAGGA ref:0:2:CCGCGG 1 5 +AGTGGAGG ref:0:2:AGAGGA ref:0:8:AAAGGTTAGCGG 2 1320 +AGTGG ref:0:2:AGAGGA ref:1:4:GCGATTTG 2 100 +AGTGGA ref:0:2:AGAGGA ref:1:5:GCGATTCCA 2 270 +TGGAGGAA ref:0:8:TCCCTTTCCCAA ref:0:8:TCTTTCTCCCAA 12 10193232 +AGTGGAGGAA ref:2:8:TCCCTTTCCCAA ref:0:8:AAAGGTTAGCGG 4 696432 +GTGGAGGAA ref:1:8:TCCCTTTCCCAA ref:0:4:GCGATTTG 4 52760 +GTGGAGGAA ref:1:8:TCCCTTTCCCAA ref:0:5:GCGATTCCA 6 142452 +TGGAGGAA ref:0:8:TCCCTTTCCCAA ref:0:8:TCCCTGGAGAAA 5 36932 +TGGAGGAA ref:0:8:TCCCTTTCCCAA ref:0:8:TCTCTTGCCCAA 11 2503462 +AGTGGAGGAA ref:2:8:TCTTTCTCCCAA ref:0:8:AAAGGTTAGCGG 4 1020096 +GTGGAGGAA ref:1:8:TCTTTCTCCCAA ref:0:4:GCGATTTG 4 77280 +GTGGAGGAA ref:1:8:TCTTTCTCCCAA ref:0:5:GCGATTCCA 6 208656 +TGGAGGAA ref:0:8:TCTTTCTCCCAA ref:0:8:TCCCTGGAGAAA 4 54096 +TGGAGGAA ref:0:8:TCTTTCTCCCAA ref:0:6:TCCCTGTCGA 6 7728 +TGGAGGAA ref:0:8:TCTTTCTCCCAA ref:0:8:TCTCTTGCCCAA 11 3666936 +TCTGG ref:0:5:TTTGTCAGG ref:2:3:ATTCGGG 2 174 +TCTGGC ref:0:5:TTTGTCAGG ref:4:2:CCGCGG 1 29 +AGTGGAGG ref:0:8:AAAGGTTAGCGG ref:1:4:GCGATTTG 3 5280 +AGTGGAGG ref:0:8:AAAGGTTAGCGG ref:1:5:GCGATTCCA 4 14256 +AGTGGAGGAA ref:0:8:AAAGGTTAGCGG ref:2:8:TCCCTGGAGAAA 2 3696 +AGTGGAGG ref:0:8:AAAGGTTAGCGG ref:2:6:TCCCTGTCGA 3 528 +AGTGGAGGAA ref:0:8:AAAGGTTAGCGG ref:2:8:TCTCTTGCCCAA 4 250536 +GTGGA ref:0:4:GCGATTTG ref:0:5:GCGATTCCA 5 1080 +GTGGAGGAA ref:0:4:GCGATTTG ref:1:8:TCCCTGGAGAAA 1 280 +GTGGAGG ref:0:4:GCGATTTG ref:1:6:TCCCTGTCGA 2 40 +GTGGAGGAA ref:0:4:GCGATTTG ref:1:8:TCTCTTGCCCAA 4 18980 +GTGGAGGAA ref:0:5:GCGATTCCA ref:1:8:TCCCTGGAGAAA 2 756 +GTGGAGG ref:0:5:GCGATTCCA ref:1:6:TCCCTGTCGA 3 108 +GTGGAGGAA ref:0:5:GCGATTCCA ref:1:8:TCTCTTGCCCAA 5 51246 +TGGAGGAA ref:0:8:TCCCTGGAGAAA ref:0:6:TCCCTGTCGA 5 28 +TGGAGGAA ref:0:8:TCCCTGGAGAAA ref:0:8:TCTCTTGCCCAA 4 13286 +TGGAGGAA ref:0:6:TCCCTGTCGA ref:0:8:TCTCTTGCCCAA 6 1898 +CCCCACACCCCCAGGTGAG ref:0:19:CAACCCA ref:0:19:CCACCCA 11 35200 +CCGAGGGGCGAGAGGTCACCACTGCCATAGAGAGGCGGCCACCACTGCCATCGGAGGGGGGGG ref:13:50:GGTCACCACTGCCATCGGAGGGGGGGG ref:0:45:CCGAGGGGCGAGAGGCCACCAC 22 110499012 +C ref:0:1:TTGGGCCAATGAA ref:0:1:CTCGCGCGGCGATG 7 10 +TGATCA ref:0:6:CCGCGCGACCTCGCGC ref:0:5:CTGTCCT 2 270 +CGCATTTGGGGTC ref:1:12:TCATGCTAGACAT ref:0:13:AGCGTTAAACGTT 7 7327824 +ATATGCGCTA ref:0:10:AGGGTCAA ref:0:10:TATCACATTTAAGG 2 768 +TCCTC ref:0:3:GCA ref:0:5:CGACATACCTTACACA 1 28 +GTTTTCGACGAATT ref:0:14:CTTGGCTTCGCATTAG ref:0:14:TTAAGATTATCC 3 1568 +TCACCCGC ref:0:8:GGAAT ref:0:7:AATCGTG 6 27060 +ACAAGGC ref:0:7:TTGGTG ref:0:7:TCAGCG 4 1140 +CCC ref:0:3:GGCACA ref:0:3:GAAGTGTTGCCAGA 4 105 +GCA ref:0:3:CACTCTATGGCGG ref:0:3:ACGAGCAATGATCCT 5 96 +G ref:0:1:CTCAGATGTGT ref:0:0:TTTT 3 3 +CGTGTA ref:0:6:CTCCTGGACGTATACG ref:0:6:ACATAAATGCCAC 4 5248 +ACTTGCGGAAC ref:0:11:AGACTACT ref:0:11:CGGGCCTAA 3 18 +GTATATGTCCTG ref:0:12:GGCACGTCGCATAGC ref:0:12:TGCA 4 1008 +ACAGTAGTAGACG ref:0:13:GACCGGCTTTTACCT ref:0:13:TG 5 13040 +TACGTTCACG ref:0:10:AAACATAGAATTT ref:1:9:CCCCAAGCCCA 4 72048 +CT ref:0:2:ACACGGTAG ref:0:2:AGGAAGTTT 3 48 +AATACCTCGACCTAA ref:0:15:ATGTCAGTC ref:0:15:GTCGTCCCGAGATGAT 8 417312 +TCCTATAAGAAACA ref:0:14:GCTCTCGGA ref:0:14:TG 9 3933 +CAGCTCTGTGATG ref:1:12:CTCCC ref:0:13:TGATTTATCCGC 5 405 +CTATA ref:1:4:AGGGCG ref:0:5:GTTGTGAACCGATAA 2 1584 +CGTCTCTTG ref:0:9:AGTCCAGTAATGTAG ref:0:9:AGCTTCGCGAATTACA 7 2240 +GTCGACAAATGTTTG ref:0:15:CCA ref:0:14:CGGCATG 8 36 +T ref:0:1:ACAAC ref:0:1:CTATATACG 4 18 +AGC ref:0:3:GCGTGTCGCAC ref:0:3:ATACCATTT 3 450 +GGG ref:1:2:AACGATTTGAACA ref:0:3:ATCCAAACCAT 7 364 +CTAGCCGACAAAACTT ref:0:16:AGTTAGTA ref:0:16:TCGGCGGCCTG 8 819675 +GTTAAGC ref:0:7:AGTAGTGAA ref:1:6:TCCC 1 36 +CGGCACTGGTCGG ref:0:13:AAAGTAACAAC ref:0:13:TGGTCAGTTTCCCGAA 7 1449000 +GAAGC ref:0:5:AGAAAGT ref:0:5:CGCCTC 1 222 +TGCACAAATATCT ref:0:12:ATAAACAAGGTTCCG ref:0:13:ATCGGAACTTGAT 6 93960 +GGAATC ref:0:6:T ref:0:6:GGTCGGAATA 1 12 +TTAACAACGGA ref:0:11:GCGGTCGGGATGAAT ref:0:10:CGGGC 7 13716 +ATCA ref:0:3:TG ref:0:3:GCTACCGG 2 18 +CCTAGACACC ref:0:10:AAAAGAGTCTCACA ref:0:10:GACTCTGGGAGCCAGT 4 44520 +CTTCTTCAT ref:0:9:CAC ref:0:9:TTTTGTAACGGTC 3 828 +TTTCGGCGAGTTAAA ref:0:15:GCTAGTAC ref:0:15:CCGAGGGG 7 6912 +GACCCTAACTC ref:0:11:TA ref:0:8:GGTGTCCTGTTCT 2 22 +TAGGCGTAGAAAA ref:1:12:CGGATAGTG ref:0:13:AACTTTTGCGCTGC 6 79300 +TGGAGTGA ref:1:7:GCCT ref:0:8:GATACAGCCTATTG 5 1785 +A ref:0:1:CTGCTTG ref:0:1:GTACCT 3 8 +GAAGCT ref:0:6:CG ref:0:6:AGAGTCAGCC 2 21 +ACGGTCGC ref:0:8:CATGGCACG ref:0:8:TAG 3 90 +AAGTGTA ref:0:7:GG ref:0:7:GTCCGG 4 4 +GGGGCACCGAAGCCGC ref:0:16:CATGAC ref:0:16:GAACGT 9 936 +TCAAA ref:0:5:GACACCC ref:0:5:TTCTATCGA 2 938 +GGAAAAGACCTATCTT ref:0:16:GTTGCG ref:0:16:TGGACCCCAATTTCTC 7 79587 +CA ref:0:2:CCACTCATTTGC ref:0:2:AAA 1 36 +GACTAATATCTGTAT ref:1:14:AATTCC ref:0:15:TAATGATTCGCAGTGC 5 126 +AGCGGGCTCTACATGC ref:0:16:CATGTCCGTACAGGCC ref:0:16:TA 6 2664 +CCCAGCAGGAA ref:0:11:TGTCG ref:0:11:CCGGGGGTCTGTA 6 24920 +GGGC ref:0:4:CCT ref:0:4:ACGGCGGTGCTGGA 2 50 +CAGGTT ref:0:6:GTAGG ref:0:6:CCTCTCTTTCAATA 2 3291 +ATATA ref:0:5:CCC ref:0:5:TGGTAGTGGAAAAGT 1 1904 +G ref:0:1:TCGGT ref:0:1:ATAGGCGATAATGGC 3 10 +GT ref:0:2:TGTATCGTACACCAGC ref:0:2:TGGCTATTGTGTGC 7 52 +CTTCAATAACTCGTTT ref:0:16:GCTC ref:0:16:GCCCTCTTGG 10 155 +CCGACTCTCAGACA ref:0:14:TACCTCCGCACCAT ref:0:14:GTCCAACCAAGTC 5 3550 +GTTGCGCA ref:0:8:ATGAGCGGC ref:0:8:AGGATCGGTAG 4 1972 +CACCCAGGCTT ref:0:11:TTT ref:0:11:GAGAC 6 396 +G ref:0:1:TCAAATCCTCGGGTTC ref:0:1:AATTTACCGACAAC 6 3 +TAATCCAACGAC ref:1:10:TCGCG ref:0:11:TCGTT 6 144 +TCAACGGATA ref:0:10:A ref:2:7:TATAA 4 4 +TGATCATACTTCGG ref:0:14:CT ref:0:14:CTTGTGT 9 35 +G ref:0:1:AT ref:0:1:CGAGTCAATCCTTTT 2 6 +CGCACTAT ref:0:8:TTATAGG ref:0:8:CTACCCCCCATTC 3 42772 +CG ref:0:2:GGATTTG ref:0:1:TCCC 1 30 +ACTTCATCGTAA ref:0:12:GC ref:1:10:CGACGGTGGAGC 5 190 +AGC ref:0:2:GG ref:0:2: 1 3 +CA ref:0:2:ATCCGATA ref:0:2:GGAGGGGAGATGG 3 84 +TGGGCCAGTACACTTC ref:0:16:T ref:1:15:ACGTTGTGG 10 120 +TTGAACGCAACATAC ref:0:15:ATACAT ref:0:15:TGCTACGCATTG 7 38760 +CCGGTGCGTGCT ref:0:12:GGTC ref:0:12:TCTCACCCATGTG 4 4304 +CACGCGCTGATGCA ref:0:14:AAGAGGGGTC ref:0:13:CTGTATACGCATGT 5 21835 +TACTGGATTCATTTCT ref:0:16:CGGTGTTGTAGACCG ref:1:15:CGCTCACG 6 1728 +AGTCCGTCGCCTTC ref:0:14:TTGCG ref:0:14:AAACTCACACCAC 5 31603 +CATTTCTGCAGGGCAA ref:0:16:GAGCG ref:0:16:CTCACAAC 7 152 +CC ref:0:2:CGCGCCTCTG ref:0:2:GGTCCG 3 10 +TGCCGAGCAACAGGC ref:0:15:CG ref:0:15:GTAAAAA 9 912 +GTTAGTAC ref:0:8:TAACG ref:0:8:GGGAGAGTA 1 104 +T ref:0:1:GGAATGT ref:0:1:GCATGAGTTTTGTT 5 14 +TTAACTCCAACGTC ref:0:14:T ref:0:14:TCCTTAAAGACGAAG 6 1536 +CCCCGA ref:0:4:AATT ref:0:4:AACAGCCT 4 630 +TCGAGGTA ref:0:8:CTTGCTAA ref:0:8:G 4 360 +AGTAAGCCGGCAT ref:3:10:AGGATTGAACGA ref:1:12:CCTATGCATAGCTA 5 3420 +AAATTCCATCACCTC ref:0:14:AGACACTT ref:0:15:AAG 8 20496 +GAGGTGGCGTACCAAA ref:0:16:CCTGCGATGGACGC ref:0:16:G 8 750 +GAGTTTGTCTAT ref:0:12:TTAC ref:0:12:ACATCGC 7 1650 +CTCCCA ref:0:6:GTTTGGCTAATTAG ref:1:5:ATGTAAAT 6 75280 +GCACACTTGG ref:0:10:CGTTACTAAGCCGAAC ref:0:10:TCTTCCGCGTACAA 8 8600 +CTCATTGGAGCTAC ref:0:14:ATATGC ref:0:14:ACAAG 8 152 +CGG ref:1:1:AAGAC ref:0:3:CACTCGATCGACCCCA 3 3 +TCCGCTCCGGG ref:0:11:AATCCCTCTAAAGT ref:0:11:AAGCGG 4 9720 +ACCCCACTTGAACGCT ref:0:15:CTACGAA ref:0:16:GTATGTCAGTGTC 8 78410 +GATCCT ref:0:6:AG ref:0:6:CACTCCAAGGGTA 2 12 +CTG ref:0:3:TCC ref:0:3:AA 2 70 +TCCATTGTG ref:0:9:CGTGCGGC ref:0:9:GACCCTGGCGGGC 7 95680 +CGCGCGACTCA ref:0:11:CTT ref:0:11:GTG 8 527 +T ref:0:1:ATCGT ref:0:1:TCCAAGTGACGCCCA 3 4 +GATGCAACAATCT ref:0:12:AATCACT ref:0:13:CGAT 6 438 +GGCATCCGATGA ref:0:12:GCGGTCAACGGGGAG ref:0:12:CGA 4 6444 +A ref:0:1:CACGATCCCACGTGTT ref:0:1:GGGTAAGTATCGT 6 9 +GCTGATTTAAGCTT ref:0:14:CGTATGGTTAATC ref:0:14:AGCGG 3 15 +GGAAACATTTAAAGCG ref:0:16:TCGGGCCC ref:0:16:TGCTAGTTCTTGAA 8 4590 +GTGTACGTTATTTC ref:1:12:GCCTATGG ref:0:14:TTACCGCCC 4 7920 +ACGTGGACCATTGG ref:0:14:C ref:1:13:TACATTTCACTCCCC 7 1335 +TTCGGAACCT ref:0:10:TCCAATGTC ref:0:9:GGTCGCGC 3 1728 +ATCTACCTGAGCGT ref:1:10:TTCATTGTGGAT ref:0:14:GCG 4 1144 +TCGGCCGTAACATG ref:0:14:A ref:0:14:AACAACGAAACGCGGC 7 17955 +CGTT ref:0:4:GCCATGTCG ref:0:4:CCGTCGTAGC 3 28 +CGGCATATGGCT ref:2:10:TCGTCTTATTAGTG ref:0:12:TTGAAGTT 4 3075 +AATGCGTATATTTGAC ref:0:16:GCGTCAAAG ref:0:16:CCCC 9 1377 +CA ref:1:1:T ref:0:2:G 1 6 +TATTGTGGGCCACGT ref:0:15:AAG ref:0:15:ACAGCCTTGTTA 9 1354 +CCTGG ref:0:5:GATAGCTTACACAA ref:0:5:ATT 5 9060 +AGAGTGCGGAATT ref:0:13:CCCGGGTAGTA ref:2:9:AACTAC 5 499624 +ACCTTATTTGTCTT ref:0:14:GCTCCGCTCATGC ref:0:14:CGGCAA 8 30240 +CGAAT ref:0:4:TGGTTCTCCCTGA ref:0:5:GGTTGGCAATGAAA 5 152 +G ref:0:1:GCATGCGTAGAT ref:0:1:TGTGCT 4 8 +GACCCCACC ref:0:9:CTCGGTCG ref:0:9:CCGCAATGTA 7 71750 +AGACCTAAAG ref:0:8:GACAAGTTT ref:0:10:CTTC 3 92 +CAGCCCTGA ref:0:9:TTTGCAG ref:0:9:TTTAT 8 7742 +TATGG ref:0:5:GTAACGTGTAAGATA ref:0:5:GAATAAGGACAAAC 4 16 +AAGGT ref:0:5:G ref:0:4:TCCTGCGCA 2 30 +CGG ref:0:3:TTCAT ref:0:3:AGTCAGTGATCACC 3 6 +GATA ref:0:4:TCG ref:0:4:TGTGTCT 3 100 +TG ref:0:2:TATCCTAAATGT ref:0:2:TCATTGTCTTC 4 12 +AATGCCC ref:0:7:CTCGAAATCAAG ref:2:5:CGGCC 2 864 +AAGAAAG ref:0:7:AGAAAATTGAAGG ref:0:7:GCCCAGA 2 8600 +CACTGTGTACAGT ref:1:12:CGCGAAATGA ref:0:13:ATCCTG 5 3264 +AATA ref:0:4:TGTCAATT ref:0:4:CAATGGTTCGGAATGC 2 18 +G ref:0:1:TTTCACACGCCTT ref:0:1:CA 2 3 +TATC ref:0:4:AATTCG ref:0:4:GCCTCAATAGCC 1 28 +ATAGATCAAATGACT ref:0:15:CAAAGTGGTTCGTA ref:0:15:TT 7 42 +CGCTG ref:0:5:TTATCCGCCAGAACT ref:0:5:GCGGAATT 4 600 +ATAA ref:0:4:GGTCCATCGGC ref:0:4:T 2 42 +AAGGTAAAGAGGA ref:0:13:CCGG ref:0:13:CCT 12 3150 +CGAGG ref:0:5:TAGCTACGAT ref:0:5:TGTCAAG 4 578 +ATCA ref:0:4:TACAAA ref:0:4:GGTTCAATTTTG 2 84 +T ref:0:1:TTTATTGCATC ref:0:1:AGCACCGGAA 5 66 +CA ref:0:2:CCACG ref:0:2:GGCAACGGATCAT 2 14 +CGGGCGCTGCGGCTAG ref:0:16:TACACTTGATCGT ref:0:16:CTTGC 10 14208 +TGCCGA ref:0:6:CGGATGAGTCAGG ref:0:6:GATAGGACGC 5 731 +CG ref:0:2:GCTGG ref:0:2:TCCTACAACTCC 1 70 +CCTA ref:0:4:CTAATGATTAATAGG ref:0:4:CAT 2 475 +AGCTGTAGGGCGG ref:0:11:GGCCGCGGCCATT ref:0:13:CGTGCATCCACGT 4 2295 +CGCACCCCCCTGCTGA ref:0:16:GTGTTCGTATA ref:0:16:AGGGGAGAAT 11 40937 +CTGT ref:0:4:AGG ref:0:4:GTGGGAGATGTGCTCG 3 828 +AACTA ref:0:5:TGGTGTCGTATC ref:0:5:C 2 28 +CAATCGGGGCAAG ref:1:12:TGGAGCCTTTCA ref:0:13:CAA 5 728 +CTGTTAAAACGCTCTT ref:0:16:G ref:0:16:TGCAGAAGAG 9 6 +AA ref:0:2:GGGTTCT ref:0:2:AAGAAAACCGC 3 540 +GGTTGCCA ref:0:8:ATGGCTCGGCCCACTC ref:0:8:CTTC 1 162 +CTTCGACAAT ref:0:10:CGCCTG ref:0:10:A 5 39 +ACCCCTT ref:0:7:TAATAGGC ref:0:7:CGCTCTAA 4 6732 +CGTGTAGAG ref:0:9:CCGTCCTGGC ref:0:9:GTCGGGTATGCTGG 3 372 +GTAGAT ref:0:6:CA ref:0:6:ATGCTGCAGCG 3 88 +CCCT ref:0:4:ACTGTAACC ref:0:3:ACC 1 4 +TCT ref:0:3:GCC ref:1:2:CACTGAAGTCAA 1 28 +CGCCCTGTCC ref:0:10:AGTAGGCTT ref:0:10:CTCAA 5 4224 +TCAGACGG ref:0:8:AAC ref:0:8:CGTCGCC 2 13 +CATGAGGGAAA ref:0:11:AT ref:0:11:TCCCCGACGGGATA 2 84 +CTCATTTA ref:0:8:AAGGGGC ref:0:7:TCGGGTCAGAGTGG 2 43 +TTTGTGTCT ref:1:7:ACTATGGATA ref:0:9:GGACA 3 8 +AGGACT ref:0:6:ATAGTATTATAGTGC ref:0:6:ACTTAAG 5 1092 +CCAGACCCGAGTATT ref:0:15:TCACAGCGGCC ref:0:15:GCTA 6 138 +A ref:0:1:GAG ref:0:1:GAAATC 1 3 +AGCTGGCGGA ref:0:10:AGAGAAGGTGCGAT ref:0:10:CCGGCACTTTTTAGGC 4 38665 +GAAAGGGCCACCC ref:1:12:TCATGAAG ref:0:13:TTTGACTACGCAAT 7 3567 +CA ref:0:2:TCAACC ref:0:2:TCCATGTATTT 2 8 +GGAGATCCCTGTCGA ref:0:15:ACGTCCTTCTTT ref:0:15:CTAATCGAACGAA 3 3996 +ACCTT ref:0:4:GTCCATGG ref:0:5:CGG 3 48 +ACAA ref:0:4:TGTGCGTGA ref:0:4:TTACTAAAAACC 3 250 +C ref:0:1:ACTATCATA ref:0:1:AG 1 6 +GGCAAATAG ref:2:7:TC ref:0:9:ATGAAAACTCTAA 3 504 +A ref:0:1:GAGCTGCCTTGGT ref:0:1:CTGCCATCGG 5 1 +A ref:0:1:GTCAACTAT ref:0:1:TTGCAATCA 5 9 +GATCCAGATAACCG ref:0:14:ATCGC ref:0:14:GTTGCTTTCCACA 6 45848 +AATCGCGA ref:0:8:GGATTGCTTTGGAACC ref:1:6:GGAGTCCT 3 140 +A ref:0:1:CTCGCT ref:0:1:TCATG 3 7 +CACATTGTATTT ref:0:12:TTAAGTGGAATCAG ref:0:12:CTGTA 5 6492 +TCAAAGTTTAACCTGA ref:0:16:TG ref:0:16:GCGG 12 66 +T ref:0:1:A ref:0:0:GGAC 1 2 +GCGCGATGGTCGCAC ref:0:15:CCGGTTCT ref:0:15:A 8 294 +GGTG ref:0:4:A ref:0:4:AACGAGTCCCGT 1 5 +GGT ref:0:3:TCTC ref:0:3:TTTGCCGA 2 14 +CTAGAAT ref:0:7:TTACA ref:0:7:T 4 40 +CGGTATTGTACG ref:0:12:TTGAT ref:0:12:A 8 24 +CTGCCGGAAAGGGCG ref:0:15:TCACATCGGGAC ref:0:15:CGTGGGT 7 10604 +TGCATTCCACTG ref:0:12:G ref:0:12:ATATATAC 5 2 +GTTTGGT ref:0:7:CC ref:0:7:TACATCAGTGAC 5 2232 +GCTTAATAGC ref:1:9:TGTGTCGT ref:1:9:TTATTAGT 4 230 +CTCAGG ref:1:5:GAACAAGCATATCTT ref:0:6:TTGATTG 3 2772 +AACACGTTCGTA ref:0:12:ACACG ref:0:9:CGCTCTGCATC 2 648 +ATCACCCACCTTGAA ref:0:15:TCAGTT ref:0:15:GAGGGCGA 8 32832 +CGTCACC ref:0:5:AGAGATTTC ref:1:6:GAGT 3 144 +TCTTAAGGA ref:0:9:GG ref:0:9:AAGCACAG 5 17 +ACATTT ref:0:6:CTAGGCCGGACGGTCA ref:0:6:A 2 112 +CCGACATACAAGAAG ref:0:15:GCCCTTATAAATCTT ref:0:15:GTGGAGTCT 7 4745 +GCCTGGGTTGGTAA ref:0:14:ATCCCCGCGTA ref:0:14:CATAAGAGC 7 12480270 +ACCTGC ref:0:5:TAGGA ref:0:6:AACCGGATCTTGG 3 350 +AGTGCTAA ref:0:8:AAATCCTTATCATATC ref:0:8:CCAGC 1 252 +GACT ref:0:4:GTTATGAT ref:0:4:GGAGCTGT 2 28 +GCGTGT ref:0:6:AAGAAAGGCGTG ref:0:6:A 2 21 +TTAATT ref:0:6:AC ref:0:6:TGGCG 5 1414 +AAACT ref:0:5:CGCAC ref:0:5:AG 3 180 +CTAGCACC ref:4:4:ATTAATCAC ref:1:7:ATCACAATGCAG 3 300 +AACTGAAATTTAATG ref:0:15:CCGCATGGCCG ref:0:15:TGCCGAAACAGCTCCA 11 78215895 +CGAGATGGCCGACAC ref:0:15:CGCCT ref:0:15:CCTGTTGCT 10 142065 +GTACCAGG ref:0:8:ACTCTGGAGTC ref:0:8:AACTTCAAGCAATTC 6 748 +TTGCCTT ref:0:7:CTTGGG ref:0:7:A 4 184 +TT ref:0:2:GTG ref:0:2:GACCTTCCATCC 1 12 +CGCTGTACTG ref:0:10:GTACAACA ref:0:10:TATCACGTTTA 7 9546 +TT ref:0:2:GCTGAATG ref:0:2:CGGCCAACGGAA 5 91 +TTGCA ref:0:5:GAGACATTGCTAG ref:0:5:GTTACG 2 6 +TGCCCGCTCC ref:0:10:TA ref:0:10:ACCA 8 2301 +CTGACA ref:0:6:AGCTTCGG ref:0:6:GACTACGCTTT 4 330 +ACTTT ref:0:5:AAG ref:0:5:ATCAC 4 540 +CCCATCA ref:0:7:TC ref:0:7:CTACGG 4 30 +ACCCAG ref:0:6:TACATGACTAAGTC ref:0:4:TGGATC 3 102 +AAGATCAATGACACG ref:0:15:CTTTAAAGCAGGG ref:0:15:A 8 22267 +GATGGGTT ref:0:8:TAAGAGGGGCAT ref:1:7:TGTGTCAAAAATC 2 84 +C ref:1:0:ATA ref:0:1:TCCGTGTACA 2 3 +TATACTTGTTCTG ref:1:12:ACCAAACGATACTGT ref:0:13:TCTGAATGAGTTCCTC 4 15360 +CAAAGG ref:0:6:TTTCTGCCC ref:0:6:T 5 147 +GCGATGTGGACA ref:0:12:AATTACTACTCCTTGA ref:0:12:TTCCAGCGCTTGAG 8 13248 +CTATACATAAAAGGCA ref:0:16:AGTGGTCCAATAGAC ref:0:16:CG 8 28104 +CGCGGACCTACAGGTG ref:0:16:ATTACCCG ref:1:15:CGTTTAGGAT 7 31900 +ACC ref:0:3:TTACCGAC ref:0:3:TTTA 2 3 +G ref:0:1:CTTTAGATCA ref:0:1:AATACGCC 3 1 +CAACTTGATATT ref:0:12:ACTGCATAGCTTC ref:0:12:ACAG 4 100 +AGCTTTTCTCGACGCT ref:0:15:AACCG ref:0:16:TGTGCTG 8 11492 +GAGGAGCCGCAG ref:0:12:GGCC ref:0:12:TCTGAGCTTAAAT 6 167706 +CTTGATGCATC ref:0:11:GTAGTAAATCACATGA ref:0:11:AACCCGCCCC 4 609840 +CACACGATAG ref:0:9:AGCGCGACT ref:0:7:GGCGTGGAA 4 838 +TCTACGAGT ref:0:9:T ref:0:9:CCCACTTGCC 5 1158 +TTCGGTGGCG ref:0:10:CGACATC ref:0:10:TTTCCCTCCCT 5 3750 +TATCAAG ref:0:6: ref:0:7:GGAAC 4 55 +GTTGGCAGCGTC ref:0:12:AAGA ref:0:12:CCTAA 8 288 +AGG ref:0:3:GCCCGAAA ref:0:3:TCACTATCAC 3 54 +GATCACG ref:0:7:TGACGA ref:1:5:CCTT 2 6 +TCATTA ref:0:6:GGGTATAA ref:0:6:TA 2 20 +TATTATTTCGTCCA ref:0:14:AGAAG ref:0:14:ACCATGAGAAGA 11 228993 +CATGATTTCCGAT ref:0:13:CG ref:0:13:TAATTTTG 6 160 +GTTGGGCGAATCT ref:0:12:CATGAGTAGATG ref:0:13:GGCTGCCA 6 395604 +GGCTG ref:0:5:GTCACGT ref:0:5:TACGGT 2 25 +CAGAT ref:0:5:CCCTTTCACC ref:0:5:GA 2 349 +ATGTCAGAG ref:1:7:GAGGAC ref:0:9:CATCCGGCA 2 74 +GCAAC ref:0:5:GGCA ref:0:5:A 2 8 +AAGTC ref:0:3:GCCCA ref:0:5:AGTTTCCGGCCGACAC 1 252 +TTGTGTCT ref:0:8:CGGAGGTTCTA ref:0:8:GCGGCAGGAA 5 14274 +GT ref:0:1:C ref:0:2:GGGGCGGTACAC 1 12 +GTCTATATACAACAA ref:0:15:CCAGGCGGTGA ref:0:15:ACA 10 528 +TGGGTCCCTGGGCCA ref:0:15:CTG ref:0:15:AA 11 144 +CCTTATTAAGA ref:0:11:ATTTCAACG ref:0:11:GTA 5 1292 +ACCAGATGCCTGCTG ref:0:15:GCAAT ref:0:13:TCTATCT 7 720 +CGGGCTCCTAGCGGG ref:0:15:TTTGACGCAAA ref:0:15:CTGAA 11 206402 +GCCATGATGC ref:0:9:CCTCAGCAAGT ref:0:10:G 3 75 +AACCTGTATACACTG ref:1:13:TCGATCCGTGTCAA ref:0:15:ACCCGTCTTGCG 6 20592 +ACAACGCTGCGATC ref:0:14:CGAAT ref:0:14:TCGAAGAGC 8 1482 +CCTGATT ref:0:7:GTGGCTCTGAAGAC ref:0:7:CATGTAGGGTGC 3 744 +G ref:0:1:AAGGTT ref:0:1:GCCGATCG 2 6 +TCT ref:0:3:TG ref:0:3:ATGGCACCCCCC 2 116 +CAG ref:0:3:CTCCCAA ref:0:3:GCCATT 2 72 +ACCTAGGTATACC ref:0:13:A ref:0:13:TGAATAGACGGCT 6 200 +ATAGTTC ref:0:7:CTACAGCTATTCAGT ref:0:7:GATTT 1 20 +GAGTTGCCTA ref:0:10:TT ref:0:10:CAGGTT 6 81 +ATTTTCGAGAA ref:0:11:TTGGGTTCTAT ref:0:11:TATGCGCAC 5 11802 +GATATCA ref:0:7:GCCTGTAAGGACC ref:1:6: 3 610 +AAAACTCTGC ref:0:10:CAC ref:0:10:AAACCTCG 3 680 +GTGAGCA ref:0:7:GGGCTATGAA ref:0:7:GA 2 150 +TTCAAGA ref:0:7:GACCTATCC ref:0:7:TA 3 36 +CAACAACAGCGACTA ref:0:15:CCAGGGGATGCT ref:0:15:GAGAGAGCC 6 8848 +TC ref:0:2:GCT ref:0:2:AACTAGCA 1 3 +GAC ref:0:3:GGTACCAAG ref:0:3:TTAATTGTA 1 4 +ACTAGC ref:0:6:TATTCAGGCTTGATTT ref:0:6:TCTTAGCGGTGAGTG 6 64 +CTCCCTATAAAT ref:0:12:TCCCTTATGGA ref:2:10:CATATCTTGATGTA 5 38048 +TTCTTGGGCCTCCG ref:0:14:ACCGTTATTGG ref:0:14:AA 10 1440 +CCGCTCCGGGATCGA ref:0:15:GTACTTG ref:0:15:GATGATCTGAGCGT 8 162 +GTACTGGACG ref:2:8:GCAGCCTTAA ref:1:4:CAATCC 2 1134 +GGCG ref:0:4:AGGAACGG ref:0:3:TCGCCAACT 2 34 +ACTATAGTGGGCTCA ref:0:15:GGCGAGCGTTTC ref:0:15:G 8 12 +TCGG ref:0:4:CACGACAC ref:1:3:CGCTAGGGTTGAG 2 650 +CTGAT ref:0:5:GTAATAGTCTC ref:0:5:TCTC 4 640 +GACTTGTAACCTGAG ref:0:15:AATCC ref:0:15:GTCGACATGCTGGAGT 5 1680 +TTAAATGGAACCCA ref:0:13:GAATAAT ref:1:13:CGTAATAGACAC 6 8320 +AAG ref:0:3:TGATAACGT ref:0:2:GTGGGGTTATTT 3 39 +GGGAAGCGG ref:0:9:TACCTAGTGCCATC ref:0:9:CCATTA 7 4050 +ATATCGT ref:0:7:CGTCCCTGGAGGCACG ref:0:7:CCC 5 4248 +CC ref:0:2:CAGATTGCGC ref:0:2:AATGCGTGGATCTGT 5 3 +ATTGCGCGA ref:1:8:GGT ref:0:9:TCCCAAGC 3 600 +CATGCAGGCGGAACTG ref:0:16:TGATTGATA ref:0:16:AACGCAACACTGCTTC 5 23635 +CATCTGTGATCTAAGC ref:0:16:CTGAA ref:0:16:GCTAGGTATG 8 3312 +GACG ref:0:4:T ref:0:4:AAACC 2 90 +GGAGG ref:0:5:ACCT ref:0:5:ACTGGTATGTCGCTA 3 10 +CCTGGGCGCA ref:0:10:CTGGGTAACTGGACAA ref:0:10:TTCGCCAATTT 3 864 +TCAAAGCGCTCCC ref:0:13:AG ref:0:13:CATTTCGCTCTTCCTA 4 204 +GG ref:0:2:GGTCGCGGTCGCG ref:0:2:CCCTGTC 4 168 +AGTCTCGA ref:0:8:GCGG ref:0:8:TGTGGACCGCGG 4 352 +C ref:0:1:ACATAATG ref:0:0:TGTTAGG 1 1 +GCCAGCAC ref:0:8:CTCGTATACGTCCC ref:0:8:GTC 3 152 +CCAAACCGCTAGGT ref:1:13:TTCAGCCCTAA ref:0:14:TATC 5 30 +TTACACC ref:0:7:TGG ref:0:7:TACTATATTGTG 5 7644 +TCAGAAACA ref:0:9:TGTGTACCG ref:0:9:GGCTGTGGC 7 86132 +GCGAAACCAAGTA ref:0:13:ATTTCTATGCT ref:0:11:CCAC 7 11086 +TGAAAC ref:0:6:CTA ref:0:6:TTTTGGTAG 3 492 +C ref:0:1:CAAAACGCC ref:0:1:AT 1 12 +TTCTTATG ref:0:7:GGT ref:0:8:AGAAATCTA 4 798 +GCCTA ref:3:2:AAAG ref:0:5:CCCTG 1 48 +GTTTCGA ref:0:7:GCAGGTGCT ref:0:7:GTGTTCCATACG 3 4369 +CCTCG ref:0:4:GTGACGATTACACCA ref:0:5:CTTTTT 2 6090 +C ref:0:0:GATAATG ref:0:1:TAAAACTCAGT 4 2 +CTACGGATAAGCTTT ref:0:15:AG ref:0:15:AGGTATATTAA 7 102 +ACATG ref:0:5:TTCCCGCGATTGACAC ref:0:5:CTACGGG 3 836 +GAAC ref:0:4:ATAGAACTTCGT ref:0:4:CGTACCAGTTGA 3 30 +TATTA ref:0:5:CGAGC ref:0:5:TC 4 450 +CTGTTCC ref:0:7:TCCCCGCCAGAGA ref:0:7:GTAGGGT 2 209 +GA ref:0:2:CC ref:0:2:AACTCTCCGCACC 2 6 +GAG ref:0:2:TAGCGACTAAA ref:0:3:CTAA 3 80 +GTCCCTTCCTCCAT ref:0:14:AGT ref:1:13:ACA 10 270 +TCC ref:0:3:TTATTCTTTAGG ref:0:3:CAAGATA 3 440 +TATCCGCCGTAT ref:0:12:TG ref:0:12:CTGGGGAAG 8 6100 +GGCGGTGGC ref:0:9:ATCTCCCCG ref:0:9:TGTAAACGCTTCCC 7 113568 +TATGCGAAGGACC ref:0:13:C ref:0:13:AAACCCAAGTTGAA 6 1920 +GTGGATAACCCTTCCT ref:0:16:GGTGATT ref:0:16:CCTCCACAG 6 6786 +CACGTATCAAG ref:0:10:GGGTGGTAT ref:0:11:CGTCTCACATTCAGAA 4 67328 +ATAGGCGATGT ref:0:11:CGAAGTGGACAT ref:0:10:CAGAGTATAAA 6 3648 +GGTCAGCTG ref:0:9:CACGAGACAGGTGA ref:0:9:T 2 12 +ACGTTACAGA ref:0:10:CCGCGCTGTCAGACA ref:0:10:TTTCATTTTAAT 3 12040 +TCTTTTAGATTTCC ref:0:14:TGATACGGACCG ref:0:14:GTCCATAATGCTT 4 2940 +TATATGCTAAGATA ref:0:14:TCC ref:0:13:AGTTACTAAGGGAGG 4 1620 +GTGGAAAATGACG ref:0:13:CAG ref:0:13:GCAGCAGGCTACGG 7 245760 +G ref:0:1:ATGAGGCACAGGCG ref:0:1:CTAAGACCTTGAAC 6 12 +TCGTATGGGC ref:0:10:TAATGCGGGGA ref:0:10:CATCAGTGTGCAA 4 5370 +TAACCAGCGGC ref:1:10:GACAACTCG ref:0:11:CG 5 2696 +ATGTCT ref:0:6:TTAAGC ref:0:5:CGAAGTGAT 1 14 +CAATGCCAA ref:0:7:AAGTCT ref:0:9:AAATCAAGTCCTG 3 308 +GGC ref:0:3:AT ref:0:3:AAAGGCCA 1 20 +AATGCCCCCGTATTTA ref:0:16:C ref:0:16:ACATTTAAGGGGTT 9 5115 +GCTGTTTTGTTGA ref:0:13:CTCTT ref:0:13:ACAAG 8 17640 +ATAACTCAACCTC ref:0:13:TGCGGGACTTATGT ref:0:13:TGATTGAGCAAACC 5 281400 +GTGGATTGCAACC ref:0:13:ATGTGCC ref:0:13:TACACACCACGCA 3 648 +CATAAAAAGTGTCTG ref:0:15:GT ref:0:15:GTCATGTTTACTA 7 40 +GCACGAACTA ref:0:10:TTGCGCTGGT ref:0:10:G 5 40 +GAATGTCGA ref:1:8:CCACATC ref:0:7:AGCAGAGTCT 2 2 +TGACC ref:0:5:GCCAGGCACTAACGAT ref:0:5:CAGGACAAAT 8 630 +GCTC ref:0:4:CCAGACT ref:0:4:TGCGCGTATCAGGAT 1 6 +TGAATTGAAC ref:0:10:CGCTGA ref:0:10:TCCCTCACACAT 5 3696 +TTTGACCCC ref:0:9:GATTGGCATA ref:0:9:T 5 2526 +ACTCATAACATGA ref:0:13:GAGTAATC ref:0:13:CGGGATCGTAG 7 11700 +CGTTTCACACCG ref:0:12:AACTGG ref:0:12:A 8 14 +TAGTAGACGGAGTCCT ref:0:16:TCTGG ref:0:16:TTTACACCCAATT 6 13780 +ATACTGTGCTAACTGG ref:0:16:CGAAATGTCG ref:0:16:TCTCCG 7 280 +ACGTGGAACCAT ref:0:10:GTTAAT ref:0:12:CTATGGTACCAAAGC 2 2160 +CGG ref:0:3:CTCTGGCTAAGAGCC ref:0:3:TTACT 3 39 +TAC ref:0:3:ATACCTTATTACCG ref:0:3:ACCGCTATTTCTG 6 20 +TATGGGACAC ref:0:10:GACTCGGTGTCTACT ref:0:10:CGAGCCGC 3 1448 +CCGCCTAAATCGTAAA ref:0:16:GTTAGCCGCA ref:0:16:ATCC 10 25137 +TGGGAGG ref:0:7:CGATTGAGTGGAACTT ref:0:6:AGC 2 304 +CATAG ref:1:4:TCGC ref:0:5:T 2 2 +TCCGGCTGTC ref:0:10:CTATA ref:1:9:AGCAAATAGG 5 336 +GG ref:0:2:ATGAGAATTTTC ref:1:1:TTGT 1 1 +CCCGTAG ref:0:7:ACCGAATACACA ref:0:7:GGTTTTGCTATA 4 33156 +AA ref:0:2:TAAAGAT ref:0:2:CGACGAAACCTTGT 3 36 +ATAGCAAGTGATC ref:0:13:CGCGG ref:0:13:CATCCTCCCAAA 5 240 +ACATAA ref:0:6:CTTCATCAGTTTATGT ref:0:6:CGTGTCTAGGCCAG 6 414 +ATCGGGTACTCTCCT ref:0:15:AATCAACCAGCC ref:0:15:TAG 8 1008 +CTATTCGCATTTACGA ref:0:16:GCACGCCGACGT ref:0:16:TT 6 675 +TGGAG ref:0:5:ATTGG ref:0:5:ATGTATACCATGTCAC 2 126 +TCTTCAAAC ref:0:8:CAAGCATT ref:0:9:GTATCCGTAGCAG 4 2304 +CATTCCATCGAAC ref:0:13:TTCG ref:0:13:ATAGAATTCTC 4 20 +ATAC ref:0:4:TTCTCT ref:0:4:CTGGAACGGTT 3 90 +CAAC ref:0:4:ATATGAAAAGA ref:0:4:ATGGGTT 5 9100 +G ref:0:1:AGAATATG ref:0:1:CTT 2 8 +AAACAAGGC ref:0:9:GAT ref:0:9:GGCG 6 104 +TTCTTTCCTGACAA ref:0:14:TAAG ref:0:14:GGCGAGTTTT 7 144 +ATCTCTGA ref:0:8:ACATCGCGAA ref:1:7:TCAAA 3 738 +CT ref:0:2:GTCGACTAATC ref:0:2:TCAGTCGTCAGACGAC 6 12 +G ref:0:1:CATGCGCGACG ref:0:1:CTTACCTATAGTA 5 4 +ATCCGTAGGAT ref:0:11:GTCAC ref:0:11:TAGTCTACTTCGTC 6 1333 +GTTC ref:1:3:TA ref:0:4:TACGGC 2 65 +ACCCATGCTTCGCTT ref:0:15:CCGAGC ref:0:15:GAGCTCCGG 8 7843 +CTGCTCCCC ref:0:9:GGATAACATAGTGACC ref:0:9:AGAAAGT 7 540 +AAT ref:0:3:C ref:0:3:AG 2 20 +GACCGGCGCTTC ref:0:12:TGG ref:0:12:TATTCTG 7 38 +CCCTTCCATGTC ref:0:11:CTCGTCAATCTAAG ref:0:12:AATTTCTAAGCC 7 887640 +GTAG ref:0:4:ATCCTATTCCTGTCA ref:0:4:GGTTAGAAACGC 3 160 +ATAGTCGCCGCA ref:0:12:GTCGTGTGGTAG ref:0:11:CCCCTCTTCATGC 6 624720 +GGCTACCCC ref:0:9:CGTTAG ref:0:9:G 6 120 +GGTCGCCTGT ref:0:10:TT ref:0:10:CCGTCAA 5 9 +GCGGTCTA ref:0:6:CTCG ref:0:8:AACTTGCAC 3 27 +TTTCTGTAGGTAGGCT ref:0:16:GCGTGGT ref:0:15:TGCCGGACGCCAC 8 117792 +GGTCG ref:0:5:ACCCCTTAATAAGC ref:0:5:GTTTAGTAGTTGTAG 6 42021 +CTTAAATGTGG ref:0:11:GTAGAAAAG ref:0:9:TTTGA 3 962 +CACACCAGGATAATT ref:0:15:G ref:0:15:GATGCCGGGTC 9 2032 +TATGCATTCA ref:0:10:GGAGGTTAGGA ref:0:9:ATCA 2 105 +GTGGG ref:0:5:CCGGACGGCGGTCCCC ref:0:5:CC 3 777 +CTAGTCTTC ref:0:9:TAGTC ref:0:9:CACAGC 3 64 +ACGA ref:0:4:ATCACGCGCAACCGT ref:0:4:AATTTTGAGATGTAAC 5 2336 +AGCAGTCTGTTGC ref:1:12:ATTATTCCCA ref:0:13:CTCACGCGCCTTG 1 228 +TGGT ref:0:4:CGTT ref:0:4:GTGGCACCTCGTAGAA 1 52 +AAAGCTC ref:0:7:TT ref:0:7:CGAATCAAG 3 72 +TCTCACT ref:0:7:GGGTTACGGG ref:0:7:GAATTCATTCTTACCA 2 88 +CCCA ref:0:4:TACAATCTAGTGAG ref:0:4:AGTAAGGCCAA 4 462 +ACTGAGGAGAG ref:0:11:CTCTGTGTAGGCTC ref:0:11:TCCCTGGCGGT 6 4455 +CTTCCACCTGTGCC ref:0:14:CG ref:0:14:TCTGCCTCTTG 6 330 +ACTATGACCTTCGG ref:0:14:CATCAAC ref:0:14:CGTGGATTACG 6 1020 +CGAGCCCCCC ref:0:10:GGTTTCTTA ref:0:10:TTGTGTCAATTCGGT 10 4756752 +TCGTTACTCTGAAT ref:0:14:ATT ref:0:14:G 10 6 +ATC ref:0:2: ref:0:2:CGGGAAAAA 1 15 +TGGAACGTGCATT ref:0:13:GAGTATA ref:0:13:ATAATCGGCA 2 12 +TAAATAACAGCGC ref:0:13:TC ref:0:13:ACAGCGCA 5 30 +CTTGGCACGGTTC ref:1:12:GCG ref:0:13:AT 7 16 +TTGAAT ref:0:6:CACAGATGTTATGTC ref:0:5:CTTAAGAACACCAGG 4 852 +TGCGTCGGCTCTGG ref:0:14:GGCAAA ref:0:14:CGG 10 11178 +GGTAACGG ref:0:8:ACGGCTTTG ref:0:8:TTCGCCTAGGCTGCAC 5 11750 +TTTTAGGTT ref:0:9:CTAAGTGCA ref:0:9:TTGTCCGCGG 3 56710 +GGG ref:0:3:TCCTA ref:0:3:TATTATA 6 6720 +TATGCTCACTAGCGTG ref:1:15:CACCAA ref:0:16:GT 8 5 +CCAT ref:0:4:TTAACCGGGGTGC ref:0:4:TTGACTGGCTCCGGA 5 35 +AGCCTGG ref:1:6:G ref:0:7:ATAGGCGATATTT 3 1905 +GT ref:0:2:CTAC ref:0:2:GACGC 2 14 +TAGTATGCTGATGG ref:0:14:GATGAATCATTTATG ref:0:14:GGGTGTTAATGAT 5 6624 +TTCAATAGACGCTGAA ref:0:16:AGTGAGAT ref:0:16:CC 8 102 +GACGAGCGTTCCTA ref:0:14:CCCTGACTCACCTC ref:0:13:T 5 480 +TA ref:0:1:GCGCTT ref:0:2:AGGTTGTGGAA 3 12 +ACCATAATGTATC ref:0:12:CT ref:0:13:CCCTCACC 8 2416 +GTAAGTCCAACGGCT ref:1:13:AAGCGCGAA ref:0:15:TTGTAG 3 20 +TAAGGCTCGTATG ref:0:13:GC ref:0:13:GGTCGACTGGTAG 5 328 +ATCC ref:0:3:GTCTAAGATTGCG ref:0:4:CGCGCTCT 3 288 +TGTAC ref:0:5:GCCGCGTCCT ref:0:5:GCGGATCGCGGT 7 2112 +CAATCAGACCTGGGTA ref:0:16:TGCTC ref:0:16:ACTCATCGACCATT 6 187 +TCGT ref:0:4:ATGTGCGCGAC ref:0:4:ATCGGTTGTTCCAG 5 230 +CCTCAAACAGC ref:0:11:T ref:0:11:TAGCTTTCATACT 5 522 +TGATCATAACAGGG ref:0:14:CA ref:0:14:ATAACGGACCCGC 5 25 +TAAATGTCAAGGTGAA ref:0:16:CCTGACGGGGA ref:0:16:A 9 8134 +AT ref:0:2:TCACGTGTTTTACATT ref:0:2:CTATC 2 11 +G ref:0:1:GACGATG ref:0:1:GTCATATTCGCCGAAT 5 9 +CGTGATTGC ref:0:8:ATTGGTT ref:0:9:ATTGATG 4 594 +CCAACACCG ref:0:9:CCCAGTACTCAGT ref:0:9:AGTCAT 5 992 +AGCCGCTGGGTCTA ref:0:13:GGTCGAATC ref:0:14:CCAA 7 950 +AGGCATATCAG ref:1:10:CATAA ref:0:10:AGATTGTGAAC 3 114 +CGTCGGGTATTTCTGC ref:0:16:TCCTTTATCA ref:0:14:GACA 6 880 +A ref:0:1:CCCAGCTT ref:0:1:CATAGTATTTT 4 3 +CTTGCAG ref:0:7:GCCCTGCCTC ref:0:7:GTTGTAATT 3 5304 +CGCTTCTGCCAGCTG ref:0:15:AAGTCCAAAT ref:0:15:G 9 960 +AGCCAGGCATA ref:0:11:CCACATAACTC ref:0:11:TTTCCCGATGG 4 730 +TGCATT ref:0:6:GGCAGTGATGAC ref:0:6:GGCTC 3 27 +ACAAG ref:0:5:TAACAA ref:0:5:TCAAAAAAATAGGCG 2 1092 +AGTTACTTTG ref:0:9:GAATC ref:0:10:CAGGGTTGTGG 3 12600 +GTC ref:1:2:TTCACT ref:0:2:ACCATA 1 20 +AGTTTGATCACGTGT ref:0:15:TATG ref:0:15:GCAGA 9 156 +ATAC ref:0:4:G ref:0:4:TAAACGTCT 2 85 +AGA ref:0:3:CCCC ref:0:3:CCGTTGTCGGAAGTC 5 2205 +GTTTGTCTTCCCCCA ref:0:15:TACTGAGCGTCAA ref:0:15:ATAAG 10 431640 +TA ref:0:2:GTAAACACTGCTTAAT ref:0:2:GCCGTGTC 5 72 +GCGGCACCTACGGCTA ref:0:16:TGAAACTATT ref:0:16:TTAATTTG 13 16019088 +CACCAGCCGGCTGCGC ref:0:16:CA ref:0:16:CGCTAC 10 456 +TCTTG ref:0:5:AA ref:0:5:ACTTACGATA 3 42 +CTTCGATTAGGTGTAC ref:0:16:AG ref:0:16:TAAGGCGA 9 24 +AGA ref:1:2:GTTGGG ref:0:3:G 1 12 +TAATCTA ref:0:7:TA ref:0:7:GGGGGGCGATTGCCCG 3 12830 +CGTAATCAGG ref:0:10:CCTTGCCTGTAGGA ref:0:10:AACCTGCCCTTTCTG 6 600 +AAGCGAGACCGAC ref:0:13:GGAAAA ref:0:13:CTCCGTA 4 45 +CATCCACCGTTCA ref:0:13:G ref:0:13:AAATGTTGCCGTTCT 5 950 +GA ref:0:2:CGACAAGCTTAG ref:0:2:AATG 3 20 +CAGCT ref:0:5:ACGCG ref:0:5:TT 1 24 +GATGTGCCGTAGT ref:0:13:AGGCCT ref:1:12:TCGGGG 3 2 +AGAAGGC ref:0:6: ref:0:7:GATT 4 25 +CGGCGCACCCAT ref:0:11:GATCCATCC ref:0:12:GGCGGAGGCGATCT 4 3456 +AAAAGTGTGGTTG ref:0:13:GTGTCAATTGTGCA ref:0:13:T 6 856 +GAC ref:0:3:TAG ref:0:3:GGCTAACAAAGTAG 2 20 +CA ref:0:2:AGCAGCTTATTG ref:0:2:GGAGATTCTTGAC 5 3 +GCTTATGGGGG ref:0:11:C ref:0:11:AGTCGTTACTTT 5 28 +ATGACCTGGATC ref:0:12:CTGATTTCGCCCT ref:0:12:ACTTGGGCGCAAGT 6 1074276 +GGGTAGCGTTCGACA ref:0:15:AATTGG ref:0:14:TATTGTGTGGA 8 1890 +AGGAC ref:0:5:TG ref:0:4:AATAGCTG 2 15 +CTACAACCCCTGTGTG ref:0:16:TCCCGAGTGGAAGA ref:0:16:TCACGCAACGT 7 53280 +GACAAGGTC ref:0:9:GGAGCTGAGTCACATT ref:0:8:CATACGAAA 3 2420 +GCACCAAC ref:0:8:ATCGA ref:0:8:CT 5 187 +ATGCGAGTC ref:1:8:A ref:1:8:TCTCTAACTCTCA 3 268 +AGAA ref:0:4:GGTTACAA ref:1:3:TCATTCATT 2 33 +GCTCCCT ref:0:7:C ref:0:7:GGT 4 40 +CATGGTTTCAGCCC ref:0:14:AGCAATCTCGGGTGT ref:0:14:ACCT 6 3416 +CCACAT ref:0:6:TTTTATCG ref:0:6:CTGGGTCCGGTGAAA 4 3120 +GCAACGATATAGT ref:2:11:C ref:1:12:AATTTAAGGTTC 3 204 +ATTTGCGAAGCCAT ref:0:14:GTGAACCTGTA ref:0:14:TGCTATT 7 19200 +AACA ref:0:4:TCAAGAGCGACA ref:0:3:CTATCGT 2 60 +TAG ref:0:2:TGTTCGTCAT ref:0:3:GGT 2 20 +CCTGAACACGCC ref:2:10:GCCCAATTCGATC ref:0:12:TGGTCATCA 5 18768 +CGCTAAA ref:1:6:CTTAAAC ref:0:7:TGAACTGT 2 90 +AA ref:0:2:TAGTCGGACG ref:0:2:ACGCCTTGTCGTGAGA 6 3 +CTGTGTCC ref:1:7:TTTAT ref:0:8:AGGCAAGAGTTGG 3 3465 +GAGGATGGGTGCTGG ref:0:15:CATCCCCATTGTTT ref:0:15:CCAGGATCT 7 21420 +TTTGGATCCATGG ref:0:13:GAGTTATC ref:0:13:CCCGAGAGTTA 9 7950 +CTACGTAAGATTTTA ref:0:15:GTCAACAGTAG ref:0:15:ACGGTCGTCCCCT 6 34532 +GTTAG ref:1:4:CACTTGGA ref:3:2:CGCATCCGTT 1 4 +CTAGTTCTTTG ref:0:10:TTAGGCAATA ref:0:11:ACGTAATT 5 21600 +GTTCT ref:0:5:TGGGTGATGTAGA ref:0:5:AGG 2 36 +TTAAATTGG ref:0:9:GTACCAGGACACGAAC ref:0:9:AGACGTGGGGC 5 67500 +ATATAGAAGTGCTT ref:0:14:AGATTATACGCCGGTC ref:0:14:TACTAGCAGGA 5 1968 +ATAC ref:0:4:GTCCCCTCTCA ref:0:4:G 3 515 +TGT ref:0:3:A ref:0:3:TCACTGAGCTA 1 16 +CCGCAATCA ref:0:8:GCGAGTTTGCTGG ref:0:9:GTATTGCAGTC 5 4080 +TTAATT ref:0:6:CAACGG ref:0:6:TCAGCCT 4 2010 +GTTAATGATG ref:0:10:TATAAATATGGT ref:0:10:CG 2 108 +A ref:0:1:CCCACTC ref:0:1:CTCGTAAATT 3 3 +GGG ref:1:2:CAACGCCCGT ref:0:3:AGAGA 1 6 +ATTGCACCC ref:0:9:TAGGAT ref:0:9:CCCGGGCTT 3 60 +CAGTGATCCCCGTG ref:0:14:TCTACCCCTTCGGC ref:1:12:TTGTGTTT 3 468 +GTTG ref:0:4:ACGC ref:0:4:CTCAGCATAGGAGTGT 2 14 +CATGTATGGAGTCAA ref:1:14:T ref:0:15:ACCGACG 10 1676 +TAGCA ref:0:5:CGCTTCGGGT ref:2:3:TCAA 2 712 +GTGGAA ref:0:6:AGTCATTC ref:0:6:TT 4 112 +ATAACTAGCCG ref:0:11:GTGGCTAGACC ref:2:9:TA 3 12 +CTCACCTGC ref:0:9:TGATACGTG ref:0:9:TCGCGTTTTGCTTAG 4 1632 +CGTATAATACAAT ref:0:13:TGA ref:0:13:AAGGCTACATCCAAGA 6 95424 +ATCGC ref:0:4:CCATAGCGT ref:2:3:GCCCAGTTTAG 2 28 +GCCA ref:0:4:CCCT ref:0:4:TAATCGAGTTTTGTT 2 234 +GATTCCTCTGAT ref:0:12:CCTCTAGATGAC ref:1:11:AATGCGACGAGC 3 255 +CGTTAATC ref:0:8:TTGCTGCCCCGA ref:1:7:TAGA 2 48 +CT ref:0:2:ACGGTC ref:0:2:TGAT 1 5 +GATAGTGCA ref:2:7:AT ref:0:9:ACCTGG 2 1 +AC ref:0:2:GAGTACGTCAATGTG ref:0:2:AGTTTAT 5 36 +CGGCGAA ref:0:7:GTCATC ref:0:7:ATTGA 4 1188 +AAGCGT ref:0:6:GTTG ref:0:5:GGCTGC 3 36 +CCAGGGGTAG ref:0:10:TGTGGAACCCAGT ref:0:10:ATCCCA 7 3497 +TGGGAA ref:0:6:GTTGCTAGAGGTCAT ref:0:6:TCTGCGCCAC 4 3904 +GGAA ref:0:4:CTTGGTGTCCAT ref:0:4:TCCCGTGCTGCGTCGA 6 940 +CCGCTACGTATTT ref:0:13:TCTTTA ref:0:13:AAGCAGTAGCCCATT 4 2850 +GGGCCCTATCATCTG ref:0:14:GGCTTC ref:0:15:CACC 6 108 +TTAAT ref:0:5:ATCTAAGG ref:0:5:CTAGAGAGC 4 117 +CCCGTCTGGC ref:0:9:GATACACGAGA ref:0:10:GAT 5 16 +GACAGTATA ref:0:9:TGGC ref:0:9:TCCA 7 472 +AAGACCCGCCCTAT ref:0:14:GGTGTAG ref:1:13:CTAGCCACCCATGCC 3 1092 +TTTCCC ref:0:6:CTCCGGCA ref:0:6:GCGG 4 270 +ACGCAC ref:0:6:GCACTAGT ref:0:6:AATTG 3 11 +CGTG ref:0:3:AAGA ref:2:2:AGC 2 12 +TCTCATATTA ref:0:10:CAATT ref:3:6:GCCGGGTCGGT 1 362 +TCTGTACTCTTTT ref:0:13:C ref:0:13:CTTCTTAAAAA 7 684 +TTG ref:1:2:CAACTCA ref:0:3:CCAACAAGCG 5 273 +TG ref:0:2:AACACGGAGCGCCT ref:0:2:ACTTGCTCACAC 5 68 +CAAGACTTATGCTAGG ref:1:15:TAAAAGGCGTC ref:0:16:GTC 6 75 +AGGCGTC ref:0:7:TTCGTCTGCCCG ref:0:7:AATCCT 4 14520 +AAAAACCTATTAACGA ref:0:16:GGGG ref:0:16:CTGTTGACATGATCTG 11 31008 +ATT ref:1:2:TC ref:0:3:TTATCTCTAACCAGTC 1 18 +TGGATACGGC ref:0:10:CTAACTGCGG ref:1:9:ATGCAGG 5 48 +CAC ref:0:3:T ref:1:2:CGG 1 4 +CTTGAAAT ref:0:8:G ref:0:8:TGATAGTTCGACAGTT 2 235 +CAAAACT ref:0:7:GAGACCGGG ref:1:6:AGAGACCAGACGG 6 4035 +GAAGTCAGGATG ref:0:12:AATCTACCCT ref:1:11:AGCTACAG 4 480 +ACTTGCATGGGGA ref:0:13:CACCC ref:0:13:GGGCTAGATTCCC 7 32734 +GTAGC ref:0:5:TGTAGGA ref:2:3:CCGCGCACCAA 2 150 +GAAAA ref:0:5:TTTC ref:0:5:TTCAG 7 15372 +GTTTCT ref:0:6:CACCGTGGTC ref:0:6:ATGGATTTTAGTTTG 2 800 +GCAGATAAGGCT ref:0:12:TGCGTCCC ref:0:8:ACGT 4 84 +T ref:0:1:GCTCTTTTC ref:0:1:ATGAGC 1 5 +CCAAAGCCAATGT ref:0:13:CG ref:0:13:GTGA 9 12 +CTT ref:0:3:ACGC ref:0:3:TAGAAAACA 4 91 +TCAGATGC ref:0:8:AGCATGATACTAAGG ref:1:6:GCGTGT 1 34 +TT ref:0:2:GGAAGCAGGAG ref:0:2:CTCTGATCCCTG 4 468 +GCGCGCAGTTA ref:0:11:AGACTT ref:0:11:GGACGCC 5 405 +CCTCCT ref:0:6:GGAGTATGTGCG ref:0:6:GTAATAGGGAGTCAGC 9 108192 +CTCCTGTTC ref:0:9:CTAGTGCCAA ref:0:9:CT 4 730 +CAATGACAAGACGAA ref:0:15:ATGATTGATT ref:0:15:TACGT 9 21084 +ATTATTGGTA ref:0:10:GCTGGGTCG ref:0:10:AGGATAATAAA 4 660420 +ATGCGAGT ref:0:8:T ref:0:8:TATGCTGC 3 22 +ATCAGCA ref:0:6:AAGCTTTCGT ref:0:7:GCTGGAAAT 4 3584 +GGTCTCAGTCAGAGG ref:0:15:TAATAGCCCTTGT ref:0:15:GA 8 17172 +GTT ref:0:3:GGATAC ref:0:3:AGCTTCAGCGT 2 33 +TGT ref:0:3:AAGGGAACCA ref:0:3:ATCTCATGCCTGT 4 820 +GTAGCTATTGC ref:0:11:TGACAACGCCT ref:0:11:CCGATAAGCTATTGCC 1 288 +CCACTACGG ref:0:9:CGTC ref:0:9:T 6 8 +A ref:0:1:CATAT ref:0:1:CGGCACATT 3 4 +CGACA ref:0:5:AGACGG ref:0:5:TAGTAGAATAC 3 684 +ACCAGAACAGCGT ref:0:13:TGA ref:0:13:CGCGGGTACGA 7 5355 +CCCGAGT ref:0:7:AGCGAGTAACAGAC ref:0:7:ATGGCAGTGGA 6 510 +CAA ref:0:3:AGAGGATTCTGCATAC ref:0:3:GGCACCGTTAA 4 10 +GA ref:0:2:TCCGCGGTTTAAACT ref:0:2:GCGATGTT 3 18 +GGGGCCGGCATTG ref:0:12:A ref:0:12:TCCCGAACCA 7 235 +GAGGCATTAACTGGAG ref:0:14:CTCTAT ref:0:16:CGGAGATGCCG 5 2492 +GCCC ref:0:4:TGGACA ref:1:3:AT 3 250 +CTCAAACGTTTTTG ref:0:14:TAGCCAC ref:0:14:AA 10 54 +ATCAGATT ref:0:7:CCCCCGATCGTCGGC ref:0:8:A 2 3 +CCTGGCTATA ref:0:10:CCT ref:0:10:TT 6 21 +CTG ref:0:3:TGCGAAGGGTAGGGAA ref:0:3:ATCCC 1 54 +AT ref:0:2:TCGTCACAAG ref:0:2:CTCGTATG 5 15 +ATTGGATCAAA ref:1:10:TACTACG ref:0:11:CAAT 6 310 +AGGGTATGTT ref:0:10:GCT ref:0:10:TGGACACAGGGCCG 5 1800 +TTTGCGG ref:0:7:ACTGTCGTCAGAAGC ref:0:7:CAGAACATGTGGGTTC 5 88 +ACAGT ref:0:5:CG ref:0:5:GATGATGCAGAC 1 6 +GAGGCAC ref:0:7:A ref:0:7:CTATGATCGTT 3 18 +A ref:0:1:CGTTC ref:0:1:GGCTCG 4 42 +GTGGGTC ref:0:7:CCAGTATTCTCTA ref:0:6:ACG 4 2528 +TCTGCAC ref:0:7:ACGAACTAGATT ref:0:7:AGGGGCTGT 6 1104 +TCGAT ref:0:5:CCAGACTAAAT ref:0:3:CGGC 2 30 +CCGGCCCTTGACG ref:0:13:TCCCAGAGT ref:1:12:TCTGCCCTTCAC 2 342 +ACTTC ref:2:3:TCGT ref:0:4:GAGTGTA 1 6 +GTCACTCACA ref:0:10:TCAGCGTGA ref:0:10:AAGTCAACGT 4 30 +G ref:0:1:TAAAGTGTCTGCGTAG ref:0:1:C 1 10 +TAAAGTGTAC ref:0:10:AACAGTCTCGCTAGGG ref:0:9:CACTCCAA 5 4144 +AAGAA ref:0:5:CC ref:0:5:TT 5 441 +A ref:0:1:CGTCCTAACCGCAT ref:0:1:GGTCTTTT 5 27 +ATTCCACA ref:1:7:CGTCGGCGCAG ref:0:8:TCT 2 184 +TGCCTCGC ref:0:8:CTGACGCCGT ref:0:6:CACGCCA 4 64 +TCCTT ref:0:5:ATGCTAATC ref:0:5:CGGCGTGAAAGCTCAG 4 3 +AACGAAGCTCTT ref:0:12:TT ref:0:12:GTAAAGAACTACA 3 36 +ATGTTGTCCGATTGGC ref:0:16:G ref:0:16:CGAGTCGGTAAGCAA 8 10420 +GTTTCC ref:0:6:AA ref:0:6:ACTGTTGGTACGAG 3 168 +GAA ref:0:3:CAGTAAGTGACGTAGT ref:1:2:CTAATCT 4 8 +GGCA ref:0:4:GGTGTTGCG ref:0:4:ACGACTAGAGCGTT 4 276 +ACAG ref:0:4:GAT ref:0:4:CTCTCCCCACAACA 1 121 +AGGGCACCG ref:0:9:CTAC ref:1:7:GCTGCTC 3 78 +TGATG ref:0:5:GGTAGCGGTTATCATC ref:0:5:GCC 3 297 +GACATT ref:0:6:GCGAGTCCGCAC ref:0:6:CGCATAAAACTCAA 4 27 +GCAAATCGCGGATTA ref:0:15:A ref:0:15:TTCAGGTCACCTCAAG 8 37480 +TTCTACCGCCTCCAA ref:0:15:GAGCGC ref:0:15:TCTTTGCCTCTGATG 5 103740 +GCTC ref:0:4:ATGTCGTG ref:0:4:ACAATGCCGCTG 5 60 +CCAA ref:0:4:AGGACA ref:0:4:ACATTACAT 3 360 +TTATCTGCAGTATTA ref:1:14:CTCATTATATCGTTC ref:0:15:CCA 3 21 +TGGAGCACGCACT ref:1:11:CGC ref:0:12:GATTTAAAAGGTC 6 43644 +CTAGTCACCGCGTAG ref:0:15:GTCCAGTCTGA ref:0:15:GGGTTGCCACAATTTT 8 3695832 +TGGTGTCAA ref:0:9:CTGGGTG ref:0:9:GCAGCATCC 3 833 +AACCGAGCACTC ref:0:12:GCATTAGCTCT ref:0:12:TCCAGAGTACCGC 4 19320 +AT ref:0:2:TAAACC ref:0:2:AGCTCCCAGTCC 3 39 +CTGGA ref:0:5:GCTCACACGGT ref:1:4: 1 2 +TA ref:1:1:GGCCCCCCCAAAGCC ref:0:2:GTCGAGT 2 3 +CCTTTTTTGACCA ref:0:13:TAAGTCG ref:0:13:GT 11 69426 +TGGCCTATCACG ref:0:12:ACTGGAGCA ref:1:11:CGGTACAC 4 2 +GGGTGTTTCTTTT ref:0:13:CCAATGAGTAGGCTT ref:0:13:TTTACTGGTAAGTC 3 13800 +GCT ref:0:3:TCGAGCTTGGA ref:0:3:GGAACGAGATTT 2 24 +T ref:0:1:TGCCCAT ref:0:1:GAG 2 8 +CTGAG ref:2:3: ref:0:5:GAGTCGTTGGGAC 1 20 +GCAGGGTGAGAC ref:0:12:TGATGGGGCCT ref:0:12:GGA 4 500 +TGT ref:0:2:AACAGAAG ref:0:3:ATAGTATTCCCT 3 52 +GCAGATATTTCA ref:1:9:TCG ref:0:12:AAAAA 4 13 +CCA ref:0:2:TTTCGAATCTCGC ref:0:3:ACGCCGAGCGAAGGA 4 126 +AA ref:0:2:GC ref:0:2:GAGCGTTACA 2 18 +GGGGTGAAGCCGC ref:0:13:CGTCTACCG ref:0:13:ATTGAAC 6 9600 +CGGTCGCTG ref:0:9:CATCTCCCTGAACAGG ref:0:9:GGTGCTTGTTTC 1 948 +GATATAC ref:0:7:AACTGCCTCTGGCA ref:0:7:CGCTGTACACG 5 6110 +CCTGG ref:0:4:TTGATT ref:0:4:CGAAAA 2 8 +ACACT ref:0:5:GATCACAGCTACT ref:1:4:AGGG 1 200 +TTTGATTAATCG ref:0:12:T ref:0:12:TTTTGGTGTGTTAGG 4 18360 +TCCTAGACAGGTGGT ref:0:15:GTTGACGGTCGTATG ref:0:15:GG 5 90 +AGTTGT ref:0:6:CTTAGTGAGTGGTCAA ref:0:6:GTGAAGTACTCCGTC 3 4 +CAT ref:0:3:AGAAGGCACGTTAGCG ref:0:3:CGAGGCACAGTC 7 12 +CCTGAGCGTA ref:0:10:CATGCGCTCACGA ref:0:10:GATTGGGTATAGAC 5 5900 +ACGGTAACATC ref:0:11:TAA ref:0:11:C 7 9 +TCAGTCGGTATTTT ref:1:13:ATGTCTG ref:0:14:CTGTCAAGA 7 1308 +CGCTGACG ref:0:8:ATTTAGTCGGTTTCT ref:0:7:TGCACAACCTGCT 4 21402 +CTCCTACGGTTTGCG ref:1:14:AGTCTGAGAGGTCT ref:0:15:TAC 6 552 +CGAGT ref:0:5:GAGGTTA ref:0:5:G 1 8 +TTCTGAGGCAGCTTG ref:0:15:TGGCTGCTGTTCTT ref:0:15:AGTGCTTCGTCA 5 270 +TCCGCAAT ref:0:8:GAGGAG ref:0:8:TTAAATAAACTTTGTA 4 8420 +CGACGGAC ref:0:6:CCAG ref:0:8:GTCTACGACTA 2 54 +A ref:0:1:TACC ref:0:1:TGGAGCT 2 1 +CGAC ref:0:4:GCACCAAG ref:0:4:A 1 4 +CCGCGCGGTAAG ref:0:12:AATTCGCGTATGT ref:0:12:CTATGGCCAT 6 90048 +ACGAC ref:1:4:G ref:0:5:GGATCTCTC 1 28 +TACTTATTAGA ref:0:11:GACCCCCCTTTT ref:0:11:AACTGTGTA 4 1236 +CTGTTTGAAGAATCC ref:0:15:ATGCGTAC ref:1:12:GTCCAAG 7 19627 +TCAT ref:0:4:CGTA ref:0:4:GTTAAACACTCTGGC 1 16 +AGA ref:0:3:T ref:0:3:GTAACAAC 2 72 +GG ref:0:2:CGTGAACT ref:0:2:CAAC 4 15 +CGAATTTCG ref:0:9:GCCATATTATTTAAAT ref:0:9:C 3 1960 +T ref:0:1:CCGGAAGTCTGTATGT ref:0:1:ATAGAACCTAACCC 5 10 +TTCTGGGAA ref:0:9:TGTGCAATG ref:0:9:GTTGGG 3 220 +GGAAACGATAGAT ref:0:13:CATACATAACTA ref:0:13:GAGACATAA 4 143 +ATTGAGACAA ref:0:10:CC ref:0:10:TCTAACG 6 33 +AGAGTCACGGTAT ref:0:13:GA ref:0:13:CGACCTCGA 7 490 +AGAATGAGAAC ref:0:11:GT ref:1:10:CGTGGGACACACT 3 22 +T ref:0:1:CCCGTA ref:0:1:AGAGAGACCGGTGC 3 1 +TCTG ref:1:2:CCCGTTA ref:0:4:AACAGGCTCAGA 2 72 +TGGGTCGTGCT ref:0:11:CAGGAGAGGGAGCA ref:0:11:AGT 5 34100 +CTCAA ref:0:5:GGGGGGACAACAATAG ref:1:4:GTTGGGG 2 819 +GGAAT ref:0:5:CCCGAACGGAACAAGG ref:0:5:C 2 414 +T ref:0:1:GG ref:0:1:AATTAACCGAGCCAT 2 9 +CATTA ref:0:5:TTTT ref:1:4:TCGTC 2 42 +TATCCTCTCGAATA ref:0:14:ATG ref:0:14:TGGGCTT 8 546 +AAC ref:0:3:GAGCG ref:0:3:GTTCACTGGATCTTAG 3 4 +TGGGCAA ref:0:7:CACAGTTCACGTGCCG ref:0:7:AG 4 2256 +ACTCCGTTCATAATC ref:1:13:GTC ref:1:14:GTCGTGGTCTGAAAG 4 120 +ATA ref:1:1:CGCGCGGCTT ref:1:2:CTTTTGGGG 2 52 +TGCACAAGGGGGGAAC ref:0:16:GTAACTTTTC ref:0:16:GG 11 535836 +CGCGGCACG ref:0:9:CTAAACATCA ref:0:9:CTACACGATA 7 5040 +ACG ref:0:3:GATTACTACGTTAC ref:0:3:AGTAAGG 3 100 +CCTTATATATTTCA ref:0:14:GCTCGTTCCTTGTGAT ref:0:14:GCACGTGTCGCTAG 10 5394328 +GGGATGGAT ref:0:9:CAGCCTTGAGTTA ref:0:9:AATTCTGCAATA 6 198710 +CACAAA ref:0:6:AAAGCACG ref:0:6:GAACGCTAAATA 1 50 +GGAAAGCCAC ref:0:10:GTAACTGTTGTAG ref:0:10:AA 5 5070 +TTTACCC ref:0:7:AAATCG ref:0:7:TGGCTCACTTGA 4 59078 +TCCTC ref:0:5:CAAG ref:0:4:CTTCTACGATGTGTT 3 248 +TAGTG ref:0:4:CTCCATCAACCC ref:0:5:ACCCATTACTCGCCG 5 14 +AATTTGTTGG ref:0:10:G ref:0:10:AGCAGCAGACGTGAC 5 5175 +TGTCTGATTGTC ref:1:11:TCCGAGGCT ref:0:12:TTAGTTGCTTGCAC 1 432 +CTTATCATGAAGTGTA ref:0:16:TCCTCTAAG ref:0:16:TGATGGCT 6 5200 +AAGTTGTCCCATTAG ref:0:15:G ref:0:15:AAACTGATACGAGCT 7 6099 +GGATAGAGATTT ref:0:12:CTAAGTTACCCGA ref:2:10:CAAGA 5 350 +CCACAA ref:0:6:GCCGGCCTC ref:0:6:GAA 2 924 +ATGAG ref:2:3:GCTTT ref:0:5:AGCGACATGGG 2 576 +CGAGAGTCGA ref:0:10:TTCGGTTAATAG ref:0:10:TAGGTAGGTCT 4 1125 +CGACCATAGGAC ref:0:12:GCAAAGTCCCAACCTC ref:0:12:AGCAGACAT 6 50730 +GACGTTCACATTGATC ref:0:16:GGCGTTCAGCCGCG ref:0:16:GGGGTGG 8 18630 +TCCCCTGCGA ref:0:10:G ref:0:10:ACTTGGGGTGTGACT 5 6244 +ACGGGTA ref:0:7:GTTTAACAAAGG ref:0:6:TGGTGGCTTC 1 360 +TACGCTTCGAGGCGC ref:0:15:ATATCCTG ref:0:15:ACCACCA 6 33 +ACTGAA ref:2:4:AT ref:0:6:TCTACTCATGC 3 88 +CCGTAT ref:0:6:TAGGGCTTCACGAG ref:0:6:G 2 6 +GCCACCCAAAGA ref:1:11:CTTTAGTTGTCC ref:0:12:AGAATTTC 10 22880 +TCTTT ref:1:4:GC ref:0:5:ATAGTAGACATAGGCA 3 117 +A ref:0:1:TG ref:0:1:CTCCAAGTTGA 2 9 +CGGGTCA ref:0:7:CTCGGAA ref:0:7:GCAAATTGACCCTAAA 4 96984 +AGTAAT ref:0:6:CAGT ref:0:6:AAC 2 14 +C ref:0:1:GCTCGTC ref:0:1:ATGTAGCAC 3 6 +GTGAAAGGACGAA ref:0:13:CGGTTAAAG ref:0:13:AAGA 6 1380 +TTCGTCCACGAAAC ref:0:14:GTGTAGATTGCCC ref:0:14:CGATAGGA 6 2568 +TCCGTTT ref:0:7:CGAGTTTCGGGCGC ref:1:6:ACCGGAGTGCGTTG 3 18 +GAGCCATATGA ref:0:11:TAGGCTTTTACGCT ref:0:11:TCG 6 27391 +AG ref:0:2:CGACCAGGAT ref:0:1:TTCCAC 2 4 +TGGTTGGGCCTCTGA ref:1:14:CGCGATCGGAAATCG ref:0:15:GGTGCTTTTAAT 3 110580 +GTTGGTGT ref:0:8:C ref:0:8:TTATGGGCACCTA 3 36 +ATAAG ref:0:4:CTAT ref:0:5:A 2 21 +TACAATCT ref:0:8:GCAGGTTCACGGCGTT ref:0:8:T 3 1515 +C ref:0:1:TACAGCTTAG ref:0:1:GAGTCTGTGG 5 2 +T ref:0:1:ACG ref:0:1:CACAGTAGTGGGGTTA 3 16 +AGGGTGGGGTTCTC ref:0:14:TACACTACCT ref:0:12:TAGCATCA 11 1475318 +GTGAGTGTTAAGC ref:0:13:TGTCGGTA ref:0:13:AACATCC 4 270 +CAAACCCGGCGC ref:0:12:GAGC ref:0:12:TCTGTAGAA 7 52 +CTGGGCGTAGTCGTT ref:0:15:TAATTTCCTTTATGGT ref:0:15:CCGCTGA 7 4746924 +GTTC ref:0:4:TCCTACATCCAG ref:0:4:TTA 2 26 +GACG ref:0:3:CCA ref:0:4:CATAGGTCGATC 2 98 +ACAT ref:0:4:CC ref:0:4:GACATACTGGT 1 25 +TCCTTAGTCAC ref:0:11:TTATGCTAGGTGT ref:0:11:TATTTGAGATACTTA 5 25402 +GTGAGCC ref:2:5:A ref:0:7:CATAG 3 3 +TCGCAGACA ref:1:8: ref:0:9:CCACG 4 5 +TCGCCG ref:0:6:GTTAGTA ref:0:6:CCTTCGGT 4 320 +AGCAA ref:1:4:GCCGCGGATAT ref:0:5:AAATTACCAAAAAG 1 1440 +TGCATAGCAGTTTGCA ref:0:16:GCTGTACGTGCCAG ref:0:16:ATACACGCTACCACA 5 8784 +AAA ref:0:3:ACGG ref:0:3:C 3 60 +GGGA ref:0:4:AAG ref:0:4:TGGGGGGGAGTTACCT 1 1365 +GGCTTTAGAAAGG ref:0:13:GCA ref:0:13:TTGCG 6 240 +C ref:0:1:GTTA ref:0:1:ATACAG 2 5 +TGGGTTCGCATC ref:0:12:CCTGCC ref:0:12:GGCGCCCAG 6 3416 +GTGCAATTA ref:0:8:TAAATG ref:0:9:TCAAAT 4 128 +ACGTACTTAG ref:0:9:CAATCT ref:0:9:TATCAAGCGCCAC 4 4890 +ATTAGGCTTTGGCCAT ref:1:14:CTTACTC ref:0:16:GCTACGCGGATGG 5 162 +AATACGATAGAG ref:0:12:CAAATGT ref:0:12:TTCTTTGA 4 1950 +TAAAGACCAATGT ref:0:13:AGTAGGAATCTAT ref:0:13:G 6 4904 +GGACGGTC ref:0:8:TCGAAG ref:0:8:AGCGCTGGTTGATA 2 578 +ATTG ref:0:4:TAAGAGG ref:0:3:AAGACGT 5 1122 +GAAGT ref:0:4:ATTTCTAAAATCGA ref:0:5:CGC 2 650 +ATGCCACCGTAGTT ref:0:12:GAA ref:0:14:GCAAAG 7 15 +CCTAATAACA ref:0:10:TTCTCGGT ref:0:10:AGATAGA 4 1038 +CACT ref:0:3:GAAACCCACAG ref:0:4:CCTGTACA 2 18 +CGTCACA ref:0:7:GTGAAAATGTAGTGC ref:1:6:GGCTAGAATGCTTAG 7 3625 +GTTACTATAGAG ref:0:12:GGGTT ref:0:12:TAGCA 6 645 +GTTTGGGGAGT ref:0:11:TTTC ref:0:11:CGAACCG 6 1045 +GAAAAGTCTGCAAG ref:0:14:TAGCCATGGCACA ref:0:14:ATAGACCATTC 3 84 +CCTGTT ref:0:6:GTACGAGCT ref:0:6:TTGTTCCGGGGTAC 5 6634 +TTGGCGGCTGCCCGAT ref:0:16:CCAGGA ref:0:16:GTAGTT 9 326 +TTGTC ref:0:5:ACCA ref:0:5:AGGGGTTCAACAC 5 5140 +GGTTAGATCGCATAC ref:0:15:TAGGA ref:0:15:TAAGTGGGGTATT 8 6300 +GTGAGCGGAGACGAAT ref:0:16:TCGTGGACCTCCTAG ref:2:14:G 7 1242 +GGCGAAC ref:0:7:CTTTGTCGAACA ref:0:7:CTCGCTTGTTG 5 805 +TCG ref:0:3:TCCCTAC ref:0:3:AGGATTTGTCGTAGCG 3 289 +TGATTCGATGGCTGAC ref:0:16:C ref:1:15:AAGTAG 9 18 +GGTGGAATC ref:0:9:ACGG ref:0:7:GAGATGCTGGCGG 4 2205 +ACGATCGG ref:0:8:GGT ref:0:8:GCCAAA 5 2493 +T ref:0:1:ATCAAAAGCAACCT ref:0:1:TGCTCCTATTTTTTT 5 20 +TTCCTCGTCCAC ref:0:12:GTCAAAACTCATAGAA ref:0:12:TACTGCGAGACGGAG 7 116928 +AAGCCAACTC ref:0:10:ACTACAT ref:0:9:TCGTGG 5 1620 +ACCGG ref:0:5:GGTAGCGTATGGGTGA ref:0:3:AATTATTCTTCAAT 4 174 +GG ref:0:2:GGTCAAGGAAGC ref:0:2:GTTATCGCATAG 5 30 +CCGATGGCCGC ref:0:11:CAGC ref:3:8:CACCGTA 3 42 +CGTAGG ref:0:6:GA ref:0:6:TTGATGGTAT 2 10 +ACTAT ref:0:5:GGGTCCGTTAGCC ref:0:5:CAGGTAATGAAGCTC 6 4356 +CCGAAGCCTCCGAA ref:0:14:TTGTTGCTTTTTA ref:0:14:G 9 57456 +GGCTGTCAGTG ref:0:11:GTCATTCTGCT ref:0:11:AAAATATGGCCATA 2 18 +GTACG ref:0:5:G ref:1:4:TAATAACACAA 1 108 +GG ref:0:2:TATCTG ref:0:2:CTTCGCTGC 4 7 +TCGATTTGGTGGA ref:0:13:CG ref:0:13:AGCTTGTCTGACAT 6 8600 +GTTC ref:0:4:TGAAACCAATA ref:0:4:AACAGCCAA 5 236 +ACCACT ref:0:6:AGGAA ref:0:6:CGGCG 4 638 +AATCAGA ref:0:7:T ref:0:7:TAAG 4 8 +AGTCCCGCAGGCT ref:0:11:TTCGAGAA ref:2:11:CTGGTAGTA 4 6300 +CTTCTTTG ref:0:8:GGGACCTACTCAT ref:0:7:TC 2 96 +GATAA ref:0:5:TATTTAG ref:0:5:CCTGG 3 1050 +GAGTTCGGCCAG ref:0:11:GGATGTTCTCGCAC ref:0:11:ACAAA 2 1980 +TGGCCACA ref:0:8:CTAAA ref:0:8:TTAATGGGAT 4 1386 +CAGCGAGA ref:0:8:GTGAGAA ref:0:8:ACCCCA 1 532 +CCATTGGGCATCGA ref:0:13:GGTTTATAAGG ref:2:12:TCGCGAAGG 7 467852 +AAGTCGTGC ref:0:9:TTAACG ref:0:9:GAT 4 24 +GC ref:0:2:CTAAAT ref:0:2:AAGAGAAAGTACGA 1 3 +ACTCACTGGATCT ref:0:13:CAA ref:0:13:TAATACGAGCA 5 66 +TTTAA ref:0:4:CTGCAGG ref:0:3:GTG 3 150 +CAAGCCCTT ref:0:9:TAATCGTCATCAC ref:0:9:GGTTGAGA 1 16 +TAA ref:0:3:CAT ref:0:3:TACGGTCGTATAATCT 2 104 +TCTCTAAG ref:0:8:ACGTGTGTTCTTTT ref:0:8:CCGC 4 991 +CTA ref:0:3:GAGTGAG ref:0:2: 1 4 +CAAACACTTAC ref:0:11:AAT ref:0:11:TAACGATAACAC 4 1824 +GATGGACAAC ref:0:10:AGCTTCG ref:0:10:GGAGAAATGCCCGC 4 240 +TATC ref:0:4:GT ref:0:4:GAGA 3 64 +TCAGACTG ref:0:8:GTTCC ref:0:8:CGTACAGTTCA 4 64 +AGCTGTAG ref:0:8:TCAGTAGCGTC ref:0:8:GCCCGTAGGAAGG 3 3648 +TCTCAATCCT ref:0:10:TTGCTAAGCTGCG ref:0:10:GGT 5 4320 +CTAGG ref:0:5:TGGGCCAGTCGCG ref:0:5:TGAAGAGAACATTCAC 3 32 +AAGTATCCAGTCTGCC ref:0:16:GAT ref:0:16:TTATG 10 10 +AGTGAACGTG ref:0:10:TTTATA ref:0:10:TATTC 7 2848 +GATATAG ref:0:7:C ref:0:7:CGCTTTCATCCTTA 3 280 +GGATCCTGGGACGAC ref:0:15:TTTAGGG ref:0:15:TCCCG 7 41 +TA ref:0:2:G ref:0:2:TTTTTGG 2 75 +GGGCTCAGCA ref:0:10:TAAC ref:0:10:CCCGTATAAG 6 5490 +TTTATCCG ref:0:8:T ref:0:8:C 6 8 +AGCAAAG ref:0:6:TCGGCCATAT ref:0:7:CCGGATTGTACAT 5 4389 +AAAGCCTAGGGGATAA ref:0:16:TAGCGTG ref:1:15:TGAACTGGGTGGCC 8 126480 +CCAGTTTATTCTG ref:0:13:GTGCGCGGACTTGGC ref:0:13:AAGGCTAAA 6 201600 +AATTATGTAGTGGTGA ref:2:14:CGGAGAGCGGCTC ref:0:16:TCAAG 7 720 +ATACTCTGAATTA ref:0:13:GCCT ref:0:13:CTCAAATTTGC 6 600 +GA ref:0:2:ATCCGCGAATCGTCG ref:0:2:AGT 2 12 +G ref:0:1:ACCGGGAT ref:0:1:CCTGGTAGA 5 9 +CGTCGGGCAG ref:1:9:AGTC ref:0:10:CCCCATTAT 4 126 +AAATGATAAA ref:0:10:CCTTCTTGAAGACT ref:0:10:TAGACAGGACAGG 6 192840 +AAGCCGTCGGACGTAG ref:0:16:GCTGGAGCAGGCATTA ref:0:16:AAT 5 32 +CCTGGGAGCACT ref:0:12:TATGCTG ref:0:12:CCCGGCTTAG 5 554 +G ref:0:1:CTCCGACCGGCGAA ref:0:1:GCATTACATCGCT 6 8 +TCGTAT ref:0:5:CTACAA ref:0:6:GCACACCTAG 4 840 +GA ref:0:2:TTGGCT ref:0:2:C 2 21 +CCTCCAAGTTTAATA ref:0:15:CAAGTTGTTG ref:0:15:GAGCAAAGA 6 14656 +GCCGTTCTATTACC ref:0:14:AAATGTGCAAGAGAC ref:0:14:AA 8 21668 +GGCAGTCTC ref:0:9:ACATCTCCATT ref:0:8:AATCGTT 4 162 +CCGGTCCCCGGCT ref:0:13:TAGTGCATAT ref:0:12:AGAGCA 10 13024 +CCAGAA ref:0:6:TCAAATACGGG ref:0:3:ACTCAC 1 16 +CAATTTG ref:0:6:CC ref:0:7:GAAGATA 3 679 +G ref:0:1:AGATGTCCGT ref:0:1:TGGAGGGAC 3 15 +TCTTCC ref:0:6:ACGTAAGGACATC ref:0:6:TGTA 3 520 +GTATGGGCGACG ref:0:12:AGCAGTTGAAA ref:0:12:GGGGAGAA 7 21944 +CGGACGGCA ref:0:9:ATAGGTGCATCATTAG ref:0:9:TATAATGCC 8 1919211 +GGCCCGT ref:0:7:GG ref:0:7:CTATTGACCCAGCG 2 171 +TAGCC ref:0:5:ATTG ref:0:5:AGGCACATAGTTGC 3 52 +TAAAC ref:0:5:CCTCCGA ref:0:5:GGGGATGTCCGCCAT 6 29480 +ACTTCGTTGCAGCCT ref:0:15:TACATGTGCAGTA ref:0:15:CAGTTTCCGTTTC 3 2400 +CAGA ref:0:4:ATCACGAGAGTCCGGC ref:0:4:CGTCGTGAGCCCC 6 125 +CTC ref:0:3:ACCTGGAAT ref:0:3:AACCCGGG 4 60 +GGTACC ref:0:6:TAA ref:0:5:CTCGAGTTACAG 1 8 +CGGGTACACGTCCA ref:0:13:GCCTTTTG ref:0:14:GATTCCACTTCATC 7 130680 +GCGCCCAGCCCATTT ref:0:15:CGCCATATCTTAG ref:0:15:GATATCCCTGTAGG 6 7350 +G ref:0:1:TTGGGT ref:0:1:AGGCG 2 9 +TACAGACGGAA ref:0:10:TTGCGCCTGACCC ref:0:11:GGTG 5 55 +CGTTT ref:0:5:CTCAAACG ref:0:5:AATGACATGAAT 5 2535 +GGAAATAATGCG ref:0:12:G ref:0:11:GTAGCTC 6 64 +CACC ref:0:4:GAC ref:0:4:ATCTCGAAAGTTCT 2 188 +CCTCCATCAGATTTA ref:2:13:AGTAATCAGCCA ref:0:15:ACTG 6 1728 +TGGATT ref:0:6:GCGTGTCGTAT ref:0:6:T 1 9 +TGGTGATTTTTACG ref:0:14:AACACTGAATCA ref:0:14:ATATGTGCACTATTAT 8 2365578 +GCTGGGAG ref:0:8:TACAAAA ref:0:8:CGTCAGGTCG 4 33880 +TCGCCCCGTGTCGT ref:0:14:GGAAACACGCCTAGAG ref:1:13:TGCGAAAAA 4 72 +GGATGGCAT ref:0:9:AGTGATTC ref:1:7:AAGAATATTAGAA 3 2461 +CTAAACAATTATACT ref:0:15:AACAGGCA ref:1:14:TTTGGTTC 7 15796 +AAAAGGGTCC ref:0:10:TACATTGCTTT ref:0:10:TCGGACATGGGTGTAT 9 11175870 +A ref:0:0:GGTT ref:0:1:GAGACATGTGGGTTT 2 3 +ACTATAGGCT ref:2:8:ATCGTTTA ref:0:10:CGGGATTGGACC 2 1722 +CCCTGTGCAATG ref:0:11:ACTTTT ref:0:12:ATGATGCTCTCGGAG 6 11020 +CAATTAATAGTTT ref:0:13:AGCGGTT ref:0:13:GT 9 3270 +ATAGGGTGCAGGTA ref:0:14:CGCCATAG ref:0:14:GAG 8 712 +AACTTAAGTATGTC ref:0:14:TACAG ref:0:14:TATTTTAATAGTTAT 5 39270 +T ref:0:0:AC ref:0:1:GGGTCGGTAC 1 2 +GGAGCTCCGAG ref:0:11:AGGC ref:0:10:CTAGTGT 6 336 +ACCGTATTCATCCAG ref:0:14:TT ref:0:15:CCGGGCGCT 8 5682 +TTCTAAGCATAAT ref:0:13:GATCGCTAACCTTC ref:0:13:CTCTTA 5 672 +GATTGCTTAGGG ref:0:12:TT ref:0:11:CACTGTTCACTTGGT 3 300 +CGCAGGTCCGGCGTA ref:0:15:GTAACGT ref:0:15:TAGATAAATC 11 906096 +CATACCAAAAACGAA ref:0:15:TGCACATGTTTGAT ref:0:15:GGCAAGGC 11 154714112 +ACA ref:0:3:TAGTCAAATCG ref:0:3:CAACCGGCCTAGA 2 48 +AATTAC ref:0:6:TACTGGTCG ref:0:6:ACCGTCTTT 4 420 +CCATTATCCAT ref:0:11:CGTTCTGCTCTAGTGA ref:0:11:CCG 4 270 +TCAG ref:0:3: ref:1:3: 2 1 +A ref:0:1:GATAGCCGCC ref:0:1:CCACACTCGTGT 4 4 +TAATGGCAAC ref:0:10:GCGCTGATCGACCA ref:0:10:ACTTTCGGACATTTCT 5 16116 +ATACAAGCACAGTAGA ref:0:16:ACGCAGTACGC ref:0:16:CTTGCGT 7 456 +CCAA ref:0:4:TTGTACATTGCCCCTA ref:0:4:TCTCATT 4 188 +CCTTTATGATATGGCC ref:0:16:AGCGCACAAA ref:0:16:AGT 10 112 +TTGCGG ref:0:6:TCTTGCTATGCTA ref:0:6:G 1 72 +ACTGCAATCTTAGCT ref:0:15:TA ref:0:15:GG 11 6 +CCTAGGACTGG ref:0:11:CTTGTGATCGA ref:0:11:ATG 4 196 +GCGCGT ref:0:6:ACGAAGCATAAGACAA ref:0:6:TATCATACA 7 6968 +ACGGC ref:0:5:GAAGAG ref:0:5:CACGCGG 1 21 +C ref:0:1:GTGTTTCGTCTCT ref:0:1:T 1 6 +TG ref:1:1:ACAGTT ref:0:2:CGATGCCCTTAGGGCC 2 10 +ATGTCTCACTGC ref:0:11:TTGTCCCTTTCCGT ref:0:12:GGCTGAC 3 2898 +CGG ref:0:3:ACCCA ref:0:3:CCTTGCGTTACC 3 38 +AGTACGAGCTCTCGGA ref:0:16:TGGCGCGAGCGAT ref:0:16:TATAG 7 23136 +GCTCATTTAAT ref:0:10:CCACTTGGACAC ref:0:11:TCGGTTGTCAAAA 2 180 +C ref:0:1:CTGGCGATTAATC ref:0:1:TAGCC 3 6 +ACATCATT ref:0:8:ATAC ref:2:6:GACGG 4 100 +AGGCGCAGACTGAAC ref:0:14:CAACACGAGG ref:1:14:TCAG 8 8568 +CACATCGAGGAGTTTC ref:0:16:ATA ref:0:16:GTGGGTAGTCTTCT 5 20 +GAGAG ref:0:5:GTCGT ref:2:3:GGCGTCCT 3 132 +TCGAGCTATGC ref:0:11:ACTTCATTAAAAATG ref:0:11:ATATATCTGCTGGAG 5 880 +AGCGGTGTAAGCTTT ref:1:14:CGT ref:0:15:TCGTTGACCCAGTT 5 1071 +CCCATT ref:0:6:TGCCGAGGCACGAT ref:0:6:GACTAGCAA 5 429 +GCCGTAG ref:0:7:CTAGGCTC ref:0:6:TCTCT 2 8 +TA ref:0:2:ATCAGGGTCCG ref:0:1:CCGCGGGCG 1 10 +TGTTCAG ref:0:6:AAGGTCGCAA ref:0:7:CTTGTAGTCCC 2 2450 +CATTTTCTA ref:0:9:GGACAC ref:0:9:TTCTAGATGA 3 212 +AGA ref:0:3:CATAAACA ref:0:3:CCAGCGG 2 196 +CTG ref:0:3:AAT ref:0:3:GTAGTATGGACGTGC 2 3 +GCTCGCCCATGAATC ref:0:15:ATGAAATTGT ref:0:14:ACGTCTGCTCAGTT 5 11040 +TG ref:0:2:AGAGGACG ref:0:2:GGCTGTACCTAC 4 19 +GTG ref:0:3:GAGCCAG ref:0:3:TGTACA 3 60 +GTGTGCGAGC ref:0:10:GAACAGCTGAA ref:0:10:CGGAATCTTAGAGTG 6 1008 +TTACTTACAC ref:0:10:T ref:0:10:GTC 8 124 +GCGGGATACAAAAG ref:0:14:TCACCC ref:0:14:AATCTCATA 9 121014 +ACGC ref:0:4:CAGTCTGAGCTCC ref:2:2:AGAAGACGGTGAG 3 12 +ATATATCTGAA ref:0:10:AACGCTGTGTTACCC ref:0:11:ATCGC 4 2070 +CAT ref:0:3:GTC ref:0:3:GCTATATTAAG 1 20 +T ref:0:1:G ref:0:1:GAAAGTAGGCTG 1 4 +AAGTAC ref:0:6:GGGAGTTCCA ref:0:6:AGTGCCTTTGGGTAGG 4 9350 +TTACGCTTGCTGTT ref:0:14:TCCTGGCGGAT ref:0:14:T 6 700 +GGCCACACAGTAAGG ref:0:15:GCCAGGATATGC ref:0:13:TAGT 6 31500 +CGCGTATACCGAAA ref:1:13:CAGTAGGCA ref:0:14:T 7 416 +CTCGGATTAGAC ref:0:12:TAAGACGTTCATACG ref:0:12:AATGCGTAACG 6 504 +CAGCGC ref:0:6:GTACA ref:0:6:GTGATAAATTT 6 414 +GTTGTATTTTCCTT ref:0:14:AGCGAAC ref:0:14:CAGTTGCCC 8 495 +AGTCTTGATA ref:0:10:TAGGCTAAACCGCGAC ref:1:9:CCCTGCCTTCT 4 28149 +GACGCCTCCTACAA ref:0:14:G ref:0:14:CAGTATAGCCTAGTGC 6 196 +GTCATGCG ref:0:8:TGACCATG ref:0:8:TAGTGTGTACATATT 4 3052 +AGCCGCTAGCAGTA ref:0:14:CGCTTTTGT ref:1:11:CCGT 5 132 +CGCCTAGAACTGC ref:1:10:ATTGCCGGAA ref:0:13:GTGTAACCACGAGGAT 3 16 +CGGACC ref:0:6:AACCGAAGAAACCT ref:0:6:TACAGG 1 6 +AAGTACCAGAGA ref:2:10:CACCGCTAAG ref:0:12:TTA 4 630 +AG ref:0:2:TT ref:0:2:C 2 18 +CCCTGAC ref:0:7:GGCTGT ref:0:7:TGCATA 4 600 +ACGACGGC ref:0:8:CATATTGTGACT ref:0:8:CATCGCTGAGAG 4 184 +CAATCGGTC ref:0:9:GCCAT ref:0:9:GCAA 6 13 +TTCTTGCATGGA ref:0:11:GCTGT ref:0:12:GGTCGTTTCTTATC 5 1593 +AGCAGAT ref:0:7:A ref:0:7:GTAGGATGCCG 2 15 +CGATCGATATTTATCA ref:0:16:GTTTAAGCGGGC ref:0:16:GGAGCCC 11 472758 +C ref:0:1:CTGCATAACCGAATAA ref:0:1:GCTCAGTCTTCT 7 16 +GGA ref:0:3:C ref:0:3:AAGCCAA 2 52 +CTGT ref:0:3:TTTAGCCTGC ref:0:3:TGCAG 2 8 +CATTTCGA ref:0:8:AGT ref:0:8:ACGCGG 5 416 +ACCGTCGC ref:0:7:CGGTAGTG ref:0:8:GTAAA 4 840 +CTCCTA ref:0:6:CGCGGACC ref:1:4:GGAGTTT 3 210 +GTCTCAAGTAGCAG ref:0:13:ATTTGAA ref:0:14:TTTTCAA 8 3128 +TGATAAGCTACAGC ref:1:13:AAAGCTG ref:0:14:GCAG 5 6 +TC ref:0:2:CAAGTTTTGCTTGTGA ref:0:2:TAGCCTGACCTA 5 24 +GACTTGTGGCATCT ref:0:14:AACTCTTCGTGATC ref:0:14:TAGA 4 756 +TCCTTAAGAG ref:0:10:CATCTTCCG ref:0:10:TA 4 567 +TGTCGGCTCCTCCG ref:0:14:TTGCGCGGCTTTC ref:0:14:A 5 2970 +CG ref:0:2:TTAGG ref:0:2:TTATGC 4 54 +CCACTCGAAG ref:0:10:C ref:1:9:GGCCCA 5 8 +TTC ref:0:3:CGCACCTCTGACCAC ref:0:3:CGTTTG 3 21 +ACGATGTGGGG ref:0:11:CAC ref:1:10:TCTTCTGGAG 4 468 +ATTTT ref:0:5:GCATGAC ref:0:5:TGTTCCTTCTGAGTA 4 2555 +GAAC ref:0:4:TATGAACGGGCAGAA ref:0:4:CTAATACCGT 4 40 +G ref:0:1:CGAAGACACC ref:0:1:AAGTTTGCTTC 4 4 +ATCCG ref:0:5:GAATGTCAGTACACGT ref:0:1:GTACCCGGAGC 4 30 +TTGGGATAG ref:0:9:TTTAACAGCGATCAA ref:0:9:GAAAGGCAAACCGAG 4 1725 +TACCTACGAACCT ref:0:12:AG ref:0:12:ATCCATGTGACGAGA 3 8 +GCTGA ref:0:5:TCCAGTTCATGCGAAT ref:0:5:TCCTT 3 80 +CCT ref:0:3:AACGGAATGACATAT ref:0:3:GATTGTCTACAC 5 26 +CGTATGT ref:0:7:GTTAGATC ref:0:7:AG 2 3 +CGAG ref:1:3:AC ref:0:4:GA 1 2 +CGTCCACAGC ref:0:10:ACGGCCGA ref:0:10:AC 4 117 +TGGC ref:1:3:GT ref:0:4:CCATCGGCGTTC 1 20 +G ref:0:1:GATG ref:0:1:AATA 2 10 +GGTCATACTATG ref:0:12:G ref:0:12:TCAGGTGCGTA 4 6 +CGCACA ref:0:6:ATT ref:0:6:AGAGCACGG 2 140 +GAAACGGACACCTGTC ref:0:16:CGTCCGAGCTCC ref:0:16:TGTAGCCATTGCCG 9 4352400 +CCCGGGTTGGTTCGT ref:0:15:AAAATTGGGTTACA ref:0:15:TATTGGCG 8 56700 +GGAGTGT ref:0:7:ATAGCTCGG ref:0:7:TTT 3 176 +CGCTCGGAAT ref:0:10:CCGACGAACTTG ref:0:10:GTCTCTTATGATA 2 1200 +CT ref:0:2:ACCAACGTCGAT ref:0:2:TCAGAAG 3 49 +AGATGGACC ref:0:7: ref:2:7:TGGTTGACCTAAA 1 3 +CCTGTGTGCACCGCT ref:0:15:TAAAC ref:0:15:GATTAGTACCTG 8 11760 +GATTAGTG ref:0:8:GCTG ref:0:8:GAGACCTTTGCA 3 51 +TC ref:0:2:GGCAGAC ref:0:2:CGGAACAA 5 70 +GA ref:0:2:GGAGGA ref:0:0:CCCTCCCATCATT 1 6 +AGGCCCTGC ref:0:9:CTACCGATTCGCG ref:0:9:CT 3 42 +CTCGTAGAAGATTCAC ref:0:16:GTCGCCCAGTT ref:0:16:GGTTCGGACGGGATCG 7 220752 +TTCTTTG ref:0:7:GG ref:0:7:ACTCTAGCCC 3 312 +CAGTATCACTCC ref:0:12:ACGGTTC ref:0:12:GGGCGCTCCGCCT 4 384 +AACCT ref:0:5:GTGTGGACA ref:0:5:CAATGAGGTGGCAC 4 123 +CGTGAGTACGA ref:0:11:TTGGGTCTGCTGTGT ref:1:10:AC 3 2174 +A ref:0:1:TTATTCTTGTA ref:0:1:AAGGG 1 4 +ATGGC ref:1:4:GGTGGCCTGGCT ref:0:5:ATCCATCAAGAGTGT 4 216 +CCC ref:0:3:CCAGGT ref:0:3:CAGACCTCGATGCGA 3 70 +TGGTTGTGAG ref:0:10:AGGGGT ref:0:10:ATTTCAGA 3 812 +ACTAA ref:0:4:CCCTTTTCCCATGG ref:0:5:TACAGCCGATTGTTAT 6 2832 +CATGACA ref:0:7:TAGGAAGTCTTGGCC ref:0:7:ACGGGCGACACTACGG 7 116550 +GACGTGTGCTAGGG ref:0:14:CCGAA ref:0:14:AAGTACCTTACA 8 1056 +TGAAGAGCATGACA ref:0:14:GAGGGTC ref:0:14:GGAGTGTT 7 170 +GATGAACCG ref:0:9:AGGTACAGCCACATC ref:0:9:TCTAGACAGA 5 26000 +GTGGCTCCAGTCAGCA ref:0:16:A ref:0:16:GCGTGTGCCCT 7 6 +CGACA ref:0:5:T ref:0:5:AGGGCGTAGCAG 1 6 +GACTAGCATGGATG ref:0:14:TT ref:0:13:CCTAGAGG 5 12 +CACAGCG ref:1:6:TGACTCCTCTAG ref:0:7:GACCGGCTC 5 3654 +GTACTA ref:0:6:ATAATACTCGTAAG ref:0:6:GCCGATTACGCAAA 4 4752 +CTCAACTATGC ref:0:10:AC ref:0:11:TACTTTGGCTAATAA 4 62 +TTTGGCCAC ref:0:9:AATG ref:0:9:CTGCCGCTGTTA 4 2040 +CAT ref:0:3:ACACAGATCGAC ref:0:2:GTCCGAAA 2 30 +GCTCCTGCCCAAG ref:0:13:CGTGGC ref:0:13:AGAGCCCC 7 11918 +GGGTAGAC ref:0:7:ACTCGGCTAGG ref:0:8:CTCATCACCC 2 864 +GGGACT ref:0:6:AGGCA ref:0:5:GTTAA 2 455 +T ref:0:1:GCACCCACTTTC ref:0:1:AAAACTGGATCCGG 5 6 +ATCACAGCCGGAGT ref:0:14:CGTGCGGTAAGCC ref:0:14:GTGACCCCATT 6 25515 +CGTAC ref:0:5:GCGAG ref:0:3: 1 2 +TGGGT ref:1:4:GACCTACGAA ref:0:5:CCCGGTTGAC 4 2340 +CAAGAGGCGTGC ref:1:11:AGTGCATTTTGGTGG ref:0:12:CACGTCAAATC 5 57912 +CTGCCGGTTA ref:1:8:TTAGCGCGT ref:0:10:GCACATTTTT 1 1776 +TCGCCCGCCCGG ref:0:12:AAGGGTGCTC ref:0:12:AGGTACCATTAGCT 10 2440980 +TGCTAAAGGT ref:0:10:CCACTACGGA ref:0:8:TAACTTGC 4 6210 +CATAGGCT ref:0:8:TATTC ref:0:8:TTCGAAAGAATCTTGC 3 1058 +GTCTATTGTGAGA ref:1:12:TGTGACCGG ref:0:13:TAAAGTCAACTCT 4 1056 +GCCCCGCGGCACTGC ref:0:15:TAACACG ref:0:15:AGTG 10 9698 +GGTTTTTGACGGTC ref:0:14:ATACTAAAACT ref:0:14:AATAGCAT 11 3063080 +ATGCTA ref:0:5:TCGAAGAAC ref:0:6:GCATT 2 25 +TCAGGTCACGAA ref:0:12:A ref:0:12:GTCCATTGGTGG 5 56 +CCCTCCAGG ref:0:9:CTA ref:0:9:TGCGT 4 30 +CTTAGTACGTTTT ref:0:13:TCCCACACA ref:1:12:GATCG 7 1350 +TCTAGTGAG ref:0:9:CGAGCTAATTTGTTTG ref:0:9:CCAGA 3 4480 +CAATACAGCAGTAGA ref:0:15:CCTTGGATCGAAGTAT ref:0:15:AACCGGCTGTAG 3 26520 +TCTTCCGAGTTA ref:0:12:CCGATC ref:0:12:GTACTACTCGGTCT 3 75 +AG ref:0:2:ATGAGTCA ref:0:2:GCTGTG 2 33 +CCATACTT ref:0:8:ATCCCATC ref:0:8:CC 3 9 +CTCTGCTTGTATTAT ref:0:14:GGAATTGAAATT ref:0:15:TAGCCGGAGTG 6 137484 +CTAT ref:0:4:GCAACCAAAATAATGA ref:0:4:TGTCTAAA 3 36 +TCGCGGCCTGCAC ref:1:12:CATCA ref:1:12:AAGTATT 8 1260 +ACTCTTTGC ref:1:8:TATTGATCCGACGC ref:0:9:TACGCAATTCATGCC 3 24 +AACGGTTA ref:0:8:A ref:0:8:GAAACAG 4 36 +CTTCCCTGG ref:0:9:TGGT ref:0:9:A 6 30 +AAGCCCCTCAACC ref:0:13:CTATCTCTGATA ref:0:13:AGCTTGTC 8 373426 +GCAG ref:1:3:TCAAAATA ref:0:4:TCCGTCTTGGTGGCTC 2 380 +TCTGATAGGGGTTGA ref:0:15:GTTCTACCGTGCGT ref:0:15:CG 7 2112 +TTAGTAGTTGTCTGTC ref:0:16:GCTGCTCCAGGGA ref:0:16:GAGTTCG 6 36 +GTCTGCATG ref:3:6:AATGCCCGC ref:0:9:AACACGATCTAC 2 50 +GCACTTGT ref:1:7:TAAT ref:0:8:AG 4 39 +GGC ref:0:3:TAGGCGGTAA ref:0:3:TTGTCA 2 5 +TCACAGCAGTAGACCC ref:1:15:CGGGGGTCTT ref:0:16:CGCTACCGGCAGC 8 5326693 +AGGCAT ref:0:6:TGTTACCAA ref:0:4:TGTTATTATGGG 4 672 +GTAGGGGC ref:1:7:TTTA ref:0:8:AGCTCCCA 5 432 +CACAAT ref:0:6:TTTCAAATGTACCC ref:0:6:AAACAC 3 90 +GCATCCAGGCAAA ref:0:13:TTTC ref:0:13:ATAGGCGAGGATT 5 728 +TACATCTCCGGATGA ref:0:15:GCCT ref:0:15:CGG 10 384 +TAACCTTGCA ref:0:10:TGTGAAGTCTT ref:1:9:AGAAGGCGGTG 5 536 +CGACGTGACGATAG ref:0:14:TTTC ref:0:13:AAGCGCT 7 4350 +TTCGCATGACCCTAAA ref:0:16:CGCTAGCAGACGTC ref:0:16:C 8 5520 +CCAGTG ref:0:6:CGCGGCTGTGATC ref:0:3:CGGTCCCTGCACT 4 180 +ACTAT ref:0:5:CATGCATAA ref:0:5:GGT 2 126 +TCTTCGACTCGGCAT ref:0:15:AGCCCAGAGGGTTTTG ref:0:15:GA 8 8576 +TCT ref:0:3:CAGGCCTCATTAGCAC ref:0:3:ACGGTATATTT 5 80 +C ref:0:1:GGCT ref:0:1:CCAATCACCTTCG 1 6 +T ref:0:1:AGAGATG ref:0:1:GGCAAGTC 3 1 +CTACACAAAAACTT ref:0:14:CAATAGACTCGGAC ref:0:14:CTGTA 9 314215 +TGGGCGG ref:0:7:ATCTCG ref:0:7:AATTT 6 936 +GTG ref:0:3:GAAATGATAG ref:0:3:TACCAAC 2 28 +CTGGAACTATAG ref:0:12:A ref:0:11:GTGGT 6 16 +CTTTTATAAGCCGA ref:0:14:TCCCC ref:0:13:TCAGTACGTC 8 56265 +TCTAT ref:0:5:TTGGCCCC ref:0:5:CGACCAGCTATAGAG 3 1800 +ACAACGGAAGAC ref:0:11:AACAT ref:0:12:GGTAAAGGTCT 5 600 +AAACCCTAAT ref:0:10:ACAGTGC ref:0:10:GACGCCG 5 810 +AAATCTT ref:0:7:CTGCTCAAGTGAGGGA ref:0:7:ACTCGTACC 5 156 +CGTCCGG ref:0:3:GCACTT ref:0:7:GAG 2 120 +ACGCAC ref:0:6:GGTGGGCGGATGCGGA ref:0:5:TGTACGAGTAGG 5 679 +GAGTCCT ref:0:6:C ref:0:7:TGTACAA 3 114 +CGGTTTCTCTCAC ref:0:11:CT ref:0:13:TTACGTCGGCATTAA 5 4760 +GTTGACACCG ref:0:10:AATAGTAACAGG ref:0:10:TA 4 1116 +GTCCTTCCTCGA ref:0:12:TCTGG ref:0:12:CAA 7 2046 +ACCGTGT ref:0:7:C ref:0:7:TTCCTCTTTTGGGACG 3 5148 +TACC ref:0:4:CCAAAACACGCGGA ref:0:4:ACTGGGATGGGCGCAA 4 62 +TCG ref:0:2:ATTCA ref:0:3:GACTGCTGGTAC 1 4 +AATGCGA ref:1:6:GGAGCGCCGGGGT ref:0:7:TGTAGGTGTTAGGTT 6 59496 +TAGCTATG ref:2:6:A ref:0:8:TTCCTTTCGGGAA 1 156 +AT ref:0:2:TTAAAACTTAGTTT ref:0:2:GCGGACCCA 2 138 +CGGAA ref:0:5:GCTCCATCCCG ref:0:5:GGACTTGATAGCTCA 6 6800 +AACGATACCATCA ref:0:13:CGCCCTGAGTT ref:0:13:GTCAGTCCGT 7 2028 +GGGC ref:0:4:TCG ref:1:2:TCGCATGTAA 2 14 +CCGGTGA ref:0:7:GGTCGCTACTCG ref:0:7:TACCAAGCGGT 1 7 +TTAGTGTG ref:0:8:CACTCAACGCGACCGG ref:0:8:ACAATTAAG 5 13832 +GGTACC ref:0:6:TTGCGCTGAGA ref:0:6:CG 3 42 +GCAACGCACCTTGTG ref:0:15:CGCATGGT ref:0:15:TACGTAA 7 6454 +CTTGGTCGACTCC ref:0:13:CCCACACAGCAGTGG ref:0:13:TCGTGTCAGGCT 3 864 +ATCTCT ref:0:6:GTC ref:0:6:TTTTCTTAAGTCAAGC 3 2664 +AGATCTGGATAGTCCA ref:0:16:ATTGTATCGTAG ref:1:14:CGTTATGCTG 6 238 +AG ref:0:2:GATT ref:0:2:GTTACTATGGCACTG 3 28 +CGTATCGTAG ref:0:10:GTGA ref:0:10:GAAAATG 5 224 +CGTCCGATCGT ref:0:11:TCTAGACACC ref:1:10:CCGC 5 254 +ACTCGTATTTTCCC ref:0:14:CCCT ref:0:14:GCCAGAAAGTGCGGGA 8 547638 +TACTACTACCT ref:0:11:GCGCACGAACGAG ref:0:11:AGCTC 5 27870 +CAGCAATA ref:0:8:GAGGAC ref:0:6:C 3 152 +AAATTCGCGA ref:0:10:TCT ref:0:9:TAGTATTGTCGCGGT 2 646 +AATGGACAGGCTAAAG ref:0:16:TCCTTGCGACGTA ref:0:16:AGAAGGGAGTGGGC 5 619944 +AGCGACA ref:0:7:ACACGGCT ref:0:6:CTATTTATGCGTAG 2 164 +ATGAT ref:0:5:GACCGCCTC ref:0:4:GAAAGTACCCAA 4 540 +GCG ref:0:2:CCCGCC ref:0:3:GCGCACCGATGGAG 2 58 +TACTGTTACAGTCCTA ref:0:16:CCGCGGGAGCTTCGT ref:0:16:AGCGGG 9 2000 +TGCCGAGGACGA ref:1:11:AA ref:0:12:GGAAGAGC 5 54 +TAGGGCATCT ref:0:9:GACCCCAT ref:0:9:CGGGGCCG 2 1830 +GAGCGAAA ref:0:8:TGGCTAG ref:0:8:TGGGGCCCCGGGT 5 23120 +CTGCTTAA ref:0:8:TTCGTCGTGATCCA ref:0:8:GAC 3 220 +AGCTAATAA ref:0:9:CAC ref:0:9:GGACGGCCCTG 5 1638 +AGGCAGGTT ref:0:9:GT ref:0:9:CCGC 6 432 +TC ref:0:2:TGGCAATCCGTGG ref:0:2:GCCTAAAA 3 50 +TTAAAAG ref:0:7:TTCTTAGACGGTAAGC ref:0:7:ATC 2 318 +CACTCGAAGCTCATC ref:1:14:CGTGGTTGCT ref:0:15:TTGCCCACATCA 3 28 +CGTCCGTGAGATTTG ref:0:15:A ref:0:14:AGGAAGA 9 48 +CCCATCCTGTTTTGTA ref:0:16:A ref:0:16:GCCTT 11 708 +GCTCGCGCTG ref:0:10:GCTG ref:0:10:CTGTATCTACAGGA 4 730 +AGCCCCT ref:0:7:AAGCAAATCG ref:0:6:CG 3 2376 +GTTGATCGGTACG ref:0:13:AGTAGCGC ref:0:13:C 7 44 +CCTATA ref:0:6:GTTTGTCG ref:0:6:ATACG 4 228 +C ref:1:0:TAGGATT ref:0:1:GCCAGTAC 3 3 +TCCATGCCTGGCGCTA ref:0:16:C ref:0:16:ACCGAAGATT 10 654 +GCTTTGGAAGA ref:0:11:AACCAACCAG ref:0:11:AGTCTTATACCTTAT 7 8471 +TC ref:0:2:CCCGAAAAACTTA ref:0:2:ACC 2 105 +CTATTTCA ref:0:8:CA ref:0:8:GGCAGCGCT 5 231 +ATTTAGTTTGACC ref:0:13:CGTAG ref:0:13:G 10 256 +ATGAACTTCATC ref:1:10:GCTACATTG ref:0:12:CTATCAGCT 5 162 +CATGCCGTC ref:0:9:TC ref:0:9:GACCTGGGATACCAG 3 348 +TTTCAGGGATGG ref:0:12:GCATGAATACCTT ref:0:12:TCCAGTCAC 8 1219680 +ATA ref:0:3:TCGTC ref:0:3:CCTTTCAGCC 4 156 +GTCTCCATCTTCCAAT ref:0:16:ACTCTGCGGT ref:0:16:CG 11 114730 +GACCCACTGACC ref:1:11:T ref:0:12:TA 9 1 +GTAC ref:2:2:GA ref:0:4:CCACCTTATTA 1 96 +AC ref:0:2:AAACACCGCG ref:0:2:TCTTC 1 105 +ACAAGTCATATGACG ref:0:15:AACGCAGAGTTTGGTC ref:0:15:GCGCCTCCGAGCTAC 4 2112 +CTAATCAGGCCGTT ref:0:14:GTATATAACG ref:0:14:CCCCCAATACTAA 5 2640 +TACT ref:0:4:AAACTATGTC ref:0:4:G 2 115 +TACTGGTCA ref:0:8:CGCCTTGGCCG ref:0:9:TTCTT 1 315 +ACTTCACGGG ref:0:10:GTAAT ref:0:10:GT 9 2665 +GTCTT ref:0:5:A ref:0:5:TAAGGCGTTCG 2 24 +CCCTAAACGCA ref:0:11:CC ref:0:11:TACAC 7 200 +ACAGTGGTA ref:0:9:CAAGTAATAAC ref:0:9:ATCACGCAGTAGA 3 1728 +AGGCG ref:0:5:TATCAGGCCGCA ref:0:5:T 1 24 +AATCGCTTAGATC ref:0:13:GCCCCCGGTCAA ref:0:13:A 8 22728 +T ref:0:1:TCACCGCATGGT ref:0:1:ACG 3 12 +ACTGTCAC ref:0:8:GAGAAATTT ref:0:8:CCATATAAGGGCG 4 3384 +TAAGCCCGCCGAGGA ref:0:15:GCCGCTCACT ref:0:15:AAA 6 132 +GTTAATTATCAGG ref:0:13:CAT ref:0:13:TGAAAG 7 1368 +TTC ref:0:3:TGATACTAGTC ref:0:2:GTGATGGTTTA 4 70 +AAACAAAG ref:0:8:TTAAGTCCGC ref:0:8:GGA 5 2988 +TATCGGACTATATTT ref:2:13:GAAACAAGGG ref:0:15:GGTTTGAGC 7 20160 +GGGTAGG ref:0:7:T ref:0:7:CCACATTCCA 5 140 +TATTCGGTCCAAT ref:0:13:GAC ref:0:13:CGTTAACTTCAC 8 33320 +ATTGTGTCACAGATA ref:0:15:TTCAATCTTGG ref:0:15:AGAT 8 9090 +ATTTTCACTT ref:0:10:A ref:0:10:CTC 7 72 +GTGTAAGTATCTG ref:0:13:GAT ref:0:11:TACGCCC 6 1620 +GGGGGCACTAGA ref:0:12:TTCCCTTCGTCATTCC ref:0:12:TGCCATTA 8 318325 +GC ref:0:2:CTACCCGGTAACCTCG ref:0:2:ATCACGCAGC 4 18 +GTGCGCACCCGGCAGG ref:0:16:ATTCGCGGGGCATAAA ref:0:16:TAACACAGTTT 7 9125010 +GAATT ref:0:5:TACG ref:0:5:TTGACAACAAGTA 4 2332 +TCTCCGCGGGTG ref:0:12:GACAG ref:0:12:GATTA 10 1177 +TACCTAGTGTTTTAA ref:2:13:TCGGAC ref:0:15:ATTCGAGCCCTG 8 825 +GTGTGACTGGCTAAAA ref:0:16:GGGCGCCTTGCGAATA ref:0:16:T 6 9484 +TC ref:0:2:GGTCCACAGGGG ref:0:2:A 1 9 +T ref:0:1:CCAGATAGGCATGA ref:0:1:CGGGCCAGGCCCATT 7 4 +CTC ref:1:2:GTGCAGGCGGC ref:0:3:GGTGCTA 3 15 +GTACCAACTG ref:0:10:AAGTGAAGTCGAT ref:0:9:CGGGCAGAGTAT 6 15555 +TCCTTGGGCC ref:0:10:CATGCG ref:2:8:GCTTAAGG 3 520 +CGTTAACA ref:0:8:C ref:0:8:AGTGTGGT 4 156 +CCGATGGG ref:0:8:CAATAAGCGTGGTTT ref:0:8:TCAAGGCGGCGGA 4 34 +CGTCT ref:0:5:A ref:0:5:CTTTTGCCGGAC 3 1032 +TGACGTGCCT ref:1:8:T ref:0:10:GTAAAAGCCGA 3 369 +ACTCAGATG ref:0:9:TAACATGCCT ref:0:9:TTTACGAGGCAA 5 12932 +CTTGGTGGT ref:0:9:TACAGTGAGAACC ref:0:9:AGAGAACGAGAGACG 6 260 +TAAGCTATATCC ref:0:12:AG ref:0:12:AAGTGAGGATAAGAAG 5 588 +CCGTGGTCCG ref:0:10:CTAGTACTCCTCATC ref:0:10:CG 4 9540 +G ref:0:1:TGAGGCGGCTAA ref:0:1:CAGCAGCACGAC 6 15 +TATGCCAC ref:0:8:GTGGTGTCTT ref:0:8:GCAGCACGATTCTGTG 4 234 +TCCGT ref:0:5:TATGCCGTGTCCA ref:0:5:TAGGAATGGTGCA 6 516 +TTGTACAT ref:0:6:TA ref:0:8:GACACGGG 2 15 +CTTGTGAATGTAAT ref:0:14:TACGATT ref:0:14:GTGTACTA 7 36498 +CATACCTCTC ref:0:10:GTTAGTGTCTG ref:1:9:GTCACTCCTCGGA 4 4480 +ATTAACACAGCACA ref:0:14:GACCAATAACCACTAC ref:0:14:ACAAG 2 33 +GGTACGGAATT ref:0:11:TGCTGTCA ref:0:11:TCGTTGGAAGA 5 320 +CTGGTTCACTATC ref:0:13:CCGCGGA ref:0:13:AGGGCCGG 9 49608 +AAGAGGAACTA ref:0:11:CTCTCTCTGCGC ref:0:10:TATCAC 8 147600 +GCAGGCA ref:1:6:ACTTTTATG ref:0:5:AAGA 3 56 +A ref:0:1:GAGCTCATTGT ref:0:1:GT 2 6 +ACTAGG ref:0:6:GCGACTGCCTGCTA ref:0:6:TCGCTTGGAC 4 18 +ATCTCTGCCAAG ref:0:12:CC ref:0:12:TTATGTGCTTGTCGGG 4 1260 +TGGGTTGGTGG ref:0:11:AA ref:1:10:AAAATTGGCCTCTCA 7 57330 +AAACC ref:0:5:TCGCTCGAGAAGACA ref:0:5:GCG 2 182 +AGTGTGTCTTG ref:0:11:AAATGCGCTATTT ref:0:11:AACTAAGC 5 22356 +AACATT ref:0:6:CTCTTCTTGT ref:0:6:TGCGTCTCC 5 3240 +TTCG ref:0:4:TGGCAACCTGTGC ref:0:4:CGGTTACCTTTA 4 517 +CAGTT ref:0:5:TCA ref:0:5:TCTGAGGAAC 3 25 +CG ref:0:2:AGCGCGCCGCGACCA ref:0:2:AGGA 3 60 +TCCA ref:0:4:CAGAAT ref:0:4:CTGT 4 275 +TCGGTG ref:2:4:T ref:0:5:ACGAATCCAAAAC 1 8 +TCGATATC ref:0:7:CTCTA ref:0:7:CTATCCGATA 2 4 +TAAACGCTCTTGGA ref:0:14:TCAT ref:0:14:CGGGCTTTG 6 300 +ATTAGGAGAGA ref:1:10:CCGCGTGGTGGCTT ref:0:11:TGGACTT 7 7952 +AACCAGACCCAT ref:0:12:GTAGAC ref:0:12:AGTATGTAAATAACTT 8 1180185 +CGC ref:0:3:AACAAATAG ref:0:3:AAGTACTAGGGCAA 4 3 +GCTCTGCC ref:0:8:AACTGAT ref:0:8:GGAT 6 2625 +TGCACCGAGACCTT ref:0:14:ACGGTAGCGATTAT ref:0:14:ATACATAGATC 6 16758 +CCGTGAC ref:0:7:GAT ref:0:7:G 5 10 +AGAGTTC ref:0:7:CG ref:0:7:GTCCCGGCAT 5 1134 +TC ref:0:2:ACAAGTGTCGCGGCC ref:1:1:GGCAC 3 16 +GGAATTGGCGT ref:0:11:TAG ref:0:11:CAAGCGCCGCA 5 684 +TATCTCGGCTGGTA ref:0:14:TGCTAGGTCATA ref:0:14:ACCCGTG 3 3074 +GGCT ref:0:4:AACGTACTT ref:0:4:TCACCTAGTAAAGCCG 4 70 +GCTAGGTGA ref:0:8:ACCGACCAGC ref:1:8:AGAGT 2 24 +TTATGCTTGAC ref:0:9:CACACTCTGG ref:0:11:TACCGT 4 9652 +CGAGAAGGTGACGACA ref:0:16:ATACCTTGGACCGCC ref:0:16:TGAGTGTCCT 7 459008 +CGGTATCCTGAAATC ref:0:15:ACC ref:1:14:AATCCCCCAAG 8 6195 +ATGAGGTAACCCACC ref:0:15:CACGACCTCG ref:0:15:C 9 7440 +CGGCTAA ref:0:7:GCTACCGGGT ref:0:7:ACTCATACACTAA 4 3136 +ATCCGTCTAAGCGC ref:0:14:GG ref:0:14:GTGATCAAT 7 30 +GTGACGCAGCCGCTGT ref:0:16:GGGGAACAC ref:2:14:GCACTGTCCATG 5 61490 +GCTGCT ref:0:3:ACC ref:0:5:CCTCAGATTTAGCG 2 252 +GCTCTGC ref:0:7:CC ref:1:6:CACACTCTATCAAA 1 36 +AGATAAGCATCC ref:0:12:T ref:0:12:GGTGTAAGT 6 36 +TGGGTCACACAGTCGA ref:0:16:CGATGGAACAAA ref:0:16:ACGGTG 5 616 +ATTGCTGGTT ref:1:9:TGC ref:0:10:GCGCCAAGCGTAAA 4 934 +AGGTTGTACAA ref:0:11:ACCAACTGCTC ref:0:11:AAG 7 2200 +TCCATCGTTT ref:0:10:GACCAGTAGC ref:0:10:AGG 6 504 +GATGTTACCGCCTGAC ref:0:16:GCAGCATGGTTG ref:0:16:ACGTAA 8 7060 +G ref:0:1:GTCGCCACCG ref:0:1:CAT 2 12 +CC ref:0:2:GGGGTTCGCGG ref:0:2:AGGCGTCAATCAG 5 3 +GCTCATTGGCGACA ref:0:14:CCACGTC ref:0:13:TTTATACT 4 106 +GAACA ref:0:5:ATT ref:0:4:AGCATAT 3 34 +GTTTTGGTG ref:0:9:TGCAGGA ref:0:9:CAGGCTGAAAGCATTC 4 600 +ACCTTCGACTTCC ref:0:13:CCATCT ref:0:13:GT 7 78 +ATATTG ref:0:6:GCGAGACAAGC ref:0:6:AGAACTCGAGCATACT 5 282 +CCGCTCCACAGTCCTA ref:0:16:GTAGTAGAGCTG ref:0:16:CACACAAGGGCT 7 536352 +ACAAG ref:0:5:CTGAATGGCT ref:0:5:GGA 2 46 +GGC ref:0:3:GAGAGGTGA ref:0:3:AATTCTGCAAAAC 4 777 +TTTAGTC ref:0:7:GATG ref:0:7:TGA 5 360 +TT ref:0:2:CTG ref:0:2:CCGATACGGGATA 2 4 +GAAGTT ref:0:6:GGAGGAATTTAACG ref:0:6:G 1 148 +TGTCACCGATTTGT ref:0:12:GAT ref:0:14:GAAGGTGTAACTCTG 5 378 +GTTA ref:0:4:AGCTCGCC ref:0:3:CGT 1 50 +GCTCGGTTCTCCT ref:0:13:GTTCATACCGCGCAT ref:0:13:CCCTGAAGAT 7 56525 +TCTAGGCGAGTGCAA ref:0:15:T ref:0:15:CGTTTTGGC 10 3825 +TC ref:0:0:CAGAACCAC ref:0:2:ATCGATCCCCCT 3 11 +TCCAGGT ref:0:6:ATTGAGAAGCCG ref:0:7:A 2 92 +CGGCCGCATGGACCG ref:0:14:GCGACGCGC ref:0:15:GGTAAGGGCAT 7 288184 +GACTGAATCATATCT ref:0:15:TAACACATGCGCA ref:0:15:AAATATTAG 6 252 +ATTTTCCATGG ref:1:8:A ref:0:11:CTATCTGATCGGGGAC 4 1476 +CGAGGT ref:0:6:GTGGTCTGATGC ref:0:6:TAGCCCA 4 1518 +ACGGGCGCCATG ref:1:10:GAGTCCAGTTC ref:0:12:CC 4 384 +GTACGA ref:0:6:TCC ref:0:6:AATCTAA 3 215 +TGTATGT ref:0:7:CAAC ref:0:7:AGTCCTCTT 4 4000 +AGACATCGGG ref:2:8:TCCT ref:0:10:CTATCCTCAGAATA 6 29174 +GGATCCGATCGCTTG ref:0:15:CGATCCGTAACTCTC ref:0:15:GAAGT 4 1128 +GTACGG ref:1:5:ACTGCT ref:1:5:AGC 3 20 +AGCCAACACCTTCTCG ref:1:15:CAGATGG ref:0:16:GGCTAGGGACCACCT 6 18480 +TTTCCTATTTCAGGA ref:0:15:GATCGGATGTTA ref:0:15:TG 7 2520 +TATACCCTCGATAGC ref:0:15:T ref:0:15:ATCACAGAGAGGGGG 7 4200 +TTGAGACTCT ref:0:10:GACT ref:0:10:ATTCCAGATGTA 2 54 +ATTAGAACTGGA ref:0:10:AGATGAATGCAA ref:0:12:CGTAAT 4 288 +CCTAAGGCACTCC ref:0:13:CCCTGAGTTTCCC ref:0:13:GTAGAACCTAGCAGCC 4 34380 +GGGTTAACATTGTC ref:0:14:TTTTGGCGCACATG ref:0:14:ACGGCTG 6 140 +T ref:0:1:ACTAATCCCA ref:0:1:ACAAGGGATGT 4 4 +TGGATGGCTT ref:0:10:ACACCA ref:0:9:GATCATAGGATAGTA 4 1890 +A ref:0:1:CAACTCCCATGCCG ref:0:1:TCGCCCAC 5 3 +CGTATAA ref:2:5:ATC ref:0:7:ACAGCTGG 3 117 +GTCCGTATATAGAA ref:0:14:AGCA ref:2:10:AGTCTTGCCT 5 114 +CCCAAACCAT ref:1:9:TGACCACCTA ref:0:9:GGTTCCG 4 3450 +TCCACCCGCC ref:0:10:GTACACTGACCGTC ref:0:10:ACATAATACGAT 6 55836 +TTATTGATCAC ref:0:11:C ref:0:11:AATTTA 5 8 +AATGGCCAGAATAAA ref:0:15:TTATGATACCGAGT ref:0:15:GA 7 1564 +CTCCGTTGGGTC ref:0:12:AGGT ref:0:12:AC 9 800 +TA ref:0:2:GACTTTGAA ref:0:2:CAGTAG 1 6 +TGGA ref:0:3:AGTG ref:0:4:TCTAGTCTTATGAATT 2 16 +AGAGTTTGATCACTAG ref:0:16:GTTAGGCCGAGATCC ref:0:16:T 8 2200 +ATCTT ref:0:5:GC ref:0:5:GATGACG 3 9 +TACGTAC ref:0:7:CCATAGCCGCCA ref:0:7:CGCAGAT 4 714 +AGAGGTGTCTC ref:0:11:GGGAGAGCAGAGC ref:0:11:TGTACGTAA 1 12 +GTTTAAGGGA ref:0:9:TGTTGTTCCGTG ref:0:9:AGCCCCGTGGCT 5 40572 +ATATGTGCTTA ref:0:11:CAGTCTT ref:0:11:CGTGTAGGTGGCC 4 1600 +TAG ref:0:3:CCCAA ref:0:2:GGATATAA 1 65 +ATCTTAAC ref:0:8:CCTG ref:0:8:C 6 82 +CGTCAT ref:0:6:A ref:0:6:ATTCAACCTCG 2 18 +TATCGTAGTCCAAA ref:0:14:TGTACGGGAGAGGAC ref:0:14:GTCAAC 7 5184 +CAA ref:1:1:GACTGGGT ref:0:3:GG 2 10 +CTACA ref:0:5:ATGGATAGCTC ref:2:3:CCG 2 315 +CGTTTACAGCAAGC ref:0:14:A ref:0:14:GGGACCACAATGA 6 336 +AATCTT ref:0:6:GTTACAGTG ref:0:5:TATCGCCTGA 4 783 +CTAGG ref:0:5:CGCT ref:0:5:TCCGCTTATG 3 108 +GTAT ref:3:1:TTAGA ref:0:4:AAGC 2 34 +TTTTATGC ref:0:8:TATCTTCTGCATAG ref:0:8:ATGTACGGG 3 1792 +GACATTGTGATATATT ref:0:16:CAAAAGCT ref:0:16:G 9 12 +CCCTTGTAG ref:0:9:TGAGCCTGATA ref:0:9:TCA 4 196 +GAGTGAAACGATCTGT ref:0:16:G ref:0:16:GTGGTAACGATCTG 4 220 +AA ref:0:2:TACGTATGCTT ref:0:2:TGTCACGGATGCTG 7 1 +AATTGGCCACCATGTT ref:0:16:GGGCTAC ref:0:16:AGTGTTGGTCTCCAT 7 13068 +TGATCAATTAGA ref:0:11:AATA ref:0:12:GTCGCAGCGG 3 3378 +GGT ref:0:3:TTGGGTCTCTGAGTG ref:0:2:CGCAAGCG 2 57 +TCGGTAGAGAT ref:0:11:GCA ref:0:10:AGTCTCCACTCA 6 1824 +GATCCCCCA ref:0:8:TTACGACG ref:0:9:CGTCC 4 5550 +TCCCGT ref:0:6:ACATG ref:0:5:GC 4 510 +CT ref:0:2:ACTGGGAAGA ref:0:1:TTATCCA 1 2 +TAAAACCTG ref:0:9:AGACGTTCAT ref:0:9:ATT 5 270 +CGG ref:0:3:GCGCGATTC ref:0:3:GAAAAAGGCCCATCCT 4 9 +CGAGCCCCTTGACAG ref:0:15:AGATTCTCAGTCA ref:0:14:GGCAC 6 14204 +GTGACTGCCC ref:0:10:TCATAGTCGTTAA ref:0:10:TACATTTAAGCCCC 4 1296 +GTACCCCAC ref:0:9:AGCGGAACATATGGCT ref:0:9:GAGTATTTCGTGAA 6 582390 +TCGC ref:0:4:CTTAGAGCAGCT ref:0:4:GCTGCGGGGT 3 34 +C ref:0:1:GAAGGCTC ref:0:1:GACAATCA 4 4 +GATTGTAG ref:0:8:T ref:0:8:ATGAATAT 3 12 +GAGA ref:0:4:TGGGTTG ref:0:4:CCTTTGT 5 1334 +CTGCC ref:0:4:ATCAAA ref:1:4:TTAACACG 2 14 +CTGGGTT ref:0:7:ACAG ref:0:7:GTACGGCGCTG 3 108 +AATTGGCACCAAACA ref:0:15:T ref:0:15:ATGTT 12 1028 +TGAGGACAACTATTTA ref:0:16:GGATGGTC ref:0:16:GTGCCGC 12 260496 +TGGTGGCAGAAA ref:0:12:CGTT ref:0:12:AT 10 1008 +GCTAACTCAGGC ref:0:11:TCGAG ref:0:12:CTGTTTCATAAGA 5 33358 +GCTCTAACTTCCCACT ref:0:16:AGACTGCATTTAATTA ref:0:16:CCTG 6 234 +TAGCTCGCGAT ref:0:11:CATCA ref:0:9:TG 5 30 +TCATA ref:0:5:ACATGCGTTCACT ref:0:4:GCCCGCGTCA 4 15 +GCTA ref:0:4:AA ref:0:4:CGAATAATTTGGCAA 2 365 +CTTAATCGCGCCTATA ref:0:16:TCC ref:0:16:CCA 12 360 +GATCCGAGTCAT ref:0:12:CCTTTGT ref:0:12:CGCCCAAAGCTGG 5 3102 +ATTCATAGTGTTTA ref:0:14:CTAAG ref:0:14:TGCCCGTAA 9 32965 +AATGGCAACAGG ref:0:10:GTCCTTGTGGCATC ref:0:12:AA 3 4590 +A ref:0:0:GCGC ref:0:1:ATACATCC 1 3 +TCC ref:0:3:TATGGACTCGTATCT ref:0:3:ATATCACCGGTAC 7 84 +TTCAT ref:0:4:CC ref:0:5:GAAAG 2 430 +CGCCCCGTTTATTTAC ref:0:16:TTGGCGTGGCATCCGC ref:0:16:CGAACT 8 190614 +CCTGTTCAGGCT ref:0:12:AGAAACCGTCTACA ref:0:12:AACGTG 6 112 +ACAGTGTT ref:0:8:GAGTGAC ref:0:8:GGGAA 6 1128 +GTTGAGA ref:0:7:CC ref:0:7:ACGTAATCGATT 4 612 +ACAACTT ref:0:7:CGCG ref:1:6:GTCCGCCGCTCG 5 3186 +CTATTCGACCG ref:0:11:TTACAAT ref:0:11:AGCTTTTTTTACCC 4 152880 +TTGTAAGGGCGGGA ref:0:14:GTGATCACTTAGGGAC ref:0:14:TCCAC 7 6080 +C ref:0:1:ATGTGGCTTTTTT ref:0:1:ATATGCCC 4 3 +CAACCATCGGATT ref:0:13:GAACCTAAAA ref:0:13:TACCTATCCCCTAGA 6 28380 +CT ref:0:2:TCC ref:0:2:AA 1 24 +T ref:0:1:GG ref:0:1:C 1 6 +CACT ref:0:4:CTCCATAAAAGCTC ref:0:4:TTAGAAAGACTTACG 7 930 +C ref:0:1:TACGGAGTGCGT ref:0:1:AGGCTGGAGAGTCTCA 8 6 +GTACGCCTCAGTCTGG ref:0:16:TCTGCTCG ref:1:15:ATCTATGGTGA 7 16206 +T ref:0:1:CAATGATGTGACCA ref:0:1:A 1 6 +ATGACCGATACAGGCA ref:0:16:TGTATGAGCGT ref:0:16:CCGCGGCAC 5 575 +GCGCTCGACTACA ref:0:13:GCGAGGGA ref:0:13:GA 8 5562 +ATCTTCGAAGCAGAC ref:0:15:GTATAGTCATATA ref:0:15:AAGAGAGA 6 12900 +TAACATGACACCAG ref:0:14:CTGA ref:0:14:CGAAGT 8 9 +GAGAACAGAGC ref:0:11:AGGATGG ref:0:11:ACACTTG 6 3960 +AAGC ref:0:4:AGATGACGGGGCCT ref:0:3:AT 1 135 +CG ref:0:2:T ref:0:2:AATGGCAATAGTCC 1 3 +TGATTG ref:0:6:TCTCCC ref:0:6:T 4 150 +ACT ref:0:3:TTAAATGAA ref:0:3:ATAACGCTTGG 3 72 +GTTGGGCCTACGTGA ref:0:15:TGGCACT ref:1:13:CTGGGGGGCTA 4 2412 +AGCAA ref:0:5:TATCT ref:0:5:CTCCGTAAT 3 162 +TA ref:1:1:CCG ref:0:2:C 2 12 +TGAGTAGGTGCGC ref:0:12:CTCCCCCATAC ref:1:11:CCATGGCCTC 6 18 +CGATGTGTT ref:0:9:GG ref:0:9:GGGGG 6 165 +TGACGTAACAT ref:0:11:CTTCTG ref:0:11:CT 7 18 +TGTACCTCAGG ref:0:11:GGTGCGACCGT ref:0:11:ATAGGGGG 2 910 +TTCTGCC ref:0:7:GGGGGGAAAAACCAA ref:0:7:GTTCCGAGGG 5 34272 +ACAAGCCGCCTCAAAA ref:0:16:TCT ref:0:16:GGTCTGTC 12 1287 +CGCTGAAGTCATGTG ref:0:15:GAGGGA ref:1:14:ACAATGTTACTTC 3 80 +GCCGGTTAAAATTTT ref:0:15:ACTG ref:0:15:AAGT 12 23104 +AAGAAC ref:0:6:G ref:0:6:CTACCAGT 3 4 +TCTGAACCG ref:0:9:AACGTATCATGATTC ref:0:8:A 2 52 +GCCATTA ref:0:7:CTAATCATAC ref:0:7:CGCAGAAC 3 288 +AGAGGG ref:0:6:CGCAAGTGCCCTC ref:0:6:C 3 329 +GATGT ref:0:5:CGGCATGC ref:0:5:AAGTTCA 1 48 +CTTTGATATATGC ref:0:13:ACATT ref:1:12:TTGG 5 18 +TATGTAAGCTAAAT ref:0:14:ACAACGGGAAGTGA ref:0:14:GCTCTTGC 6 3924 +TGAAGAA ref:0:7:CTT ref:0:7:GGGTATCAGAAA 2 168 +CGCGG ref:0:5:GCAACATG ref:0:5:GTT 3 322 +GAATCTTGGTCTGTGA ref:0:15:TCCTCGCG ref:0:16:CCG 9 124 +CGAGGTTGAGG ref:0:10:ACCATATGAGATC ref:0:11:AGTGCACACT 4 252 +GGCCA ref:0:5:ACGCCCCAGAGCT ref:0:5:CCACCGCGGA 5 4592 +CGACTCCATCC ref:1:10:AGCACCCTAACAAG ref:0:11:ATACACCCCGGATAA 4 690 +GA ref:0:1:GTCCTCGCC ref:1:1:CCACCTAG 4 4 +CAGTCCATG ref:0:9:CTGCGGCACA ref:0:9:GGGGTAGGC 4 3000 +CAACAGGACGG ref:0:11:C ref:0:11:AATT 8 393 +TATC ref:0:4:ACCTAT ref:0:4:CCAA 3 18 +C ref:0:1:CTCTCGTT ref:0:1:GTCGTAGT 4 3 +GGCCCTTACC ref:0:10:G ref:0:10:ACCCACCCCTCTACCA 1 512 +AAA ref:0:3:CTCTTTGAGGGGCCGA ref:0:3:GTAACAA 2 68 +ATTCAGTCGCG ref:1:10:CGCAGGA ref:0:11:AGT 4 2 +GGAATGATA ref:0:9:TAGCTTCGCC ref:0:9:GGT 5 4228 +AGTGTCTTACATTGG ref:1:14:CGCCCACA ref:0:15:GGTTA 6 438 +AGTTTGATGGGTTTA ref:1:14:TGCCTCCCTTT ref:1:14:CTGTTTCGGGTGAG 3 13140 +GAAAGCGAA ref:0:9:CATCAACCGCCTTTG ref:0:7:AGAGATCAG 1 80 +GTAATCAACCCGCT ref:0:14:TCGGA ref:2:12:TCCACACGCCG 5 256 +CAGCAGGGTGAATTA ref:0:15:ATAGTA ref:1:14:CT 8 213 +CGCGCGTCTGC ref:0:11:GCGGAAGCTAAA ref:0:11:CT 5 1050 +GTGAT ref:0:5:ACCGC ref:0:5:TATA 2 40 +G ref:0:1:AAT ref:0:1:GTCCCCGATT 2 8 +TT ref:0:2:CTCGCCC ref:0:2:TACATCTTATTTA 2 168 +TCTCGGCAATGCA ref:0:13:CTCCTGCCATTA ref:0:10:ATGGTCCTGCCTA 5 168375 +TACGCAG ref:0:7:CGAGAAGCCAC ref:1:6:C 2 370 +CGACTGGCAAA ref:0:11:TAGGGAAGATAGGT ref:0:11:TGAACTTG 3 2420 +TGATCC ref:0:6:GCATTCTGCCGGTTT ref:0:6:TTTG 2 147 +TGTTTGGGT ref:0:8:AACTCTAGATATCTG ref:0:9:GAGCAGGAGTATT 2 1386 +CTGACGGGTTGTG ref:0:13:ACCCGCAGTCG ref:0:13:T 7 6192 +CTTGCGA ref:0:7:CCGCGGACCTT ref:0:7:AGACGCTTCCCAG 1 256 +GCAAATCTTATCA ref:0:13:TA ref:1:12:ACTAGCCAAC 6 420 +AAAGTGAC ref:0:8:CTGTGTTG ref:2:6:CAGCGAATATTG 5 9600 +TCCCCGTTCGAACA ref:0:14:TTGGTAAAACGTCT ref:0:13:TTACGCT 9 37824 +GGT ref:0:3:A ref:0:3:CTGCAAA 3 132 +AACTAG ref:0:6:ATAACAGGCCCACT ref:0:6:AATACACGCGGTG 4 210 +AGCACG ref:0:6:A ref:0:6:TACTT 4 50 +TCATATGGACGAGGC ref:0:15:C ref:0:15:AGCTCCGCTC 10 10596 +ATAACATCGG ref:0:10:GTGCATGT ref:0:8:CGTGGCAGT 6 324 +CAGGGCCGTGG ref:0:11:ACTTATTAG ref:0:11:CGATAAAACCACCT 6 353720 +AAAAGTT ref:0:7:TGGGT ref:0:7:C 5 1088 +CCGCGAGGGGCTAC ref:0:14:AACTTCGTACAT ref:0:14:ATTCGGT 10 41144 +CCGAAGTGGATCTGA ref:0:15:GT ref:0:15:AT 12 80 +CGTTTTAA ref:0:6:TTTCC ref:1:7:GGGCTCCACCACATA 3 17718 +ACGAATAT ref:0:8:TTAGCCA ref:0:8:CTGCGTC 6 1539 +TCTCCTG ref:1:5:GCTGTTACTAC ref:0:7:GCGCTGA 3 224 +AT ref:0:2:TATGG ref:1:1:TTGG 2 2 +GTCAGGGAGTAGAAG ref:0:15:ACAAT ref:0:15:ATAC 10 60 +ATGCACCTCCTATT ref:0:14:GGCC ref:0:14:A 10 171 +AAGG ref:0:4:GCACACCTTTGT ref:0:4:C 2 40 +CAGGGATTCCGCGG ref:0:14:ATACC ref:0:14:GC 9 340 +C ref:0:1:CATCGGGACAAGG ref:0:1:GCTCTACCCTTA 5 15 +ATGACG ref:0:4:CG ref:0:6:GCCAGGACGTTAGC 2 18 +G ref:1:0:TACTATATA ref:0:1:CC 1 3 +CATAGCGTTCCTGGT ref:0:15:AGCAAGTCTATCC ref:1:11:AGTGTCCC 3 71 +TAAA ref:0:4:GTATCCTGATTCG ref:2:1:CGATCCTC 5 12 +T ref:0:1:AGGAGAGTA ref:0:1:ATTCACTTC 2 4 +CTGGAAGCATCGA ref:0:13:AG ref:0:13:GAACCAAT 6 120 +ACAA ref:0:4:TAGCTTGGTGCTC ref:1:3:GGTGGCTCCGCT 9 3472 +CTCGCCGCAC ref:0:10:CGGTATATACT ref:0:10:TTTTTCCCACCCATCT 4 12552 +AGCTTTATTCA ref:0:11:AT ref:0:9:GTGGCTCA 4 385 +TATAT ref:0:5:GAGATGATGA ref:0:5:CAGGT 3 126 +TG ref:0:2:TTGTCGGATATCAGG ref:0:2:GGGAAAT 5 126 +GTGAGCTTGTCGC ref:0:13:TCGGTGTCCCTGGTG ref:1:12:CATTGAAGAATTG 3 32160 +CGTGGCTCCGAA ref:0:12:ACTCTATAGG ref:0:10:T 6 2 +GTTCCGGACTGTCCAG ref:0:16:TGCACGCCTCGT ref:0:16:TTAAA 6 4312 +CCC ref:0:3:AA ref:0:3:AGCGGAGCGTCAGAA 2 10 +TCTCTCATTGCAATTT ref:0:16:CATGATGTTGAT ref:0:16:CG 8 1071 +ACCATGCCCTACGGT ref:0:15:ACTA ref:0:12:TTGACAGTGAGCT 5 300 +CCTAC ref:0:5:C ref:0:5:T 3 3 +TGAGAAACGTGAC ref:0:13:CCTGATGAT ref:1:12:AGAGTTCTG 5 782 +GGAGAGG ref:0:7:ACCCTTGT ref:0:7:CATTCC 7 31350 +GGGGAAC ref:0:7:ACCTGAGTCA ref:0:7:TAAACGATGCTGAA 6 7657 +CTCTCT ref:0:6:AGC ref:0:6:A 6 154 +GGTCCAAA ref:0:8:CGACATTTGTCTC ref:0:8:CTA 3 24 +CGCCCATG ref:0:8:GGCT ref:0:7:TTTCATTTCCTT 2 1320 +GCG ref:0:2:ACACT ref:0:3:AAGCTAGT 3 6 +GATCGCCGCG ref:0:10:CGGGATAG ref:0:10:CCGAGAGTACCA 7 16184 +GCGAAGAGGAGCC ref:2:11:ATTAT ref:0:13:CGCGTTAGCG 8 151440 +CAGTCCTGTGAC ref:0:12:ACAAAAGC ref:0:12:TATTCCAGACGCCGT 7 142080 +T ref:0:0:CGAGACGAGA ref:0:1:CGCAGTTCACAA 5 2 +GAAGCGATGCATGT ref:0:14:G ref:0:14:C 12 10 +TGGAGACGGTCTT ref:0:13:CAGTCGTT ref:0:13:CTGGCTCGAG 6 4275 +TA ref:0:2:TTTGGCTCGAGAA ref:0:1:C 1 24 +ATGGAATCTTCTCCTC ref:0:16:TTTGT ref:1:15:GGC 8 245 +TGCGTCGAGCGCGG ref:0:14:AGG ref:0:14:GCGATGCATTTACT 6 2496 +CTAAAC ref:0:6:CCACATT ref:0:6:C 3 120 +G ref:0:1:ACCCCTAACCC ref:0:1:GCCG 2 24 +ATTAGCACGGTCTA ref:0:13:TACT ref:0:14:TGGGT 6 64 +TCTGAC ref:0:6:TGTCTA ref:0:6:CAGA 1 4 +GTTTACTTTCCGTAA ref:0:15:CCGCAGCAATA ref:1:14:ATATACCTTC 3 630 +TTTA ref:0:4:CTTTGCCGTAAATAA ref:0:4:CAGCTGTAAGT 4 576 +CTTCGTAGACGTAT ref:0:14:GTCTA ref:0:14:CCATTGAT 6 108 +CGGCCACTT ref:0:9:GAG ref:0:9:TCGGTCCTACGT 2 27 +CATGCGTGTACAGT ref:0:14:GGT ref:0:14:GTAA 9 50 +ACAGACACGATATA ref:0:14:AGGGTA ref:0:14:G 9 116 +GATAAGCT ref:0:8:AGTCAGCG ref:0:8:ACATTCTAA 3 672 +TGAGGA ref:0:6:GGTGAT ref:1:5:AT 2 5 +AATGTTAA ref:0:8:GA ref:0:8:TTTCAAGA 2 6 +ATGCCGATTG ref:0:10:GTAAGAATCCAGGA ref:0:9:AAGACAGTGTTA 5 6615 +GGGCTATTGCTGACGA ref:0:15:TGGTACA ref:0:15:TAA 9 4 +ATTTAGACTTG ref:0:11:TTGTACCCTTC ref:0:11:CTAAC 3 396 +AAGGCGCAC ref:0:9:CTCG ref:1:7:CTAGACCAGGA 4 784 +AAATCATTCCAA ref:0:12:TTTCAGCTTGTCCTGT ref:0:12:GTCAA 4 22500 +GGATCTACT ref:0:8:TAGGGAAAATTAAAG ref:0:9:TTGTA 3 2484 +CCCAAATATTAC ref:0:12:GTTTCCGGTCAAGTG ref:0:11:AATTGAA 4 5320 +GTCTGGC ref:0:7:CGGTCCAGCGTTAG ref:0:7:AAGGTC 3 3900 +AGCCAGCCTAGGGGTC ref:0:16:AC ref:1:15:ATTA 11 63 +CAAGGTA ref:0:7:CCTAGCGACGGCG ref:1:6:A 2 69 +TGACAG ref:0:6:CGAACGACATT ref:0:6:AT 3 518 +GGGATGGCATAA ref:0:12:TAACTTACAC ref:0:12:AATATCTCGCTGGAGG 7 180608 +ACTATTCGG ref:0:9:GGGGATGGAATCGGG ref:0:9:AGCGAA 3 855 +AAAG ref:1:3:TAACCTCGGG ref:0:4:AGCCACGCGAGAAAAG 1 108 +AGACATTTTAGTCCCA ref:0:16:TTACCCAACG ref:0:16:AAT 7 216 +ATCACCAT ref:0:8:GCCGTACGAAGCCACG ref:0:8:TTCCACC 2 216 +G ref:0:0:CACT ref:0:1:GAATGCA 2 2 +ATTGGTTCGAAATT ref:0:14:CTTCTA ref:0:14:GTCAGGGTAAAGG 7 163800 +CGCGCAGAACATAAC ref:0:15:TTATACTTCTGCGTG ref:0:15:ACA 6 108 +GTACT ref:0:5:AGGAGGCCTAAACATC ref:0:5:TTAATTGAAGGGGC 3 732 +ACTCACCTTG ref:0:10:CATAGTTGTCG ref:0:9:TAAC 3 270 +C ref:0:0:AAGTG ref:0:1:TGCCTCGTAACTTC 3 5 +A ref:0:1:TAAC ref:0:1:CCAAGACTGGCGG 2 6 +AGGCACTTACGT ref:0:12:GTCGCTTCAC ref:0:12:CCAAAAG 4 1488 +TGCCC ref:0:5:GAGCCT ref:0:5:GCTCT 3 90 +GAG ref:0:3:GTGAA ref:0:3:TGGGCTC 1 32 +GC ref:0:2:GGGACGCAAT ref:0:2:TGGACACCTGGTAA 5 42 +CT ref:0:2:GAAG ref:0:2:AGGATGCAGC 5 150 +AC ref:0:2:CTCCT ref:0:2:TTACTAAA 2 8 +T ref:0:1:CC ref:0:1:TGACT 1 6 +CTTCCCTCGCGCCT ref:0:14:TTCAACGGTG ref:0:14:TAAA 9 22560 +CCTGTTGGCGGCTC ref:0:14:CACGCT ref:0:14:GCT 9 304 +TACCACGCCGA ref:0:11:AATTCAATTTCAGACC ref:0:11:TTGACAGGTCTT 5 23408 +TAGAGGGGCTTCCA ref:0:13:AGCGCT ref:0:14:ACATT 7 272 +C ref:0:1:CACTCCG ref:1:0:AGAA 2 4 +CAGTAAA ref:0:7:AAGAGGCAGGG ref:1:6:TAATGATACGTA 3 476 +TAAACT ref:0:6:GTCCTGCGACCCAG ref:1:5:CAGGG 6 92180 +ATGTAC ref:0:6:TAACCTCTAG ref:0:6:GCC 1 32 +CCCAATAT ref:0:8:GCAACGG ref:0:8:ACCCGCCA 4 10752 +AGGGTCTCCATG ref:1:11:A ref:0:11:TGGGACCGTGCCTTA 2 40 +TCGGATCTTAGGT ref:0:13:ATTTGAATAGCGGTCT ref:1:12:ATTTTACCGGCTTCG 7 12880 +AG ref:0:2:ATCAACCCTGATACGT ref:0:2:GCGATATAGA 5 24 +TTG ref:0:2:TTTCTCTA ref:0:3:TATCCTGTCCCTT 3 30 +GCCA ref:0:3:CGCATCCCCGCGGTC ref:0:4:AACTGCGT 4 396 +TAGGG ref:0:4:CACCGTGTCAA ref:0:5:CATAGAACTT 3 56 +CAGTCT ref:0:6:ACTTGGCTAG ref:0:6:GAAAA 3 3850 +AGTCAATAGCGAGACT ref:2:14:CTCTATGAA ref:1:15:TGATTCTTTAACAC 6 1840 +TCGC ref:0:4:CGCCGTTTATCTA ref:0:4:AGCTAGGT 4 330 +AAAAAAATAGTAACCT ref:0:16:G ref:0:16:GAGCCTTAGCAGTAC 9 52804 +CCGCCTTTAAGCAGT ref:0:15:ATTATTGTAATCTACG ref:0:15:G 7 1350 +CACAGTCAAATC ref:0:12:CATTATATCG ref:0:12:TGTTTATTACGGT 7 57800 +TGGGCTCC ref:1:7:GA ref:0:8:TCCT 4 180 +A ref:0:1:T ref:0:1:GTCTTCGTATA 1 4 +GTACTTTGAGGG ref:0:12:T ref:0:12:CTCCCCTTCCG 7 11728 +CGCCTGCC ref:0:8:GCACGGTTGTACTGT ref:0:8:GTCACCACACGAACTA 5 7826 +TGCGTCTTCCTTCCC ref:0:15:TTCACCAACTG ref:0:15:GAAAACCA 10 8300501 +CGTCTTCCA ref:0:9:TAGAAGA ref:0:8:ACGGG 8 26532 +TAGTGT ref:0:6:ATGAAGAGGCCCG ref:0:6:CAGTTGTCGCA 2 440 +ATACATCA ref:0:8:CCTAGCCTCTTGCT ref:0:8:CTTTGATATG 5 23040 +AG ref:0:1:ATA ref:0:2:TCGGTGCTCAGT 1 2 +A ref:0:1:TC ref:0:1:AGGCAGTGCCAGTAGA 2 15 +CAATAGGACTAA ref:0:12:ATCTAAATTAGA ref:0:12:GGTGTGCCGTCAAG 2 5370 +CGTAGACCGGGAGG ref:0:14:GACTGACGGA ref:0:14:TGATTTTCAATTC 6 6714 +TGCGA ref:0:5:GCCCGATAA ref:0:5:GGCCCCGATCGGACTC 5 639 +T ref:0:1:AGACACGTC ref:0:1:TTCT 1 3 +AATGTTCTGCGATA ref:0:14:CTAGGCTGGC ref:0:14:GTATGTTTGGAGACGC 5 1584 +AACTGGGGGTTCA ref:0:13:TCTGCGTAT ref:0:12:GCGCAGACC 7 283500 +CCCGTTATATGTCCG ref:1:14:ATCCGCAGATC ref:0:15:ACGGCCTGC 6 560 +TGGCTTGGGAGT ref:0:11:CCACCAGTCTGTCG ref:0:12:CATCAATCCA 9 597308 +G ref:0:1:TAACTC ref:0:1:CTGTCAACA 4 7 +GACGACCTAT ref:0:10:GGAACCCG ref:0:10:GCCG 6 1760 +CGCAAATCGAAGT ref:0:13:ATCACCCTAGTGTGGT ref:0:12:CTTCGCTCATCAA 4 82446 +TCACTCAGTG ref:0:10:GCACATAGTCC ref:0:10:GGCCTATAAAGA 3 18 +GAT ref:0:3:ATTGACAACCTAGATA ref:0:2:TTGTTGAA 4 36 +CAAAAGAAAGTGCT ref:0:14:CCGCGATGACC ref:1:13:TTAATGCCTC 7 206190 +ATAGCAATACTG ref:0:12:CCTGC ref:0:12:TTTTACTATCGC 5 50 +AGGGAT ref:0:6:A ref:0:6:TCT 4 44 +AGCCCGTA ref:0:8:A ref:0:8:CTATCACACAATGAT 2 20 +CCACA ref:0:5:G ref:0:5:GGCCA 3 36 +TAAAGCGTTATTTTCT ref:1:15:AACCATGAAATCAA ref:0:16:AATAC 8 90864 +GTA ref:0:3:GGAGA ref:0:3:CGGAATGTTGCCC 3 627 +AACC ref:0:4:ACAATCACAAGCCGCT ref:0:2:CGCAAG 3 75 +CAAAATAGG ref:0:9:ACCCCCCGTTGAAT ref:1:6:TACGACCGA 5 45080 +CCGAGTAAATACGGGT ref:0:16:AGCCGGG ref:0:16:AGC 10 8 +TTGGTCCT ref:0:8:TCCTG ref:0:8:TGG 2 6 +CGCGT ref:0:5:GGGCGGTG ref:0:4:GGGCTGGTACGCA 3 26 +CGGTACGCCA ref:0:10:GGCAGGAGCTAGCTC ref:0:10:GGGTC 3 60 +CTTCGTGCTAT ref:0:11:CGC ref:0:11:TTCATGATAGAGCTGA 2 8 +GACGATGACCCCAAAG ref:0:16:TTAACCAAGTTAT ref:1:15:GGAATA 7 7400 +ATGGTAAATGT ref:0:11:GGTATGGTGCA ref:0:11:AGC 5 150 +CCACGTTCCGCGG ref:0:13:TCTGCGAT ref:0:10:TTCAACGCCA 3 1512 +GAGTT ref:1:4:TAGTACACAGCGATA ref:0:5:CCCCCGCT 1 70 +TAAAAA ref:0:6:CT ref:0:6:ATCATT 4 154 +GCTCG ref:0:5:CGATTCCTAGTGCTT ref:0:5:AACACGAGAATC 5 1568 +GCCTATC ref:0:7:TGAATCTGAGCC ref:0:7:TGACAACGGGTGGA 5 25 +A ref:0:1:GCGG ref:0:1:TGCTC 3 30 +AAGATAGCT ref:0:9:G ref:0:8:GAAGCTAGCGAAGA 1 4 +CTATTTT ref:0:7:TCGTATTTGCCAG ref:0:7:TAAACAC 3 2169 +CTTTGGG ref:0:7:TTTGAGGGACGTTACT ref:0:7:GCGAAGA 3 70 +GAGGGAGC ref:0:8:ACAATTGGGCAA ref:2:6:A 2 86 +TCGGTTGGAAGCTT ref:0:14:GAAAA ref:0:14:GTGGAGCTGCACC 6 11648 +CTGTAA ref:0:6:ATAAAACATTA ref:0:6:GACTGTTGG 2 32 +GAAA ref:0:4:ATACCGACAGTGT ref:1:3:AAAAATCGC 3 140 +GTCAGACGGACAAAG ref:0:15:GAT ref:0:15:AGATTTA 12 44640 +GG ref:0:2:GCTGATTTGGCACAT ref:0:2:GACGGCATATGTTCCC 7 36 +ATACGACTGC ref:0:10:CCAA ref:0:10:GATGTTT 5 1525 +AGTCGAGGAA ref:0:10:TTCGCTTACCAGGG ref:0:10:CCTCG 6 3168 +TATACCTTAAT ref:0:11:CCATAACATCATCGTA ref:0:11:GTAG 4 1918 +CTAATGTGCA ref:0:10:TGTTGTCGTGCCGAAA ref:0:10:GACATTGT 3 15066 +GGGTAGCTGT ref:0:10:TCCGTCGTTGA ref:0:10:A 4 366 +ATACCCTGGC ref:0:9:AAAGTAGGT ref:1:9:AT 4 25 +ATTTGTCCGGCA ref:0:12:CCGTACACGAC ref:0:12:CAGGCGTCCAAATCT 8 117900 +ACTGGTTAACAG ref:1:11:GAGATGATACA ref:0:12:TG 3 30 +ACAGCTTC ref:0:8:CCCGTCTAA ref:0:8:C 4 531 +AGAAGGCGCGCGAAG ref:0:15:GGCCAAGAAGC ref:0:15:GCTACATTAAA 9 116250 +TAAACACACC ref:0:10:CAACCGGCGGT ref:0:10:GAACGAA 3 1078 +CACTTTGGAGGC ref:0:12:CGTTACC ref:2:9:T 6 168 +CGGATGT ref:0:7:CCTTAACCA ref:0:7:CTAACGCGGTAG 3 90 +TGCCACCC ref:0:8:TTTCA ref:0:8:AAATGTGT 6 1568 +TGGGGCAGTTATGAC ref:0:15:TTCCCCGAGAACCA ref:0:14:CATCTGCATCAA 7 138446 +TAGTTCCGGC ref:1:9:GCCGCTGCGG ref:0:10:GTCAACGACCT 3 14 +ACCCAAGCT ref:0:9:TGACAGC ref:0:9:GCGAATGGAAAGGA 5 38964 +AGGAAACAGCGC ref:0:12:CCGCTTGCTATA ref:0:12:GCGT 8 162 +C ref:0:1:GCATCCTCAACCGGT ref:0:1:G 1 12 +CATGACC ref:0:7:ATGAA ref:0:7:T 3 4 +ATTTGGAA ref:0:8:CTCAGGTTG ref:0:8:CCGGGGAAGGAAGGC 3 70 +AGACGAGTC ref:0:9:TATTATCTACATTA ref:0:9:A 4 879 +CAGATA ref:0:6:TGCCTGTGCTC ref:0:6:GCCACGCTCAA 5 1010 +GGGAGGCGG ref:0:8:TATGCCGATCATCGA ref:0:9:AGTGAATTATGTAC 6 25715 +TT ref:0:2:CACTGG ref:0:2:ACTCACATACAA 3 7 +TGGTCGTGACCATCGG ref:0:16:TTATCA ref:0:16:ACGGCCC 7 165 +AATCTTAAACAA ref:0:12:CGTAGGCCGCCTGCC ref:0:12:GATGGAC 9 4803750 +ACGACTCC ref:0:8:TCCGACCTT ref:0:8:TGTTCATTAGTC 4 30745 +CACCCG ref:0:6:TCCATTGCCACCC ref:0:6:TCGGAACCTGAAT 2 306 +GTTTC ref:1:4:TACACGCAGCC ref:0:5:TGCTTTAGGAGAAGT 5 2210 +TTCC ref:0:4:TACTTACA ref:0:4:GGA 2 560 +TATAATCGGAAG ref:0:12:TGCCC ref:0:12:C 10 668 +GCC ref:0:3:ATAACATAGAAGT ref:0:3:CGTCTTGT 5 624 +AGT ref:0:3:ACTACCAATCCA ref:0:3:CC 3 180 +ACATAC ref:0:6:GCTG ref:0:6:CAAAACAGGAGGG 2 384 +GGGGCCAA ref:1:7:TGTCTGCACGCGGC ref:0:8:GGTAAAATGTG 4 278 +AGAGAGCAC ref:0:9:ATGGCGCTG ref:0:9:CTGTTTACGTTATA 3 234 +T ref:0:1:GATAAGTGGTTGTACA ref:0:1:G 1 10 +TGAC ref:0:4:AGTG ref:0:4:CCAATCATTGTAAA 2 18 +GGTCATTGGAAG ref:0:12:CTCAGACGG ref:0:12:GGGGGTGC 4 1530 +CGTACATCGTCAGA ref:0:14:ACAGTGTAGAAC ref:0:14:AGCGTGGTG 6 56 +CCCCTAAAAATCGGCT ref:0:14:ATCGGT ref:0:15:ATCCTTACGACACCG 4 48150 +TCCAAAGCCGGTCGC ref:0:15:GGAGAGCCGGGCCGCA ref:0:15:AGGTCGTTACTAC 5 240570 +GAAAGGGCCGAAC ref:0:13:TACTTACG ref:0:13:GCTCT 9 14560 +AG ref:0:2:GTGTG ref:0:2:TATAAATTTTTGATA 2 36 +CTGCAGGACGCGGGAA ref:0:16:GGAACT ref:0:16:TCGATCA 9 3792 +TAGGCCCTTGT ref:0:11:CG ref:1:10:GACTGGAA 6 918 +CATAGACTAG ref:0:10:G ref:0:10:ATCATGCGACGGT 3 76 +A ref:0:1:CAGAGGAGTGTTGG ref:0:1:TGATACAAGC 3 12 +ATTT ref:1:3:TTCCGTCGTTAATCG ref:0:4:GCCTC 3 1040 +AGAAGACGAGCGGCCA ref:0:16:AACCCCGGGATG ref:0:16:CACGGTTGTCGGAT 8 286900 +TGTCTCCG ref:0:8:AAGTACGCCGCGAC ref:0:8:CTTGAATATATT 2 4526 +ATTTAGA ref:0:7:CCATGGAAC ref:0:7:GACAACTGAAATCT 6 13260 +G ref:0:1:ACCGCGCGACATT ref:0:1:ACAGAAAGTAAAC 5 6 +GAGGCTCCATCTTTCT ref:0:16:CCCCAAACGCAA ref:0:16:TATCTACCCCGC 10 128304 +CAACAACAAGCAAT ref:0:14:TCCTGTACGGGAAA ref:0:14:CGTGGGTT 10 3407250 +TGCCCGCTTCACGC ref:0:14:CTCTCG ref:0:14:AGCCTTAGTGCA 5 4416 +GTCGCCGGC ref:0:9:ACGCAGAATGTG ref:0:9:GGAGGCATACCG 5 24187 +GGAAGGCCCA ref:1:9:TTGATCCTCG ref:0:10:ATGTCCGAGCTAC 5 770 +T ref:0:1:ATGGGCG ref:0:1:C 1 2 +GGATGGCTTATTGA ref:0:9:CCTGATCCG ref:0:14:GCAAGGGGCG 3 9025 +CCTTTCGCTCGTTCT ref:0:15:GTCTGCACTCAGTC ref:0:15:AATAAATGGCATCAGT 8 116424 +AATC ref:0:4:ACATAATCCT ref:0:4:TAGG 1 364 +CACAAGTGAAGTCTA ref:0:15:AACGATCTT ref:0:14:CTGTCGC 6 8160 +CCGGG ref:0:5:CACCA ref:0:5:TA 4 378 +AGATACTGCTT ref:0:11:TCGGCTG ref:0:11:TAATGGTG 6 945 +TCCTCGAGTTAACCA ref:0:15:AGATAG ref:0:15:AAT 12 5635 +AAGTGCAA ref:0:6:TATG ref:0:8:ACCGTA 2 24 +CTGGCGGTGCGGAGAT ref:0:16:GGATTAA ref:0:16:CGTCACCGACAACTA 8 202168 +CTTCATTGATA ref:0:11:ACGCCGACTCGTT ref:0:11:CCC 6 2040 +GTTG ref:0:2:GCGTCAACAG ref:0:4:TCGTGTTAGCGGCA 2 24 +ACAC ref:0:4:TGTACAGTGTCCCCG ref:0:4:TGCCCTTAGCG 4 48 +CGACGTGGTATATGAG ref:0:16:TTGC ref:0:16:GAGCG 11 1896 +GTCACTACTA ref:0:10:CAATATTTAAGGCC ref:0:10:TCATTC 4 216 +TCTG ref:0:3:AAAA ref:0:4:TGAACTCGCTCGACTA 2 245 +CCGCGTCCGGCTCTT ref:0:15:TATTGGCCGC ref:0:15:CAAATGTCATAG 6 35400 +CTGTG ref:0:5:AATACTGTTAA ref:0:4:TACAATTAA 4 7 +GTCC ref:0:4:CACT ref:1:3:AACT 3 13 +GTACTGTCG ref:0:9:TACCCCTTAGGT ref:0:9:CACCGA 2 132 +ACCGCGA ref:0:6:CTGT ref:0:7:TCGCCGTT 3 612 +AGATGA ref:0:6:CCGA ref:0:6:TGACGGTCT 3 1848 +CGGGTGAACGCCTGA ref:0:15:ATCAGATC ref:0:15:CACTAAAATCG 11 2301904 +ACTAGTATC ref:0:9:GATCG ref:0:9:TCGAGACTGCGTGAG 4 29 +AAAGTATACT ref:0:10:A ref:0:10:GCAAACTAGCCCCTAC 2 10 +CCCGTG ref:0:6:CCACC ref:0:6:GGAC 2 7 +ATC ref:0:3:G ref:0:3:CATTGTGCTG 1 12 +CCTTCTTGGCGGAC ref:0:14:TAACAAGA ref:0:14:CTCTAAATCGGTTCT 6 6240 +CG ref:0:2:AGTTGAATAGACGCAG ref:0:2:AGCCA 4 21 +GGAACAAAAAGGC ref:0:13:GTAAGTTCCTTT ref:0:13:CACCCTTTGCA 8 15592620 +CAT ref:0:3:ATAGCCACA ref:0:3:AGCCATGACT 4 60 +CC ref:0:2:TCGCCGGAAGT ref:0:2:CTGTTTCAGACATTTT 5 9 +AC ref:0:2:CGCGCTTGC ref:0:2:CGCTGCCCG 6 450 +ATTGA ref:0:5:TC ref:0:5:G 3 7 +GAGTGTTTACCACTG ref:0:13:CTTGAAGCGG ref:0:15:T 8 315 +CGCGC ref:0:5:GCTTGTGACT ref:0:5:GCATCAATGTTCC 4 48 +ATAA ref:0:4:CTACCTTT ref:0:4:AACTTCGCTG 5 2760 +CCTGAGTG ref:0:7:ACGCGGC ref:0:8:ATGTGAGCATC 3 64 +TTACGA ref:0:6:AGTCAGTGGGCGTTG ref:0:6:AACAGGAGCAT 3 900 +GAATAAAAGCTAAAC ref:0:15:TTG ref:1:14:TGACGAGAGATAGAT 7 2366 +ACTAGGATACCCG ref:0:12:AGTC ref:0:13:CTCTCCCTATACCCT 3 6552 +TGCGGTTA ref:1:7:GT ref:0:8:AAA 4 270 +CTTGTTTTGCT ref:0:10:GACACCGGGA ref:0:11:CT 7 1840 +CGATACCTTATACG ref:0:14:AACCGACCTAGAT ref:1:13:GGGT 7 13205 +CAATT ref:0:5:AGAAAACCATAAGAT ref:0:4:ATTTAGAAGTGG 4 1760 +GTTCACATTCAG ref:0:11:C ref:0:12:ACGGACTGCCCA 5 402 +CCAATA ref:0:5:TAA ref:0:6:TGTGAGCCTTCGAG 1 12 +GAATAT ref:0:6:TTTG ref:0:6:AACCTG 3 77 +CCCGAGGGT ref:0:9:TGTCTT ref:0:9:TGGATTACAG 8 467677 +GCCCGAAATGGG ref:0:12:AATAAG ref:0:12:GGTTGCCGCGAGCTC 3 16065 +AGCGGGTTGGCA ref:0:12:GGCTTAAGAAACGCAT ref:0:12:TCACCCGAATTC 2 1053 +GCCTCG ref:0:6:TA ref:0:6:TTGATCCGTGGCAT 2 18 +C ref:0:1:CTTC ref:0:1:ACGGATAATTT 2 2 +TGTATT ref:0:6:CCGCAT ref:0:6:AAGCAACCTAA 4 1296 +CTTGAGAGGGGAG ref:0:13:TCG ref:1:12:GGATC 9 6862 +A ref:0:1:TCGCCATGT ref:0:1:TTCGGATC 4 1 +TACTATGCCGGC ref:0:12:GTCT ref:0:12:TCC 8 24 +ATAGACG ref:0:7:TAGTGACGTTCA ref:0:7:CTGACGATGGCTTTTA 4 84 +TAGCTCCTGGGTAG ref:0:14:TCATGATTG ref:0:14:T 8 1408 +CGCTGTTCCGACGT ref:0:14:ACCTTGGCGAG ref:0:14:CTT 6 420 +G ref:0:1:CTCCCAATGGGA ref:0:1:GCGCCC 1 6 +GGTTTCTGTAACAA ref:0:14:ATCCGTT ref:0:14:GGACG 9 7832 +AGGTGCAA ref:0:6:ACCTACCGGTCCC ref:0:8:GCAG 1 108 +GGTGCTTC ref:0:8:AGGCTCC ref:0:8:GGGTAGAACGT 1 189 +TCGTTGGGTATAGGA ref:0:15:CTCAAGGTCCACAATA ref:0:15:CGGAGCGGCGGTGC 6 7844736 +ATAGCTTGCGAATGTC ref:3:13:CATTGGCAGTAG ref:0:16:TTGGTA 6 1638 +ACTCCCTAATA ref:0:11:GATTAG ref:0:11:CATTGATC 6 120 +TGCTA ref:0:5:G ref:0:5:CTT 2 4 +AGG ref:0:2:TTCTGCACGC ref:0:3:TGGTTGTAAGGAGCC 4 6 +CAGGATAAA ref:0:9:TGCGAGGT ref:0:9:GC 5 14 +CGAATAGCGCGCCACT ref:0:15:ACGCACTCCATTACA ref:0:16:AATGACTTA 5 3480 +CTGGTG ref:0:6:GTGA ref:1:5: 2 2 +GACAGGT ref:0:7:CAATCGTC ref:0:7:AGCGCAG 2 432 +GGGCGA ref:0:6:AGCTGGGTTCGC ref:0:6:ACTCTTTT 4 3304 +AATGCCG ref:0:7:GAGGGAGGCAGTT ref:2:5:GGTTCAATTCTTTT 5 300 +CCAATTGTAT ref:0:10:TGCACTCTTACCGTCA ref:0:10:GGA 4 603 +ACGC ref:0:3:TGTACT ref:0:4:GCACGCT 1 2 +TACGACACAGGC ref:0:12:G ref:0:12:ATCCTTTAA 6 6 +AGGTGGAGGCA ref:0:11:GATGCAT ref:0:11:C 6 28 +CAAACGCAAACGAGAA ref:0:16:CCACACCAGAGG ref:0:16:GCCCAG 7 3024 +ACTAAGGAC ref:3:6:AGTCAG ref:0:9:AACGGCATAATA 3 360 +AGGGATTTCAC ref:1:10:ATTCACAAGTA ref:0:11:CCAGTATTGACC 3 387 +TGCCGGACTGGTT ref:0:13:GCACAACAGCGGCC ref:0:13:AGACC 7 38808 +GTTTAAGG ref:0:8:ATGTAACA ref:0:8:GCGTCATCAGAGGCG 2 4242 +CTATTTG ref:0:7:TCAT ref:0:7:AGG 3 30 +GCCTT ref:0:5:GAAGCCAAACCA ref:0:5:TCGAC 3 490 +A ref:1:0:TCCGT ref:0:1:ACGCTATTACA 3 4 +CAAGT ref:1:4:TGGGGGGTGAA ref:0:5:AGGAACTGACTT 2 1008 +AACTGCTAACG ref:0:11:CA ref:0:10:CGCAGACGTACTAT 3 76 +CCCTGTGCGCGTCG ref:0:13:GCTGTCGCGA ref:0:14:AGGCGTAAGTGGTGAG 6 8964 +CTTGATAAGGTTT ref:0:13:TG ref:3:10:GCGCTTGAAGA 5 1008 +ATTT ref:0:4:AGAAGTTCGCATTGG ref:0:3:AACACCGTCATGG 5 36 +CCGG ref:0:4:CCCATTGT ref:0:4:GGTTCAACTA 2 133 +CAGAAC ref:0:6:CAGCAAGAAGTCGATG ref:1:5:GAGCGATCCGAGG 6 286 +TCACTAGTC ref:0:9:GCTTTGTACCCATCGG ref:0:9:ATTGTGACGG 3 550 +TTGTCACGTTAGGGG ref:0:15:ACAGACCAAAT ref:0:15:GTGCCTCCCCTCG 8 41275524 +A ref:0:1:TATAACTACCGTATT ref:0:1:GTACGAAAAAA 5 35 +TGTCAG ref:0:6:TTGCT ref:0:6:TCACACAC 2 1176 +TAA ref:0:3:ATATTACTCAATATC ref:1:2:GGAAAAGAA 3 375 +GATGCTAACTAAG ref:0:13:CAACGTCA ref:0:13:TATAGCA 6 210 +TGTCCGCGGTATGC ref:0:14:GGGAATTTCCT ref:0:14:CTCTGATACGT 7 533544 +CGGCGGGCCTAA ref:0:12:GGAGA ref:0:12:GTC 7 2622 +GTGGGTTTCTCTCG ref:0:14:ACGGTGTTTTGG ref:0:14:T 6 2082 +AAAGGCCAGAAATA ref:0:14:TCATATCGAACGAC ref:0:14:AGT 6 6600 +AACTTC ref:0:6:ACCCCCAAGTAAACGG ref:0:6:TTT 1 1610 +AAGGACTAA ref:0:9:CAGACTTGCAACACCT ref:0:9:CAAC 3 180 +CC ref:0:2:TGATGACGTAG ref:0:2:TGGCCTGAGCG 6 36 +TGAGAGG ref:0:7:AAGCTTTTC ref:0:7:GAAAACCGGT 3 80 +TG ref:0:2:CA ref:0:2:GTCGACG 2 12 +AACCTTTGACTTCCA ref:0:15:AAAACCTATTG ref:0:15:ACAGGC 7 40482 +CCAGTTTA ref:1:6:TACAT ref:0:8:TATGATCAG 3 147 +ATTGTCGG ref:0:8:GTCATTTCGTTCT ref:0:8:ACACTGGCGATCT 5 6240 +ATATGTGGAACTCGG ref:0:15:CGCGGTGTCG ref:2:13:GCAGGTGCAA 7 7900 +CATG ref:0:4:GACAAGCCG ref:0:3:CAGACATA 3 48 +GTACACCA ref:1:7:CATACG ref:0:8:TGTTATTCTCCCC 2 3224 +GA ref:0:2:CCGCCGGGCACTG ref:0:2:CTTGAATTCGG 3 8 +TGTGATCGGATGGAAG ref:0:16:GCCCTAT ref:0:16:GCGGCAC 11 82634 +CTAAACCA ref:1:7:AGGATCTGAGGA ref:0:8:GGTTGC 3 9102 +CGCCGTCA ref:0:8:AGC ref:0:8:GGCCGCTTGCGGTGGG 2 902 +TC ref:0:2:GGCCTTA ref:0:2:AGAA 3 180 +GTTTTCAGTTAGC ref:0:10:TCGT ref:0:12:ATGATAGGTAGGA 4 3680 +CCACATAAAATTGAGT ref:0:15:CGACGTATTACGGC ref:0:16:AGACCAAGGCGG 7 1784376 +TCATTCTATTCGATC ref:0:15:ATCGTT ref:0:15:AAAGA 8 744 +GGAACGGAAAAT ref:0:12:GACCGAGACCAGCG ref:0:12:GC 5 3636 +GAGGGTACTAG ref:1:10:TCGCGCGTCAAGGC ref:0:11:GTTA 2 96 +AGATCAACG ref:0:9:GTCTCTTCATC ref:2:7:CTT 5 2541 +TTCCATGGCGCGA ref:0:13:GAGAAAC ref:0:13:CT 8 1220 +GCTGACAGGAGGATAG ref:0:16:CGTTAAATT ref:0:16:CGTCCACTTGGTTGAT 7 111296 +ACAAGGTCCGATTTG ref:0:15:ATTTT ref:0:15:AATGTGCCCGTTTGA 4 147 +TGCCACAATACA ref:0:12:C ref:0:12:AACCG 9 224 +CGC ref:0:3:CGGGAACGAGCAATAA ref:0:3:TTACT 2 130 +GTG ref:0:3:GAAGTCCAA ref:0:3:ATGT 2 39 +TTGTTGGGGCTCAAG ref:0:15:ATGACGTAACTA ref:0:14:TCATTAGTGTAGGGG 5 25074 +CGATAGTTGCTC ref:0:12:TCCATG ref:0:12:TAGCTGACGGGGG 6 1776 +GTTG ref:0:4:GCCA ref:0:3:AGGACAGGTCGTC 2 84 +ATTG ref:0:4:AAAGCTGTTC ref:0:4:CGTCGTCCCGGTGC 4 648 +TGAATCCT ref:0:8:AT ref:0:8:GTCCGTAAAGAC 2 156 +AGACAATGTGC ref:0:11:ATAGGTGACTA ref:0:11:GCTCATTTAT 5 31390 +TCGTGA ref:0:6:GGATAGAC ref:0:6:CTAAGT 2 36 +GCGGA ref:1:2:CATTAACAGTAA ref:0:5:GAATGCGGATACT 2 8 +CATTATTCTCCTCGTA ref:0:16:AGCATCTAGGGC ref:0:16:CCC 10 103700 +TCCGGGGCCC ref:0:10:ATTGTTATGGTAGG ref:0:10:ACGAACCCCCATGCC 5 1712868 +T ref:0:1:CCACGTT ref:0:1:CTGGCC 1 2 +CACT ref:0:4:CAACAGCAAGAC ref:0:3:TAA 1 385 +CGAG ref:0:4:TCGTTCCA ref:0:3:TCCTGGAT 1 4 +TTGAAAA ref:0:7:AAAACATAGCCA ref:0:7:ACACGCGCTA 7 1320 +TCC ref:1:2:AAGGAC ref:1:2:ACTAT 2 42 +TCCACAACG ref:1:8:ATT ref:0:9:AGGGTAAA 5 37 +TTTACGCTTGCCCCAG ref:0:16:CGAGC ref:0:15:CCC 10 380 +GTGTTTAGTGGGACC ref:0:15:AGCTTGAAT ref:0:15:CTCACTCGGGTGTGT 10 145901900 +CGTGCGTCAT ref:0:10:TA ref:0:10:TTAAGCGTC 3 8 +ATTGCCACGTTAGGA ref:0:15:CT ref:0:15:GGCCCTCACT 9 1560 +AGCGCGGGTCGAC ref:0:11:TGATCACATC ref:0:13:CTTGTCCTAGATA 8 16256 +ATCGCCTGGACTGAT ref:3:12:ACACGGGGGCAC ref:0:15:TATTAACTA 3 1296 +GGCTCCGGGAAG ref:0:12:CTCTTTAACCAGAGCC ref:0:12:ACGTGGGAGT 3 4522 +GATCGCTGCAG ref:0:11:AGG ref:0:11:ATCT 5 6 +GCATTTTGCACTACCC ref:0:16:AGG ref:0:16:CGAAGTTAGAATAC 8 15660 +GGAGCCCGAATACTAG ref:0:16:TCATAATAACCATGTA ref:0:16:GAATCAACTGCCA 9 2838582 +TTTTGTCGT ref:0:9:CTCATCCATCGCGC ref:0:7:TTCGACCTAACC 2 440 +AATA ref:1:3:GCAT ref:0:4:CTCGTGTTGG 2 337 +TCCAC ref:0:5:CACTACTAAG ref:0:5:TAATCACATT 2 13 +TCTTGC ref:0:6:A ref:0:6:TATAAAGA 4 168 +CA ref:0:2:ATGGGAATAG ref:0:2:TT 3 138 +TTTAATT ref:0:5:GGGTTATTTGACGC ref:0:7:AGACAGCT 5 3550 +GGGCTGGG ref:0:8:CGGC ref:0:8:TTTACTGTAC 5 4200 +CCAAAC ref:0:6:TGGAAGGGTTCTTGG ref:0:6:CGAGTTTCAGGCC 5 8280 +CTTGTAC ref:0:7:TAGCGAATGTAAGCG ref:0:6:ATTTTT 1 588 +CATA ref:0:4:ATCAGACGCTTCACT ref:1:2:TGGGTGTTGATC 2 4 +AACGAC ref:0:6:TCAAGCAGCCTGTCCG ref:2:4:G 1 59 +AAG ref:0:3:ATGTTGGAA ref:0:3:TTTGCGC 5 620 +TGCGCCCTAAAAAGA ref:0:15:AAGCCGTATGC ref:0:15:GACCCGG 9 145920 +AGTGAAAT ref:0:7:CATGG ref:1:7:TGTAGCGC 4 1056 +ATGCG ref:0:5:TTTTTCAAAACC ref:1:4:GCA 2 1328 +TTATATCC ref:0:8:AGGCACGGTTCAT ref:0:8:AACGAACGCAAAA 7 9815 +ATTAATGATT ref:0:10:AGCAG ref:0:10:TTCACCGCTCTTT 4 8346 +GGTAAAGCAAGG ref:0:12:AGAGTGTGA ref:3:9:ATGCTGAAA 6 3750 +CCACAAACACT ref:0:11:GGTC ref:0:11:AGTTAAGTATAATAC 8 247394 +GGCCATTGACCG ref:0:12:GATT ref:0:12:ACAG 6 62 +CAATTCTGTTTTTAG ref:0:15:GAATCGCATGGCT ref:0:14:GGATGGATTAAAC 8 21618900 +CGTACGGGTAAAA ref:0:13:GGGCTGCTGAC ref:0:13:TGAACTTCCCCTACGC 8 1212680 +CCTTATTGCTAG ref:0:12:CATTGACTCCTT ref:0:11:TAC 4 354 +GTTGATGTCTTGGCA ref:1:14:TACCAC ref:0:15:TGGTGTT 4 56 +CATGGAG ref:0:7:TATTGTGACGCCTA ref:1:6:GCGGC 1 4 +AGGTGCCTTCCCTTGG ref:0:16:GCA ref:0:16:C 14 585 +CTGACAG ref:0:7:TTTGAC ref:0:7:GAAGA 1 6 +GCCT ref:0:4:CCAAGCC ref:0:4:AGCGTATCCA 2 17 +ATCGATACCAA ref:0:11:GCTAGTAGAC ref:1:10:CACTC 5 1688 +ACTCTGCGAG ref:0:10:GGGTGCGGGGT ref:0:10:CCCCGC 3 28600 +CTGCCATGGT ref:4:6:TTCTTAC ref:0:10:ATTTCGTCGATCAAC 6 3101 +CCAACCGCACTCGCAG ref:0:16:GAAGGT ref:0:16:TATCTTGCCTCA 7 5076 +TTCAGTCCGTGCAGC ref:0:14:GCGCCA ref:0:15:ACC 8 132 +GCAGACAATGACAC ref:0:14:AATTAGCTT ref:0:14:GGTTGCTCCCATGCA 6 447636 +T ref:0:1:CACCTGGTGACGA ref:0:1:CGCCTTGGGGACACCC 9 4 +TGTTGCCAACCG ref:0:12:CCCCGTTACAACCC ref:0:11:ACTACTAA 5 16700 +GAA ref:0:1:TGTCGGGC ref:0:3:ACTCGAATGAGATGTC 3 28 +AT ref:0:2:AAGCGACGCTT ref:0:1:GGG 3 24 +A ref:0:1:GATAGGACAC ref:0:1:TCCCATGACATAAC 6 20 +GTCTGGGCTTGGCC ref:0:14:AACCCGCCTCTT ref:0:14:TTGGGACCCCTT 4 36 +CAACTATCGT ref:0:10:TGGA ref:0:9:TGTGG 7 114 +GTTAACCATTTC ref:0:12:TC ref:0:12:TTACTAGTT 5 252 +TGGAATTCTACCCCCG ref:0:15:GTC ref:0:16:ACATCCC 8 3400 +AGGCAGGAAAAC ref:0:12:AGGAAT ref:1:11:GACAGTCCCAACT 5 40824 +GGCTTTGCAA ref:0:10:CTCTTCATCTACCCCA ref:0:10:CTAGAGC 4 768 +GAGCT ref:1:4:ACAGGGGCGATA ref:0:5:CTAC 1 32 +CTCAATT ref:0:7:GTCGG ref:0:7:GTGTTCGACCCCT 5 10560 +ATTGG ref:0:4:ACAAGAAGTCGA ref:0:5:TGAATTCCTGTATGA 4 204 +CGCTCTAGCGAGC ref:0:13:CATATGTGA ref:0:12:AA 6 42 +TAGCCCATT ref:0:9:ACCTAGTGA ref:0:9:TTATTA 4 207 +TAGAG ref:0:3:GATGCCTCGTTCGG ref:0:5:A 1 126 +GA ref:0:2:TCCTATGATCGTGG ref:0:2:CAT 2 2 +ACCTC ref:1:4:CCCACAAACGAAGAG ref:0:5:CTCGAAA 4 78 +CGACCCA ref:0:7:AACGGGTCCGGCTAT ref:1:6:TGAAGAACAGGAGA 3 4104 +TCAGACAATT ref:0:10:AAATC ref:0:10:GGAAGTCAGGTTAAAG 2 72 +GTGT ref:0:4:TTACC ref:0:4:GGAGTCTG 1 24 +GAACA ref:0:5:TGAGACCG ref:0:5:CG 2 15 +AGCAACATAAAGAC ref:0:14:GGCCACTGTTCT ref:1:13:CCTCAGGTGTAG 6 15012 +AATGCACCACGC ref:0:12:GTATTCGCGT ref:0:12:CGCTCCCAGTGTT 7 567240 +AGCCCTA ref:0:7:TTGACGACACAC ref:1:6:GGT 1 50 +C ref:0:1:ACCAGAGGGGAACAAC ref:0:1:AGCTTACAGCGCAAG 8 16 +TC ref:0:2:ACTAGTATGTCAAC ref:0:2:TCACCTCGGAGCT 5 56 +CACTAA ref:0:6:T ref:0:6:CTG 4 6 +TGTTCGCGATAGGT ref:0:14:GACGGACGGAAA ref:0:14:C 7 264 +ACTGTC ref:1:5: ref:0:6:T 4 2 +GTATGCGAG ref:0:9:CCGATACTCCATA ref:0:9:CTCTGAACTTCCCCT 9 129360 +CATAGC ref:0:3:AACACGACCATG ref:0:6:TGAGCAT 1 7 +GTAGGTCACGAG ref:0:12:ACCTGAGAGAA ref:1:11:CTATCCTGCCTT 4 1512 +GCCGT ref:0:5:TCGGTAACTC ref:0:5:ATG 3 656 +GAGCTATGTTAGTA ref:0:14:A ref:0:14:TTACCAAC 10 1216 +CCATGT ref:0:6:GAAAGTTAAG ref:0:6:TGC 3 238 +CACA ref:0:4:GGTTGATACG ref:0:4:TAGAACTAAGCCTT 5 1480 +GGAATGGGC ref:0:9:GCTTCTGCATTA ref:0:9:AGCTGAATAGCCA 5 7696 +CG ref:0:2:GAT ref:1:1:GGT 1 2 +TAATCAA ref:0:7:GAAATCT ref:0:7:TG 3 231 +GT ref:0:2:AACAGCTCAA ref:0:2:CTC 2 2 +ATTGGATAGCGTACT ref:0:15:CGGAGG ref:0:15:GTCGTC 6 16 +GGAGGACCACGAG ref:0:13:CGACGCCTATCC ref:0:13:GGGTTAT 7 23625 +TTCTTGATAGA ref:0:10:CTGGGGATATGGGGT ref:0:10:GGC 3 56 +TGTC ref:0:4:CGGGCGC ref:0:4:ACGCCTTA 4 1456 +CTCCTCA ref:0:7:CGACAATATTCC ref:2:4:GAAT 5 2940 +TC ref:0:2:AGTATT ref:0:2:TAACGGGTAAGTGC 4 28 +GTTCTTTA ref:0:8:AGGACTGGT ref:0:8:C 4 45 +TTATCCCTCCTCA ref:0:13:CCTTAAG ref:0:13:TGCCCTGCTAGA 6 864 +CT ref:0:2:TGTCCAGCAGTACT ref:0:2:GTAGGAT 6 63 +TGGTATAACCAGC ref:0:13:G ref:0:13:ATGGGTT 8 9 +TGCAGG ref:1:5:CCAAAAGAAAGGACG ref:0:6:GACCCAAC 3 3159 +GCC ref:0:3:CGTCGCCTATAG ref:0:3:AAA 2 80 +ATCTCCTTAA ref:0:10:GGTGAATCTAGCT ref:0:10:AAACTTTTATAG 2 624 +GGCAA ref:0:5:AACAAA ref:0:5:AT 2 54 +CTACAA ref:0:6:TCTGA ref:0:6:ATTATTTTGGTCG 3 180 +GAGTTGACGGTAATG ref:0:15:C ref:0:15:AGGTGC 10 21 +CGCCAA ref:0:6:TATTTCCCTGA ref:0:6:CT 3 52 +G ref:0:1:AATGCGAGACAGAG ref:0:1:TGAATCACAC 6 5 +ACCCATCC ref:0:8:GACC ref:0:6:CTCTCGCATTT 2 270 +A ref:0:1:ATGCCGTAAGCT ref:0:1:TTATC 3 3 +CCGGGGTGACCCGC ref:0:14:ATA ref:0:14:TCGAGACCG 7 1512 +CTTAC ref:0:5:TACAGCG ref:0:5:ATGCCAAGAT 4 2682 +AATGTCTTGT ref:0:10:ATCAATAT ref:0:10:CTAT 6 240 +ATCATTTAACAGAA ref:0:14:GTGAGAAATC ref:0:14:GTTTCG 7 18491 +CAGACC ref:0:6:GGCCA ref:0:6:GAGAGCCACCTGTG 3 100 +CGAACCTGTGTG ref:0:12:TT ref:1:11:AAGCCCGC 4 138 +GGCT ref:0:4:CTACG ref:0:4:GAGGATCA 1 13 +CA ref:0:2:ATGCT ref:0:2:CAATGCTTTGATAT 4 18 +TAGAA ref:0:5:G ref:0:5:ACAACCGCCGCCCTGG 1 2 +GTTCCATTTTATC ref:0:13:TCGCAA ref:0:13:CATCATTACCCAAGG 5 1512 +CGGGAAGAC ref:0:9:GCGTATGGTGATTG ref:1:8:GCCG 3 1800 +AGACTTATGGCAT ref:0:13:C ref:0:13:GATATA 6 4 +CTTACC ref:0:6:AACGATCCC ref:1:5:AGTGCATAA 2 104 +CATAGCTGGCTTGATA ref:0:16:AACCCCTACGCTC ref:0:16:ACGATGGTCTCATT 7 935415 +AGCAACCGC ref:0:9:GT ref:0:9:GTACTCGCTC 4 100 +ACACCGCAGTT ref:0:11:TGCCTAAGGATACG ref:0:11:CTA 7 145260 +CATTCTTCGAGCTCA ref:0:15:CCGGAGTAGT ref:0:15:AGAGGTGTGCTTCC 2 108 +TCTAG ref:0:5:GTAGGGACAAGCAAAA ref:1:4:ACAATTCCGGGACT 4 126 +CTTGCGGC ref:0:8:T ref:0:8:GTCCGACGTGATGT 3 234 +TGGGGAGCT ref:1:8:GTGCCGTAG ref:1:8:AAAACAA 2 2016 +AGG ref:0:3:CGAGTCAC ref:0:3:TGAAGTGAT 3 16 +TGCG ref:0:4:CCCGGA ref:0:4:AGAAGGCT 2 1080 +AAGCCTGTCGCT ref:0:12:AAAATATGGCCAGTTC ref:0:11:CAGCGGTACCCAGA 2 67200 +ATA ref:0:2:GCGTAGGTCCTT ref:1:2:TT 1 9 +GA ref:0:2:ATGG ref:0:2:ACCTTTT 2 4 +CTCGGCTGCAG ref:0:11:GT ref:0:10:GTAACCAA 6 184 +GTCGGGGTC ref:0:9:ATCGAAACGAA ref:0:9:CCACAGA 8 547560 +TAAGTC ref:0:6:GCG ref:0:5:ACGCCTTTGCAAG 1 3 +AGGAGAGC ref:0:7:CACCGGCGGG ref:0:8:GCAACA 1 33 +ATTAGTTTCAT ref:0:8:CCGACATAGAT ref:0:11:CTGATC 5 2016 +CCATTAT ref:0:7:TCGAAG ref:0:7:G 5 64 +AATTTGTACC ref:0:10:CAACGACG ref:0:10:TAGCTTGAATATCCA 2 276 +GTTAATTA ref:0:7:CAAGGCCCGCT ref:0:8:TTTGCGAGAAT 3 1152 +GAAAATTCTCAATC ref:0:14:CCAATGCAT ref:0:13:TGGGTGCATCTT 6 461025 +CGATT ref:0:4:GCCGTCTCAGTCGCC ref:0:5:TTAGCTGAAGA 2 36 +TGGTTTAGAGCGT ref:0:13:ATGGTCCTCGACTG ref:0:13:CGGAGTTGCGCGA 3 2200 +GTCATCGCTCTCGG ref:0:14:ATC ref:0:14:CGGGCGGACGAGA 7 15841 +GAAGTGACCAGT ref:0:12:TTTCTTTTAGTTGG ref:0:11:TACGTAGCGAGGAA 5 55242 +AGTTGAGACCCTGC ref:0:14:GAGTGGTATAAAGG ref:1:13:CTATCC 5 1212 +GTGCTA ref:0:6:TACAGTACCCCGTG ref:0:6:TCT 2 41 +CACACCTGCGGGCTA ref:0:15:CTC ref:0:15:TTAGTCATGTTAGC 8 1416 +CCGAC ref:0:5:CA ref:0:5:ATAGCTGATTATTA 2 168 +TCCGA ref:0:5:GCATGTTAACGT ref:0:5:TACTTTTCTTCTATGT 5 1736 +GACGTAGA ref:0:8:CTCCAGGCTG ref:0:8:TTTCTTCCG 6 6800 +CCACAGGTTGAAAGGT ref:0:16:CG ref:0:16:ATCA 12 690 +TC ref:0:2:ATCAATGTCTT ref:0:2:ACGGCTGT 5 44 +TAT ref:0:3:GAACTAAC ref:0:3:TACGGGTATA 3 40 +G ref:0:1:ACGACACTTAATGTCC ref:0:1:CCCGGTAGATCTCT 8 6 +GTGTAAAGAGTGCA ref:0:13:GCAAGGGTTTCT ref:0:14:ATGGGCAT 6 9648 +TCCGTACCATTCTGTG ref:0:16:CTGAACAA ref:1:15:ATAAACGGC 9 12544 +AC ref:0:2:CTT ref:0:2:TTTGAACGAGATCGGG 1 6 +ATG ref:0:2:GTTGATCT ref:0:3:GCCAAGTTAGGAG 2 24 +CTTAGAATA ref:0:9:GTG ref:0:9:GAGTGGCTGAG 6 2415 +TTTGTCTACAGAC ref:0:13:TTG ref:0:13:TGTTTACGCTACGG 4 624 +GCC ref:0:2:CGATAGCG ref:0:3:GGG 2 20 +GTGACGCCTGGCCAA ref:0:15:TAGCTGGGGCGTCGA ref:0:15:GCAGTTTGCGTCGGC 2 1728 +CCTAA ref:0:5:ATGTACCAACGAA ref:0:5:GGG 3 896 +GACTG ref:0:5:GCGCGAA ref:0:5:GGCGAC 4 48 +GACAAAGC ref:0:8:TCTGCAAGG ref:0:6:TAGCTCCC 3 1860 +CTGTT ref:0:5:GATCCG ref:0:5:GTGCTGTCGAGCCTC 2 12 +TCGCCTCCAGCCCTG ref:0:15:CGTCATCA ref:0:15:GCAGTGAGTACAGCA 9 295812 +ACT ref:0:3:TTGAGTCTTTTGA ref:0:3:TCGGTGA 3 8 +TAGCAT ref:0:6:C ref:0:6:GAGCG 3 6 +TGAT ref:1:1:ACCCCGCGCG ref:0:4:ATGGACATATGATG 3 63 +AGTG ref:0:4:G ref:0:4:GACGTATTAACCTAC 1 62 +TGAGCCT ref:0:6:AACGGCCGG ref:0:7:GCCCTATCCTTAG 1 96 +CTCCGATC ref:1:7:AGAAAGGCCGGTTG ref:0:8:GCCCA 2 152 +TTCAACCGATAACGT ref:0:15:CCAG ref:0:15:ATAATCTAGGACAG 5 81 +TGAAACAGACACAAA ref:0:15:GACACGGGGGCCCTGG ref:0:15:A 8 171675 +GACAGCCCTTGATGGC ref:0:15:TACGTA ref:0:16:AGTAAGCCACTGATGA 3 40 +GAAAC ref:0:5:GGAT ref:0:5:TCATCTACGGCG 2 1275 +TATAGAGCCCA ref:0:11:CCAAGACCAGGACCCC ref:0:11:TCACC 3 2460 +TA ref:0:2:C ref:0:2:GGAACCA 2 42 +A ref:0:1:GGGTTACAGATGC ref:0:1:TCTCGACTGCAACAA 7 15 +TAAGATAAATGT ref:0:12:ATATATATC ref:0:12:CCT 6 51150 +CTCCATTTTAG ref:0:11:GCCGTC ref:0:11:GATAGTAAGCA 7 85860 +CGTGAGATAGCACAGG ref:0:16:ATG ref:0:16:ATTC 12 180 +GAGTCGGA ref:0:8:ACTCTTCTATAGCC ref:1:7:TTAGCGTCGAAG 4 7280 +TTTTCCGAGTTCGTC ref:0:15:GG ref:0:15:TGGCACCATCGCC 6 2088 +TTAGGAT ref:0:7:TAAC ref:0:7:TACCAATCTGGTAA 2 288 +GTTAG ref:0:5:TTGAGCTAT ref:0:5:ACGACT 3 8 +ATG ref:1:2:CTCGTCATATACA ref:0:3:GC 1 1 +CGAC ref:0:4:AAACTGTACGAGCCA ref:0:4:TGACAGAAACCA 5 54 +CCATAGTCGA ref:0:10:GTACGTAAGCGACA ref:0:10:C 3 270 +TGCCTTCCA ref:0:9:CC ref:0:9:ACCTCATCGCATCTCT 2 18 +CTGTGAGGC ref:0:9:AGCCGACG ref:0:9:ATGGCATTGTCACC 5 6348 +ATAAAACAGCGT ref:0:12:GCGGGTAAGTTTCAC ref:0:12:AGAGGGTCGCCCA 8 961128 +CAG ref:0:3:GTC ref:2:1:TTTCC 2 12 +AGCTGCATCACCT ref:0:13:TT ref:1:12:CCCTAGCCCTCG 5 273 +GCACGCACGGCA ref:0:12:CGG ref:1:11:GAGTTGAT 5 8 +ATCTTTCAC ref:0:9:TACGCCACTT ref:0:9:GTGACA 5 4288 +CGCAACCCAAC ref:0:11:TTATC ref:0:11:AGATCTC 8 80995 +CGAACGATAGACTG ref:0:14:GGCA ref:0:14:CTAAGCTT 7 3150 +CCATTTAATTGGGTT ref:0:15:GTATCCC ref:0:15:CCCTTTACAGAGTG 5 226356 +CAAGAGGAATCCA ref:0:13:TCGGA ref:0:13:AGTTG 8 2097 +AGATGGTTTA ref:0:10:TGCTGATTGGGTCACC ref:0:10:GTCATCTACGGC 6 18297 +TGTGAAGC ref:0:8:AGTCACAGTCC ref:1:7:ATAGACTGCCA 3 160 +AACCTCCGGTGCG ref:0:13:AAACCG ref:0:13:TCTGTTAC 5 14784 +AT ref:0:1:TCTAAAA ref:0:2:AACCGCAG 2 68 +CCCGGAGAATGTG ref:0:13:GGTCTATCA ref:0:13:TGA 9 35972 +GGAAC ref:0:5:TAAGTACGTGA ref:0:5:TA 3 301 +TT ref:0:2:TGTGCACATGCAGGCC ref:0:2:CTACA 3 18 +ATGGGA ref:0:6:CCAATTC ref:0:6:GCTCTTAAC 7 13530 +TCAGGTT ref:0:7:CCCCTGAAG ref:0:6:AATTGAGATCCGTG 3 465 +CAATGT ref:0:5:ACATGGCAG ref:0:6:A 1 20 +CGGCAGGATG ref:0:10:TTGTCAT ref:0:10:CTCGGAGT 4 240 +CGCTAGGATGCGGGGT ref:0:16:GT ref:0:16:ATGACAATCCCCCA 10 28296 +GGAGGGGGCTGT ref:0:12:TGC ref:0:12:A 9 35 +TAGTC ref:0:5:TTTAAT ref:0:5:AATCTGAATG 4 306 +TAGGTTAGCCGATGG ref:0:15:C ref:0:15:GGCAGGATCTGGC 5 12 +GAGACGA ref:0:7:TCACGGCACTT ref:0:7:ACTCGCCCAGAA 3 1215 +CGT ref:0:3:GATCTCTTCAGCTT ref:0:3:TAATGTGATCC 3 102 +AACTAGTGGTTT ref:0:12:GCCAACGTACCCCC ref:0:12:CTAA 7 12258 +CAACAAGTCGCCA ref:0:13:GCATTGTTTATCTT ref:0:13:GCCACCAATGGT 7 7752096 +TTCTAAACAGTGCCG ref:0:15:GAAC ref:0:15:ATG 10 672 +T ref:0:1:CATGCCGTCGAGACA ref:0:1:TCCCCTAT 5 6 +TAGTGCACCG ref:0:10:CGACAAACCCTTGCAA ref:0:10:CTTAA 4 1377 +TTGACTACAATGTTAG ref:0:16:CCCG ref:0:16:TCGCGTCTAAGGGAA 8 5712 +TTGCGGTC ref:0:8:CTGAG ref:0:8:T 5 57 +CTATAGGGCAAT ref:1:11:TGAGTCCGCCTTC ref:0:12:TGACCTCCGGGACG 6 28509 +ATCGCGATGGG ref:0:11:CATATTGCTG ref:0:11:TATACTAC 6 4223 +TTTG ref:0:4:AGATTTA ref:0:4:ATTTTAACTCAATC 3 194 +TGCGCTG ref:1:6:AGTTAACTTT ref:0:7:GTCTT 5 3075 +AGAC ref:0:4:GTCGCGTT ref:0:4:AGAAGTGA 2 180 +ATATGG ref:0:6:CTGCGTAAATGGAAGG ref:0:6:AGAGTTTATCGA 3 4248 +AATAAG ref:0:6:AGTATCTACTCGGCC ref:0:6:GTGCTATA 4 1024 +TATCCGCGTGATA ref:0:13:GCCCTTGCT ref:0:13:CATCTTCGGAACG 2 576 +ACCGCT ref:0:6:CCGGTAGA ref:0:6:AATGGGCACATA 2 402 +TTGTACTC ref:0:8:GATGAAACATCA ref:0:8:CCGCTCG 2 162 +ACATTCAAAGA ref:0:11:GAAA ref:1:10:GCCTTA 5 684 +AA ref:0:2:ATGGAACCTCCTGC ref:0:1:CGATTGG 3 3 +GCCAAAT ref:0:7:AGC ref:0:7:GTTGCAG 4 126 +GTGAAAAGCACCTTC ref:0:15:CCGAATT ref:0:15:ACTAAGGCGAGATTA 7 63280 +CCAATAGTGACG ref:0:11:GCCTCGTCCTAGA ref:0:12:AATTCCA 4 48 +TACACTCGAGCA ref:0:12:ACCGCGTTCAACCAT ref:0:12:CGAAGAT 5 1036 +AGACTCGCTCC ref:0:11:CTG ref:0:11:CAGCAAGTTGCCCC 3 114 +CTC ref:1:2:ATTTT ref:0:3:G 1 40 +CGCCCAGTC ref:1:7:CCCGGACGA ref:0:9:CACCAACTGAT 3 48 +GTATCAACATTACA ref:0:14:CTGAAAGC ref:0:14:AAGATTAGAGC 7 6016 +CATACCTCTC ref:0:10:TTAAATTCCGCCGAAC ref:0:10:AGCCTATGCCTCCC 4 65536 +GTTTGGGTG ref:0:9:TCAATCATC ref:0:9:CGCTTACAAATCA 9 122808 +TTTCGATTTG ref:0:10:CCT ref:0:10:TAGAGGTTCGTAC 4 2520 +CTCA ref:0:4:G ref:0:4:TGG 4 30 +CATACAAACAAC ref:0:11:TATCTTCCATGAAA ref:0:12:CCTAGGAA 5 132207 +T ref:0:1:CCAAGGTG ref:0:1:CAAG 4 5 +ATACATTAG ref:0:9:CGGTAA ref:0:9:CTTAAACT 6 5719 +CCTCGCTT ref:0:8:CTA ref:0:8:ATATTGT 5 3792 +CTCCATCGT ref:0:9:TTATCACTAGTTTG ref:0:9:CAGATTTG 6 73236 +AGCGTGACT ref:0:9:CTAGCTCAGTG ref:0:9:CATGCACCCTTT 3 288 +GCAT ref:0:3:TTC ref:0:4:TGGATTCG 1 18 +GC ref:0:2:GAGAACACCAAC ref:0:2:CGGTG 1 72 +CCGCAA ref:0:6:CGTGGGCGAC ref:0:3:AGAAGG 3 2808 +CACTGAACGCA ref:0:11:ATCTGCGGTATT ref:0:11:AACCGTG 5 680 +CGTATACAACT ref:0:11:GCATGTT ref:0:11:AAAACAC 4 8142 +AGC ref:0:3:GCTGGGCG ref:0:3:ATCAACTGTCAAC 2 102 +ACTAGTGCC ref:0:9:CCTATG ref:0:9:CG 4 6 +CCTGGCGC ref:0:8:TATGTGATTGAGCCT ref:0:8:TACGTA 4 3816 +ACC ref:0:3:ATAACTCGTGCTTCAG ref:0:3:GTCGGATATTAGCA 6 414 +GCAC ref:0:4:CAAGTGCAACCCAT ref:0:4:ACACCCAATG 5 72 +GCGCGGCTGGAACGGC ref:0:15:AC ref:0:15:TC 12 2 +GC ref:0:2:T ref:2:0:TT 1 3 +AGGCT ref:0:5:GCCAGATGAGGTTA ref:0:5:CGGCA 2 168 +TGAGGCAGCCCTGATT ref:0:16:CGAT ref:0:16:AACGTCCC 8 70 +GATCCCC ref:0:7:CCTGTGTC ref:0:7:TTAGAAA 5 1260 +GATTAGC ref:0:7:ATGGGCGTCGTTCCCT ref:1:6:A 1 12 +C ref:0:1:GAATAAAGATAACAT ref:0:1:AGCACC 3 3 +GTGCCAGCGTCT ref:0:12:ATCTC ref:0:12:ATGC 8 180 +GCAGAACGCCT ref:0:11:GTAAGGG ref:0:10:CTAACCAG 5 9176 +TCGGATTTCC ref:0:10:ATTATTTG ref:0:10:ATGTCGACT 5 825 +TCAGC ref:1:4:CCACTAACTGAA ref:0:5:ACCTCCG 2 180 +T ref:0:1:CATTAGAGA ref:0:1:TCCCGCGAGACTTCGT 4 8 +ACTCCCCGCTTGA ref:0:12:TCTGGGGGGCTCT ref:0:13:TTCCATACAAC 7 4091115 +GAGA ref:0:4:TAGCC ref:2:2:CGTTTG 1 36 +ACACGGGCGTAG ref:0:12:AA ref:0:12:TAACCTCCTTTCC 7 15789 +GCTTTCGTTCCGAACG ref:0:16:TAGCTA ref:0:16:CCCACAC 8 1296 +GCGCTCCAATGGAGAG ref:0:16:GTCAACGGC ref:0:16:TGGTCGATAGTCTAGT 6 1184 +AGACA ref:0:5:TGCC ref:2:3: 2 8 +TGGGCTTCACCTCTTC ref:0:16:ATTCCCGAACTGAATG ref:0:16:TCCCT 8 2688 +ATGTA ref:0:5:TGGGTGACCGT ref:0:5:GCG 3 36 +TAGTATTACTCCCA ref:0:14:AATACCCCCTCACGG ref:0:14:AAGCATCG 5 21168 +TTTAACTCT ref:0:9:T ref:0:9:GGTATACTCCG 3 550 +AGTGCT ref:0:6:GTCTT ref:0:6:CTAGGATCTCTT 2 54 +CAT ref:0:3:GTTGCTCTATT ref:1:2:GGACTTAG 1 8 +GC ref:0:2:AT ref:0:2:CCAGTTCT 2 6 +GCCGAAC ref:0:7:AATCTCGTACTAT ref:0:7:TAATGTACTCT 8 7560 +TTTCCCTGA ref:0:9:GTTTTGCCTT ref:0:9:TGCTGAAGTGGCC 4 4248 +TCTCTTTATGCA ref:1:11:CGAAAGCATACATTG ref:0:12:CGCTGC 5 2976 +AATGTCC ref:0:7:CTTTGCTA ref:0:7:CCTTTCGGCCATAAA 8 37347 +GATAATGT ref:0:8:AATTTC ref:1:7:AAGAAG 1 128 +TGATACG ref:0:7:GGA ref:0:7:AACCTCATAAGTCCC 1 270 +TTCTACGACTATACGG ref:0:13:TAGAATCATG ref:0:16:AG 6 297 +TATTTAATGATCGTA ref:0:15:C ref:0:15:TTCCCTCTCTC 9 837 +GATTCGAG ref:1:7:CAAATTACC ref:0:8:AACAAATGTG 5 5520 +TAACCCCGCGG ref:0:11:TTGCT ref:0:11:GTGGTTACCACGCTG 5 3960 +TTGCACG ref:0:5:CTGCCATTATGT ref:0:7:TGT 2 156 +CCGGGGCTGTGAGA ref:0:14:GAATGGGAACAAAA ref:0:14:ATGACACAACT 11 115812 +GCC ref:0:3:TTGGGAC ref:0:3:ACGGATGACGCG 3 36 +GAC ref:0:2:GCATATGTATG ref:0:3:CCTCT 2 56 +CGAGTCCTGCATG ref:0:13:CTGCC ref:1:12:GGGGTGTGTAA 5 14328 +ACATC ref:0:5:AATTATGGCGCACACC ref:0:5:AATCGTATCA 4 256 +CCAGCGA ref:0:7:TGGAC ref:0:6:ACGGGTTC 3 192 +ATGATGACATGAAC ref:0:14:GATCCG ref:0:14:TTTGTAAGTGCG 5 84 +TTATCGTCGCTATGG ref:0:15:T ref:0:15:TTCGACATCCAT 6 30 +GACTACATGC ref:0:10:GTGGAGGTT ref:1:9:TCTG 4 137 +AATGACTTTT ref:0:10:AGGC ref:0:10:C 7 9 +AA ref:0:2:CG ref:0:2:GGGAGCGATGGAG 2 18 +ATTGAAAGGA ref:0:10:AACTAAAACACCTCC ref:0:10:TTTGTGGACG 1 2224 +ATGG ref:0:4:CGCAATTTTG ref:1:3:CGCC 1 252 +CTATCGAACTTAT ref:0:13:GCGCGCTTTG ref:0:13:GGATG 7 552 +A ref:0:1:GTCATGAAT ref:0:1:CATAGTGA 4 9 +GATTCC ref:0:6:ATGAGACAACT ref:0:6:CAATTGTTG 3 2562 +CGAAGA ref:0:6:AACTC ref:0:6:A 4 36 +AA ref:0:2:ATGTGTCTCTC ref:0:2:CA 1 36 +GTCCAGTCTT ref:0:10:ATGCGTCTC ref:0:10:ATTC 5 216 +GGTCAAGCCC ref:0:10:TATGATTCGTGCGCAC ref:0:10:CAGGTGAGT 4 1960 +TTCTTGTCCG ref:0:10:GCTTGGCGGAGCTCTT ref:0:10:CATTCGGTTA 7 88576 +GCATAAGGGCAA ref:0:12:CAACCTCA ref:0:12:A 7 1105 +GTTTGGTGCCAA ref:0:12:TGGTGATTGTCTAGT ref:0:12:CGGTCACCTTACAATT 6 14448 +TGGCATAGTGCTCT ref:0:14:TTTAATTAGGACTGG ref:0:14:CCGCGAATTATGAATG 7 1058400 +GACGCCAGTGC ref:0:11:TACTATGGTTGGA ref:0:11:TAC 6 5100 +CCGTTTGAT ref:0:9:CCC ref:0:9:AAAACATTGG 4 1930 +GTATCGTG ref:0:8:TTCACCATACGAC ref:0:8:TA 3 73 +AATTCTC ref:2:5: ref:0:7:CCC 3 8 +AACACCTTCGAGA ref:0:13:CGTGCCAT ref:0:13:AATGGCAT 8 3780 +CT ref:0:2:AAGGCCTACTAAT ref:0:2:ATGGGCTGCCAGAA 6 8 +ATTTCAAAGA ref:0:10:GAA ref:0:8:TAAT 5 552 +AA ref:0:2:GAGAAATGACGTT ref:0:2:ATCGAATTCAGT 6 60 +AAACCCGTACC ref:0:9:GCGTAACTTGCGCG ref:0:11:AGTCACCGTCACTATA 3 1372 +GGCG ref:0:3:CCCGG ref:0:4:ATCTTACTCACTT 3 685 +CCGT ref:0:4:GTGCCCCTG ref:0:4:CTTCGGCTTGTT 2 224 +CTGGTGTCG ref:0:9:AGTGCA ref:0:9:CCTCTTCCCGTGAG 3 3990 +TCTGGTCTTTGAGTTG ref:1:15:CCAACCAACTCCATC ref:0:16:CAC 11 1961385 +TAGGCTTCTTA ref:1:10:AATGCCTGTGGGATT ref:0:11:CTCT 2 348 +GGAGTGATACACTACC ref:0:16:T ref:0:16:TTCGGTAAC 10 1428 +AAGAGGTGCTT ref:0:11:AGAGGTGCCATGATG ref:0:11:CCAAGAAACTAACAC 1 2336 +ACTGGGCGGAC ref:1:10:A ref:1:10:TAGTTATCAGT 6 466 +TGTTACTTGTT ref:0:11:CTGGAGCTA ref:0:11:CGTCCGTCGC 6 19328 +CACCT ref:0:5:ATTTTTGCTAGAT ref:0:5:A 2 27 +ATTAT ref:0:4:TCTTGAGCACAG ref:0:5:ATATATAGAGTTC 4 285 +GCGTCTTGTCTCTG ref:0:13:CAGACTGTCAAGCA ref:0:13:ACTCTGAAAGT 6 12160 +TGTGCCGTGT ref:0:10:TGT ref:0:10:GATCCAGGGTC 3 56 +TAATCGCTGGGG ref:0:12:CTTATAGCA ref:0:12:TTATGCGAGGAGA 5 360 +GTCGTTTTCCT ref:0:11:ATAGTGGCATTAACA ref:0:11:CAAACGGCTATGATT 7 438100 +GACA ref:0:3:ACG ref:0:4:TCAC 1 6 +TATCATGTGGGCGTAG ref:0:16:TGGCTAGCTACGG ref:0:15:AAACTTGAACTTT 6 1088000 +TGCATTTC ref:0:8:CGACTCCGCATTACA ref:0:8:A 1 4 +CATCACTCTTT ref:0:11:TACAAGCGGCA ref:0:11:TTTGAGCGTCAG 8 21000 +TAG ref:0:3:AGTGGCAT ref:0:3:TTTGTTG 2 192 +ACTTGGAGAAC ref:0:11:CAACTGGGTTAT ref:0:11:GTCCTAAAATTGTG 5 39672 +CGGAGGTAT ref:0:9:ACTTCTTTTATTATT ref:0:9:GATCGCTTGCGG 4 4896 +GTT ref:0:3:AAGCCCCC ref:0:3:CCTTTCCA 4 210 +TACATAAA ref:0:8:CACTGTA ref:0:8:GCACAACGCAAT 3 153 +GTGAATCGGCCCGGAT ref:0:15:TAATCCGCGCAACGG ref:0:16:AATGTATTCTGCTT 3 21060 +GGCCCCACCG ref:0:10:TCATTCAGTG ref:0:10:ACAATC 7 136258 +AATACGCACTCCGTG ref:0:15:CTGAGTCAGGAAT ref:0:15:GG 8 393 +AGTAGCCCTTAT ref:0:12:AA ref:0:11:ACAA 8 99 +AGCCCCGAGTG ref:0:11:GGACCAGTCGCT ref:0:11:TTACAG 4 328 +A ref:0:1:G ref:1:0:TCCG 1 2 +GCGGCAAGTCGG ref:0:12:TTGACCGTACTG ref:0:12:AGTCTTTGA 5 36 +AACAGATGGCACCGAT ref:0:16:CGTCTTTGTATCACA ref:0:16:TGTCCGC 8 32016 +AAA ref:0:3:AAGGTACTAGACTTTG ref:0:3:AAATCTAAAGAAG 6 560 +TTAGATCGGGAGCTTT ref:0:16:CGGATCTAA ref:0:16:ATTCGACGAAGACTG 6 13104 +TCAATCAT ref:0:7:CGCG ref:0:8:CTGCTCACGG 3 32 +CTTTTCGCGGATGAA ref:0:15:TATG ref:0:15:GTCCA 9 168 +GACCGGGCG ref:0:8:TACACTCATTT ref:0:9:TAGGGCGGC 2 32 +TTTGCGCTGCGCG ref:0:13:GTATTAGAAG ref:0:13:TGGCCATTGC 5 55350 +GCTTTTT ref:0:7:AGGAGAAG ref:0:7:AGGTTCAACA 9 595755 +TTCAAGGTTCCCGTGC ref:0:15:ATGA ref:0:16:CCC 10 180 +CGACTAG ref:0:7:AAGGTGAAACGTGCC ref:0:7:GAGCGTCAACCCGA 2 78 +CGGTTG ref:0:6:ATATTAAA ref:0:6:T 4 232 +CGACGGGACGTGCG ref:0:14:GGACACATAT ref:0:12:ACGGC 4 216 +A ref:0:1:TGCCGGGG ref:0:1:CGAGGTGG 5 9 +TGT ref:0:3:CTCGCCACCCCGA ref:0:3:C 2 48 +GTAGCGCTGCT ref:0:11:TTAT ref:0:11:TATCGTACC 5 144 +TGTATCTGGCA ref:0:11:TTGTACTAC ref:0:11:ATTGAGGGATT 3 248 +AGCAGTGTCTTT ref:0:12:CTCCAG ref:3:9:GACTC 6 6440 +TAGGGTTCT ref:0:9:CGATGTT ref:0:9:GTCAAC 4 6256 +TGAAG ref:0:5:TTAGCGAACCC ref:0:5:TTCGCTCTTAGAGGT 2 64 +CAGCTCCCTCCA ref:0:12:GGTTTCAGG ref:0:11:CTAAAT 6 6278 +AAT ref:0:3:CCG ref:0:3:GGCGATGATG 2 20 +ATACTGAGGC ref:0:10:AGGAGCAGTTCCTG ref:0:10:TCTCCGTTCTGT 6 7600 +CAGTGGAAA ref:0:9:ATACGC ref:0:9:ACCCGTTTC 6 18592 +GCGCC ref:0:5:CAGCACCAAGGTG ref:0:5:TAATCA 4 800 +AGTCGT ref:0:6:TTCCAAAGAGAC ref:0:6:AGTAGTTGTTTCCATG 4 24642 +TTTAC ref:3:2:AGGA ref:0:5:GTCCTAGTG 3 135 +AAG ref:0:3:TGG ref:2:0:CCTC 1 9 +TA ref:0:1:CACGTGCGG ref:0:2:TTTGC 2 12 +CCGTTAGCGCGTACA ref:0:15:TATCGGCTA ref:0:15:TACCGCACC 7 1376 +AGTCTAAGA ref:0:9:GAT ref:0:9:CGTT 6 30 +TCAGCAAGCTGGGAA ref:0:15:AGCACTACCCCGGAC ref:0:13:GCTCAT 5 7371 +TACACCCGACTTT ref:0:13:CTGCTCTTCGCT ref:0:13:AGGTCCCTGCCCT 6 59421 +GGAGGCCGCAT ref:0:10: ref:0:11:TGTTGTTTA 8 4878 +AG ref:0:2:TGGAGAC ref:0:2:CAGTGGGGTAATCCG 3 8 +CAGGTGTGACATA ref:0:13:ACCGGTCCGA ref:0:13:GCAAAACG 4 522 +CAGGCTC ref:0:7:ATGAGCCCCCA ref:0:7:TACTATG 2 340 +GTT ref:0:3:CCCTGACGGCTG ref:0:3:GAACGTGAACCACAA 5 546 +CAGACACT ref:0:8:TTCACAAGG ref:0:8:TAGTCCAACGGGA 6 5104 +AAAGA ref:0:5:ATAGTCCCTGAACT ref:0:4:ATTGGCCAAACGCG 3 232 +CCGGAGCTCT ref:0:9:ATGCACGAGGCT ref:0:10:ATCCGCATAG 4 295 +TTCTTATCCTG ref:0:11:CCCCCCGGACCCAC ref:0:11:TGGAGTGGG 6 18510120 +GTCGCCAAC ref:0:9:CGAGATGATTA ref:0:8:ATTTGGGCGGCGGGC 1 60 +GAGAGACCAAC ref:0:11:GGAGGT ref:0:11:AAGC 5 147 +CAGAGCAAGG ref:0:8:TTAGGCTTA ref:1:9:CT 3 60 +GAGTTATGCGCG ref:0:12:CTCAAGCTCACAGAAT ref:0:12:CGTGAATCGCTTA 7 163248 +ATTGGCTGAAC ref:0:11:GCA ref:0:11:CCAAAGCAACGCTG 5 240 +CGCACAAACCGAGCCT ref:0:16:TCAACA ref:0:16:GCGCCACTG 7 6396 +ATGATCG ref:0:7:TTGCATTCGAGGCCTC ref:0:6:GAA 2 100 +CGGGAACAAAATG ref:0:13:AGAGCGAAT ref:0:13:TCTGTAAGCCA 6 56000 +AGGGTAACAT ref:0:10:ACAGGGAGCCTC ref:0:10:TTTGCGGCGACTATAC 4 1640 +ATCTTCAGGATTGGC ref:0:15:TGTTATG ref:0:15:CTTACCTTTAAAT 7 10960 +GACATAG ref:0:7:AACCTCCAGAAGCCA ref:0:7:GGACGG 2 1120 +GGCTCTACGC ref:0:10:CCCGCGATTAG ref:0:9:CCGAACGGG 1 105 +AACCGATTACT ref:0:11:TCTG ref:0:11:GCCCGCAA 3 24 +GAT ref:0:3:ACGGTTGC ref:0:2:CAC 2 20 +ATTCCGCCATGCGGTT ref:0:16:GCGACGA ref:0:16:CGTT 9 1960 +TGATAACAGTGG ref:0:12:A ref:0:12:AGTCCGGCTA 7 904 +AGGTGA ref:1:5:CCTG ref:0:6:CGAT 3 108 +TGC ref:0:3:TCTACCATCG ref:0:3:CC 2 132 +ACGAAGCGCTTTCA ref:0:14:TG ref:0:14:TCTTC 10 1595 +GATTATGAC ref:0:9:AGTG ref:1:8:TGCCATA 3 55 +CTT ref:0:3:GAAAGCTTAT ref:0:3:GCTTTG 2 9 +TGTGG ref:0:5:GC ref:0:5:CTAG 3 119 +TGTAATTATT ref:0:10:CACCGCAGGATA ref:0:10:CGGCCC 7 29700 +A ref:0:1:GG ref:0:1:CGGAGTCCACA 2 9 +GAGAAGGTGATTC ref:0:13:ATACACATTG ref:0:13:GATTTTTACCA 5 9120 +AAGAATTTAAG ref:0:11:AAAT ref:0:11:CCCTCGG 6 40764 +GAGAGTGGGTCGCAC ref:0:15:CTATCACAAAATTCC ref:0:15:TTCGACCCTAGGCG 9 699380 +CCCTACCA ref:0:8:G ref:0:8:TTTC 6 441 +CCAACACTGAACGCAT ref:0:16:GGTACA ref:0:16:ACAAGA 8 1863 +AAAT ref:0:4:GTCAGGAGAA ref:0:4:GTATG 2 50 +AAATG ref:0:5:T ref:0:5:ACTTTCAGCAAAC 2 85 +AGTTCACG ref:0:8:TCCAGGAGTA ref:0:7:CTAAA 5 6336 +TAGGCGGCGTTTGT ref:0:14:CGCAATCTGATTA ref:0:14:CCTACTGTTGTGG 5 3300 +GAAGTAGTTG ref:1:9:CCATATTAAACC ref:0:10:ACTCCATTGG 3 240 +CGATAA ref:0:6:TTAGTTGACTCAAC ref:0:6:ACATCCTA 2 77 +TA ref:0:2:CG ref:0:2:CGAAAGAAC 3 162 +ACTGATATGCGAAACT ref:0:16:GGCCG ref:0:16:CAGACTTGTCAACA 6 84 +T ref:0:1:GAAA ref:0:1:GCTAGGATACC 4 10 +GCGGTAGT ref:0:8:ACTCA ref:0:8:ATTTTAGAG 5 1476 +AGCTTACAA ref:0:9:GCCGT ref:0:9:GCACGTGA 6 65 +CTCTGTAG ref:1:7:GTGGTCCTTAC ref:0:8:GGAGGTCAT 5 2176 +AGAAAATCCCGAAC ref:0:13:GAGATCTTA ref:0:14:CATGT 7 53900 +ATGGTGGACACTAGAG ref:0:16:CCA ref:0:16:CAATATTATACAT 8 2196 +CGTTTATC ref:0:8:TTACAACACCAAATAG ref:0:8:TTGAG 5 4296 +CGCCT ref:0:5:ATTCAGACC ref:0:5:ACTGGCGATCTCGTCC 3 10 +GTTAGAGCGGAGCA ref:0:14:TGAGCCTAC ref:1:13:ATTGGT 6 940 +TGGGACAACA ref:1:9:A ref:1:8:CCCGTTACTCT 4 336 +GCCTTCGACCT ref:0:11:TGTT ref:0:10:CGGTCTGTACTAGA 4 112 +ACCCAGGCGGATGA ref:0:14:TAGTCCCA ref:0:14:C 9 52 +ACG ref:0:3:CCTGACATCTCAGCAC ref:0:3:GACGCCG 3 20 +GTATGC ref:0:6:ACACGTGGGCTTG ref:0:6:ACGGTCGGGTCAG 7 3920 +GGG ref:2:1:AGTTTA ref:0:3:AAAAAACCTGCAT 2 105 +GCGAGT ref:0:6:TCAATACTGAGTTG ref:0:6:TCTTGTCTATAT 5 396 +CCAC ref:0:4:GTGACTGGATTG ref:0:3:AGGGCGC 3 46 +TTTAGTATTGTG ref:0:12:AGTGATTGAC ref:0:12:GCTCTGCAAGAATGT 2 1071 +ATGTCTTCAACAGTGA ref:0:16:TACTCGAACATGCAC ref:0:16:A 5 50 +CCGAAAA ref:0:7:AAATAACGTA ref:0:7:TG 2 108 +AT ref:0:2:AGCTGCTAGAGTAGC ref:0:2:GAGTTT 3 15 +GGACTATATTGGGC ref:0:14:CACTGCACCTA ref:0:14:CTCACGAGCTAAAT 7 216 +TGGAACCAAT ref:0:9:TTG ref:0:10:A 6 20 +CTA ref:0:3:GGC ref:0:3:G 3 4 +CCCTGTCCGAGGCTAG ref:0:16:GTTGGGAAAACA ref:0:15:GCGACC 6 96 +TGATTTTCTCTG ref:0:12:GGTTT ref:0:12:GCA 7 855 +TG ref:0:2:ACTGAACAAG ref:0:2:ACCCCGTGA 3 2 +CCCTGG ref:0:6:GCAGGT ref:0:6:GGGAACGCCCTAG 2 192 +AAATCGGTTTA ref:0:11:CATGGTATGTTT ref:0:11:A 4 496 +AA ref:0:2:TATGAGACGTTCAGA ref:0:2:CGACCTC 4 80 +GAATCACCTATAAG ref:0:14:CCAGCT ref:0:14:AATGGAAAAGTCT 6 150 +TCTGTCC ref:0:5:GAGA ref:0:7:GTTTGAGTCTGCAC 3 864 +ACCATACCGCGCT ref:0:13:CAACGTGCATCTT ref:0:13:GGAGCCGA 5 140112 +CTAAGGGACGT ref:0:11:TAATTTTGA ref:0:11:T 6 42 +ACCGTCTATCCA ref:0:12:A ref:1:11:TTTCTAAGGATGTAA 5 2802 +CT ref:0:2:TTTACGTATAG ref:0:2:GAGTCTGGCGGATCTC 4 12 +CCATGCTTATTCG ref:0:13:A ref:0:13:TCCGCCGCGCA 6 58 +TAGTCAAACCGTA ref:0:13:CCTGGAGT ref:0:13:GC 7 54 +ATCATGCTATT ref:0:11:AGGATTATGAGGTATC ref:0:11:AGGGGGACGTAGGGA 8 516384 +AGTACGGCATCGCCT ref:0:15:TAGAA ref:2:13:AGGGG 8 240 +GGAAAAGGAGCA ref:0:12:AG ref:0:12:AAA 8 260 +GT ref:0:2:ATGAACGTGAT ref:0:2:TAATAGTCTCATTC 5 20 +TCAGG ref:0:5:GCCGGG ref:0:5:TTAACCACCGGTT 1 104 +GTTTGA ref:0:6:CC ref:1:5:ATCGT 4 728 +TGACGCAGACTGC ref:0:13:GTGCTGCG ref:0:13:GA 6 228 +CGGATTATCT ref:0:10:AAAGCGCAACGTAAA ref:0:10:GGAATGCATGTTGT 4 1344 +GG ref:1:1:CTCCTTAGTT ref:0:2:AACGCTCTC 4 10 +CAGGTC ref:0:6:AAATCTCC ref:0:6:GGGAGCCATGCATCGT 4 2448 +AAGTACTCGGGAGGCC ref:0:16:CCGGTTCGTGACT ref:0:16:AACATT 7 31488 +TAGTTGCGGCAG ref:0:12:CAGTG ref:0:12:TTAT 7 176 +ATTTGCACCACCAT ref:0:14:GAATCATCCGACAC ref:0:14:GACATAAA 7 6840 +GGGGTCTA ref:0:8:TC ref:0:8:TGGGCGTGCAGACCGA 1 16 +AGCCAGGG ref:0:8:TCGGAGCCGCGCTCA ref:1:7:TGGGGCCGG 2 96 +ATAGACGCTAGGTAT ref:1:14:CTCCCGACGCCCCG ref:0:15:CTGCGTGTGGCACCTC 4 9240 +AAATATGTTC ref:0:10:GTGCTATTATA ref:0:10:GCTCC 3 546 +T ref:0:0:GCAGAGAGA ref:0:1:ATCCTAAGTT 4 4 +GCGTAACTTTA ref:0:11:CTCCGACAGA ref:0:11:ATTAACTTTTCTATGT 3 38640 +CATCCGCAGACTTCCC ref:0:16:CC ref:0:16:CAA 12 168 +TGCCGGACG ref:0:9:AGTATCATACC ref:1:8:GGCAAACCC 6 241854 +GTGCGTAATAAGTTCT ref:0:16:GCTA ref:0:16:CTGAGAGCTCG 8 9156 +ACACTCACA ref:0:9:TCA ref:0:9:TCGTGTTAGCGTGC 3 24 +TCAT ref:0:4:AG ref:0:4:C 2 2 +ATAGTCCTACCATG ref:0:14:AAA ref:0:14:TACCACGC 6 12 +AAC ref:0:2:GCGTAGGG ref:0:3:GGT 4 180 +GACCCC ref:1:5: ref:0:6:C 4 4 +TCCCGGGTTGTTA ref:0:13:CGAGCCAGCTACA ref:0:13:AAAC 10 271884 +GGATAGTTGTTT ref:0:12:CTTGTACG ref:0:12:ATTCAGGCGGGCG 8 715244 +ACAA ref:0:4:ATAACCGTGATCAGT ref:0:4:CGCGGTACT 5 198 +TCATATGT ref:0:8:GCGAG ref:0:8:GACCTGGAAGGTCG 5 1360 +CAG ref:0:1:TACGT ref:0:3:TTTTCAGGGGGAACC 1 5 +CCACTA ref:0:6:AGAAA ref:0:6:GCCTCCAATGAATCCT 3 5194 +TTGTCGAAATTGA ref:0:13:CATTGGATCTG ref:0:13:ACATCGGTGG 7 3186 +ATTCCC ref:0:6:GGGTGCCCGAACGGCG ref:0:6:CTAGAAGCTTCT 2 3600 +CGTA ref:0:4:GTCCGGAGACAGCCA ref:0:4:GATAT 1 115 +CTGGATGTCCAC ref:0:10:GCATCGGC ref:0:11:ACGAAGACCAGG 3 660 +AGGGGGAACATAG ref:0:13:CCCA ref:0:13:CAACGAAAAT 8 53865 +ACCCCCTACAGTTTA ref:0:14:CTG ref:1:14:GCAC 8 75 +CTTGAGT ref:0:6:GA ref:1:6:G 3 2 +GCGTAGAGTGA ref:0:11:CG ref:0:11:AGGTTTTATCGGC 4 928 +TCACCCTCGT ref:3:7:TCTCCTACC ref:0:10:AGTAT 2 64 +TG ref:0:2:CCCAACGTTATA ref:0:2:ACACGGC 4 198 +TTGCCGACTTGCCCA ref:0:15:G ref:0:15:GTCTGGTTTATTTCT 7 156 +TTTGT ref:0:4:CAGCCGATGCCA ref:0:5:CC 4 945 +AGACAGCGT ref:0:9:CGGTGGACAAC ref:0:9:CACTATGATTGGCTAT 4 20736 +ACACGAGTTAA ref:0:11:CAAGGGG ref:0:9:TCCT 3 908 +ATCCGAATTT ref:0:10:CGCGCGCATGAGCG ref:0:10:CGGCG 7 992 +AAATCTTTGAATTTGC ref:0:16:TCTGGATTAT ref:0:16:GCATCGTTCT 7 840 +TTGGGCATCATCCT ref:0:14:AGTGCTCTATCAGA ref:0:14:AGGTCTCCCTTT 5 45150 +TAGTTGCTAGAGCC ref:0:14:ACCTC ref:0:14:CGATTG 8 637 +ATAATGAGGAGCAAG ref:0:14:TGGGCTAATC ref:1:14:AACTGGATGGACA 2 32 +TTGAAGCGGTCCATT ref:1:14:GTCGTCAAACGCAAG ref:0:15:ACTTGACCTG 6 3024 +TCTAAG ref:0:6:CCTATGTAAT ref:0:6:AATGCAA 3 58 +TAGTAACCAGGGTCTT ref:0:16:GGA ref:0:16:CACTACTTCTTGTG 7 17280 +TGAT ref:0:4:GGCGAGCACGGC ref:0:4:G 2 121 +CCTGCGGAACCGGGG ref:0:15:AGAGTA ref:0:15:TCTAAGAGTGGAACGA 9 511800 +CTCTGGT ref:0:7:TGGCGACAACAATT ref:0:7:GATCGGGCG 4 2850 +CTTGCAATGACGGT ref:0:14:GATAAACGGTCT ref:0:13:CAGACTAGCGATGC 6 4234 +CCAGGAGCGGGTCCG ref:0:15:CAATGA ref:0:15:ATACCACCACTC 7 24 +TCCACAGTGTGCTTA ref:0:15:TGTG ref:0:15:ATCCAATGTTTC 4 10 +C ref:0:1:TATGCGC ref:0:1:TGCCACGAGCATG 4 8 +CT ref:0:2:CCTTCCGAGTGC ref:0:2:CCTCATCG 5 40 +TGCT ref:0:4:AGGAAGGTC ref:1:3:GG 2 260 +CACGGCTC ref:0:8:ATGCCCGGAACAGA ref:0:8:CCAG 3 784 +TTTCGG ref:1:2:GACTGCATG ref:0:6:CTGTTT 1 7 +ACATTCATAGACGCTT ref:0:16:CTTAAGAAAC ref:0:16:AATAAC 6 234 +GGCGCGCCGCACCTA ref:0:15:AAGCTTCCCCC ref:0:13:GTGTTACCAAC 6 391778 +GGATCATGGGGCTT ref:0:14:TTGCCGGCACTGAC ref:0:14:TGG 7 1956 +CGGTTCCATTAAT ref:0:13:GCCA ref:0:13:TACTTC 6 384 +CATGGGTCACTCTGTC ref:0:16:GTGATGCTA ref:0:16:GCATTTTTATACGCCT 8 76608 +GTTGGGAGACATTC ref:0:14:ACGCCGTG ref:0:14:AC 10 230 +CTCGCTCA ref:0:8:C ref:0:8:TTTAGGATAACCAGTC 3 1364 +TAGGGCGCTGCAACT ref:1:14:GCGTGGTACGAGTCA ref:0:15:AAATGCGAGCAACTG 4 63504 +AA ref:0:1:GCGCAGGT ref:0:2:CCGTG 4 21 +TAAGCACTAA ref:0:10:GACCTACGCTCCCT ref:0:10:AAACCTGACCTA 5 5655 +TAAAG ref:0:5:ACGCTTTAT ref:0:5:AAGGAAAT 4 3525 +GGCAACCTT ref:0:9:GCAAAC ref:0:9:CGCACGATCGAATCG 4 2800 +TGAACTAACCTC ref:0:11:CGGTGTGTGG ref:0:12:GTCAAG 6 125 +ATCAGTGGTGTCCGA ref:0:14:TATATAGGTAGC ref:0:15:CTTATGTGCGATC 5 64 +ATATTGTGGGCTACCC ref:0:16:AGACACGTCAAAGTCT ref:0:16:GACCAGATC 12 2357556 +TT ref:0:2:TAGCATATTTATACGC ref:0:2:GCA 3 150 +T ref:0:1:CC ref:0:1:GTCGGTAAAGCAGTTC 2 12 +ATCTACCTCAA ref:0:11:CTCCATCGAGAG ref:0:11:GCTAGTACTTGATTAG 4 352 +CGCAAAC ref:0:7:GGCCAACGACT ref:0:7:ACCTGTTGTGCA 1 126 +TGATTCTGCCGCAACG ref:0:16:CACTGT ref:0:16:ATCCAACCC 8 5152 +GATTGGCCGAG ref:0:11:TCTGATATAGA ref:0:11:GGTTGCGTCC 2 27 +ATAGCAAGCTGAA ref:0:13:TGCAACATAT ref:1:12:TTC 4 64 +GACTTCGAAACATTCC ref:0:16:AGC ref:0:15:ACCGTTTCA 8 24 +TCGCGGCCGA ref:0:10:GT ref:0:9:TATAAGC 6 6248 +AGGTTACATA ref:0:10:TTGTATATTCGTG ref:0:10:CTCATCCGTC 6 10836 +AAA ref:0:3:TCATAAGG ref:0:3:TGCCAATT 2 9 +CTGTG ref:0:5:GTATGGCAAGA ref:0:5:AT 3 468 +GGCCTCTACCAAAGAT ref:0:16:ACGTTGACTGGTAG ref:0:16:ACCGACGGTCGATCCC 10 116776 +GTGGGC ref:0:6:TGCTGTTTTAATG ref:0:6:TGTAGAGA 4 143 +ATATA ref:0:5:CTA ref:0:5:TTGACCCGCAGCAC 2 600 +TGTA ref:0:4:TTCCACGCAGTCT ref:0:4:GTTTAATC 4 308 +CGTAGAAGTTATAT ref:0:14:TGGCAAAAATGCGTAC ref:0:14:AGAGAGTCTTTAGC 6 2912960 +TCTGCGG ref:0:7:ACCTCT ref:0:7:TGATCACTTT 6 5744 +CGGA ref:0:4:GT ref:0:4:TCGGACAAGTTG 1 15 +TC ref:0:2:AG ref:0:2:TACTTGTTACCCCGAT 2 126 +TACT ref:0:4:CCATATGTGGCTT ref:0:4:GTAAATGCGAATCTG 3 26 +CTCGGTT ref:0:7:TC ref:0:7:TACCTCGATCG 2 30 +TCGT ref:0:4:GATCTCTGGG ref:0:4:A 2 120 +CTCTCCCCGT ref:0:10:ACCG ref:0:10:CCCGCAGTTAAAA 4 2856 +AAGATTTCA ref:0:9:GGAC ref:0:9:TGCGTCAGG 5 372 +CATG ref:0:4:ATA ref:0:4:GT 2 8 +CTAGTGCTAATGT ref:0:13:TA ref:0:13:TTTGTGTCTCCAA 5 70 +CTCGACCA ref:1:7:TATAACTGGGGGA ref:0:8:ACCATTCCGAGACG 4 58384 +T ref:0:1:GCCACTGGCCCCCG ref:0:1:TGCGGCACAGCTG 6 2 +GAATT ref:0:5:TGCCCGGGCGCAT ref:1:4:CC 4 960 +ATGATAACGCTCCA ref:0:14:TCGGAGGTTTGT ref:0:14:TTAAT 6 30 +TCTGGC ref:0:6:TTACATCAC ref:0:6:GTCCCGCGCAAGACGG 2 434 +AGACTAGTTGGCCC ref:0:14:TGCTCGCAGGTGCC ref:1:13:GGCCTCGGTGTCCA 6 104544 +A ref:0:1:GGAAAC ref:0:1:TTGGCGGCG 3 30 +TACT ref:0:4:GGG ref:0:3:GCGGC 5 630 +TCTTTTATCGCCAAAG ref:1:15:TGTATTAGTGCCC ref:0:16:GAGGTCTCTCCTAA 3 3200 +GTC ref:0:3:GAAAGCGACATCGTTA ref:0:3:ACGCGCCCATT 6 75 +TA ref:0:2:GCTGACCCATTC ref:0:2:ACAATCT 4 24 +ACTACATCGCCATGC ref:0:15:TCCG ref:0:15:GAGAGGA 8 2110 +ACTATAACCTATG ref:0:13:CCGTTA ref:0:13:GCA 9 1025 +ATCAGGCATGT ref:0:11:T ref:0:11:GTTCAGAG 5 30 +TAGATCAACTAA ref:0:12:AT ref:0:12:CTGTTTGACG 6 1374 +GACCACTGCGCCTAA ref:0:15:CTAACGCGTCA ref:0:15:ATTAGCTCAAT 7 24300 +AGCCTTATAC ref:0:7:TTC ref:0:10:AAATA 3 16 +CCGT ref:0:4:ACAAA ref:0:4:CCTTGCAGAAATACC 3 160 +TTTAAAACG ref:0:9:TTCT ref:0:8:GTTGGGTCAGAA 2 42 +ACTTAGGGA ref:0:9:GATATCCTTTCGCTAC ref:0:9:GGG 1 384 +ACACTA ref:0:6:TGAC ref:0:6:ATAAGCTCAC 2 54 +GCATCGCGACTGGGAT ref:1:15:CCGAAAAA ref:0:16:TAGGGAGCCTTTCCA 7 3488727 +AATGGATATTGT ref:0:12:GTTGCA ref:0:12:TGAA 5 36 +AGATACAGTTAA ref:0:12:T ref:0:12:ATGTTAGGC 6 30 +CACATGGCGTGATC ref:0:14:AACCATGTGTGGCGGT ref:1:13:AGAACTACGTCCGGT 5 17430 +AGC ref:0:3:TATACGTACTTAC ref:1:1:T 1 8 +GCCA ref:0:4:ACAGCC ref:0:4:ATGGTGT 2 60 +CGAAGCTC ref:0:8:AATTGCGCCACGAG ref:0:8:GGACCTGCGGAACG 6 3956 +GTCACCGCTATG ref:0:12:TGAATGACTTCTTCT ref:0:12:CCCAAGGGTGA 3 7380 +AAACC ref:0:5:GCCC ref:0:5:TCGATTGGGA 2 198 +TAC ref:0:3:ACATGCCTACCG ref:0:3:TGTGCCGTGACTCCCC 5 60 +ACAAAATAGACTA ref:0:13:GTTAT ref:1:12:CGCAAAAC 5 4128 +CCTTTG ref:0:6:GACC ref:0:6:ACGATGCGACGGTAGA 4 128 +GTT ref:1:2:TGCAAACGCACCA ref:0:3:CTTAGGC 3 28 +GGATGGAAA ref:0:9:TATAACGTAGGCG ref:0:9:GATGCGGATACT 3 114 +TTGTCTTTT ref:1:8:ACATGGAC ref:0:9:AAATAGTATC 7 1420 +GTG ref:0:3:TAAA ref:0:3:TCTTTGGCCTGCCTTA 1 8 +TTGATGTACGATATAG ref:0:16:C ref:0:16:CGTGTGTTGGT 7 9 +AGGCATGACC ref:0:9:GAATCT ref:0:10:AG 4 40 +GGACC ref:0:5:TCATGCCCTCACGA ref:0:5:GGTTTCTCGGCTCTA 6 10000 +TGAG ref:0:4:CTTCTAGT ref:0:4:TACTATCGGT 4 120 +TCTGGAGCGATGGT ref:0:14:GTG ref:0:14:ATTTTAGTACTCA 7 20064 +AAT ref:0:3:TTTGTTC ref:0:3:TCCTAAGAGAAG 3 1564 +TACCCAGTGCCA ref:0:12:ACCACGAG ref:0:12:CGGGTAACACGTTGG 5 5940 +TAGCC ref:0:5:C ref:1:4:GCG 2 6 +TATCGA ref:1:5:GCACCCCG ref:0:6:GTGCCGGT 4 750 +GCT ref:0:2:AAGGTGGGCCAGCA ref:0:3:CTGGCC 3 112 +TGCTTACACCATA ref:1:12:CTGTGAGGTAGTGC ref:0:13:GAACTCGGATTTCC 6 4480 +CTCATCATACGTA ref:0:13:GCTCCTT ref:0:13:ACCTCTTCGCATG 4 36 +CTCCAC ref:0:6:TCTC ref:0:6:TTGAAGTGTGGCGT 3 306 +ATGCGCTGCTCGAG ref:0:14:CGGATTGGGAGA ref:0:14:GATTC 7 2880 +TGCGACTGA ref:0:9:ATGGTTTGGACAG ref:0:9:ACAATAAGCTAGGGCT 4 920 +TTGAATAC ref:0:8:GTCTAAAGAGGTACG ref:0:8:T 1 42 +GAGA ref:0:3:TTA ref:0:4:GCGGGTGAC 1 84 +AG ref:0:2:GA ref:0:2:GGCCTCT 1 6 +CATGAAAATATTT ref:0:13:ATACGCTA ref:0:13:CCACTGTGGGTTGC 5 2160 +AC ref:0:2:AAA ref:0:2:AGCGGGACGAAC 2 42 +AGGAGTTGCGGTGTA ref:0:14:TGTACCACCCGCAT ref:0:15:CAGCGCGGCCCAATG 9 9942380 +CGCTTGATATCATCCG ref:0:16:CAACAGT ref:0:16:CCT 10 28 +CAGCAACATAGT ref:0:12:GTAGAAGA ref:0:12:TAAACCCTATT 5 4284 +TACTCG ref:0:6:CT ref:0:6:CGCGTCGTCGCTG 1 3 +T ref:0:1:GCCA ref:0:1:CGGGTCATTC 3 15 +CCAATATTAC ref:0:10:TAACAAGAT ref:0:10:TATAATGT 5 340 +TAGTTCCT ref:0:8:GTGGGATGAC ref:0:8:CGACGCTTC 3 852 +GTTACCTCT ref:0:9:GAGTTTA ref:0:9:CCAAGTTTAATGTT 5 3780 +AGCCGTCGTGCC ref:0:12:TTCTGAATAACGC ref:0:12:GGGTATCTT 6 34230 +CACGCGGCATTGCGAC ref:0:16:TTCACTC ref:1:15:AAAG 9 364 +TGATATAGAGGA ref:0:12:TATGTACTAGC ref:0:12:GACCCCAGGTGT 4 8100 +GCCTGATTCTATATGT ref:0:16:ACGCAGTG ref:0:16:TAAGCGACGGCCTA 9 11270 +TGTGTGTT ref:0:8:CTGACGAGATC ref:0:8:GCC 5 1176 +TTATAAAGCGCCGGG ref:0:15:TTGACCGGT ref:2:13:TGCCA 7 6324 +ACCCTTT ref:1:6:TA ref:0:7:CC 3 18 +GACAGACTAGGTACG ref:0:14:AGGGGAAAATA ref:0:15:GCTGGGGAAGC 3 1768 +CGT ref:0:3:TATTGGTGTGGCG ref:0:3:ATCTCC 3 31 +TTGGAAGTC ref:0:9:CCGACA ref:0:9:TGGTT 3 1152 +GGC ref:0:3:CCAAGATTA ref:0:3:GGTCTGCC 2 308 +CCCCTCGTTGCGAGCG ref:0:16:TCTG ref:0:16:GGTGGACGGAAAGC 6 2736 +AA ref:0:2:AATAGTAAGGAACCA ref:0:2:AATGAAT 4 168 +TCCTA ref:0:5:TGAAGAC ref:0:5:T 3 118 +ATGATTC ref:0:6:CCGGCAG ref:0:7:CA 5 294 +T ref:0:1:TGTAGATTG ref:0:1:CGGCTCATT 4 12 +ACTTGGCCGTCT ref:0:12:CAT ref:0:12:TAACATCCAA 8 5040 +CTTT ref:0:4:TAGCCGACA ref:0:4:AGTATGTTGGGAGA 6 2100 +GTT ref:0:3:TGT ref:0:3:A 1 12 +GAT ref:0:3:ACCTAAGACG ref:0:3:AAGCA 3 4 +CCATGG ref:0:6:CCCAAGTGGCG ref:0:6:CGTGA 1 306 +GCGTAGGC ref:0:8:TTACACAACA ref:0:8:CGCTAGACCTAC 5 11803 +CTGTGAAGC ref:0:9:TGTTT ref:1:8:TCGCCACTA 4 1232 +AGCCTAAGACTTGGA ref:0:15:TTTCCGCTGACTCC ref:2:13:ACCCATC 8 241785 +GCTGATGGCGGGC ref:0:13:ATGC ref:0:13:TTCTCAA 7 28 +GTTCCTAACGTA ref:0:11:TTCG ref:0:12:TCCTTTATGAGCC 4 630 +TCTCCT ref:0:6:AAGTG ref:1:5:TCA 3 510 +GACC ref:0:4:ACCACCCTACCTCATG ref:0:4:CGTAACTGCCCCTTC 6 3450 +CAGATGGAGCCTTA ref:0:14:GAAGCAAGCCCATGG ref:0:13:GTCT 4 7392 +GGCCAGCTTCGTAC ref:0:14:GCGTTTTTACGC ref:0:14:AGAGACATATAG 5 45600 +A ref:0:1:GACG ref:0:1:TTC 1 4 +TACGAAACTACA ref:0:12:CAC ref:0:12:ATAGATGG 5 240 +CCCAA ref:0:5:GGATCTCGGTC ref:0:5:TTA 3 25 +TTT ref:0:3:A ref:0:2:GGATAAGGAAGTGCC 1 4 +C ref:0:1:ACCCTA ref:0:1:GTCGCGGTT 2 6 +TCTGCGTATTAC ref:0:12:GAAAT ref:0:12:CACTGGGGGTGCC 5 434272 +GTCCCCCGGAGACTCT ref:0:16:CGGGGAGAG ref:0:16:CAGAACTATGAGCGA 8 162000 +CCGCATGTAGAGG ref:0:13:CCTAATCAT ref:0:13:GA 7 7212 +T ref:0:1:AACCCTCA ref:0:1:GACC 3 5 +TGGGGACGAGATTCG ref:0:15:GT ref:0:15:AAGCCCCGC 9 420 +GTA ref:0:3:TATCC ref:0:3:TTGCGATTTAT 1 6 +GAAGTTCGCAGTCC ref:0:14:TGGCAAAAAGTAC ref:0:14:C 7 2840 +GACTACGCATCGAA ref:0:14:CTCTCCGCGGGGA ref:0:14:AC 6 31304 +CGAGATTTTGGGC ref:0:12:A ref:0:13:TAGTT 8 36 +ACAGCGGGAGTAG ref:0:13:TCGCCCGCGGCACCTA ref:0:13:GATTGCCTGGGCG 5 6984 +CGGAGAGAGATAC ref:0:13:GTCTACT ref:0:12:GAGTTTGAAGT 5 3872 +CGGCAGA ref:1:6:GTGGACACAACTA ref:0:7:ATTCGTCG 1 243 +AGTCTATTACGTAC ref:0:12:CGTCAGCCCAC ref:1:13:CTGTAGCTTGCCG 6 9720 +CACAA ref:0:5:ACGCCGGTATG ref:0:5:TTCCA 2 138 +GTCAATCCGC ref:0:10:GTCGTTTCAATAGA ref:0:10:TGCCTTT 5 21120 +ACGGTTTACGAGTCGT ref:0:16:GATG ref:0:16:GGTATGGAAATGCGAG 7 7550 +GATTAATGTG ref:0:10:AGGAATTGTAGGGA ref:0:9:ATATGTA 3 1432 +GTGGCCAGAGCAGC ref:0:14:TTTAATCACAA ref:0:14:GACGTGAT 6 6720 +GCT ref:0:3:TACGATGCA ref:0:3:TTTGCTTG 2 18 +CTGCT ref:0:5:TTGTACGGCGATAG ref:1:4:TGATGAAT 3 322 +ATCCAGAC ref:0:8:CATA ref:0:5: 3 6 +ATACGTGTC ref:0:9:GTTG ref:0:9:TCGTGCAA 3 6 +CCCAACGTGTT ref:0:11:TTAGTGAAGCACCAT ref:0:11:GTGTGATTGGAGAA 7 14223 +CAAC ref:0:4:ACTG ref:0:4:ATTGTTTCGT 3 16 +TGGG ref:0:4:CATCGGACACAAAT ref:0:4:CCCGCG 3 264 +GCGTCTCAACT ref:0:11:AAGCTCA ref:0:11:CTATGTTAAGTGT 3 120 +TCGGTGTA ref:0:8:CTAGAATCCC ref:0:8:GAGACAGTGATGTC 3 70 +TCTTAGG ref:0:7:CCCGGACTAT ref:0:7:AGTGGAAATTCGCAGT 5 5880 +CGAGAAGTAGTGGTT ref:0:15:TTC ref:1:14:AACTCACTTATGCT 7 480 +CCTTTA ref:0:6:AGATCCTGGGTTTTGT ref:0:6:CATAG 1 675 +GAAACG ref:0:6:TAAATTTCTGCTGTT ref:0:6:GGTTCTGCA 4 180 +CCCAGGCCCGGCTAC ref:0:15:GTGTTACAT ref:0:15:GGCTTGGTTCCTTAG 8 6400 +GCACAAAAC ref:0:8:ATAGCAGCGATGAT ref:1:8:TTATAGGTAACGGC 2 3584 +ACCCATTTAG ref:0:10:ATAAGCCCATGTTCAA ref:0:9:CATTC 1 189 +GGCAATCT ref:0:8:TTCAAT ref:0:8:TTCGTTAGGG 5 444 +CTTGATCC ref:0:8:GCCCGTCAA ref:0:8:AGGTC 5 1520 +TGG ref:0:3:CTCGAGTGTGG ref:0:3:GCGCTC 1 14 +GAG ref:0:3:TAGGCTTGCAGGTAA ref:0:3:CTTTGGAGC 3 12 +CATTTTTACC ref:0:10:T ref:0:10:GCAACGGTACGGAA 5 5885 +CAGATGTA ref:0:8:GCATATACATTGGGTC ref:0:8:GCCACCTTGGCGCC 8 509292 +TCGCTCCATCTTGCTT ref:0:16:CATAGG ref:0:16:AGCCAACTACGGTACA 10 1196460 +GCTAGGGTGACGAG ref:0:14:TCATAAGTAACC ref:0:14:ACTAAGTAGAGG 6 17496 +ATAACTAT ref:0:8:TCCGTAGTTAAAAGA ref:0:8:CCGGCGAGTGTCC 7 116532 +ATCAAA ref:0:6:AAATGATGATAA ref:0:6:GCGTCCGTCGCGAC 3 31652 +GGGTTACTGGAGG ref:0:13:CTCTTACCTGCC ref:0:13:CTGTGGTACCTC 8 38976 +CTGGAAGAAGCA ref:1:11:ATACAGCCG ref:0:12:CA 6 822 +TCACCAGAGCTTT ref:0:13:CATTTAAGAATCGCA ref:0:13:CGTCCGAACA 7 25600 +TAAAGGTGAG ref:1:7:GAAGGC ref:1:9:GTTTTCTT 3 12240 +GCGGTTTTCAGTG ref:0:13:ACGCACG ref:0:13:TACCGCTT 8 10336 +TTTTCGGG ref:0:8:GTACGTCAGAACT ref:0:8:CACCGATGGCCG 6 318816 +GCATTTCCAGCG ref:0:12:TTG ref:0:12:AAC 6 6 +AGTGCTCCTGATAA ref:0:14:GTAACTC ref:0:14:CGCAC 9 1488 +GCAGCTCGTAC ref:0:11:ATCCCC ref:0:11:G 6 123 +TCGC ref:0:4:ATGTAAAACGA ref:0:4:GTATCTACTGGGCC 3 150 +AAGCTCCC ref:0:8:TT ref:0:8:TTCCGAGTCGGAC 4 378 +CGG ref:0:3:GGGGACGTAGC ref:0:3:GTCTTTGTGTG 2 3 +C ref:0:1:G ref:0:1:GGATACTAACCCGTG 1 8 +CGCGCATTCCTAA ref:0:13:GATCAGGTCCCTT ref:0:13:CCAA 4 9664 +TGCAGGAAC ref:0:9:CGGGT ref:0:9:G 6 90 +TTCCGGAGCAGCA ref:0:13:CGC ref:0:13:GCTGGCCT 8 1500 +AGC ref:0:3:ACTTCCACTAAGGTA ref:0:2:TAT 2 92 +TTAACTTCG ref:0:9:GGCTTTTTAA ref:0:9:GTCTAATCTTGGAA 5 186 +C ref:0:1:AGTCTCAACC ref:0:1:GCCAAATGTCCAA 6 16 +ATTGCAG ref:1:6:GCGCGCTCGAATGAC ref:0:7:CTAGTG 4 6900 +CCGCGT ref:0:6:TCCACTGCATT ref:0:6:CTCTT 3 380 +ATAATTATCCG ref:0:11:GGGCACCCCTA ref:0:11:A 8 52476 +TGA ref:0:3:GGGTTAATTG ref:0:3:GACCAA 2 72 +AACACA ref:0:6:CCTG ref:0:6:CGCCTTATTGTTAG 5 372 +ATGTCTCTTGAAG ref:0:13:TCACTGCACATA ref:0:13:CTCCCCACCTCCC 9 4261572 +GCACGTCT ref:0:8:CCTCA ref:0:8:TGTG 3 60 +GGCAAGGA ref:0:6:ATATTGAAATTAGA ref:3:5:ATTTC 2 7950 +TACCAATAACATTT ref:1:13:TA ref:0:14:ACGG 10 657 +CC ref:1:1:ACA ref:0:2:ACCATAGGGGTCGC 1 6 +TTTTGTGGTT ref:0:10:CCAGTTCGGACACTTC ref:0:10:GTTTTATC 5 39494 +GGATTGA ref:0:7:CTTGTTAAGGGCTT ref:0:7:TCG 3 387 +GTACTC ref:0:6:ATGTTTCTGGGGAGTT ref:0:6:TCCCTCGCTCGAAGGT 6 6825 +T ref:0:1:CTAAACGT ref:0:1:CGCTAAGC 4 2 +CGATTTGCTCCAGA ref:2:12:AATATT ref:0:14:GCGCCA 5 550 +ACGTAAGT ref:0:8:TTCCCAA ref:0:8:GACAGGAAGCCTTAG 1 240 +GT ref:0:2:ACGGCAGGATGT ref:0:2:CGCCGACTGGGCT 6 63 +CCTAAGGCTGGC ref:0:12:TCAC ref:0:12:ACAGA 8 3366 +GTGTACCCTAGTGTG ref:0:15:TAAGAACTAGA ref:0:15:TCTG 8 3888 +CAAGTCCTTC ref:1:9:GCTT ref:0:10:ATTTCCTG 2 168 +ATTGTGCTT ref:0:9:CGTGATC ref:0:9:G 5 82 +GAAACGGGTCGTC ref:0:13:TTGCGCCACGACGA ref:0:10:GGTTTAGTA 6 225968 +CC ref:0:2:ACCCTACGC ref:0:2:AGT 2 100 +A ref:0:1:CGTTCATCAA ref:0:1:GAAAACTGA 3 15 +CGTTGGAATCCCC ref:0:13:TCGTG ref:0:13:TGGTACC 5 224 +ATCCGCC ref:0:7:CCGAATGGCGA ref:0:7:TT 3 608 +GT ref:0:2:CTATCCGCTACCC ref:0:2:GAAATGTTTGAATGA 3 10 +AGTAC ref:1:4:GGAAG ref:0:5:TAGAAGACA 3 190 +TG ref:0:2:CTCCCCTTGGTGATC ref:0:2:CCGGT 4 80 +CGAGCT ref:0:6:GGAACTGGCCCTCT ref:0:5:CCTGAA 1 728 +C ref:0:0:TATA ref:0:1:AATAGTCCCTGAGG 3 3 +TACCCAGGA ref:0:9:ACGCGTTGTATCCGCG ref:0:9:C 3 108 +CAAGAGTTGGGA ref:0:12:TC ref:0:12:TAAATG 7 144 +AATGGCCTACCACAA ref:0:15:TTATATTGTAG ref:0:15:TTT 10 1120 +T ref:0:1:CAGGGAGCCTGGACGT ref:0:1:TCCCAGTGCA 5 4 +ACTGGTGACG ref:0:10:TGTTCGCTGAGCCTAT ref:0:10:G 3 40 +TCCAATCAGTAAA ref:0:13:ATAATACGACAACCT ref:0:13:AAC 4 2 +GTAA ref:0:4:GGTATACCT ref:0:4:AATAGTGGTCAGAGTG 2 8 +CA ref:0:2:TGGCAGACTTACCTG ref:0:2:GC 1 4 +GTCAAGCTGAAATA ref:1:13:ATCCT ref:0:14:TACATGATGC 5 90 +ATTAGG ref:0:6:GCAAAGGGACTTTAT ref:0:6:GACAATCTCTC 6 4284 +CGGGAAAAGGCCC ref:0:13:CCCTCCAA ref:1:12:TATTCAGTAT 9 73234 +ATTCGGAGAGCTTA ref:0:14:TGGACGGTTGGCT ref:0:14:TGGACGTTCCACAA 7 9176 +GACTACAGTTTT ref:0:12:TGGGTCAG ref:0:12:T 7 50 +ACTCGTCA ref:0:8:CAATGCTGGG ref:0:8:CGTGCTGTGCCGCG 6 2222 +A ref:0:1:CTATCGCGTGAGCGGT ref:0:1:AGGGTAGAGCGGG 9 6 +TGAAGCCACT ref:0:10:GCA ref:1:8:ACGC 4 84 +GTCCATGAGCG ref:0:11:CACTATAATG ref:0:11:CCGAC 3 15 +CCGCGCTTAAACT ref:0:13:CTCATCTAAGCCGCTG ref:0:12:CGGCACAATGTACCC 7 495552 +CCCT ref:0:4:ACTTCACTAGGCG ref:0:4:GGAGTATC 4 164 +ACAAAGGAG ref:0:9:TGTTCTGGTAGC ref:0:9:TCCT 6 1920 +CTATTACAGGGCCGCT ref:0:16:GCGGCTGCACTGTAGT ref:0:16:ATGTACCAGGTCACTT 7 8704 +ACACTGTTGTTTGCTT ref:0:16:GAATGCTG ref:1:15:TCTACGC 8 207 +AAAAAG ref:0:5:TACTCGTTAAAT ref:0:6:CGCACGGGTGTG 5 35698 +TTACCCTCCTT ref:0:11:GGTCTGCGTGGA ref:0:11:TGCGCATGCCTCTTA 6 75072 +TCTCTGAACCC ref:1:10:ATTAAGGACCTAA ref:2:9:ATGTCTAGGCGT 6 25536 +TTATCCGATCAGTGT ref:0:15:CAATGAGGTTGAC ref:0:15:GCTG 7 824 +GCCCGCCTGCGAGTT ref:0:15:TA ref:0:15:AACTCC 11 782 +AAATCGGCCTTTTG ref:0:14:CTGTTTCCAATAGCG ref:0:14:ATTTTAACATAC 10 198 +C ref:0:1:ATTTAT ref:0:1:GT 2 21 +GACACGAAACGGAT ref:0:14:ATT ref:0:14:TATC 12 6627 +CTATTGGA ref:0:8:GAAGGATGATGCC ref:0:8:CCCACCCCCCTTT 3 41715 +CCATAA ref:0:6:TTCCA ref:0:6:ACGAGTCG 2 72 +GCGAGTCTGTGGCGA ref:0:15:AG ref:1:14:GATGTATG 8 370 +CGCGTTGTC ref:0:9:CTGTG ref:1:8:TTGGGTTTAGGAA 4 4320 +CTATCCAATC ref:0:9:CCATGA ref:0:8:GACACTACTCG 4 690 +TAGCCCTCCCTG ref:0:11:CGAACACTGACA ref:0:12:TTTAACGCCTACCGGA 5 544050 +TTTG ref:0:4:TATAGTACTAAGT ref:0:4:ATATGTTCACCGGG 4 48 +GGAC ref:0:4:GCTAGTGTAACAAG ref:0:4:TTGATCTAG 4 24 +CCCAGGCATA ref:0:10:TTGAGA ref:0:10:ATGCCGGG 6 8918 +AATCCCGTG ref:0:9:CGAGTAACTT ref:0:9:TTAATGGA 4 301 +ATCACCC ref:0:7:GCTGC ref:0:7:A 4 244 +GATAGACAGCAA ref:0:12:CGAGGCCTGAAATG ref:0:12:TAAAGAGTAAGAGGGC 5 8864 +TAATATTGGTCAGG ref:0:14:TTGAGAC ref:0:14:G 9 356 +TGGAGAATCCCTCACA ref:0:16:ATCAAC ref:1:15:GAAGGGAG 9 370944 +A ref:0:1:CCCTCCAATAATGGC ref:0:1:TGT 2 16 +CTACGTTCAAATGGC ref:0:15:CAA ref:0:15:AGACATTGCCGGTACA 6 2448 +GGGGAAAGGGTAGGT ref:0:14:AGT ref:0:15:TTGGTCATAG 7 3726 +TAGAGACGATCTAT ref:0:14:GAACGGTACCG ref:0:14:TTA 6 330 +CA ref:0:2:AAAGACG ref:0:2:TCGGCCCCAGAC 3 130 +TGCCACG ref:1:6: ref:0:7:GTCATTATCCGGTAG 2 122 +ATATAGTGG ref:0:9:GAAGG ref:1:8:GTTTAATCGGCT 3 225 +GGA ref:0:3:ATGCCCCACGT ref:0:3:CCTTCAA 4 490 +CAG ref:0:3:ATCGGGCAGCCA ref:2:1:CGTCATA 2 2 +AT ref:0:2:TCATCTTTCTA ref:0:2:GTGAAATCTAT 4 50 +TATGTTCCGTCCTA ref:3:11:GGCTTTCG ref:0:13:GAACCCTG 3 2296 +AGTGTACCAC ref:1:9:GAGCA ref:0:10:GGAAAGTT 4 280 +TACTT ref:1:4:GCCAGC ref:0:5:C 2 1 +CAGTC ref:0:5:AGTCGCTGAACGCA ref:0:5:CGCACAGCTCCGCTTA 5 210 +ACAGGCTGTACCAA ref:0:14:GGAT ref:1:13:ATTC 7 64 +AAAACGGCGTGCAC ref:0:14:AGCATGACTTACGAG ref:0:14:GGCTTTTTTAACATGA 9 22608 +GTATGAA ref:0:7:A ref:0:7:TGT 4 30 +GTTGCCTA ref:0:8:AGGTCATTCTTGC ref:0:8:TCCG 4 1440 +GGTGAGGGACGA ref:0:12:TGGA ref:0:11:ACCATGCGC 7 10864 +TCCGATAC ref:0:8:CTCCTGG ref:0:8:GT 3 12 +TA ref:0:2:ACCCATGG ref:0:2:GTGCGATACTGCTATC 4 63 +G ref:0:1:TAAGTTGTCTCG ref:0:1:CACTCGTGAAGGAG 5 15 +CA ref:0:2:ATTCATAAGCTACAGA ref:0:2:TGCCGCGAC 4 33 +TTGTG ref:0:5:CA ref:0:5:CGTAAATAT 4 42 +GGCCTATC ref:0:8:CAGATAGCCGTAACA ref:0:8:TATCGTCACAGGGAG 5 999 +TCGGCTGTTGCC ref:0:12:CACATG ref:1:11:GCGATCGTAGAAA 6 11880 +C ref:0:1:ACCCGTTCTAAA ref:0:1:GGGTT 3 24 +TGTGA ref:0:5:GGTTTTGCCG ref:0:5:CCCGTG 2 488 +ACTTTCACGA ref:0:10:CTCTTTGACAGAGG ref:0:10:AACTACACTC 1 1980 +GAGGGTGCCAC ref:0:11:AGCGCACTCTT ref:0:11:G 5 430 +CCGACCAGCGCC ref:0:12:GACACACGCCGGG ref:0:12:TCCTAGACCCTG 1 1 +CAACCCAGATTCGAAC ref:0:16:GA ref:0:16:ATTCCCTTTGAG 8 700 +TATAATCGGGGG ref:1:11:GATTACTCGTGA ref:0:12:ACTGGGTGATCAGAG 5 207515 +GCTTCTCAGTCAGTGC ref:0:16:CTGTCGTACCCAA ref:0:16:TGGCGTGAAACAG 9 916725 +GAAGCACCGG ref:1:9:TAGC ref:0:10:AATCTGGATGGTT 2 135 +TAACGAGT ref:0:7:GTTGACGGGAGCG ref:0:7:CTCCCTTTCAACTCG 2 1512 +G ref:0:1:GTCACGTTAC ref:0:1:ATGCT 2 2 +ATGAAAGA ref:0:8:GACGGTAT ref:0:8:TCGCCTCTC 6 8946 +CCATGCATATTC ref:0:12:CGAGA ref:0:12:AAGCCGACG 6 570 +TGGAAGATGGCATG ref:0:13:CACCTCTCCCACGTA ref:0:13:AGAAGGC 5 156672 +GAG ref:0:2:CGTCGTGCGATA ref:2:1:CT 1 24 +AAC ref:0:2:CATCCGGAG ref:0:3:AGCGGGT 1 3 +AAACGCCT ref:0:8:A ref:0:8:ATGGGTGCGCAGCG 3 216 +GAG ref:0:3:GTGAACA ref:0:3:CGACTCTCATTAGTAG 3 144 +CCTGAGGTGCG ref:0:11:ATATCTCCAAT ref:0:11:GGTGC 4 1359 +TAGGGC ref:0:6:G ref:0:5:AAGCTAGCTAG 1 27 +AGTC ref:0:4:CA ref:0:4:CGCGGGGGAGATTA 2 10 +TTCACGTAA ref:0:9:GTT ref:0:9:AACCT 5 168 +GTC ref:0:3:AGAA ref:0:3:ACTAACC 3 36 +CGTGTGAACG ref:0:9:GACCC ref:0:10:A 6 54 +AACGCCTCATC ref:0:11:TGCGTTGTAG ref:0:11:CGGTGAGGTCAGC 8 335664 +CTTCAA ref:0:6:TCGAAGGTGACCCCA ref:0:6:AC 3 1480 +GATCGCGTTTATGC ref:0:14:C ref:0:14:TAAGCAAAA 10 6012 +ACG ref:0:2:GTGATATCT ref:0:3:TGATCATCTGGAGTC 6 18 +ATACATTGTATTG ref:0:13:CATGCTCGCA ref:0:13:TG 7 396 +GACGGTGGAGC ref:0:11:GCCGAAACGCACTCAA ref:0:11:TTTTCAATACTCG 8 2036848 +AT ref:0:2:G ref:0:2:C 2 9 +GTATAGCATT ref:0:10:TATG ref:0:10:ATTACCGCCTC 3 40 +AGACTCAGTGTCCGCG ref:0:16:CATTA ref:1:15:GCGCGCACTAGT 8 2100 +GGCCACG ref:2:5:ACAGAAGTC ref:0:3:GTTCAAT 2 188 +TTTGCC ref:0:6:C ref:0:6:CGTGGTGGCAGTGAGA 2 310 +TCATTACCGGGA ref:0:12:TTC ref:0:11:GTTAGGC 5 144 +CCA ref:0:3:ACTATACCGATT ref:0:3:TTCT 3 27 +CAAGGAGCTAAA ref:0:12:GCATCTCCACTACAC ref:0:12:AACGTAACCGCCT 4 7362 +CGCCGTCA ref:1:7:GGCCT ref:0:8:ACGCG 2 4 +GAACTCGACTAG ref:0:12:ATTGCTAAA ref:0:11:TACTTGGGC 5 7020 +GT ref:0:2:TAGTAG ref:0:2:AAACGCTCCTAA 2 2 +ACGCCATCCGTATA ref:0:14:TTGT ref:0:14:CG 10 132 +TCTCT ref:0:4:AAATACCA ref:0:4:TTCCCAGCCTACAG 2 10 +GACTAT ref:0:6:ACA ref:0:6:TACCAGGGTCGCGTTC 2 105 +A ref:0:1:CAGTGTCGAACGT ref:1:0:CTC 2 3 +ACAAGTTTA ref:0:9:CTATACAAC ref:0:9:AGACCGGAT 5 73602 +CAACGCCGAAAGTG ref:0:14:GTGGGCTACCCC ref:0:11:ATTTAGGCCA 4 333 +ATCGAAGAGCCTG ref:0:12:GGGTCTTAACTT ref:0:13:TC 6 726 +TCGCGTTCAACTGAT ref:0:13:GGGACTC ref:0:15:ACTCTCAGATAATATA 3 228 +CA ref:1:1:GTGAACC ref:0:2:AGTGGCT 1 6 +GTAAACCTTTCCGGTA ref:0:16:TAAGC ref:0:16:TCGATGCGGTC 9 46136 +TCTTCTTCATG ref:0:11:TTTTGGGGAA ref:0:10: 6 386 +CGGTTTGG ref:0:8:CCA ref:0:8:ACCTCC 7 6424 +TACACATG ref:0:8:TGTTAGGAC ref:0:8:GACAGTGCG 3 270 +AGCTCATTCCTTGA ref:0:13:GAATGCGTT ref:0:14:CAAAGG 7 44310 +TAAGAGTGTTATCT ref:0:14:AA ref:0:14:GGCG 9 48 +GTTGTGGGCATC ref:0:12:CAATCACCTGCCGGT ref:0:12:TCCCTAGATAG 8 48600 +GA ref:0:2:ACTGGCG ref:0:2:TGCGGGTCTTT 4 279 +AGA ref:0:3:CC ref:0:3:T 3 40 +CCGGAGAT ref:0:8:TGGTCGTTAAGC ref:0:8:TATAAGACTCAATGT 6 2592 +TTTAGGAGGGGTTACA ref:0:16:GGTAAACACAATGGTC ref:0:16:A 9 263864 +GCCATTCGGCT ref:0:11:AT ref:0:11:GT 8 15 +GCTTGTATGCTCGAT ref:0:15:CTGCGACCGGA ref:0:15:TCTGCCTCTACAGCA 6 1330 +CG ref:0:2:GATATCTACAGACCTC ref:0:2:AAGATA 4 6 +AG ref:0:2:CGGAGTTATGGTCC ref:0:2:CAATGGGCGCT 6 40 +CAGATT ref:0:6:AGTTTTCATTGTCCG ref:0:6:TC 2 12 +TT ref:0:2:GCTATAGCCCCCGTTC ref:0:2:A 1 18 +AACCCCCGAAGGTTC ref:0:14:AGGCGA ref:0:15:GGCTATGA 10 2232 +TCTGGGAT ref:0:8:CAGACTACACT ref:0:8:CTGATTAGACACTCG 7 2960 +CAGCACGACCATA ref:0:13:TCTGTT ref:0:13:C 10 950 +CCAGTCTGT ref:0:9:AAAATT ref:0:9:AAAGGTTCC 7 61600 +TTAATTAA ref:0:8:CGCA ref:0:8:GAAGGTTTTAACAA 4 30888 +CAG ref:0:3:AATGTGT ref:0:3:GTAA 2 66 +TCTGC ref:0:2:CCGGAGGCC ref:0:4:AAGTGTT 3 380 +CTCAGTGAGCA ref:0:11:GGTTACGCATCGAATT ref:0:11:GA 4 165 +T ref:0:1:CTGAGGGATGAGGAGA ref:0:1:CGCCCGATTCCG 5 4 +TATGTGACTGA ref:0:11:GGAAACGCCGCGCTCT ref:0:11:CAGCTTGGG 6 820583 +CTCCACACTTC ref:0:11:TCCA ref:0:11:TAGCATTGTAA 4 56 +GCGCAGGCTTT ref:0:11:GGTCTCTGGT ref:0:11:TAA 5 4500 +ACCGCGGCACCCTTAG ref:0:14:GTGCCGTATT ref:0:16:CCGCGTCGTTTTCGT 7 896995 +CTGTG ref:0:5:TATCTAGTCAAT ref:0:5:TATGGTACC 4 240 +AGATGA ref:0:6:TGGTCACTGACT ref:0:6:CACGCTCAG 2 35 +AGATCGGTG ref:0:8:TTA ref:0:7:CGGTCATCTTCG 2 55 +GGT ref:0:3:CACCGACGGTGCACC ref:0:3:CCACAAAACG 5 33 +CATAACCC ref:0:8:GCCCAAG ref:0:8:AGTTACG 4 2370 +TC ref:0:1:TGAATT ref:0:2:GAGTTGTCCGA 3 18 +AAAGGCCTCAGTGGT ref:0:15:G ref:0:15:CTACAAGC 10 350 +GGCTTGTATGGA ref:0:12:CTAG ref:0:12:TTTGCCGCTTTC 4 108 +AACCGCACC ref:0:9:TTGGGATACGGCATGC ref:0:9:AAATGCTAAGGAA 3 16060 +CT ref:0:2:ATTCG ref:0:2:GTTCTACGG 3 7 +TCAAA ref:0:5:CAGATGCCCTACCTC ref:0:5:AGAGTAGTCGGCTAA 1 23 +ACAAAC ref:0:6:TATTATCATGCTC ref:0:6:GGA 2 3904 +TCCATATCC ref:0:7:CAGTCCTCGCCCTA ref:0:9:CGAACAGT 2 2240 +ACA ref:0:3:TGACGCTGCGACCTC ref:0:2:CGCTCT 4 27 +GAACTTCATAG ref:0:11:CGCCTTGC ref:0:11:TTTGG 5 63 +TGG ref:0:3:GAAAAGTGCGCATC ref:0:3:A 1 4 +TAGTGTTTCAGGA ref:1:12:CATACCAT ref:0:13:CT 9 7347 +ATTCCTGGGCCGG ref:0:13:CTGCAAATGTCGA ref:0:13:CACAAATCA 11 86310 +AATGG ref:0:5:A ref:0:5:CCACACCG 2 18 +CAGAAAACGGCTTGC ref:0:15:TAAGTGCGGG ref:1:14:AACG 8 37000 +GGC ref:0:3:CTAGGCTGAGCT ref:0:3:TCAGTATTAGA 4 14 +TTA ref:0:3:TACACCC ref:0:3:TCAAAGCGTATGTACA 3 78 +TCCTAGAGCATGCTG ref:0:15:CCCTTGCT ref:0:15:GGAGTA 5 14 +AAAATCT ref:0:7:TCCATAGGATTG ref:0:7:CAG 4 530 +AGCTGC ref:3:3:ATACGATCGTG ref:0:6:GATGCAACAAAGG 4 47 +C ref:0:1:AACA ref:0:1:ACGCTGCATTAT 2 3 +TTTCCTGCTTGCTA ref:0:14:CGACGAT ref:0:14:TAGCTG 7 192 +GA ref:0:2:GTCCGCGG ref:0:2:CCAATAATTA 2 450 +TTGGGGAA ref:0:8:AGAGATCT ref:0:8:AAGCGTATAGAGG 4 1158 +GACCAACGCGTCC ref:0:13:AC ref:0:13:TGTGTT 8 1988 +AGTGACTTTGTAT ref:0:13:TT ref:0:12:TCCGT 8 105 +ATCCAGTCCCG ref:1:10:TTCTAT ref:0:10:GCCAACA 3 595 +AAACATATC ref:0:9:CCACGGACTGTT ref:0:9:T 4 320 +TGAGAAT ref:0:7:ACGTGGTTTATAAA ref:0:7:ACACTA 2 350 +CC ref:0:1:TCGGGGGAA ref:0:2:TGGGCACCCGATA 2 6 +GGCGGTT ref:0:7:CGTATCTTCAAC ref:0:7:TGACCTACTACG 6 442 +TCAGTAGATCGACTGA ref:0:16:AACTTCTGACCAT ref:0:16:C 8 486 +GTGACGG ref:0:7:TGCTG ref:0:7:ATTGTAAAAG 2 615 +TCGAT ref:0:5:TAGGGTGCTT ref:0:5:GCCGC 3 2355 +TCCTCCTTGATAAG ref:0:14:CTGTAAAAAGACGAG ref:0:14:CTCGTTTCCCACCT 6 2424852 +TTGATAGGAA ref:0:10:ATCTTCG ref:0:10:GC 6 75 +GACGACTA ref:0:8:TGTCTTTGCAGTCGAC ref:0:8:CAAG 2 12 +GACA ref:0:4:ATCTTCAGTCGCCAAG ref:0:4:ATGACTTCGGTAG 6 168 +TAC ref:0:3:ATTT ref:0:3:CAA 2 112 +CGTCCGG ref:0:7:AGCCGTGGAAAA ref:0:7:G 2 24 +ACGT ref:0:4:GTCGCCGGGCC ref:0:2:TGGGTGCTT 4 1351 +ATCTCGCGTGAC ref:0:12:GGATTGTAA ref:0:12:CTCC 3 24 +A ref:0:1:GCGTTGC ref:0:1:CATCACACGG 3 24 +CACATGCC ref:0:8:GT ref:0:8:GAGATAAGGTCG 4 288 +GGCA ref:0:4:ACGAGTCGTCTGGAA ref:0:4:AAG 2 72 +AGC ref:0:3:CGAATTGCACATC ref:0:3:TTGATGCCTCT 5 18 +CTTGACACGGGC ref:0:12:A ref:0:12:AGACCTCTGTGGGA 5 472 +AGGATAAG ref:0:8:TCAACCTCCT ref:0:8:CAATTATGCAA 5 896 +CCAACTAT ref:0:8:TTTCGTATG ref:0:8:TA 4 56 +TCGG ref:0:4:GGCG ref:0:4:AAGATCGAGGATGGT 1 110 +CCGACAAA ref:0:8:TGAGACAGCG ref:0:8:TAGAAGC 8 43776 +G ref:0:1:CAGTAGACTCTCGGAA ref:0:1:ACTGCA 4 4 +GTCGTTCCT ref:0:9:CCTTCGACAATGTGA ref:0:9:CCCCTGAAGAAGC 7 90 +ATGGC ref:0:5:GGG ref:0:4: 2 6 +TCGGTGCAAGGG ref:1:9:GTCAAGTT ref:0:12:CCTATTATATGCG 4 1894 +CCTTTCCC ref:0:8:GTAGATTCGCAGG ref:0:8:GGGCGTCG 5 4158 +TCGGAT ref:0:6:TACTCGATCC ref:0:6:TTAGCAATT 2 816 +GTAGCGGGGTAC ref:0:12:CACACGTCTCGT ref:2:10:AAGGCA 5 300753 +CTAACC ref:1:5:GAGCGCC ref:1:2:ATCACTC 1 25 +CGTCACGTAGCCACC ref:0:15:GGA ref:1:14:TCGTAGGAA 7 168 +TCACTGCTCGT ref:2:9:CCCGCA ref:0:11:CGTCTCCATACCAA 6 1368 +TGGTCCCCGACA ref:0:9:AACT ref:0:12:AGGTTGTCAG 6 8064 +GCTCGTTCCG ref:0:10:AATTTA ref:0:10:C 6 96 +TATCAGC ref:0:7:AGGG ref:0:7:CTAACGTTTTGGTGCC 4 18144 +TAGGGAACA ref:0:9:ATGTGCATTAACG ref:0:9:TCGCTTAAACGGGGG 7 98256 +GCCCCGATACG ref:0:11:TGATTGTGG ref:0:11:AAC 5 483 +GTCGAT ref:0:6:CGCACTAA ref:0:6:CAA 3 8 +CAGCGTA ref:0:7:AAAAGATCGC ref:0:6:ACAC 2 30 +CTCG ref:0:4:TTC ref:0:4:ACACTTGCA 2 48 +CGCA ref:1:3:GGG ref:0:4:TCGAGGAT 3 80 +TTACTGTCGAAGGACG ref:3:13:TC ref:0:16:GCCAGTC 7 340 +ATAT ref:0:4:GTTGGCTCACTTGAG ref:0:4:TACAGCGTACTG 5 58 +TTCCACACGTTACGTC ref:0:16:GTGTCTACT ref:0:16:AGGT 7 22 +CTCT ref:0:4:TACGAAAGGGCACTTC ref:0:4:TGCGAA 4 220 +G ref:0:1:TAAGGAAGTGAAT ref:0:0:TTA 2 4 +TATGAAAGGGCGA ref:0:13:TAGA ref:0:13:ATAGCAACGGTGCCAC 3 1056 +CGGACTTCGCTG ref:0:12:ATAGGATACGCCTT ref:0:11:GCAGAGTACGCA 4 4752 +CTTTAAGAC ref:0:8:TCACCCCGTTCG ref:1:7:GG 5 808 +CCATGATTTGCAG ref:0:13:CGATGGCCCCAGAT ref:2:9:TCCGT 3 252 +TGACAAAATACT ref:0:12:ACCACGCTAA ref:0:10:CT 6 630 +A ref:0:1:CGCGT ref:1:0:GCCCC 2 6 +TC ref:1:1:G ref:1:1:ACGCA 1 4 +GTTTCCGC ref:0:8:ATCCTAATTTTT ref:1:7:GA 4 3120 +G ref:0:1:AACAA ref:0:1:CTCTTCA 3 48 +CCGTTCATCATA ref:0:12:AGAGAGTCACT ref:0:12:TTGTGCCTGCC 6 76076 +CACG ref:0:4:TCCGA ref:1:3:C 1 1 +TGGTGTTGC ref:0:9:CG ref:0:9:GGGATCAAACGG 5 1083 +GGGTACCTT ref:1:8:CAGGCCTTTCAG ref:0:9:C 2 6 +AAATTGACC ref:0:9:CCCAGCATA ref:0:9:GAAT 5 128 +GGAAAATGGG ref:0:10:CAAATCTAGGAA ref:0:10:CTGG 5 4893 +TAAGCTCTATAGCC ref:0:14:AGCGTTAG ref:0:14:GTCTCTTCACGAG 5 560 +A ref:0:1:ACTCTGCTACCCAAT ref:1:0:GGG 1 4 +TGA ref:0:3:TTTGCGCCTT ref:0:3:ATAGCGCGTCATACC 5 216 +TCAATG ref:0:6:ACTCCCCGC ref:0:5:AACAACAGTTT 2 1080 +CTACCCTGCACCAATG ref:0:16:ACGCGTGAAATTTAA ref:0:16:AAAGCTC 7 46200 +ACCATAAGACCAAG ref:0:14:T ref:0:14:AGTAGGAAAACA 7 2511 +AATAGACTGACT ref:0:12:ACCTG ref:0:12:GCACAGCCAATGCAC 5 1472 +TAG ref:0:3:ATAAGCCGGTGGCC ref:0:3:GATGTTTCCGGTA 6 540 +TGGTCAGAT ref:0:9:CCGA ref:0:9:GCGTG 4 21 +CTCGGCAACAA ref:1:10:CGCGCGAATTA ref:1:10:GTTCGA 2 192 +A ref:0:1:CTGTGCGATCTGCACG ref:0:1:ATTGGCA 5 4 +GCAG ref:0:4:CATAGATCTACC ref:0:4:GT 2 25 +A ref:0:1:CGT ref:0:1:TCACTAAGAGGGCT 3 16 +TGACGTGTGT ref:0:10:GGGATGTCTTC ref:0:10:AAACGCCAATAGGAC 3 2970 +TTACGGTCATTTCTT ref:0:15:AGGTGATGT ref:0:15:T 8 416 +GGCAGCTAGACCCTAC ref:0:16:ACATACACC ref:0:16:ACTTCAGA 8 632 +CTAAGCAGTGAC ref:0:11:ACCGTCCAG ref:0:12:CA 6 576 +AGTTCGAACA ref:0:10:TTGTACACGAGCTTCC ref:0:10:GGACATCACG 4 1 +AAGCGGCGATTAGCCG ref:0:16:ACTATGTGC ref:0:16:TAGA 8 952 +GGTTGA ref:0:5: ref:0:6:G 4 3 +GGTTGA ref:0:6:GTAGAATAGGGG ref:0:6:CTCTTATTTACGAC 3 19968 +CAAGCGGA ref:0:7:GATCTGGCCGTGCGC ref:0:8:ATC 3 990 +CATGACAC ref:0:8:ATGGGAAAGCCC ref:1:7:GGGT 3 8208 +TTCTTATGACAGT ref:0:13:CATAG ref:1:12:AGTACTAGCTCACA 3 12 +GCGTCCGTCATAGG ref:0:14:TGTGCTAAACCCA ref:0:11:GA 4 24 +TATTTCATAACGTG ref:0:14:GTGGCGAC ref:0:14:ACTATGGTCCGGGCGC 7 31200 +G ref:0:1:CGTCACTGTTTAC ref:0:1:ACCCTTGTC 6 2 +TTGCGGATTAGAAC ref:0:14:CGTTTTAAACAGA ref:0:13:ATGT 5 650 +A ref:0:1:CAATGCA ref:1:0:CT 1 3 +CGCCGACTGAATCCGG ref:0:16:CG ref:0:16:GGTACACA 9 560 +TGACGTCCCACAGG ref:0:14:A ref:0:14:CATTAAACCG 9 16209 +ATCAC ref:0:5:TCGATCATGA ref:1:4:CGTGAG 3 36 +TCGTTGTTGATCCACC ref:0:16:TTAGCCATCCCAAGTA ref:0:16:GTATGGCTAAG 9 472248 +GGTGCGCTGGGC ref:0:12:GCTGGTATCCA ref:1:11:CAGGCCAGCAAG 5 13740 +CG ref:0:2:TCCA ref:0:2:CGCTCATGGTGCTGC 2 70 +CTCCTG ref:0:6:ATTGTTCACTTT ref:0:6:AAAT 4 3744 +CCTTCTCCCT ref:0:10:AACCTGTA ref:0:10:ACGGGAC 8 121485 +CCCGGTA ref:0:7:CGCACCCGCGGCT ref:0:7:GGCCCCGTCGG 5 2480 +GTGCAAGTGAG ref:0:11:GAACCA ref:0:11:TC 5 20 +TTTCCTCTAAGG ref:0:12:AGGTTCCGCGCACC ref:0:12:TGCCTGAG 5 398634 +ACGAGAAACAGT ref:0:12:GCATT ref:0:12:TG 8 120 +TAATCGCTTG ref:0:10:CGATGGG ref:0:10:GTCATCA 5 2520 +AA ref:0:1:CTGATGC ref:0:2:CAT 2 4 +TCCGAGGGTTGTAC ref:0:14:GACTCCGAGGGG ref:0:14:CACGACCTATTT 2 96 +ATA ref:0:3:CAGCC ref:0:3:CGAAGGAG 3 104 +GTGTATGCGGTGTC ref:0:14:ATGTTCGACGCAGAA ref:0:14:AAGCAACT 7 125600 +CCTCGTATA ref:0:9:TCACC ref:0:9:TTCTGAGATAAGTC 4 1856 +AATTTGGTCCAATC ref:0:14:CTG ref:0:14:CGCTTTGACCCCCAA 7 26600 +CCGATGCGTA ref:0:10:CTCTACCCAGG ref:0:10:GGTCAAAAAC 5 49500 +A ref:0:1:TCGATTAATGCA ref:0:1:GAAGCAAC 5 16 +CAAAGGATGCTTGG ref:0:14:AGACGTCA ref:1:13:TTCTGAT 7 44965 +CCTAACCGTGGCA ref:0:11:CTGATGCACTA ref:0:13:TAGCACCAATAG 6 504 +TAA ref:0:3:AAGTGATAGAATAGGG ref:0:2:CAACCAGTCTAT 5 32 +TAGAGCCGGTATC ref:0:13:GCTCAGAT ref:0:13:CC 7 18 +AAGGT ref:0:5:CTTGTATCGCCTGTA ref:0:5:G 1 18 +CTGATGTCGTTG ref:0:12:GACGGC ref:0:12:GGTC 5 1 +ACTCTT ref:0:6:TCTCAACGCTGTTGAG ref:0:6:CTG 2 380 +ATTGGACACCTTAC ref:1:13:TGGTACAGGAGTG ref:0:14:TGATCCCGAGTAG 7 19920 +GTCAGG ref:0:6:ATACGGCGCGATTCT ref:0:6:TAATTAGGACGCG 7 7527 +GCGG ref:0:4:TACTGAGTGTAAG ref:0:4:CTAGAGGG 5 392 +CGCGTTCCCGGCG ref:0:13:CTA ref:0:13:CACGCT 9 7412 +TTGCCGAGGTAGC ref:0:13:C ref:0:13:GT 10 12 +G ref:0:1:GGAGACGGTCGA ref:0:1:AGTCGAGTATAG 6 24 +CCTTGAGGT ref:0:9:TCCTAAACCTAGCCAA ref:0:9:ACCCTGATCC 4 175 +GGGGCAAAGTGTTGGT ref:0:16:AGAGTCCATGC ref:0:16:GTGATATG 10 4654000 +GGCT ref:0:4:AGGACGGTT ref:0:3:TTCTACCGGGCCGC 2 24 +AGTGAGGTTC ref:0:10:TAGGA ref:0:10:GTAAG 5 35 +TCGCATAGCTGGTGA ref:0:15:GTATTGCCTAAGGAT ref:0:13:GTACTGGTCTTA 4 360 +ACACTAAAGT ref:0:10:CAA ref:0:10:TAACAAGTCTT 3 81 +TCGTTTAATGG ref:0:10:CATGTGAGC ref:0:11:GCGTGGACCTTGTTAT 4 9638 +CTGAGGAAG ref:0:9:GTA ref:1:8:GTAGTGGA 4 480 +TCTGTAAGGTCAC ref:0:13:ATTGTCTCTGTCG ref:0:13:AGATGCCC 7 102680 +TAC ref:0:1:GTTT ref:0:2:G 1 9 +GTAAATAG ref:0:8:ATCCAT ref:0:7:TTTAACCGT 4 1280 +TGAGGACCCC ref:0:10:CTA ref:0:10:GCATGACAGCGCT 2 48 +CCCTCCACC ref:0:9:CTAGTATA ref:0:9:GGGA 7 43176 +ACCGGTTG ref:0:8:AAT ref:0:8:CACCGACGAAGCCC 2 78 +CGA ref:0:2:TGCGG ref:0:3:ACCGG 1 12 +CTATGTC ref:0:7:G ref:0:7:GACTTTTTCGCTAGA 2 142 +ACATAG ref:0:6:GGAGGC ref:0:5:GCCA 4 854 +T ref:0:1:AATTCGGCGGTCCA ref:0:1:GCACCG 4 21 +GATA ref:0:3:CTCC ref:0:4:CAATTGGCCCCAGGA 4 78 +AG ref:0:2:CGCGGA ref:0:2:TACACTACGACC 3 36 +CCAGACTGAATTGGGA ref:0:16:ATGTTATCTGCGTC ref:0:16:AGAATATGTTTAGC 8 898035 +TCACTGAACAGCA ref:2:11:CGTATCTCTTT ref:0:13:GTCTATAA 5 1680 +AGGGGCTTAGATG ref:0:13:GAGTT ref:0:12:CCGGTAAAAGACCAC 5 176204 +CCTCGTACACATA ref:0:13:G ref:0:13:GTGG 11 72 +T ref:0:1:AC ref:0:1:GCGATCTTACGCGAGT 2 12 +GCGAGGCCT ref:0:9:CAACCAAGGAGAGGC ref:0:9:CCGTATAAGCTTGC 5 43362 +CCGTTACACC ref:2:8:TGAGTATTAC ref:0:10:CATCAA 4 5920 +TA ref:0:2:TTACCT ref:0:2:GGAGCT 2 8 +CCGGTG ref:0:6:CA ref:0:6:TATTCTGTGCGG 2 1254 +TTTTA ref:0:5:AACACGTGAGG ref:0:5:TATAACGCAATAGG 8 1980 +ACCTAGA ref:0:7:TGAGGATTAGCT ref:0:7:GCGGGACATGTTTT 6 4095 +TTTGTC ref:0:5:GCAGCACAATT ref:0:6:TTGTTTTCTA 2 3960 +TTACTTACGGC ref:0:11:GGATCAGGCTGCGGA ref:0:11:GATACGGCTGTCT 3 1440 +CCCATCGGTGCATCT ref:0:15:ACGTATCCCG ref:0:15:TATGGCC 5 216 +GAGGGTTTTAAGTAG ref:0:15:GCCTAGC ref:0:14:TAACTTATC 9 2560392 +GATTGCATAAG ref:0:11:GA ref:0:11:CTTCCAAGGAAATT 5 6447 +GAGTCTGTTGAACAAA ref:0:16:ACTTGATACCAG ref:0:16:GCGGC 5 96 +TAGTTCGGT ref:0:8:CGTGCTCAAACA ref:0:9:ACCTTTCCAGTGCA 5 22308 +GCACCGCTGAGG ref:0:12:AATCTAGC ref:0:12:CACACATTTGAA 5 14280 +TTCGGGCCATCCTCA ref:0:15:CGGTACGTTGG ref:0:15:CCTCCCTTTGAA 8 361200 +TGAGGCCTTGCCCG ref:0:14:AAGAAATA ref:0:14:GTTCTCCCTGAAGTGT 7 1354245 +CTGTGTCACACG ref:0:12:ACTCACAA ref:0:12:A 6 24 +CGGAACCTCGCCACT ref:0:15:AACTCAGAATA ref:0:15:GCT 6 190 +GC ref:0:2:AGTGATTGCG ref:0:2:CCGGTAAGTCAGT 4 9 +AGA ref:2:1:CTTATGCG ref:0:3:CTTATCAAGTTGCCTG 5 50 +TTGAGGAAA ref:0:9:GGACTT ref:0:9:ACATCCTTGT 5 3150 +GGCATTTGGTGTA ref:0:13:AGTTGAAGCGTCATC ref:0:13:CAACTG 5 1950 +GCACGC ref:0:6:GATGAGGA ref:0:6:ACCTAATCTGGAG 5 5360 +GTGTATACT ref:0:9:TGCTGAGTTTT ref:1:8:GAGCCCCGAC 2 308 +ATAGGCACACCCT ref:0:13:AAAG ref:0:13:AAATTCAAAAGTA 8 107849 +AAACGAATCGG ref:0:11:ATGGCACTT ref:0:11:A 7 8360 +TGGCTAG ref:0:7:CGAAA ref:0:7:ATTC 4 728 +ATTTGCTCCTGTCCCT ref:0:16:AATGCCAGCCGC ref:0:16:CACGAGGCTG 8 127260 +AATAATCATA ref:0:10:ACTATGACCCGA ref:0:10:ATACAAT 3 6062 +TGAGC ref:0:5:AGTA ref:0:5:CAACATG 3 228 +CCACTTTGGCGAATG ref:0:15:AAT ref:0:15:GACTC 9 27 +TACCCGCAG ref:0:9:GGCAA ref:0:9:C 6 84 +ACGCTAATTTACTA ref:1:13:TATCCCTGAGTG ref:0:14:CATGGAGAGCAA 7 175584 +GACGCCATAGCAAACG ref:0:16:CCTCTGTCCTTTC ref:0:16:AGTGCCT 8 120 +CGACCGGTGAGCCGAC ref:0:16:TGA ref:0:16:GCAGCCAAGA 7 8 +TATGAGTCTGGC ref:0:12:ACTTGGGCA ref:0:12:ACCGACTGCCC 4 1485 +CCTG ref:0:4:TTACTCC ref:0:4:GATAGCTACATGAC 4 20 +AATGA ref:0:5:TAAAGCCCGG ref:0:5:GTGGAGTACG 4 2812 +ATACATC ref:0:6:CTCTGTGAGTACCTA ref:0:7:ACCGTGT 2 370 +AATCGCTCAA ref:0:10:GGAC ref:0:10:TGCGGCGAGTCACGG 5 670 +A ref:0:1:GATCAGCTAATTGGA ref:0:1:CTGCACGGACT 6 10 +GGCTT ref:0:5:TTGATCTC ref:0:5:AGGTAATG 1 27 +TTTTTGGTGGATTT ref:0:14:GGTAA ref:0:14:ATT 8 21 +T ref:0:1:AATGGACG ref:0:1:TTTGTA 2 4 +GCCTTTAGC ref:0:9:GGTACCAGCTATATG ref:0:9:CTCAACAC 3 8640 +A ref:0:1:C ref:0:1:GCGGGATCC 1 2 +AGATTTCGTACAATGC ref:0:16:GACAGA ref:0:16:GATATAG 9 2520 +GACGCACGCAT ref:0:11:CTGTTAACTCTCTA ref:0:11:AAACTC 6 9672 +CCCTTGTGCATATGT ref:0:15:GGCCGCC ref:0:15:CCATCAT 8 14388 +AATGGGCCCGGTATA ref:0:15:CGATGCCATTC ref:0:15:A 8 1680 +TACGG ref:0:5:GGGTAT ref:0:5:ATCCATGGATT 3 70 +TGGCT ref:2:3:TAGACGGTGGA ref:0:5:TCTACCCATATGC 3 161 +AGAAGTCC ref:0:8:CGTGTCT ref:0:8:GTC 4 72 +GT ref:1:1:CTCACTAG ref:0:2:CTGGGGTCAGTTT 3 38 +TTGTG ref:0:5:TGGA ref:0:5:ACAATG 2 94 +AACGCTGGGA ref:0:10:GCAAATAGATATA ref:0:10:ACGTTCTT 4 8172 +T ref:0:1:ACCTAGAGTAAC ref:0:1:CTCGATGTA 6 6 +TCAGAT ref:2:4:ATTCTTC ref:0:6:CTTCCGGAAATCC 3 2112 +TGTGGT ref:1:5:AATGG ref:0:6:CAGTGAGACGCGTC 2 90 +GTTGAACATACCT ref:0:13:TGCGTGTA ref:0:13:CTTTCG 7 350 +AGAC ref:0:4:TAGGCCT ref:1:3:CGCG 1 8 +GGAC ref:0:4:CTGAATTGTG ref:0:4:GTATCAATTTGAA 6 396 +GGCGAT ref:0:6:GA ref:0:6:C 3 3 +TTGC ref:0:4:GA ref:0:4:TATTAGGTT 1 42 +TAT ref:0:3:AGTG ref:0:3:TTGACA 1 9 +AAGCAC ref:2:4:TGC ref:0:6:CGTTCCAACGGGCCGA 1 18 +GAAAAA ref:0:6:CCCTAGGACTAT ref:0:6:TCT 6 39900 +TGCATAAAATTTGG ref:0:14:C ref:0:12:GTC 10 16 +AGATA ref:0:5:TCTTGCGCTTAATGC ref:0:4:TATTTCTAAAGA 5 988 +CTGCGAAGAAGTA ref:0:13:GT ref:0:13:AATAC 8 24 +CGCATGCTT ref:0:9:ACTCTCAC ref:0:9:ACC 6 572 +GTAAGGGGCTGTTGT ref:0:15:CAGGT ref:2:13:CTC 9 4046 +GCGGCCG ref:0:7:GTT ref:0:7:ACCGAGGCT 4 5400 +GCC ref:0:3:A ref:0:3:TTCCT 1 12 +ATA ref:0:3:CC ref:0:3:AGAT 1 40 +C ref:0:1:AGCGGATCGTA ref:0:1:GTGG 3 10 +CACAGCCCTCATGA ref:0:14:C ref:0:14:GATGATGGGACACT 8 8520 +ACCAC ref:0:5:AAGCATAT ref:0:5:GCA 3 255 +CCTT ref:0:4:GTTTCAGGTGCATGTA ref:0:4:AGTGGTGTTTAGTACA 8 367 +T ref:0:1:ACGGCGTACCCGATCC ref:0:1:TAAAACTCAC 5 4 +GAA ref:0:3:AACC ref:0:3:TCACATACTGAAGCGT 1 1 +ACGTGAGTG ref:1:8:TCCCA ref:0:8:TGTGCCTT 4 1102 +TCTAGGGGTCCAGT ref:0:14:CGGTGACGTAC ref:0:14:AG 7 480 +GCCCGCTGTGCT ref:0:12:TGTGCCCTGCCAAGTA ref:0:12:ATCTACGAAGT 7 248376 +TAGGG ref:0:5:CCTGAGGACAAAA ref:0:5:AAG 1 120 +AGCCA ref:0:5:TCGTGGTAACCTTTAT ref:0:5:GCGTTTAAATACGAGG 1 17 +ACGA ref:1:2:CCC ref:0:4:GATAAC 1 96 +CTAGTGAACCTGGC ref:1:13:GAGGCC ref:0:11:ATC 5 28 +TCAGCTTTAATGCT ref:0:14:GAGGCTTAGA ref:0:14:GGGCAATCGC 6 1890 +TTGAAGGCCTTCT ref:0:13:CTCCGCGAAATCGTGC ref:0:13:TTCAT 6 103056 +AATCACTGGCCATC ref:0:14:TAATGCT ref:0:14:AT 8 324 +ATTCGCCCAA ref:0:10:CATTCACACAGGCA ref:1:9:TAAAGCCTGA 3 3332 +CAGG ref:0:4:CCAACTGC ref:0:4:TATCTT 3 880 +CGGGACTGCGCATCC ref:0:15:GGCCTTCTACT ref:0:15:C 8 6564 +TGGAACGTTACGGCGT ref:0:16:AACTTATTGC ref:0:16:CGAGGCTGCACGGTGC 6 37710 +CG ref:0:1:AT ref:0:2:GAAGTCAACAGAGGCC 2 18 +CCA ref:0:3:AAAACGAAAG ref:0:3:AT 1 24 +GTGAGA ref:0:6:CTCG ref:0:6:C 5 56 +CGACTAATCGCATT ref:0:14:GCAATCCCTTTGCT ref:0:14:AGC 5 156 +CGGC ref:0:4:GATCCGACC ref:0:3:CGTCGGG 2 162 +T ref:0:1:GCAGAGCGTATAAC ref:0:0:ACCG 3 2 +TCCCGTGACAAGCGA ref:0:15:CTCACTTGTGAA ref:1:14:CGAAAAAGAGCGG 3 61236 +ATAGGC ref:0:6:TTTCGTCA ref:0:6:TGAGATTAATCTGTCG 5 3843 +TCCCACGATA ref:0:10:CGGGGGCGCCG ref:0:8:ACGTTAA 1 2 +CAAATGTT ref:0:8:GCATGTGGGTG ref:0:8:CTTCTGTCA 3 351 +GTCTACTATCA ref:0:11:AAGCCGTTAT ref:1:10:CCATCCCGC 4 78 +GTGGACCATCATTCA ref:0:15:CAC ref:0:14:AATATTAGAACCTCT 5 1764 +TAAATAGTT ref:0:9:AGGGACTCT ref:2:7:CACCACCGAG 3 764 +AAATTTCAAC ref:0:10:CTTAAAGG ref:0:9:GGTA 5 16652 +A ref:0:1:GTCCCGTAGCTTCT ref:0:1:TGCGGG 4 7 +GAAATAGATG ref:0:8:TTTCAAGGGGAA ref:0:10:CGCTTTCTATAAT 6 75996 +AAGAGAT ref:0:7:TGTTGTCC ref:0:6:CATG 4 162 +AACTCTC ref:0:7:GGCTATCAGC ref:0:7:TCT 2 78 +AGTGCTC ref:0:7:CGCCAG ref:0:7:TTCACC 4 252 +AAGTA ref:0:2:TT ref:0:5:AATTATACGGTGTACT 2 180 +CGCCAACTA ref:0:9:TAATGAAG ref:0:9:CAATGT 5 180 +TACGC ref:0:5:C ref:0:5:ATCCGCCGGAG 1 20 +GCCAC ref:0:3: ref:0:5:TG 2 1 +GGTTAGCGC ref:2:7:TAAGGACCCTA ref:0:9:CCTCTAGGAA 3 990 +TC ref:0:2:ACAAAGCCCGGCCC ref:0:2:G 2 195 +ATC ref:0:3:AACAAAGA ref:0:3:CCAA 3 24 +CCCAATTTT ref:0:9:CT ref:0:9:TATCACA 5 348 +CGTGATTTTACTGGC ref:0:15:GGCTGCCACCT ref:0:15:ATGGG 7 25785 +CAATCGA ref:0:7:ACACACCAACGGGG ref:0:7:CCCAC 4 3536 +TTGTACAAAGGTCG ref:0:14:GTCCTGGTACT ref:0:14:TAATGATT 7 23674 +CGGGTAAG ref:0:8:CACTGCCGCGAAACT ref:0:8:AATC 3 78 +AAATTAG ref:0:7:GCCGTAAAA ref:0:7:AC 3 20 +CGGACGAGGCCAGCAT ref:0:16:C ref:0:16:AAGACGGATACACG 8 18830 +CAACA ref:0:5:GCAATGATTTTC ref:0:5:GAAGGCGT 3 36 +ACATGG ref:0:6:TGAGTGT ref:0:6:ATACCCACC 2 2220 +ATACTGTGGTTGA ref:0:13:CGTAAAGTACA ref:0:13:C 7 55 +ACAGTCGTTCTCGC ref:0:14:ATT ref:0:14:ATTATCTCGA 6 48 +ATAG ref:1:1:C ref:0:4:GCTTGGAT 1 84 +CTCAGTCAGCGAA ref:0:13:TGAATGAGGATC ref:0:13:AGCAACTCACATTATG 5 3612 +CATGCG ref:0:6:ACCGCGTTC ref:0:6:GTGCGAGGC 2 91 +CTCT ref:0:4:A ref:0:4:GGTGC 2 15 +TGACATGGTCCA ref:0:12:GCCCCCTTAG ref:0:9:CA 6 90 +TATTGAGATC ref:0:10:CA ref:0:10:ACCACAAGAGGCAGT 5 3162 +TCCACGGTAA ref:0:10:TTAGAAAGG ref:0:10:ACGAGTACGGGAGA 4 3132 +AGAAATCGAC ref:0:10:TCGTGCCTAACCCTC ref:0:10:TAAGGTGCCAGCA 7 710208 +TGAGTG ref:0:6:GTTGC ref:0:6:GTAGCC 4 112 +GCAGGA ref:0:6:TCCTG ref:0:6:TC 5 66 +TGATCACAGCAATCT ref:0:15:CAATCGGACACCCCCA ref:0:15:GTTTGTGTGG 4 253460 +GAATGTTACTAAGA ref:0:14:CT ref:0:14:AGA 9 13 +G ref:0:1:CGAT ref:0:1:GTAGCAGTACCGG 2 5 +AT ref:0:2:ACGTGTCTATCTTGGT ref:0:2:TTTGTC 4 121 +CGTATAT ref:0:7:TTGTT ref:0:7:GCGCTCATTATGTT 2 138 +GGCGCAT ref:0:7:CAAAGTTTGCTCATAC ref:0:5:CGGTACCGCCTTGC 3 28 +TG ref:0:2:ACAGCCAGA ref:0:2:ACGATGAAGAGTGC 6 60 +TTACG ref:0:5:GAACTCAACCCCT ref:0:4: 1 210 +CACGATAGATTAAAA ref:0:15:ACAGGGAAA ref:1:14:AACGTGAGCGGGG 7 1680840 +GGCG ref:0:4:GC ref:0:4:GCGC 1 6 +TATGAAATATTTGGA ref:0:15:GCCAGGCAACGAACT ref:0:15:TCGGTGCCC 8 130176 +ACGCTGGT ref:0:8:CAGCCTCTCCA ref:0:8:G 3 45 +TGCTGCTT ref:0:8:TATATACTTCCCGGCG ref:0:8:AC 4 1638 +CGAATATAAT ref:0:10:AGCAGACATGGT ref:0:10:GATG 5 2610 +TTAACGGACGTTAA ref:0:14:AGGTCG ref:0:14:TCTGTA 6 368 +AGTTACATATTGAT ref:0:14:CCGCCCCCTG ref:1:13:ACACCACC 10 445068 +CGTTGGCCCGAGCA ref:0:14:ATCGAGC ref:0:14:C 8 105 +CGAAGATCTCGCATTG ref:0:16:AATATCCTTT ref:1:15:AATA 6 468 +TCACCACTCC ref:0:10:A ref:0:9:CTCTCG 4 40 +CAAAGTAT ref:0:8:TCTGAGAGTCGCGTCC ref:0:8:AGGGCCCATACTCGCT 5 10020 +TCC ref:0:3:AAGAGGCA ref:0:3:TTGGACGCCG 3 252 +CTGTTCCCGC ref:0:10:GCTATTTCGG ref:0:10:ATCCGACAC 3 10208 +GCTCAA ref:0:6:AAGGAAG ref:0:6:TGGA 4 100 +TAGAC ref:1:4:CCG ref:0:5:AGTATTTG 2 48 +CTTGG ref:0:5:ATAGAGTAAGCA ref:0:5:GAGCGGCTTG 2 148 +T ref:0:1:TTCATTGAAACGAA ref:0:1:AGTGACGGA 6 4 +GCCGAT ref:0:6:AATAGT ref:0:6:CTTGTG 4 332 +GTCGACT ref:0:7:AGGATTCTGGCC ref:1:6:CACATAAAGA 2 45 +AGTCTGGTTACCGTCA ref:0:16:ACCGGC ref:1:14:A 9 39 +CAA ref:1:2:TG ref:0:3:CCAGTGCGCACC 2 12 +GGCAATTCCAGACGCC ref:0:16:GACGCC ref:0:16:TCCCATCGTTTGCGA 7 990888 +CGAAAGAGATA ref:0:11:CCCCTT ref:1:10:GTGTTAAG 7 229646 +CTGTCGTGAA ref:0:10:G ref:0:10:AGAAGCGAGCGGCA 4 54 +TAAGGTAACATTG ref:0:13:TTTTTCCTATTGA ref:0:12:GATTCTGGCT 6 60876 +C ref:0:1:TCCGCTTTTAGTTTT ref:0:1:CAGTTGC 4 6 +GGTAGAACATA ref:0:10:TTTT ref:1:10:CGACGCCGCCA 3 8514 +TCTACGACAAGGAG ref:0:14:AGGTTGAGTC ref:0:14:TGCTT 8 69 +CAAATCTGACAC ref:0:12:AT ref:0:12:AAGGATTGAAATCCG 3 66 +CGCGGTCGTACAATTT ref:0:16:CTCGCATGAGCCG ref:0:16:AGA 10 62244 +AGGGGATATTAGT ref:0:13:CAGAA ref:0:13:CT 9 468 +TGATTATCGCCT ref:0:11:TATGCCAGAC ref:0:12:TATAGGAATATG 4 2877 +TGGGAACGATG ref:1:10:ACCCGCGAACTTCA ref:0:10:GCTTAACAAACC 4 63360 +GAATA ref:0:5:TCCG ref:0:5:CGCA 4 35 +GTATGCTGCTATCG ref:0:14:TGTC ref:0:14:ATATTTT 6 28 +GCATTTCGACT ref:0:11:ACCGTGTAAAGTCCG ref:0:11:ATGCTTAG 6 1512 +AAAGTCCCG ref:0:9:GCT ref:0:9:G 7 20 +AGCTGGCGTGGA ref:0:12:CCAACTGGGT ref:0:12:TGTCCATCTCTGATC 4 312 +TCGT ref:0:4:TCTAACGCCTAAA ref:0:4:ACTC 1 9 +CTTGGGTCTTACAAT ref:0:14:ATATTCTT ref:0:15:A 7 6 +TCGTACGTGCC ref:3:8:CGAG ref:2:9:ATTGCGTAG 5 28 +GCTATCGTTTTGC ref:1:12:TGAAAT ref:0:13:T 9 1038 +TTGAT ref:2:3:ACCCAGTTACTTT ref:2:3:GGCC 1 48 +AGGGTTG ref:0:7:C ref:0:7:TATCTCGATAGT 4 1328 +GATGC ref:0:5:TCTCGTCATTAGAAT ref:1:4:TGCCCGCAAAACT 3 56 +A ref:0:1:TTAGGGAGTAC ref:0:1:GGACGGTAGCAACGA 6 15 +CCCGTTAAGTACAT ref:0:14:TC ref:0:14:GGCACCTGCAAA 7 204 +AGGGGAACC ref:0:9:GGTAATGGAACGACA ref:0:9:A 1 3 +CGTTAAGCTAACC ref:0:13:TGGGCCGAGCAG ref:0:13:T 6 84 +AGAGACCCCGGACAG ref:0:15:GCCGTGAAATCAA ref:0:15:CCGCTGG 7 9612 +CTGCTAGTC ref:0:9:GCCTCATTTCGAC ref:0:9:ACCATCGGA 5 132 +ACTCTAACTGACTACG ref:0:16:CCAAGGTACGTAT ref:0:16:AG 7 216 +CGATCGGCAGAAG ref:0:13:GCGCGTAGTGTATCA ref:0:13:AGCGAT 5 210 +TCGT ref:0:4:CCTGAGATT ref:0:4:GTCCAATCGCTCA 2 80 +CCTGCACGT ref:0:9:CTGCTAGTAGCT ref:0:7:TGGGGC 3 528 +GATATCCGTCCCCTA ref:0:15:TAGAACACGAT ref:0:15:G 8 16 +ATTCG ref:0:5:AATCCACTGGCTTTAA ref:0:5:TC 1 128 +GCGTT ref:0:5:TTCAGTTCTACAAG ref:0:5:TCAAAAA 6 1080 +CGC ref:0:3:A ref:0:3:TGTAAAATTG 3 112 +CCCCAATAGTCATCAC ref:0:16:ATGCTC ref:0:16:AAGCCTCTGCCTTAT 7 1368 +ATCC ref:0:4:CGTGCGGCTCTGCCAC ref:0:4:GCTTGGGACA 6 7656 +GGGGT ref:0:5:ACCTTGTA ref:0:5:GTACTTTGCATT 6 12096 +TCATTTAACC ref:0:10:ACTAAAGCCTAGTC ref:0:10:AGACCTGCATTTCA 3 882 +GTACGC ref:1:3:AT ref:0:6:GGTCCCTCC 1 294 +ATCTGCGG ref:0:8:AGACATCCGTCTCCTC ref:1:7:CCTCCC 6 75972 +GCAGGG ref:0:6:ATCAT ref:0:4:AGCTAGTATT 2 12 +TAGCT ref:0:5:ATGTG ref:0:5:GTCATTTTAGGTA 2 36 +G ref:0:1:TAATGGACACG ref:0:1:TTCAACAA 5 27 +GGGT ref:0:4:AGTGAGGACTGG ref:1:3:TATTGGCCACCATTG 5 8 +A ref:0:1:TAATGGG ref:0:1:TGTGTACTCGAACGGT 5 6 +GCATCTTCCATTCGTA ref:0:14:CAACCAAC ref:0:16:TAGACCAGATG 6 1581 +AGA ref:1:2:GCCCCGGTGGCT ref:0:3:G 1 32 +CGCCTGTCTCCCGG ref:0:14:TCGC ref:0:14:AAGGCTAT 9 21840 +CCAGTGCGTCGTT ref:0:13:GGAAGCGGAATG ref:0:13:ACTTTAAGC 6 492 +A ref:0:1:TATCCGATCTTTTT ref:0:1:CGCG 3 10 +ATGACGATAC ref:1:9:CTGAGTAG ref:0:10:CACTTTCTAGCT 3 20 +TATGAAGTCAAAATC ref:0:14:AACCGA ref:0:15:ATTTAGAT 8 36540 +TTATTCTATTCTAAA ref:0:15:A ref:0:15:AATACATGTTTGCCTC 7 14330 +AATGGAGTTTATTTT ref:0:15:AGTCCCGCCGCA ref:0:15:CAGGCTATCACT 9 660852 +CACAGTGATCCGC ref:0:13:CGGTTGA ref:0:13:TATGACGAAAATTG 7 156208 +G ref:0:1:GTGTAGTG ref:0:1:CTCGTC 2 4 +TAACT ref:0:5:T ref:1:4:CC 3 10 +GAAT ref:0:4:GGCAAAGC ref:0:4:TGATTGAGAGAACTT 3 800 +TTGTTAAGCGTAA ref:0:11:C ref:0:13:AAATCTACACTCAAAT 5 144 +CCCGC ref:0:4:ACGCGGATCGA ref:0:5:TTATGTCTT 2 35 +AGCAGTGCTG ref:0:10:TGCGAAC ref:0:10:TT 5 25 +GGGTGCCTCGGG ref:0:12:TTTGAAATGAACGTCG ref:0:12:TGC 5 1620 +T ref:1:0:AG ref:0:1:GATCCGTTCGG 1 3 +AGATAGTGAGA ref:0:11:A ref:0:10:TCCACCCAAGGACT 4 60 +GACAATC ref:0:7:GCCCCGTGGACC ref:0:7:ACTAGG 4 9204 +ACAC ref:0:4:GAATCGAGTGCAAA ref:0:4:CTCATCTA 3 10 +TAGGGTGACTCAGA ref:0:14:ACTCTGTGGATA ref:0:14:CT 6 236 +GGCGAT ref:0:6:A ref:0:5:CGTAC 2 1 +AGGAAAATCGGGGCG ref:0:15:CGCTCCTAATGG ref:0:15:C 8 6800 +GGT ref:0:3:GTACACAGGACAGTCC ref:0:3:GGCG 2 30 +AACAT ref:0:5:CCCAAA ref:0:5:CGCGAAGGAA 4 12 +TGTACGCTGA ref:0:7:A ref:0:10:GGTAA 4 6 +TCCGGACAGTTA ref:1:11:AGAGATGAAATAGTC ref:0:12:GGTTAACA 6 37094 +AAACCGCAT ref:0:9:TTAATCCGCTC ref:0:9:GCCGAGGACTTCGGGA 1 324 +ATCG ref:0:2:AA ref:0:4:GACCGGGTGAACGCC 1 3 +TC ref:0:2:GTTTTCCATTACA ref:1:1:AGCGCCC 2 56 +GGTCCCCTCAGATAG ref:0:15:ATCG ref:0:15:AG 12 200 +GCCTAAA ref:0:7:CGGCCTTT ref:0:7:CAAAGTGCAC 1 330 +TTAGATGGTCG ref:0:9:GAATAGAA ref:0:11:GAGG 5 270 +CATATG ref:0:6:TCTACCTCACGA ref:0:6:GTTCCAA 2 6 +AAAT ref:0:4:CGGATACACAAAG ref:0:4:TGTTCGCCGAG 6 9800 +TTAATTATAT ref:0:10:AC ref:0:10:GGCCGTTGTTCGTAGA 4 1344 +CTCGCAAGC ref:0:9:TACAGTCG ref:0:8:CA 4 60 +GCTACTAT ref:0:8:TAAC ref:0:8:C 5 8 +CTCAGAGCGAACT ref:0:13:ACGTGTATGTCTA ref:0:13:GGCAGGCTCCC 6 9240 +AACGTTGCGAGAGG ref:0:14:CTCGTCATGC ref:0:14:GGCAA 6 415 +GTCGGTA ref:0:6: ref:0:7:TCCAAGAGGAA 2 22 +GCTCG ref:0:5:A ref:0:5:CCGCGTC 1 6 +CA ref:0:2:GTTCTGAG ref:1:1:AGAGTTTCT 2 2 +GGGGCGTCAG ref:0:9:AAATCC ref:0:10:CGTAGACG 5 1932 +TGTTACAAAAGCT ref:0:12:A ref:1:12:GAGCCTTGATT 7 4615 +GTCCACTCCACGA ref:0:13:CCGGCGCACTTGTT ref:0:13:TATA 4 294 +CCAACACTAGACAATT ref:0:16:GGCTACTGGATG ref:0:16:CTT 9 32760 +T ref:0:1:CGCAAGG ref:1:0:CGGA 3 8 +CTGGTCG ref:0:7:CGACATT ref:0:7:AAACGGCCAAA 4 559 +TAATGAAA ref:0:8:CGATGGGGTGAA ref:1:7:AGCCAT 2 11718 +CCGTCGCTCTGTCCA ref:0:15:GCTT ref:0:14:TCGTTAGGGG 7 385 +ACTGGGAGGGGCGA ref:0:14:AGTG ref:1:13:T 11 146 +CTTAAGGTCCGC ref:0:12:CCA ref:0:12:TGGTAATTA 6 660 +CTTTAGTAAGA ref:0:11:ACCTG ref:0:11:AT 8 28 +ACCAG ref:0:5:TAGTGTGGTG ref:0:5:TTACCACCCTATACC 3 27588 +GA ref:0:2:ACCGGAG ref:0:2:TCTGCAACATA 1 8 +CTC ref:0:3:A ref:0:3:AGACCTTAACATGGCC 1 72 +CCTGTAGTG ref:0:9:CTGAGCACGGAGCCG ref:2:7:GCACGGTTA 5 10736 +GTCTGTGAATCGAG ref:0:14:TCGC ref:0:13:ATATTCCG 6 376 +TATGAACCG ref:0:9:TGATCTAT ref:0:9:ACGC 4 2210 +GCGCTCTCT ref:0:9:ATGTCGGTAGTATAA ref:0:9:GTGCTG 4 792 +ACGTTCCCCGTCTG ref:0:14:AATTGAGCC ref:0:14:GAAG 10 77552 +C ref:0:1:GGTATA ref:0:1:ACAGCGCCAGC 3 35 +CGGAC ref:0:5:ACGTGA ref:0:5:GT 2 7 +AATC ref:0:4:TCGTGGGTCACGC ref:0:3: 2 189 +TTTTTG ref:0:6:TC ref:0:5:GCAT 4 1400 +AT ref:0:2:TGTTCC ref:0:2:CCTGACTCTGA 3 16 +GGATCCGTTCCCTT ref:0:14:CACTCACAAA ref:0:14:AGTCATA 9 29400 +AGATGATCG ref:0:9:GGCGTGCAACTTGC ref:0:9:CA 4 2184 +ATGGTGCCGGCAAA ref:0:14:GTGGCTAGCGAGCG ref:0:14:GGCCTTA 4 3168 +T ref:0:1:GTTGTTTCCGATC ref:0:1:TGCTAATC 5 18 +GGTCTTATTTC ref:0:11:TG ref:0:11:CTGTATGAGTT 5 34 +AGTAGTCCCAT ref:0:11:TTTGAACTTGTC ref:0:11:TTAATTCTCGTTAA 7 344472 +CA ref:0:2:G ref:0:2:GTGTCGAATAAGCTCT 1 12 +ACACCTA ref:0:6:GGACGTTC ref:0:6:CAGCTATGGCTCTTG 2 168 +AGTTT ref:0:5:CCTC ref:0:5:TGTCGG 4 1961 +CGCAAA ref:0:6:CCTCCC ref:1:5:CACTTTC 5 3612 +CCCACTTTCATGA ref:0:13:TCGCTTTA ref:0:13:TACTGCG 5 2520 +G ref:0:0:TCAC ref:0:1:GCGAATGCTTTGTT 3 4 +GT ref:0:2:GCGCGAG ref:0:2:C 2 48 +CTATCTAGTACCAAC ref:0:15:CA ref:0:15:AC 12 156 +TGTAACGTTTTGC ref:0:13:GG ref:0:13:GACCAAAGAATGG 7 6300 +ATGGAGAAATTC ref:0:12:GCCCC ref:0:12:CCTGATCCAC 9 275772 +AGCATCACCG ref:0:10:AATCGCCATCC ref:0:10:GCCTAGA 2 68 +AACTGAAGCTAGTT ref:0:14:AGTAACTTA ref:0:14:GGGGGTTC 5 3822 +A ref:0:1:TCCACCATTGACT ref:0:1:TATGGCGTTCA 5 6 +TCTGCACCCTG ref:0:11:CAGCGGAGTCAAA ref:0:11:CCTCAGGTTGGTA 6 63360 +C ref:0:1:CGAAAGGCTGGCACAA ref:0:1:AGGA 4 20 +GATGTCTCACA ref:0:11:CA ref:1:10:CGTTG 5 75 +GTTGATCAAAGTCA ref:0:14:TTGGATGACACCGAT ref:0:14:TGATCACGTTG 6 23112 +AACGAAGAGATGT ref:0:13:TAGCGTGA ref:0:13:ACAT 7 3168 +GTCC ref:0:4:AAGAAGAACGGGAGTC ref:0:4:ATCACGTGGTCTT 6 525 +TTTAGATAGCAGGT ref:0:13:TCAGAGAATATC ref:0:14:GCCGGTACCC 4 1200 +TATTAAAA ref:0:8:TA ref:0:8:AGAAAT 3 221 +GTCGTGAGC ref:0:9:AACCGGGGACG ref:0:8:GAGCTTTCAGCGATA 4 28446 +GGTCTCTGGTTACCTG ref:2:14:CCAAC ref:0:16:CACGGT 7 90 +AGCTCC ref:0:6:GA ref:0:6:T 4 6 +CGCTGTCTGGC ref:0:10:GCGGCG ref:0:11:GGA 5 209 +TTTACTACT ref:0:9:GCAAGGTTGGTAGT ref:0:9:CTACTCGGAAAG 4 19625 +GCGC ref:0:4:CGTGATGCA ref:0:4:CGTATAGGTT 5 741 +TCTCA ref:0:4:CCG ref:0:5:ATATCCACAA 1 42 +AAGACGATGGAAGA ref:0:14:TTCCCGGTCACTC ref:0:14:TAGAATGTG 7 2158200 +T ref:0:1:CGGGGTGTATAGGTT ref:0:1:TATGCCCAT 4 15 +GAGTTG ref:0:6:CATACATTGCTCTCTC ref:1:5:CTACCGTAACGA 4 640 +CGTCCC ref:0:6:C ref:0:6:TGC 4 48 +AAT ref:0:3:TTGCACGCAATCTC ref:0:3:TGTA 2 72 +CCCCGA ref:0:6:GCT ref:0:6:T 6 301 +CACTCACAATTCGG ref:0:14:GGGAAGTTCCACCAAA ref:0:14:AATATTAGACT 7 622596 +AAGAGCATGGC ref:0:11:AGCCGGGCGTTACA ref:0:11:CTAGCTTGTGAGAAT 7 1956375 +CTGCGCTACTGCGA ref:2:12:CGCGCCCTT ref:0:14:A 5 78 +TGAAGAACC ref:0:9:CTCCACGTCGCTG ref:0:9:TACAGTTGAGCAA 5 2484 +G ref:0:1:TTGCGT ref:0:1:GGCGCTGAGCTT 3 10 +GAGTGGGAGG ref:0:10:ACACAAATCGGCGC ref:0:10:GG 5 48216 +CAAATTCCTAG ref:0:11:TC ref:1:10:ATTAAACCCAGAG 3 828 +AATACGGGCAGTG ref:0:13:GCAAA ref:0:13:CCTATGTGCTCATAA 8 27846 +A ref:0:1:CTGCAACCCCG ref:0:1:TGTGGGACCAAC 5 6 +TGTTATCGTCTCCAG ref:0:15:C ref:0:15:ACCGCA 10 64 +CGGGGGCATACCC ref:0:13:TAAAACTCTAGG ref:0:13:TA 9 2374 +CTC ref:0:3:GCTAAGGGCC ref:0:3:AGG 3 40 +TCA ref:0:3:GATCAGTATG ref:0:3:ATAGCAC 1 2 +TCA ref:0:3:GAGGGCGCG ref:0:3:CTTACTTATAACCTAC 2 774 +ATCTTAG ref:0:7:CC ref:0:7:GGAGTGGGGTAGACT 2 184 +TACTGC ref:1:5:AAGAAGTGATACGG ref:1:5:CTGCAC 1 32 +ACCCGCGCATGCC ref:1:12:AT ref:0:13:GTCCAC 6 2 +GCGTGGGGGCGTGCT ref:0:15:C ref:0:15:GT 12 57 +CGG ref:0:3:TCATAGCTGT ref:0:3:CAGCGGT 3 4 +AATACTCTATGAA ref:0:13:TCCGTCGAACG ref:0:13:GTGCGCACCT 5 162 +ACACTAA ref:1:6:TGGGCAATGACATA ref:0:7:CGAGGTGAGCAC 3 54 +CACAGTTGCATT ref:0:12:GATCGCAGGACG ref:0:12:TATAATCCGAATA 5 114720 +ATA ref:0:3:TTCTCACCTTTTCGT ref:0:3:CTCGATCACGAAACA 5 150 +TATCCGATTTTTCGT ref:3:11:GTGTCTCGCAC ref:0:15:CT 5 273 +GTAGATTTCCT ref:0:11:ATATG ref:0:11:CTAAA 7 3120 +ATTAATTTAGCTA ref:0:13:TGGTGT ref:0:13:AGTAGCGTCAG 6 3486 +GTACAAGGATCCG ref:0:13:C ref:0:13:ATCAGCT 8 270 +AAACA ref:0:5:ATACAACAG ref:0:5:AGGTTAGCGGTTAGAA 3 128 +CCTTTTCTAGGCT ref:0:11:ATC ref:0:13:CATCGTATCAG 5 1368 +GGAAGATTGTGC ref:0:12:GCAAGAGGGCCGT ref:0:12:TACCCCCG 6 442440 +TATT ref:0:4:CCCAGCAACGCA ref:0:4:GATGACCAAAA 7 31212 +CTAGGCT ref:0:7:A ref:0:7:C 5 2 +CCCTGGATGAA ref:0:11:CATGTGT ref:0:11:GACGAAGTGA 4 5208 +TGCGGAAGATG ref:1:10:GAACGACTGGGAC ref:1:10:GTGACCCCGTTAC 5 4212 +GGATGTCCTA ref:0:10:GCGA ref:0:10:AATGAA 5 576 +G ref:0:1:ACAATTCGT ref:0:1:CTACAGGATA 4 2 +CGTTACCACGCCGGG ref:0:15:AACCTAGTCGCAGCGA ref:0:15:T 6 720 +ACTTCGAGAATG ref:0:12:CGACCAAACAT ref:0:12:CTCCAGTAGATGGG 2 306 +CT ref:0:2:CAGCACTCAC ref:0:2:TACTTAGAACTCTGA 6 21 +GCAAA ref:0:5:TTCCCACGTGCTA ref:0:5:CATG 4 1300 +AATATGTAGAG ref:0:11:ATGGATTACACAGG ref:0:10:CACGGGTCAAGCCAC 5 12350 +GCATCTTCACCTATTA ref:1:14:TGTACCCA ref:1:15:TGTTT 7 1376 +ATA ref:0:3:GT ref:0:3:GGCTTAGGTAGAAGTA 1 16 +GTAACGCTGTCATGC ref:0:15:ATCCC ref:0:15:TTTGTATGAT 6 1508 +TTGAA ref:0:5:TGAAGGACGGCTCATA ref:0:5:CCA 3 1850 +CGGCTGTTAGA ref:0:11:CCAGGGGTAAC ref:0:11:TCGTACCTC 5 17472 +GGTGTTGTAAACCCGT ref:0:16:C ref:0:16:A 14 9 +TGTCTTCATCC ref:0:11:C ref:0:11:ACGAGATTTATTGC 4 224 +GGCAGCGTGTGGGTA ref:0:15:ATCTACG ref:0:15:AGATTC 11 12160 +CACTGACGT ref:0:9:AACAATGCCGCAC ref:0:9:GCTCA 4 2070 +A ref:0:1:TTAATGCGGCGTTA ref:0:1:GAC 1 3 +TACCAGCGAAACA ref:0:13:GCGGCC ref:0:13:GCTCTGACTGGG 8 141210 +GCGCG ref:0:5:CC ref:0:5:AGCATTT 2 55 +CGCCATGTCGCGTCGC ref:0:16:AGTCA ref:0:16:AATTG 10 960 +AGAAAGCTCGCT ref:0:12:AAA ref:0:12:GACGGGC 5 320 +TTGTGAA ref:0:7:AACCT ref:0:7:CTTCGGGC 2 15 +A ref:0:1:C ref:0:1:GCAACT 1 4 +GCTTGATGTATGTAAT ref:0:16:CTTTTG ref:0:16:GGCATCAGAGGCAA 4 695 +CGATTGGCTTCATT ref:0:14:AGCT ref:0:14:TGCCC 8 408 +A ref:0:1:GTGTCAGTTGGCC ref:0:1:GGGCTCGTATCTAAC 7 3 +TA ref:0:2:GTAGATGTGTCCGAC ref:2:0:CTTG 3 6 +GCGAG ref:0:5:TATCAGTC ref:0:5:TCGAGAGTTGACACC 4 72 +TTACGCGG ref:0:8:GG ref:0:8:CGTCGATC 4 27 +GTGCTAAAG ref:0:9:CA ref:0:9:CTTACCTCGAA 4 447 +ATGAAATCTG ref:0:10:CAGATATCTGAC ref:0:10:GATACGGC 4 120 +CGTTGGCG ref:0:8:TGACTACGGAGA ref:2:6:T 2 68 +ACC ref:0:3:TGCATGTATATTGCAT ref:3:0:GGTTAAATGTTG 2 32 +GGTAAATGT ref:0:9:TAAAGA ref:0:9:AAC 4 26 +CTCGCAAGCG ref:0:10:TCCCAG ref:1:9:TTC 4 322 +AGCTA ref:0:5:T ref:0:5:CCTT 3 12 +CTCCCTCGGCAATC ref:1:13:GTACCG ref:0:14:AG 10 480 +TCGGC ref:0:3:TTTTCCAAGCCT ref:0:5:CCTCCTC 2 80 +GTCGG ref:0:5:TATCGGTGTA ref:0:5:GGACACTATAA 4 5652 +AGTCCACCC ref:0:9:TCGATC ref:0:9:GAGGAA 4 612 +TAAGGCCATGTA ref:1:11:CCACTACCA ref:0:12:GAAGG 4 114 +AAAGAACACTGTGA ref:0:14:CGAGAC ref:0:14:ACCTATCTGTAT 6 2484 +CTT ref:0:3:AACGCATGAC ref:0:3:TGGAC 4 98 +GTTACGGAGCCC ref:0:12:TTGGTTA ref:0:12:TGAGTTAAATCCTG 3 146 +CTACCACGCTAA ref:0:12:AGCCT ref:0:12:TTTGACGATTTAG 5 53888 +GAGAGACAAACACTAC ref:0:16:GTCTCTATATGCG ref:0:16:CGTGTGGTCAACA 6 20736 +ACTCTGG ref:0:7:CGGACCTGGGTACGG ref:0:7:GGCAAAAAAAGTCATT 3 3657 +ATCACTGGTCTTATT ref:0:15:CAGCCGTGTC ref:0:15:AACCTTGCGAGTGTG 5 1313 +AGAGTAACGGCCTC ref:0:14:TG ref:0:14:CGCCGAA 9 60 +GCGTTTTACGCCGAAC ref:0:15:TTGG ref:0:16:ACGT 9 162 +T ref:0:1:CCATATGCG ref:0:1:C 1 4 +GACTTAGCATAGA ref:0:13:CATCCAGAGGCC ref:0:13:CACTAACCCCC 8 1049 +CTGTT ref:0:5:TGGCT ref:0:5:GAG 3 84 +TTCGATAGTACGTTT ref:0:15:GGATCGAGAA ref:0:15:CCTG 8 6440 +TTTGCGA ref:0:6:AT ref:0:7:TC 4 18 +TTCGACGTACTCT ref:0:13:AA ref:0:13:ACAAATGGACA 8 1450 +TGGTTATTACATGC ref:0:14:TCTCGCTA ref:1:13:GCGGCGCCT 9 702 +CGAGGGG ref:1:6:T ref:1:6:ATGAACCGGCGA 2 126 +AAAATCAGATCC ref:0:12:AAGTCCCGTTATAT ref:0:12:TCTG 5 2700 +A ref:0:1:CCTGCCAG ref:0:1:TGATACTGACCCCCCT 3 3 +CGAGCG ref:0:6:GGCTT ref:0:6:CTATATCGTTGACATC 3 540 +GTTTTCGGT ref:0:9:A ref:1:8:CATCAA 7 2030 +GAT ref:0:3:AAGCGTGATCGTCT ref:0:3:TTCTGATTGGCTCAG 5 27 +TAGGACCC ref:0:8:ACTGTCTGT ref:0:8:CACTATTTCA 8 147412 +CAAATTG ref:0:7:TGAATA ref:0:7:ACGAGACAGTGATTGG 2 756 +TCGCGTCGAGCGAA ref:0:14:A ref:1:13:GACCAAAACTCGCG 6 216 +AAAG ref:0:4:AGTCG ref:1:3:GGGAGCTTATGATC 2 18 +AAGCGCCGCCCTTA ref:0:14:ACGCTAACA ref:0:14:GG 7 1584 +CAGGCGG ref:0:7:TACAATCTTATGCTAT ref:1:6:GGATCTCGTACGCC 6 640 +A ref:0:1:GGTTTTGT ref:0:1:GCCG 3 45 +A ref:0:1:TCGACGTGTGGTCAG ref:0:1:TGCT 4 10 +CCGGT ref:0:4:GGGAA ref:0:5:AGTGATTTAGTACT 4 205 +TGCCCAGCACATA ref:0:13:CATAACTACTGTGAT ref:0:13:GACTCACA 6 31486 +G ref:0:1:CTACTGAT ref:0:1:AATCTATTGT 5 1 +TATTGTATAACC ref:0:12:GGCGCAAGAGTA ref:0:12:CGCAG 10 12000 +AGGC ref:0:4:GTGTAACGTCGGCTT ref:0:4:TGAGGGG 3 60 +TCAGCGCT ref:0:7:AACTAATTCAG ref:0:8:CCCGGG 3 4810 +C ref:0:1:CGTAACTGTTTAGT ref:0:1:CATC 2 4 +TCGACCGGC ref:0:9:GCCGAGTGTTTGGAA ref:0:9:AACAG 4 36995 +AGGAG ref:0:5:T ref:0:5:CCGGCGCTCAA 3 216 +TAATAGTCCAGAG ref:0:13:GTAAAAGTT ref:0:13:AGCA 5 612 +CTGA ref:0:4:GTGTGT ref:0:3:CCAGTCTCCCGGTTG 3 540 +ACGATATTAAGCTCCT ref:0:16:CATTCGG ref:0:16:CACCTTTT 9 8151 +AGAG ref:0:4:TAAACGTTC ref:0:4:GACGAAACCCACCCA 3 148 +ATTTTCT ref:0:7:CTCTTGTTGGG ref:0:7:TTTA 2 38 +CTTAGG ref:3:3:GCGAATGAA ref:0:6:ATCGCCGT 3 224 +AAGGCACCAAT ref:0:11:TA ref:0:11:CCGGGGTAGGG 9 512285 +ATAGAGGGCCA ref:0:11:TCAAGC ref:0:11:AGCGTCAT 4 810 +GCATCGTCCTT ref:0:11:CTTACTAGCTGAGTG ref:0:11:CCGGGGGCAGT 6 8410 +CTGTGTGCGCG ref:0:11:CCTATCA ref:0:11:GA 7 3000 +ATCGAG ref:0:6:CCCTTCCAGCGA ref:0:6:CCAGGGACGTACA 5 6576 +TAAGATCGGGTACACC ref:1:15:AT ref:0:16:CAGGCC 9 882 +TCTTT ref:0:5:CAGAC ref:0:5:ATG 5 1080 +CTAATCTCTACCCGGA ref:0:16:GCGCTCA ref:0:16:C 11 582 +CTTATACGCAATCA ref:0:14:AGTAAATGATTAC ref:1:13:AACAT 5 7216 +ATCGTGTAATCAG ref:0:13:G ref:0:13:GCTCT 10 390 +TTAAATGTA ref:0:9:ACT ref:0:9:AGAATATTG 4 918 +GGCCCCCG ref:0:8:CGCA ref:0:8:GGTGC 5 6120 +GACGGCAAA ref:0:9:C ref:0:9:ACTCTGCTGTACC 4 568 +GTGG ref:0:4:AAACTGCTCACCTA ref:0:4:CAAGCTCCC 8 810 +ATTGG ref:0:5:GACA ref:0:5:CCGT 4 1029 +TCGAAGTGAAAAA ref:1:12:GCGACGGTTT ref:0:13:GAGGCCGG 8 160440 +AGCACGTGTC ref:0:10:TTGA ref:0:10:AAACCC 5 1230 +CCGAA ref:0:5:CA ref:0:5:GTTTCAACCGGGTTTA 1 216 +TAGGC ref:0:5:CTCTTG ref:0:4:GTCTAGGAGGAT 2 308 +TTGGGACGATGATC ref:0:14:GACTG ref:0:14:CATGCCA 7 15 +CTAC ref:0:4:GTATT ref:0:3:ATTGCCGGGTTTAGA 1 72 +GTCACTT ref:0:7:AGGCCCGCTTCACC ref:0:7:CAA 2 395 +GAACGGTC ref:0:8:CTA ref:0:8:A 5 4 +GCGCAGAGC ref:0:9:A ref:0:9:GGATGT 5 32 +GACTGGCTGATAG ref:0:13:CAAA ref:0:13:TA 9 100 +CAT ref:0:3:TTAGATTAGAAAAGCT ref:0:3:TATACACAAC 7 1343 +GCTTCACAC ref:0:9:TCATCACTATCCA ref:0:9:TT 2 14 +TTAAGTAAGAGGTGTC ref:0:16:CGAAGAGACTGG ref:5:11:CTCTGGG 6 10693 +GGTCAC ref:0:6:A ref:0:5:CTC 2 3 +TTTAGCA ref:0:7:CG ref:0:7:CTCCCCTACGCTC 3 224 +ATGCCGGA ref:0:8:AAAGACTTG ref:0:8:CC 3 102 +CGTCGGAAA ref:0:9:GCTTTTCGAACAC ref:0:9:ACATCATGAGG 2 2968 +GTGCGACCGCTC ref:1:11:ATGGACAATTTGGCA ref:0:12:GACGTTAGG 6 18338 +TCAAATCCC ref:0:9:CTCGCTGCCAGG ref:1:8:T 4 86 +CTAGCGCACAGCAGG ref:0:15:C ref:0:15:CATCATGCTCTTG 8 14255 +AT ref:1:1:GTCACA ref:0:2:GCGGAGACCCTT 1 4 +CCC ref:0:3:GGCACG ref:0:3:CCACTAACC 1 70 +GG ref:0:2:AATCTAAAAGCC ref:0:2:TTATGTAACAATTCCA 9 221 +TCTTCCTACATACC ref:0:14:TGGC ref:0:14:CGCGTACTACGCACT 6 18546 +GAGAGCTCTATCCC ref:0:14:CTGTCC ref:0:14:CACGC 8 240 +CAGCTGACCAGGTGT ref:0:15:TTGCAACCATCAC ref:0:15:CCAGTCAGCGCG 4 3256 +CTGTAAGTT ref:0:9:TG ref:0:9:GCCGCAA 4 18 +AATCGGAACGTCAA ref:0:14:GAC ref:0:14:AT 10 48 +GTAGGGTCCTAAA ref:0:13:ATGCACCGG ref:1:12:TTCGTTCGTGC 8 6408450 +GGCAACCCAT ref:0:10:C ref:0:9:ACGGTGGGAG 6 2756 +CGGAAGGACATA ref:0:12:CATT ref:0:12:G 8 112 +GTCTCG ref:0:6:TGATAC ref:0:5:TGGGC 3 330 +A ref:0:1:GTTGGGTTGTAACT ref:0:1:TCCCATCGCACG 4 4 +G ref:0:1:TTC ref:0:1:CAGGCAACTCCCAACG 2 12 +CAGAGGAGCGAGGAC ref:1:13:ACAG ref:0:15:GTTTCATAA 8 9144 +GCGTACTACGA ref:0:11:ATGTCACTC ref:0:11:CGACCTG 3 24 +GTTGGCAGATCGTAGA ref:0:14:TATGATG ref:0:16:CA 7 42 +CCAT ref:0:4:GTTTCTCGGATACA ref:0:4:GCTCAACTAC 4 2 +CTAG ref:0:4:ACATAACACGGGCATC ref:0:4:GTTT 1 234 +GTGTAG ref:0:6:TAAGCAA ref:0:6:ATTTAAGCTGT 4 598 +C ref:0:1:GGTTTCGGATTGT ref:0:1:GAGCCAG 4 2 +CCA ref:0:3:GTCGGCCTATCCG ref:0:3:TAATGAAA 3 282 +AGGAG ref:0:5:GGCTGCCTCGGGGG ref:1:4:CCGCCTTG 5 14694 +GAGTGAGAAGTAT ref:0:13:CCCCTTAG ref:0:13:GGCAGTACCGGG 7 13482 +TGCGAGACTCAT ref:1:11:G ref:0:12:ACACGTCGATC 4 33 +CATACG ref:0:6:TAATGGTGGCGTCATA ref:0:6:ACCA 4 1275 +GCCC ref:0:4:GCTACCAGCCC ref:0:4:TTCA 2 651 +CTAGGA ref:0:5:TGATGT ref:0:6:ACTTGCCCCC 2 435 +T ref:0:1:CTATGAACAATA ref:0:1:ACTGCAA 5 3 +AGAGGGGG ref:0:8:AGCTCCGTCCC ref:0:8:CTGA 4 7344 +TCGTTC ref:2:4:ATAA ref:0:6:AGCCTATGAGAG 5 1638 +AGGCC ref:0:4:TTGTCGAATGCATT ref:1:4: 1 19 +TAA ref:0:3:GTCGGGGA ref:1:2:CAACCAATTGCTC 1 42 +GAAGTCTCGCACGAGT ref:0:16:TAATC ref:0:16:ACT 11 176 +GCGGCCTG ref:0:8:GAT ref:0:8:AAC 6 507 +GGTTCCATCGCT ref:0:12:CGCTCCTGTATA ref:0:12:A 4 44 +GAC ref:0:3:TATCGAAT ref:0:3:AACTC 2 42 +GCTAGTCTTCATCTGC ref:0:16:CTG ref:0:16:CTGACTCATCACT 6 588 +AAGGGTG ref:0:6:TC ref:0:7:CT 5 6 +TGCACGGACCCT ref:0:12:GAGGGAGACCTTC ref:0:11:AAGAAACTATGC 6 185472 +GCCGTCCAG ref:0:9:GGACCATTCTGGA ref:0:9:GCG 3 1744 +G ref:0:1:CAACTTTCAT ref:0:1:GTGTTTCATAGTGT 6 44 +GTGCTACTAC ref:0:10:AGGGCCTTCTTCACG ref:0:9:GCCGAGA 2 3024 +G ref:0:1:GCATACGACATGTAAT ref:0:1:AACCGATTGCCTCG 7 9 +CATGGGG ref:0:7:GTCCCAGTGATAGG ref:0:7:ACATATTCTACCTTT 4 102936 +CAAACGCAC ref:0:9:AGCCCGA ref:0:9:TTGTTGC 5 68355 +GCCCTTGAAG ref:0:10:GTTCAAGCCCCAGGC ref:0:10:TCATCTAGGCATT 7 512230 +AAGGCCAATCCAATC ref:0:15:ATACAGGATGCTGTGG ref:0:15:TCTCC 7 24624 +GCGCCAATGAGGC ref:0:13:CGAGTAA ref:0:13:AGAAA 8 116 +TGAACGAGAGGCATCT ref:0:16:AGAAATGC ref:0:16:GGCGAAT 7 88 +TAATTGTAC ref:1:8:CAAAGGGCACCT ref:0:9:TATAATCTAGA 2 800 +GGAGATTGTTAG ref:0:11:GTTCTCTCC ref:0:12:ACT 6 576 +ATGTC ref:0:5:CTATAA ref:0:5:CGGGCGCC 2 6275 +CACGGTCACCCCAGGA ref:0:16:TGCGAGGGC ref:0:16:CCAC 9 23928 +ATCT ref:0:4:CCCCCAAATTGAAG ref:0:4:CCCAAC 4 9 +TAAAAGTG ref:1:7:CACGCTAGAAC ref:0:8:AGGAT 4 792 +G ref:0:1:CGCCAGGTAGCA ref:0:1:CTCAAACTTAAATCTC 6 68 +TACGAAGCAGCCACG ref:2:13:AACAGGTCA ref:0:15:G 6 28 +TAGAACT ref:1:6:CCATTCTCG ref:0:7:ACTGTTTGTGCC 5 25840 +TAGATGAGCGAC ref:0:12:CCTTTCCGGG ref:1:11:TGCCA 5 60 +CCTTGGA ref:2:4:TC ref:0:6:TCTG 2 98 +TTGTTAGGTAATA ref:0:13:T ref:0:13:ATACCAGAAGT 7 1512 +GGGCCTAG ref:0:8:AGTAGG ref:0:8:TCGAAAGTGGCGC 2 156 +GGTGTCTAAATT ref:0:12:TAATC ref:0:12:AACGGGCTG 4 243 +ACGGGCTCCTCGCATA ref:0:16:TCCTTTCATC ref:0:16:GACTAT 8 3330 +CGCTTTT ref:2:5: ref:0:7:GGCC 4 19 +TTCGGACTTACGCG ref:0:14:TGCGGATGT ref:0:14:G 7 108 +AAACCGGACCAC ref:0:12:ACTTCAAGTACT ref:0:12:TCCGGACTCTACAG 3 1164 +TGTTTGCGTGGAG ref:0:13:AGGCCCCTGTTACC ref:0:13:GCTGTGGGGGGAA 3 284592 +TCAGTTTCTT ref:0:10:AAACCGCTTCGA ref:0:10:GCGACTTTCGCTTGGC 4 6900 +AAC ref:0:3:GGTGGATCACAAGAC ref:3:0:AT 1 11 +C ref:0:1:AGTAACCGATCA ref:0:1:TCTGAGTACTTGTTCA 8 9 +CGGGAGGACGGGCTG ref:0:14:AAGAACCTTTCACC ref:0:15:TTAAACGAACGGTCCA 9 23409 +GAAAAGAATTGGCGTT ref:0:16:CTTTTTTAC ref:0:16:AC 10 5094 +TCGAAGTCTGTTAGT ref:0:15:TC ref:0:15:AT 12 33 +AGT ref:0:3:CCGCTTATACATA ref:0:3:TGCAG 2 22 +TTAGAGCGC ref:0:9:TAT ref:0:9:GGGCATCTTGCTCTT 4 3450 +CATGCAT ref:1:6:AAATGGAAATACCTG ref:0:7:CTCAGCGTTGATA 2 987 +C ref:0:1:CATTTTTCGTTCAAAG ref:0:1:GGGAGATGGTGATAT 6 48 +GATATATTCAATCT ref:0:14:TATGCGAT ref:0:12:AATGTGTGGGGATG 5 3120 +GTATGGGAACACTCA ref:0:14:GCGCC ref:0:15:GTA 9 845 +CTGGTGTC ref:0:8:AGGCCTGTCCGACG ref:0:8:GCAAGG 3 221 +TAAACTACATA ref:1:10:CCTAG ref:0:10:ACAAAAAGTC 1 11 +ACTT ref:0:4:CATTGTAACG ref:0:4:TCTGGTGGTTG 4 84 +AGACCG ref:0:6:CTGTCCACATACTA ref:0:6:GC 2 18 +GAATCCTTCTA ref:1:10: ref:0:9:TTTGTCTGCGCATT 3 9 +CCCTTTGCGAATT ref:0:13:GGAT ref:0:13:CTC 6 36 +TCCGTTCATCGG ref:0:12:GATC ref:0:12:CTACG 5 8 +GCTCGCGTAT ref:0:10:TAACAATTCG ref:0:10:AGAAACTC 7 250 +AATGCCGCAAGA ref:0:12:GTAAATTGGATTG ref:0:12:AGTTGGTCTGCTTA 5 21672 +AA ref:0:2:TGAC ref:0:2:AGATAA 1 30 +CTACGCGGAA ref:0:10:ACCGGGGTTG ref:0:10:ACCT 6 1400 +ATGGATAA ref:2:6:GCTATAGCCTT ref:0:8:T 2 66 +GTGTCTCGC ref:0:9:AACTGT ref:3:6:CTA 4 152 +TTGATTAT ref:0:7:GGTT ref:0:8:G 4 5 +GGAT ref:0:4:AGACGTCTACGGTT ref:0:4:CA 1 6 +GACATAGATATG ref:0:12:AAGTTA ref:0:12:C 6 16 +C ref:0:1:CTATCT ref:0:1:CCTGGCCCTTAG 3 10 +AATATA ref:0:5:TGCA ref:0:6:GCACGTAC 4 62 +CTAA ref:0:4:ACCGCAT ref:0:4:AACAAAACC 2 370 +AAGAA ref:0:5:TCGCATCCGGAT ref:0:5:TAT 4 1872 +TT ref:0:2:CTTTCAAGG ref:0:2:ACTTCTCTTTA 4 45 +ACGTCCCCTCTATTG ref:0:14:GACCGC ref:0:15:CCTACTAGTGTCC 6 6420 +GTCCTTCATACTA ref:0:12:TTCAACCTCTTTG ref:0:13:AAGTCTTG 5 10530 +CTCATAGTGGATTAG ref:0:15:TAGGGTGCAGGCACGT ref:0:15:TATCGGTAAC 8 246120 +GCCAACCG ref:0:8:TACTCAGTGA ref:0:8:G 4 150 +ATCCGC ref:0:6:T ref:0:5:CGGCGGTAATAGAAG 2 40 +TA ref:1:1:G ref:0:2:CTGCGATATGGCAA 1 18 +GATACGAC ref:0:8:C ref:0:8:TAGGTTACTTACA 2 80 +ACAATAAG ref:0:8:GGTACGACCC ref:0:8:A 5 1460 +TCTCCGTCAG ref:0:10:TAATTTTGCCAAC ref:0:9:GGCCGAAAAAGCGT 1 9753 +ATGGGCTCG ref:0:8:TAGGAGTTCTA ref:0:9:GACTA 4 210 +TGAT ref:0:4:GGTCCTGCAAGAAGG ref:0:2:CT 1 54 +GTTTGCATTCGC ref:0:12:AGTCGACGATA ref:0:12:CTGGGCGGCT 6 76140 +T ref:0:1:GGGATGACTT ref:0:1:CGAGACG 5 24 +GT ref:0:2:TGAGGCTGCGA ref:0:2:CGGGCCACGACATGC 5 12 +AAATGAC ref:0:7:GCATTACG ref:0:7:ACATTAA 4 1715 +GA ref:0:2:AAACGGACGAG ref:0:2:GACGAGGTTGAGTTTT 5 40 +CTCTGTAAAT ref:0:10:ACTGCCAATCA ref:0:10:GT 4 192 +ACAACCTCA ref:0:9:ACCTCTAA ref:0:9:TCCACTACGTGGC 2 468 +AGCATGATGACCGTT ref:0:15:TGCC ref:0:15:ATGT 9 78 +GCCTACT ref:0:7:TATAGCTAGTGAGTAC ref:0:7:ATCGC 5 3575 +CTCGTTCACGTCT ref:0:13:TGAGTCC ref:0:13:GCTTATTAGG 4 237 +CGGAAACTCCA ref:0:11:G ref:1:10:TGTAA 7 96 +CAC ref:0:3:AAGGTTTATATCGG ref:0:3:CCACAGTTCTGATA 5 147 +TTCGAG ref:0:6:AAAGGTTGGACAAGG ref:0:5:AA 2 150 +CTTTTGTTGCAT ref:0:12:A ref:0:12:TTCTCAGTATCTCGCG 3 76 +CTTCACGGCGAGGG ref:0:14:ATAGCAGGTGAGACG ref:0:14:GAAGAAGTCAC 7 14000 +TTAGGGCAAAACGGG ref:0:15:ACC ref:0:15:TATC 11 48 +G ref:0:1:TTGTTTGATAAGTT ref:0:1:CCTTATCATGGGC 5 9 +CC ref:0:2:GCAATACTTCAGCCC ref:0:2:ACTGCAGAC 5 45 +CCGCGTCGT ref:0:9:TTTCCAA ref:0:7:CAAAGATGT 4 11235 +T ref:0:1:GAGCGAGTAA ref:0:1:CGAAA 5 6 +CAATAA ref:0:6:ACATACGT ref:0:6:TGTGC 4 1216 +A ref:0:1:AACAAATATCGT ref:0:1:GCAACTCTAGTC 6 18 +GCC ref:0:3:ATAGCTCAATTCAG ref:0:3:ACTTA 4 33 +CTCCCCTA ref:0:8:ATCT ref:0:8:GCGCTTTC 4 6888 +TCCGA ref:0:5:GAGTT ref:0:4:GTTGTGTG 2 64 +GGAGACA ref:0:7:TGTTGGGGCTCCTTG ref:0:7:CGCGC 3 5328 +CTTGGGTCGCC ref:1:10:TCATC ref:0:11:TATTCTCCCCCTGA 5 46980 +CGACCCCCAATAAC ref:0:13:GCATATGATG ref:1:13:ATAACGTAA 4 210 +GCCTAGTCTATTCAA ref:0:15:GAGCGATCAACATA ref:0:15:CCTTACCGCGCG 4 4440 +TACATCCTATA ref:0:11:CAAGGGGGTGGT ref:0:11:TTTTCTCGCCA 4 84500 +GTA ref:0:3:CTTTCTAGGT ref:0:3:ACTAATAT 4 255 +TATCAAG ref:2:4:TTT ref:0:7:GTAAAGTCGGTT 2 225 +CACATCTGGGTGGAC ref:0:15:GTT ref:0:15:CATTTTGCAGA 7 988 +TGCCGATA ref:0:7:A ref:0:5:TTTGCATAC 1 3 +GAG ref:0:3:TTGACCGTGCAGG ref:3:0:CTA 2 10 +ACACC ref:0:5:TCG ref:0:5:GCCCGCTTG 3 231 +TGGG ref:0:4:GCGTCCTT ref:0:4:ATGAA 1 90 +GGCCTCC ref:1:6:ATGCTGACAAGAAGT ref:0:7:T 2 23 +ATC ref:0:1:CG ref:0:3:GTCATG 2 12 +GGAATGAAATGGGTAA ref:0:16:TCACGATGATG ref:0:16:TGCTATAT 10 107892 +AAATTG ref:0:5:CGAGTAGAC ref:0:6:TGTAT 3 138 +ATACACTTAGG ref:0:9:TGGTTGCTACCAT ref:0:11:AAAGGAGCTG 4 29832 +CATACT ref:0:6:C ref:0:6:GCCTTGACGAAGGG 2 112 +AAAAAGTAG ref:0:9:TCAGTATTAGCTCGG ref:0:9:CGTATGTGGGG 8 354750 +GC ref:0:2:TACC ref:0:2:T 2 21 +TGTGGGAGGA ref:0:10:T ref:0:9:CCGAGT 5 294 +G ref:0:1:TGTGTCACACACCCG ref:1:0:CCATTC 4 3 +GGTT ref:0:4:GAACCT ref:0:4:CTTC 2 78 +TTGTTG ref:0:6:ACGAGCAT ref:0:6:ATTAC 5 6156 +GATATAACCCATCCA ref:0:15:TCAATGGGCACT ref:0:15:TAACAAT 9 174832 +CAACT ref:0:5:CGTTCACTTGT ref:0:5:ACACGTTCCGTTC 5 1008 +G ref:0:1:C ref:0:1:GGACTCT 1 4 +TGCGACT ref:0:7:GTTC ref:0:7:CTGGGTTC 5 1156 +TTCAGCAGCGCTG ref:0:13:GAGAGGGCTT ref:0:13:GATGGCCGTCAT 6 2160 +AGGT ref:0:4:C ref:2:2:TGTGAGAC 1 5 +GCGATCACCAGAGTAC ref:0:16:C ref:0:16:GGCCTTCCACATGTA 6 5545 +ACG ref:0:3:CGGGCA ref:0:3:TCTAACAACGGAGCC 3 54 +AGAGCGTAGTACTAG ref:0:15:GGATGATCGTTCTA ref:0:15:CACCGTCTC 5 1035 +TAGTAATGCATGC ref:0:13:TG ref:0:13:TGCCCTCT 8 600 +ACGGTCCTTCCCTGA ref:0:15:GAGGATCCGAA ref:0:15:GCTGAGTAT 7 36112 +CGTTTG ref:0:5:ACTGTGCGTCA ref:0:6:TCGTCGGGTT 2 9 +AGTG ref:0:4:G ref:0:4:CGGTTAGGGG 1 100 +GTGCGTTT ref:0:8:CATTTTTT ref:0:8:ATACC 4 4472 +CTTGCT ref:0:6:GTACGCAA ref:0:6:TTCCA 4 210 +GCGGGGGCATGTG ref:0:13:TTTTGGCAACC ref:0:12:TTGGTTAA 9 2398000 +CACCCAGAGCTCGGC ref:0:15:CA ref:0:15:CATGGTA 10 648 +ATAAGATC ref:2:6:GTCAA ref:0:8:AT 3 5 +TA ref:0:2:AGCTGCCCAGATCTC ref:0:2:ATAAAT 3 6 +CTAT ref:0:4:GCGCCCGTGTT ref:0:4:GCAAGAACCCCACTAG 6 1056 +CCCGCTCGCGGC ref:0:12:CCTAGGCAA ref:0:12:GCATTAACG 5 1824 +GTTGCCGGCAGCCT ref:0:14:CCCAGGTAGTGT ref:0:14:CGAAG 7 1568 +AGAG ref:0:4:GTA ref:0:4:GGACAAAATTGGTCC 1 83 +CCAGAGGGCCGTTTTC ref:0:16:GTAAATA ref:0:16:C 12 9470 +C ref:0:1:TCACGTT ref:0:1:AAAACG 2 2 +ACATTATCGCCT ref:0:12:TACTTTAAACCGA ref:0:12:TGATGCTTTAAT 7 67617 +CATCC ref:0:5:TATTAAG ref:0:5:GGACATAATGACTCA 3 200 +CCAAGCCAC ref:0:9:AGCGG ref:0:9:GTCTGAAGAA 3 1020 +CAGAGC ref:0:6:GT ref:0:6:TA 5 36 +AACCACGGCGT ref:0:11:GCCACTTCGAGGA ref:0:11:GCCGACCGAAGCGCC 6 216 +CCTACAGAACCTTTG ref:0:15:TCCACGTTCTGACCT ref:0:15:ATACAATCTA 5 67284 +GTAATAGC ref:0:8:TGATCAAGCC ref:0:8:CTGAAG 3 352 +CCGT ref:0:4:AAAA ref:0:4:AAGAACTA 6 910 +GTT ref:0:3:AAAATTATC ref:0:3:T 1 32 +TCGCGCGTGTTA ref:1:11:GTTCT ref:0:12:CGCACAAG 3 84 +CGGGGTTCGCTGC ref:0:13:ATAGGGAACATAGTGG ref:0:13:CG 6 15588 +CGGCTTAAGGTTAGT ref:0:15:AGGCCATCA ref:0:13:GCTGAC 5 432 +GTGCACACGAGTACGT ref:0:16:CCCGCTTTTCTTCTGC ref:0:16:GTG 9 12216 +CCTACCCAATTTG ref:0:13:TGAGGCCAAAGTGCC ref:0:13:TAAAACTTCTT 4 4060 +CAA ref:0:3:AGTCCGGCCGAGTTGG ref:0:3:TTAGG 4 645 +CCGAGCAAT ref:0:9:GTTTTT ref:0:9:TGATATAGCC 6 30800 +CAAATCAA ref:0:8:TGGAGTT ref:0:8:GCA 6 5100 +TGTATG ref:0:6:CTA ref:0:6:TCATGGAGCTTTCC 3 828 +GGGGGGCGATTCGGAA ref:0:16:CGA ref:0:16:GACAATAAA 9 10395 +CTCCGAGGCAACGT ref:0:14:CGTACCG ref:1:13:ACCAGTTCCCCCG 5 1288 +TAACGC ref:0:6:CTATCT ref:0:6:AGAA 2 224 +GCATAC ref:0:6:CACTTCA ref:0:6:CTTCGGAG 4 50 +GCAA ref:0:4:CCGTC ref:0:4:CT 2 3 +TAAG ref:0:3:TTTATATT ref:0:4:GCTTAC 1 36 +TGTCAGTC ref:0:8:AGATT ref:0:8:GCGAAGGCTCT 3 52 +GG ref:0:2:TTATTGGA ref:0:2:CACATCCGCGTC 2 1 +ATTGGCGTCTGC ref:1:11:CTG ref:0:12:AGATACGCAAAT 5 99 +ATGT ref:0:4:TGTGCGGATTAGGAAC ref:0:4:G 1 46 +C ref:0:1:GTA ref:0:1:GAGCC 2 8 +CTAGCTCCGTCATAGT ref:0:16:G ref:0:16:GATATGCAAAACGG 8 270 +AGTG ref:0:4:CCATCCC ref:0:4:TGCTAGCAAACGCC 4 40 +CTATCGACC ref:0:9:GACTA ref:2:7:TCGCCAGC 2 112 +GAGGAGAGCAGGTCC ref:0:15:ACT ref:1:14:ACTCCAAAGGCAAG 6 3270 +A ref:0:1:AGGTGTTGTGGCGAG ref:0:1:CTTTAGTCGT 4 2 +CTGTATA ref:0:5:TACCGTC ref:0:7:TGGGAGT 1 48 +TACA ref:0:4:CTTGACGTTG ref:0:3:GTGATCGTGGG 4 10 +TCGAACTA ref:0:8:CCAAATCATTAGAA ref:0:8:GTAT 1 540 +TGCTCGCC ref:0:8:CAGG ref:0:8:CCAA 6 418 +AT ref:0:2:GGCC ref:0:2:GCGCGTCCCATCCGTT 4 45 +ATTCGCTCAGTAAAC ref:0:15:CAAA ref:1:14:TG 8 60 +AC ref:0:2:G ref:0:2:CCTGAATCCCACCTA 1 36 +ACCGGTATGGT ref:1:10:GGATCGG ref:1:10:A 4 1 +AACGGT ref:0:6:G ref:0:6:ACATTAATC 2 234 +CTAC ref:0:4:GTTGA ref:0:4:GACTCTACAAGTAAC 3 120 +ATCTTTCCCCCTT ref:0:13:CCAATGCAAGT ref:0:13:TG 10 1394442 +GCGCCCTAGAAT ref:2:10:GGGTTACATG ref:0:12:TCGC 4 1992 +A ref:0:1:TCCCCGTCTT ref:0:1:GCGACAAGCA 4 44 +AGTGGTAACC ref:0:10:CGAGTC ref:0:10:GGGATTGTAATGCCGG 3 1620 +GT ref:0:1:A ref:0:2:TCGATGTGAGT 1 14 +CT ref:0:2:GTGTTCGGATCC ref:0:2:TCGTCGGTATATG 6 7 +TGTCTAGG ref:0:8:T ref:0:8:GATATTGTTA 3 9 +CCA ref:0:3:TT ref:0:3:ACATCCTCTCGTGTAA 2 200 +CCCTGGCATGGC ref:0:12:TAATCCCTGTTGCAT ref:0:12:GGA 3 1 +GTCTCAGA ref:0:8:ACCCATGGCT ref:0:8:T 3 210 +TCGCTCGAACGTGCGG ref:1:15:GCACGCCGTAAACGG ref:0:16:CGGTCGTGCGGG 3 2952 +CTAGT ref:0:5:G ref:1:4:AAGGGGTAGAC 1 15 +TCTCCAAACG ref:1:9:CCCGCATAGGAC ref:0:10:GTCAGT 1 135 +AA ref:0:2:GGGCTCC ref:0:1:CGCGGCACGG 5 36 +AGATCCTCAC ref:0:10:ACTCAG ref:0:10:CACA 5 168 +GTCACCGTTCTAC ref:1:12:CAAAAAAG ref:0:13:AA 9 1772 +GATCGATACTGG ref:0:12:ACGTC ref:1:9:TGGGGCAT 2 144 +A ref:0:1:TACCCC ref:0:1:TAGATATCG 2 3 +ACCTGAATTGGG ref:0:12:GC ref:0:12:GTAGGT 8 1102 +CAGGC ref:0:5:ACGCGCCTTTGAAAA ref:0:5:TATGTT 3 96 +ATGCG ref:0:5:TCTTAATTGTC ref:0:5:AAAATA 2 64 +CCT ref:0:3:TAGTATCGTG ref:0:3:CATGAA 2 27 +TGGGAGATGAGTTT ref:0:14:ACG ref:0:14:TT 10 180 +CATCCTGTTC ref:2:8:GAA ref:1:9:GTACTG 5 80 +G ref:0:1:AC ref:0:1:GTGCGAACGG 2 15 +CAGACCAGCCGTAAC ref:0:15:TTCAT ref:0:15:GGAATAATAAACTA 8 56316 +TTTT ref:0:4:TAGACCTGA ref:0:4:GCACACCCGACT 7 25025 +ACATTTC ref:1:6:GCTAGGAAAATGGCA ref:0:7:GGGTCCTTCCTAA 4 29610 +CATACCCGTGTGACT ref:0:15:ACACCCGTG ref:0:15:TTTGACTGAAAACCG 4 70416 +CAGAAAAT ref:0:8:TAGTAGCAATGAA ref:0:8:CTTTCCAC 4 44220 +GCC ref:0:3:CTTACCGAAC ref:0:3:CCAAGAGCGTCGTGG 3 46 +GCGCG ref:0:5:TAGATGTATC ref:0:5:GAC 3 15 +ATAAACGCCC ref:0:10:CACCATGCCTGG ref:0:10:AGAACGCCGAGT 5 43400 +ATCATACAGC ref:0:10:GACTT ref:0:10:TACTT 8 531 +TC ref:0:2:TGGATCCCCCAC ref:0:2:TAGGAT 4 84 +GGTCGACTCAGGAT ref:0:14:GACGGCGC ref:0:14:CCGGCTA 8 27744 +ACCGAACGCTCGGAA ref:1:14:GCGATTG ref:0:15:GA 9 1000 +ACAGCG ref:2:4:TTGGCA ref:0:6:CTCTGTG 4 442 +TGCGGCAGCGTT ref:0:12:ATAGGAAAGCTGATG ref:0:12:CGCGATGC 3 1190 +AG ref:0:2:TCT ref:0:2:TTACAGTGCCAAACGT 3 90 +TCCTATCTATTCTG ref:0:14:CGGTAATT ref:0:13:GGC 8 1380 +TTCT ref:0:4:TG ref:0:4:GT 3 56 +ACTGGGCCAGACTC ref:1:13:AAC ref:0:14:G 9 8 +TCCTGATTTT ref:0:10:TGTATATGACGGGAC ref:0:10:TGTACGGTT 7 176814 +ATCATGGATTGCGCA ref:0:15:CTTTCACCC ref:0:14:CGATGAAGC 5 1462 +GCGGTAAGGG ref:0:10:CCTGGTCGAAGTA ref:0:10:GAGTATTGCAGT 4 6300 +ACAAGT ref:0:6:TGCTAGTTG ref:0:6:CCTGCGA 4 3024 +TATA ref:0:4:AGACGCGGGAATTG ref:0:4:ATCG 3 609 +T ref:0:1:GACATACGGCC ref:0:1:TTAGTTTTAGAGTAAG 5 7 +CCGCGCT ref:0:5:CGTGAT ref:0:7:ACAGGACCGGTCCTCT 2 988 +TGGCATCGAC ref:1:9:T ref:0:10:TTCCATC 5 33 +GAAAAATGG ref:0:9:CTTGA ref:0:9:CTAAAACCG 5 21411 +TGGGCGGTAGCGTG ref:0:14:C ref:0:14:ACTCTA 10 22 +GTGACA ref:0:6:AG ref:0:6:AGGATTGG 4 288 +GTAGGGGGGT ref:0:10:TACCTATGC ref:0:10:CAGTAATTTAAAGCG 8 5174400 +CTGTTCAGGCCTGGA ref:0:15:GAAAGTAGTTC ref:0:15:GTCGAC 9 118368 +TTACCACACAT ref:0:11:CTGACCCATC ref:0:10:CGC 4 408 +GGTG ref:0:4:A ref:0:4:CGGATGGTAGGCCG 1 115 +GCGGC ref:0:5:AGGCGTGCGCAT ref:0:5:GAGCCGCACGGGGT 4 1984 +GCGGATG ref:0:7:AAAGA ref:0:7:AATTGGC 5 1416 +GTTAGAAGC ref:0:9:AATCAATA ref:0:9:TTCCCCT 4 1008 +GGACATTCT ref:0:9:GATAGGG ref:0:9:A 6 688 +CTCACCGGCAGTGGGA ref:0:16:T ref:0:16:GAGCATGTCTGG 8 162 +TCGTTA ref:0:6:GTTTCGAGCCCCTC ref:2:3:TGAGGAATTTGC 3 873 +CAA ref:2:1:GTTACCG ref:1:2:GTGAGTTAGA 4 3 +T ref:0:1:GCCG ref:0:1:TTGT 1 15 +GGACTG ref:0:5:AACCTCTA ref:0:6:ATTGC 3 60 +CGATC ref:0:5:GAAGCTG ref:0:4:GGA 2 27 +CACAGCCTACC ref:0:11:CGATTG ref:0:11:GAACGCAGATCTTCGA 7 297804 +T ref:1:0:AC ref:0:1:GGTCAT 1 2 +CTGACAAGCTGATGCA ref:0:16:TA ref:0:16:CAGTATTCGCGG 8 264 +ATTACAACTCC ref:0:11:CGGTAAAAAG ref:0:11:AACGC 6 112000 +CGCCAT ref:1:5:TAGCCG ref:0:6:G 2 3 +TGAGGCACC ref:0:9:CATTGAAATTGAAGCA ref:1:8:GG 2 18 +GAGTCGTGCTGCTCCC ref:0:16:ATCTTCTTCCA ref:0:16:CGCCTATAGGCCCAA 6 43850 +GG ref:0:2:CTGGCGC ref:0:2:GAGGAGGTAAATA 1 30 +TACTAATTATTCGGA ref:0:15:TTCTGGTAAC ref:0:15:TGG 9 2910 +CA ref:1:1:T ref:0:2:GCCCATATCGGCCC 1 12 +GTGTGATG ref:0:8:TTAACATTGG ref:0:8:GTAACACC 5 9828 +TTTATGA ref:0:7:ATCTCGCATT ref:0:7:T 3 268 +GGCG ref:0:4:GCGTTATTGAAC ref:0:4:GATTTGGGAAA 3 65 +CGAACTTCATCC ref:0:12:TCGTGTTGC ref:1:10:GGACCGCGGACGA 3 168 +GTCGCAT ref:0:6:TTGCCCTGGACG ref:0:7:C 2 290 +CTCCTTGTTAG ref:0:10:G ref:0:11:TCGACGTTATGCG 3 2 +ACGGGTAAACAATCAC ref:2:14:GA ref:0:16:GTTCACA 8 702 +ACGGTCGCTGAAC ref:0:13:GACCGACGTGG ref:0:13:TATGTCATAAACCGT 3 11256 +AGA ref:0:3:CCTCTAGTCCCC ref:0:3:TTGAAGCCCGACA 6 48 +GGGTTTACG ref:0:9:AGTTCATCGGCTCCCT ref:0:9:TGCAAGTTCTGAT 5 2940 +CTTCG ref:0:5:TCGGACCCCTCC ref:0:5:TATGCACAGCGTAAGC 4 648 +GCAGTCTACCTGGAC ref:0:15:TGCATTAAG ref:0:15:ATGTTGGTGTACGAT 6 7033 +GGCGAAGGACAC ref:0:12:ATCCTTAGCGCGGCA ref:0:12:TAGTTGTATGGTTC 6 27300 +CCTTTAAAGGATTTGG ref:0:16:GGTAGGCGGGTACACT ref:0:16:GGGA 11 1394256 +ATAAGGTGCAT ref:0:11:GGGTA ref:0:11:GAGGGA 6 80 +AG ref:0:2:AATTGGTCCT ref:0:2:TGCGAC 3 32 +AGGAACATC ref:1:8:GTGGTTCTTCACC ref:0:9:CACTCGGCCATT 4 5988 +CAGCGCCA ref:0:8:GATACGCT ref:0:8:AAAGACATAACATG 4 8415 +GG ref:0:2:TGCGGAAA ref:0:2:CATAAACCTATTTG 2 45 +GGGCAACAAAT ref:0:11:CCTAGAC ref:0:10:CTCGGGCAAG 4 400 +CTGC ref:0:4:ACATATTATT ref:0:4:GGGGTCGCGTGACCA 2 228 +ATGGGG ref:0:6:AA ref:0:6:CCCT 4 28 +GAAGTGGTCGCA ref:0:12:AACTTACCC ref:1:11:ATGTACCTATATACC 5 120 +TGTTGGCT ref:0:8:GAATCCCGGGCTG ref:0:7:GCC 3 253 +GC ref:2:0:TAA ref:0:2:TGCGGGT 1 1 +TTGCTCA ref:0:7:ATTAAGTTC ref:0:7:GAG 1 3 +ACA ref:0:2:TCGAAAACGC ref:0:3:AAGAC 2 72 +TTACCGCTA ref:0:8:G ref:0:8:TTCTGCCCG 3 82 +CT ref:0:2:CATTAGCTCTG ref:0:2:CACAA 2 56 +TTG ref:0:3:ATAAGACAAATCAAGA ref:0:3:TGAAACA 1 2 +TCTTTCAGTCAC ref:0:12:GGTAGCCTAG ref:1:11:AGCTAGTCT 7 3600 +TCGGGA ref:0:6:CAAACTGAGGCGTG ref:0:5:AG 2 1884 +ATGACCCTGTGCGTAA ref:0:16:CGCCAGCCCCC ref:0:16:GACAGTAAAATG 6 27984 +TCCATACCCGGCGCA ref:0:14:CG ref:0:15:GGAACTCAG 9 12672 +GTCTACTACGCTGGCT ref:0:16:TTC ref:0:16:CCGCCAGCAGCGTTC 6 1586 +TGGCTAAA ref:0:8:GTCAATTCAAGGACG ref:0:8:TGTGTTTTGCATTCC 5 5272 +ATCGATGTCTACGGAG ref:0:16:GG ref:0:16:CGCT 11 20 +AAC ref:0:3:ACTCTAT ref:0:3:GAATA 2 40 +GCATACTCCG ref:0:9:TTTGTTTTGCCTA ref:0:10:CCC 3 112 +GACTGAATG ref:0:9:CACTAAGGACAA ref:0:9:TGTATCTGAGGATT 1 78 +AA ref:0:2:CCACGAGCTT ref:0:2:AGCTTCGTCC 4 11 +TGCGCCAGATG ref:0:11:CGTTCACGGTCT ref:0:11:T 5 182 +ACTGTCCCGGCAC ref:0:13:CAACTACGTGCAGGA ref:0:12:GAGCCGGATT 2 60 +CTGCT ref:1:4:AGGCCTG ref:0:5:TGTCATAAGAT 1 40 +TGGGTCTCAGACAGA ref:0:14:GATAGCATGCGT ref:0:15:TC 7 1200 +TTGATACAG ref:0:9:C ref:0:9:CGG 7 6 +GACGTTTTGGATGCG ref:0:15:TGGGGC ref:0:15:GTTTCTCGAATGAT 4 4200 +A ref:0:1:TGCTTGGGGCGG ref:0:1:TATGCAAAGCCAAAT 5 91 +AACCAGA ref:0:6:CCACCATACGT ref:0:7:GCCCCGACCTA 5 1984 +AGCTGGCACTACCT ref:0:14:TCATATCCC ref:0:13:TT 6 4 +C ref:0:1:TGGTAAGTATT ref:0:1:GTTTTACTC 5 24 +CCTGCTAA ref:0:8:AATATGC ref:0:8:GAAAGA 3 315 +GCCTATAGAGAGCTC ref:0:15:AGTCCT ref:0:15:ATATTAT 9 9664 +TCCGCTAGAGT ref:0:11:CGCTTCTGGGTC ref:0:10:CGAAACGG 4 4370 +T ref:0:1:AGAGTGCTG ref:0:1:TCATGACACGCAATAT 5 8 +GCT ref:0:3:ATCATAAG ref:0:3:CAAATACG 4 3 +TGCACTCACAGGGA ref:0:14:CTTTATATTAACTAC ref:1:13:TAATG 8 72948 +CTAAGCTGGCAG ref:0:12:GTCGCGAAGGCATGG ref:0:12:GGGGCGTGTACATGG 7 108180 +AACGCTGATTAAGTTG ref:0:16:CAAACAGTGGCCGCCT ref:0:16:GGGTGATTA 4 40446 +AGCAGTCTGGTATC ref:0:14:AGAAGCAGCTG ref:0:14:TTTG 5 232 +TCTACTGAGT ref:0:10:CT ref:0:9:CTAACT 4 10 +AGACGTCGT ref:1:8:TCGCGATCG ref:0:9:GGAGAGAACCAGC 2 42 +CTACAATGAG ref:0:10:GGTATGGAGGA ref:0:10:GTCGAACGGGTGGC 3 72 +ACGATC ref:0:6:CTGGTTCTCCGGAATA ref:0:6:GAACCACTATGACTCA 4 1862 +TTTGACCGGGTCG ref:0:13:AACACTCTAGAGA ref:0:13:CGAACACAATCAC 9 3840 +TTATCGCACGGAGC ref:0:14:AGATATAAAT ref:0:14:GGGGCGCACTGAAGG 5 235620 +ATCTC ref:0:5:AGCAGACT ref:0:5:TTCC 1 100 +CCAGTC ref:0:6:AGCCTACCGCCG ref:0:6:ACCCATAGGGTGGA 3 216 +GCGTGTCTACG ref:0:11:CGATCA ref:0:11:TACAC 5 20 +TCA ref:0:3:GCCACCCCG ref:0:3:TAATGAATGTCGCGCG 5 335 +GTATTACAGTAGTTC ref:0:15:CCGAGTG ref:1:14:ATG 10 392 +AACCC ref:0:5:ACTCT ref:0:5:CGAGG 2 660 +AG ref:0:2:CCCGAGTCCA ref:0:2:TGA 1 3 +G ref:0:1:TCTGGCGA ref:0:1:ATGGGGAGAGGACCG 4 24 +CACCTT ref:0:6:CGCAAAAATAGCC ref:0:6:TAGGGATCAATGGGC 6 5304 +AGGCCCTGCCGC ref:0:12:GA ref:0:12:CTGTCGGGCCC 6 23954 +ATGAAGCACAATTAC ref:0:15:CCACCGTTTT ref:0:15:GATCCGATCGGCACA 6 85779 +TCTTTGGCCGCGGC ref:0:14:CGACCT ref:0:14:GGAACTAGGTGA 8 840 +ACGGAGCCA ref:0:9:TCGCGTTGACGCAA ref:0:9:G 2 246 +CTCGGGCTC ref:0:9:AACGTGT ref:0:8:ATGCTGATCCTAT 4 7998 +GAA ref:0:3:ACCTACATTTGA ref:0:3:TTAAACAATCCTGGA 7 1606 +GATGCGAAAAAATT ref:0:14:TAAGCG ref:0:14:GAAGACT 9 8048 +AGCCAAGCTT ref:0:10:TCTACGTAACCCAATG ref:0:10:ATCTGATCC 5 8652 +TAAGAG ref:0:6:GAT ref:0:6:A 4 6 +GTAAGTTCAACTATGA ref:1:15:AGAACGG ref:0:16:TTTGTAGTAAACCAAT 5 2376 +ACCGCGGTGAGCCGG ref:0:15:CGTGTGATC ref:0:15:GCGCTA 7 520 +AGAGCCAG ref:1:6:ATCTCTCCC ref:0:8:GAACCACT 3 852 +AATGA ref:0:5:AGCGTGGCCCATCCTC ref:0:5:CAACGGACCGAACCT 7 410 +CAAGCCTATTGTCAAC ref:0:16:AAGGCAGGAACTA ref:1:15:AGGG 7 870 +GCAAACA ref:0:7:CT ref:0:7:TCA 5 112 +AATCT ref:0:5:CTTGAC ref:0:5:TA 4 140 +G ref:0:1:TCAGTCAAAGTTCT ref:0:1:CAGGCAGCA 6 6 +AAACA ref:0:5:GGGACGTGGGC ref:0:4:CCCC 3 5985 +TTA ref:0:3:AATCCCATATAT ref:0:3:TCAATACAGTGA 4 20 +AGGGGA ref:0:5:G ref:0:6:CACTGGT 2 144 +GAAT ref:0:4:CACTTAAC ref:0:4:CTGTACACGA 5 228 +AT ref:0:2:TTTAGGCAATTGC ref:0:2:ATACCTGCCCGTCG 4 30 +TCTGAATAG ref:0:9:ATCCTA ref:0:8:AATTTCC 4 180 +TGACGTCCATGTTG ref:0:14:ACTGAACTAGT ref:0:14:ACCAATCGTATGGCC 2 56 +CGGAGAACT ref:0:8: ref:0:8:CGCCCCCGGACGA 2 19 +GCAATAT ref:0:7:AACG ref:0:7:CAGACCC 5 640 +CGCG ref:0:4:ATTTG ref:0:4:GCCATGAAATCT 4 280 +ATTTGACGCGTGAA ref:0:14:GCCG ref:0:14:AAATTATCGGAGC 4 864 +CTAT ref:0:4:GGAGAACATAA ref:1:3:A 1 4 +CAGGG ref:0:5:CCGCCGACACT ref:0:5:ACTGGGTGTCC 3 403 +CGACACTGTTC ref:0:11:GTGTGATGTTT ref:0:11:AATCCGGCGGGGG 3 7144 +CC ref:0:2:TCCAGGTGAAACATGG ref:0:2:ATGTGG 6 84 +CGCAATCTGGGGT ref:0:12:AAACCTACGAGCGGC ref:0:13:GGAAGAGGACACGC 5 240 +TCAGACTCTTGTT ref:0:10:CT ref:0:13:AGGCATGTCGCCGG 6 28328 +C ref:0:1:ATAGCAAACCAC ref:0:1:GCTCCGACTGT 5 16 +GATACATATTAGGGAT ref:0:16:TATACTTA ref:0:16:TA 9 192 +CGGGAGTAGTTGAT ref:1:13:GAATAGT ref:0:14:AAAGGTGAGATTCTTG 3 8820 +CAGTACTATGAGAA ref:0:12:TATACGACC ref:0:14:GTCTACACGT 5 108 +TGCACGGGGTAAAG ref:0:14:GAGGTCTTAGTAA ref:0:14:GACGATCTCATTGT 7 59064 +CGTCGGGGTACG ref:0:12:CAGGCATGGT ref:0:12:AATACTTGGGG 5 4347 +CGTCACTCTCGA ref:0:12:CAT ref:0:12:CCAAGTCAAG 6 588 +AT ref:0:2:AAACGAACGTTAT ref:0:1:GGTCGGGCAGCGG 4 16 +AGCTCCTCGC ref:0:9:GGA ref:0:10:ACCAAGAGAGTCCTTC 2 210 +CACGCGCC ref:1:7:TATAG ref:0:8:TGGCTACGCCGAGC 3 195 +AGCAAGAA ref:0:8:CTACACCGGA ref:1:7:GGTAATCCGTC 4 837 +CAAT ref:0:4:TGTCAGGTAATTA ref:0:4:G 1 30 +GGATAGTGCG ref:0:10:CATGATCTAC ref:0:10:AAATT 6 5712 +CGGTCAGACGAAA ref:1:9:TCTACTC ref:1:12:TTATGAA 6 2772 +GTCGATCGCC ref:1:9:CATGCGATACCACGC ref:2:8:TG 1 13 +AGCTCA ref:1:5:C ref:0:6:CGTGAATTTGGTGCC 2 48 +GGCTCTGACAGAAGAT ref:0:16:AAGTCCAGCTTCAGTT ref:0:16:GA 7 1653 +TAAGCTCGCAC ref:0:11:CGG ref:1:10:AT 6 32 +TAGGATTTTAAGGAC ref:0:15:GAGCT ref:0:15:TGTAGTGCTTTG 6 624 +CGGTT ref:0:3:GTTGGGGA ref:0:5:TGACTCGCA 3 4128 +TTGGACATAT ref:0:10:GCTTGCGATATC ref:0:10:TATTGTA 2 28 +CACAA ref:1:4:TATCGCCCACTCCT ref:0:5:TAACGC 4 1785 +ATCTCCAGTA ref:0:10:GTACAGATTTTTC ref:0:10:GCGTCTCCAGTTAA 3 10416 +TTGCTCAA ref:0:8:GTCTGATGGGAG ref:0:3:GCAGATGTA 3 414 +GCTGCCTCTC ref:0:10:GCA ref:1:9:TATGCAC 6 2964 +CGG ref:0:3:G ref:0:3:TCACC 1 28 +CAGG ref:0:4:CCTGAGACAGTTAC ref:1:2:TGGTTTTACGT 2 2 +AGCCGATCTTAAGA ref:0:14:A ref:0:14:CAATTC 10 820 +CTGTAGAA ref:0:8:ACACACCTGACG ref:0:8:CGAATCCTCGGGATC 6 1560 +ACATGT ref:0:5:GTTTGTCATA ref:0:6:C 2 14 +CCTTAAGCCGCTA ref:0:13:GATTGGGGAAG ref:0:13:TATTCATAGT 8 14976 +TGAA ref:0:4:AACCCCCTG ref:0:4:GCC 3 12 +TAGACCGAGTTAGGA ref:0:15:GCGAACAC ref:0:15:GGGAGTTG 5 96 +CGCC ref:0:4:GTAAATGGTCA ref:0:4:GCTTTGC 4 234 +AAATACAT ref:0:8:GA ref:0:8:CGATGCTT 5 1080 +GGACGTCGTTCTGTTT ref:0:16:ATCCCAGG ref:0:16:GTATTCA 10 9720 +CTTAGTG ref:0:7:CTCCTTTA ref:0:7:CCA 4 116 +AG ref:0:2:CCGA ref:0:2:AAGCGATTACCGA 3 32 +CCTATACCTACACTAC ref:0:16:TAACT ref:0:16:CACA 9 954 +GTTGA ref:0:5:CTGCAA ref:0:4:AAAATC 3 450 +GTTTGTGCC ref:0:9:TAGGGCATAGAGT ref:1:8:TCTCTG 4 15257 +C ref:0:1:CGTATGGTTGCCT ref:1:0:TATAG 4 3 +TCG ref:0:3:CT ref:1:2:CACGCCCT 1 6 +CGC ref:0:3:TACCTGAACAGTAAT ref:0:3:TGCGTCCG 2 4 +CTTACGCAGTATGTT ref:0:15:ATTAGCCG ref:0:15:TCTACAATGCTA 5 576 +AAGATGTTGTT ref:0:11:TACGAGAAGAGC ref:2:9:CATT 3 540 +TACGGTACT ref:0:8:GCGCCCGATA ref:0:9:CATG 3 3 +TTTAAATGAATC ref:0:12:TCTCTGGTTAGAGAA ref:0:12:TGTATAGAT 4 3478 +AAAATCTACTAGTACG ref:0:16:GC ref:0:16:A 13 7 +CCGAC ref:0:5:ACCCCGTTTTGGAA ref:0:5:AAAGTGGGTACG 4 5130 +CGAGCTGATATTCC ref:1:13:TGTGTCCTTTGGC ref:0:14:GATTCAGGCT 7 17640 +TTG ref:0:3:TGCACACCACAGCATT ref:0:3:TAGGATGGTG 4 90 +AGT ref:0:3:CCG ref:0:3:CAATAAACGA 3 39 +AAT ref:0:3:CTTC ref:0:3:TTTTCCCG 4 180 +TTGATGCAGCCGGGAT ref:0:16:ATCCTGATC ref:0:16:CA 9 84 +TTCATGCAATGT ref:0:12:AA ref:0:12:AGGC 8 15 +GT ref:0:2:CGTGCAGGACTAAA ref:0:2:TA 1 5 +GGCC ref:0:4:AGACG ref:0:4:ATGAGGAT 4 352 +GACACAACTC ref:0:10:AGTG ref:0:10:ATTGGCATGAAAGGGT 5 7632 +TTCAA ref:0:5:GTACG ref:1:4:GTACCAACTGGCCCA 3 144 +TCCCTTCGGAA ref:0:11:CTGGG ref:0:11:TATCACTAACAT 3 9750 +TAATATCCTATGTTTG ref:0:16:ATC ref:0:16:CCCCGCAGGCG 9 50350 +AGGTGGTAAAAGAC ref:0:14:GTTCGTTCTG ref:0:14:CCCAGTTCA 8 39202 +GGT ref:0:3:ACGCAC ref:0:3:AACAAACGG 3 22 +A ref:0:1:GGG ref:0:1:CAGTTTTCCTA 1 8 +ACTACACGCCTT ref:0:12:TTGTCTTATTGATTT ref:0:12:GCACTA 7 284632 +ACAGATT ref:0:7:GAATCTCCAGCCCC ref:1:6:TCATGGGCAACTAGG 4 8463 +TGGATGATCGAACCTA ref:0:16:AGCCAAAACAC ref:1:15:GTCGATTGAGCCAA 4 14559 +CATGT ref:0:5:TCGCACA ref:0:4:ATGAGGGGAGCAC 4 198 +GGCACCAGT ref:0:9:TTGTAGACTATAGGC ref:0:9:ATCCATGTTC 3 116 +GGCAACT ref:0:7:ACGACTTT ref:0:7:A 3 108 +CTT ref:0:3:AAGGTGAC ref:0:3:ATCCAG 4 1044 +TAACAAATTTAAGACC ref:0:14:AACGTATT ref:0:16:CC 8 102 +GTTCT ref:1:4:A ref:0:5:AGCCATCACCATTC 2 220 +GTGGGG ref:0:6:ATC ref:0:6:ACATTGTACTG 5 3230 +CGACC ref:0:5:CTACAACGGGTCC ref:0:5:TCACCGAA 2 75 +CT ref:0:2:CGATGCGTAT ref:0:2:GGAGTCCTTCGAGCGG 4 20 +ACGTCTGAGG ref:0:10:T ref:0:10:TCC 8 18 +CGCGTATTGAGGGCGG ref:1:15:CAGT ref:0:16:GGTG 10 900 +ACCCCCTGTGCGC ref:0:13:TCTCAAA ref:1:12: 9 466 +AGTG ref:0:4:ATCACTTATT ref:0:4:GCCC 3 1375 +TTTGA ref:0:5:ACAGCGTTGAG ref:0:5:GTGACAGTCACATCCT 5 1386 +CGTTACG ref:0:7:GATTTTCCTA ref:0:6:T 2 196 +CGGGC ref:0:5:AT ref:0:5:CGCGGTAATGA 3 315 +T ref:0:1:ATCACGATC ref:0:1:ATCGAA 4 2 +AA ref:0:2:CGGGTGCCCCAT ref:0:2:CCTGA 4 78 +GCGCTCAGAG ref:0:10:ACTTGACTA ref:0:10:CCCATATAAGC 3 248 +CCCGGCGGAAG ref:0:11:TC ref:0:11:ACACAAGCT 6 324 +GTTGTCTACTT ref:0:11:GAGG ref:0:11:TGTTCCTCTCGGACCT 2 765 +AAAGGAGGTCATAGAG ref:0:16:TCCCGAATAACAGAGT ref:0:16:TGCCG 7 860 +CCGGCACCT ref:0:9:GTCGA ref:0:9:AAGC 6 840 +GCGTCAAA ref:0:8:GGCGCAATT ref:0:8:CCTATA 2 210 +TAGTTAGCCA ref:0:10:CCAGGTAGTTCTGAA ref:3:5:CACTCTGCT 2 227 +ATA ref:0:2:GGGCAG ref:0:3:AGCGAGA 4 24 +TGACCTGTAGTTAAGT ref:0:16:CTTCTGCGGAACTCTG ref:0:16:GCCGTC 8 67694 +ATCATCG ref:1:6:CGCAAACGCCGTC ref:0:7:GCCGCCTCCTTCA 4 18816 +CCTTGGAGGC ref:0:10:CCCGAGCA ref:1:8:ACTG 3 176 +AAACCTCT ref:1:7:TAA ref:0:8:A 5 3 +GAGGGTAC ref:0:8:ACCGCTT ref:1:7:TTTTACACTGCGGT 5 152 +TGTTCT ref:0:6:GCACGCAAGTGTA ref:0:6:TCTTATT 3 3808 +AACCGTTGCAGGGA ref:0:14:A ref:0:14:GGGTTTCTTC 9 21196 +TTTGC ref:0:5:CCTTG ref:0:5:CAGTCATCTAGTCACT 2 10 +GG ref:0:2:GCTAAAGG ref:0:2:TCTCGGGGATG 2 30 +AAAATTAA ref:0:8:CTTCGGG ref:0:8:AACTTTT 5 13575 +ACACCATCA ref:0:9:AAGATTCCTC ref:0:8:T 2 6 +GGGATCA ref:0:7:GTCGTAATT ref:0:7:TTT 5 2844 +CACTAGCACGG ref:0:11:CTAAAGACA ref:0:11:GCTCA 5 176 +AAA ref:0:3:ATTCGAG ref:0:3:CGG 4 160 +GCACGAC ref:0:7:AGACTTG ref:0:7:AAAGTGAGG 4 364 +GCTTGGCTATG ref:0:11:TTGTCCGCC ref:0:11:T 6 144 +AAACGGTACAAT ref:0:12:CTCTCA ref:0:12:TAA 7 129 +GAAGACGACGGG ref:0:12:TCCC ref:0:12:GTATT 9 33768 +TTA ref:1:2:CTAGGCAGGGTGC ref:0:3:CGAAAAGTTGTATGAC 4 18 +TGGTTTGATCTGGCC ref:0:15:CGCTGCCT ref:0:15:AA 8 384 +ACCCGCGGTGGT ref:0:12:CCGGCGTAAA ref:0:11:CTACGGGCTG 5 7232 +GCAATAGCTC ref:2:8:TCCCT ref:0:10:AAAATAG 1 240 +TCTAGCTCGAGTT ref:0:13:ACGCC ref:0:13:AT 8 15 +AG ref:0:2:AGAAAACCCGA ref:0:2:AGGCGAGAACGG 5 78 +TGCGGCG ref:0:7:GTTCGCGAGGGTCCC ref:0:7:GGTC 2 328 +CGCACCGCA ref:0:9:TTTCGCTA ref:0:9:TT 7 6435 +GCA ref:0:3:GGCGAGCTAAGGTGG ref:0:3:TCGTGT 4 322 +GACGCGG ref:0:7:AGTCAAGATGCGTA ref:1:6:TCACGT 5 2398 +A ref:0:1:AGAGCATAC ref:0:1:AGTCTCTACAG 5 12 +TTAGGTA ref:0:7:TTCGCTAAATCA ref:0:7:ATCGGCAACACAG 7 9928 +C ref:0:1:CTCCAGGTTGAAGAC ref:0:1:ACCGAAACT 6 12 +GGCGCGTTACGGTATC ref:0:16:TC ref:0:16:AC 13 18 +AATGGT ref:0:6:TTTGTTTTAAC ref:0:6:TTCCCT 4 7360 +ATGCGTA ref:0:7:GGATTAG ref:0:7:CCGTAGA 3 30 +AATGTGTGA ref:0:9:AGATG ref:0:9:TCC 5 882 +TCGGGTGTCAATTGTT ref:0:16:CAGATACCGGCA ref:1:15:ATGCA 10 1120 +CGTTT ref:0:5:TTGGTTAGA ref:0:5:GCACTACAGATGCCGC 4 9129 +TACAAGGGGGCCC ref:0:13:AATACAAG ref:0:13:TTCTGAGGATT 6 42705 +GCAATAGCGATT ref:0:12:TTCTGCACCGAGAAA ref:2:10:TCACAA 7 10030 +CGAAGC ref:0:5:ATGCGCGCTTACAA ref:0:5:TCCCCA 5 360 +CAGTCGTCCT ref:0:10:GTTAATCGCCTTG ref:0:10:C 3 128 +TTC ref:0:3:GTTAAGTTTCTG ref:0:3:CAGGCGATGGCACGC 3 390 +AAAAGC ref:0:6:CCAAGACTA ref:0:6:CCTTTGTAAGA 5 2806 +CAGACTAAG ref:0:9:AGCTACAAGGGGCC ref:0:9:GCCTCACGCCATA 2 576 +GACAGTTTAGAGTA ref:0:14:TACTC ref:0:14:CACTCAA 10 10032 +TGAATACGGG ref:0:10:GACAACGCCTCAAA ref:0:10:G 4 180 +GCAGTGCT ref:0:8:TA ref:0:8:GTTCG 5 232 +CA ref:0:2:TCTAGC ref:0:2:G 1 3 +TTACCCT ref:0:7:GATGGGC ref:0:7:GAGGCCTGACCACC 6 10485 +TCG ref:0:3:CCTCGAACTGCG ref:0:3:CATCTCTAC 4 119 +AGTTT ref:0:5:GCGCGTGATAA ref:0:5:G 2 73 +TCTGTCACCTTGTC ref:0:14:CGTTGTAGA ref:0:14:TTTGTGCGATCTG 5 672 +CACGAAC ref:0:7:GGCTAT ref:0:7:CCAGGTTAGGGCG 4 9240 +AAAATGTTCCG ref:0:11:ACGCTTAA ref:0:11:TCGATCCAC 6 2240 +GTGG ref:0:4:AAATTGAGCGCACATC ref:0:4:TCAG 2 116 +TCAGTTCAGC ref:0:10:A ref:0:10:CTACCTA 6 114 +GAGAG ref:0:5:GTGAGAA ref:0:5:TACG 2 96 +CTA ref:0:3:AC ref:0:3:GCGTAGTCATTCTT 1 6 +GCCG ref:0:4:TTTGCCGCTCGCGCT ref:0:4:GGTCAGACAAAT 4 399 +GCGCA ref:0:5:ATTAAC ref:0:5:ACTGCTGGCATTCGG 4 336 +CGC ref:0:3:GTGATCACATTT ref:0:3:AAACGCT 2 10 +ATGATTACCGCTT ref:0:13:GAGTCCA ref:0:13:TATCGTCGGGGCAGCC 6 660 +TCG ref:0:3:TTGAACTCA ref:0:3:ATTAC 3 34 +TAATA ref:0:5:AGTATACAAACCGA ref:0:5:C 2 702 +ACTAATAAAACCAG ref:0:14:CGCTACTAGTATTTTA ref:0:14:GGTAAGT 9 2239074 +AC ref:0:2:GCATTAGGCGA ref:1:1:TT 2 6 +AGTA ref:0:4:G ref:0:4:TAAG 2 5 +AAACGGCA ref:0:8:CAGTCGCGAA ref:0:7:C 3 238 +TACAG ref:1:4: ref:0:5:GAATTAACGTCCC 1 6 +A ref:0:1:CCAACGT ref:0:1:GCAGGCGCCGACCC 3 4 +GCC ref:1:2:AA ref:0:3:CTTAGGAGTGGG 3 612 +ACTGCT ref:0:5:CCA ref:0:6:CCGGCCG 2 55 +TACGCCAAATC ref:0:11:CCAGTAGGCACAAT ref:0:11:ACTGCCA 2 48 +GGC ref:0:3:G ref:0:3:CGCTATGA 1 10 +AGAATAACAC ref:0:10:GAGCCCTGAGCAGTG ref:0:10:TGTTA 4 8192 +GGGTTTGG ref:0:8:AGGGGGGCGACGCA ref:0:8:CAATATGTC 3 121440 +GTGACAGATATTTG ref:0:14:ATGGTAT ref:0:14:TTCT 8 228 +A ref:0:1:TCCTG ref:0:1:AACGCCCAG 3 18 +GATGC ref:1:4:TAG ref:0:5:TATTT 2 40 +GCTTCCACGACAT ref:0:12:AACGTTG ref:0:13:AAAAAAC 7 8064 +TGT ref:0:3:ATGGTGTTTCATGGC ref:0:3:TAATATTTA 4 612 +CTTAGCGCT ref:0:9:AACCATACGCGTG ref:1:8:ATTCTGACCAGG 4 1722 +CAATATG ref:2:5:CCGCAA ref:0:7:A 3 3 +ACT ref:0:3:AAGTGCTCGAGTC ref:0:3:GTAGCGGGTCTGC 4 18 +TG ref:0:2:GCTTTGC ref:0:2:AGCGTACCCA 3 36 +ACCG ref:0:4:TGCTTTGTT ref:0:4:TGGGGAGTT 5 18 +TTC ref:0:3:ATGTTACATCAC ref:0:3:CCACCGTTAAGAGAA 5 120 +GCATGC ref:0:6:CCGA ref:0:6:C 4 30 +TTGCA ref:0:5:GCTAGAACCTAGGCGC ref:0:5:AATAC 4 247 +AAGA ref:0:4:AAACCTAG ref:0:4:TGT 2 120 +CGGTTGCTAG ref:0:10:AATCCT ref:0:10:AGCCATAC 7 6880 +GCAACG ref:0:6:TCAACAGTGTTC ref:1:5:ATTCGCCCA 1 16 +CT ref:0:2:GACCTC ref:0:2:CTGCGCTTGCAA 3 14 +TACATATGTCG ref:0:11:GTTT ref:2:9:GTCATA 4 8 +TCATTAT ref:0:7:AGGG ref:0:6:CGGCAAGGAA 5 8385 +CCCTGTT ref:0:7:CCA ref:0:7:AGGAAAC 5 5856 +GTCCCTACGATGCCT ref:0:15:ACCCC ref:0:15:TCCTC 9 1260 +CTGCGCT ref:0:7:GATCAGGCGG ref:0:7:AAACGTTGTCA 4 3569 +ACATAGTCTAA ref:0:11:CAGCGTGAC ref:0:11:GGCCGC 5 128 +CCCT ref:0:4:CAATCAAGGGTAACC ref:0:4:ATCTTAAGT 6 1120 +ATTACCGA ref:0:8:GATCGGAG ref:0:5:CCCTTCTGT 2 40 +AAACCCCG ref:0:8:AGCAAAGCAGGTA ref:0:8:ATTTCTCTTA 4 422912 +TA ref:0:2:TGTGACTC ref:0:2:G 1 6 +CCGGGGC ref:0:7:GCCATGTGCATGTGCA ref:0:7:ACATAGAGTT 4 522 +AAACT ref:0:5:AGG ref:0:5:GCGTGACTTGAT 3 2976 +GCTATTTCGCCTGAGT ref:0:16:TT ref:0:16:CAAGACCAGAGGAC 6 1470 +GAGAGTCTCGC ref:0:11:GCCGGAGACA ref:0:9:C 6 566 +TAGGACGAC ref:0:9:ACATAATGTGTAC ref:0:9:ATCATTGAAG 5 861 +TCGG ref:0:4:AGC ref:0:4:TTCGC 2 78 +TTGC ref:0:4:AGTATCG ref:0:3:GGAGAGAA 3 70 +GGTTCTGAGG ref:0:10:TCCGATCCAGAGAT ref:0:10:A 4 535 +CTGGTTTGCCTTT ref:0:13:TCCCGTAGCTG ref:0:13:CCGCC 7 22680 +TGGCTAGATGTGGT ref:1:13:GTGGTGTCAGC ref:0:14:AACAAC 4 6230 +TAACATT ref:0:7:CTCCG ref:0:7:CTGTGGAAAACGT 4 2754 +TCGCAC ref:1:5: ref:0:6:TATCAGGGGTTAG 2 72 +TGTATAATGG ref:0:10:AGATTGGATTAGA ref:0:10:ACACCCAGCT 4 5410 +A ref:0:1:GGGACG ref:0:0:GTT 1 1 +ATAG ref:0:4:C ref:0:4:CTAACGCAG 2 105 +CGTCGCCTCGGCA ref:0:11:GATCGCGCCAACG ref:0:9:GGGGAC 4 8600 +CCA ref:0:3:CGAT ref:0:3:ACAC 1 12 +CAGCCA ref:0:6:TGGG ref:0:6:GATTGTAAATCACTCT 3 2048 +GGTTGGCAC ref:3:6:GTCCGGCGGGTCG ref:1:8:CGGG 1 5 +TGTCCACC ref:0:8:GACGATTC ref:0:8:CGTAATACGA 5 5336 +CACATGAGAAATGGGC ref:0:16:TG ref:1:15:CGA 11 56 +ATTCAG ref:0:6:TTTTCTCATT ref:0:6:CGCCTGCCCCCAGC 2 15750 +TGAGATGGACATC ref:0:13:TACGT ref:0:12:GCGGTATT 6 4800 +CACAGTCG ref:0:8:TTGTTCTCAC ref:1:7:TCGTGATAAAA 2 4 +GGAAGCTGATACC ref:0:13:CGAATAGGAGTCGA ref:0:13:ACCTCATTCCGAATA 5 13440 +CCCAGATGCGCGT ref:0:13:CTAGATTAAAGTG ref:0:13:TATTTCTAATTTC 8 1215216 +TACACACGTGAGTAAG ref:0:16:GTCG ref:0:16:A 12 192 +CTGGAGGTAT ref:0:10:GCGAGAATA ref:1:9:GC 4 912 +TGGTACTAA ref:1:8:TACATGCCA ref:0:9:AAGGAATAACCTATC 2 288 +ACCG ref:0:4:AGTTTTAG ref:0:4:GATC 2 90 +TTGTATACGGA ref:0:11:C ref:0:11:TA 8 11 +TTTATGAGCAAGC ref:0:12:ACGACCCGG ref:0:13:GTATAAA 3 564 +GCCCCAA ref:0:7:A ref:0:7:GTTAGGTAGAAG 4 2212 +AGGTTACATATTTACG ref:0:16:TAAGAGCTTCGACGGG ref:0:16:GGCATCGG 7 6510 +GCTAT ref:0:5:GAGCGAGCGAGCGA ref:0:5:AAG 4 2304 +ATTGGCCGT ref:1:8:C ref:0:9:AGAAATGGAGGGGGTC 2 5220 +GGTGATA ref:0:7:CGCCCCCA ref:0:7:AATGGG 3 690 +CTCACCA ref:0:7:CAGCCATTGCACT ref:0:6:TGCGC 3 776 +ACTAAGCAGAGGAGG ref:0:15:TTCGA ref:0:15:GCAGACCA 8 168 +GAT ref:0:3:TGTCC ref:0:3:GGACGTAAC 1 2 +TTCTGTGT ref:0:8:TAACACAATGTG ref:0:8:ACATGACGCC 4 270 +AGAAAAAGCCTCGG ref:0:14:GTCATACCCAGATT ref:0:14:TCAGAATT 6 30240 +TGCCAGGGGAAGT ref:0:13:GACGAC ref:0:13:AGGCTAGACACTCT 7 69300 +TAGA ref:1:3:AAAGGTGCGAATCG ref:0:4:TACTACAAGTATAACG 6 504 +TA ref:2:0:TC ref:0:2:GATAAGCACTTAGTG 1 6 +ACCGC ref:0:5:CATAACCGCAAATCA ref:1:3:GAATTATTAA 4 6 +GAACCATA ref:1:7:ATTTCGGCA ref:0:8:GGCGTCTCACT 3 400 +CATACCCATCCCGCCG ref:0:16:TTTGTATACCCGGTTG ref:0:16:CAGCACAAA 6 49988445 +GTTACGGATCGTC ref:0:13:G ref:0:12:CGACAACAAAAAA 7 560 +ATTACGTGGCCTGGT ref:1:14:ACAAGGAACGGA ref:0:15:TTCA 6 3330 +AGTCCGACGAGGCCAT ref:0:16:GCGATG ref:0:16:TAGAGGTTGGC 8 10664 +GTCTA ref:0:4: ref:0:5:ATTCTT 1 15 +TTGGAAACGT ref:0:10:CGTGACCGTGCCTGGA ref:0:10:GACGAATG 5 6534 +CGTTGA ref:0:6:ATACCCT ref:0:6:AAGG 4 78 +GAG ref:0:3:TCAA ref:0:3:ACT 2 30 +TCTGGCTGCATAG ref:0:13:ATGAGTCACGA ref:0:13:CCAGCT 2 56 +GACAATTAGT ref:0:10:CATG ref:0:9:TAGAAGGTGA 3 300 +AGGCAGCA ref:0:7:CAAAACTAAGGTCT ref:0:8:TCATTGGGGCTAGCGC 3 2400 +CAGAGTCAGATTGTTG ref:0:16:ACT ref:0:16:ATTCGTCACAAG 8 3168 +CTGGCCTA ref:0:8:ATAACTGTT ref:0:8:CAGCTCTGCTAGGCC 4 847 +ACCCAACACGCGATG ref:0:15:GT ref:0:15:CACT 10 52 +GTCCACGGA ref:0:9:GGCTGGTACAA ref:0:9:AACCC 3 1770 +CCT ref:0:3:ACCGATCTGGGGATTC ref:0:2:CCAACCG 3 60 +CGATCGTG ref:2:6:CACGAGATA ref:0:8:ATGGCATAT 4 282 +CTTCTCCCAGGGCTAG ref:0:15:CGAAT ref:0:16:GGCACACCCAGA 7 6210 +TGAGGTGTTATGCAG ref:0:15:AACGCC ref:0:15:CTCTA 10 2097 +GCTAAATCCC ref:0:10:TACAAAGTATAGC ref:0:10:AGGC 6 49625 +AACCATT ref:0:7:ACTTCCGTCGG ref:0:7:TGC 5 2620 +TATCCTCCCCACACT ref:0:15:TTTAGGGTTTAAG ref:0:15:ATGTGATCG 9 18468 +CGCGTTC ref:0:7:AGTCAAGATTT ref:1:6:CTATG 1 16 +TCACCCCGA ref:1:8: ref:0:9:AGACTGCAACCGCCTG 1 2 +G ref:0:1:GCTAGAAGTCTTC ref:0:1:CACA 3 15 +A ref:0:1:CGCAGGCTC ref:0:1:ATTGACCACTGTCG 5 3 +CTGGTCCTCGGC ref:0:12:TGCA ref:0:11:AGCCAGTTCACAGGA 4 17808 +A ref:0:1:TGC ref:0:1:TTAATTCCCA 2 12 +GTCATCCGC ref:0:7:C ref:1:8:A 4 3 +GGCAGAATCCG ref:0:11:GCGAA ref:0:11:GACCGTCGTC 3 76 +GACTCGGCCTCC ref:0:12:ACGTCCTG ref:0:12:CTGGAGATGATGCAAT 4 1116 +GTTCCAGATACCAATC ref:0:16:ACCATCTTCATGTA ref:0:16:TTAGTTCTTTAGAA 8 41480 +CACAGACCCCTCCTAA ref:0:16:CGGATATCA ref:0:16:GGTAGG 11 74400 +GATA ref:0:4:TGC ref:0:4:ATATG 2 7 +CAGACAGTTA ref:0:10:CCCCACGTG ref:1:9:GACCCT 5 5625 +AAAGGATGTATCA ref:0:13:GACTGGCT ref:0:13:ATGCTGGTTAAT 7 34398 +C ref:0:1:GGG ref:0:1:TAAGATACTACCCT 1 16 +ATTAGGCTCCA ref:0:11:GCTTAGTGTCTCACC ref:0:11:ACC 2 126 +TAATCCGGGGCCGTTA ref:0:16:TGCTCGTAT ref:1:15:AC 8 192 +CTTCGAACAATTA ref:0:13:CAAGCGCCGTTGAGT ref:0:12:TGGACGCAA 4 10098 +ACTACACCCCTT ref:0:12:TCT ref:0:12:CGTTCCGACCAAG 5 11000 +ACGACATTCAG ref:0:11:TGGCTC ref:0:11:TTCCCT 7 1656 +TAC ref:0:3:TAGTCCAC ref:0:2:CCGAT 2 25 +GAGACGGGAAG ref:0:11:AACCGGGTATCTTA ref:0:10:CCATAT 4 18 +GACA ref:0:4:TGGGAC ref:1:3:C 1 3 +CACCAAAAGC ref:0:10:GGTTCT ref:0:10:GCTTGGCCG 6 50 +ACAAGCGGGATGACA ref:0:15:AACTCGGCGTTTG ref:0:15:TGGGGGCGGCCG 7 634110 +AAGTGCT ref:0:7:GTCAAGTTATAT ref:0:7:GGTCTTGGGCTG 3 1368 +G ref:0:1:AATC ref:0:1:TGGCCGGAACTTG 3 25 +CACGCGACA ref:0:9:GCTACTTGGCT ref:0:9:TTACACGGAATT 2 2 +CACCTACACTCT ref:0:12:TATCGTGGGTAGAAC ref:0:12:GATGCAT 5 3072 +CTAT ref:0:4:AACC ref:0:4:TGACGTTCCCTTCCC 3 522 +ATCTA ref:0:5:GGAAGACTCGTAGCT ref:0:5:CGG 2 18 +GCCCAGTAGGACATTA ref:0:16:AGGCGAG ref:0:16:CC 10 366 +GCGATTAAT ref:0:9:TTG ref:0:9:CGTTAGCAGGG 4 24 +CATC ref:2:2:GGTTCGG ref:0:4:TGTAACG 2 40 +TG ref:0:1:ACGTC ref:0:2:GCCTGT 1 1 +ATATCCAA ref:1:7:CTAGATCGCAGATTC ref:0:8:GTATCT 1 28 +TTTC ref:0:4:GTCTATT ref:0:4:AGCACGCGCTATGG 4 210 +TTCGGG ref:0:6:ACACGTCCGTTGGGT ref:0:6:TCTGT 3 1664 +GCACGT ref:0:6:CGAAACCGGC ref:0:6:CAGTCGTAACCAG 4 475 +TCTAA ref:0:5:AGACGGGAAAGGAT ref:0:5:AGACCATTAACGA 7 6384 +AAAG ref:0:4:CCCCCCTCAAGCTT ref:0:4:CATAACTGGGTAGTCC 4 77 +ACTTG ref:1:4:T ref:0:5:GGTCTT 1 8 +CTATTTCTT ref:0:9:AATCGA ref:0:9:GAGTCGAACC 8 82710 +TAGACCATGCCC ref:0:12:GTACAGAATAAAGCGG ref:0:12:ACGCCATGGAC 3 320 +ACAGATCGGTGCTGG ref:0:15:TCCCTCACGGGTACAA ref:0:15:TCATTGCTA 7 184380 +ATCGAGTA ref:0:8:GTTGCGACTCT ref:0:8:CGAGAGAAC 2 1000 +GTAGCG ref:0:6:A ref:0:6:ATATCCTGCACATA 2 30 +C ref:0:1:TACGCCGCATATTTT ref:1:0:GAATATGTAAA 6 4 +CGCAAT ref:0:6:CTTCCGACAGAAG ref:0:5:GGACCGTTAAA 2 861 +AAGT ref:0:4:GATTGTCCA ref:3:1:AAA 1 20 +ATTAGATCT ref:0:9:CTAGGAACC ref:0:8:TAT 2 440 +GTGCTGACATGTC ref:0:13:CGGAAG ref:0:13:GCCTTTAACCCTAATA 4 76080 +TTGGAG ref:0:6:TCGCCAGCGAA ref:0:6:GAAAATTA 1 73 +ATCAGCACTACG ref:2:9:CCAGCCCGAACC ref:0:12:GTGTCACAATCCCC 3 86464 +TCGCACGATCAATT ref:0:14:GGGCACATTTAACG ref:0:14:GATT 6 4810 +TCGTCTTAC ref:0:9:CGCTTGACGA ref:0:9:GTCAAAATGT 1 1 +TCGGGCTCTCGTG ref:1:12:AGCTACTAA ref:0:13:GCGAATATAT 8 99792 +TTAT ref:0:4:GAAG ref:0:4:G 4 105 +AGTGTA ref:0:6:G ref:0:5:CATATCTAGTGGC 1 56 +AATACATCTAGAGCG ref:0:15:TCCTT ref:0:15:CCGCACGCCCTTGG 7 72 +TC ref:0:2:CAACTGAGAGTA ref:0:1:G 1 30 +CG ref:0:2:GA ref:2:0:CCTAAACTTTA 1 1 +CTCCATAGTGAG ref:0:12:ATTTG ref:0:12:AGGTTA 7 336 +AAAGGATCGTAGAAG ref:0:15:A ref:0:15:ACCCTCCCAGGT 9 8673 +AAAAGCTCGTGCC ref:0:13:ATTCCGGTTTGACTAA ref:0:13:GCGTGCCACCCA 6 56160 +TTGATCAA ref:0:8:ACA ref:0:8:TGCAAGG 2 4 +GTAAAAT ref:0:7:CCTAGCC ref:0:7:CCCAATTTT 5 157320 +AGAGTC ref:0:5:TAAAGATAA ref:0:6:TG 2 56 +GTCGATGCTCTGT ref:0:13:GAGA ref:0:13:CCTACGTC 5 21 +TCTTGATGCT ref:0:10:CGTCTGAACTCGGAGA ref:0:10:CTTCAATGTGT 4 9324 +TGGAGAGCCTGGC ref:0:13:ACTGTAGGAA ref:0:13:ATTA 10 32494 +CG ref:0:1:TTTGTGGGCATAATA ref:1:1:TGTAAGTACC 3 2 +G ref:0:1:GAAGCGGCTCATAC ref:0:1:GCGGCATATCAGG 8 20 +CT ref:0:2:GGTGT ref:0:2:A 1 24 +TAATGC ref:0:6:T ref:0:6:AATACTCA 2 26 +AACTAGGGCAT ref:0:11:ATAGATTCGGGTA ref:0:11:ACTTAATCCTC 5 35280 +CAGTAAT ref:0:7:G ref:0:7:AAGAATTCTACAGCTA 1 9 +AGTAACACGTGC ref:0:12:G ref:0:12:TATTATCCAGGTT 5 1488 +A ref:0:1:GTTTCAGA ref:0:1:CAGCGGGATGTTCCC 3 4 +ATGCGAGATACGCC ref:0:14:TCTCT ref:0:14:TT 10 7 +GGGTTAT ref:0:7:CTAA ref:0:7:ACACG 6 2759 +CGGTTAGACACGA ref:1:12:TGGAGAGG ref:0:13:GCTACT 4 1990 +TAGAC ref:0:5:CGTGGGCACA ref:0:5:CTGAAGTATTCCT 2 24 +GAAAT ref:0:5:TCCGCCCAAAGGCAC ref:0:5:CGTTTTATT 1 588 +GGACTGGG ref:0:8:CTAGATCGCTGGAT ref:0:8:CGCTTGGGGTACTAT 4 1560 +GGAG ref:0:4:GGGAGGGCTCC ref:0:4:ACTCGTGACCAGCC 2 18 +TACGACTGCT ref:0:9:CT ref:1:9:CGTGGTTCTTATGTT 3 272 +GGGGTTTACC ref:1:7:CAATAGTGCGT ref:0:10:CAGAAGTTC 4 504 +ACGTGTAAG ref:1:8:GGCCCTAAAA ref:0:8:GAAAACA 4 1290 +GG ref:1:0:CT ref:0:2:TG 1 3 +GA ref:0:2:TTAC ref:0:2:GTCGCAAATT 1 18 +TCGT ref:0:4:CACCGTG ref:0:4:T 1 16 +GAATCCTGCAA ref:0:11:AA ref:1:10:G 7 6 +GGAAGATTTGTATC ref:0:14:ACTTCTCGACTT ref:0:14:TTAAGACCC 7 18720 +AGCGCTCTCGAA ref:1:9:CCCGGTCCCGG ref:0:12:TTCGCCGGACGACG 4 32256 +GGTCGGTCTA ref:0:9: ref:0:10:GGTCT 4 9 +TATCGAAGCCTCACAG ref:0:16:C ref:0:16:T 14 15 +GGTTAC ref:0:6:TT ref:0:6:TATAGTCAG 2 1 +T ref:0:1:CGAG ref:0:1:CGCGCGCGAATCAGC 4 5 +GGA ref:0:3:TTGAA ref:0:3:AG 1 36 +TGTGC ref:1:4:CAAAAGGCAGATTC ref:0:5:ACGATCAATTGCCA 5 684 +ATACTTGTTCGCG ref:0:13:GTATAGCTCA ref:0:13:GAGTAAG 8 28658 +TTTACGGTA ref:0:9:GCCCAATAA ref:0:9:ATCGGCG 4 73472 +ATGTCAACT ref:0:7:TC ref:0:9:GG 4 20 +TTAGACGC ref:0:8:GTGTAGTGCTTGCC ref:3:3:TGGTGACCAT 3 48 +ATACGCATAACT ref:0:12:T ref:0:12:GCGCCAC 6 132 +TTATGTCCTTTGA ref:0:13:CCTTTACGATTCC ref:0:13:TGC 6 126 +GTAACGCATTGTGC ref:0:14:AGA ref:0:14:TGGCTTTCCT 5 36 +GCTTGACGCTGCC ref:0:13:TGTAAAGAGCTCGCT ref:0:13:AGTGACAATCACGC 5 5232 +CA ref:0:2:TGGCTGTCTCGC ref:0:2:TAGCTTGACGTG 7 18 +TTTTCA ref:0:6:GG ref:0:6:TATAGAG 5 1568 +TTCGACTTGAA ref:0:10:CAGATGCCATC ref:0:11:TAACGGCGATAGTG 3 86 +TC ref:0:2:TATCATAGCATC ref:0:2:CCTTCATG 4 18 +GGTTTCGA ref:0:8:AGCAGTTT ref:0:8:ACAGGCTACTGCC 3 77 +CGTGTAT ref:0:7:GC ref:0:7:AAAAGGACTACCAGA 4 737 +ACGCGGGTGACG ref:1:11:GTTG ref:0:12:TC 7 42 +CGCCTCTTTT ref:0:10:GAGTGTTTTTGAGC ref:0:10:CC 2 822 +CCCAT ref:0:4:TTAGCC ref:0:4:AAACG 3 357 +TCA ref:0:3:TTATCAAATTTGATTT ref:0:3:AGGAACAACC 2 144 +GT ref:0:2:GTCCCGAGATACATA ref:0:2:TA 1 7 +GGGACGA ref:0:7:AGTGTCTTG ref:0:7:GTAGCACCTTAA 4 1056 +CCGATTTCTCG ref:0:11:ATGAGTT ref:0:11:ATCCGCGAATT 7 4288 +TCA ref:0:3:TTCCTATGGCCTGT ref:0:3:ACGAACTTA 3 60 +TT ref:0:2:AT ref:0:2:GCTCAACG 1 27 +GCAAAGCCTGGTCA ref:0:14:T ref:1:13:AGGTTC 8 72 +TGCCTACATA ref:0:10:GGCAGACA ref:0:10:TCATCGG 4 7548 +G ref:0:1:TGATTGACACCTAGTG ref:0:1:GAATCGTCCACATG 9 12 +TTGCAT ref:0:6:AGGTCCCTACGAACCC ref:0:6:CCGCGGG 4 2460 +TATATACAATTTATT ref:0:15:GCCAACCCGCG ref:0:15:GTTATTAGTCATGGG 10 334455516 +GACGTC ref:0:6:TTAA ref:0:6:C 4 76 +AAGTACCAACT ref:1:8:CAGTGGCGGAT ref:0:11:TGGTTAACTTGGCTG 4 166320 +T ref:0:1:TTATAC ref:0:1:TCCGTGAG 2 6 +TTTATT ref:0:6:GAGGTAGGTTGGGA ref:0:6:CGGGAGGAATCGAAGG 10 95920 +ATCTTCA ref:0:7:CTCAC ref:0:7:GGGGTCTCCTG 3 200 +G ref:0:1:CCACCACCTGCGT ref:0:1:TA 1 6 +CACAG ref:0:5:GTTTGTCATCGTCC ref:0:5:AC 1 1 +CGTGGGGGTCC ref:0:11:CGCGTAGGAGCTGA ref:1:10:TACCGACTCAGAA 8 1671488 +CCCGGACGT ref:0:9:TTCCTACGATCA ref:0:9:GGCGACAGCATC 4 624 +GCCGCC ref:0:6:T ref:0:6:ACA 5 266 +ATCACCACTAG ref:0:11:CATT ref:0:11:GCT 8 528 +TAACTGTATGGCA ref:0:13:TGGCTATAA ref:0:12:CGAAG 6 1008 +ATGAATATGCT ref:0:11:TCGAATATCCAGGGGA ref:0:11:T 3 224 +CAC ref:0:3:ACTTCAGGGCG ref:0:3:GGAATT 1 48 +TTA ref:0:3:GAGTTACGTCTTT ref:0:3:ATTGAGTAC 4 4 +TCTGA ref:0:4:ATAGG ref:0:5:G 2 15 +CGTATAGACT ref:0:10:GCGCGC ref:0:10:ACCAATGACCCCCC 4 1785 +A ref:0:1:CT ref:0:1:CCTTCGATGGTCA 2 6 +AAGGCAT ref:0:7:GGCTCCCTCTTC ref:0:6:GTAAG 1 114 +TCAGTTGTGT ref:0:10:TGA ref:0:10:CGTTTTC 3 29 +CGTCAAGGACAA ref:0:12:AT ref:0:12:TGTGTGTAGCTA 6 150 +TTAGTTAGGCTTTTA ref:0:14:CACGC ref:0:15:AGAGCATGG 9 7524 +GACACC ref:0:6:CCCTCTGCGATT ref:0:6:TGTCAGCTCGG 4 88 +TCAGGTGCAC ref:0:10:TTGATA ref:0:10:GGGGTCGG 4 7920 +TGTGACTA ref:0:6:GATTGTA ref:0:8:ATAG 2 5 +AACGATTGG ref:0:9:G ref:0:8:AAAAACCGTGCCA 2 120 +GATCTACTTTGC ref:0:11:TATTCGT ref:0:11:CGCCAGCTTTTTTGG 2 7920 +GTGGGGCGTGGTG ref:0:13:CGTTAC ref:0:12:TGGTGTGATC 5 219 +GA ref:0:2:CACCATGCCTGCCGTC ref:0:2:CT 3 156 +TC ref:0:2:TGGTCCATGCGAC ref:0:2:AGTCTCC 4 50 +TTGACGCGTAT ref:0:11:TGCATTTATGGAACG ref:0:11:CCCGAA 5 25152 +TAAAAGGTGTGGG ref:1:12:CGGAGCCGGCCT ref:0:13:GATT 7 4879 +CCTTGCGAC ref:0:9:GA ref:0:9:ACG 6 26 +GAATACG ref:0:6:CCAAAATAA ref:0:7:ACTACGCCAGCGAT 2 2112 +CTAAATACTAGTGAG ref:1:14:ACCCCCA ref:0:15:GGGT 8 2842 +G ref:0:1:AGTCTAGTTCAA ref:0:1:AGACG 3 4 +GCA ref:0:3:TCGT ref:0:2:AGTGCC 1 36 +CTACGGGGAGTCA ref:0:13:GGCCAAATTCAA ref:0:13:TGATTCCAATCATGC 6 29120 +GTACTAGT ref:0:8:AGCCGGGAA ref:0:8:ACATGAG 4 400 +GCGCGCGT ref:0:8:G ref:0:8:CTATGCATGACA 3 12 +CC ref:0:0:GTATATTTT ref:0:2:AGTGCAACCCCTG 4 10 +CTACTG ref:1:3:GGATCGC ref:1:5:AGTCAACT 2 20 +GTTTAA ref:0:6:CTAAAAGGGACT ref:0:6:A 3 340 +ACTTACT ref:0:7:GTACG ref:0:7:AAATCTGTCTTCC 1 84 +GTTGTCTAATCAC ref:0:10:GTC ref:0:13:TATGGA 5 176 +TAATCGTGGGACAGCC ref:0:16:TGGGA ref:0:16:TGACTGCCGGTT 8 21564 +CAGCCGTTGACCG ref:0:13:GCAAGGGTTGA ref:0:13:AGT 5 40 +GTGTTATAGTGC ref:0:12:TTAAGGGACAC ref:0:12:CTACTTCCAG 4 5184 +TATTAAAGAT ref:0:10:CATCACCGCGCA ref:0:10:GAG 5 5148 +T ref:0:1:TCT ref:0:1:AATGTCAAGA 1 4 +GGTC ref:0:4:GAT ref:0:4:ATATTGCG 2 108 +TTCAAA ref:0:6:CCCCT ref:0:6:GAGCGCCGAGGA 5 82209 +TGT ref:0:3:GAGGTATGTG ref:1:2:CAGACGAACTGAA 2 4 +CGTCAACGG ref:0:9:CCCAG ref:0:9:TCGTATGATCT 1 75 +CCGCGGGGCTA ref:0:11:GTATCGTCTTGCG ref:0:11:AAC 7 47783 +TTGTAGG ref:0:7:AGACTTTGC ref:0:5:ACTATATATTAA 3 150 +CCAAGATTCCCAAAC ref:0:15:ACTATGCA ref:0:15:ATGGGA 11 2448576 +GTCGTTCA ref:0:8:AA ref:0:8:ATGTTTCAC 3 63 +TTTTAC ref:0:6:GATGGACGCGGG ref:0:6:T 3 448 +CGCAAT ref:0:6:AAAAGA ref:0:6:CTACGGTCCGGGCC 3 79350 +ATTTA ref:0:5:GCTTTGGTATC ref:0:5:T 1 39 +GATTTGTATA ref:0:10:TAAG ref:0:10:TTGCCG 6 444 +TCCC ref:0:4:GTCACT ref:0:4:CTACTCGCTGTCCAA 1 70 +TAGCTAGA ref:0:8:GC ref:1:7:GGAGACGCGTA 2 20 +TAACCTCGGCG ref:0:11:CGCAGATT ref:0:11:CGGAGTTAGTAA 9 408 +AAGTCTAAAG ref:0:10:AGGTTTA ref:1:9:GAGTCGCTACT 4 2850 +CGCGGTCTC ref:0:9:TTA ref:0:9:AACCGTAGCATCGT 2 8 +GACCCTGGG ref:1:8:TCCTCTG ref:0:9:GGTCAGTACGCG 4 5772 +ACCTGTCTCCTGAG ref:0:14:GACCGTGCCTACCTCA ref:0:14:CAGTATACA 4 360 +C ref:0:1:CGAGGCGTCG ref:0:1:TAGCATGGTTC 5 6 +TCACACCGTTTCTCAG ref:1:15:CGAGCTCGCGG ref:0:16:TTATGACATTC 7 430353 +CTGATACATTCTACAT ref:0:15:TTCATCGAC ref:0:16:C 7 16 +TAACATGATCA ref:0:11:CAGGCATCCCACCT ref:0:11:AATGACGAGCGCCAGG 5 4338 +GCTGATTCC ref:0:9:ATCTAGTGCGCTTCT ref:0:9:TAAAAATTTTGC 4 104940 +AAACGTTCTCCG ref:0:12:CATAAAGGAA ref:0:12:ACGTCACC 2 60 +CGAGC ref:0:5:G ref:0:4:GCCTTGA 1 4 +ATTTTCTACGGACAG ref:0:15:GGT ref:1:14:CCGGTACGGG 8 84 +CATGTCTA ref:0:8:AGAGTGG ref:0:8:GCCCGCGCTAAAC 3 28296 +CGGTGCAGCCCC ref:0:12:TTCATCCGGTGT ref:1:11:TCCCTTTCCTAG 7 525 +GT ref:0:2:C ref:0:2:ATATGGGCCGCGA 2 108 +G ref:0:1:CTCCATTATGGACGCG ref:0:1:TAAC 4 20 +ACCACGCCTTCGC ref:0:13:ATTAGGA ref:1:11:CTAACCGTC 5 4500 +CATGATGTTAAAGAC ref:0:15:GAGGCA ref:0:15:TGATCGCTACGTTAA 6 368 +GCTCCCAT ref:0:7:CTGAGTCAG ref:0:6:GCCCGCTTGCCTCG 2 360 +ATACCAACTAGG ref:0:12:GGATTGACGGG ref:0:12:AACGC 6 6944 +CTGA ref:0:3: ref:2:2:AAGGC 1 8 +CCCTGGTCGCCTGC ref:0:14:GTGTAGGAAACC ref:0:14:TCAGG 8 712 +GGCCGGCTCGTCACA ref:0:15:ACCC ref:0:14:GTGTGGAGTCTCAT 5 3360 +CTTTCGACGTTCTT ref:0:14:CGTGTCC ref:0:14:GCAATCGCAC 8 12540 +ATTATGAAGTATCTAG ref:1:14:TCTGCTTCGCCT ref:0:15:AGAACCGCGTGAC 5 540 +CTACTTGC ref:1:6:C ref:0:6: 4 1 +CGGACGCCCGG ref:0:11:TAATCACAAT ref:0:11:AG 7 16467 +CAACTAC ref:0:7:GAGCT ref:1:6:CGTGGTT 3 133 +TGTGATTGGGGACCA ref:0:15:TGTCGCGCAAGCC ref:0:15:ATCACTTTG 6 195216 +CAGTTCCAAAA ref:0:11:AAGATGT ref:0:11:TTATGA 5 45 +AACACAGTCAT ref:0:11:TTAAGA ref:0:11:CATTACA 5 266 +CGATCATTGAAC ref:0:12:TGCTTTGCAG ref:0:12:AAAGTCGCGATCGAG 6 61608 +T ref:0:1:TATAATCCATAGG ref:0:1:CTACCCAG 5 4 +ATACAC ref:0:6:GTAGGAGA ref:0:6:AATGTTATCT 3 2622 +AACC ref:0:3:AAGATTCGAGGGT ref:0:4:GCAGTGCTCCG 3 69 +G ref:0:1:GCTAAGG ref:0:1:GATTCG 2 6 +ACAGGTTC ref:0:8:GATTCGGGGT ref:0:8:CAAGGGTTTCACGTCT 2 2700 +ATTCTAGCG ref:0:9:GTACGA ref:0:9:CTTGGAA 4 100 +GGA ref:0:3:AG ref:0:3:CGACAA 1 56 +C ref:0:1:ATAAGTAGGTTG ref:0:1:CGCCCATTGAAGC 5 65 +ATCGAAAA ref:0:8:TGCCCCTTGGCT ref:0:8:CCTTGAT 8 28000 +GGGTCAACG ref:0:9:AAGACTGTTCACTCT ref:0:9:TCGGTAGAA 2 12512 +AAGACGTTACG ref:0:11:TT ref:0:11:TTCCGG 7 6 +AACCCCCGATAT ref:0:12:TAATTG ref:0:12:AGAGC 8 184 +ATGCAGCTC ref:3:6:CCTAACTGGA ref:0:9:CATTTGGT 1 75 +AACTTCGGACG ref:0:11:CTGGCTAGAGGTG ref:0:11:TCG 5 2640 +T ref:0:1:GGTTTAG ref:0:1:CGCAGAATC 2 3 +AAGGGA ref:0:6:AATAATCCGAACT ref:0:6:AATTCTAATGTGGGGC 5 43050 +TAAGGC ref:0:6:GACGTGAGCC ref:0:5:A 2 154 +TCTTGCA ref:0:6:ACGCTTAG ref:0:7:AGTTCT 3 126 +TC ref:0:2:TAAATGGCTGT ref:0:2:AATACCACG 3 6 +GTTTACGATT ref:0:10:G ref:0:10:CACACAAGCCTGTGA 5 602 +ACTTAAACTTTG ref:0:12:CGCAAGACTGCC ref:0:12:CCTTAT 4 756 +GCTATATTGATACG ref:0:14:TCGCCGATA ref:0:14:CTATTAT 4 40 +G ref:0:1:TTGACTCTCCCT ref:0:1:TCGGCGCA 3 3 +A ref:0:1:GGTATCTACGACCGT ref:0:1:CTGAGGGGCGA 5 6 +TGAGTCGC ref:0:8:ACACA ref:0:8:GAGAAT 2 2 +TAGACCGTCAGTTCG ref:0:15:TTTCGACCCCA ref:0:15:AGT 6 1080 +CGGACAGATA ref:0:10:TTTCGTGGGTTCCCC ref:0:10:GA 4 1230 +GAAATG ref:0:6:TT ref:1:5:AGCCTTA 4 686 +CACC ref:0:4:C ref:0:4:ACTGGT 2 18 +GAAGTTTGGA ref:0:10:TGTACATGAAC ref:0:10:CCCCGGTTGACT 3 90 +CAGA ref:0:4:AGCAC ref:0:3:GGACTACT 1 3 +CAATGCCCCATCGGA ref:0:14:TGAGTTTGTCT ref:0:15:GATCATTTTAGACT 9 606720 +GTGACTG ref:0:7:CA ref:0:7:GTGTCGCAAATAAC 3 1085 +TGTGCAGTA ref:0:9:AG ref:0:8:AGCTTGGGCAG 2 23 +AGATACGGCTT ref:0:11:GCGTGAT ref:0:11:CGA 7 91 +CACCAA ref:0:6:C ref:0:6:GAA 3 27 +AACACCAGATATA ref:0:13:CATTGG ref:0:13:C 9 63 +GCCG ref:0:4:T ref:0:4:AAATAAGTTA 4 520 +TCGGGC ref:0:6:GCCTGTAGACAAACTC ref:0:6:GTGTTGT 5 2496 +GC ref:1:1:TTT ref:0:2:TGCTACAAC 1 12 +ACGA ref:0:4:TGGAGGAG ref:0:4:ATGGTCACGGTG 5 90 +CCTCGGCGAGATTGCG ref:0:16:AAAA ref:0:16:TAATTATTCTCTA 12 88128 +AACGATCGACGTCCTG ref:0:16:TA ref:0:16:TTTCTATTTT 11 2616 +CCT ref:0:3:GC ref:0:3:AGGCAATACCCACCA 2 189 +GACACAATCGATA ref:1:12:AGATGTAGAACC ref:0:13:AGGCAGGAAAT 5 4188 +CATGAAAACGA ref:1:10:TA ref:0:11:TCATA 7 25 +C ref:0:1:TCAG ref:0:1:TGTAATCGGTA 2 1 +TACGGATAGGCTTG ref:0:14:C ref:0:14:GTGCCGAA 9 62 +GA ref:0:2:GAGTTTA ref:0:2:CTACAGTGTCCTAG 4 6 +GTATAG ref:0:6:AGGTCAAACTATGCC ref:0:6:GGGCGCGCAGTT 3 2550 +TCTGTAGTTTGA ref:0:12:TGGTGAG ref:0:12:ACCTCCTTG 4 3360 +AATG ref:0:4:TCTCATGAAGCTT ref:0:4:AAAGACGTTGCTCACC 4 300 +ACTCAAACGT ref:0:10:GC ref:0:10:CTGAACTTCGTAGTTG 4 2944 +TCATTCGGG ref:0:9:GCACGTACTCA ref:0:9:C 4 16 +AAAGA ref:0:5:GCCGTCGGACAA ref:0:5:GCCGGTAATGCTGG 6 1170 +TGAGGTCGTG ref:0:9:AACGGCCAG ref:0:10:TCTTCAT 3 504 +GAGAG ref:0:5:C ref:0:4:CCTAAAAATC 3 570 +ATAACACAGAAGGG ref:0:14:GCACAGTCGTT ref:0:14:AC 8 3570 +ATAGAGTGAGGGC ref:0:12:G ref:0:13:GCTTCTGCCGG 7 7926 +GCTGCTTCGGCT ref:0:12:GGGGTGTCCCA ref:0:12:AAGGGCAGC 6 34370 +ATC ref:0:3:TAGTAAGGTCTTCT ref:0:1:C 1 28 +GCTC ref:0:4:ACGTGGCGAC ref:0:4:ACTTCTAGC 4 225 +CAT ref:0:3:TAGGGAGAC ref:0:3:AAAGGCATGA 5 58 +TATGCTGCGGAAGAC ref:0:15:CTACCTACTAAGATA ref:0:15:CGGTAAGGCTCGACCG 5 26624 +CAAC ref:0:3:AGT ref:0:4:AATGATACAGGCCAT 3 308 +TGTCCAG ref:0:7:GTCTGTCTAA ref:0:6:TC 1 92 +TCCTTTTTTGGCT ref:0:13:CAGTG ref:1:11:GGCTAAACTAGCG 7 1582425 +CATTAGCC ref:0:8:TC ref:0:8:AAAAGCTGTGT 3 720 +GTATCTTG ref:0:8:CGTAGAAAGACGGA ref:0:8:AATTGATAT 3 9440 +GATATT ref:0:6:CATTCAGTTT ref:0:6:C 2 84 +AGTCTAGTCCCAGT ref:1:13:CACGAAGTTG ref:0:14:TCAGG 6 44 +T ref:0:1:TACCCCTTC ref:0:1:AACCA 3 18 +CAACAG ref:0:6:GTTGTCCGGTCCC ref:0:6:A 2 9 +TCGATCCGATTG ref:0:11:GG ref:0:12:ACAA 6 15 +C ref:0:1:GCGTAC ref:0:1:TCGTTGG 2 2 +AAAGCGTTGCC ref:0:11:GGGTCGCGTGTG ref:0:11:TACCCCT 4 5858 +TTTGTCAAT ref:0:9:GTCCATGA ref:0:8:TATATCTTCCA 2 280 +GGATAGCCCTGCAAT ref:0:15:GAGTTTG ref:0:15:CTAGC 8 2944 +TAATTGAA ref:0:8:GTG ref:0:8:CCATC 5 810 +AA ref:0:2:CCCATACTG ref:0:2:G 1 3 +GTGGCGGCCGGC ref:0:12:CC ref:0:12:ATTGATCTA 8 47100 +GGAGGTTGA ref:0:9:CTAAATGTC ref:0:9:TGCG 7 135628 +TACGGTGCTT ref:0:10:GGACGGG ref:0:10:GTCCTCCA 3 291 +CTT ref:0:3:GG ref:1:2:TC 1 30 +AGTCCCCCGAC ref:1:10:CG ref:0:11:CAGTGA 5 5 +TTGGCTTTCTATATC ref:0:15:TGAGCC ref:0:15:AT 8 18 +T ref:0:1:GCCCTCTAC ref:0:1:GGCGGA 3 14 +AGCT ref:1:3:GGCTGCGGGGA ref:0:4:CGCGCCTTT 1 84 +CTA ref:0:3:TTTGCGT ref:0:3:TTC 3 8 +GAGAGAGGCT ref:0:10:TA ref:0:10:ACGGCGCCGCC 4 78 +TCACCCGGGGGCTGA ref:0:14:AG ref:0:15:GTGAATATGAGAA 10 359586 +CCGCACGGC ref:0:9:TGGATAATACAAAT ref:0:9:CGAT 6 70750 +GTGAAGTGT ref:0:9:AGGTCCCAC ref:0:9:TTGTTCAGT 3 230 +CGCAGCTAGCGA ref:0:11:ATGAAGTTCGCCCCT ref:0:11:TGACATGGC 6 25488 +TGTCTCGACT ref:0:10:TACC ref:0:10:ATTAC 6 130 +TGACCGCT ref:0:7:GTCCGACCACCC ref:0:8:AAGGCTGACCAAG 2 19 +TGATCACTGAAC ref:0:12:T ref:1:11:AATGCGA 6 99 +CTTCGCCCCTTC ref:1:11:TGATA ref:0:12:CTCA 8 4104 +AGA ref:0:3:TGTAAATAGC ref:0:3:GGATGAGTGTCTTTAC 4 174 +GGTACGAG ref:0:8:TCGTTAAT ref:0:8:ATTTTCAAGGCCGCGG 3 21160 +G ref:0:0:TTCTATTC ref:0:1:CCAGGGTAAGATTC 3 4 +C ref:0:1:GATGGGAGGGCC ref:0:1:TAGCAGGGAATTCA 6 4 +CGCGCACTTG ref:0:10:GAGCGCCGGA ref:0:10:T 3 32 +TAAT ref:0:4:G ref:0:4:GACCTGTGGCATTGT 2 250 +GTTGAGT ref:0:7:CCCTCTAAG ref:0:7:TAGACGCTTGC 2 72 +T ref:0:1:CATCCCACTTTT ref:0:1:GGTGTTGTCTA 4 25 +GACTAGCTGA ref:0:10:TTT ref:0:9:CACCC 4 341 +AGGT ref:0:3:GGA ref:1:3:TTTGTGCATCT 1 2 +AAAACACGTTCTA ref:0:13:TCGAGGCAATTCCCT ref:0:13:TGTCCTCCATGAAT 7 487050 +CTG ref:1:2:AAGTC ref:0:3:AATTTA 3 170 +TGGTAAGCATTCATT ref:0:15:GAACGA ref:1:14:CGG 9 88 +GACAGATAGGCAAG ref:0:14:CGCTAAGAGG ref:0:14:TCGTATAAT 7 7965 +CGGATTAT ref:0:8:TGGGTC ref:0:6:TTGGATC 4 756 +GTGGTCTATC ref:0:10:AGTTAAGGCG ref:0:10:TCCAAATAGTCG 5 616 +CCTAATTAGTTGCGCC ref:0:16:TGGTTAACAACAAT ref:0:16:ACA 11 60496 +CCG ref:0:3:CCCCTGT ref:0:2:AAAGCAT 1 48 +TGG ref:0:3:CTT ref:0:3:CCGA 2 48 +CAGAGTCT ref:0:8:TTGCATA ref:2:6:AGCTCG 2 186 +TTACGTTAACA ref:0:11:AGGTTTGTACTTCATC ref:0:11:CCTAATGG 3 4680 +ACGGCCTGGAAACTG ref:0:15:ACACGCACGAAGCAGT ref:1:14:GG 5 2400 +CAAATCA ref:0:7:CCATGCTCTCTT ref:0:7:TGTTGAGAA 3 27675 +TCCGGAGACT ref:0:10:ATCTATCTTCGTGTA ref:0:9:CCCAG 4 522 +AATCTGGGGCTTG ref:0:13:GGGGGT ref:0:13:GTTCGCCACCGTGC 6 158472 +GCGCGTCCGACAG ref:0:13:ACTC ref:0:13:GTAGGAGC 7 3186 +GGTTGT ref:0:6:CTAGCTAAC ref:0:6:AACTG 4 300 +AATCCGAATGTATAG ref:0:15:CC ref:1:14:GCATACAATT 6 9 +CCTAGCATAGCAGGG ref:0:15:GTTGAACTGG ref:0:15:AACCCTA 4 168 +CTGATACCAA ref:0:10:CCTCTCTA ref:0:9:AAATT 3 69 +TCTCTAA ref:0:7:GCGTTCCCTC ref:0:7:AATTTGCACCATAGAA 3 6750 +TAGCCTTGGGTCACT ref:1:14:CCCTCGTCTG ref:0:15:CACA 6 4536 +GTCTGTGCA ref:0:9:TGAG ref:0:9:TTAGGAAA 4 54 +A ref:0:1:ATACCTGCT ref:0:1:GAGAT 2 4 +CAATAACGCACGA ref:0:13:TCCAATAAG ref:0:13:AGAACTCG 4 448 +CTGTCACG ref:0:8:GACGGGAC ref:0:8:TATAGCACAA 3 360 +A ref:0:1:CTCTAGTT ref:0:1:TCGGAGC 3 1 +GTAGCTTTCGAAA ref:0:13:A ref:0:13:CAGGTTTCA 6 120 +GTTACTGCAG ref:0:10:TAGTTCATG ref:1:9:ACCTT 3 450 +CTAAGGGAATTC ref:0:11:TCTATAT ref:0:12:CCTCGAAG 5 4896 +GCTTG ref:0:5:GAATGCTTC ref:0:5:CGCTGTTTA 1 72 +CACTTCACA ref:0:9:ACTATCTGCT ref:2:7:TTGAATAA 2 234 +TTCTGCCTCA ref:0:10:CGAG ref:0:10:AGCCAATACCCGTT 5 692 +CTGGATGATCCGAGTC ref:0:16:CCTTC ref:0:16:GCCTTCACATT 10 6804 +ACTAC ref:0:5:CCTGTCTGCG ref:0:5:GA 2 300 +AGTACCAGGA ref:0:10:GTGTC ref:0:10:A 6 104 +TGTTCCGGGACCAAT ref:0:15:ATAGGATTCAC ref:0:15:GTCTCG 7 96 +GTACA ref:0:5:TTA ref:0:5:TG 3 40 +CCG ref:0:3:ACTCATACATGCA ref:2:1:T 1 6 +GGCCTAG ref:0:7:ACGTGC ref:0:6:ACAGCAGGCGCTATC 2 48 +TGAGGATAG ref:0:9:GCATCCGAGGCTTTGC ref:0:9:G 2 64 +TTGAT ref:0:5:TA ref:0:5:G 2 2 +TAGGAGCCA ref:1:8:CTC ref:0:6:CTAGG 2 3 +CAGGA ref:1:4:GGTAGCTCTC ref:0:5:ACCA 1 13 +GAGGAGCGAG ref:1:9:TCAGGCCATGAT ref:0:10:AGTCCCTGAATA 6 17115 +GTCGTAATA ref:0:9:ACCGCTGACAAAGAGT ref:0:9:TATAGGATTTAGCC 3 4230 +AGGCGACTCGCTTAAA ref:0:16:TCCAAACGCCG ref:0:16:GCTCCGTGAACGCGG 11 6501 +CCCCTGTTACCGTA ref:0:14:AATGACCCG ref:0:14:ACGCATGACT 7 1890 +CCACTCACAAG ref:0:11:AAGCCTTAAAAGTC ref:0:11:AA 4 1626 +GCTTCAGTA ref:0:8:ATCATC ref:0:9:TCACCAGCTCATGGTG 2 56 +AAATCATAC ref:0:9:GATGGCGAGTG ref:0:9:GGCCCCTATG 7 41094 +TTGTA ref:0:5:CAGTGATTCTGT ref:0:5:AT 2 48 +TTTCTAAT ref:0:8:GATTGCCAAAATTTAC ref:0:8:CCAAAAAACC 7 380970 +GG ref:0:2:CAGTCC ref:0:2:TATAGGCTG 2 21 +TACC ref:1:3:GGACATGAAGA ref:0:4:TGCTAGA 6 243 +CTACCTGCGACG ref:0:12:TCCTGAGTGC ref:0:12:GCCGGTGGCTCGTTTC 6 7952 +TGGTAGAAGCGATC ref:0:14:ATGGGAGCACGTATAG ref:0:14:TAAGATCTTTAGTG 6 25704 +TTGGCAGA ref:0:8:TAAGCTG ref:0:8:GGTGATCGAATG 4 4394 +TA ref:0:2:CTATTGC ref:0:2:GCGATGGAGTGGTGA 4 4 +GAAGCC ref:0:6:CCTAAAAACATGCTTA ref:0:6:TCCTCAC 6 83655 +CTCTAAG ref:0:6:AAT ref:0:7:CACA 3 6 +TCTG ref:0:4:CATCTCGATTGAG ref:0:4:GCTACGT 2 60 +GGTCTCAGCCGG ref:0:12:ACTCATGA ref:0:12:TAATGTTGG 6 6048 +TGTTCGTCAGAATCTC ref:0:16:AAC ref:0:16:GATGCG 8 18 +AACTAC ref:0:6:ACACC ref:0:6:TATGCCGGTG 2 275 +ATCC ref:0:4:GTTACTC ref:0:4:TTGACGTCCAACCCC 3 120 +GTGAGTAACTTAGTAC ref:0:16:AGTCCTTGTCTG ref:0:16:GCCGGCAGCTGG 6 1592 +GT ref:0:2:CCACTATAAGTCATCG ref:0:2:CCAAGTTATCAGAAGT 8 12 +TAGCCAGGGC ref:0:10:CAAGGCTCAAGGAGCG ref:0:10:CCCCTAGGATTGGT 4 4700 +GGATTAATATTGAC ref:0:14:TGTATT ref:0:14:TTGCCCT 7 3540 +TATTTGTGAAA ref:0:11:GCCTTTTG ref:0:11:CCATAGAGAG 5 8025 +CCCGGCAAGT ref:0:10:G ref:0:10:ACAC 7 342 +GGACACAAACT ref:0:11:C ref:0:9:CTC 7 6 +GCTTTCTAACTA ref:0:12:CTGC ref:0:12:TCTACATGAGAGA 5 2340 +ATT ref:0:3:TGGATAACAAA ref:0:2:TGAGTC 3 9 +GATC ref:0:4:CTACGTCGTAG ref:0:4:TGACCGATATCGTGA 6 32 +CACACTC ref:0:7:CTCTCAA ref:0:7:AATTCAAGG 4 24 +ATGTCGCA ref:0:8:ACACTCGCCGGG ref:0:7:GGCCAGGCGCTT 2 812 +CAGAAATGGATCCT ref:1:12:TGGTGTAATC ref:0:14:ACGTTGAGGAC 6 26100 +TGTCGA ref:0:6:CGTTTATCC ref:0:6:ACGCTAGGGTCC 6 1332 +GTGCA ref:0:5:GGG ref:1:4:GCCAGTTATACTTCT 2 36 +CTATTTTGAGATG ref:0:13:GTTCAGTAATGACT ref:1:12:T 6 11706 +GTGT ref:0:4:CCCT ref:1:3:CATGATCAAGA 1 24 +TCAGCGATTTGTACA ref:0:15:GC ref:0:15:CGTATCATG 9 464 +GGT ref:0:3:TACGCTGCGGGC ref:0:3:TC 2 37 +GAT ref:0:3:TAGAACTACAACCTC ref:0:3:ACCTCGTGGGGT 3 140 +TTATAAATCCTCG ref:0:13:AGCGTGTCAGA ref:0:13:CGG 9 3487 +C ref:1:0:TTG ref:0:1:CCTCGTACCT 2 5 +CGTCCTCCTCT ref:0:11:TGACCTAGTCCTCTA ref:0:11:TCAG 4 1240 +ACCTCACTAACAAGA ref:0:15:CAGCGCCAT ref:0:15:CACTCAC 8 51 +ATTCT ref:0:5:GTCCTTGA ref:0:4:TGTTTCCC 3 1014 +AATGCTA ref:0:7:ATGTTATATCA ref:0:7:TGTT 3 228 +GT ref:0:2:A ref:0:2:AGTCAGCGCATC 1 12 +TCCCCGTCGCACTAA ref:0:15:CTTGGTGACAAAGGGC ref:0:15:G 7 810 +TAGCAGTGTAT ref:0:11:GCTAGTAGCGCGTCC ref:2:9:CTTTGTG 3 13456 +GTAGCAGTA ref:0:9:TAGCTCC ref:1:8:TTC 4 18 +GTAAGA ref:0:6:GCGTGGGTTGTTTCCG ref:0:6:A 2 3918 +CACACGC ref:0:7:AGGAGCGTACCTA ref:0:7:TTTCAGGCTTGTTGG 5 3014 +CG ref:0:2:AATTGCCA ref:0:2:TGGGTCTCGTGTGCGC 4 90 +GTCGTCGAGAAGGGTG ref:0:16:TAAACGAGCTCCAT ref:0:16:G 9 1968 +TGTGAAAACACCAGT ref:2:13:CTTTGCGA ref:0:15:CAC 8 84 +AGTTCAATACC ref:1:10:CTAATAGAAGGTAA ref:0:11:CGGCGTCCC 3 5600 +TGACACGACATCC ref:0:13:GGCAGTCTCCACAGC ref:0:13:TATTAAG 7 54758 +ATGGTCGTAGACCA ref:0:14:GGTAAG ref:0:14:CGTA 8 105 +CTA ref:0:3:AGATGTCGCGCTCG ref:0:3:GGATTCGCAATTAAG 7 72 +CCGTTTATATTTGAT ref:0:15:CGAAAAGGCTATACA ref:0:15:ACAAG 8 21021 +ACGTTTGT ref:0:8:AAC ref:0:8:CGGGCTCCAG 3 182 +AGCGAGTGAAGC ref:0:12:ACCCTACAAGAAGGA ref:0:12:CGTATCG 5 53208 +ACCCAGACTAACCCA ref:0:15:CGG ref:0:15:CGCTTTC 10 5382 +ATGT ref:0:4:CTAT ref:0:4:TATGAAAGGATTAAC 1 36 +GGTGTAGGGCCG ref:0:12:TTGATC ref:0:12:CACCTGGGCTT 6 100368 +CGTGCG ref:0:6:GGCGGGCCTAAAC ref:0:6:AACAGGTTGGAGGC 3 5184 +CAAGA ref:0:5:TATCCTCTCTATAAGG ref:0:5:TAATGTCACCCCCTAG 6 200 +TCTGAATC ref:0:8:ATAATT ref:0:8:AAGCAGCGCC 4 13284 +TGTAGCTGGGGTGC ref:0:14:CTATCCTAT ref:0:14:AGCCAATTCGCTA 7 280 +TGCTGTCCG ref:0:9:GCC ref:0:9:GG 5 12 +C ref:0:1:AG ref:0:1:TCAGGTCGGT 2 6 +CTCACCAA ref:0:8:AGGCT ref:0:8:T 6 14 +AGAAAGCAT ref:0:8:TAG ref:0:7:ACTACAGG 4 714 +CAGCCGCAACAAGCC ref:0:15:TCCCAAGGTCG ref:0:15:AAGC 8 13380 +T ref:0:1:CCATGACA ref:0:1:ACCAG 4 6 +CCCGTTCGGAATAC ref:0:13:TCACGTGT ref:0:14:TCCATGCCAACGT 6 23580 +GCCAGGCGCCAGAA ref:0:14:CCCG ref:0:14:TACGCTCCT 8 4400 +ACATGGCAGGTCTATG ref:0:16:GAA ref:0:16:TTTCAGTA 9 224 +CCGCACGATCCG ref:0:12:ACACACA ref:0:12:CTTTGGGCAG 5 12060 +GGGTT ref:0:5:ACCAATCAGAC ref:0:5:GGGGTGTACTT 3 35154 +CAGAGTCTGTC ref:0:11:AGTGAGTCGA ref:0:11:GTCTCAAGGAAAT 3 36 +CGGTCCT ref:0:7:GCACGTGCAAC ref:0:7:TCCCAAATAG 1 36 +GTAGAGAATTATGCA ref:0:14:TAGGTG ref:0:14:TATAGCGTC 7 516 +TTCGCGAAATCC ref:0:12:T ref:0:12:CGTTAACTGATGTAT 5 252 +CTAGGTATGA ref:0:10:TATACTTTCAGGCC ref:0:9:TGAATAT 4 240 +CCCAGGG ref:0:7:A ref:0:7:TACCTC 3 1 +GAGGGT ref:0:6:CTAGGCC ref:0:6:GGTTGAGCGTGG 2 1332 +C ref:0:1:CCTATGCTAGGAGT ref:0:1:ATGGGTCATGATGC 7 6 +GAGCTCGGAGACATA ref:0:15:AAAATTTCCTAGCCCC ref:0:15:GAT 8 1890000 +GCGGC ref:0:5:CCACCTGAAGAT ref:0:5:CGA 3 180 +TTCTAAAGAAGAAG ref:0:14:AG ref:0:14:GTCCTAGGCCGAT 7 40005 +AATCCGATTTA ref:0:11:ACATATAT ref:0:11:ATGA 4 108 +AGCGATGCT ref:0:9:TAACCCAATATC ref:0:9:GTCAC 3 540 +ATTGTTTCCCCGC ref:0:13:T ref:0:13:CCGGGATAGACGG 8 1410 +CC ref:0:2:A ref:0:2:GTTAGTATGTCA 2 39 +CGGGACTGCTGCG ref:0:13:TCCCCAGA ref:1:12:A 7 1 +AATGTATTTACGA ref:0:12:GGTTAGGGCTTA ref:0:11:GCGAGT 7 11466 +CCTA ref:0:4:GTGAGCAAA ref:0:4:ACAATAAAC 4 870 +A ref:0:1:GTCATGGCGGGA ref:0:1:CGGTGGGCACCTATTC 6 4 +GATGCCACCCAT ref:0:11:GAC ref:0:12:CCAAGTAGGGCC 6 11286 +ACTC ref:0:4:CAACCTA ref:1:3:GGTCTGGCGTCTCG 1 100 +TGGCAAAGAGATCGA ref:0:15:CTTATAC ref:1:14:GTTCG 10 13543 +TAGATGCGCTAAT ref:0:13:GTTGG ref:0:13:CGG 9 76 +TCCGCAAACCCCGTG ref:1:13:CTTGTAAGTCTAA ref:1:14:GC 7 3640 +AAAACATGAGAAGCGC ref:0:16:AC ref:0:16:CCGCATCG 11 5740 +TCCCGCACACCGTACG ref:0:16:C ref:0:16:GTATT 12 656 +AATTATACGCTCCTAT ref:0:16:TCTC ref:0:16:CTCATTCC 9 120 +TGTATCCATCGTATC ref:0:15:GGCGTGTTCGAAGT ref:0:15:ACCGCTA 4 516 +CAG ref:0:3:ATTCCGATCT ref:0:3:ACCTATGAGATTC 5 72 +TATGAACAAC ref:0:10:AAACAGCACGTCG ref:0:9:CTCAGAACCCAGT 4 30 +TCGTT ref:0:5:CGACGCACA ref:0:5:ATTCT 2 555 +TGA ref:0:3:AGCCGCGGCTAGAAGT ref:1:2:CAAACGACCGCCGTA 3 8 +AATCAGT ref:0:7:CATGGGTCAGCCGTC ref:0:6:TTTGGC 3 1540 +GTGGCGCACGTTGTT ref:0:15:CTGCGCTTA ref:0:15:AGATCGTATACTGACT 5 4928 +TCATCTGCTACGCGGC ref:0:16:CTCGCCT ref:0:16:GC 10 232 +GGAGTGC ref:0:7:GTAATGTTTTTCG ref:0:7:TAAAACCG 5 142350 +CCAACGT ref:0:7:G ref:0:7:GTATA 5 24 +TGC ref:0:3:AAGACAA ref:0:3:AAGATGGCCGATGA 4 12 +TATCAACCCAGTTA ref:0:14:GTC ref:0:14:ACTAGAGCG 8 252 +GTCCGGATAGTCAGGT ref:0:16:TTTGGGATCG ref:0:16:ATTGC 8 5082 +CCGCAATAACCA ref:0:12:AACCC ref:0:12:GATTAAAC 5 1218 +TTCC ref:0:4:TCAT ref:0:4:CTGACCAATCTCA 2 9 +TGCAAGTA ref:0:6:CATTGCCAC ref:0:8:ATTGGG 3 384 +GGCCGGAG ref:0:8:CGAAGGTCG ref:0:7:ATTACGATTAA 5 108550 +CGCCTGCCAGGCTC ref:0:14:CTGTCATGAG ref:0:14:GTCATAAA 6 152 +AGACATAT ref:0:8:CATGGGA ref:0:8:GG 4 9 +GGTAGGACGACCA ref:0:13:CGTTTGTGTTAGC ref:0:13:AAAACCACCCTTTG 2 90428 +CTGGTAACGCCTCGC ref:0:15:TTCCAGCTGTAAG ref:0:15:TCGCATTCTTA 10 60528 +G ref:0:1:GCTCCACCACTAG ref:0:1:AGCTT 3 2 +CA ref:0:1:TTGCC ref:0:2:ACAACAATCATCAGCA 3 36 +C ref:0:1:CAAC ref:0:1:ATACCTCCCCGAA 2 12 +TTTT ref:0:4:GCCGGCAGTATTAC ref:0:4:CCCTGGGCCGG 6 5460 +CTGAGGAGGACTGCCA ref:0:16:GCTAAAAC ref:0:16:C 10 140 +C ref:0:1:GTA ref:0:1:TTCTG 1 4 +ATTACAC ref:0:7:TGAGCTTACGAGGGG ref:1:6:GGTTCTGAAAGAAT 4 1225 +TGATCTGCACATCG ref:0:14:AATCC ref:0:14:GCTGT 6 52 +TGTGA ref:0:5:CCCTACCTC ref:0:5:CCCTTTCCTGAATC 7 736 +TGGAGCTAACCAT ref:0:13:CTGGTAGT ref:0:12:CGCA 7 1920 +CGAACTAGTCAATCGA ref:0:16:GCTGCCAATGTTAG ref:0:16:C 6 12 +AATCGGAAATG ref:0:11:GGGG ref:0:11:CGATGCGGGT 6 336 +AGAAACGCGGGT ref:0:12:CCCGGCAA ref:0:12:AGCGA 7 9960 +GTTA ref:0:4:CTAC ref:0:4:AACGC 3 45 +AACTCAGACGCGC ref:0:13:CGC ref:0:11:TATCGCG 5 48 +GCC ref:0:3:ATG ref:0:3:TCTCAGCCAA 1 1 +CC ref:0:2:CTTACAGCAGGC ref:0:1:TATCGGGATT 5 6 +GTCGCAGA ref:0:8:CTCT ref:0:8:TCGCTACATGCG 4 420 +AATTCGGGCCCCATAG ref:0:16:GATTAAAACGC ref:0:16:GGCGAGGGGACTTT 8 17129070 +CTAC ref:0:4:ATAAGCATACGTTGC ref:0:4:AGTAG 3 12 +TATTGCCTCCTACTT ref:0:15:TGTAG ref:0:15:T 11 168 +AGGGAGTCGAG ref:0:11:TGCGCGTATC ref:0:11:GGTCTAGAACA 5 164 +CTCGCGAGG ref:0:9:GTC ref:0:9:GTGTCAC 6 30 +CC ref:0:2:TAA ref:0:1:TCT 1 10 +AGTCGCTTTGC ref:0:11:C ref:0:11:CAACGCCCACGTTACC 4 6300 +TAGTGGGC ref:0:8:GTGCTATAATTGAA ref:0:8:AGTCCAGTCTA 5 32604 +CAGATGA ref:0:6:GT ref:0:7:GGTCCACACTAGCC 1 16 +TACTACTGCTCGCGG ref:0:15:AGAACACGCGT ref:0:13:ACCGCCTTTGTCCT 5 86670 +GCAGTGTTG ref:0:9:AAAGCTACAC ref:1:8:ACTTGTTACTCTGGG 5 557010 +GTG ref:0:3:GGTCCC ref:0:3:AAATCGGAACATC 3 117 +ACAACG ref:0:6:GGGTATTCAT ref:0:6:AAGTTCAA 4 14 +GAGGAGT ref:0:7:CTGGATGACGAGCGAA ref:1:6:CTCGTTCGCAATCT 3 640 +TAATTTGCCGGCCGG ref:0:15:CGCCAGAAGATCATA ref:0:15:ACCAC 9 6372 +ATC ref:0:3:CTTATATGCGCTGC ref:0:3:TTCC 2 66 +CG ref:0:2:TTTCCT ref:0:2:TCACGATTGACCA 3 20 +TAGGATGTCCATCT ref:0:14:GCT ref:0:13:TTAT 7 45 +GTGGATGGG ref:0:9:GGTTTCCGTG ref:0:9:GGTACCAGATGCCTA 6 85176 +AAAACCCAG ref:0:7:CAGTGTAAC ref:0:9:CTACCAGGGTTC 4 4941 +TACGTTGCGATT ref:0:12:ATAGAATATGG ref:0:12:TAATAGTGCCACTC 4 264 +ACTAACAGACTC ref:0:12:TTCGAGCAATAAT ref:0:12:CAGCACGAAGT 6 86 +T ref:0:1:AGTAAGATGGGAC ref:0:0:ACGA 3 2 +CA ref:0:2:TATGCCG ref:0:1:AGGAGGCG 3 7 +AGTAGATGCAATGAC ref:0:15:CCCT ref:0:15:A 12 564 +TTACAGT ref:0:7:GACCATC ref:0:6:GTAGAAGCTCAACAC 2 24 +AATCAACACATAACT ref:0:15:TGG ref:0:15:TTCAAGATAGATGGC 8 8560 +TTTCGTAGA ref:0:9:AACGGGACG ref:0:9:G 5 220 +TGCAGGATGTGA ref:0:12:GCGCTTTAGCACGTTG ref:0:12:C 4 94 +CCGGTGG ref:0:7:CAG ref:0:7:GGGACAAGTAACATTA 3 28 +TGTGTGCCGC ref:0:9:CTCACGACAGCGCC ref:0:10:TTGTTTACAATACA 1 5848 +CCGTCG ref:0:6:TCATTATTGCGGGC ref:0:6:TCATCTTA 5 10760 +ATTCTTCCTGGATT ref:0:14:CGG ref:1:13:CAAAACAA 8 1116 +CCAGCTG ref:0:7:GACTGAT ref:0:7:T 3 4 +CGA ref:1:2:TAAC ref:0:3:CGACAAGCCGA 2 50 +CAGATCAGGTT ref:0:11:GAACCTCTTCGACAA ref:0:11:TTACTA 6 668 +TC ref:0:2:ATAGTCCTCCTCGCA ref:0:2:AGGCGAATTAAGT 5 288 +CCAAGGAAGTACGC ref:0:14:AAAGTTTTT ref:0:14:TC 8 1008 +GCCTAG ref:0:6:TAAATGGAACAC ref:0:6:AATATAATCTCTTCA 7 468 +ACATGAACAAAAA ref:0:13:GGCCTTTGAAA ref:0:13:GTTTCACTGCCCCGCA 7 15722280 +CCCC ref:0:4:CAC ref:0:4:CAGATTCC 2 90 +ATA ref:0:3:TGTTAAACTAT ref:0:3:ATTGCCATATCGT 3 18 +GTGGGCACGAACAA ref:0:14:TACTACCGAGA ref:0:14:TC 7 384 +TAACGTCCAGC ref:0:11:ATCA ref:1:10:AGGTTGACTA 5 704 +ATTATCAATTA ref:0:11:CATAC ref:0:11:ACA 6 36 +GATGTAACGCTTG ref:0:13:C ref:0:12:TGATATGGAGTCGCC 4 504 +ACGCTATATT ref:0:10:TCGAG ref:0:10:CCACTTGAAGGAA 6 25520 +TGTTGAAA ref:0:8:CCGTCTCAATGGGAC ref:0:8:ATGCCTCAGGGT 6 2640 +TAGAGGGA ref:0:8:AAGTGTTTGGGT ref:0:8:CTGCGAGCATCCAA 3 52650 +CCAATACTCTGCAG ref:0:14:ACGAGAT ref:0:14:TTCCAGGGACTA 5 270 +CTTCCAAGAGA ref:1:10:GTTCTCCGCTCC ref:0:11:GCGGTGTGTAGAGC 5 11890 +AG ref:0:2:ATGTTAATGGAG ref:0:2:TA 1 11 +GAAGGTTGCA ref:0:9:T ref:0:10:AC 6 4 +CGAGGCGAT ref:1:8:GTGGAG ref:0:9:GTGC 4 120 +AAATCTTGCCAA ref:0:12:CAGCCACCAT ref:0:12:ACCATTCG 4 2088 +GTCTG ref:0:5:AATATGCT ref:1:4:CCTCTAGTGAGCC 2 75 +AAGTAAC ref:0:7:T ref:0:6:GGCGTG 4 42 +GC ref:0:2:CACAAGCTCA ref:0:2:CCTCCCATGA 4 40 +CCGTAGCGTGCCTTGA ref:0:16:ATGGT ref:0:16:AGCCTACT 9 2700 +CCAGT ref:2:2:GGC ref:0:5:TAC 1 42 +TTTAGCGTCG ref:0:10:TCAAACCTCAGTC ref:0:10:GAATA 6 57228 +GCTATTGAAGA ref:0:11:ACTGGCTACATTAACG ref:0:11:CCGAG 2 56 +CTCGACCG ref:0:8:GCAGG ref:0:8:ACGGT 5 297 +ATATCTACCAATGC ref:1:13:GTAGGGTA ref:0:14:TTTCAACATT 5 13959 +GCC ref:0:3:GTTTTAATGCGACTCG ref:0:3:CATTA 2 42 +TATATTTATAGCT ref:0:13:GTAACAGCCCCCC ref:0:12:CTG 6 13020 +GGTTCCTCCCA ref:0:11:GTGAGGACGAC ref:2:9:ATCGG 8 4104971 +ATTG ref:0:3:AAT ref:0:4:GGCGATGC 1 10 +GCGTGGATCCTCG ref:1:12:CCAATCTCACCA ref:0:13:GTCCGGTGG 4 127368 +CACCATCTACG ref:0:11:GGTCTA ref:1:10:GAGTGAATCA 6 546 +CACATTTCACAA ref:1:9:CTCTCA ref:0:12:TTACGAATACTA 1 360 +ACTCCTATAATGGTGC ref:0:16:GCGCGGAGA ref:0:16:CGTCTTG 9 1344 +ATAC ref:0:4:TTAGCACGATAGGTTT ref:1:3:TTCGAAGCAGTCGGA 7 300 +CT ref:0:2:TC ref:0:1:AAAATACACCGAG 1 6 +GTTCTCTTAA ref:0:10:TGGCTC ref:0:10:CTCCCATTTAGCAC 2 768 +TCCTTAATAGT ref:0:11:ATTAACGGTCAAG ref:0:11:AC 5 228 +ACGGTAACTGAAC ref:0:13:CTTGAAGTAA ref:0:13:CATCATGACGA 5 2640 +TCATCGA ref:0:7:GAGC ref:0:7:GCTC 4 26 +TGTATGC ref:0:7:AATGGGATGTTGGA ref:0:7:TCACCGA 3 9266 +AGCCC ref:0:5:GTC ref:1:4:GGATACCGG 2 102 +TGCAGCATGTTCATGT ref:0:16:CACGCGAGA ref:2:14:TCAATTCGAACAAT 5 1080 +AGAT ref:0:3:GTTAAGACC ref:0:4:TTAATG 2 2 +CAACCTTTGT ref:0:10:A ref:0:10:ACAAGGTGGTAAATG 3 12 +TGTGACAAAGCCT ref:0:13:TCTTT ref:0:13:ACGC 7 232 +CTTGCCG ref:1:6:GGAGTCA ref:0:7:AGTCATTAACTTAT 5 12150 +ATGCGCTGAC ref:0:10:CGCCGAGCCTTT ref:0:10:CACTAAAGTGGGGTAA 2 9324 +GCTGCTAGG ref:0:9:TAGGCG ref:0:9:TATGAG 5 325 +CTG ref:0:3:GACTCTGAAAAGA ref:0:3:TTGTTTATACGACC 5 180 +ATCGACCGCGGGA ref:1:11:CTGTGCAGTAGGCT ref:0:13:CTTCGGTAATATACC 3 1840 +ATCA ref:1:3:TTAA ref:0:4:TGCTTATAACTCG 2 144 +GCAT ref:0:4:CCTGGT ref:0:4:TGGGCGAGCGCGTTC 3 126 +CAC ref:0:3:CGCCTCC ref:0:2:GACCATGAAA 3 240 +GTTTTG ref:0:6:CTAGA ref:0:5:GAGGGTAA 4 6930 +AATAGTC ref:0:7:AAACACAGGGGGGCGT ref:0:7:T 2 1512 +AGAAACGTG ref:0:9:CCGATGGCT ref:0:9:GCAG 5 3104 +TGTGGTTC ref:1:7:CAGTAAGCGCAGAA ref:0:7:A 3 8 +CGAACTC ref:0:7:AGATTTATAG ref:0:7:TG 4 24 +GCGGCTCGTCT ref:0:11:GGAACCGATAC ref:0:11:ACCCT 4 65 +TTCGAAGCGCCT ref:0:12:TCGACGGAGTTAGAG ref:0:12:AAAAAATA 6 769860 +CC ref:0:2:CGATTAA ref:0:2:TAA 4 80 +CGGAC ref:0:5:AGCTCTTG ref:0:5:CCTGGCTCG 4 352 +T ref:0:1:CTCGGTCAG ref:0:1:AGCATGCACA 4 2 +TTACGAACGCC ref:0:11:CGAATTCTTCT ref:0:11:ACAGTCGTT 6 972 +GGCTTAACACCGTG ref:0:14:TGCCCAGCC ref:0:14:GTGGAA 7 1254 +GATTGA ref:0:6:GTGACGATAATCGCG ref:0:6:TGCGGTATAATCCGC 8 120 +TAGAGACAACGG ref:1:11: ref:0:12:GGCGCATGACTTCTTG 4 479 +AAGC ref:0:4:GCCACTA ref:0:4:A 2 18 +ACTGCGT ref:0:7:TGATTCCCTAA ref:1:6:CGAA 4 768 +CG ref:0:2:GCTCTTCGTGC ref:0:2:ACCAGTGTCCGGC 6 72 +TGAGGGGTGAGA ref:0:12:CTCTTAAT ref:0:12:GTGACTACGGGGCCTC 4 430 +GATACTTTC ref:0:9:TTCC ref:0:9:TAGT 5 189 +GACTGCCCGC ref:0:10:TCA ref:0:10:TGT 7 117 +TACCT ref:0:5:ATCCC ref:0:5:AGA 2 117 +CATCTGATGG ref:1:9:CTGTA ref:0:10:GGAGCATAT 3 32 +TAGGGGGC ref:0:7:CT ref:0:8:CAGCACTTAACGT 6 2694 +GCGGGTGT ref:0:8:CTAACTGATATTGTT ref:0:8:CCAATCTTGTTTTTCG 10 7675798 +GG ref:0:2:GCAGGGTAAAGG ref:0:2:AATG 2 75 +GTGTAGCT ref:0:6:ATCCCCA ref:0:8:GT 3 204 +AGTA ref:0:4:T ref:0:4:GGACCAACGAAT 1 12 +CGGGAACGGAATTG ref:0:14:TGAGTTGCA ref:0:14:GATTCATATAAGTTT 6 83520 +CCCAGTTGG ref:0:9:GTAAGACTGGG ref:0:9:GTCTCAGTC 4 16506 +TGACCAGCTCGGTAC ref:0:15:GTTAG ref:0:15:GCAAAGGGTACGT 6 56 +CCCAAAGTG ref:0:9:TACTAAGTCTTGGATC ref:0:9:AGTTAATCTTCCGGAC 10 6372 +AAACCGAGAAG ref:0:11:AGCGACGGCTCGT ref:0:11:ATAGGTAGT 6 6840 +G ref:0:1:ATGG ref:0:1:T 1 4 +GG ref:0:2:GCATAT ref:0:2:A 2 21 +GACATGCCATCG ref:0:12:ATGATGCAGTCT ref:1:11:CTATCATTACT 4 160 +TAAGGAGATCCCT ref:0:13:AGGCGAAA ref:0:13:TC 6 1050 +TACACTTGCA ref:0:9:TG ref:0:10:TT 6 9 +TCCGTTATTTTATAA ref:0:15:AACGTGC ref:0:15:AATTCGATATTCCCT 10 2089980 +ACTCATT ref:0:7:CTTAGTGATT ref:0:7:GTTTTATAAGTC 4 2028 +GAGTCTCTGTT ref:0:11:GCAGA ref:0:11:TGACTTAAATGA 7 3792 +TAGGTTGC ref:0:8:GT ref:0:8:GCTATAAGGAATACG 2 300 +TTTTACGCGCAAT ref:0:13:GGTT ref:0:12:GGGAGC 9 1205 +TGT ref:0:3:TA ref:0:3:AGTCCATGCAGG 2 96 +CCGGAAGGCAACCG ref:0:14:CGGCGCAT ref:0:14:GCTTTGTCGCCAAGAT 8 270216 +TTACC ref:0:5:GCTCTTTCGT ref:0:5:CGGGTCCAAAACGTCC 4 5635 +ACCCC ref:0:5:TATA ref:0:5:GCATGAGAAC 5 4640 +AACTAA ref:1:5:TAGCTGGTTGCGA ref:0:6:AAACAGCAT 2 60 +CTTA ref:0:2:AGGTG ref:0:4:GCT 1 8 +GTTTGC ref:0:6:TGCACACT ref:0:6:ACTAT 2 135 +AGTCA ref:0:5:CACC ref:0:5:TTTCAGCAGAAGA 2 24 +C ref:0:1:CAACACT ref:0:1:CAAGCGG 3 6 +TCCTGGCGTATACGGT ref:0:16:CTAACGGAAA ref:0:16:GTCACTAC 7 900 +GGAGGACTATTT ref:0:12:ATAGTCCTGAGTGT ref:0:12:GCGATCTT 5 142500 +GATAATATGAT ref:0:10:CAG ref:0:11:TAGGGAGGTCTAAGTC 5 1368 +GTCGCAGCC ref:0:9:GCGC ref:1:8:CGCGA 4 36 +AGTA ref:0:4:AAGG ref:0:4:TT 1 45 +AGTGCAGCAGCTTC ref:1:13:CCCTA ref:0:14:AT 9 35 +GGCAGCATGAGCGGT ref:0:15:CAGATGCTAGCGC ref:0:15:CTCTAATAGTG 5 585 +TCATTCATGGGGCCAG ref:0:14:TATG ref:0:16:CGT 9 1656 +ACCGAGTAAGATTT ref:0:14:CAACCGGCACAC ref:0:14:AG 7 840 +AACCGCTGAACAGTT ref:0:15:AGATTTGCA ref:0:15:CATTT 7 2574 +AAAATATGG ref:0:9:GTTGAGACG ref:0:9:TGCTTG 6 3115 +TACGG ref:0:5:ACATTAA ref:0:5:ACGGCCCA 2 31 +AGG ref:1:2:GTCCAC ref:0:3:GGAGTCGC 3 7 +GCGTACAAGT ref:0:10:TGATGATTGACAGAAC ref:0:10:CTTGAGGCTGGAA 5 480 +TT ref:0:0:CAACGGCAG ref:0:2:ATGTC 1 1 +CGTCAGGCCGAATGA ref:0:15:TCGTG ref:0:15:GAAC 8 235 +ATCGCAATAGTG ref:0:12:CCACTACCCGC ref:0:12:C 6 78 +GTCTAACATCTAC ref:0:13:AGGTGCTAG ref:0:13:CCGTTACCTT 5 4170 +TGTTAATATTAAGT ref:0:14:TTGGTCCTCG ref:0:14:AAAA 5 16545 +CGACCA ref:0:6:AATAT ref:0:6:CCGACAG 1 64 +TTCTTGGCC ref:0:9:CG ref:0:9:ATAGTTTT 3 20 +ACGCGTTCG ref:0:9:GACTGATT ref:0:8:CGAAGT 3 48 +GAG ref:1:1:CATTA ref:0:2:TGAACATC 2 6 +TTATGGACGATGCT ref:0:14:GCGAG ref:0:14:AA 8 6 +AGGTT ref:0:5:AATATGATCTA ref:0:5:CACGCAGGTGCAGA 3 493 +GATCGTCAA ref:0:9:ATCCTCCCCTGTGT ref:1:8:TTCACTGAGGGCA 5 143310 +TTCC ref:0:4:GTG ref:0:4:TAACGTTGAGCAATCC 2 120 +T ref:0:1:GGGCCTGGGT ref:0:1:CGATGCGA 3 2 +ACTCTATGTGCCGGAA ref:0:16:GGTG ref:0:16:GTGAGCTAAAC 10 71604 +TAGTTTACCTCTTG ref:0:14:AGAGGGTGC ref:0:14:C 9 333 +TAAC ref:0:4:CGTTTT ref:0:4:CAGCA 2 324 +CCGCTTAATACGTA ref:0:14:AATGTGAC ref:0:14:GTTCAT 5 21 +TATTCGACCGACT ref:0:13:CGCCGGTA ref:0:13:CAC 6 36 +CCAATAATAG ref:0:10:GA ref:0:10:ATGTAAGCG 6 2940 +GTGCAAATAATGGA ref:0:14:AGCACCAC ref:0:14:TA 9 17960 +GGAGGTTGGTAG ref:0:12:GTGGTCAGCACCGCA ref:0:12:TGC 6 6090 +GCT ref:0:3:TCTGACGTGACGGCA ref:0:3:CTCCCTAGTTTTTC 5 95 +TGGTATC ref:0:7:TA ref:1:6:CGTA 3 6 +TCCA ref:0:4:TTCGCCTTCGT ref:0:4:CGGGCTCCTCT 4 448 +GAGGACAATTGA ref:0:12:CACGCCTGAGGTT ref:0:12:TCTTT 7 9492 +GG ref:0:2:AGCTGA ref:0:1:TTAAGAA 1 1 +GAATACCA ref:0:8:CGGCCGTCC ref:0:8:CAT 4 182 +TGAGTACA ref:0:8:GAGAATCCTGCGG ref:0:8:C 3 89 +C ref:0:1:TAACTA ref:0:1:GCGTGTGCAGGAACT 4 3 +AGCACTTA ref:0:8:TACTTATATTAATTAC ref:0:8:ACTTTGGGTGATGGG 5 1485 +TCGCTTTGAAGGGGCT ref:0:16:AAGCTGGGGCCG ref:0:16:AGCATTA 7 12096 +TAGCACATGAC ref:0:10:CCGCTGG ref:0:11:AACGATCCACCGG 3 468 +AAGC ref:0:4:CGAGGTCAAAG ref:0:4:GAGTAAGAGTCTCGA 5 270 +AGGAG ref:0:4:GTTGAT ref:1:4:TGAC 1 6 +TGCAGGTCTTGTC ref:2:11:GGCTCTAG ref:0:13:GTCATATGTGATAGAG 1 80 +GCGAGACC ref:0:8:AATCG ref:1:7:TGAAATAAAGAAT 3 432 +AAA ref:0:3:GCGCCACA ref:0:3:CTAAGAT 1 9 +GA ref:0:2:TGTCATAC ref:0:2:AATC 2 6 +TGGTGTC ref:0:7:TGA ref:0:7:AT 5 187 +CAAAGCA ref:0:7:ACGGCAT ref:0:7:TCAATCGAAGC 2 84 +CTGTCGT ref:0:7:TCCTCGGCTA ref:0:7:TTG 2 26 +CATGT ref:0:4:AGAGTGACGCAGAC ref:2:3:CCGCGACA 5 532 +ACACACCACGTAAATC ref:0:16:AGTGTGGGTG ref:0:16:CGTATGGGGGCGCGGG 13 130320 +GGCGTCATCGGCAAA ref:0:15:ATGTCTTCACGGCA ref:0:15:CGTGGG 4 855 +CACATCTCTGA ref:0:11:ACTCGC ref:0:11:TCGCAAATCCTG 2 168 +CCGC ref:0:4:CCTTCCCGTCC ref:0:4:ACTAGA 1 200 +GGGCTAGGATGTCATG ref:0:16:CAGTTTTGTTCAGG ref:0:16:CAT 7 1464 +CATGTCACGTC ref:0:11:TGCATATTGA ref:0:10:TGTGGTCGGGGATG 5 107172 +GTAAAATGC ref:0:9:GGCCCTCACGTG ref:0:9:CAACCTTGAT 5 27370 +GTGTCGTCTAG ref:0:11:AGTCAGTGGCACACCC ref:0:11:GAATCACCTTTATCTT 6 1378260 +ATTGCTTATA ref:0:10:CCGTCTTTG ref:0:10:AAGGCGTTTATGAAT 3 3744 +TATATT ref:0:6:A ref:1:5:AAAA 3 42 +GTCGAA ref:0:6:CTG ref:0:6:CGGCAAGACGGTATT 1 9 +AGAGCACA ref:0:8:TTAGA ref:0:8:GAGGG 4 493 +GCGTACCACGTTC ref:0:13:TTA ref:0:13:CATGAC 9 1940 +GGCGCAATTAGT ref:0:12:CGTGTCCGGGCGG ref:0:12:GA 5 432 +TCAAGTAAA ref:0:9:GGGGTTGTT ref:0:9:CTCAC 4 725 +T ref:0:1:GG ref:0:1:CCGACTCAATAGGGAT 2 9 +ATATGCGGGGTGC ref:0:13:TCT ref:0:12:CT 9 2 +GCA ref:0:3:GCCTCGGCGCATGC ref:0:3:AAAACGAAGT 2 130 +TGTGAACTGCCACCA ref:0:15:GTCG ref:0:15:TTAGGAAT 7 18 +AA ref:0:2:GGGTCGTGTG ref:1:1:CATTC 3 66 +TAGCTGTTGCGGACCG ref:0:16:ACCGTTTTAGACA ref:0:16:AAATATGA 8 907555 +TAAACAG ref:0:7:CAC ref:0:6:AGATGATGGGC 2 11 +GGC ref:0:3:TGGGGTTACGGCA ref:0:2:CTTCCTAAGATAT 4 294 +ACTTGCTTCCGC ref:1:11:CAACCGG ref:0:12:G 7 344 +GGAAGTCA ref:0:7:AGGAT ref:0:8:TGAGTTGCTAGA 1 48 +TGTA ref:0:4:GCCCCAACC ref:0:4:GTAATG 2 22 +GAGATG ref:0:6:TCGACTACGC ref:0:6:CCCGTCATACGC 6 336 +AT ref:0:2:CTTTAG ref:0:2:C 2 33 +TATCCGCTG ref:0:9:AT ref:0:9:GATGTC 5 12 +GGGCACA ref:0:7:ATAACCG ref:0:7:TTGTACTGGTCG 5 3450 +ACAA ref:0:4:TTTTGATTTTAC ref:0:4:GT 4 720 +GATACTACGAC ref:0:11:CTCACTCTCCTTGT ref:0:11:GGCCTCGGCTGTCTTC 8 547664 +GAAAAT ref:1:5: ref:0:6:TATTGATCTGAAA 1 1 +CCGCCA ref:0:6:CGGATTT ref:0:5:AG 3 27 +AAGTGCC ref:0:7:CACTGGATG ref:0:7:CT 4 84 +TCC ref:0:3:GAAATCTGCAA ref:0:2:CGGG 1 1 +TGGACATACG ref:0:10:GC ref:0:10:AGTTAT 6 712 +CAATACCCGGTATC ref:0:14:CCTACTGATAGTCCCG ref:0:14:GTCTA 5 3072 +CTTAGA ref:0:6:GGCCTAATA ref:0:6:CGGCAACAA 5 9006 +TGACACAAAAGCGCG ref:0:15:TT ref:0:15:GCAAGG 8 768 +CACTATT ref:0:7:TCTTTACGTCTTGTA ref:0:7:GA 1 63 +GGTCATTCT ref:0:9:T ref:0:9:CTCAGTATA 4 120 +GTCGGTTTGC ref:0:10:TCTGGCA ref:0:10:TCTCCGGCAGCGAGG 6 1170 +CGTTGCTCACTCG ref:0:13:GT ref:1:12:CCAAGAAG 6 390 +GTCAGCA ref:0:7:CGGATGATGAAGGGA ref:1:6:TT 3 1974 +CCCTTGTATATGG ref:0:13:CCAGATGTTCCCTCA ref:0:13:AAACTCACATCT 6 1680 +CTG ref:0:3:TGCACCGTCGTCAGC ref:0:3:ATAGTCTGTTATA 4 10 +GTGACAA ref:0:7:AAGAGCGCGA ref:0:7:CTTTCTAAAC 2 11730 +ATATATTGCCATA ref:0:13:ACGTT ref:0:13:GAGACTGAC 8 96500 +TGGATCTTGTG ref:1:10:TCCTTCTAGGGAT ref:0:11:GGCCTAGGA 5 702 +TCTCCTCCG ref:0:9:GC ref:0:9:AGCGAAAGCTTCCA 5 11448 +AGTACTGAAA ref:1:9:TATTCCCATGA ref:0:10:A 3 45 +T ref:0:1:GGCTTTAGTGTGA ref:0:1:TTGGTTGTCCAG 6 25 +AAAC ref:0:4:TTGGGCGTAG ref:0:4:TCACGAAACG 4 708 +AATACGC ref:0:7:CTTGGTATGGAAGACT ref:0:5: 2 25 +AT ref:0:2:AATTTTGTATCTCTAA ref:0:2:CTGCGACC 4 95 +TGTG ref:0:4:AGTTCTT ref:0:4:GTGATACGG 2 92 +GCTAA ref:0:5:CTGT ref:0:5:CCAGCC 3 208 +G ref:0:1:CTAGAACACC ref:0:1:GTGTTCTGAC 4 3 +CTGATTGA ref:0:8:TTAC ref:0:8:CGACTAGGCCTT 3 222 +CGCTTTGACCTGGGTC ref:0:16:TTAATCACGTCGAG ref:0:16:GCTATCGTACC 7 23868 +CGGTATCTGT ref:0:10:TGTCAACG ref:0:10:ACATACATAGAGTT 2 240 +GAAGT ref:0:5:ATATGACAATAGG ref:0:5:GCTTGGTAT 3 1541 +CCGAT ref:0:4:TCC ref:0:5:AA 1 6 +AA ref:0:2:GTTTAT ref:0:2:GGCACGATCCGAGGG 2 21 +GCGTCAT ref:0:7:C ref:0:7:GTGCGA 3 12 +CTCGGTT ref:0:7:AAA ref:0:7:CGACCTTTCGT 3 4320 +ACCATTACA ref:0:9:AG ref:0:9:ATGGTGG 7 380 +CAGTGT ref:0:6:CCGAGCTCTAG ref:0:6:GGGAGAG 3 64 +TGCGGCAATA ref:0:10:CCCTG ref:0:10:AG 7 342 +GCTCGCCAAACCGGTA ref:0:16:CAGTGGTCTAG ref:0:16:TCGTAGGGAATG 10 329622 +CGAGT ref:0:5:GGAATGTTCCATGTT ref:0:5:GGCCCATGC 5 1848 +ATGAGCGC ref:0:8:TGGGCATCTTAA ref:0:5:GTTT 2 658 +CAGCCCTGCAAC ref:1:11:TTACTTGCGGCCCT ref:0:12:AGGCCATCCA 4 44536 +CA ref:0:2:TAACCTGCAG ref:0:2:TCTCCTTCAGTGTCTC 5 12 +GAGGCAC ref:0:7:AAAAACCTTCG ref:0:7:GTGGAAGGCCACGT 3 11544 +TAAGAA ref:0:6:GATATTTGT ref:0:6:AAAGGCCTG 4 3476 +AGATCACGGGCAGCC ref:0:15:GCTTATCACAGG ref:3:12:AGAGTCTCTAAT 3 54 +AGG ref:0:3:C ref:0:3:ACTTTAATTTTTTA 3 748 +GAATTTAGCGTG ref:0:12:AGTGCGAATGTATGTC ref:0:12:TCCAGT 4 4725 +AGGTTAGTCCTC ref:0:12:CCTCGTG ref:0:12:GCCG 8 15 +GG ref:0:2:C ref:0:2:GGTATCTCGT 1 9 +AA ref:0:2:GTCTATCCAGCCGC ref:0:2:TGGAGAGATTAC 3 6 +GTCT ref:0:4:AACCGGAT ref:0:4:AGCAAG 3 108 +ATCTACAAGATG ref:1:11:CCCCTACT ref:0:12:GGCGACACCC 6 12480 +AACGCACCAGAT ref:0:12:C ref:0:12:TGCCCAACGGGCTATT 4 192 +TCTGTATCAT ref:0:10:ATGCTTACTCGTCCTG ref:0:10:C 2 26 +T ref:0:1:GCC ref:0:1:CCCATCCGAGTCC 3 8 +GA ref:0:2:TGATG ref:1:1:AAGTTGGGCC 2 2 +GGCTTGAGTGTC ref:0:12:GATATGTTAAAGCGAG ref:0:12:CTGTG 4 2288 +AGGCTAAACGT ref:0:11:TC ref:0:11:AA 7 6 +GCCG ref:0:4:TGGTTTTTG ref:0:4:ATCCGAGCC 2 400 +C ref:0:1:ATGCGA ref:0:1:GGCCGGG 2 2 +GGGCTCACTCA ref:0:11:ATGTCC ref:0:11:AAA 6 360 +CCTTCAGCTAG ref:0:11:ATGTCCCTCTCGTT ref:0:11:ACAGGT 4 510 +CGA ref:0:3:AGGATA ref:0:3:CCCGGTTAAAGTCT 2 180 +CAGGATGAAC ref:0:10:G ref:0:10:ATCAATAGGA 4 18 +GGCCTGTCCGACCCC ref:0:15:GAAACGTGATGA ref:0:15:ACGATCGTTTGG 10 238750 +TCTCAGAGAA ref:0:10:TCGGGAC ref:0:10:TGAATACAAT 4 14904 +CTAGTTGCTA ref:0:9:TTTTTCATCG ref:0:10:AAATCG 4 5724 +CACGCCG ref:0:6:AGGACGTACCT ref:1:6:TACCGCAGTGGC 1 165 +CG ref:0:2:TTCCGC ref:0:2:ACACGGAGAT 1 12 +ATACCAACTT ref:0:10:GGACTCC ref:0:10:GTACAAA 4 260 +CA ref:0:2:CTATTGACACTTT ref:0:2:CCCACAGT 3 28 +CCGGTCTAGGATACG ref:0:15:AGTTTA ref:2:13:GTATCATGAGC 6 2744 +GGC ref:0:3:GGTTGCACGC ref:0:3:AGCGGGGCTAA 2 120 +TAG ref:0:3:TTTCCACTA ref:0:3:GGGCGACCGAT 3 96 +GGAGGAGCGATG ref:0:12:ATCCA ref:0:12:CCTACGATTA 7 10560 +CTGGGCCCTT ref:1:9:CCCAGT ref:0:8:CCTCGAAGA 2 200 +ATCGCCC ref:0:7:GTGCGTAGCTATAA ref:2:5: 2 190 +GTCTTT ref:0:6:GGGAAGTCTCATGAC ref:0:6:CAGACTG 3 384 +AGGTGTTGTTGAA ref:0:11:TGT ref:0:13:CCATTTAT 6 380 +TAACTCCC ref:0:8:ACCCCGTTTCC ref:0:8:CAGAGCACG 3 13888 +TACTACTGGTA ref:0:11:GGTATACGCTAGTC ref:1:10:CCCTAGCATTTT 3 2142 +GAAAGATACTA ref:0:11:AGTAAGCCCGAGTTCC ref:0:10:AATTAATGTG 3 780 +GTTGCTAGTCA ref:0:11:TAAGTAATACT ref:0:11:TATGTTAGTAAATGAT 6 2160 +TACAATTCTTCTGTG ref:0:15:CACTTC ref:0:15:AGGGCCGCACTCGGA 6 44 +TAGTTGAT ref:0:8:AAATCAACCCTTGG ref:0:7:ACCGTCT 3 36 +CACGCAGCTTCGATC ref:0:15:GGATGAGTACGAATAT ref:0:15:GGCA 6 324 +T ref:0:1:CAAGTCCACTT ref:0:1:GATCACGAAACAG 5 3 +CGAT ref:0:4:ACCCC ref:1:3:TGAACGCCGTACCCC 4 80 +GCCTATCCGAAC ref:0:12:CTCCCG ref:0:12:TTC 6 63 +GTAGAGATCTA ref:0:11:TTACACGAT ref:0:11:A 5 48 +CAGGCCTGGA ref:0:9:AGGCTAGCTC ref:1:9:GTAAGTGCAAACT 3 30 +TCCTCAGGCG ref:0:10:ACCGGA ref:0:10:TCG 5 490 +ACAGA ref:0:5:TCCACAGATTAG ref:0:5:TCTCAT 3 68 +TATTCGCCGTGCTG ref:0:14:GCC ref:0:14:ACGT 8 33 +GTATAATTA ref:0:9:TCCCATG ref:0:8:TTTAA 3 930 +CCCATC ref:0:6:TGTAGCTAGAGTTT ref:0:6:TACCCTTAATG 5 2184 +TCTTTTATATT ref:0:11:AGAGACAAGCC ref:0:11:CAGTCAG 8 180 +ACACGACTGACGG ref:0:13:CCATTACCACAAA ref:4:9:ACGATTCCT 4 20052 +GTCTTGACTTCTACA ref:0:13:GAACTAGGTGTAA ref:0:15:ACAAAG 7 15648 +TGTATACGGT ref:1:9:GGGCG ref:0:10:CCGTCTATCTTT 2 7420 +CAGATACCG ref:0:9:CCTTCATATCT ref:0:9:ACGTCCTC 3 2796 +ATTTAACGAG ref:0:10:CCGGATGGTGAAACT ref:0:10:CACAATGGT 4 752 +TGGAAACGAA ref:0:10:G ref:1:9:CA 6 6 +TACTCTAATCGTC ref:0:13:CTCATAG ref:0:13:ATAATAA 6 329 +TG ref:0:2:CCATCGTCCG ref:1:1:ACGGGG 2 12 +ACAATA ref:0:5:GGCAGAACCGTC ref:0:6:CTTTCC 2 385 +A ref:0:1:TGCCAC ref:0:1:CGACATCCG 3 2 +TTGATCCA ref:0:8:TAAATGCACGTTATTA ref:0:8:AATAATT 6 7920 +AGGGGATGCG ref:0:10:TTTTAACTG ref:0:10:CTTG 7 255 +CCGACCGCAGGCTT ref:0:14:CAGCAGGCACTAGAG ref:0:14:TCGACAT 4 504 +CGTGGCCGAGC ref:0:11:ACCTGGAGACTGGT ref:1:10:GCAAAG 4 7824 +GCGGACGGTCT ref:0:11:CTTCTCACTC ref:0:11:ACTTCTCATTC 10 5822 +GAACAGGTGGGAGG ref:0:14:TTATACAAGCATG ref:0:14:ATCTCGTGTCCCATAA 8 13919994 +CCACGGTAAAAAG ref:0:13:TGCGGGTATATTTGCG ref:0:13:GTTGACT 8 11530692 +TTAAATATTC ref:0:10:GGCA ref:0:10:TCTTCG 6 7344 +CTCTCACACGGAT ref:0:13:TTGA ref:0:13:AAGTGGC 6 40 +GCTTAAGT ref:1:7:ACG ref:0:8:AACTTAATG 2 24 +GGCCGCT ref:0:5:CGAAGCGGT ref:0:7:TTTAGGCTC 2 75 +TGTGCGA ref:0:7:CTTCACCAAC ref:0:7:CCCGAATACT 6 3367 +GGCCCGGGCATAGGC ref:0:15:TTACCTGTTGGATAGG ref:0:14:ATGTAGAGACTACTG 7 135900 +CG ref:0:2:CAATTAAGGAACGGA ref:0:2:AGATAG 4 48 +CAGACA ref:2:4:GG ref:0:6:TAACACTGCCTT 2 60 +CCTCTGCTT ref:0:9:TGACAAGG ref:0:9:AATTGTTC 3 276 +AAACTAAGACG ref:0:11:CTCGTGCGTAC ref:0:10:GTTAAGCCAT 5 14100 +GACTTG ref:0:6:GGAC ref:0:6:TTTATT 1 8 +TCCTGCCTACCGTTC ref:0:15:AGTACA ref:0:14:GCCGGGCCGACAT 6 18144 +CACATC ref:0:6:GCCTCCG ref:0:6:C 2 6 +AAAGAACGGCG ref:0:11:GGGAGAGAGGGGGGT ref:0:11:TGGG 4 37300 +GGCACCCCTGGCAGGG ref:0:16:ATCCCAACAGCCG ref:0:16:ATCTCTGAG 7 31140 +ATGA ref:0:4:TCCCCATCAA ref:0:4:A 1 10 +TCGATACAC ref:0:9:TTACCGGGTTAGACA ref:0:9:CTAGCAGG 3 792 +ACCCGGGCGTTAT ref:0:13:TGTTGTCAGCTGAG ref:0:13:GCGA 7 864 +AAC ref:0:3:ATTGGCGA ref:0:3:TTCATCTC 3 98 +C ref:0:1:AAAGTCGC ref:0:1:TGTAATCCTAGCG 5 6 +AATGAACGGAGAT ref:1:12:CTATGAGTGGCCTTA ref:0:13:CTGTACGGCG 4 288 +TCTCAC ref:0:6:ATGGCGAGTTATCTG ref:0:6:AT 2 18 +ATAATGGCGCGTTAC ref:0:15:TCCGTCAATTGATATG ref:0:14:AAGTGATTGAGATTG 9 5743584 +CATTAAGT ref:1:7:TTGTGGTAGTC ref:0:8:TGCGCAACC 4 4824 +A ref:0:1:GT ref:0:1:CCAAAACGCTTAT 2 15 +GGGACA ref:0:6:TACCAACGAATTC ref:0:6:CGTATCTTCGGTGCC 6 8074 +G ref:0:1:T ref:0:1:AC 1 6 +TG ref:0:2:TTTA ref:0:2:GCGACACA 1 36 +CATATCGG ref:0:8:TGTACGTTGGTGAGCG ref:0:8:GATCTCT 4 14448 +AAAG ref:0:4:TC ref:0:4:CCTA 4 225 +GGGGAATAAGGGAAAG ref:0:15:GAGTAGCCTAGA ref:0:16:ACGGGATC 7 2445744 +GCCCGTATCCCGT ref:0:13:GGGGG ref:0:13:GCT 8 1575 +GACGACCAC ref:1:8:TCTAA ref:1:8:CGGGGGCTCATCTTG 1 60 +AATGGCTCCTATCTAA ref:0:16:GTAGATGGTC ref:0:16:CTCAA 6 65 +C ref:0:1:TCTAAGAGT ref:0:1:G 1 2 +TGGGATGCCCAA ref:0:12:TTGTACGGGGCTCTAC ref:0:12:GTTCCCCGA 3 76076 +AAGA ref:0:4:CGACAT ref:0:4:GGTCTTGATACG 3 18 +G ref:0:1:AGCATGAAATTAT ref:0:1:TCTGCTTCGGATGAG 6 10 +CATGTATGCA ref:0:10:TTT ref:0:10:AATTAAGG 4 45 +GAGTGGGAGGCAG ref:0:13:TG ref:0:13:CAT 10 24 +GCAGTAC ref:0:7:TGCAGTTGAT ref:0:7:TGCGCACTAATACG 2 208 +TCTCTCCAC ref:0:9:CAGTTCGGTGT ref:0:9:CACG 5 520 +GAAGCGA ref:0:7:A ref:0:7:ATAG 4 6 +C ref:0:1:AGA ref:0:1:CGATCC 2 12 +CCAATACGCTCAGTTG ref:0:16:TTTC ref:0:16:GAATCTATAT 8 120 +GCCCCGCCTCG ref:0:10:ACCGTTGCGTAACCA ref:0:11:AGTACGA 6 5047 +ATGTCCGTTACTCG ref:0:14:GATCCACCAGTAGGGG ref:0:14:CCCAAAAACT 6 1236605 +ACAACGCCGCT ref:0:11:TCACCACCGAAA ref:1:9:TCCATACTTTCGAG 5 84360 +GGGGCCCAATGC ref:0:12:GGATATATGCA ref:0:12:GCCATTA 5 26136 +CGTCGTAAGGATATG ref:0:15:GAGTCCTCCGGTGGCT ref:1:14:GAGCGGAAATCT 6 25920 +CTAAATCAAGCCTGGG ref:0:16:AATTACT ref:0:16:TCAAAC 9 3220 +TCTTGTACATT ref:0:11:GCAGG ref:0:11:TCAGT 7 186 +CTGTACCGACG ref:0:11:TTCTATAGCGCAAC ref:0:11:TTTT 5 1404 +CCAATGT ref:0:7:TAGTAC ref:0:7:CTTAAGACCGGGGGTT 3 6008 +A ref:1:0:CTCTCGTCCCG ref:0:1:AACCTAGATACGCGT 8 5 +AGTGTCAATCGCT ref:1:12:TACCGACAAAC ref:0:13:A 6 60 +TGAGGGCAAT ref:0:9:ACA ref:0:10:GATT 5 56 +GTCACTCGACCG ref:1:11:TTATAAAAAGCC ref:0:11:ATTTA 5 3936 +GGA ref:0:2:T ref:0:3:G 1 6 +TCATTGCCGT ref:0:10:GAACCG ref:0:10:T 5 76 +ACA ref:0:3:AAGGGCCGTTTCGC ref:0:3:GTGACCAGAGGCC 5 172 +GGCGCGTAGTTTT ref:0:13:CGTT ref:0:13:TCCCAACGTGT 7 45612 +AAATGTAAGTGG ref:0:12:GGCAA ref:0:12:CAGCGCGTCAT 8 4563 +TGTTAGAGATAC ref:0:12:CTGATAGACCAAGTGA ref:0:12:CAT 4 693 +C ref:0:1:GCAACTGC ref:0:1:ACTTAA 2 3 +CCTACG ref:0:6:CTCT ref:0:6:TCTAA 3 60 +TGTGTAGGTCC ref:0:11:ATACAGCAAACG ref:0:11:TGGG 4 560 +CAGT ref:0:4:GG ref:0:4:CTCGGAGCTGGA 1 10 +AGCCA ref:0:4:TAAAATAGACCCC ref:0:5:TTCAGGCGCGAGCG 2 60 +GGGACTGACAGCTCGC ref:0:16:TGGGAGGAGGTGGAG ref:0:16:GCCACCGT 3 3192 +GTGCAGCAAG ref:0:10:T ref:0:10:A 8 3 +C ref:0:1:GTTCTATGATT ref:0:1:CTCGCGGC 2 4 +AC ref:0:2:CAG ref:1:1:CTGCGGGTATT 1 6 +AC ref:0:2:TTAATCG ref:0:2:TACGAGGCCACAGA 3 16 +ACCTTTTCTGG ref:0:11:GCAACCGATC ref:0:11:G 5 80 +GCACGTCCATCA ref:0:12:CGCCCAACCGGAGAGT ref:0:12:GGCAGGGCGGA 6 955996 +ATACCGATGTCAC ref:0:13:GCCCA ref:0:13:CTCTTCGGTTTTCTAA 5 1056 +CTCAGTTTC ref:0:9:TGACCGAG ref:0:9:CGCTTACGATCG 4 264 +ACTGTACACGC ref:0:11:TCATGTGTTCC ref:0:11:TATCGTGATG 6 5697 +CTACCCTTCATAGCG ref:0:15:GCTGTGCCGATGTT ref:0:15:GTTTTCGGGGAGA 9 5159463 +GGTAGATA ref:0:8:CTCGGATTTGTCCTAA ref:0:8:GAGGAGTGACTC 3 2849 +GGGT ref:0:4:CCCACAAGC ref:0:4:AATAG 6 3100 +GG ref:0:2:CCTCC ref:0:2:TCAC 5 315 +ATTTTTAGTTCTCAGG ref:0:16:T ref:0:16:G 14 24 +GG ref:0:2:TGTGAGATCCT ref:0:2:GCATGTGTCA 4 9 +TGCTACATGGAA ref:0:12:GTGGCA ref:0:12:ATACGAATAGTAC 4 1440 +GTCTTTC ref:1:6:CGTA ref:0:7:AGT 4 64 +ACGAGCAG ref:0:8:GA ref:0:8:CAGC 3 3 +AAATCCCTGG ref:0:10:GCCCTCGTCCGGG ref:0:10:ATTGAAACCCGTCCGT 5 7800 +CCAGAAACGGAAATC ref:0:15:CGTCCGATTG ref:0:15:TTTCATCGGGT 8 465696 +GT ref:0:2:TGAGTGAGTCGCC ref:0:2:ATTA 2 30 +CTTACCACTG ref:0:10:CC ref:0:10:TTGTATAAAATGC 2 2946 +TCGAAAGCGTATT ref:0:13:GG ref:1:12:GACCGAAGTTTG 4 42 +TTTACT ref:0:5:AGGAGGTGGTAG ref:1:4:CGCTATAACC 1 88 +ACCGTAATGTT ref:0:9:GACCAAGC ref:0:11:ATAGGCAGAAT 2 40 +T ref:0:1:ATCTAAA ref:0:1:CTGGCAATCTT 3 8 +CGATC ref:0:5:TGGACCGCCGG ref:2:3:AACCTT 2 952 +AGG ref:0:3:CGCAGCAGAGAT ref:0:3:CACTCC 3 60 +TGCGCGGGTATAAG ref:0:14:ATCAAT ref:0:14:TTAGGCTACTC 7 240 +TTTGCC ref:0:6:TT ref:0:6:AGA 3 36 +CCCGTCT ref:0:7:T ref:0:7:ACTAA 5 96 +C ref:0:1:AACACTTTCA ref:0:1:AGGGCAGCAAGT 4 6 +ATAAGTGCAAG ref:0:11:AGGGAT ref:0:11:TAGAGCATTGTG 5 7072 +GAAGTGAG ref:0:8:ACATCCG ref:1:7:ACTGGCTACCC 4 679 +T ref:0:1:TCAGTAAA ref:0:1:ATCTAAGG 4 4 +TGC ref:0:3:G ref:0:3:CCGCGATGG 1 6 +CTTCTGTCTGA ref:0:11:AAGGCAGCG ref:0:10:GTACGAGTGCCC 6 35775 +CGCAGAAGAGCA ref:0:12:GACCTCGGTCAACACT ref:0:12:C 5 1842 +GG ref:1:0:ATCCTCCC ref:0:2:CGATAA 2 7 +CTCATATTACAG ref:0:12:TTCCTTGGGGT ref:0:12:T 7 6340 +TTCAAAACGGAACTGA ref:0:16:GAATCGACATCC ref:0:16:G 9 6750 +GATTCTCCAACGAT ref:0:14:AA ref:0:14:ATTGTATAAAA 7 1236 +TGACTTACTA ref:0:10:GACCCCGGG ref:0:9:GTGACTTTG 2 246 +AAAACCC ref:0:7:AAACCTTT ref:0:7:TGC 2 1536 +TGTTCCGGCGTGT ref:0:13:GGT ref:0:13:CACATAGCCC 6 16 +TACTTCACGACCA ref:0:13:GA ref:0:13:ATTGATCGCC 4 4 +AATGAACTG ref:0:9:AAG ref:0:9:TGTACATA 3 56 +CCACCCGTGCTA ref:0:12:GTGGGGACATG ref:0:12:GTTTTCGATCACTG 3 516 +CGGTAT ref:0:6:AGACCCGGGAAGTG ref:0:6:ACCACGGGAAC 6 2574 +GATACCTTT ref:0:9:CTAT ref:0:9:TCTTGTGGTATG 5 442 +TG ref:0:2:TTCCGCTATAGT ref:0:1:TATTCCCTCCTACC 7 30 +AGG ref:1:2:GTGTTCGGG ref:1:2:C 1 30 +AGACATGGTC ref:0:10:C ref:0:10:AT 7 12 +AGTGTTCTAT ref:1:9:TCTAGACTACACCA ref:0:10:AAA 5 5940 +GCAGGCACTT ref:0:10:TTTTAGATAC ref:0:10:TCATTCGTGCGAAAAC 5 2312 +G ref:0:1:TGTCTGAG ref:0:1:AGATCCAGGATAC 4 9 +GCAAATCAGTG ref:0:11:AAAGTAGCTCTGTT ref:0:11:TGTCA 1 2 +GACGCTAGGT ref:1:9:AACTA ref:0:10:CATAAAG 4 324 +TCATCCTAA ref:0:9:CCACCG ref:1:6:GCATATACAGTT 1 444 +AGAGTGATCACTCAAA ref:0:16:TCCCCTCTTAT ref:0:16:TATAAGTGA 8 99750 +TGGGA ref:0:5:ATT ref:0:5:CGG 2 49 +TAACCATG ref:0:7:TCGCGTAACGGAA ref:1:7:ACGATAC 3 468 +TCAACGGGAAT ref:0:11:C ref:0:11:CATCCTAGCC 7 4852 +TCAAAGGTA ref:0:9:CATGCACGCTG ref:1:8:GTGTTAGG 3 242 +TTGCGTTTGCCA ref:0:12:CGCCCGAGAGACCAG ref:1:11:AAATGG 3 756 +TT ref:0:2:GTCTCAACCTCGCAGT ref:0:2:GACGG 5 126 +ACGACCCTCATTTTT ref:0:15:TCAAGAAGCAATT ref:0:15:CCAGCAATAGAG 10 427451200 +CG ref:0:2:TTTCCGTAC ref:0:2:CACCCAAACGTC 3 10 +T ref:0:1:GCCAAATGTACA ref:0:1:TTTATTTAGGGTGC 4 14 +ACTGGCACTGTTT ref:0:13:TTATATG ref:0:13:GCTCATG 6 2 +TCCCAAGTCCTTA ref:0:13:GTCTGCAACC ref:0:13:ACCGCTTGGG 3 280 +CGAGCCCTTGAAC ref:0:13:TCAAACCGAGTCAA ref:1:12:AGGGTAGGAGAGTG 6 798912 +TATAGCACGACTCACC ref:0:16:A ref:0:16:ATCTCGCTG 9 50 +TTTA ref:0:4:ATTTCCAA ref:0:4:AATACTC 2 50 +GTCTTTC ref:0:7:CTCATGCC ref:0:7:TTTCTCC 3 126 +GGCGTACTTATG ref:0:12:GCACGGCTATACTA ref:0:12:GGATAGTT 4 15252 +TATGAGGCGTATAA ref:0:14:GGTCTA ref:0:14:TGC 8 264 +GTGTGA ref:1:5:GGCC ref:0:5:AT 1 18 +GCTGTAAGCG ref:1:9:TT ref:1:9:AACTCGGTACC 3 18 +TTCGAA ref:0:6:ATTGAG ref:0:6:AGAAA 2 36 +GGAATACATGACTC ref:0:14:TCCGTGAGA ref:0:14:GTTGAAGATGGCG 7 17205 +AAGAATTC ref:0:8:CATTG ref:0:8:CGGAGCGACTTG 5 2640 +ATTAAAAC ref:0:7: ref:0:7:GATA 4 8 +CTTGTATCATAAAACC ref:0:14:TATAATAA ref:0:16:ATTGCTCTACAAGAGT 3 5520 +TTGAGCAATCCTC ref:0:13:C ref:0:13:AAATATCACG 7 360 +TTGAATCCA ref:0:9:TT ref:1:8:CGTAGAAACG 3 69 +CGTTTAGCA ref:0:7:GGCAAGTA ref:0:9:CCTATGC 2 75 +ATTAATAA ref:0:8:AA ref:0:8:TCTTT 3 100 +ACTTTA ref:1:5:CGGGCGGGG ref:0:6:GCCAAAAAATGTTT 3 80230 +GA ref:0:1:ACGCG ref:0:2:CTGCGCAGCCGT 3 4 +GATACCTTCACCCGA ref:1:14:TTT ref:0:15:A 10 4 +GTTCTTATGAAA ref:1:11:CT ref:1:11:G 8 3 +GCACCGC ref:0:7:TATGG ref:1:6:TAGCA 4 74 +GCTC ref:0:4:ACCCTGGTGTT ref:0:4:GCGAACGACTCC 2 2088 +AGGCTATGGCTT ref:0:12:TAACGCCT ref:0:12:CGGTCCAATCTTGAT 4 10260 +CACTG ref:0:5:GGTTATCC ref:0:5:CCTTTGTCGGAGTCGC 5 1512 +GGTGCGCGT ref:0:9:GG ref:0:9:ATTCACATATCAGA 4 6600 +CGCAGGGCACCTCAGG ref:0:16:AACGGCA ref:0:16:GGGAG 9 3808 +ATCGTCA ref:1:6:CGAG ref:0:7:TGTACGCAGTAC 3 48 +A ref:0:1:TGTG ref:0:1:GGACTCAGCGGTC 3 10 +GCGGTTA ref:0:7:TATTTTCCGCGCT ref:0:7:C 3 53 +CGACCGTAGAC ref:0:11:TTGTTTGAATCG ref:0:11:GGTT 6 3636 +GGG ref:0:3:C ref:0:3:AGATTGCTTAT 2 48 +G ref:0:1:ACTGTACAGAATGTC ref:0:1:GATCTGATGGGCA 7 15 +AGCTC ref:1:4:GGGATAAAAACAACG ref:0:5:GTCCATCTTC 2 378 +CAA ref:0:3:GGCCGAAATT ref:0:3:TCTTTTGCGA 2 72 +CATCGTAATGCTTCGG ref:0:16:TAAAGGTCCGACTAC ref:0:16:T 8 705 +ATCTTTTATCTGCC ref:1:13:TGGAGAA ref:0:12:GACTCATGCGAG 6 10824 +GCC ref:1:2: ref:0:3:CGATTC 1 6 +AAGCA ref:0:5:ACT ref:0:5:GTGG 3 152 +CTC ref:0:3:GAACCAGGGTATACTA ref:0:3:CGGCAC 3 40 +GGGCA ref:0:5:AGACCCTATAGAAAGC ref:0:5:TAGGGAGCT 3 9 +CGGCACCATCGGGT ref:0:13:GTTTCGAG ref:0:14:TGGAATCTGG 5 2048 +TCCCAGGCATG ref:0:11:AAGCTCTCCTTTCGG ref:0:11:TTTAAGCAATTCCC 5 547146 +AGAGCGACAT ref:0:10:TTGCTGTC ref:1:9:ACGG 4 273 +AATCGGTAATTACC ref:0:14:CTCTATCAAATTG ref:0:14:GGCTAGCGCG 4 8208 +CGA ref:0:3:GC ref:0:2:AAATCCT 1 15 +GGAGAT ref:0:6:CAACTCTTGGCTGGTC ref:0:6:C 3 84 +AGGATTAGTCTA ref:0:12:ACCAGTAATT ref:0:12:CG 7 1888 +TTT ref:0:3:TTGATAAAAGCCGTTA ref:0:3:TGTTTTTCGAG 3 200 +GATCCG ref:0:6:CCTGCAGG ref:0:6:AAA 3 2212 +GGATTA ref:0:6:GTTATGCCCTAAC ref:0:6:GGGGGC 2 1640 +CTTTGAGT ref:0:7:AAAACCCA ref:0:8:GCAATAATGTTTC 3 4284 +CGAGTTAAT ref:0:9:TCAC ref:0:9:ACTGAAC 6 1085 +GGGCGC ref:0:6:GATTTTGGAGTGCGG ref:0:6:AGGA 3 1218 +GTACAGCCGCCG ref:0:12:GGTTTGTGTGCAGAAC ref:0:12:CAC 6 53960 +TCATCGT ref:0:7:GCAGCACA ref:0:7:CATTGGG 3 2565 +TCTGGGTTTGTTT ref:0:13:CCCTCTCGCA ref:0:13:GTGTC 8 191322 +CACTAAC ref:0:7:CCGCTAAATCTATC ref:0:7:TCTTCCTGAGACTTCA 5 1296 +GTCTCGGGTGTATC ref:0:14:CATCGAG ref:0:14:CCTT 7 75 +A ref:0:1:TGCAACTGGGGAGCGG ref:0:1:GGCGCAG 4 3 +AGGTT ref:0:5:TATGC ref:0:5:GCTTGCACCGAATG 4 1170 +GCACAAACGAT ref:0:11:G ref:0:11:GCGGCGCCCCA 6 1546 +TTGGGGGT ref:0:8:TGTCTCGAC ref:0:8:ATCTTCGATG 7 493920 +CCACCCCCAT ref:0:10:AAGGGTGGAA ref:0:10:AGAGAATATCGT 9 22035 +GATTGT ref:1:5:CTG ref:0:6:ACCAACGACAGATAAC 2 35 +AAGAG ref:0:5:TTCGCTTC ref:0:5:CGGGCGGG 5 57905 +ATCCTAGCGCGAGT ref:0:13:AGGTAGTTGGCGC ref:0:14:TGTTCGGGTCGTT 8 1712722 +CATGCTTATGGCCTG ref:0:15:GTCGTGATTTGATA ref:0:15:T 7 280 +ACTAACTGTCAT ref:0:11:TCGC ref:0:12:CAGAGCCC 4 23 +GCCGTCGG ref:0:7:GGGTTTGT ref:0:8:CTTTATTGA 5 17220 +GCTTACGCG ref:1:8:GC ref:0:9:ACTAATCACTTTAG 1 58 +ATCCGCATA ref:0:9:CGCTATTTGTCAGAA ref:0:9:CTT 4 2109 +CACT ref:0:4:AAAGAA ref:0:4:CCGGTCACTT 1 612 +GGCTGTCGG ref:0:7:TGGTCATCT ref:0:9:TCGTATCCGAA 4 1782 +GGAT ref:0:4:ATCCCGT ref:0:4:CGA 2 27 +TTCCAAAGGTT ref:0:11:ATCTCTCCG ref:0:11:AT 4 102 +GATAC ref:0:5:CGGTGGGGTTAAT ref:0:5:TAAAACGACC 2 63089 +TCCTTAAGCACTCAC ref:2:13:ACATACGCGAGCC ref:0:15:TATCCCTACGTC 5 17000 +TCA ref:0:2:AACCGTCT ref:0:3:AGGC 2 5 +GGTACAT ref:0:7:AG ref:0:7:TGT 5 90 +G ref:0:1:AGAA ref:0:1:CA 1 3 +GAGGAA ref:0:6:CACAATATACCCATAG ref:0:6:GCGACGCTGCAGAG 5 2808 +CGCTTGGAGCCGCTG ref:0:15:TTAGTCAGGACGCTTC ref:0:15:TGTCGT 7 26640 +AAAACCGTAATGGCCA ref:0:16:GCCCAGAG ref:0:16:TTCATTGCT 9 1647150 +CGATCTATCCC ref:0:11:GTGAATAGCG ref:1:10:AGTCATAA 5 21536 +CCTACGACTA ref:0:10:GCAC ref:0:9:CAGGCC 5 512 +CGGGAGGCATACCTG ref:0:15:GA ref:1:14:TAATGTTCGAGG 9 137618 +CAGTGCGACTCTCG ref:0:14:ATTCTAC ref:0:14:GAAC 7 60 +GGTACCATGT ref:0:10:TACG ref:0:10:GCTG 4 8 +TACTTCCTC ref:0:9:GGCCAATAAAT ref:0:9:CGTAAGTGAGC 7 989120 +GGTTG ref:0:5:ACGGTTATGAGGC ref:0:5:A 1 54 +GCGGA ref:0:5:AGATGC ref:0:5:C 3 37 +CG ref:0:2:AAATA ref:0:2:CCGGTA 2 84 +CAGGCG ref:0:6:ATATTT ref:2:4:TGACCAC 4 8778 +GCCTTTTG ref:0:7:GGGGTCGGGAC ref:0:8:CTCCTTCC 3 848 +TCAACGTGAG ref:1:9:AAGTG ref:1:9:GGCGCT 3 32 +GTATGGAT ref:0:8:A ref:0:8:AAGTA 5 70 +AGTCACACCA ref:0:10:CTTACGCGTAT ref:0:10:G 4 155 +TGGCCCAACGCAAAT ref:0:15:AATTCAACA ref:0:15:AACTTCACTT 10 4656 +GGGTCGCATTCGATCT ref:0:16:ATCTGATATA ref:0:16:TCGACTAAGCAGGT 8 42920 +TCGCAG ref:0:6:TTGTCCCGTCT ref:0:6:GTATACTCTCGAC 5 5340 +ACCCTAAGTGCCG ref:0:12:CCGTGA ref:0:13:CAACTATA 6 1386 +A ref:1:0:CTG ref:0:1:CGGAG 1 1 +GCACTCCATAA ref:0:11:T ref:0:11:TAATGTT 8 802 +GGCAGCC ref:0:7:TACTACGCT ref:0:7:CAGGACTGTCAT 4 432 +GAA ref:0:3:TAGTTGACGCGCCTAG ref:0:3:TGCAAG 2 2 +GATTTATCGAATAG ref:0:14:AGCCCGAGATCGG ref:0:14:CACCAAAAGAAATT 8 9718056 +AGT ref:0:3:TGCCCACTA ref:0:3:GTGACG 3 8 +GAAG ref:0:4:AACA ref:0:3:TTATT 1 90 +AAGAG ref:1:0:TGGT ref:0:5:GTACA 2 14 +TCTAGCACGCCCATC ref:0:15:GTTGGGCACA ref:0:14:ATCTGACACGGTTT 4 11704 +CCTGTA ref:0:6:TAATCAATCTAGCCT ref:0:6:ATCAAGCAAT 6 120 +GTTGCA ref:0:5:AT ref:0:6:GCATGGG 3 235 +TA ref:0:2:GAGGTTAGTCATC ref:0:1:ACGCAGTCCC 5 5 +CTGTCTTGAACA ref:0:12:ATTACGACCCC ref:0:12:T 6 240 +CAAGATTACCCT ref:0:11:AAGCCG ref:0:12:AT 6 40 +TCTC ref:0:4:GGAG ref:0:4:TTGTGGTT 5 5460 +CTAC ref:0:4:CGCGCGAAGCTCTCGA ref:0:4:TCGGATAATGTTCC 6 444 +AAAGCAAT ref:0:7:TATGGTGCCATAC ref:0:7:GGGACTGAG 5 27984 +TTCATCTGGCGATT ref:0:14:CGTTTGC ref:0:14:CAA 7 32 +ACGATCAGAC ref:0:10:AACCCCAAATT ref:0:10:T 4 736 +GGGGATG ref:0:7:GTTGGGAACGGACATC ref:0:7:AACCCGGTTACC 6 63384 +TCACGAATCCGTGCG ref:0:15:TG ref:0:15:ATGAAGCT 9 270 +ATCTACCTGTC ref:0:11:TTGCG ref:0:11:CAGGGTAACT 4 1144 +TCAC ref:0:3:CTCTAATGTAAATAT ref:0:4:GGAT 2 78 +GGACCC ref:0:6:AATAGACGATCGAT ref:0:5:GAAGGCTCAAAGG 4 675 +AATATGCCGGT ref:0:11:TCAGTGA ref:0:11:TGCTGAGGCTCCTAG 7 53253 +TTGGCCGG ref:0:7:AAGCCTCGC ref:0:8:ACATAGTAAA 5 106650 +TATGTATCGGTTTGGA ref:0:16:CGCACCACAGGTAGCC ref:0:16:A 9 22968 +CTTAGCCA ref:0:8:CCCTCCCAGGACTT ref:0:8:TATTGCTACAGGCAGC 5 177234 +TTCACCG ref:0:7:AACACTCTTT ref:0:7:CCTCTCA 1 24 +GCAGTGCGGCGGGCGA ref:0:16:TGCAGACACCC ref:0:16:GTGACT 9 33558 +TAAGCGTAGCCAC ref:0:12:AGGGAT ref:0:13:ACACCAAGTATTGA 3 6 +CCGTTGGAGTCGAACT ref:0:16:ATCGGAAAC ref:0:16:CGTTTAGGACTCTTTT 4 33356 +GCGCAA ref:0:6:TCGAACC ref:0:6:TGATTCTCCAATAG 1 36 +GCCTCGACGACGA ref:0:13:T ref:0:13:GGCGTCC 8 50 +CAG ref:0:3:AGCACTCCACTGCATG ref:0:3:AAGGATCCATGGAGC 8 128 +CCATTA ref:0:6:CTGTACTGGG ref:0:6:GCGGTCA 3 96 +ACACCATA ref:0:7:TCGCA ref:0:8:CTGAGACTGAAT 4 1204 +TAGTACGTCT ref:0:10:TATTCATAAGAAGGT ref:0:10:GTA 3 2270 +GAATGGGGAAAA ref:0:12:CTTTTGTGCA ref:0:12:TTCAAGTTA 9 12452340 +CCTAATG ref:0:7:GTAT ref:0:7:CAGGGGACCA 3 708 +GTCC ref:0:4:CACAACCGGAC ref:0:4:GTAGGCACCTTGTCC 5 2120 +GCGCCGAATATCGC ref:0:14:CCGCATATA ref:0:14:GT 7 612 +TTCGGGCCATGAAAT ref:0:14:TAGAGCGCCTGGGGA ref:0:15:GTGTCTTA 5 183430 +AGACCTTTTGGTCTG ref:0:15:C ref:0:15:GTAT 11 198 +ATATTGTAT ref:0:9:CTGGCT ref:0:9:GTACCTG 5 1449 +TACCACGCTTT ref:0:11:TCTGCCACTGTAAC ref:1:10:GGG 5 16764 +ATCACCGGTACATGGA ref:0:16:ACCTGATGC ref:0:16:GATTACCTT 7 660 +TTTGG ref:0:4:TCACGA ref:0:5:TTACCGAAC 4 630 +CTTGTGCAA ref:1:8:GGC ref:0:9:ACCGAGGTTT 2 2 +GCGC ref:0:4:ATCAGTTG ref:0:4:GTCTGCGTAGATGTCT 4 198 +CGCAATGGTTTCT ref:1:12:CACGGGGATAGGAT ref:0:13:AATC 4 44 +GCACTAGAGCCACCCG ref:0:16:TC ref:0:16:ACTATGTCCTTAGTTA 7 35 +GTCGAGTGGCTTC ref:0:13:CAGAACGTGTCTT ref:0:12:CAGAGCAGATCAT 5 810 +AAACGGTTTGTGT ref:0:13:T ref:0:12:ATACTTAGAAATC 5 160 +TAG ref:0:3:AATCTCA ref:0:3:TGTG 1 10 +AGGATGACCATA ref:0:12:CCAGGGCGGC ref:0:12:TGA 4 3 +T ref:0:1:TGGTTGATCTATTC ref:0:1:A 1 14 +TAC ref:0:2:TGATTGTAT ref:0:3:GGCTGAG 2 10 +CCCGAAGTTCTCAGTC ref:0:16:CAAATTCTAAGG ref:0:16:GGTACACATCCAG 6 38448 +GTCGAGATC ref:0:8:TGATCGAGAA ref:0:9:TGACTCTGGAGGT 2 21 +AC ref:0:2:ACAGATGGTCGCAC ref:0:2:CATTTTATATCAGT 5 33 +GAGCTCAAATACAACA ref:0:16:GTTATCGGTTCAG ref:0:16:CTAGCGTGTGT 11 542700 +AAC ref:0:3:GCTTA ref:0:3:GACCCGGGGGAGTAAG 4 270 +AGCCCTAGCTCGTGC ref:0:14:TAATACGA ref:1:13:TATT 7 68 +A ref:0:1:TAGGATCG ref:0:1:AACCGT 3 4 +CATAGGGAGCCAAGGC ref:0:16:TAT ref:0:16:CCGTGA 12 7524 +CGCGCT ref:0:6:ATTATGATCCATACA ref:0:6:GCCCGATCGAAGCCG 3 180 +ACTGTCTGCC ref:0:10:AACCAGCGGCTA ref:0:10:TGCCTA 5 2680 +AAGCCTTGCCCCA ref:0:13:AGTC ref:0:12:GT 8 32 +TCTATAGATGT ref:0:11:GTGCATACCAAT ref:0:11:CG 3 56 +TCTAGTCTAACGA ref:0:11:TACGTT ref:0:13:GTCTGGTCT 4 9 +A ref:0:1:TGCCGATCGGAAG ref:0:1:ACCTTCTGTACCGAC 6 9 +CA ref:0:2:AAGCAAACGCACCT ref:0:2:GACTTGGTACCAACTT 6 42 +ACACTGAAGTA ref:0:9:AAGCCATGTAC ref:0:11:GGGGGTCG 3 36960 +TTACTCCGACTATT ref:0:14:TTCGCATA ref:0:13:ACGTTAATC 4 1462 +CGATTT ref:0:6:G ref:0:6:GCAAT 3 21 +GTGACGCAACCG ref:0:12:GCACTAATTT ref:0:12:CGTAGCCAACATC 4 1600 +GAG ref:0:3:T ref:0:3:TGGCG 2 24 +AAG ref:0:3:TACGC ref:0:3:A 1 8 +GCCGACTA ref:0:8:AGACTTGTCAGCCTG ref:0:8:CAGAG 3 630 +GCGCCACG ref:0:8:T ref:0:8:CCTACCTGTACC 4 405 +GCTTATTCG ref:0:8:A ref:0:9:AGGGGGCTCT 3 110 +CACG ref:0:4:ATTTAGGT ref:0:4:T 3 130 +TGA ref:0:3:TAGTGT ref:1:2: 1 9 +CCGCGGTA ref:3:5:ATAGGTT ref:0:8:ATATTAACTTG 5 29424 +GTCTTAATGCGC ref:0:12:CCGGGTACG ref:0:12:GGATGACAAGGATG 5 4704 +GCGGCTGGTG ref:0:10:AAAG ref:0:10:AGTTCAACGATTCA 8 95550 +GATCCCGTTATTG ref:0:13:ACACTTGGCTGAA ref:1:12:AAGGAGA 6 2432 +ATCGTAGCAGGT ref:0:12:GTTAGAA ref:0:11:TAGATAG 6 1272 +AGAACGGCG ref:0:9:CAGTATTCACGGAGA ref:0:9:C 1 4 +CGTGGCCCGTTC ref:0:12:T ref:0:12:ATCGGGA 8 96 +G ref:0:1:GTGAAGCGTACA ref:0:1:CCGGA 2 8 +TACG ref:0:4:CGTA ref:0:4:CTACTAGCTGG 1 18 +CAGTCAT ref:0:7:AAGCTCTATAT ref:0:7:TACTAAGAA 2 90 +GGACCCCGCAGTG ref:0:13:A ref:0:13:GTTCCAGGG 7 1614 +TGTAATGCACCGGTG ref:1:14:CTCAGAGCGACA ref:0:15:TAAAAAGTAGA 5 5368 +TGGACA ref:0:6:CTAAAGCGG ref:0:6:CCTC 4 57 +GTCAATCGGCCTAA ref:0:14:ACGCTGTA ref:0:14:CATTTTATC 7 24912 +TTCAGGGCGCATA ref:0:11:GTCG ref:0:13:C 8 63 +CTCCAACCCGCACCGA ref:0:16:AGGTTCCAATTG ref:2:14:AT 10 17487 +TGTAA ref:0:5:GCTCAGC ref:0:5:CCATCCG 1 5 +GAAGTAGCGCACGCTT ref:0:16:TTGCCTAGCCCAGT ref:0:16:TCGGCAAAAGTCC 7 134800 +GAT ref:0:3:TAGTGGGCAGC ref:0:3:CTGGCTCGCCACGG 6 255 +GGGTCCTGGG ref:0:10:TAGTTAGGTA ref:0:10:GTTCAGTCGCTATA 7 10080 +CTTTC ref:0:5:AGGTAGCCA ref:0:5:GCAT 3 1050 +TCAAAACCGCGAG ref:0:12:AGCCCTG ref:0:13:GCGGCGCATT 6 3960 +CAG ref:0:3:AAACGATGCCG ref:1:2:AAACTTCGTG 2 12 +GCGGTGAGGAGTTAG ref:0:15:CGCCACTAAGTTCC ref:0:15:GGCTATCCCCTT 7 115920 +GAC ref:0:3:GCCGATGTCTA ref:0:3:GCTGTACGGCGG 3 8 +CC ref:0:2:CTA ref:0:2:AC 1 12 +GACGATCCGT ref:0:10:CATCAGG ref:0:10:AACCCATG 4 400 +TAAGCGTAGTGAT ref:0:13:AAAGGGAC ref:0:13:ATTGTGAAG 5 3080 +GGAGAGCAG ref:0:9:CTTCAT ref:0:9:AGTTTGCGG 5 2040 +TG ref:0:2:GTGATGAGCCCC ref:0:2:CAGT 1 20 +CACAGCG ref:0:7:GTACGTCGAGGA ref:0:6:G 2 18 +AACTGCGCA ref:0:9:ACCCATCGTCTTC ref:0:9:G 3 172 +CATTGATTCGGTAGAA ref:1:15:GCG ref:0:16:GGACATCATGCGTATC 7 1764 +GTGGTACCAGTC ref:0:12:CTCGAATTACGGGCAT ref:0:12:TAGGGCGGACCG 3 1104 +CGCATACTAATAGGG ref:0:15:GCAGCATT ref:0:15:TGTTTGA 7 882 +TG ref:0:2:GT ref:0:2:TAGTTTG 1 10 +AATTCTCGAGCCAGG ref:0:15:CGTGCTTTT ref:0:15:GTGCC 11 17640 +GACCCTTTATTA ref:0:12:TAAGCTTAGTG ref:0:12:AATAATCCTAG 6 52521 +GCCGACAGGG ref:0:10:CCAC ref:0:10:GA 5 4 +TAATACTAATTG ref:0:11:GC ref:0:11:TCCT 8 246 +CAAAAACA ref:0:8:CCTCGCGGAAGGGAG ref:0:8:TGGCAGA 7 168640 +TTAT ref:0:4:TGGAGCATC ref:1:3:AAGGGTAGTAGCC 4 11 +GACGC ref:0:5:TACCCAGCGC ref:0:5:CTCG 2 243 +GC ref:0:2:TTAGGAT ref:0:2:TCGAAAG 3 56 +TCAGTCACGTGCCGC ref:1:14:GGGACACACTC ref:0:15:AC 7 27 +TGAGGAAATATTTG ref:0:14:GCACG ref:0:14:ACTGACT 10 148176 +ACATTACGACT ref:0:11:CAA ref:0:11:AACTCGCCTACGCCA 3 72 +TTGTGTTTCTGCG ref:0:13:TCAT ref:0:13:ACGCT 9 234 +CTTGTTCA ref:1:7:TCGTGACCT ref:0:8:AGAGCGTGATTTCT 4 2220 +TCC ref:0:3:CATCGTGCATAATGGA ref:0:3:AAT 1 1 +CGGT ref:0:4:GACTCCAAC ref:0:4:AACTGACC 5 95 +GTATAG ref:0:6:CCCCTTT ref:0:6:TGCACGCTATC 5 465 +CTACGC ref:0:6:TGCTT ref:0:6:ATGGGACGCC 1 4 +G ref:0:1:TCGTTGCGCATGACA ref:0:1:GCTATTAGTGTAAGT 7 16 +ATGC ref:0:4:AATGT ref:1:3:GTG 1 4 +GCGACCTCCCAAC ref:0:13:TGAGATAA ref:0:13:CCCAACGT 3 40 +ACCGGTGCCC ref:0:10:TAGCC ref:0:10:TTATACAGCGG 4 168 +TTCATAT ref:0:7:TAGGTTACA ref:0:7:AGC 5 684 +AGCGATTATGCACC ref:1:13:GG ref:1:13:CATACCGCTTG 4 6 +AAGGGCT ref:0:7:GAAGGTACGA ref:0:7:G 2 63 +CAGCGTTTAC ref:0:10:GCCG ref:0:10:CA 6 12 +AT ref:0:2:GCTGGT ref:1:1:CTA 1 9 +CCGGCACACCAT ref:0:12:CACAGCGGAA ref:1:11:GCGAAGATCTACAGG 4 618 +ACGGACGCTGGAACAT ref:0:16:TGGGAGG ref:0:16:CTTACCGATAG 7 9180 +CTTCCCTA ref:1:7:TAAACACACGGATTG ref:2:6:ATC 2 120 +TA ref:0:2:ATTATC ref:0:2:CATTTG 3 22 +CTCTGAGGCGGT ref:0:12:TC ref:0:12:GCGTA 7 18 +TTAAAATCG ref:0:9:TACCT ref:0:9:TTTTGA 4 1080 +TTGTCCGA ref:0:8:GG ref:0:8:ATGG 5 3 +TCTGCTCATACT ref:0:12:GCCAG ref:0:12:AAATCGTGAT 4 96 +TGACTAAGC ref:0:9:CCGCTTGGTCGTTCTA ref:0:9:GG 4 459 +GCTTGCATTA ref:0:10:ACT ref:0:10:CCAATAGA 5 322 +ATTACAA ref:0:7:CGGACA ref:0:7:G 5 344 +AACCGCAAGACCA ref:0:13:TGCTCGTGTGT ref:0:13:CG 9 7800 +CTCTTGACCATCGTGA ref:0:15:GTGTTGAGCCTCT ref:0:16:GTGTTCGACTT 7 32 +CCA ref:1:0:GA ref:0:3:TCGCCCGGATTACG 1 12 +TAATAGGAGGGCAAAC ref:0:16:ATTTCGATGTGGATA ref:0:16:CTATGGAC 5 26624 +CTTTCTCGTGCC ref:0:12:GTC ref:0:12:CAT 8 52 +GGATCCGCTA ref:0:10:ATGCACTCTGCCGC ref:0:10:GGC 3 100 +CAG ref:0:3:GCCAAATAGATT ref:0:3:CGCTCCCA 2 48 +GTGCGCGACATTGC ref:0:14:ACG ref:0:14:GAAGGAG 8 38 +TG ref:0:2:ATAGAACA ref:0:2:CGA 1 2 +ATTTACC ref:1:6:CTT ref:0:7:CGAAGTT 4 36 +A ref:0:1:ACAACCCTTA ref:0:1:CAAGTTGCTCGAT 5 12 +ACCTGG ref:0:6:GTGAA ref:0:6:GAAT 4 68 +AATACACTCGTCCA ref:0:14:GC ref:0:14:GATCGGGCG 9 2842 +AAGCACGCACACG ref:0:12:CGCTGAAGGAGGTA ref:0:13:TTTGAGGCTT 8 327894 +TTACAGTATTTGAGGA ref:0:16:TGGAGCCGGG ref:0:16:CACTCTCGT 9 2103135 +GTTTCA ref:0:6:CATACTTG ref:0:6:CAGGGG 2 9 +CGAACGCGGCCACGAA ref:0:16:CCGCTTGTT ref:0:16:C 11 6210 +AGA ref:0:2:TGCTT ref:0:3:TTGCCAAGTTTCGATA 3 16 +TGGGCGGTTCCATGA ref:0:15:GCCGATGC ref:0:15:GGGAGCAACACAACAG 6 313180 +GTGTTCG ref:3:4:ATTTT ref:0:7:AGATGTAAAGT 2 225 +G ref:0:1:GGTTTAGTGATCT ref:0:1:TTGGAACGCCAC 5 12 +ACAGGTGAGGCTGTG ref:0:15:TGTGTATC ref:0:15:GGTTCGTTGGTA 9 184230 +GCAACGAGTCTGC ref:0:13:TA ref:0:13:CAGAAAA 9 7282 +CGACCCACTGCGT ref:0:13:ACGGCCTTGTA ref:0:13:TCGCCG 6 3488 +CTTCTATTTGT ref:0:11:CGG ref:0:10:CCTTACGGCCCACGC 5 1824 +ACTGGCGGTAGACTGG ref:0:16:GAGTTAA ref:0:16:GGA 11 864 +GTTT ref:0:4:TTCGAACGGTCAGATG ref:0:4:CAGGGCCA 6 3885 +TCCTAACC ref:0:8:GTCGGAGAGAACGTG ref:0:8:CGTTCAGACCA 4 7924 +GGCGATACTCC ref:0:11:TGGCAAATAACAAG ref:0:11:G 4 1224 +GAGTCGAATTATCAT ref:0:15:GAA ref:0:15:TTCGGCTAAGAC 8 858 +GCACTCCCTTGAG ref:0:13:TATTGCCGTG ref:1:12:CCG 6 6960 +AAACTAT ref:0:7:CGTTA ref:0:7:CATAGA 4 138 +CCCCGGCGAGCTGT ref:0:14:GGGTCCATCCGCGCCA ref:0:14:T 5 162 +GGGTAATCTCTTGGT ref:0:15:AACACCAACGACACAC ref:0:15:CTTAGAAACG 12 13561060 +TACGC ref:0:5:GTGTCA ref:0:5:AATAGCGCCACCAAA 1 4 +GTTGAGCACCAGCGC ref:0:15:CCCACCT ref:0:15:ATGCTCTTCCAGAT 7 3212 +TTACACCCCCGAC ref:0:13:ATTAGACCTCA ref:0:13:GACTCCTCC 5 6330 +TAATCTATTAC ref:0:11:GTTGTGGGGCG ref:1:10:GACGGTACGAGGA 7 146955 +TTTCGT ref:0:6:C ref:0:6:CATTC 3 5 +TTCCTGAGGTAGCTT ref:0:15:GG ref:0:15:AGAGCCAGCCATG 8 3078 +AGTATTCATATGTT ref:0:14:CTAGTGTGGATG ref:0:14:CGC 7 1050 +GCCCGAAAGCTGATA ref:0:15:TGCCAT ref:0:14:CACAGCTTGATC 4 1152 +TGGCGAATCCAGGGCT ref:0:16:CCG ref:0:16:GGT 11 162 +A ref:0:1:GGGAATAAGTTATC ref:0:1:CGTCGATATTA 7 15 +TTCGCATAAACCCGGT ref:0:16:CAAGTCG ref:0:16:C 11 2370 +GGGGAA ref:0:6:TTAGTCCATCGTCCC ref:0:6:CCGATGATCGCCTG 8 2715 +GTGTGCAGGC ref:0:10:CGAGCAGTGAGTCTGT ref:0:9:CGAAG 5 7654 +GTA ref:0:3:CTTCAC ref:0:3:CTTGAGAT 3 85 +GCCTGTGATTGCTC ref:0:13:TATC ref:0:14:CAAGCGTTTTCA 4 12 +ATGTGGC ref:1:5:TGTGGGTTAGTGA ref:0:7:CGGCGTTCG 2 72 +AGTAA ref:0:5:CTTGATCGGA ref:0:5:TGTGCGG 6 1350 +CAGGGAAG ref:0:8:ACATCTA ref:0:8:TGTCGGGTGTCA 4 1500 +GGAAACTTTAATGAGT ref:0:16:TCCGGGC ref:0:15:CACTATCTGTATTA 7 1762866 +TCTATGC ref:0:7:GTTATCCCGTTA ref:0:7:CCTCC 2 310 +TTTCTCA ref:0:7:AGGACT ref:0:7:TAT 5 595 +ACGGC ref:1:3:TTCT ref:2:3:AATGAGAT 1 9 +CCGAAGGACT ref:0:10:CTATCCCTCT ref:0:9:GTG 5 18560 +TTCG ref:1:2:GCCTACACCAAAT ref:0:4:TCCT 2 39 +AACCCG ref:0:6:TAGATAACCCTGC ref:0:6:CCCGTTAGACTCGAC 3 30 +TTTAACTTCAACA ref:0:13:CACT ref:0:13:CGTTAGAGCCCTGC 7 11570 +CGTCACGG ref:0:8:TATTTGCAAGTCT ref:1:6:AGTGCTAAGA 4 2565 +AGCAGCAT ref:0:8:TCGATA ref:0:8:TCCC 4 72 +TGCCATG ref:0:7:GAGTC ref:0:7:ATATT 3 9 +GTCATAAGCGT ref:0:11:TCGCGTCAAG ref:0:11:TTCGATTT 4 783 +CCAGGC ref:0:6:GCTCG ref:0:5:TA 2 6 +TTCGGC ref:0:6:TGATACAT ref:0:5:CACAG 3 552 +CCCGATAGAG ref:0:10:AGAATAT ref:0:9:AAAACA 6 5824 +ATGAGCACAGG ref:0:11:CCTCTCTCT ref:0:11:TTCTCAAAACCCAAT 9 14039424 +AAACCAC ref:0:7:AACCAGACCAATT ref:0:7:GCTACAAACCATGACG 2 320 +TCTGTAACCCGTGCA ref:0:14:AG ref:0:15:CAAATAA 9 160 +TAGCACATAG ref:0:10:AGATAAGCAATGGT ref:0:10:GCCTAAAGGGC 2 162 +TCTCATAGACAAT ref:0:13:GTGCGAGGCGGAGC ref:0:13:CATAAATC 4 18256 +AAAGGAAACGCC ref:0:12:CATGTAATCGCCC ref:0:12:AACT 4 53550 +AGAACACCTGAGGAT ref:0:15:GCGC ref:0:15:T 11 90 +AATTTGAGGA ref:2:8:TGTTCCT ref:0:10:ACGTCCTGGCTTTTGC 5 2950 +CACCTTGCCTAG ref:0:12:AAAGGGCT ref:0:12:GA 7 722 +TCTCATG ref:0:7:TCACCGA ref:0:7:ACGACAAT 3 300 +CTTATCTG ref:0:8:T ref:0:8:GG 6 36 +TAACCA ref:0:6:ATT ref:0:6:AGCCAGAC 2 198 +TTACTCGTCG ref:0:10:TG ref:0:10:TCAAAC 6 1729 +TCCGCACCATC ref:0:11:C ref:0:11:GAG 8 54 +CTCCGTA ref:0:6:AGCATTT ref:0:6: 3 6 +CC ref:0:2:TC ref:0:2:CCCTACCAATTTT 1 30 +AGCGCTCGGCA ref:0:11:ATATCTGATGTGT ref:0:10:ATAGACCAGT 6 5220 +ACAAGCCGTGCC ref:0:12:CGTGGTTGGGAACGAT ref:0:12:AAGAAGTG 5 25270 +CCACGGCTT ref:0:9:GGTTC ref:0:9:CCGC 2 6 +A ref:0:1:TATGAA ref:0:1:TTAAGA 3 9 +GCGG ref:1:3:CAAATAATCTGT ref:0:4:ATGT 4 416 +TTTAGCCGT ref:0:9:T ref:0:9:CTCTATA 5 24 +TCTA ref:0:4:GCTGGGAATCGA ref:0:4:AGAC 3 270 +GTATAAACCGAAGGA ref:0:15:CCG ref:0:15:AGATCAAACT 6 51 +ACAGCTAGGG ref:0:10:CGTATATA ref:0:10:TT 7 1144 +GCTCC ref:0:5:CAAGTCTATGTCAGTT ref:0:5:TT 2 156 +CCAGCGTTAGG ref:0:11:ACTGACGCTCTTACG ref:0:11:TAAATGAAAACTTGTT 5 21375 +GCA ref:0:2:CCAGTGCTCCC ref:0:3:GGGCGTCTT 3 240 +TTCTAGAGACCTCGC ref:0:15:CACGCGTCTG ref:0:15:GAGCAT 7 140 +GCGTAC ref:1:5:GA ref:0:5:C 1 1 +GTA ref:0:3:GGGCGATAGTAT ref:0:3:TG 1 39 +GT ref:0:2:GAGACAAGGGGCCTGG ref:0:2:A 1 18 +GATCATG ref:0:7:TCACTAATACACTT ref:0:7:AGATCT 2 57 +TAATAGA ref:0:7:GAACCTCGCATC ref:0:7:CCG 4 84 +CA ref:0:2:ACGTGCCCACGAAGCT ref:0:2:TTATCTCTCCGAC 7 56 +CGCGTGA ref:0:6:GTTTGCGGGGT ref:0:7:GAAGAGTTC 3 18400 +CACA ref:2:2:TC ref:0:4:ACCGGGCGC 1 68 +CCTAATGATATTCCTT ref:0:16:ACCGTCGTTAT ref:0:16:CTGGGT 9 327922 +G ref:0:1:AGTAACGGTGCC ref:0:1:CAA 2 16 +GAAGGGGT ref:0:7:AAA ref:0:8:AACTCACCGCTA 5 2160 +CTTCGTGAACCCT ref:0:13:AGCGTTCGGAAACGA ref:0:13:CAACGTTATCGACC 5 22770 +GCAGTTGGCAAACAAC ref:0:16:TAGTCGC ref:0:16:CAGACGCATA 9 82680 +TATGCAGAAGACACA ref:0:15:CCCAAAT ref:0:13:CCGAC 9 45880 +TGACCAAAGTGATG ref:0:14:ACAAAAAAC ref:0:14:GCCC 7 3926 +CGCCCGAATAA ref:0:11:GGG ref:0:11:CGATACAA 4 480 +ACAATCGTCTTTAGAC ref:0:15:CATAAACTT ref:0:16:TTCACCTTTACCCACC 5 18720 +ATTGCCATGTT ref:0:11:CGAAGA ref:1:10:GTTCTTGCTCGACA 5 34532 +CTTA ref:0:4:ATGAACTACACT ref:0:4:AGGGGAACAAGACAG 7 396 +TCCTTAATTAA ref:0:11:TGACAC ref:1:10:GCTGCAGTCTAC 7 54108 +ACCACGGACACCCCAG ref:0:16:TACTAACTCATCGG ref:0:16:CGG 7 28359 +TTCGC ref:0:5:CTTAGAGGGGATGTGA ref:0:5:ACAATCATCGG 4 888 +AAAGGCCTA ref:0:8:CGAGATG ref:0:9:GCGGAAGG 6 826 +AGGTTATCG ref:0:9:TAGTTAACATGTGCC ref:1:6:CTTCGACATA 3 468 +ACAGGTCG ref:0:8:CTTAGAG ref:0:6:CCGTAT 3 232 +AGGTGA ref:1:5:TCGCTCG ref:0:6:TGATTATTCCCGGCC 5 3230 +AATAGTGGATCCA ref:0:13:TGCACTACGTCAC ref:0:13:CCGT 8 24832 +CCCAGCT ref:0:7:TTAAAAATGTATA ref:0:7:TGTGTCATTGTCATTA 8 45920 +TGACGCAAGTC ref:0:11:A ref:0:11:GCTGCCAACTAATT 4 729 +T ref:0:1:GTTGTATGACGAAAC ref:0:1:GA 2 12 +GGAGGGCAT ref:0:9:AACGGTA ref:0:9:GGCGCTTCAC 4 10560 +AAGT ref:0:4:TAGCTATGCGAGCATT ref:0:4:CGGATACGACC 4 40 +G ref:0:1:CCTCGGGAA ref:0:1:CGATAGGACAC 5 9 +TATTGCC ref:0:7:T ref:0:7:GGTGGGCTTTACTCAA 2 117 +GGC ref:0:3:AAGAAAATCGCTGTGG ref:0:3:CGATAA 3 26 +GTTTGA ref:1:5:TCCCTGGTAA ref:0:6:CCAAA 4 5887 +TAATCACCAAT ref:0:11:AGATCCTGTAAGCAG ref:0:11:GA 5 4050 +GGCGACGCGTAGACG ref:0:15:CCGAAACTGCGG ref:0:15:TCGGTACCA 6 39902 +GGGCTCAGTACGCACG ref:0:16:CAGG ref:0:16:CCTTCAAATACAACCC 5 26400 +GTATA ref:0:5:TT ref:0:5:TACAGCGAG 1 12 +TTCCCCCCAAGTATG ref:0:15:ACACACTTTTT ref:0:14:AAA 8 68156 +CGCCCGTTT ref:0:9:GCCCTTCTTTGGCTAC ref:0:9:ATCA 4 15399 +AGGCGCACATG ref:0:11:TTC ref:0:11:TGCTATTTACCCTGTT 7 103950 +CTTGGCGC ref:0:8:TAGAGGCGCCGT ref:0:8:TGTATTAAAATACA 3 137852 +CTGAA ref:0:5:GGCTT ref:0:5:GAGACTAGATAGGGT 3 5 +AGGTTTTTTT ref:0:10:CGC ref:0:10:CGGCAG 10 10374 +ACGGGATATTTATGA ref:2:13:T ref:0:15:TGGTAGTTCT 6 500 +CGTCTCAGGGAATGAC ref:0:15:GG ref:0:16:GAAGGAGCAGAT 7 800 +TTATCCGGGATATC ref:0:14:TGGG ref:0:14:A 9 9 +CTCAAA ref:1:5:GTTGTGAGCGCCCA ref:0:6:CCTCCAAGATGCTGTA 4 3776 +TTAAGTCTCA ref:0:10:GTATACCACAAGGT ref:0:10:ACTG 4 1380 +GTCGGGGAGTGT ref:0:12:CTAAGG ref:0:12:C 8 34 +CTGAGCACAGTTTCGG ref:0:16:GGTCATCCAGTAAATA ref:0:16:CCTCCGGTGGGTG 4 21100 +A ref:0:1:TCG ref:0:1:CGTTT 3 24 +GCAAAACTATTTACTG ref:0:16:TCTCCTGGTATAA ref:0:16:AATGAGGCACGTTTC 7 132832 +AACATAGTG ref:0:9:CTATTCATAGC ref:0:9:TGATTGA 4 494 +CTGGCAGCCG ref:0:10:G ref:0:10:TCATAGCGTAA 4 24 +TGGTTGAATAGC ref:0:12:GCGTCGGT ref:0:12:TAAAGCCCTAGGGA 4 3078 +AATAAGGTC ref:0:8:ATTGTTTT ref:0:8:CAA 3 1474 +AA ref:0:2:CGGAATCCG ref:0:2:AGATTGCTTACTGT 4 3 +ACTGAA ref:1:5:GTGAGAAT ref:0:6:GGAGTTTTC 4 2024 +ACCTGCCGCAAGA ref:0:13:GATT ref:0:12:TCCTGAATTT 8 960 +GA ref:0:2:CACG ref:0:2:CCCAGAGCTGGCGGA 3 21 +CTTAGTCTGGCTGCGC ref:0:16:CTT ref:0:16:TG 12 220 +CGAGCA ref:0:6:GGGGACAACTT ref:0:6:AATACTTGC 1 1050 +GGTAATAC ref:0:8:GAGTGCGTACACATA ref:0:8:ATGTT 3 84 +ATACGCACCGACCGGT ref:0:15:TCATGCTC ref:0:16:GTT 10 156 +CTCTATC ref:0:7:ACAA ref:0:7:GGCATCGGGG 3 161 +TTATGAACACTTGTC ref:0:12:GC ref:0:15:TGGCCGT 8 34 +AGT ref:0:3:CGGACGCTGCGTG ref:0:3:GTCACGATGT 4 16 +TTCCTCC ref:0:7:TGGGCGCCCATT ref:0:7:AGTAACCGCACTG 3 60 +ATGAGAGGAAC ref:1:10:CTACTTCCCTCTA ref:0:11:CTACCTTATA 11 1953574 +TT ref:0:2:CTAAG ref:0:2:AAGG 4 90 +TGATAATC ref:0:8:AGAATACAATCTCAGT ref:0:8:TACG 2 180 +GCCCCCTCCTG ref:0:11:ATAAGAGTAT ref:0:11:TACGTACTGCA 9 24024 +TC ref:0:2:ACGCGTAAAAGG ref:0:1:AGTAAATTT 5 52 +CCAATTC ref:0:7:GTGTTCTGGTTGTT ref:0:7:GTGAGCCTTCGGCA 7 2632 +AACTGACTTGTAG ref:0:12:CTTAGTGAA ref:0:13:AGTTGGGTTACAT 5 5472 +GTACGCGGC ref:0:8:GGCGCGGG ref:1:8:CCTTAAC 2 492 +TCCCAG ref:0:6:TTC ref:0:6:CGTGCT 4 576 +CA ref:0:2:ACC ref:0:2:CGCTAAT 1 16 +CTATCCTGCACGTGAT ref:0:16:ATA ref:0:16:CCCATTAAACTTGG 8 7476 +CGGACCTGGG ref:1:9:GGCCGCCCCT ref:0:10:TAGGCTACGATAG 4 17088 +GTG ref:0:3:CAAAA ref:0:3:TTCTATTTGATTA 5 1848 +AGCCAATTA ref:0:9:CCGGGGAACGGGATGC ref:0:9:GGCCTGCT 4 171 +CGTTCTTC ref:0:8:AG ref:0:8:TACGCATATTTCCG 2 4 +CATCTGGAGAATGG ref:0:14:AGCGCGA ref:0:14:GCGA 10 1590 +GACGCCCA ref:0:7:AAAATG ref:0:8:TGATGGCTCG 3 1470 +TCGTTGTTCG ref:0:10:GTGA ref:0:10:ATGTCTCACGGACC 5 2704 +CTCACGAGAGGCCCCT ref:0:16:TTGGATATACCACG ref:0:16:TCGTGCGTG 8 2863680 +TCCTTTTCCGAAC ref:0:13:ATTAGTC ref:0:13:ACTG 9 12100 +ATAATGGGAAC ref:0:11:CTGTCTTTTT ref:0:11:CCTGGAAATA 7 74970 +ACGAATGTC ref:0:9:AG ref:0:9:GAT 5 16 +TTAAGTGCTGTATGCA ref:0:16:TGGGGTATCACG ref:0:16:ACTTGGACTGT 4 38 +ACACACAG ref:0:7: ref:0:8:AGTGTGAC 4 74 +TCTGGAAG ref:0:7:A ref:0:8:CCGCGTGA 3 184 +GTGGCC ref:0:6:TCAG ref:0:6:A 5 56 +GCCACATGAC ref:0:10:ATTTATAGGT ref:0:10:CCATTG 5 520 +GATAA ref:0:5:ATATAACCGCACACA ref:0:5:ATATCC 4 285 +GGGTATATAA ref:0:10:ATGTCAGAC ref:0:10:CAAACTC 6 254 +ACTAACA ref:1:6:TCG ref:1:6:TCATACGT 3 24 +CTTGGTAGCGCTGCG ref:0:15:TCTAACACTCTCAGTC ref:0:15:AGAATGGAGCAA 8 3038980 +TGACAGTTAACACT ref:0:14:ATA ref:0:13:GCAA 8 72 +ATAAATTCGTTTGG ref:0:14:GAGAACATC ref:0:14:TCTACCTGGGGTGAC 5 370832 +GT ref:0:2:GTATTTTCGATGCCT ref:0:2:AAGGTCACTTATCCCT 8 100 +GCTG ref:0:4:CAATACGTT ref:0:4:TCCACTGGGGGA 2 50 +CGTATCGCGGA ref:0:11:AAACTTATATGGGTTT ref:0:11:ACCAGAGGACCTCTA 6 80560 +TGTGCTAGCGAG ref:2:10:GCCTAAAAACC ref:0:12:GCACGGCGCTTGGGGA 4 2289696 +GCGA ref:0:4:GGGGGCC ref:2:2:GGT 2 475 +ACTGATTG ref:0:8:CTGTGGACAAT ref:1:7:GCTGCCCGCT 4 2912 +TGAC ref:0:4:GTTCATTGTGG ref:0:4:GGCCCTATCTGTGGC 8 3488 +AAAC ref:0:4:CTCGC ref:0:4:CCGTAGGGTTGGTCTT 5 4830 +CGTT ref:0:4:AAGATTCCTTT ref:0:4:CTGACGGC 3 1927 +AGTTGCC ref:0:7:TA ref:0:7:G 5 20 +CACCTGAATGCCT ref:0:13:AAACCC ref:0:13:TGTGC 4 12 +A ref:0:1:CGGTACCGCGTGT ref:0:1:CCGTTCTGAGGG 6 1 +CAAGCTCGAGAT ref:0:12:GCTACACGAAGA ref:0:12:ACTTTAGAC 3 800 +GCAAAGTGATA ref:0:11:TT ref:0:11:CTC 8 7 +TATTTTCACGGACG ref:0:14:CCTTAGTTTTTGGTCC ref:0:14:GAGAGTAGTAC 5 38304 +AGCGGTCCTCGTTG ref:0:14:T ref:0:14:GCACTGGATA 8 1152 +GACTCGACGGTCCTC ref:0:15:CCTTTATAT ref:1:14:GGGATTA 6 264 +CGCC ref:0:4:ATCGAT ref:0:4:GCTA 2 24 +CAGGATCGGGGCCGA ref:0:15:ATGGGCTCGG ref:0:14:TTTAGGCCCCTC 4 7296 +GATA ref:0:2:CGC ref:0:4:TTTATCGAAT 1 22 +CTCATTTA ref:0:8:ACTGGGGTCCACC ref:0:8:TTGTATACCGA 5 766 +CTATGACGT ref:1:8:ACAGTTT ref:0:9:T 4 45 +CCACGC ref:0:6:TCCAGCTG ref:0:6:ATCAACAAAC 2 98 +ACGCCTCTGGT ref:0:11:GA ref:0:11:C 9 60 +CG ref:0:1:A ref:1:1:A 1 4 +CCCTAATAGTGGTTTA ref:0:16:CCACTCC ref:0:15:GCTAGTAGCGCTTTG 6 480480 +TAT ref:0:3:TATAGATAGTAA ref:0:3:GCATTTC 2 182 +CGCCACG ref:0:6:CTCTCCCGGAGTGCC ref:2:5:ACTAC 1 216 +AGCGG ref:0:5:AATG ref:0:5:TGCCAT 3 800 +AGG ref:0:3:TACAGCCAGGATG ref:0:3:GGTAGGAAGTCTTTA 3 45 +GTCCTCCCGGATCAC ref:0:15:CGCGGCT ref:0:15:T 10 558 +GGTCAATTTCTT ref:0:12:TGTGGAT ref:0:12:GTA 8 760 +GATGCATGTCCT ref:0:12:TATTAAGGA ref:0:12:GGTTGAAATTCTA 5 94080 +GT ref:0:2:CCAC ref:0:2:AAAGTCTACCAA 3 30 +GTAGGCAA ref:0:8:ACGGCGCCCTA ref:0:8:TCGATCTTATAGGA 2 770 +TCCC ref:0:4:CGAACTCGG ref:0:4:TTT 1 15 +GGACGTCTAAAACCCG ref:0:16:GCCGTGCTTCCTCT ref:0:16:TATACGTTCATATAT 6 227136 +TTGAC ref:0:5:AAAAAATGCTGTTTGG ref:2:3:ACAAGTG 3 69 +ACGGGCGCGGCGC ref:0:13:CGGATCTGAAAAACA ref:0:13:T 8 98322 +TAACACATTAG ref:0:11:GTGGGAAACTTAGA ref:0:10: 2 1 +ACTTCAAAGTGGC ref:0:13:TTC ref:0:12:CCTGTGTATAATT 5 300 +CTTACTTT ref:1:7:TGCGGCTGT ref:0:8:AGACCCGCGGATGAC 5 3795 +TACCTTTAAATA ref:1:11:CGAAGCCAG ref:0:12:ATTCTGAGACTGTGG 5 12042 +CAACGAGAGGTCG ref:0:13:CG ref:0:13:ACATTGCAAAGCCAC 6 42790 +GTGGCGA ref:0:7:AATTGTAT ref:0:6:AGCGTCC 4 3750 +GCAGC ref:0:5:TGTTACTGTATAAATG ref:0:5:CGTAGTCTTTG 2 12 +AAGAAGTGGCT ref:0:11:TGCCTGTTCAA ref:0:11:CGGCTG 7 38325 +T ref:0:1:A ref:0:1:CCACCTGTG 1 4 +TG ref:0:2:AAGCCG ref:0:2:TGCTGTGGA 2 81 +CGGG ref:0:4:ATCCCC ref:0:4:GTGCGGCT 3 385 +TT ref:0:2:TAAAGC ref:0:2:AAAG 5 105 +CTGATGC ref:0:7:TTTCCTCGCC ref:0:7:A 2 154 +T ref:0:1:AACTAAATGACGCGAT ref:0:1:GCATGTTCTTGGC 6 15 +CCTTGCCTG ref:0:9:GACGTTCGATCGATAA ref:0:8:G 3 165 +ACG ref:0:3:TGTC ref:0:3:GGAGGAA 1 21 +GGCTGAGCTGA ref:0:11:TCGCCCGTAAGCGGG ref:0:11:TGGAAG 6 71760 +GGGCC ref:0:5:TTTAACCTCATATAG ref:0:5:AGTAACACTCCACC 8 124852 +ACGA ref:0:4:AAATCAGTATTGA ref:0:4:GTCCC 1 360 +AAATTGAAGT ref:0:10:GACCAC ref:0:10:ACCTGACCTTA 7 2142 +CATAGATGCTGG ref:0:12:TCTTGCGC ref:0:12:AT 5 21 +TAC ref:0:3:GGGCAAATGTTTG ref:0:3:CCGGCGTGCGGTCT 7 1728 +ACCT ref:0:4:GTGACTTCTCTAT ref:0:4:TAATC 2 77 +CGCTGGTCTGTACCA ref:0:15:GTTGCACTAAGTGGCC ref:0:15:TACGA 6 2574 +AGCTCCCGCCGT ref:0:12:CGGTACTGTAC ref:0:11:GTCACCA 6 37711 +TCGG ref:1:3:GCCGCATTTTGAG ref:0:4:TAGATGGGCACCA 3 182 +GGGCTTC ref:0:7:CCCAATCA ref:0:6:CCGCGGTATT 3 330 +TGACAAATGCGGTA ref:2:12:CGCTT ref:0:14:GTGGG 5 5 +TCAAAA ref:0:6:AACAGGG ref:0:6:TTGGTCA 1 96 +GCGTATGATCAT ref:0:12:AGTTCC ref:0:12:GGTCGG 7 4851 +GA ref:0:2:ATTGTGAC ref:0:2:ACCAGGC 3 20 +GGACTTGGCACA ref:0:12:G ref:0:12:CCTCATGACAGTGC 5 100 +T ref:0:1:TGGCCTCTTGGCAGC ref:0:1:GAGTTAC 5 8 +GCAAGAT ref:0:7:ATCGAC ref:0:6:TACGCTATGTCAG 2 70 +TCA ref:0:3:GCGTAACCCTCTACC ref:0:2:TTTGACCGCCTGGT 5 60 +C ref:0:1:AAAGTTGTCAC ref:0:1:GTG 3 8 +ACAAT ref:0:5:CTTTGACCTGCGC ref:0:4:A 2 36 +CTGGT ref:0:5:AAGTGATA ref:0:5:CGACAATGCGATGA 4 36 +TT ref:0:2:TGGC ref:0:2:ATC 2 20 +AAGTACACCT ref:0:10:TTATGCCGGAGGGTA ref:0:10:TACTGC 6 11328 +ACTTCGC ref:0:7:TA ref:0:7:CGAGGCGCTGCC 2 260 +GTGGTCTTC ref:0:9:T ref:0:9:CAGTTGTA 5 392 +AGACACACCAACC ref:0:13:GATGGTTTCTAAGACG ref:0:13:TGCCTAGCGAGTTAAG 8 174600 +TTCTGACAGTAGCG ref:0:14:GCGTGATCCGCA ref:0:14:GCA 7 288 +GCGCGCTAAAATATG ref:0:15:CCACGAGCACGAAGGC ref:0:15:AAACGT 8 182367 +G ref:0:1:ATGAGTATAGCGCG ref:0:1:TTGCAGCCTGACCAG 8 20 +ATCTGACAACATGGAC ref:0:15:GACTTGT ref:0:16:CG 10 637 +ACGAACGAACTGTAA ref:0:15:CGATAACAACCTGC ref:0:15:CATAGAT 5 96 +GGGATGGT ref:0:8:CACGAAGGGACACT ref:0:8:TTTC 2 2763 +GAAGT ref:1:4:TAAGCATTGGGG ref:0:5:TGTTCAGCTCCTCCT 3 30 +GGGCG ref:0:5:TTCAACCGACAGC ref:0:5:TC 3 272 +TGTCTTCA ref:0:8:GGATAGTTATGAG ref:0:8:CAGCGTTGGTGGGGC 3 34 +AGTTGTCGTA ref:1:9:TTGC ref:0:10:TACGACCACGAC 3 170 +AAGAGGCTACGGG ref:0:13:CGT ref:0:12:CGATGCTAGGC 5 243 +GACACCGTCG ref:0:10:CCGACCGGATGGT ref:0:10:CGCCAAGGTTA 6 27642 +CCTGCTAG ref:0:8:AGGACTGACTACC ref:0:8:ATCCGCGATGTGAA 3 486 +A ref:0:1:TCCCCATGGCT ref:0:1:TTTAG 2 1 +C ref:0:1:ATTACTCATAAGAAGT ref:0:1:GATTTCCC 4 6 +AGCTACATGCCTTGGC ref:0:16:GCTACC ref:0:16:ACTCACTCACAAGCCT 5 1620 +TCCATC ref:0:6:CGTATCAA ref:0:6:TTCTTT 2 305 +ACCTCGCTCAATTG ref:0:14:CGAAC ref:0:14:A 10 36 +GGTTA ref:0:5:TAAGACTTG ref:0:5:AACAATTAGGGCG 5 294 +ATGCGGGTAGAGAC ref:0:14:AAGCGTTTCAGCTT ref:0:14:CT 6 402 +GC ref:0:2:CAAGTCCA ref:0:1:CGG 1 4 +GTCTGACA ref:1:6:CTCTCGATTCTTT ref:0:8:TCACT 1 2 +ATGCGGGT ref:0:8:TTTAG ref:0:8:T 6 364 +ACAAATTTCGT ref:0:11:CTCATTAAAC ref:0:11:G 5 146 +T ref:0:1:GACGTTGTCTTGTT ref:0:1:ACCGTAGAC 5 7 +ACG ref:0:3:CTATAGA ref:0:3:TGAACCC 2 60 +CACT ref:0:4:AGCTGAATGACGCGAA ref:2:2: 1 35 +ACTGCATCTCAT ref:0:12:CAAGATGCCCCAGTGC ref:0:12:AATCCCCAGACATC 8 238735 +GGGTCCGTCT ref:0:9:TT ref:0:10:CCCAAA 4 4 +GCACCTTTACCCTCC ref:1:14:CGTCC ref:0:15:TGTC 10 24382 +CACAACGA ref:0:8:AGTTTTCCTCAGACC ref:0:8:CACTACGAACGAGG 2 444 +CGCACAGTTGAACT ref:0:14:AGAATCA ref:0:14:ATGATTT 8 3388 +AGGAGAACTATCCT ref:1:13:TTGGA ref:1:13:GTGGGAGGGAGGGA 8 12608 +AGTACTAGACA ref:0:11:A ref:1:10:GGAGGGTA 6 2050 +CG ref:0:2:CCTCTGA ref:0:2:TTT 2 30 +GG ref:0:2:CG ref:1:0:CCCAA 1 3 +TTT ref:0:3:GG ref:0:3:CCCTGTCGAGCGGCGC 3 170 +GTA ref:0:3:AGG ref:0:3:GTGCTACCGCCT 1 15 +CTCAGGTTC ref:1:8:CGAACGCAAG ref:0:9:AGCGGAATTGAGA 4 500 +TAATTTTACAAT ref:0:12:CGAGTTAGTGCGAGTA ref:1:11:CCGAATCTTT 5 8460 +CTGGGTTTA ref:0:9:TAACTC ref:0:9:GCTCTAACGATGTAT 6 218096 +CTATAG ref:0:6:GTCTGGG ref:0:6:TAAGTAAAGGTG 3 810 +TGGCGAGACTCCCTCT ref:0:16:CGTGG ref:0:16:AGGAGATGAAG 11 208568 +AGCAATC ref:0:7:CATATCC ref:0:7:CCAAT 2 8 +CAC ref:0:3:GAG ref:0:3:ACCGCCCACTGC 2 40 +AGACCAGTGG ref:0:9:TCGAGGGACTTATGA ref:0:10:CACAATACGCTTCAA 5 52044 +CGCCCGGAAGTTGG ref:0:14:GCA ref:0:14:CTCCCCCA 8 780 +CTACGATTGG ref:0:10:TGGGTCAT ref:0:10:TATTTCGTCCGGAGCG 4 2352 +CGCGTACAGTC ref:0:11:TATG ref:0:11:TCGGCAACGTCACCC 2 1120 +T ref:0:1:CATACACACTAA ref:0:0:GAGA 2 2 +CGTTA ref:0:5:GCGCT ref:0:4:TGCC 3 66 +CTG ref:1:2:AGATT ref:0:3:CGCGGTAT 3 95 +A ref:0:1:C ref:0:1:G 1 4 +AC ref:0:2:GTCGTTAACCTGAT ref:0:2:G 1 12 +AATATCC ref:0:7:AGTACATCCGG ref:0:7:GACGACA 3 384 +GCA ref:0:2:CTTTCTTGCC ref:0:3:CCTCGTACT 3 22 +TTGTTGGTAGCT ref:0:12:GGACATGA ref:0:12:CATGGAATCGG 8 6543 +CAAGTTTGATTTATC ref:0:15:GTG ref:0:15:TGGAGT 10 504 +ACGA ref:0:4:GTG ref:0:4:CTCATATTGAAAGA 2 666 +G ref:0:1:GCG ref:0:1:CTATGAGAGCTC 1 6 +AATGTCCACCTA ref:0:12:ATTATCACTTGCATTG ref:0:12:TTAAAGTTCGAGCGC 4 14800 +GCATTGTAA ref:0:9:C ref:0:9:ACATCT 5 12 +CGTTAACAC ref:0:9:G ref:0:9:ACCGACTAGCTG 3 4 +TGACTGGTGCGAC ref:0:13:AATGCA ref:0:13:GTGCA 7 138 +G ref:0:0:TACCA ref:0:1:TGCTCAGAT 4 2 +CTCA ref:0:4:GTTTCAGGTA ref:0:4:TTACGTCCTT 3 133 +GCTGCACTCGTT ref:0:11:TGCCAGCCTCTA ref:0:12:TGCGTGCCT 3 77 +T ref:0:1:GAACAAG ref:0:1:TGGATCACGGAGCTTT 6 40 +CAACTACTTAA ref:0:11:AC ref:0:11:CCGCAAAGACGTA 4 1170 +AGCAAAGATCAGA ref:0:13:CCGCAGTCAGGGGG ref:0:13:GGTTTATTAC 4 6210 +AGCATGATCTCAGGGT ref:0:16:CG ref:0:16:TGGTGGTGTGA 8 120 +CACTTTAC ref:0:8:AAATCCC ref:0:7:TGT 4 1972 +CGCCC ref:0:5:CCAGGGCTGTC ref:2:3: 1 43 +ACTTACTTGCAGCTG ref:0:15:TACTTGTACGCCGT ref:0:15:CTCGGTTTTTGATAC 5 27945 +GTCGT ref:0:5:CACAAGGC ref:1:4:ATAAGCG 2 40 +TTAAGTAC ref:0:8:GGCACTGAGCGAGGA ref:0:8:A 3 72 +TCGATTCGT ref:1:8:A ref:0:9:CGGG 4 8 +GTTCT ref:1:4:CTTG ref:0:5:ATCCGCCATATCTCTA 1 40 +T ref:0:1:TGCTAGACGGC ref:0:1:TCAAAGTGG 5 4 +TGA ref:0:3:TTGGTCACTGCTTAAT ref:0:3:CC 2 200 +TTAGAC ref:0:5: ref:0:6:AAGCCCCGCCG 3 110 +CATTTAACGGCGA ref:0:13:CCTCT ref:0:13:GTATA 9 30420 +CTCATTGCGTGGGCT ref:0:14:CTTCT ref:0:15:AAGCGCCGTGATT 6 16016 +TGCACT ref:1:5:GGTCCCCC ref:0:6:ATCTATC 1 140 +AGACATGACTTTT ref:0:13:GCCGCT ref:0:13:TTGTGGGGCTTGGTAA 5 4800 +GCCTTCTCCTCAG ref:0:12:C ref:0:13:CGAGCCAC 8 11328 +ATATTTTCACG ref:0:11:ACACCTGATGTT ref:0:10: 4 12 +GT ref:1:1:TATCAACAGAA ref:0:2:CTTG 2 12 +CTCCGATGTCGAA ref:0:13:TGGGAC ref:0:13:GAAGCACTGGAAAG 5 1278 +CAATTCGCCCAATAGC ref:0:16:CAT ref:0:16:GTAG 10 16 +GGTG ref:0:4:TTCAC ref:0:3:AATA 3 102 +A ref:0:1:GCGGCAGG ref:0:1:CGG 3 4 +TAGCGATGGG ref:0:10:ATGCCCGGC ref:1:6:GCTGAA 2 510 +CCCGCGA ref:0:7:ATTCAA ref:0:7:AT 5 186 +GAAGCGGAC ref:1:7:AGG ref:1:8:TTAACTTGCG 2 42 +ATAAGGATCACCGGTA ref:0:14:AGGAGC ref:0:16:GTG 8 240 +ACTAATCTCGGTTC ref:0:13:CCACTGGACT ref:0:14:CACTCA 6 792 +GCGCCGCCCTT ref:0:11:CACACGCGATAGAGGA ref:0:11:GCTCC 4 13528 +ACAAGC ref:0:6:TTG ref:0:4:TTTAC 4 15 +ATGCGTCCTCTG ref:0:12:TGATCTTT ref:0:11:CCCT 3 230 +CGT ref:0:3:ATCAACGGGG ref:0:3:ACAACCACCGTG 5 100 +TGGTTGCT ref:0:8:ATCCA ref:0:8:TGCTCAGGGACC 4 14964 +TGC ref:0:3:CCACTTACC ref:0:2:TCCTCGG 3 48 +GCTGTACGA ref:0:9:TGAACATT ref:0:9:GCGCGTGCTAC 1 9 +ATGCATAGTACCCAC ref:0:15:TTG ref:0:15:GTGCTAAGAC 7 38 +ACTACTGTAGTC ref:1:9:TTCTCGGTCACC ref:1:11:GCACGAGACC 2 165 +AAGCCGTCC ref:0:9:CGCCTAATACTAT ref:2:7:TCGTACCTCTA 5 1881 +TATTCAC ref:0:7:A ref:0:7:TGGCA 4 28 +GAG ref:0:2:TAA ref:1:2:TACGTCGC 1 10 +CA ref:0:2:TGCAAAGGC ref:1:1:G 1 6 +GTCTCAAAGACAA ref:0:13:G ref:2:11:GTCC 8 4 +C ref:0:1:AGCTAGAT ref:0:1:AAGCCGACTA 5 3 +G ref:0:1:C ref:0:1:CAAGTGACGAC 1 6 +CCCCTCT ref:1:5:TCCCATGTCG ref:0:7:CCACATGCCTAATAA 2 82 +GTCTCGTACCG ref:0:11:TCACCCTGGGAA ref:0:11:TAC 5 198 +C ref:0:1:GGAAGAA ref:0:1:GGCACGAGGACCTCG 6 40 +CAGGTA ref:0:6:TCATAGCAAG ref:1:4:TCC 3 43 +GACTTCCGATACTT ref:0:14:TTTTTTCGGCA ref:0:14:CC 9 59310 +TAC ref:0:3:CGACTAAGGCA ref:0:3:CAGGTCCTA 4 18 +ATG ref:0:3:GCTAAGATAA ref:0:3:TTTACAAGTCA 5 330 +CGGACA ref:0:6:GATT ref:0:6:GCTAG 3 28 +GATCTGCGAC ref:0:10:TGTGA ref:0:10:CGGCCCCCACACT 4 30312 +CAGCGAGTTCAGCA ref:0:14:GAAT ref:2:12:TCTGCGTATT 6 35 +CATAGAACTCCCG ref:0:13:TG ref:0:13:TT 10 3 +CGGAGTGTCC ref:0:10:GAAAAA ref:0:10:AAGTCGCTAGG 6 85800 +CAGTATGGCTTGT ref:0:13:ACTGGACTC ref:1:11:GGTAAGAGGAGGTT 4 34560 +ATGTCTCTAGGGACCA ref:0:16:AC ref:0:16:CAACACAACC 9 80 +GTA ref:2:1:AAAAACGA ref:0:3:GGATGGGTATTTA 1 174 +TGTCTTGTC ref:0:9:CCGAT ref:0:9:TGA 6 140 +CAAGAGCGTAAAGGCG ref:0:16:AAG ref:0:16:TCTCCCT 10 41340 +CTGGACTTAGT ref:2:9:CT ref:2:9:AATCTATGTTTA 3 153 +TATGT ref:0:5:GACGTTAGCCC ref:0:5:GCGGCCTCCA 7 1216 +TCGGCTTAAA ref:0:10:GCTAGTC ref:0:10:CTA 6 816 +TGAGATGCGACCGTC ref:0:15:TAT ref:0:15:CGCTGGTA 9 918 +TCATAATTAGGGT ref:0:13:TGGG ref:0:13:ACGCAGTGCGGTCC 6 1060 +TTGGTA ref:0:6:GTGTTGAGGG ref:0:6:G 2 146 +CCTAAACTGAACA ref:0:12:TTAAAGATAGTG ref:0:13:TTCCTTCTGCTGAC 3 2944 +ATCTAGCTGGCCGC ref:0:14:AATACCTTGAA ref:0:13:TCAAATGCCT 5 141300 +GA ref:0:2:TCAC ref:0:2:TACTGTCC 3 18 +ATT ref:0:3:TAAGTATGATGCATA ref:0:3:GCA 1 16 +AGC ref:0:3:GGAA ref:0:3:T 2 56 +TGGAAGCTGTTTGC ref:0:14:TATGAGGAAT ref:0:14:ATGTAA 9 10010 +AGTAGCGGAA ref:1:9:T ref:0:10:TGTTTACGATG 3 54 +GTCAACGGCGCT ref:0:12:TGA ref:0:12:GCGTCTTGCTGCTAGT 5 5376 +AAAGGAAGATAAGA ref:0:14:CTCCACGGTATGACT ref:0:14:GGGCCGATTCCAA 5 315700 +CGGCTTTCACGTGC ref:0:14:AAAGGCGCCTAT ref:0:14:GGAACCTACTT 8 20650 +CTATTTGAAAC ref:0:10:GCCTTATGATA ref:0:11:TTACGA 4 12384 +CTCCGATTAGCTCG ref:0:14:GG ref:0:14:ATTCCTCTTCATTGTC 3 6 +TTCC ref:0:4:CTA ref:0:4:AAGTTAACCTACC 2 112 +ATGCGTCGACA ref:0:11:CGTAATAC ref:0:11:GAGGG 3 25 +CCGTG ref:0:5:TA ref:0:5:AGA 4 28 +CCCGTCTGCGT ref:0:11:CTT ref:0:11:G 7 30 +GTG ref:0:3:CGCTAGTAAGTTGCC ref:0:3:CTGTCCTCTAAAAGTT 7 39 +CGTAAGCTA ref:0:9:TTCCTC ref:1:8:AGTC 5 441 +CACAA ref:0:5:TTACCTAAGTGGAAC ref:0:5:GG 3 1428 +AGTACCTCCCTAACCG ref:0:16:GT ref:2:14:A 12 9 +TTGT ref:0:4:CGAGGGG ref:0:4:CGTCCGCAG 5 6228 +AT ref:0:2:GGTGCTACCC ref:0:2:GCCGCGAGAATACTA 5 91 +GGTCTGA ref:0:7:CCACAC ref:0:7:CTGC 4 122 +ACACAGCA ref:0:8:GGAATTCA ref:0:8:GAAAGCAAACGGTCC 4 7524 +TAGTC ref:0:5:ATTTCAT ref:1:4:CCGAGTTA 2 70 +GCTGACT ref:0:7:CTCTACCG ref:0:6:TG 2 36 +TT ref:0:2:GGATTCT ref:0:2:CCTCGTG 1 3 +CAGCTTCGACCAATA ref:1:14:AATAACGAATTG ref:1:14:TCTTGCGAGG 6 319428 +ACTCCA ref:0:6:TACTAGG ref:0:6:TTTAGTTATT 3 9 +GTCTGGCCGTTCCTAC ref:0:16:CCT ref:0:16:TGGCC 10 512 +GCTCGATTCACCTGA ref:0:15:AGCCTGGATTGAA ref:0:15:CATTTTGCGCGAC 4 11584 +CG ref:0:2:AACATACATTCGAC ref:0:2:TTACCCGTT 3 9 +CTTGCCTATCG ref:0:10:AAAATCGTACTTAT ref:1:9:TTATCA 3 1128 +TCCTTCACACGT ref:0:12:CG ref:0:12:TAATGTG 6 30 +CCAACACA ref:0:8:AACGCGCCAAC ref:0:8:CCGAG 4 5586 +AGAATC ref:0:4:CACTTAGCCTAC ref:0:6:CCATGCC 4 624 +C ref:1:0:TG ref:0:1:AAGAATATCCGGAGT 1 2 +AAACCAACCGGGT ref:0:13:AAGAACGGGTT ref:0:13:CCCTGCTAT 3 7488 +GGG ref:0:3:CTCCAAAAAGTTAC ref:0:3:C 3 480 +GGGCGTCCC ref:0:9:TTGGCCTGCTCTGTTA ref:0:9:AGGGGATTAA 5 18840 +TTTGTATCC ref:0:9:CAATAATTCTTA ref:0:9:CA 5 126 +CGTCTCCCACCA ref:0:12:CCG ref:0:12:GC 9 540 +ACTCT ref:0:5:CCTCTAGTGC ref:1:4:TCG 1 12 +TTCCA ref:1:3:GAATCGCC ref:0:5:GTTTGCCCGTGGAGCG 1 27 +CCGAGTACTTC ref:0:11:GCTCTTTAAAAATCT ref:0:11:CTGGCACACTCG 5 273672 +ATAGACTGATCA ref:0:12:GATTAACCAGAG ref:0:12:GCTTCGCACTGG 6 9828 +GTTATGGTGTGTCAT ref:0:15:ACGATGACAG ref:0:15:ATACTA 10 47008 +TATAT ref:1:4:GCACGAATACATC ref:0:5:AAA 1 36 +TCTG ref:0:4:GATCGA ref:0:4:GGCCCT 1 12 +AA ref:0:2:TATCTCCGGGGGT ref:1:1:TTCCATT 5 14 +GGGTGTTGATGAGC ref:0:14:CAACCTGGTGCCA ref:0:14:CA 9 8624 +AAC ref:0:3:TTACTTGTAAA ref:0:3:GGGCAGCCCG 2 336 +ACCCTGC ref:0:7:GCCCACGCTC ref:0:7:TCATGTGGAGCGATCA 4 36135 +ACTTAGG ref:0:7:GCGACCAATCT ref:0:7:A 3 4 +CCGCTAGT ref:0:8:TAATATATGATTGGAG ref:0:8:CT 3 3750 +CGAGTGCCCTATA ref:0:12:GACCAACGGTTT ref:0:13:C 5 16 +TC ref:0:2:GGAAAAGTGT ref:0:2:CTATTAAGCCA 2 24 +CACGGACTCTGAGCGC ref:0:16:GAGGCATGATAGCCTC ref:1:14:CATTGGGGTG 3 7440 +ACCGCCTGTAAGATG ref:1:14:TTCTTCAACAC ref:3:12:GGCCA 4 1044 +GTCGCATCCTTACCGT ref:0:16:CCGGTGAGACCCA ref:0:16:ATTT 6 2032 +AAGCATC ref:0:7:C ref:0:7:ACGCCAAGCGT 2 96 +CCTATGTTTACC ref:0:12:AGGTATTATACAA ref:0:12:AGTTCA 6 3562 +TC ref:0:2:TCGCTCCGCTGCGCTA ref:0:2:ACTAGAGGACCCAAA 5 42 +GCGCTTTCTCT ref:0:11:TTTCCCTCGGCTTTTC ref:0:11:CGATTGTCTA 2 1222 +GATCTCGG ref:0:8:TCAC ref:0:8:TGAAACACCT 4 402 +TACATGTCGGCA ref:0:12:GG ref:0:12:CAT 7 6 +TTC ref:0:3:TTTCCACTCCGTCA ref:0:3:GATTTAATACCCTGGT 6 558 +GG ref:0:2:CTAT ref:1:1:CCTAGTCATCC 4 15 +AATACGTCTCTCGTGT ref:0:16:ACACTACCGC ref:0:16:TATAGTTG 6 9990 +TGTGGCAGAT ref:0:10:CATATTCTCC ref:0:9:TA 5 64 +TATAC ref:0:5:GTCAGGCAAAG ref:0:5:GTGTCAGAG 6 1408 +ACCGCCCTTGACA ref:0:12:TTTA ref:1:12:CTATTTCTATCATT 7 21549 +TGACTGATTGAAT ref:0:13:GCTACAA ref:0:13:CCACGACTTGCC 3 240 +GTGCCCCTTACGAA ref:0:14:AGTGAGTA ref:0:14:TAAAG 7 9 +CCGTAATTATACCAT ref:0:15:GAGCGGCTA ref:0:15:GAGCGCCTTTT 8 3400 +CCATCT ref:0:6:AGTTATCAAACGGG ref:0:6:CC 3 1290 +GTATTGCT ref:0:8:AGTTGATAC ref:0:8:AACTTACCG 4 1248 +CGGTCGCCAAAT ref:0:12:GGCAATTGTA ref:0:12:AGAGC 6 3920 +TTGGAC ref:0:6:AGTGCGACAG ref:0:5:CAA 2 80 +CTACC ref:0:5:GA ref:1:4:TAGTAAACTT 2 117 +GAGAATTCCC ref:0:10:CATGAAGGGGGTCT ref:0:10:AGGT 5 946 +GC ref:0:2:CCCGAAGGCAGAGTG ref:0:2:CTG 2 6 +GTGCGC ref:3:3:AGAT ref:0:6:AGCATACACTCTCCG 3 1014 +TTTCAAGAGC ref:0:10:T ref:1:9:GTTGGT 5 6 +GTT ref:0:3:AATCCGATACTCACCA ref:0:2:CAGTAGGGG 2 1 +CCACGG ref:0:6:TATCTACCTCTAA ref:0:4:GTGACT 3 4750 +A ref:0:1:CCGTCTT ref:0:1:AAGACTATG 4 32 +TGGCAGACCGCTTAGG ref:0:16:AAGACAC ref:0:16:GGCAACGTCAAA 7 10416 +CCCTCCCTGGTG ref:0:12:ATGCTGG ref:0:12:GGA 7 360 +C ref:0:1:CCAGTTGTTAGGCGT ref:0:1:ATCTTAGC 6 6 +CGAATTGGCCCAGA ref:0:14:AGGGAGATGTGAC ref:0:14:CTCTTGTT 6 613602 +ACCGGTGTTGTTG ref:0:13:GATTCGAGTT ref:0:13:TTGTCAAGGGA 7 81130 +TACTACAAGACTACGT ref:0:16:AATGGGGGCGTG ref:0:16:TTATAAGTGTAAGGCA 8 20050576 +AAAG ref:0:3:TGTAGGGCA ref:0:4:GGCAGGTTTCTTGCG 6 2470 +TAT ref:0:3:CACTGCATGACTC ref:1:2:GAGG 2 12 +GCCT ref:0:3:TGTAATATTTGGC ref:1:3:CCTCTCTTACTT 4 612 +CCAGTCCGCTAGAGC ref:0:15:AGTGCT ref:0:15:AAA 7 1 +CTAGTATAA ref:0:9:GTATGAAGCTA ref:0:9:TGGATAAGGT 4 108 +ATACAGTCTGGA ref:0:12:TGACAG ref:1:11:AATGTGATCTCAA 2 81 +CATTTC ref:0:6:CGTCTATTTGCC ref:1:5:TATGTCCA 2 44 +CGTTACT ref:0:6:GCGAAAGGCC ref:4:3:AAAAGGAGC 4 100 +ATCATTCCCCTTCGTA ref:0:16:T ref:0:16:TGAGTGT 11 216 +GCTCGGGA ref:0:7:AGCTCT ref:0:8:TGGATCAA 3 164 +CAGCCTCA ref:0:8:CCTGCCCTATGC ref:0:8:GCATC 3 200 +CGT ref:0:3:CACGGATTTACAGGG ref:0:3:AATTATCTGCGG 4 132 +CTCTC ref:0:5:CTCTTACGTGC ref:0:5:CACCTCTATCAACGGA 4 120 +GAAGCCGT ref:0:8:AACAAAGCTTCCCG ref:0:8:GTCTTGGGGCTAAATT 3 1168998 +ACTTCTCCATT ref:0:11:CTTAGAATCT ref:0:11:AAATATTCATACGCG 3 19320 +GTTTCCT ref:1:6:CAACCTTGAA ref:0:7:AGACATG 5 572 +GGACTGAGGACTAA ref:0:14:TCCAGGGAGA ref:0:14:CTCCGACGA 9 101475 +TTAGCATTGGT ref:2:9:CGCTCGATACG ref:0:11:GAGAGCG 3 264 +CATATTCCAAGG ref:0:12:AG ref:0:12:AGTG 9 208 +GTCCACTGTCCGACA ref:0:15:ACGTGCACTGCTGAAG ref:0:15:CCCCATACAGGGAC 3 23616 +GCGCAATG ref:0:8:TCT ref:3:5:ACA 2 18 +ATTTTGAT ref:0:8:TGAAGGGGGC ref:0:8:CTCCGTTTGTC 2 120 +CAG ref:0:3:TTAGACG ref:0:3:CGAACAGGACGTAGAG 3 420 +AGGGGGG ref:0:7:CGCAAGTCA ref:0:7:CCCCCGGTG 6 1079840 +TATCTATCGC ref:0:10:TTG ref:0:7:GCGTGCCGTA 3 174 +ACCC ref:0:4:AAACTCAGCAAAG ref:0:4:GAAGAGCAGG 5 306 +TAATGCAGACTGGGAC ref:0:16:GGC ref:0:16:AG 12 187 +TGTA ref:0:4:TCACTCATTCAGCC ref:0:4:CGCGACT 3 496 +TG ref:0:2:TATTAGAGG ref:0:2:GG 1 27 +TTTCTGCCTATCGAT ref:0:15:GATTACTAG ref:0:15:ACTG 10 5341 +C ref:0:1:TACAAGC ref:0:1:CTGCCCATCCTCAC 4 16 +GGTAGT ref:0:6:CGTTT ref:0:6:TACG 1 16 +TAAACACGTTAAAGCT ref:0:15:CTTAGCCC ref:0:16:CTCCCCGGCGTTACA 6 37800 +CTCGAATATCGC ref:1:11:CT ref:0:12:TTGCG 6 24 +GAT ref:0:3:TGCTT ref:0:3:GTGCCGTAACTCT 3 60 +ACTAAACGGGCA ref:0:12:AGCAT ref:0:12:CCATTCGCT 7 4752 +TGT ref:0:3:GGTCGATAAT ref:0:3:CTGTAGAAG 2 2 +CTATGT ref:0:6:TGCACTG ref:0:6:GGAGCTT 3 42 +GCGCGCAGCACGGCT ref:0:15:GAAGG ref:0:15:GAGACTGTGCCTGTT 6 234 +AAGGGGCTCCGCA ref:0:13:AACAACTAC ref:0:12:TAGCGATAGGC 7 402129 +G ref:0:1:TTTGTC ref:1:0:CATC 2 1 +GATACCGCACCAG ref:0:13:TTTGGGT ref:4:9:GTTACT 6 5691 +GGGGTCCTCATTT ref:0:13:AGCACGCGCATG ref:0:13:CCCGATATACAGCACC 8 29160 +TTAGGGGA ref:0:8:TCAGCCCGCGTAA ref:0:8:CGCGTAGGGT 3 3078 +AGTG ref:0:3:CTGCGCCTAT ref:0:4:ATATTCATCCAGGAGG 4 2601 +GCGAATTAGT ref:0:9:CATAGTGTTGGGC ref:3:7:A 1 63 +GCACTTCG ref:0:8:TGG ref:0:8:CGTGTATTCTCAACGT 3 896 +CAAAGCAGGGGGC ref:0:13:G ref:0:13:AGCAATTT 9 5292 +TCGCGACGTACTTCA ref:0:14:GAGAACACCGTTG ref:0:15:T 6 64 +GT ref:1:1:AACTC ref:0:2:ATAAGATCAAGTTTGC 3 7 +TC ref:0:2:TGAAGTAT ref:0:2:ATGG 3 36 +CTTTCTT ref:0:7:TTATGCA ref:0:5:AATACGCCGGA 4 585 +CCCCC ref:0:5:CCTGAATATGAAT ref:0:5:AGTCGGGCGACGAT 7 67200 +TACTAGACAG ref:0:10:AA ref:0:10:GAAA 7 96 +T ref:0:1:AGTTCGTCTGGAGA ref:0:1:AGTCAATAGTCGT 7 16 +CGTGA ref:0:5:GGGATTG ref:0:5:GG 2 17 +ACCCTTTACAA ref:0:11:CTTTAAGTCG ref:0:11:GGGC 6 7761 +TTGGAAATATCGCC ref:0:14:CTGTAACTTTG ref:0:14:CCCAATACTGTGC 7 577920 +GAAGTGTT ref:0:8:TGCGAC ref:0:8:AGACGAAGGT 4 1456 +TCATCT ref:0:6:CGAG ref:0:6:AAAG 5 296 +TACTTTG ref:0:7:GTGGT ref:0:7:ATCCAGAGTTAT 4 1122 +A ref:0:1:ATCGGGTAC ref:0:0:GCCTTCCCTC 3 2 +CAAACGCATCCTCAAA ref:0:16:ACTGGAAGTTGAA ref:0:16:ACCCG 7 32767 +GATGATG ref:0:7:GGTATAATA ref:0:7:TCGGCGAAA 4 1968 +GCTCATCA ref:0:8:TACGGCGTACAC ref:0:8:AAAA 3 180 +ATATTAGC ref:1:7:ACGTACCT ref:0:7:TGG 2 156 +GGACAAACCTCCAT ref:0:14:CCAACACTCATA ref:0:14:CGATTTACACCGT 6 192660 +AAAATTGTGG ref:0:10:CA ref:0:10:GTCTCCGC 6 2770 +ACTTGGTGTGCTCTAG ref:0:16:GCACCAT ref:0:16:GGTGCGACAAGAATC 10 20325 +TACAGAT ref:0:7:GAATGTGATGTC ref:0:7:ACTATTCGA 3 16 +GCACTTCGT ref:0:9:TA ref:0:9:AATGTGTGTCCAG 5 2522 +C ref:0:1:CGCCCTGGTTT ref:0:1:GCGCCCTTGTTGTGGG 9 16 +GAGGCA ref:0:6:AAAACTG ref:0:6:TG 5 1464 +GACACG ref:0:6:G ref:0:6:TTCTCGT 3 24 +GCAGGCGGCCTGTGGT ref:0:16:TGTCATGGCGGACT ref:1:15:TAATATCAAGTTAC 7 98892 +TCCGGATTGGA ref:0:11:GC ref:0:11:GTTGTCTG 7 550 +TTTAA ref:0:5:GTCCGAGGCGC ref:0:5:A 3 356 +AGTGTTGGACAAA ref:0:13:A ref:0:13:GTGGTGCCTCTG 6 11800 +TCACACCAGGATA ref:0:13:AAGAGG ref:1:12:AGAACT 6 171 +AGGGCGAGCTTT ref:0:12:ATTA ref:0:12:CCAC 7 56 +CAAATTG ref:0:7:GCTATCAGATTTATTA ref:0:7:CGGCCT 3 5043 +AAAGCGCATTC ref:0:11:ATGTCCCACTA ref:0:11:GCCTG 5 960 +AGTCGCAAGC ref:0:10:AG ref:0:10:GTAATTCTAGTGCGG 4 3340 +GACCGC ref:0:6:GTGAACGTAGGTT ref:0:6:TACCCTGGCGAGCTG 4 11328 +CCAAGCCCT ref:0:9:ACAAATTGACA ref:0:9:CTTAATAACG 6 119360 +GAAT ref:0:4:ATGGGCCGACCAA ref:0:4:ACGTCAAGAGAAAG 5 1232 +GGT ref:0:3:TTTCATGTTTCA ref:0:3:GCTTGACACCCCGC 5 567 +CTTTCTATTCGGTCC ref:0:15:TCGATTGCCCC ref:0:15:TGGTAT 7 21888 +TCGTCCAGT ref:1:7:CCTC ref:0:8:CATGTA 2 14 +G ref:0:1:CTCC ref:0:1:AT 2 15 +AAT ref:0:3:GGCGTTTGCC ref:0:3:CTCAG 4 896 +TTT ref:0:3:CCAGAT ref:1:0:AGCGCGC 3 28 +GCCATAATAGGA ref:0:12:TTATTTGTTTGCGTCC ref:0:12:CGTC 8 1541020 +CGTTTGAGGCAT ref:0:12:ACGATCATCACGCTGA ref:0:12:TGATCA 3 819 +ATCAGGG ref:0:7:CTGA ref:0:7:GATGATA 5 1353 +CGGTAGCCCC ref:0:10:AGCGGTAGC ref:0:10:AGAA 4 228 +TGAGCACTG ref:1:8:ATATC ref:0:9:CCAATTATCGGTTTT 6 36288 +CTATCCCGACGGTATG ref:0:16:AAAA ref:0:16:TGT 10 204 +TTA ref:0:3:ATCAATGGCTCC ref:0:3:CTACAAACTAGAGACT 7 66 +GTCATAAACACG ref:0:12:CCTGGTTACAC ref:1:11:ATAGGTCT 4 1314 +TATGGCGAGGG ref:0:11:A ref:0:11:CAGATTATGTGATAGG 3 252 +AA ref:0:1:CGAGTTC ref:0:2:GCG 2 10 +CACTGATG ref:0:8:CGTA ref:2:6:GTGGCCT 3 180 +TCTATTTAC ref:0:8:CTCTTG ref:0:9:T 4 170 +CAG ref:0:3:AATGGGTTTGATGC ref:0:3:CGGCAC 3 182 +CACTCCG ref:0:7:CGG ref:1:6:ATAAATA 3 1700 +TA ref:0:2:ACGC ref:1:1:GAAGCCC 2 2 +AAGT ref:0:4:GCGAGCGGTGG ref:0:4:CTATTGCG 4 780 +ACTACT ref:0:6:GCGATG ref:0:6:TGACTAGCCCA 1 36 +AATTCATT ref:0:8:ATGGTTGG ref:1:7:TATGTAT 3 80 +GAG ref:1:2:CACAAT ref:0:3:T 2 40 +A ref:0:1:TCCTTTGACA ref:0:1:TACAGAACAAGTGCTT 5 12 +ACGACAGCGCGCTCGA ref:0:16:CACAGGGTAGGTAGAT ref:0:16:TTACTCAACGCCC 2 1768 +GGGGTTACGGCTTAC ref:0:14:GCT ref:0:15:TAGGTGAA 7 400 +ACA ref:0:3:AGAAAGCAAAGAT ref:0:3:TTGGCCGCT 4 1040 +ACGGTCG ref:1:6:GTGT ref:0:7:AATGGCCAAAC 2 330 +AA ref:0:2:ACGGCT ref:0:2:CGTGAATCACCGCTCT 4 21 +CCTACTCCAC ref:0:10:TCAATGCTCC ref:0:10:GATTCTCCG 5 12284 +ATATAACGAGGGCAGC ref:0:16:GGGCAAGATTCCCGT ref:0:15:CAGCACCTCACTT 6 432 +AA ref:0:2:CTACAGGAAAGCTACC ref:0:2:CTTTACCATA 5 45 +AATCGTGGTCCAT ref:0:13:TCTACAAACTAACCAG ref:0:13:GACC 6 5244 +GAATT ref:0:5:TGCTAACG ref:1:4: 2 6 +GTGC ref:0:3:CGGCATTCCTGG ref:0:4:CGTAAGGTAAG 2 180 +TTTTATTGAGCA ref:0:12:CCAGGCCGATTAGCCG ref:0:12:GT 7 79050 +CCTCG ref:0:5:CCGCATTC ref:0:5:TTGGAAAGAGTTAAC 4 1320 +CAGTGATCATGAGGC ref:0:15:AGCAGCCATACGGT ref:0:15:GCCCTATTGATGGT 5 1848 +GGTATAGGGTAA ref:0:12:ATGATACTTGG ref:2:10:ATG 5 276 +CATAAATCGCCCTAA ref:0:15:AT ref:0:15:GCCGTTA 9 297 +TAAAGGAC ref:0:8:CTAAT ref:3:5:TTAGG 3 22 +ATTTCAA ref:0:7:TCCTCCTA ref:0:7:CCAAAGCTGGT 3 1720 +TCT ref:1:2:GTGA ref:0:3:GAGAGCCGCTCGATA 2 2 +CCT ref:0:3:CTTTAGACCGTAAC ref:0:3:TATTTGGCTGACCGCC 7 96 +GT ref:0:2:CCGATGTTAG ref:0:2:AGAGTCAACTCACTC 4 30 +CCCAATGTACG ref:0:10:GAGCT ref:0:11:CTTCATGGGA 4 2280 +AGTGG ref:0:5:CAGAATGGCTCCC ref:0:5:GACAAGACCTCAC 4 30 +GCCCCGAAGTGGTT ref:0:14:CATCATATTTTA ref:0:14:CGTAACA 7 12600 +CATATCCAC ref:0:9:TCTA ref:0:9:TAAAATGTACGAACAA 3 15708 +GTTAC ref:0:5:TTAAT ref:0:5:TGTATGAAAACACCT 2 70 +TACGCGTA ref:0:8:CCC ref:0:8:CCTCGGGGACCTC 4 549 +TGACGGTGTGAGGA ref:0:14:CGACCTAAAG ref:0:14:AGCTCATAGGAT 6 11088 +ACCTGGCAGCACCCCC ref:0:16:CGAAGAGAGG ref:0:16:GAGCCTC 7 2940 +CCTACTGTACAT ref:0:12:CC ref:0:12:ACAAGGGGTG 6 6 +CCGCA ref:0:5:GACTTCACTGGAAT ref:0:5:TCG 2 84 +CTG ref:0:3:GATGCTCCC ref:0:3:TAGAGGTA 2 21 +TTAA ref:0:4:CAAAAACGGCGATT ref:0:4:GTACCAAGGTTCCT 6 1452 +TGCAATCTCACG ref:0:12:GGCACTGAACATA ref:0:12:GTTCGATTGGTTTACA 6 589798 +T ref:0:1:CTGCATACA ref:0:1:TACAAGTGATGTACT 6 10 +GCCCAATCCTGGGCGG ref:0:16:TACAAGATTCTA ref:0:16:CCCCTGAACTT 8 1103310 +GATCCATCACCAT ref:0:13:AATATACGAGC ref:0:13:A 6 156 +GGATATAGAG ref:0:10:G ref:0:10:AACA 6 40 +ACACACA ref:0:7:CAGTGCGTTTCATT ref:0:7:T 3 40 +ACGAGC ref:0:6:ATGGGCCACAATC ref:0:6:T 3 1442 +TCTTATG ref:2:4:ATACTT ref:0:7:GGC 1 77 +CGGTCATGC ref:0:9:GTATAGGGCCGCGG ref:0:9:TGACCCACCGTCATGA 1 1000 +A ref:0:1:AGACC ref:0:1:AGACGTT 3 4 +GAGAGAGGCCGGATT ref:0:15:GGAGTGCGAGCAGGGG ref:0:15:TG 6 300 +CATCGTCATCTTTCGC ref:0:16:ACTCGG ref:0:16:CCGAATAGTACTAGA 6 12636 +TCTATGGT ref:0:8:GCTAAAGGGGGG ref:0:8:ACATTCCT 1 28980 +CCTCC ref:0:5:TCCGTACGAACGTAT ref:1:4:GGGGCGTAGACAA 5 7 +CTCGTATGACGA ref:0:11:ACCTCAGCCGTG ref:0:12:CGA 4 234 +GG ref:0:2:TGCTAC ref:0:1:CAGCCTTAC 4 7 +CGTCACAGGAA ref:0:11:AATGTAAA ref:0:11:TCGGTGCCAGGCCATT 2 348 +CAAAGAG ref:2:5:CTTAAGGCGACCA ref:0:7:TGCATTTTGCGC 5 882 +CCGATCG ref:0:7:GAAGAGGAACACGA ref:0:7:GCGAATTTTAGT 4 70392 +TAGGTTTCT ref:0:9:AAGAGCTTGCG ref:0:9:ACG 4 150 +TCATGGACGC ref:0:10:GATATTAT ref:0:10:GTTCGA 6 144 +CCCA ref:0:4:CCTGGAGT ref:0:4:GT 3 90 +AAAGCCCCATGCC ref:0:13:GCAGAGTC ref:0:13:G 8 452 +GAGCTTTATCGCACG ref:0:15:AACCGAGGTTT ref:0:15:GA 9 222 +ATTGCCACTCC ref:0:11:TTGATAGTTCAGCCT ref:1:10:CTGGTAAA 5 563680 +T ref:0:1:GTGTCAGACTGAT ref:0:1:CGTTAAGC 5 8 +TATGGAGATA ref:0:10:AGCTGAT ref:0:10:CTCCAT 6 1728 +AAGA ref:0:4:ATTACTACGG ref:0:4:TTGTAACCATCAAACG 6 912 +CAGTGGTTA ref:2:7:CGAGCT ref:0:9:ACCGGGGTT 3 616 +TGATAGGCGCAA ref:0:12:GCT ref:0:12:T 10 58 +GTGTGTGTTAGTTT ref:0:14:CTGAAAGAGCGGAAGT ref:0:14:TCATTTCCTCGTGGGC 5 683424 +GTTGGCGTACATTTGA ref:0:16:TACCTGATGATC ref:0:16:CTT 9 5742 +GCCAGCAGATGG ref:0:12:GAG ref:0:12:AGCCCCATGC 5 672 +ATGTCCA ref:0:6:CGG ref:1:6:TCCAT 2 44 +GA ref:0:2:C ref:0:2:ATTACT 2 15 +TCAA ref:0:4:CAGTAATGAGT ref:1:3:CCGGACTGAGCCCTC 5 20 +CAACGCAGAACCACG ref:0:15:GCGGATCTTCCC ref:0:15:AA 7 2610 +AGG ref:0:3:CGGAGT ref:0:3:GACG 2 40 +TACTGT ref:0:6:CTAGCAGAAAGC ref:0:5:AGCCTGGCAG 3 144 +TGGGTAAAC ref:0:9:CAGATCTGGGCGACG ref:0:9:TCATGGTCT 4 504 +TGGAGAGTG ref:0:9:CCCGTTATGA ref:1:7:CAAAG 3 2895 +CAAGCAATGATAAA ref:0:14:GG ref:0:14:CTCTAGACATGATT 5 140 +AG ref:0:2:GCGAAAGCAGGGACA ref:0:2:GATATTTAGT 3 45 +AGT ref:2:1:ATCCCTGCACG ref:0:3:CAATATCT 3 50 +CGGTCGTTTC ref:1:9:CATAA ref:0:10:ACAATAAGGGCT 5 950 +GTAGATGA ref:0:8:TGCGCAACATC ref:0:8:ATG 3 602 +T ref:0:1:GCTCTTCTAATAGCT ref:0:1:CGCTG 3 6 +ACTAG ref:0:5:GTTATATA ref:0:5:GGACTCGCCTCT 2 16 +ACA ref:0:3:TGGTGCAGG ref:1:2:TCCGGCAGT 4 18 +AAGGATAATG ref:0:10:CCTAATCA ref:0:10:CTCACGTGAGGTGGG 5 49815 +GCTCTGTAAAAGAAC ref:0:15:CT ref:0:15:TGCTG 11 65 +A ref:0:1:TACCTTTC ref:0:1:GGAGTCAAGGA 2 4 +TTTCGCCG ref:0:7:TGATCGCTGACC ref:0:8:A 2 252 +AAGCA ref:0:4:TTCCAAACGGGT ref:0:5:A 1 93 +GCGGGC ref:1:5:CAAATTCTAAC ref:0:5:TTCTCGGAGAGGT 5 26048 +TATGGAAAGGCATCTG ref:0:16:T ref:0:16:GTAT 13 452 +GTGAGTCCA ref:0:8:ATACCCGCAAGT ref:0:9:TCTCTGAGG 5 288 +TCTCATCAGCACCT ref:0:13:CGCTAAAGGGATC ref:0:14:T 6 3312 +GGAA ref:2:2:CCTT ref:0:4:CAAGCTACT 4 765 +CCCCA ref:0:5:AGCGAA ref:1:4:TCGTGGCTCTACTG 1 91 +ATTGCTTAACCGTTGT ref:0:16:AACCAAACATTGAAC ref:0:16:GCCCGAATCAGCAGGG 8 322848 +TT ref:0:2:CGGATCTGATCCT ref:0:2:GGG 3 60 +AATGCATGTCCGGA ref:0:14:GGGTACTCATT ref:0:14:TAG 7 48 +CT ref:0:2:AGGAAGGGCCGTG ref:0:2:TCACCGCGCTCCAC 3 10 +GGAT ref:0:4:TGTGGGGCGTTG ref:1:3:AACGA 1 105 +GGCGAGGT ref:0:8:CATTT ref:0:8:AGCTCGGAGA 2 1010 +CAA ref:0:3:AATG ref:0:3:CTCTCAGTT 1 21 +TATCCAAGTC ref:0:10:CCTATTATCT ref:0:10:GTTCTTGGTAAGCG 2 70 +GGCAGTGGAA ref:1:9:TAGAAGCCGGC ref:0:10:TGAACAGACCC 5 2025 +TAACAACGAACC ref:0:10:GGTACGGCAGCGAT ref:4:8:CTGT 3 405 +TCCTTAG ref:0:7:GACTGGAT ref:0:7:CAAAT 5 11520 +C ref:0:1:ATTCTCCCG ref:0:1:CGTAGTCC 3 12 +GGAAATGACTGACG ref:0:13:AGGTACA ref:0:14:CCTA 6 10 +AC ref:0:2:TTGCCGCTGTGTGTGT ref:0:2:CCCCAG 4 192 +ACT ref:0:3:TACACCTATGC ref:0:3:CTTTCG 2 30 +ACCTAGGACC ref:0:10:TGTTTA ref:0:10:A 7 15 +TGATTTGATAGA ref:0:12:CGCGTATTT ref:0:12:AACGATGCCC 4 3344 +AGAAAGACATTACCT ref:0:13:GACTTTACA ref:0:15:GG 5 20 +TTCTATTTTGGGCCT ref:0:15:GCTACACCCTAACCG ref:0:15:TGGGCCCGTAT 8 619626 +AGGAAGA ref:1:6:AATGCCCGACTT ref:0:7:AGAGCGAAACTCTCTA 3 184 +GG ref:0:2:T ref:0:2:ACGGATTTGC 1 9 +CCTAA ref:0:5:TTTAGGG ref:0:5:GACGAGGGTGTTA 4 6105 +CTTGCG ref:0:6:AACG ref:0:5:G 3 17 +ACTCGTCTAGCTGCA ref:1:14:TCCA ref:0:15:GATAAT 9 528 +GT ref:0:2:CTAGCCTG ref:0:2:CCCTATACTCGAAA 5 23 +CGCTCAGGGCTT ref:0:12:GCCATGCTTCGATTG ref:0:12:CTGAACGAC 5 28956 +GGC ref:0:3:CAGTAGGCGT ref:0:3:T 1 12 +GGTTAAGAGACT ref:0:12:TCCGG ref:0:10:AAG 5 64 +A ref:0:1:CAACATAC ref:0:1:AGTCTTA 3 8 +TT ref:0:2:ACACAGAATCTGT ref:2:0:GACAAC 1 3 +CGCTCAT ref:0:7:AGTGATTACCCAGGCA ref:0:7:GTGGGCCGCG 7 391125 +CCAC ref:0:4:AG ref:3:0:GT 1 2 +CTGAATA ref:0:7:CCGCGGCGCGT ref:1:6:GC 5 2880 +TTGCTCGATCTCTCAA ref:0:16:TGGAC ref:0:16:GCG 10 12 +CAGTAACTGTCA ref:0:11:ATG ref:0:12:TCAA 7 88 +ACACCAAGTGGTGCTT ref:0:16:AGATATCGATATAC ref:0:16:ATGGTCTTAG 8 15180 +AGCACAAGCTCGTA ref:0:14:GCGCGGAG ref:0:14:GTGTCTGGTTAAGGG 8 2160 +T ref:0:0:ACCACCCGCAG ref:0:1:TTCAT 2 3 +GTT ref:0:3:TCTATATTGCGAGTA ref:0:3:GCTGGCTGACAGTTAA 7 966 +TTAGTACTATGA ref:0:11:AACCCA ref:0:12:TAGGGAATTAGCC 4 3816 +ATC ref:0:3:TGTTTTT ref:0:3:TAAATACCTTTTGGA 5 432 +TAGTACTGT ref:0:9:GTTACA ref:0:7:C 3 12 +ACTAGCTGGACCAGG ref:0:15:GCGTAAGCTCG ref:0:15:AGTGGCAA 4 320 +GG ref:0:2:TCACTGTTCAATGCTC ref:0:2:GCCCGGAGCGAA 4 10 +AGC ref:0:3:ATGATCGATCTGCAG ref:0:3:GCTCTAGGTGAA 5 160 +TTTAGGGTCTAGC ref:0:12:C ref:0:13:ACTAATACACGGG 7 528 +TTAAG ref:0:5:GTA ref:0:5:AATTT 2 60 +GGAAAT ref:0:6:ATAGGAAC ref:0:6:CTGTCCGCGGAATGCA 3 203 +CACG ref:0:4:ATGGAACTCGGAGGTA ref:0:3:A 1 110 +GT ref:0:2:TGAGCTGGT ref:0:2:AACGAGC 3 36 +CAACCTAAGG ref:1:9:GAAAACACAGAG ref:0:10:CA 2 320 +AATATCGGGGAGAT ref:0:13:G ref:0:14:AATCACATA 6 60 +GTCCGGGTGATTTCG ref:0:15:TGACCCA ref:1:14:CGTTGGCATGAAGAA 6 2532 +CCAGATG ref:2:5:TTACTGGTTCA ref:0:7:GTGAGGGACCATGTTC 5 3312 +CG ref:0:1:T ref:0:2:AATCGGCGAC 1 8 +TG ref:0:2:GCCCAC ref:0:2:ATAC 2 3 +CCGATAT ref:0:7:G ref:0:7:CGTTATGTGGCG 2 16 +AGAGAAGTGG ref:0:10:CCAATA ref:0:10:CAGAAACTGACC 5 1020 +CAGGAT ref:0:6:GCGGAATAT ref:0:6:TCCCATCCTCCATCA 1 420 +TTAGGT ref:0:6:ATGCGGGTA ref:0:6:GTTTAAGAATTGAA 1 4446 +CTGCGT ref:0:5:TTGTTGGAGAG ref:0:6:GCATATACTAAAATTC 4 22428 +TCGGAGA ref:1:6: ref:0:7:GTCCTTGAGCTTCC 2 54 +GGCCAGAGTTGGA ref:0:13:AAGGCTGTCAC ref:0:13:AGG 7 2205 +CGGCATC ref:0:7:GCGG ref:0:7:TACAGGATAGGAT 2 23 +GAACCGATCTCGG ref:1:12:TCTTCACCTCAC ref:0:13:AGATAGTTACGAGGG 3 498 +CGGACCTATGCC ref:0:12:AAACGACGCCG ref:0:12:ATCCGTGAGGCTAGGA 4 384 +CAAGA ref:0:5:ATTT ref:0:5:ACTAAATGACAA 1 279 +CGTAA ref:0:5:TAACATTCATCC ref:0:5:GAGACAACCTTTC 7 1170 +GTGTGTTCAACGC ref:0:13:GTATCATAA ref:0:13:GTGCCGGGAGTTTTC 5 404090 +ACCA ref:0:4:TG ref:1:3:TGCTCTTT 3 60 +TTAGGACGGG ref:0:10:ACAGGGTTGATACAC ref:0:10:C 5 1206 +TCATAAGAGAATG ref:0:12:CTGGAGTCCTCTAA ref:0:13:CCCGAGTCGCGTGGTC 3 288 +CC ref:0:2:GCGCGTGACCAGAG ref:0:2:AAGGGT 4 168 +GAGTGAGCGG ref:0:10:CACGATAAGACC ref:0:10:GGCCAAAAATTA 5 5253 +TCTAG ref:0:5:GAGATTCCACCAGAA ref:0:5:ATTTAC 3 256 +ATGGTCCTCAGTG ref:0:13:TGGAAGGAGAA ref:0:13:TCT 5 462 +CACACTATCT ref:0:9:TCCCGGGTGT ref:0:10:CATGTACTT 3 162 +GGG ref:0:3:CGATGCAACCGA ref:0:3:AATGAG 3 7 +GATC ref:0:4:AGCTTT ref:0:4:GGACGTTGTAGACGTT 3 150 +GGTCCAAGCAG ref:2:8:ATCCTCAGCT ref:0:11:GCGTTCG 3 336 +AA ref:0:2:AAATAG ref:0:2:GCTAGAAATA 3 60 +CTGAAAGCAAGAC ref:3:10:GTG ref:0:12:TCCCTCCACGGATA 6 14832 +CTTATCATGC ref:0:9:AA ref:0:10:TCCGCCG 4 36 +TATGGTT ref:0:7:C ref:0:7:AGTTAATTTCAAA 3 32 +GATAAAACCC ref:0:10:CTCGACGATCTCTGA ref:0:10:AATG 7 282283 +CGGC ref:0:4:TCAAGAAGATGTGCT ref:0:4:GAGTGATTCCATG 5 60 +CACATATCCA ref:0:10:GTTCTAATGAC ref:0:10:GCCTAGGGACGCGCC 4 340 +CGAGCGTGTGGGGAGG ref:0:16:TGC ref:0:16:TATGG 12 9100 +AGGTGGAA ref:0:8:CGTTGAATAACG ref:0:8:TCGCGACAGGTTG 4 2596 +GTCTCA ref:0:5:CTTTTTG ref:0:5:TGGGATAT 3 996 +CAATCGAT ref:0:8:GCC ref:0:8:ACTCCCCCAA 4 200 +CTCACATCTTCCT ref:0:12:AGAAATTGCTGTG ref:0:13:GTTT 7 14868 +CTCTCATTAGG ref:0:11:GTCTT ref:0:11:CCTGAGTC 5 1164 +TGGATACGTACG ref:0:12:ATA ref:0:12:ATGCCATAGACC 4 48 +AAAGTGCATC ref:0:10:ATCGACG ref:0:10:CTTCTTCAAGTCG 5 4992 +AAAGACAAGACAC ref:0:13:AGTGATACAT ref:0:13:TGAACGTT 9 641516 +GT ref:0:2:CCGAGCCCTGCGGCC ref:0:2:GTCACATGTGG 5 8 +TAGAGAGATCAG ref:0:12:AA ref:0:12:CCACTCAGCGCGA 6 840 +ATGTATTTTTAT ref:1:11:CGTTCACCCTG ref:2:10:AGTGAAG 5 140 +TT ref:0:2:CAGGCAT ref:0:1:CACGCAAACGTAACC 5 8 +TGTCA ref:0:5:TTCCCAGATAGTTT ref:0:3:CGGTAAGAGGGA 2 220 +AAC ref:2:1:T ref:0:3:GCTGGATTCCTAAA 1 58 +TGGCGAGTGTCCT ref:0:13:GCGTTGGTCG ref:1:9:C 3 150 +GGA ref:0:3:GACACCTAAAG ref:0:3:CATAGGGGC 1 544 +A ref:0:1:TGACGACCGCCTGC ref:0:1:GGCTGTTGAAG 4 4 +CCTTTGCC ref:0:8:CACA ref:0:8:CTGGGAGGT 5 49794 +CTCTTCCTGCA ref:0:11:T ref:0:9:TGG 7 84 +CGGTTCGCGTGTCCT ref:0:15:G ref:1:14:TTGCCCAA 8 15 +GAGAGATTAAGG ref:0:12:GT ref:0:12:GTCATTCCA 7 720 +ATA ref:0:2:TGACGATGTGCG ref:0:3:TGTCACTGCT 5 36 +GAGTCACTG ref:0:8:CGCCGGAATT ref:0:9:TCAACA 3 1890 +CTATC ref:0:5:GGGAGCAAACCACA ref:0:5:TCACCCTGGTTG 4 6930 +CCTAT ref:0:5:TTG ref:0:5:TTCTGTCCGTTCA 1 9 +CCGTT ref:0:5:GTTCATTGGT ref:0:5:AGTGCTA 3 276 +AACACCCACAC ref:0:10:CTCGAAATATAGCAT ref:0:11:CAGTA 4 2236 +TTACT ref:0:5:GGCTCGCGAATA ref:0:5:ATCGG 4 676 +CGCGTTTG ref:0:8:C ref:0:8:CTCCAGAGT 4 240 +TTGATCCACA ref:0:10:TCGTTGAAAT ref:0:10:CGATA 4 18 +GT ref:0:2:GCTACAACCAGTTTC ref:0:2:AGTAACAC 5 7 +GCA ref:0:3:TCGGGGGCGT ref:0:3:CATGGGCCCAACGT 5 270 +CTTCA ref:0:5:AGCGCGTCGTAGAGC ref:0:5:ATTTATGCGGTTCT 5 52 +GAGGAGTGCTGCTAC ref:0:15:TTAGAGGGATAGGT ref:0:15:CTTGATGTC 7 920 +ACCGGTCTCAGC ref:0:12:TGAAGTCCCG ref:0:12:TAAAAAA 7 187824 +CA ref:0:2:ACGCATCGCCCG ref:0:2:TCGGAAG 2 4 +CAATTCC ref:1:6:TTACCACA ref:0:5:GTGTTTTAAAAG 3 1395 +CGTTCTAGAG ref:0:10:GACTTAAA ref:0:10:T 5 222 +TTGGCCAGA ref:1:8:AGCTGGCTTC ref:0:9:CACTACC 5 31 +TTGATGCCTCGAC ref:0:11:TATT ref:0:13:TGACATCTACCTTCAA 3 512 +CTTGAGGACTCCACG ref:0:15:TTTAGGACGGTC ref:0:15:T 6 45 +GC ref:0:2:CACACTCTCGAGTCGT ref:0:1:ACAGGAGT 6 6 +CCAGTGTAATTTCAG ref:0:15:GGCAAGATCTTATCCA ref:0:15:CGACT 7 189672 +TACGCCGGGGG ref:1:10: ref:0:11:ATTGTTCGAG 6 560 +CTAAGAGCCGTC ref:0:12:TGCCGACGCA ref:0:12:C 6 244 +A ref:0:1:TGCTGATTGGCATCC ref:0:1:GGAAACGGTGA 5 8 +CAACTGG ref:0:7:TCGCTACCACG ref:0:7:G 2 8 +CTCATTGGG ref:0:9:AGA ref:0:9:CCTTCCTGCGGTT 1 204 +AGCCTTGCGGGAT ref:0:13:CTCAATGGTC ref:0:13:TACGCGATAAGGCCGC 7 174180 +CACCCTAAGTCA ref:0:12:CCAGCTT ref:0:12:AG 7 306 +GCGCACATGGGGG ref:0:13:GTTGT ref:0:13:ATAG 9 10120 +CT ref:0:2:G ref:0:2:TGTCGA 2 21 +ACCGAACAGGGACAGC ref:0:16:CATATGCTCCAGCAT ref:1:15:GATCTTCATTT 9 894600 +CTTCGATAAGG ref:0:11:GTCGCTA ref:0:11:AGGATAG 5 1600 +TCTGCTTACGGTGG ref:1:13:CCTGCATGACC ref:0:14:CCCAGGAGGATTAGA 6 151404 +TGACTCCTTGGTGGTG ref:0:16:GTTAGAAGGAGAGGTC ref:2:14:TCCAACGGTGT 6 29512 +AGAAC ref:0:4:AA ref:0:4:CTG 1 9 +GGCGAACAGGGT ref:0:12:CCGTACCC ref:1:11:TTGCCCTACGGTATC 6 105364 +GTTTGGGCAAT ref:0:11:C ref:0:11:TTTCTGGCTCTG 4 146 +CAGTCT ref:0:6:C ref:1:5:TCCG 3 10 +CCGAGTCCGGAAAGC ref:0:15:AGTGCATTTG ref:0:15:TGGTTGGCT 7 3978 +GAGGCACGTT ref:0:10:TG ref:0:10:GTCGA 8 1463 +TTGTTCTAAT ref:0:10:GGATCCGTACGCCG ref:0:7:GGGGC 4 45360 +GCCCGGG ref:0:7:TGCTCATTGATT ref:0:7:TGTAAGGGAGGCT 6 60112 +TTTCCCCGC ref:0:9:TAAAGATC ref:0:9:AAGAGCAATCATCA 10 2861220 +GCGATAGGATT ref:0:11:TCTTACTTAATTAG ref:0:11:TTTGTAAACCGCGT 4 2112 +GTTGTA ref:0:6:ATAAGTTTAG ref:0:6:GATCAAAAG 2 165 +AATATAATAATACTTT ref:0:16:CTC ref:0:16:GATCGACTAGCGGGCG 11 5055996 +ACAGAAGCAACGTT ref:0:14:GA ref:0:14:GTACTAAGGTGAGA 7 4710 +AC ref:0:2:TGCCTTGGCGACAT ref:0:2:CCGATCGGAC 5 3 +TCTTA ref:0:5:C ref:0:5:CCTAA 2 17 +GATGCGGGT ref:0:9:TTTG ref:0:9:TATATACG 7 6300 +GCGGT ref:0:5:CATTATTAACAGG ref:0:4:ATTCAGCCG 5 99 +TTTTTCAGGCTGCTGG ref:0:16:TTGAGGAATCGTC ref:0:16:GCGACTGACCCA 8 984960 +TCTGTCACCTGTC ref:0:13:CCT ref:0:13:TCCGCGTGGCA 6 1368 +ATC ref:0:3:GTTAAG ref:0:3:AAGTTTGAGGTA 5 1674 +ACGAA ref:0:5:ATAAATTG ref:0:5:GT 2 39 +T ref:0:1:CCTTGCGTTGT ref:0:1:ATT 1 10 +AT ref:0:2:GTGTGCAC ref:0:2:GCACA 4 32 +GCCTCCT ref:0:7:CCCATCCCG ref:1:6:CCTA 1 280 +AGCCGC ref:0:6:T ref:0:6:TAGATC 4 105 +TGAACTGGTTA ref:2:9:GGTC ref:0:11:C 5 5 +GAGACCT ref:0:7:TGTGCGTAGC ref:1:5:G 3 38 +TAAAATTAAATTTAT ref:0:15:GCGCAAAGGCAAGA ref:0:15:GTG 10 1951425 +AAC ref:0:3:CTAGAA ref:0:3:T 2 16 +GGAGG ref:0:5:T ref:0:5:ATTCCAGTGGTA 3 540 +TA ref:0:2:AGACG ref:0:2:TAGTCGTCGTGAGA 3 36 +A ref:0:1:TTC ref:0:1:AATG 1 8 +G ref:0:1:AT ref:0:1:AGTTGT 2 6 +GTCCTCCCAGGGCTA ref:0:15:ACAAGAATAC ref:0:14:TCAC 8 18800 +GGGGTCCAC ref:0:9:GACATCTGCATAGA ref:0:9:CCCCACTACGAT 8 60480 +AAAATGTCAACATG ref:0:14:CTCAGCGCCAACCCCA ref:0:13:AGTGTTTAC 5 550400 +TCGGCGATATA ref:0:11:GTCAATTGG ref:0:11:GTCC 6 89 +AGGCGAATCT ref:0:10:CTGGATGTGTCGGAGG ref:0:10:AAGCA 4 600 +CT ref:0:2:TTACTGTGGACGG ref:0:2:AACTCCG 3 2 +GCTACCTAGTCCATCC ref:0:14:TTTCTATCCATA ref:1:15:CCAGCC 2 648 +GCAAAGGGGTAAT ref:0:13:CGGGCC ref:0:13:AGCAC 9 17754 +ACAAACT ref:0:7:TCGA ref:0:7:G 6 96 +ACAC ref:0:4:GAGTTACTTGGACAG ref:0:4:T 1 10 +GGACGACAGGTGT ref:0:13:AAAT ref:0:13:CCGAC 6 10 +GACCCCACGTAAATGG ref:0:16:CAAG ref:0:16:AACTAGATATGGGCGT 6 324 +GAAAGCGTTGGGTAAC ref:0:16:TAGCAG ref:0:16:TGGTAATTCTCGGCCT 8 773955 +CG ref:0:2:CCA ref:1:1:ATGGACTCTCA 2 10 +TTACACTT ref:0:5:CGTTTTGCCAAT ref:0:7:TGAGTCGAAATAGG 2 2378 +ATTAC ref:0:3:TGC ref:0:5:CGCGTCTGTTCCA 3 824 +C ref:0:1:CTTGCATCTTGCAC ref:0:1:TGAACCAAAGATG 5 10 +GGAA ref:0:4:A ref:0:4:CACGATATATTTTA 1 76 +CAGCTGATCGG ref:0:11:GGC ref:0:11:GGTCTATGGG 2 16 +GGAGCC ref:0:6:G ref:0:6:CGACCACG 2 36 +TAATGCTGGAGG ref:0:12:TT ref:0:12:ATTAGAATCATG 5 126 +ACGAGCACATAACC ref:0:14:GCCGTCT ref:0:14:CGGCAGGTGC 7 672 +CTATATTAA ref:1:8:TGGAGCCGGTGG ref:0:9:AGACATTACTTGG 6 16002 +CATTCTC ref:0:7:ACCGTGTATA ref:0:7:GA 3 48 +ACAGT ref:0:5:ATC ref:0:5:CTTATGTATCAAGG 2 42 +AATACGGTCCCCC ref:0:13:TCGGCGACCTAA ref:0:13:AGG 5 135 +TGTA ref:3:1:CGC ref:0:4:C 2 20 +TCATTTTCGATACGTA ref:1:15:AAAAAAGGCCCAG ref:0:16:CCACGCGTCAA 6 61698 +TTAAATCCTTGCCC ref:0:14:TGCA ref:0:14:CTTTTTGAAT 8 600 +TTAC ref:0:4:ACTCTGTGAGCAAGCA ref:0:4:ATGTTTGTGGCGA 7 672 +TCTTCATGTCATTGA ref:0:15:CAGTAGGG ref:0:13:ATCGCTAGGA 6 1710 +ACTCCTCTGTAGCT ref:1:13:TCGTTGATCA ref:0:14:AAGG 5 312 +AA ref:0:2:AGTCCCGCCTTAAAT ref:0:2:ACTCACTCGTACGTG 7 18 +CAAGTCCTAATTA ref:0:13:TACGTAGCC ref:0:12:TGTGATGATC 6 4788 +G ref:0:1:AA ref:0:1:AC 2 9 +CTTC ref:0:3:GGGGACGTGTT ref:0:4:ATCGTTG 2 6 +AATTGGTCACAGCC ref:0:14:C ref:2:12:CGGTTTTCCC 6 488 +TAGCCCA ref:2:5:GGG ref:1:6:C 3 63 +CGTCA ref:0:5:GCGAGAA ref:0:5:TCAC 1 24 +AATA ref:1:3:CGGCATTCGATTT ref:0:4:GACCACCCAATTGCC 5 130 +CGCA ref:0:4:GACTCAATTGG ref:0:4:AG 2 24 +TCTC ref:0:4:CGATCTACGACATT ref:0:4:CCGATGACCGCCC 5 82 +ATCTAC ref:0:6:TGGGCACCCCTACCT ref:1:5:CAAGGCG 1 90 +GAGGGACGGAATCG ref:0:13:CCCGG ref:0:14:CTCCGGCT 11 22932 +GCAAACGA ref:1:7:C ref:0:8:TTTTCCAG 4 116 +CGGT ref:0:4:AGGAAA ref:0:4:GGGCA 3 104 +CTCTTGA ref:0:7:CCGACGCAAGA ref:0:7:CAAG 5 9042 +CGTATGTGGAC ref:0:11:TAA ref:0:11:AG 7 3 +TGATGC ref:0:6:TTTACGGCCCGTTG ref:0:6:CGCAATACCCA 3 7992 +TCCCGCGCTAGACTTC ref:0:16:ATCCC ref:0:16:CTCTGACCGCGTA 7 70 +GGTCCGTTGAAAGT ref:0:14:TCTCGCTTACCAAG ref:0:14:AGCCA 3 9 +TCTCAGTT ref:0:8:ATAGGTGAGTAAATG ref:0:8:ATACACCTCAGG 3 96 +TTCACCTTAAGGGT ref:0:14:ACCC ref:0:14:GCACATGAGATTC 7 30618 +AGCCATT ref:0:7:GCTTACTATATGG ref:0:7:CCCATTCATG 3 15 +GGGAAGTT ref:0:8:ACTGCACAG ref:0:8:TAGTTC 3 189 +CCGAGGCACGCC ref:0:12:ACT ref:0:12:AGAGT 8 120 +CATGCACCGATAAAT ref:0:15:GGTATTCA ref:0:15:AATTGG 9 288 +GCTCCGCATCAAT ref:1:12:TCTCCGGAT ref:0:13:AAGGAA 4 57 +TGACTATCTCCAGAT ref:1:14:GGATGAATGGA ref:0:15:GGCGACCGGAG 7 14400 +CTAAA ref:0:5:A ref:0:5:TACGTT 3 78 +C ref:0:1:ACTCTACTCTTCA ref:0:1:AA 2 15 +GGAGTACTCTCG ref:0:12:AGACTCACAGCCCG ref:0:12:ACACTCACCATTGGCT 7 80080 +T ref:0:1:CTGTA ref:0:1:ACGCGCCTCGCG 2 2 +GT ref:0:2:CTAA ref:0:2:GCAAATTCGAAATG 3 8 +CTTGTG ref:0:6:TTGCCAACA ref:0:6:GATAATCTTA 4 1922 +ATTAGATGAA ref:0:10:TACAGCTATCCTAT ref:0:10:GC 5 1935 +GGGTCGCGGACA ref:0:11:CGCCAGTTCACT ref:0:12:TCC 5 345 +GACAGCTCTGTTA ref:0:13:TGT ref:0:13:AGCATCT 6 48 +GTCGAGGGC ref:0:9:AACAGGT ref:0:9:AGCGTTCATGCC 3 3360 +TCACAAAACTGTGC ref:0:14:AGCGTGGTAGGATCGC ref:0:14:GATGCATG 8 159036 +TGGGTATG ref:0:8:GGGGTAGATTGATAC ref:0:8:TCCA 1 320 +GGATATCC ref:0:8:TAAGACATTTGTGA ref:0:8:CACGG 6 74426 +CCAG ref:0:4:AGTACTACAACCA ref:0:4:TTC 3 60 +GTTAACCTTCAAGCTG ref:1:15:AAAAACGTGCACT ref:0:16:TGTATAGTGGC 4 45024 +TGGACGCGTGCGGGTG ref:0:16:CC ref:0:16:CGTAA 12 450 +CTGAAATGCTACGCTG ref:0:16:ATAAACCATCGTTAGA ref:0:16:A 6 216 +TCA ref:0:2:AGTTTACCTCC ref:0:3:ATCCACCTTGGT 2 28 +ACCACAA ref:0:7:GGTT ref:0:7:GTGCCGGG 7 92400 +ATCCAGAC ref:0:8:CTTTGTCAGGA ref:0:8:AACT 2 336 +AGCAAATGG ref:0:9:GACG ref:0:9:AAGCGGAGAAGACTT 2 1100 +GAGTCAATC ref:0:9:TGGACCTAGTAAAAT ref:0:9:GTGCTGAA 3 320 +CT ref:0:2:GCTTCTG ref:0:2:TCATAGCATCAG 3 12 +GGCATG ref:1:5:TGTACGAGA ref:0:6:TT 1 7 +TCGAA ref:0:5:GTACTCG ref:0:5:TCCTCAT 3 108 +CTGGCCCACCCAG ref:0:13:GGTACCCA ref:0:13:GCATCCATGAATATC 4 96 +AAAA ref:0:4:ACGCAG ref:0:4:CTTTACATA 2 280 +CCTA ref:0:4:TGTTACGATTCAGAA ref:0:4:GGATCGAG 6 1495 +G ref:0:1:TAATTGCC ref:0:1:GGTAACGTGTTAAACT 5 4 +AAGTTTGTCCGTG ref:0:13:CTGCC ref:2:11:TGTA 6 480 +TCGTT ref:0:5:TTCC ref:0:5:CTGC 3 165 +TAGTACACCAA ref:0:11:TTGTCT ref:0:9:TCTGCCAGCTCT 4 1209 +ATACCACC ref:0:8:GATGTAG ref:0:8:TGGATTAA 6 90 +GATGTAGTT ref:0:9:ACATCGCATAGGTCA ref:0:9:CCTC 5 8424 +CCCTCGCC ref:0:8:AATA ref:0:8:TCAA 7 700 +GA ref:0:2:AGTCGC ref:0:2:ATATGGCAA 3 32 +GGCGGTAGACATG ref:0:13:A ref:0:13:GAAGTGCACC 7 891 +ATTTCGACATTG ref:0:12:CAGAAGGAACACGT ref:1:11:GTTTAATCT 4 1918 +CTACGGGGCACTTT ref:0:14:G ref:0:14:AAACCTAGTCGTCACC 6 1240 +CACTTGTTAAAAGGG ref:0:15:AGTTTCTA ref:0:15:ACG 7 32 +AGTGAGA ref:0:7:TAAGAATTGAAGG ref:0:7:TGAAGATTGGCG 6 952 +CCAGGATTTAAG ref:0:11:AAAAAGTTA ref:0:12:ATACTTCACTATGA 5 39846 +AATGGAAATCCCGAGT ref:0:16:CTTATGC ref:0:13:AGGT 8 1374 +GCCTACCCCGTCTTA ref:0:15:CTTAAG ref:0:15:ACATCACAA 10 334521 +GACAGGCGT ref:0:9:TCGC ref:1:8:A 4 12 +CTC ref:0:3:CGAAAATTCGATGCA ref:1:2:AGTGGTGGGCG 4 12 +TGAGTAT ref:0:7:GGG ref:0:7:CGCCTTCGGGA 4 80 +GC ref:0:1:CAGT ref:0:2:GCTCTGCCGCCGGT 1 12 +TCACTGCAAGG ref:0:11:CCCT ref:0:11:GG 6 30 +TT ref:0:2:GTGGGCAG ref:0:2:ATGCTCCTCTGC 3 54 +TTTG ref:0:4:CTGGCGCTAGACCCGG ref:0:4:CCCCGCAGATGT 7 3239 +GCGG ref:0:4:CCTA ref:0:4:AAAGGGTG 1 110 +CGT ref:0:3:AGTGCCTAACC ref:0:3:TCTTC 3 33 +GGG ref:0:3:CT ref:0:3:TGCGCCCGTGG 2 100 +GGGTC ref:0:4:TA ref:0:5:GGTCA 1 3 +AAAAGGTGGGGGAAGC ref:0:16:TGG ref:0:16:ATACGTGAGCCGAAG 6 16800 +TTTTATACC ref:0:9:CT ref:0:9:CTTAGGAGTAGCG 4 2888 +C ref:1:0:GTAAA ref:0:1:CAATATCCCCCA 3 6 +TGTACTTAAGA ref:0:11:CACCCAAGGGATCT ref:0:11:CGCTGTTTGAAAAAG 1 3000 +GTCCCCTATCCCC ref:0:13:TCATTC ref:0:13:AAGTTCGGTCTGATA 5 23520 +GCCATGTCCAT ref:0:11:GGGGT ref:0:11:ATCCATTTATAA 2 1692 +GGACTACGGA ref:0:10:TTGGTCAT ref:0:10:TTTGTAAGAGCAGT 5 26 +GGAAAATA ref:0:8:GAC ref:0:8:CGCTGCGCC 6 13756 +TCAG ref:0:4:AAAAAAGCCT ref:0:4:CTTATC 2 840 +TTAGACCATAGCAT ref:2:12:GGG ref:0:14:CCAT 6 78 +GGTGCCATCTGAGGG ref:0:15:CGGGGTGTAC ref:0:15:GGTT 9 1040 +A ref:0:1:TACCCCCT ref:0:1:TAGTCC 3 1 +GGT ref:0:3:CCTGCCCAGTAA ref:0:1:TACTGCTTC 4 1 +AGCTGTAG ref:0:8:GG ref:0:8:CAGTGGG 3 15 +GGCTACGGACAG ref:0:12:AGTTACGCT ref:0:11:TAAGG 4 180 +CATCGTACCTTGAA ref:0:14:CTCTTCAG ref:0:14:CGGGG 7 23598 +ACACTTATCTCATG ref:0:14:TGCGTTCGTTGCGT ref:0:14:CACT 6 10346 +ACACTCCGTTGTTGGT ref:2:14:TAAATCTAA ref:0:16:GTGT 7 19440 +AGGGTAGCCG ref:0:10:GAAGAGTCACCTTT ref:1:6:GTCTA 3 520 +GCAGG ref:0:5:TTAGCTAGGGGTG ref:0:5:TGTCAATTCAC 2 550 +GTGGCTGGTCTT ref:0:12:CT ref:0:12:TACGGATT 6 90 +GACGGTCCA ref:0:9:GCCTAAAGC ref:1:7:GTGTTTGCTTT 3 3612 +GGGCATCTGATTGTG ref:0:15:GAGCAGGGGTTGTA ref:0:15:CCCGAACAT 5 318528 +C ref:0:0:GG ref:0:1:TGCAG 1 1 +TCGCGTGAACG ref:0:11:T ref:0:11:GCAACCCT 5 18 +GATCAGCCTGCGGG ref:1:13:CGTTGA ref:0:14:A 8 120 +AAGCGC ref:0:6:GCTAGG ref:0:6:ACTATTACCC 2 216 +TCAG ref:1:3:GACCGGC ref:0:4:A 1 12 +GGCACCA ref:0:7:CATATGCTAA ref:0:7:ATGCTCGTCTG 4 792 +CAGTAA ref:0:6:AGACTGTTC ref:0:6:TGGAGCCA 4 4214 +CAATCCAGTCAC ref:1:11:TTGAACAGTGG ref:0:12:TGTCATGTT 6 2700 +AACTTAGT ref:0:8:CGGACGTCA ref:0:6:CAACAAT 3 248 +TGGTATTT ref:0:8:GAACCGCGTTT ref:0:8:GTCC 4 2200 +GGTGGAGGGAT ref:0:11:GTGGTC ref:0:11:ATATATAG 4 240 +CT ref:2:0:CGACAG ref:0:2:TACCTCATTGAGGA 4 8 +AGTC ref:0:4:T ref:0:4:G 2 1 +TTTAACTGAC ref:0:10:CA ref:0:9:TG 5 4 +ACCGCACATC ref:0:10:GTTCATCT ref:0:10:TCCAGGTAAGCG 3 180 +GTTGGGAGCTA ref:0:11:CAGTGGCCTTCGTAGC ref:0:11:CGGAGC 4 32 +GCACCTGACAT ref:0:11:TACGGGAAGAGGTCT ref:0:11:ACCC 4 849 +CACAAGTGTCTAG ref:0:13:GTGCTCTACCACAGT ref:0:13:GGGTTCATAGCATCG 8 2124 +TGGCTAAACCGCGCG ref:0:15:C ref:0:15:ATCCCATGCAGAAACC 7 3370 +GAAGGG ref:0:6:AACGTGTT ref:0:6:A 2 14 +GGATG ref:0:5:CTTGACATGG ref:0:4:CGGACCCACATT 3 144 +TC ref:0:2:GCTTAGCG ref:1:1:CAGGGCTAT 2 4 +AATGTAAA ref:0:8:AGTTGCTT ref:0:8:TAT 4 700 +CACGCAGGCACAGCT ref:0:15:TGCAGCA ref:0:15:ACCCC 6 120 +AACCTCT ref:0:7:CTCCTGGCAGGGG ref:0:7:T 3 106 +TCATCTACGG ref:1:9:GGCACGGTGGAG ref:0:10:T 3 21 +TAACGATGGAACCA ref:0:14:A ref:0:14:CGATATTCTTGAG 7 150 +ACAAGTAGTAA ref:0:11:TATTTC ref:0:11:TTTAAGACTTAGTACG 6 25172 +CC ref:0:2:GAATGCGTGTG ref:0:2:GTTATCGCG 5 12 +CTATAGCCAGGA ref:0:11:CCTGTACAACTG ref:0:12:AGCGTGGACGAGGGC 4 92124 +A ref:0:1:ACCAAAAAA ref:0:1:CT 1 21 +GGTCGTCAGTTTC ref:0:13:TGCGG ref:0:13:GCCTACAGGCT 5 2079 +AAGGTG ref:0:6:CGGTTTAT ref:0:6:A 2 78 +CA ref:0:2:TTACTGACCC ref:0:2:GGAACTGACTC 5 1 +TTCCAG ref:0:6:CCTTTTGGCAATGA ref:0:6:ATTGCTGGA 4 1550 +ACAGGGACCTCTGTTG ref:1:15:TCAGCCCGTCCA ref:0:16:A 7 126 +CAACGAA ref:0:7:GCCGA ref:1:6:TAGGCCGTG 2 154 +GTATCTGTCAT ref:0:11:AGCGATGACGAAC ref:0:9:TGAG 5 394 +AGCAGGCCA ref:0:9:C ref:0:9:TAGTTTTATTTAT 4 525 +GTGTGGAAC ref:0:9:TTCATGTGCG ref:0:9:TGAGTTCC 5 10885 +CCACAACAAC ref:0:10:AGCCTGGAATCCAT ref:0:10:GT 6 17424 +AC ref:0:2:TATACTG ref:0:2:GGCGGCCCGGCC 1 94 +AC ref:0:2:CACCGGGCCCGT ref:0:2:CTCTAATCATACATCC 4 80 +ATTTCAGA ref:0:8:GCAGT ref:0:8:TGCTATGTTTGC 2 160 +A ref:0:1:ACCTCAATCTCCG ref:0:1:CCGTACTCCC 7 3 +A ref:0:1:TTAGCGTCTCAT ref:0:1:CCTTGACG 4 2 +AACTCG ref:0:6:CAGCTATCTGCGCATG ref:0:6:GGCC 1 18 +TTCCAAACATCCCGT ref:0:15:GGCGCGGA ref:0:15:C 12 51300 +TGCT ref:0:4:ATGCAAGATT ref:2:2:TCGTGCGCGGC 1 2 +ATACTCTTTGGCCGC ref:0:15:GCGGCTAGTCAA ref:0:15:G 9 120 +TAATACTTGAACAGTA ref:0:16:TC ref:0:16:AGCTGGATAAAAT 7 7782 +ATGAAATCA ref:0:9:CCAAACTTGGGTGATG ref:0:9:T 4 2662 +CTCACGAAGC ref:0:10:CAGCAGAG ref:0:10:AG 4 56 +GCCACGGA ref:0:8:CGTTCATGACAAG ref:1:7:CGATAAG 6 40014 +ACGAAGTGCTAG ref:0:12:CCCCTTGTTATT ref:1:11:TTCCTCGTGAT 8 576028 +T ref:1:0:GGGAA ref:0:1:CGTATGATT 2 4 +TAAGAGT ref:0:7:CCGGAG ref:0:7:GGTCAA 3 150 +ATGCGTATCCA ref:1:10:CTCCTGCATC ref:0:11:CATGCCGTA 3 144 +AAAAAGCGACCCATT ref:0:15:ATTCGGGAGCAAGT ref:0:15:CC 8 165294 +GTACGAAAACCTA ref:0:13:TAGTGCCTCGAGCA ref:0:13:AGTTATGT 6 1592 +CCTGGCTCAGTGACGA ref:0:16:TGGGAGAGAGAG ref:0:16:CGCCCGGAGTAA 4 900 +GAGGTCCT ref:0:8:GCGTCACA ref:0:8:AAAGCCTCAGAC 4 528 +TATCTAATC ref:0:9:GTGG ref:0:9:CTAATCGTGTTG 6 10716 +AGATCCGG ref:0:8:CTCGGGCTTAT ref:0:8:TCTATAAG 4 7316 +AACTATA ref:0:7:CTCTGGCGCCAA ref:0:7:CC 4 96 +CT ref:0:2:TGC ref:0:2:CTCTGCCGT 2 14 +TGCTACCATT ref:0:10:C ref:0:10:AATTCCA 5 3 +AAACTCAGCACCAT ref:0:14:GCG ref:0:14:TGCTGTGAGCGCATT 7 21942 +ATAAACCTCG ref:0:10:GACGCTA ref:0:10:TCAGCATGACAC 4 234 +GGCCTCCAGG ref:2:8:TGAAAA ref:0:10:CAATCC 3 468 +CCCAGT ref:0:6:GATACA ref:0:6:GCATCAAC 6 1664 +TGTAAATACGACCATA ref:0:16:AACAAACACG ref:0:16:CAATCAGAT 8 9009 +CCCCCGAGCAAA ref:0:12:TGAGAGGTCACAAGTC ref:0:12:CCGT 4 17040 +CAAGGGCCCCTGCA ref:1:13:TGAGCTGG ref:1:13:ACC 7 8000 +TCACCTACGTA ref:0:11:AGAATC ref:0:11:G 8 128 +CAGCCGTGCGCTCA ref:0:14:GTGCAAGGAATAC ref:0:14:ATGATTAATCTGC 8 32480 +AATATAGGGGAATT ref:0:14:GACGTATGGGA ref:0:14:ACTAT 7 3000 +CGC ref:0:3:CT ref:0:3:ACCAGATTCAAAAA 1 8 +CTCGGA ref:0:6:GCCAAAGATTGCGCG ref:0:6:TC 1 4 +TCAATGTTCGTGGA ref:0:14:GCCTGGAGGCAAAG ref:0:14:AGCAATTGTAG 5 1944 +AGGCCTT ref:2:5:CCGCCCGACA ref:1:6:GTAAACCTCGTTC 3 1860 +CCCTTA ref:0:6:TCTCTACTGTTT ref:0:6:ATG 3 230 +TGTGA ref:1:4:TCAAAG ref:0:5:TATCGCAGAA 4 220 +CCCCATAATAA ref:0:11:GTCACACATTGCTG ref:0:11:AATAAT 4 4536 +ACGCTTACGTC ref:0:11:GGGCCCA ref:0:11:GCCAC 7 150 +AT ref:0:2:CTGCAG ref:0:2:TAGACG 4 36 +CTAGCCCATCTC ref:0:12:C ref:2:10:CAGAGGGTGT 5 12 +TAACGGC ref:1:6:AGTT ref:0:7:AATTCAGTAAAAGG 2 972 +ACGTC ref:0:5:TAAGG ref:0:5:CTA 1 28 +ACGGGTGCCTAG ref:0:12:CGGATCTGGCTAA ref:0:12:CTGTCACT 4 1176 +GCTTC ref:0:4:AT ref:0:5:TACTATCTCGT 2 84 +CCCA ref:0:4:CGCAATTA ref:0:3:TGCCGACTC 2 68 +CG ref:0:2:CATGTCAGAGG ref:0:1:ACTACCACTATAC 4 35 +ATTACCTGTTTACCA ref:0:15:GTTTCAA ref:0:15:GAGCTGA 6 252 +CTCACCTAACCATAT ref:0:15:A ref:0:15:CGC 12 360 +TTCTCCTCA ref:0:9:GGCTAGAACGTCGGGC ref:0:9:CTCGCAGTGCTG 6 1233 +GTCTTGGGAATTAC ref:0:14:A ref:0:14:CCCCGGCCT 9 15204 +AGCCC ref:0:5:CGGA ref:0:5:TGCATCGTGCA 4 96 +CGAGTTCACGCCGC ref:1:13:TCCTT ref:0:13:TGCGA 8 504 +GGCCTAAC ref:0:8:GCTAAGCG ref:0:8:CGC 3 76 +GGCTGAGAC ref:0:9:CAAACTACGTAGGTTT ref:0:9:GG 4 2976 +TCTATCAGTCCACGT ref:0:15:CCCCGC ref:0:15:GCAGTC 8 384 +CAC ref:0:3:GAGGATGGG ref:0:3:TACC 1 205 +TTACGATCCCAT ref:0:12:CTTGGA ref:0:12:GACGGACTCCAG 3 624 +AAGCCCGACCCAG ref:0:13:TGCCC ref:3:10:CGTGGGTCGGCT 6 473221 +CTACTGCTGTTGGATC ref:0:15:TTAATGCA ref:0:16:AGCAG 9 144 +TGTGCCTCATGGGAGG ref:0:16:CCAGCGCTGATTCC ref:0:16:TA 8 315 +CAAGCAGTCATAT ref:0:12:ACATACCACT ref:0:13:TC 5 8 +TGGTTAGCGCTTTGG ref:0:15:TATAT ref:0:15:G 10 216 +TGCCTGAAAC ref:0:10:AGTGTACAA ref:0:10:GCGCG 2 9 +TAGGC ref:0:5:GTAAGAAATACA ref:0:5:GCACCATAGATT 4 210 +ATAACGGGAA ref:0:10:ACCGC ref:0:10:GATATGGGGC 4 13050 +GTTCGATCACGCTGCT ref:1:15:ACGAGTCATTC ref:1:15:CGAA 7 21 +CTCTCACTGCAAAG ref:0:14:AA ref:0:14:C 11 30 +TTGCGGGCAAA ref:0:11:GCG ref:0:11:TGCTTCC 6 378 +GATATACTGCCA ref:0:12:A ref:0:12:TTATGT 7 16 +ATCGAGTGC ref:0:8:GTTT ref:2:7:AAGCCTAGAT 3 836 +C ref:0:1:CACCGTAACCTGAGAC ref:0:1:CGGATGCTTCT 5 18 +TTCCCCCGATATA ref:0:12:GACCTGAAG ref:0:13:AGCACTCATGCGA 8 922932 +ATGTGGCTG ref:1:8:CTATG ref:0:9:CTT 6 286 +TGGAGGAACC ref:0:10:GCTGTAAGGAC ref:1:9:AT 3 504 +CTCAG ref:0:5:GTTCAGTCT ref:0:3:GCCTT 2 35 +GCAGTTGGGGATC ref:0:13:CCAGCCGT ref:0:13:A 8 402 +AGGGGAATCAGGGC ref:0:14:TGGGTTTCGGA ref:0:14:G 7 4900 +TGTGCCAGGTGCC ref:0:13:GAAAATCATCTCGT ref:1:12:GGACTCCGGG 2 12 +ACTGAATAATGCGC ref:0:14:GGGTGGTTTATCCACA ref:0:14:TAACCGACGACAGA 7 7146000 +CTTA ref:0:4:TGTGCTACGTTC ref:0:4:AGTTTG 3 368 +CGACTACTTTTT ref:0:12:GGAGGGACAGGCTTTC ref:0:12:ACAACAACAT 4 42525 +GCGACGTCG ref:0:9:GGGCCACCC ref:0:9:CCCATCCCCTATAC 5 21840 +TTTCGCCCCGC ref:0:11:GATGATGGATCTCCAA ref:0:11:AAT 7 17570 +AATG ref:0:4:TCGTCGT ref:0:4:A 1 24 +AGAGAATTTCACG ref:0:13:GCTA ref:1:12:AAAGTT 5 128 +GTAGTAGCT ref:0:9:CATGA ref:0:9:CGGTTTATAACCAGC 3 324 +CATAGATC ref:0:8:GACTAACATTTGACT ref:0:8:GGTTCAG 4 6072 +TCGTT ref:0:5:A ref:0:5:TACCACTCAGTC 2 138 +ACCCGAA ref:0:7:GACAATGG ref:0:7:CCAAAAAGCT 3 225 +CGCTTATG ref:0:8:TGGCTAGGCATTGGG ref:0:8:GGTCGCTTGAGAG 5 1525 +CAAGCTAC ref:0:8:GTAGCAA ref:0:8:GCACCAGCCTAT 2 148 +A ref:0:1:ACAAAC ref:0:1:TCGTC 2 24 +T ref:0:1:AGCCGATCGGATAAAC ref:0:1:TGCCTTGAA 6 6 +TTCATATAACT ref:0:11:TG ref:0:11:GAGCTATCTTG 6 952 +TATAGTCA ref:0:8:GGCGCCATGCC ref:0:8:TGCAGCAGAGACG 6 3332 +CGCAG ref:0:4:AGCCGC ref:1:4:GGGGTGAA 1 222 +TTTCAGTGAGAAG ref:0:13:CCCGAGGCGAGAGG ref:0:13:ACTCAGAGGC 5 10200 +TCAAGAAGAAACTTA ref:0:15:AGATATATGCGC ref:0:15:TTAAA 8 895254 +TCG ref:0:3:CGGCTCTTTTATGG ref:0:3:GCGTTATCCTCGTTA 3 20 +A ref:0:1:C ref:0:1:ACCGATCGGGCATTTC 1 6 +GATATACC ref:0:8:CGACTGCCC ref:0:8:TTGCAATCTGTAG 3 2944 +AACAACAACTATTAGG ref:0:15:GCACTGAAGAC ref:0:16:AGAC 8 1980 +CGCACCCCCTAG ref:0:12:GAACAGAT ref:0:12:ATGA 7 50 +AGAGTACTACCGTCC ref:0:15:TATAGGC ref:0:15:GCAC 7 88 +T ref:0:1:TCGTCAGCCGTTTC ref:0:1:GCAAATGG 3 5 +GAAATACCTGATAA ref:0:14:CCAC ref:0:14:GTGTCTTTCTT 7 98 +TATGAAGAG ref:0:9:AGCACGTCAAGGTA ref:0:9:TCCGCTA 6 13824 +TTGAGTGGCAATA ref:0:13:AATAGAGGTGTTTTG ref:0:13:AGACTAG 6 52725 +TGC ref:0:3:GACT ref:0:3:CCAGGGTCGCTCC 1 3 +TAAAAGCGAGAGT ref:0:13:GACC ref:0:13:CTCGAAGAA 7 8118 +GACCT ref:0:5:CGAATT ref:0:5:AGCGTAC 2 169 +ACGTCTACGTGAGAA ref:0:15:TTGTAG ref:0:15:TACGCACA 3 3 +AGGCTTATCT ref:0:10:CTACCG ref:0:10:TTAACTTAGATA 4 728 +CATCG ref:0:5:ATTAGTG ref:0:5:TTTTACTCAGT 3 114 +GACGAAG ref:0:7:C ref:0:7:ACAAGCGTGGAGACA 2 284 +CAGATCGTT ref:0:9:TTAAAG ref:0:9:TGGACACACGTACGTA 4 494 +GGCGTCCACTCC ref:0:12:CTCGAAAGAG ref:0:12:TCTTCAGTGCCCAA 7 133672 +C ref:0:1:TAGGTAG ref:0:1:CACGCGTGTAGGTTG 6 24 +GCGTGATACCG ref:0:11:ATTCACTATGGCCTGG ref:1:10:CCTTTCGT 4 7740 +GTCGTAGGAGGAC ref:1:12:TTCGA ref:0:13:GA 8 468 +TAGCCGCA ref:0:8:TTC ref:0:8:CGGAAACCGG 3 2368 +CTACAATCTAAAG ref:0:13:AGCCCGC ref:0:13:AAGCA 7 231 +CAAATGG ref:0:7:TGACAAACA ref:0:7:GGCGTATATA 4 247 +CTGCTTACACT ref:0:7:ATTATT ref:0:11:CATCTCGGTCCTAAT 3 2088 +ATGACGGGTGTGCC ref:0:14:ACGACC ref:0:14:CCCAA 9 50 +CATATAACGTCAT ref:0:13:TTGGAAGAG ref:0:13:GTA 6 2 +ACCCTTGCCTGG ref:0:12:GAGCAATG ref:0:12:G 7 24 +CAT ref:0:3:CCAGC ref:0:3:GCGGTCCTTCCCCG 2 144 +TCGCAGGGAAAT ref:0:12:CTTGGTGTTC ref:0:11:AGCG 6 2327 +TTCTTATACA ref:0:10:TTAA ref:0:10:ACGTTTCTAATATGG 3 5082 +AGACGTTCCA ref:0:10:TTAACTGCTTAA ref:0:10:CCGTGGCATGAGATC 2 24 +CTCGG ref:0:5:GTTCGTCC ref:0:5:GT 3 145 +TTACT ref:0:5:CTA ref:0:3:CATTGCATTTG 1 4 +GCCTCAACGACAC ref:0:13:T ref:0:13:CG 10 4 +CT ref:1:1:GTAACAGA ref:0:2:GACC 1 3 +ATTTGTGCAGGGA ref:0:13:CC ref:0:13:AAAACCAATGGACTA 8 182000 +TCTATCTTGCCGCACA ref:0:16:ACGGT ref:0:16:TCCGCT 10 515 +T ref:0:1:TATGAATTGCA ref:0:1:AATGCG 4 4 +GCAATTGTGATG ref:0:12:ATAGCAAACGTG ref:1:11:CCGCGGC 5 744 +GTTGA ref:0:5:T ref:1:4:TGCTAT 1 6 +ACTACAGTGGACCTAG ref:0:16:GTTT ref:0:16:CGATGTCT 11 1742 +ATCTTGGACACC ref:0:12:CAAGGGCAA ref:2:10:GCGTGGCAG 5 2862 +CTCGGTACTTTTT ref:0:13:GCTCACTCTCGGTCC ref:0:13:ATAC 5 440 +CCAACTCAC ref:0:9:ACGGGCTGCGACGC ref:0:9:GTCGA 5 588 +GAGTGTTCTAAAAA ref:0:14:CTGCCTCTAAACAG ref:0:14:CCCAGAGATATACA 5 430080 +AGACA ref:0:5:GAAACGGAT ref:0:5:GCTGCGGCTACCG 3 987 +GTATACAAAC ref:0:10:TTTTGCATTAG ref:0:10:TAAGCGGTGGGGTA 6 21780 +AGGT ref:0:4:C ref:0:3:CTTATAACTGA 2 95 +CTA ref:0:3:GTGGCGTAT ref:0:3:CCCGGCGCCAG 3 31 +ATTAAAATGGCAA ref:0:13:CTGCTCAAAA ref:0:13:TCGTCGGGTCAACTC 6 5922 +GCACTTGGGCCCCGGA ref:0:16:ACTG ref:0:15:TT 10 10 +AG ref:0:2:GCGGGCGCG ref:0:2:GTGGT 3 232 +CTTAGTCCATATGC ref:0:14:G ref:0:14:GCGA 11 32 +GTAGGCT ref:0:7:AACTGCAC ref:0:7:GGTAGA 3 1792 +ACAGGGGCGCCTAT ref:0:14:CGAACTGGCGGGGG ref:1:13:ATCGTTT 5 17280 +GCACC ref:0:5:AGACATAT ref:0:5:T 3 114 +TTATGAAAAGGAGGAT ref:0:16:AT ref:0:15:CGTGGAC 11 5240 +TGCGAACGCATG ref:0:12:GGCTAC ref:0:12:GAGACCCGGTTC 7 99258 +ACCGATACCCGTT ref:0:13:ATTAAAATCG ref:0:13:TCGGCATATCT 6 377468 +A ref:0:1:CAG ref:0:1:CAATTA 1 3 +TCTATGTGCGTTG ref:0:13:CGAAGTTGAGAAGTC ref:0:13:CATGATTC 7 60760 +ATGCTAAGGTTCGG ref:0:14:GAACTTACCAGGCTG ref:0:14:CAGTA 5 4104 +CGA ref:1:2:TGGAAC ref:0:3:GGAATACTAAGCTCC 3 100 +GGGCATGTAGC ref:0:11:GACC ref:0:11:GCTA 6 234 +GGGGGTGAA ref:0:9:GAATGGTTAGCTGC ref:0:9:TGTTGGA 5 15048 +AA ref:0:2:GGAAAAC ref:0:2:ATAAACCGCTGACACA 3 126 +GGCAAGCCGAA ref:0:11:TAAGATTAT ref:0:11:GCTGT 6 792 +AAGGCTG ref:0:7:GATATGGCGATCCCC ref:1:6:TCAC 2 6 +GCGCATGT ref:0:8:TCTCCCCGTGAGGAG ref:0:8:TCT 5 85918 +TACCCTACTGGC ref:0:12:CGCGGCGCTA ref:1:11:TATGGAACAC 4 344 +GAAGGT ref:0:6:TCTTCAAAGTGGACAC ref:0:6:CACTAGTGCTG 4 696 +GCTGG ref:0:5:TAATAGGTT ref:0:5:TCTT 3 88 +CTTACTACAGTGGCG ref:1:14:AGCCCA ref:0:15:T 9 28 +GCGCC ref:0:5:GAAC ref:0:5:C 3 63 +AAGCAAG ref:0:7:CT ref:0:7:GTTAGGTGCGTAAGCC 2 76 +AATCGAGAA ref:0:9:ATCAGGGGATG ref:0:9:CGTAAC 2 994 +GAAGGCCTTTG ref:0:11:G ref:0:10:TATGTCC 6 104 +AG ref:0:1:CTCAAAACCA ref:0:2:ATAAAAGGC 4 50 +CATT ref:0:4:GTTCGCTATTT ref:0:4:GGAGTCTAAAGGG 2 18 +TAACAAGAAT ref:0:10:TTGGGTGC ref:1:9:ATATGATGGT 7 45000 +TTTCACCATG ref:0:10:TGAATCCAGTTTGCA ref:0:10:GAAA 5 6210 +AAATAGCGAACAAGTC ref:0:16:AGACCTGTCAAGCAAT ref:0:16:GAGGGA 6 2166 +GTCTTG ref:0:6:CACGCGTAACAA ref:0:6:CAT 3 162 +G ref:0:1:CCTTAACACAGCT ref:0:1:GGGCGTGGACT 4 6 +GTAGTAAAATAA ref:0:12:ATCTTTACGCGCAA ref:0:12:TCGT 7 132404 +C ref:0:1:GCATG ref:0:1:AGG 2 4 +ATCAAAAAAGGTGAT ref:0:15:CATTCAGTTTGTG ref:0:15:CGGGGGAAA 6 47520 +TCAAAATG ref:0:8:AACCGA ref:1:7:CGCCGA 6 5700 +GAGACATCCTACGGT ref:0:15:GTG ref:0:15:CCGGG 9 272 +TACCGCGGTTTGAAT ref:1:14:CC ref:0:15:GTCCA 11 18 +CCT ref:0:3:CCAAGAACTGCG ref:0:3:CCAGGCTC 4 9 +TCA ref:1:2:G ref:0:3:TTTCGTT 2 36 +TTCGGGAGGCTC ref:0:12:TAGCGGC ref:0:12:GACGATATCAGAT 5 3564 +TGTTCAGAAG ref:0:10:GTTCAGCTTGACATGC ref:0:10:AAGGCATCGAA 2 88 +AGC ref:0:3:CGTAGAAG ref:0:3:TACAA 3 7 +AGGCAACGAT ref:0:10:CCCGAGGG ref:0:10:GTACTAAGGCCAA 4 4389 +CC ref:0:2:CACAC ref:0:0:TA 1 3 +AGG ref:0:3:AAAGGGCCCAGG ref:0:3:GTAGTTTGC 1 31 +GCTGCTCTCAGCCAAT ref:0:16:CAC ref:0:16:AGGA 11 176 +TGCTTCAACTGC ref:0:12:ATTC ref:0:12:CAGTCAT 7 740 +CATCAAACGTTCTAC ref:0:15:TTCCAGCCGC ref:0:15:G 9 1266 +GCCGGTATTCCGT ref:0:13:AAGGCCTAAT ref:0:13:GGAGCAGAC 6 6072 +GGGAACACAACTTCG ref:0:15:CGGATCAC ref:0:15:TGGGA 8 1060 +GT ref:0:2:AGAATTCCGGG ref:0:2:CGGTGAGAC 2 4 +GGCAAGCGGCTGT ref:0:13:CGCCCTC ref:0:13:TCGTCAGTTATAC 7 13532 +ATTCACTGCCGC ref:0:12:GTGAAGGGA ref:0:12:CCGCCTCT 3 1596 +AAAGCCTCGTTGGAA ref:0:15:AGTCGTGGACTG ref:0:15:CGAGTCGTGCC 7 9600 +TGCGCC ref:0:6:CAACATCCTG ref:1:5:CAAAGT 5 150 +TCGAGGGATTTC ref:0:12:GGTCCA ref:1:11:GTA 8 2592 +CAACCGCCGCCACC ref:0:14:GCTGGTCACATAGC ref:0:13:GCTCCGTAACT 9 167912 +CTATACTATTACTGC ref:0:15:GT ref:0:14:GGCGTTTACGCTAC 7 4371 +CGCACCGGAAC ref:0:11:TGACCCGAGATGGT ref:0:11:CATA 4 6500 +GGACTGGGATC ref:0:11:TTTGTCCCGGAGTCCA ref:0:11:GTTGAAA 5 481156 +CATTAG ref:0:6:ATTC ref:1:5:TTTACCTGCAACGAC 1 123 +CTCGTAGCTC ref:1:9:TTGTTTGCGA ref:0:10:CAGT 3 300 +CGTGGCGGTAGT ref:0:12:ACTACT ref:0:12:GACT 8 528 +ATGTGATG ref:1:7:GCTCCGGATCAGCT ref:0:8:TCGTTGATATCGGATT 3 36 +GGCC ref:0:3:CTAA ref:0:4:TTTGAGCACCGTTAGG 1 3 +TCCACGGTTG ref:0:10:GAATAGAAGCGGATCT ref:0:10:TTAACGATGC 4 1768 +GATT ref:0:4:TTCTGGAAACAGT ref:0:4:CGCCCA 3 42 +AGGCACGTTA ref:1:9:AGT ref:0:10:AC 5 6 +GAAAAGAAC ref:0:9:CCG ref:0:9:ACATTT 7 21888 +TAC ref:0:3:AACACCTCGTG ref:0:3:CGA 2 100 +TGATACGATGTTATA ref:0:15:TTGACCAAGCC ref:0:15:T 9 11310 +GAGTCAGGGCGTA ref:0:12:TCA ref:0:13:AGTTCCTATCAT 6 62 +CAG ref:0:3:GTCTCCGTG ref:0:3:TCTGCTG 5 180 +TATTGCTA ref:0:8:G ref:0:7:GGCAAGC 4 17 +CG ref:0:2:AACTGGATTG ref:0:2:GAAGGGGA 4 69 +CGTGGTGAGATTGATC ref:0:16:ATGCCAT ref:0:16:GCGCCTCCCACTGT 8 10436 +GATTCC ref:1:5:AACCACCGGTA ref:0:6:AGCACATA 5 1624 +TGTCTTCAAGAAATCC ref:0:16:GAACGGC ref:0:16:AATCA 10 780 +GCCGCGGCTTGTAGGG ref:0:16:CG ref:0:16:TGGACTGCGGTAACT 8 56448 +GGCCCGGCT ref:2:7:ACAGTAGAGAA ref:0:9:CATGACCAGGTGAT 6 113928 +GTACTTATTGGGTATT ref:1:15:ATGC ref:0:16:CAAGCCCCCGAGCAT 8 3888 +GGCGT ref:0:5:GCGTTTTGTATAGA ref:0:5:CCTA 2 130 +GGCTAGTATATCG ref:0:13:GCGTGAGGCAAACT ref:0:12:GCTGAGTTCCCA 3 9120 +GGATTGCTCA ref:0:10:CGGC ref:0:10:CAATAAGTGCAG 4 456 +CTTC ref:0:4:AGCGGCATAATAAT ref:0:4:A 2 60 +TAGA ref:0:4:GTACCTCTGGC ref:0:4:CCCAGC 2 40 +AGT ref:0:3:CAGCTAGCC ref:0:2:C 1 3 +ACCGCATCGAATGTGA ref:0:16:CATGT ref:0:15:GCCATG 8 120 +TTTTGGCA ref:0:8:GCAATCTCTTC ref:0:8:GCTCATCTT 7 1 +TCAC ref:0:4:ACCAGCTGGA ref:0:4:A 1 5 +ACGAG ref:0:5:TACTTGGGGCTAGGG ref:1:4:GCA 1 24 +ACCATAGGAGGTAAGC ref:0:16:GGTCAAAG ref:0:16:ATG 9 266 +TGCGA ref:0:4:GTTGACGTGGT ref:0:5:AA 1 36 +CCTGTGCTCTGA ref:0:12:AAACTCAAATCAT ref:0:12:ATTGGTGCAAGGG 5 60360 +GCTTGCACGCTGG ref:0:13:GAT ref:0:13:GAGCTCTGTTCC 4 32 +ACGT ref:0:4:TCGTGACGAATCG ref:0:4:CTTTCAAAA 1 6 +TCTTGCAACC ref:0:10:ACAATC ref:0:10:AGTGCCG 5 1632 +ATG ref:0:2: ref:0:3:TTAGAC 1 4 +AAAAATTAT ref:0:9:ACTGCCCT ref:0:9:TTCTCAGGCGTATT 7 3412240 +GCCCAGGAGCC ref:0:11:CTGT ref:1:10:ACAAAA 6 42504 +GGCCTCCGATAATGT ref:0:15:CACA ref:0:15:TCGCC 11 8976 +GGTTCGACAGAGCTTG ref:0:16:GTGACATCCGGAC ref:0:16:ATTTGAACAGTTCC 4 4320 +CTTGTCCGGCTAACC ref:0:15:TGATCAGTCT ref:0:15:GAGATGAG 9 32410 +GAGCTCTGAAT ref:0:11:CATTTCCG ref:0:10:CAAATCCT 7 7392 +AAAACATAGTA ref:0:11:GCTGGT ref:0:11:TCACCCGAATCT 5 22785 +AGCACACGC ref:0:8:TCTACAATGGA ref:0:9:T 4 410 +CCTCACTGCCATCA ref:0:14:CT ref:1:13:GCCCTGC 7 36 +TCGG ref:0:4:TCCTCAGTGG ref:0:4:A 1 60 +ACCCCCTTGCCT ref:0:12:CCTTCGC ref:1:11:GCTTCGCGATCAAA 5 4050 +GCTCTTAAAAGA ref:0:12:TGGCCTCTTAGCGAA ref:1:11:TTT 3 304 +T ref:0:1:A ref:0:1:CG 1 6 +TCACCAGAGC ref:0:10:CGTCGGCTTGAGTG ref:0:10:GGTGATCGGG 6 8968 +CATGCTGGGGT ref:0:11:GC ref:0:11:ATTTAA 5 1 +TC ref:0:2:AGTAACCGCGATCTA ref:0:2:TGATGGA 4 55 +GCTCTCACTTAT ref:0:12:TTGC ref:0:12:AG 9 36 +TCGAGTGAG ref:1:8:T ref:0:9:TTCAGATGGAGTTCGG 1 54 +GAGCGTCCAGAAGTC ref:0:15:GGACG ref:0:14:GGAGACTAAA 6 206 +CCACTCTGG ref:0:9:ATTGGCCCA ref:0:9:AGTCAATTACC 5 465 +CAAGTAAAGAGCATTA ref:3:13:TGAGGGGCACTG ref:0:16:T 6 2751 +AAGGTTTTCAC ref:2:9:GCACGCCA ref:0:11:GTCGGTC 5 2912 +ACAGATGGAAGCTGAA ref:1:15:TCCAAAT ref:0:16:ATG 9 170 +CAGACAC ref:0:7:CCCCTGA ref:0:7:GCGA 4 171 +TAATCGCAGA ref:0:10:CTTCGACCACTC ref:0:10:TCCGACAGAG 3 189 +GGA ref:0:3:TCTCTATTCCAC ref:0:3:TACTTCAATTCAGTT 10 16530 +GCGTAAGTGCA ref:3:8:CACCCGT ref:0:11:ACCCTGTAGTGTC 2 198 +CTT ref:0:3:GGCGTCA ref:0:3:TTTAT 1 50 +CATTGCTAC ref:0:9:TCGCCACACTAG ref:0:8:CTACATCTCTGCTG 3 2970 +TAA ref:0:3:GTGATAGTCAC ref:1:2:CG 1 24 +C ref:0:1:TCGCTG ref:0:1:ATCAACCGTGA 4 6 +TACTTG ref:0:6:AA ref:0:6:TCGTTGAGCTTTAATC 2 476 +GTTGA ref:0:5:CCCTCCAG ref:1:4:TTTT 1 1200 +AA ref:1:1:GGAGGCCC ref:0:2:GTGTTCT 3 36 +ACTCAATCAATGTA ref:0:14:TTAGGGTTGTACGC ref:0:14:GCA 7 2072 +GTAT ref:0:4:TACGC ref:1:3:CCCC 3 140 +CTTGAGAGCTGCC ref:0:13:TGACTGGAGTCACCC ref:1:12:AGTAAGAATCGT 3 240219 +CG ref:0:2:GAACCAGA ref:0:2:TAGGCAT 2 20 +AGCATGTAGTGGCGTG ref:0:16:GTCTGATCCCCCA ref:0:16:CGATGGATTCGAT 7 28224 +ACAAGTTTTT ref:0:10:GAG ref:0:10:GACGCCTCATTAA 5 440 +C ref:0:0:TAGTAA ref:0:1:GCCCAACTTATGGT 3 4 +CTTGCGACA ref:1:7:ATA ref:1:7:CA 4 3 +CCCTTAAT ref:0:8:AAAGCGTGCCCTGA ref:0:8:GACACGAAGCTTG 4 1540 +TTGCG ref:0:5:CCTCGC ref:1:4:GTAGGAGCACA 1 216 +CGCTATC ref:1:6:AGGCTCTTTCTCTTG ref:0:7:AAGAGGGTTAGAACG 4 103008 +AGCTATCAAG ref:0:10:CAT ref:0:10:GACAAGGTA 2 2 +AACCATCAGAT ref:0:11:CAGGATAAACGCAAA ref:0:9:TGT 1 10 +GGAGT ref:0:5:GAATACCAAGCG ref:0:5:TTAG 3 702 +A ref:0:1:GACAACCTGACGCCAC ref:0:1:ACAGTGGTTC 6 10 +TCCCATATCGGTA ref:0:13:AA ref:0:13:GGATGGCGTAG 7 1584 +GACTCACGGAAGC ref:2:11:TCAGGGAG ref:0:13:TGGG 4 9 +AGGACCGCCCACA ref:0:13:G ref:0:13:TACTGGCCAG 7 2208 +A ref:0:1:GGAGGTCA ref:0:1:TGCGTCGCTGTTT 5 28 +GATTGTAGACATATA ref:0:15:CAGGGCGGTCG ref:0:15:CTTTGTC 9 36720 +GCTAAGACCGGGAT ref:0:14:ACAGGTCAC ref:0:12:GCGGG 6 4952 +TT ref:0:2:CTCCACCATGTACCTA ref:0:2:GGATCCC 3 48 +CGGGTGAA ref:0:8:TTCT ref:0:8:ACTGGTGACGTGCCGT 2 112 +TACTCACGTGTTGGT ref:0:15:ATAA ref:0:14:CCCGATAGCATTCAC 4 130 +TCCC ref:0:4:AATAAACT ref:0:4:GGACG 3 1092 +TTTGTAC ref:0:7:G ref:1:6:GTTGCACCCCATT 1 8 +CTAGGTAATCC ref:0:11:GGTGTCCCTAGTTTAC ref:1:10:ACGGCTAAGGA 2 5610 +TCTGATCACAACACT ref:0:15:GCGGCGAGAGGCAC ref:0:15:GTG 7 2055 +CTAT ref:0:4:GCGAGATGGGACG ref:0:3:GCACAA 3 99 +TTGTT ref:0:5:TGGGGC ref:0:5:TAGTATGTACCCCC 3 3465 +TTCGGCGATTA ref:0:11:AT ref:0:10:TCAAGTTT 5 384 +GA ref:0:2:CAACG ref:0:2:AAGGGCG 4 96 +A ref:0:1:CAATGAAGATTTTG ref:1:0:GCCTGCCCTCTGTG 6 5 +ACCGGTTTTTATTCT ref:0:15:TTTTGGA ref:0:15:CGAAATA 8 11410 +CATAAACGTGAAAC ref:0:14:TGCAGGGATCACAA ref:0:14:ATCTGCGT 5 1588 +TCTGCGCTACGCCGT ref:0:15:GACCGCAC ref:0:15:TACCATTCTGTTTC 7 82800 +AGA ref:0:3:CTTCCAGTTC ref:0:3:TGTCAC 3 8 +GTCATT ref:1:5:T ref:0:6:GGGATC 3 99 +TCTATGGGAATA ref:0:12:CTGCGGT ref:0:12:GCTAGTCAAAGCG 3 56 +C ref:0:1:ATCTG ref:0:1:CAAGTCA 2 2 +GAAACGGTCTC ref:0:11:C ref:0:11:CCCTA 8 63 +GT ref:0:2:TGATT ref:0:2:TG 1 4 +ACCGACG ref:0:7:GAGCCTTTATAACATT ref:1:6:TCCGGCTTACCTC 4 1088 +TCCATATGTTG ref:0:11:GA ref:1:10:CCTTCTGAAGGGCTT 4 2775 +CCAGAG ref:0:6:T ref:0:6:CGAACTAG 3 266 +G ref:0:1:CACTTGAAC ref:0:1:CAATGTA 4 1 +ATA ref:0:3:CC ref:0:3:AGGATTTGGGGT 1 470 +AACT ref:0:4:TTCTGGTTTACCCC ref:0:4:GTTTGAGGCTCATATG 7 7920 +CCATTAGTA ref:0:9:CCCCGC ref:0:9:TGCTG 5 1092 +CATAAG ref:0:6:TATGGAGAGGGGTCG ref:0:6:TTGAAAT 4 360 +TCCTAATCAAACT ref:1:11:CCACTTCCCAA ref:0:13:GTGAGGTCTGAGC 3 66600 +CTTC ref:0:4:CGCGGATGCGATGTG ref:2:2:CCTAAGGAACT 3 32 +GGCTCAGCTAAGTTA ref:0:15:AGTCCGGTAGG ref:0:15:G 8 2524 +CAAGATAATCGCG ref:0:13:AAACACCTGGTAA ref:0:13:GTGATCGCC 2 486 +TGTGTGTCCATAGGGA ref:0:16:TTGCGCAAT ref:0:16:CGGGTCCCC 6 8140 +AAT ref:0:3:AACGCCAAC ref:0:3:GCCTGGTTGTAAAC 5 140 +TCC ref:0:3:TTACAGAGCAAGTAG ref:0:3:TGAGGAGTGC 4 26 +AGGCA ref:0:5:TTGGTC ref:0:5:CCCGTTCT 3 132 +GGCGGCTT ref:0:8:ATGTAGA ref:0:8:GA 7 9264 +TCGGCTCGCTAGATCG ref:0:16:CTTGCAACGGC ref:0:16:CGCACCAG 5 240 +CAGGTACAAACC ref:1:11:GTGGTAAGATTG ref:0:12:AAGCTAT 5 109800 +ACAAATT ref:0:7:CGTAATGTTGTCG ref:0:7:ATAT 2 1110 +GAAGACTTTCTACAT ref:0:14:CGTGAA ref:0:15:TATTCAGCGCACTCAC 5 1224 +TTCA ref:0:4:AGGTC ref:0:4:AGGCATTTCAGCCT 3 15 +AG ref:0:2:AATGGCT ref:0:2:AAAAACTT 3 120 +TTAAAGAGCACCC ref:0:13:GTA ref:0:13:GAAAGTCCCAGACGAT 6 1738 +GGTCTCCAAGCG ref:0:12:GCTCCTGAGGA ref:0:12:ATAGTCTCTCC 2 40 +CGCGCCCACAT ref:0:11:ACCCA ref:0:11:TG 6 483 +GTCGCGACAAGTTT ref:0:14:CCG ref:0:14:ATAGGGAAGCTAGA 6 7740 +TGAACCGAGT ref:0:10:CCTCATACTCCGTAAA ref:1:9:ATGG 3 532 +AGAGTTTATGTC ref:0:12:GGTGCTCTAA ref:0:12:CAACTTATCCTACG 3 210 +CCCTTCCATAAGTT ref:0:14:GAGTGTCAGGGTC ref:0:14:TTT 8 34000 +AT ref:0:2:CAGGGTTCAA ref:0:2:TTAGATT 2 8 +ACCAGTTTAAAACCT ref:0:14:ATAA ref:0:15:TCCCTTATGGGT 7 348264 +CTCATT ref:0:6:GA ref:0:4:AAAGTAGA 3 80 +ATGACTTAGATGCTA ref:0:15:AATCT ref:3:12:TTCCCAACGCC 4 64 +AGTATGT ref:0:5:GTCGACTTTT ref:0:7:ATTATAGTACTTG 2 72 +ATTCACATAT ref:0:10:AT ref:0:10:AACAAAATTTTCAAG 4 17604 +CCTCGAA ref:1:5:TCGGATCAGGAG ref:0:7:GTACT 1 68 +TAG ref:0:3:ATT ref:0:3:AATGGCT 3 63 +GGCACT ref:0:6:CACCGCCGG ref:0:6:TCA 3 114 +TC ref:1:1:GGCAAGCC ref:1:1:CCCCACA 2 15 +CCTACTCC ref:0:8:TCACCGCAGCCG ref:3:5:CTCTGG 3 1155 +TCAAGGTACTGTAG ref:1:12:CCTACGGCGGACA ref:2:12:TTCTGGAC 6 11613 +ATAAGAT ref:0:6:TGGACA ref:0:7:GCTCCCGAGTAA 4 1944 +AACTTCAAGCTAT ref:0:13:CCTTTAGCAGTAAG ref:0:13:GGC 5 4160 +TGAC ref:0:4:CGTAAGCGGTGATACG ref:0:4:GGCTCTCGGCCG 4 160 +GGT ref:0:3:CATAGAA ref:1:2:CCG 2 27 +AAACAAAATTGTAATG ref:0:16:AGTTCTAAAGAAGG ref:0:16:GAAGACAGCGGTCTT 4 636975 +GTTGTGGGAC ref:1:9:ACGTGAG ref:0:9:GGTGTCTG 4 4980 +GGATATTCGCA ref:0:11:GGTGATATTTCGGGT ref:0:11:CACGATATGTTGCAC 1 3420 +TTTGACGAGAGTGC ref:0:14:ATAGCGATCCC ref:0:14:ACACAGCT 5 2160 +CCAC ref:0:4:GTACATT ref:0:4:TTGCAATATTACTGG 4 630 +CTTATTCCA ref:0:9:A ref:1:8:T 6 8 +TCACCCTAGG ref:0:10:TCTCACTTCCACG ref:2:8:ATAAACGGCTCCG 4 2736 +GCTTCCTTGGATCTT ref:0:15:T ref:0:15:AAGGTGTAGTCC 9 11788 +TTGCACGGATTC ref:0:12:CAGCGT ref:2:10:CCG 5 12 +ATCAGCGTCCC ref:0:11:TACAACTCG ref:0:11:TGGGTTAGGCCA 2 6408 +CAAGGTT ref:1:6:TATG ref:0:7:ACAT 4 126 +GTTTGTC ref:0:7:GT ref:0:7:CGGATTGATAT 2 200 +AGAGACGAGTATAC ref:0:14:TATTTAG ref:0:14:CTTA 9 250 +GCGTGC ref:0:6:AGGGAGGATACTTACC ref:0:6:AATG 3 8830 +CTAG ref:1:3:GGGAGAGA ref:0:4:AAGAGCTCTTT 3 742 +GAGGAGATTTAT ref:0:12:ATCT ref:0:12:GCGTCTAGGAT 6 15288 +GTG ref:0:3:GGTAGGCGTTGGA ref:1:2:TTTA 3 270 +ACCGGCAACCGAGT ref:1:13:AAGCGGC ref:0:14:GCTGTACCTCA 5 4962 +TTTAC ref:0:5:CAT ref:0:5:TAGTTCACACATACGG 2 190 +CTCCTTGGATGGT ref:0:13:GCATCTTCTAACTTA ref:0:13:AATCGGTATAA 6 5124 +GT ref:0:2:GTTCGGTAAGACT ref:0:2:GGGGACTCTTAAC 5 108 +TGACGCCTATCCAG ref:0:14:GTGA ref:0:14:A 11 99 +CCTTGTAGATAGGGC ref:0:15:AA ref:0:14:CAGAAAATTCG 8 12909 +GACA ref:0:4:ATGCTGC ref:0:4:AAGACCACA 2 84 +GCTCAGGAAAATCTAT ref:0:16:TTCGTAAGCACATCAC ref:0:16:CTCGGAT 4 312 +AAGGGCG ref:0:7:GGCTTAACAGGGAACC ref:0:7:CGCGGCTTCGTGCTA 2 108 +AGCATCCTAC ref:0:10:CGAGATCACTCACTC ref:0:10:ATGA 1 36 +GAGTAACACG ref:1:9:GTACTC ref:0:10:AACTGCTTA 4 456 +CA ref:0:2:CGATTCCTCGGCAA ref:0:2:CGCCGCGTATGAATA 7 176 +AAGTTATCGC ref:0:10:GTTTTC ref:0:10:GTTAACACGCTG 2 132 +TGACGGTGGCACTAA ref:0:15:GTTCCACG ref:0:15:GAGGAGG 5 704 +ACTCCAGTG ref:0:9:CTGTGATTGCTA ref:0:9:TTA 5 728 +ACCCG ref:0:5:AGCACAACTTC ref:1:4:CGAC 2 64 +TGGGCTATTTGTA ref:0:13:AGCTTATTTACTGT ref:0:13:GGGTGGATAAGTAGGT 3 1800 +CC ref:0:2:ATTCAGA ref:0:2:CAT 2 32 +TACTTACAGG ref:2:8:GTTGGCTGACCA ref:0:10:ACCCTGTAAAGA 2 780 +GCGCCA ref:0:5:GGCTAACGGGCTT ref:0:6:GCCACCT 3 1349 +CTGCCACGT ref:0:9:GCCTACAACTTG ref:0:9:TATACTTTAAT 5 70006 +TAAGACGAGAGCT ref:0:13:GAA ref:0:13:GGAATTTAT 8 216 +CGAATC ref:0:6:TCCTCG ref:0:6:ATATTT 1 30 +C ref:0:1:TAGACCCCCTGCAC ref:0:1:CCATTG 3 14 +A ref:0:1:C ref:1:0:CTCGGCTTT 1 2 +CACCCGGCCG ref:0:10:ATA ref:0:10:GAGGTCACGAGTAT 6 192 +CAC ref:0:3:ACGT ref:0:3:GCCCTA 1 7 +TCTTGCTGCCGTA ref:0:13:CTAA ref:0:13:ATACAAGGTGCTGCC 3 258 +GAATTTTTTTATTAT ref:0:15:GTGAATA ref:0:15:CATAG 10 100116 +AGATGAG ref:0:7:AACCCAATGTACGC ref:1:6:GGGTGACGTCCTTAG 4 1408 +ACTCGTGT ref:0:8:CACTACC ref:1:7:GCAGCA 5 756 +GATGAA ref:0:6:TCCTCCATGCTT ref:0:6:GGGCGCCC 4 21140 +AATGCTATC ref:0:8:GGTTG ref:0:9:CCCGCTGGGACGACGG 4 1476 +ACGGTTGAT ref:0:9:G ref:0:9:TT 6 9 +GATTAAAGACGCG ref:1:12:AATAGTGAGGGAC ref:0:13:CCTCA 5 512080 +TTGTCATGCTT ref:0:11:TAATCAGGTC ref:0:11:CATTATGTTAAATCGT 3 38250 +AGCCTACGTCG ref:0:11:AAAT ref:0:11:TT 7 9 +ATGGTAACTAATATC ref:1:14:GA ref:1:13:TAGC 9 90 +GGA ref:0:3:ATTTGTG ref:0:3:AAGGGAGGGCGCAGG 1 24 +CCAT ref:0:4:GTCAGGGATAGC ref:0:4:CTGTCCGCGTGG 5 228 +CCGT ref:0:4:AGTGTCTGAAGCCCCC ref:0:4:TT 3 1220 +TACT ref:0:4:AGATTGAATA ref:0:4:GT 2 30 +GCGGCCAGAAA ref:0:11:TATTACCG ref:0:11:AT 7 1518 +TCGCGGTGCCT ref:0:11:CAG ref:0:11:AC 9 525 +CCCAGCATAAAGTTAT ref:0:16:AG ref:0:16:CGATGCAGAGCC 9 9936 +TATCATCGCTTC ref:0:12:TCCGGC ref:0:12:AATG 4 14 +TTGACCGG ref:0:8:CACGTATCTTCCCA ref:0:8:GTAT 6 16674 +GTT ref:0:3:TTTAGGCAGGGGAT ref:0:3:ATGGT 3 329 +AGGGCTGAG ref:1:8:T ref:0:9:GGTCCGATGTCCAATA 2 114 +TGGAGT ref:0:6:CCTCGCGGCTCCGT ref:0:6:CGCATATTAAA 3 1656 +ACCATC ref:0:6:GCCATGAA ref:0:6:AGC 2 80 +T ref:0:1:CGTTGGA ref:0:1:CGATGGGCGTC 4 4 +TT ref:0:2:TCAA ref:0:2:ATCGTTA 2 15 +GAGAG ref:0:5:TGCTT ref:0:5:CCAACGATTCCCAGTT 4 1400 +GA ref:0:2:ACTTTCACC ref:0:2:ACTATCGGGACCATCA 7 72 +GGTAGGTCAGATTG ref:0:14:CTAAC ref:0:14:TGCTGAATTC 9 5518 +CACGCCA ref:0:7:T ref:0:7:AGACCG 3 16 +TG ref:0:2:TGCGAAGGGTCG ref:0:2:CGGGAG 4 105 +TGAGAAAGTCTATGGA ref:0:16:AGTTC ref:0:16:GTAGAT 10 4620 +AAATACAGGATCAAC ref:0:15:AGG ref:0:15:TGACTACCCTCG 7 12560 +GAGCGC ref:0:6:GGGCTCGCATGGA ref:0:6:GCTCCTCGTCT 4 336 +AAAA ref:0:4:ATCGGA ref:0:4:GAGCTCGA 5 1260 +GC ref:0:2:AATAGCTA ref:0:2:CGTG 1 5 +TCCC ref:0:4:AGGATCCGCGTCATCA ref:0:4:AAA 3 350 +CTACT ref:0:5:TGACTCAACGACGGAG ref:0:5:AAGACCCTC 4 1600 +ACGTGAG ref:0:7:TATATGTTTGTAA ref:0:7:CCATCCGTGTGCAAC 4 2376 +CCCTGAGT ref:0:8:ATGG ref:0:7:TGATGAGC 4 96 +G ref:0:1:CATAGGCGATACGT ref:0:1:AATAGCT 5 4 +CATGGGACTG ref:0:10:ATATATGAT ref:0:10:C 4 212 +ACTCTATCGG ref:0:10:CACGTGCTTGGAGC ref:0:10:CT 2 20 +TCGGGGAGTA ref:0:10:CACTTCT ref:1:9:AACAGGGTGACAATC 4 576 +TCA ref:0:3:AGTGGCTTTGCC ref:1:1:AGCC 2 38 +TCTGGACCAATCGG ref:0:14:CGTGC ref:0:12:AGCACCT 6 272 +ATGTCCAG ref:0:8:CAGTAA ref:0:8:TA 4 10 +ACTTCGGA ref:0:8:CCGTTCT ref:0:8:TCTCATCATTTG 4 276 +CTCACGGGGACATCA ref:0:15:TTCTCGGGTGTGGGC ref:0:15:GCGATG 6 2304 +TATTGCATTCTAA ref:0:13:CCG ref:0:13:GCACAAA 7 16 +CTTCCAAAGG ref:0:10:C ref:0:10:ATTCTAGATGACGA 3 174 +GAGAGAAGATCG ref:2:10:ATTTACAGCAGC ref:0:11:TCGGACC 4 2976 +GT ref:0:2:TAAAGTTACAT ref:0:2:CTCGCCCGCGTCAGGT 4 24 +CAGATAC ref:0:7:C ref:0:7:TGAAATTG 3 522 +GACCA ref:0:5:CTTAA ref:0:5:AACTTGGTTCGCCATC 3 572 +ATCCTCCGCATACGAT ref:0:16:GGCAACTAGAA ref:0:16:GACCTCCATCAA 5 1215 +ATGGCCGAAG ref:1:9:TTACGCCTG ref:1:9:TCTACCGTATA 4 675 +TATTCTTAAGTAC ref:0:13:GGATAGACT ref:0:12:CAATTTAATCTGCT 3 528 +A ref:0:1:AAGGT ref:0:1:TGGCGGCTGACATG 2 4 +TCTCGCCG ref:0:8:AATAAGTCGTTTCGAG ref:0:8:C 2 264 +CGTACATTCTAATAT ref:0:15:AATCCGGCAGA ref:0:14:CCTACCCTTAAT 4 24888 +ACTTAAGACCG ref:0:11:TCTGGAATAGCATAA ref:0:11:CCGT 5 5937 +GGCTTTGGGA ref:0:10:ACTCT ref:0:10:CACCCTTTAAGTAG 5 8448 +GAGACATA ref:0:8:ACAT ref:0:8:G 3 4 +CGGTGTC ref:0:7:TCAGGAGATG ref:0:7:CCAACCTAGAGTCC 3 2072 +CGTGATGGCTTCTCT ref:0:15:GG ref:0:15:ACCGGGGAGCCAAGC 7 1344 +TTTT ref:0:4:AGGATGGCAGAAGCAT ref:0:4:TTATCTACAT 5 765 +GAAT ref:0:4:TTAGAGTTCCCCAAC ref:0:4:AGCGG 3 990 +CCACAAAATCGTCA ref:0:14:TTAC ref:0:14:TCTAAT 10 518 +AGCC ref:0:4:GTA ref:0:4:CCG 1 7 +ATTTG ref:0:5:CCTCCGTATGCCC ref:0:5:AAAT 1 57 +CGAACGTTTGC ref:0:11:GGTCCTATGTATAA ref:0:11:TTGGGAAGCGAA 6 2736 +AGCCACCACACGGA ref:0:13:TAGTGTTGCG ref:0:14:ACATGTCCGCCCTCC 7 444864 +GTC ref:0:3:TGAGGGGAGCT ref:1:2:ACTTCGGAT 2 68 +TGCCCTCCGTA ref:0:11:CGTATGAT ref:0:11:TCCGAT 6 4906 +ACGTACTT ref:0:8:TC ref:0:8:GATGTTTTG 2 12 +ATGC ref:0:4:GCATAGTCTG ref:1:3:GCTCGGTT 2 10 +CGTGCGACCTTGG ref:0:13:TATACTCATACGCT ref:0:11:GCTCAGCT 5 160 +GTACGTTTTCGT ref:1:11:CGCTT ref:0:12:TTAGGAGCTCTGGAC 6 304152 +AACAACTAAAAGG ref:0:13:TCAG ref:0:13:C 10 208 +AGGGAG ref:0:6:CACTAAGT ref:1:4:TTGGCTTG 2 31 +CACCA ref:1:4:AAGCGTAACT ref:0:5:GAGTACAGTT 4 560 +CCTCCTGCAC ref:0:10:G ref:0:10:TCTTGATGTGACTGT 4 480 +CGTGCCCTTCCTGG ref:0:14:GCCGCCACGGAG ref:0:14:GGCCATAATCT 2 64 +CGTCAGAC ref:0:8:AAAACTTAAAGGTCCC ref:0:8:TACCATTCAACT 4 6120 +TTGGTCCAACGGA ref:0:13:CAGCCACGACTGT ref:0:13:GTAAGTGCCGTG 6 23280 +CTGGATAGTAT ref:1:10: ref:0:11:TGATACTATATAA 2 28 +GTCAA ref:0:3:TAACAGTCC ref:0:5:ATGGATGATGGCTCC 4 276 +AATACATCAATA ref:0:12:CGTGTTTAT ref:0:12:ACGGTCCGCTCAGT 8 292740 +TCATGTAATGCTG ref:0:13:GAAG ref:0:13:GCTGCC 7 128 +GTGATAGATG ref:0:10:AGTCTAATGTA ref:0:10:AATCGGATATGTTGT 3 63 +CAAGCACTACATG ref:0:13:CCTTGGCAACTGTT ref:0:13:CCGG 6 1599 +GAGGAACTGTGA ref:0:12:TCTTTT ref:0:12:CACT 8 3822 +GGTGTC ref:0:6:CTTCCG ref:0:5: 3 6 +AATGAAA ref:0:7:AA ref:0:7:ATGT 3 80 +T ref:1:0:GAGCCGGCCGCG ref:0:1:G 1 2 +TGCAAGCTAGTG ref:0:12:ACT ref:0:12:GTGACT 7 16 +TCGAGAGATATCACT ref:0:15:CTAT ref:0:15:CTTTGTCCCGATTG 9 50568 +AGAGACAGGAA ref:0:11:TCGTC ref:0:11:TACCAGAT 8 21504 +TGACCTGGC ref:0:9:GTCCCCAA ref:0:9:GCAGGGTAGA 5 7896 +GATCAAA ref:0:7:CTAGTAAGTTCCG ref:1:6: 3 96 +AC ref:0:2:ATCCTTATTAC ref:0:2:GATACCTTCACGTAA 7 45 +TT ref:0:2:GTCCCGATC ref:1:0:GC 1 1 +C ref:0:1:T ref:0:1:GGCTGAG 1 2 +TACTTTAGATCCGCT ref:0:15:GA ref:0:15:TT 11 15 +ATTCCTCTACCCC ref:0:13:GACCGATAGAGC ref:0:13:CAGCCGATAAC 10 195650 +ACCGGATCAAC ref:0:11:CGGACTAAAGG ref:3:8:GTTTAAAGGGTT 5 27646 +TGATCCTG ref:0:8:TG ref:0:8:AGTGAGGAGC 4 316 +CAAGCCCA ref:0:8:GAACGGCCCCGTAGG ref:0:8:CTCTGGCTT 3 14272 +GCATTATCCT ref:0:10:TTACGGAG ref:1:9:ATAC 4 80 +A ref:0:1:CCCACGGAAAGAT ref:0:0:TGTGC 2 5 +CTATAAT ref:0:7:CCCCCTCGGGAA ref:0:7:GCGTGGGGCCG 6 138960 +CATCG ref:0:5:GACTA ref:0:5:A 3 16 +TTAAACTACTGTA ref:0:13:CTCCGTCCC ref:0:13:GAGGACGAAC 6 15568 +AACAAT ref:0:6:CCA ref:1:4:GAGCGAGGAGCCA 1 27 +AT ref:0:2:AGTCAAGGCAGCT ref:0:2:CGAACCGTGAGCTCG 7 25 +GCCATGAGCACTAAAT ref:0:16:T ref:0:16:CATCTGCAA 9 654 +TTGGCT ref:0:4:GAAATTATAAAA ref:0:4:CCCAAGGTAAGTAT 6 8816 +TGACTT ref:0:6:A ref:0:6:T 4 3 +TGC ref:1:2:CAGCGTCGT ref:0:3:TTAGTGA 3 42 +GCCAACTG ref:0:8:ACTC ref:0:8:C 5 12 +CTA ref:0:2:ATG ref:0:3:TTTTAAC 1 40 +ACGAATACTGCAGAC ref:0:15:AACCG ref:0:15:AACT 9 36 +CAGA ref:0:4:GGGAGACCG ref:0:2:GATGCGAA 3 8 +TATAGAGGA ref:0:8:TCCCCTCATATCAG ref:0:9:GCCAGTTTCAAAGG 4 804 +CTGCGTACCCGA ref:0:12:ATATAT ref:0:12:TACCGTTCCGCCCT 6 139392 +CG ref:0:1:TAAAAATGCT ref:0:2:GTAAAAAATGCC 8 14 +CTGCTCTGTT ref:0:10:TGAG ref:0:10:GACTGTA 5 75 +GCCT ref:0:4:ACATC ref:0:4:ATGCGCGAGCATTCTC 3 171 +ATCAAAGAG ref:0:9:TCCCCTC ref:0:9:TCCAGGGATTTAT 6 457989 +TGACACAGAACGAG ref:0:14:CCCGCAT ref:0:14:CTTGCAATC 6 540 +ACATAA ref:0:6:GTACTCCGAAG ref:0:6:GTG 3 12 +AGTCGGTGCGTGGGTG ref:0:16:TTAGCG ref:0:16:TTTTAAAATTTTTGCA 8 720 +ATGAGATA ref:0:8:GTCGCGAGTTAA ref:0:8:TTCTGCTAATG 3 616 +TCA ref:1:2:AGCATGAAAA ref:0:3:GACCAAA 3 105 +GAGCTA ref:0:5:ATG ref:1:5:CACGTAAT 1 8 +CTAAGGA ref:0:7:TAGAGGTGAAGG ref:0:7:CTCCTCAAGGATGACC 2 96 +GAGTATTCCGTT ref:2:10:ATCCTATT ref:0:12:GCCGATAACTCA 4 8080 +CGAAGTAAGGG ref:0:11:GTGCGACC ref:0:11:AGGAGGCCACAGCT 7 15120 +GCCACT ref:0:6:ATGGTCAGATTGAGT ref:0:5:CTGA 4 1210 +TGCGCCCAGGGCCATG ref:0:16:ACCTTTTGCG ref:0:16:GTT 11 243300 +ACACTTAT ref:0:8:GGAGCCGTTC ref:0:8:GGTCAGC 4 24 +A ref:0:1:GCGGGTCCC ref:1:0:GTG 2 10 +GGGCGGAAC ref:0:8:GAAATACAGCAGA ref:0:9:GCTATGG 4 714 +GTCTACGAGC ref:0:10:TCCCTCGCATTAG ref:0:10:CCGGAACTAAT 3 168 +TCATG ref:0:5:CCCGTGCTATAATCCA ref:0:4:CCTCGGGCTCTCCCT 6 1216 +TATTCA ref:0:6:GGCTCCCG ref:0:6:TGTCACAGTAC 5 30832 +GGGTTCCTCTGATG ref:0:14:TATGT ref:0:14:TGC 10 1425 +ACCTAACCTGCCG ref:1:12:CCCGAATCAAA ref:0:13:GCAGT 6 8624 +TAAGAGTATCGTT ref:0:13:AATCGTGGACAT ref:0:13:AAAACTGCA 7 1974 +GAC ref:0:3:AAGGCAA ref:0:3:AT 1 24 +GATC ref:0:4:TGCTGGCC ref:0:4:TCTGTTAGG 4 80 +AAAGTAGTTCAGCAGT ref:0:15:ATTA ref:0:16:ACG 9 260 +GACATT ref:0:6:GGTACGTTGTGTGACA ref:0:6:ACTGGGATTTGATCTG 5 884 +CTGT ref:0:4:AGAGGACCGGCC ref:0:4:TCTGTCGTAC 2 108 +TCG ref:0:3:CTTTGAAG ref:0:3:AGG 2 207 +CTTTTAATG ref:0:9:ATCCAGTT ref:0:9:CCGTGG 7 267050 +GAG ref:0:3:AACTTAGTAATAATGT ref:0:3:TACGAATACTACGGG 6 48 +GTTTAATCTCCGGAT ref:0:14:CCCGGATCATACG ref:0:15:C 7 198 +CCAAGTCAGGGCAG ref:1:12:TGCATAACGAC ref:0:14:ATTCC 6 1512 +ATGTCAATAGCCGC ref:0:14:GGTGACGTTTGTTT ref:0:14:CATATATAAA 7 8133800 +GGTTC ref:0:5:GGGTGACA ref:0:5:AGGGAGTAATGTGACA 4 234 +AGCCATT ref:0:7:CATACGGCAC ref:0:7:CAAAGTCAATAACCTC 4 966 +TGTCGCAGAGGTTA ref:0:14:ATAGGCCAA ref:0:14:AGTAA 8 544 +ATTTT ref:0:4:CTTCCCTAC ref:1:4:CGGCGTGCTAGT 3 26 +GGGCATTAAAAACGAC ref:0:16:ATCA ref:0:16:AGATTAC 9 132 +CCTGCTTGCAGAT ref:0:13:TATACATGTGA ref:0:13:CAGCTACC 7 90600 +GATCCTGACGA ref:0:11:TAT ref:0:11:TGCCAGTGTATC 5 34 +GTT ref:0:3:CCACGATTCGACGTGA ref:1:2:CAATTAGCC 3 3 +TC ref:0:1:AA ref:0:2:TAGATGCCTG 2 12 +GGGAT ref:0:5:ATAGA ref:0:5:GCTACTTGATC 3 144 +TAGG ref:1:3:CAAGGAGCATC ref:0:4:GGTAATCAC 4 258 +CGCGTCCCAGCGGCA ref:0:14:AGGTTCACAG ref:0:15:AAAACGCT 7 123660 +GCGTATGA ref:0:8:AATAGGTTAC ref:0:8:G 3 3 +TTCTATATCGTATGC ref:0:15:AGTA ref:0:15:GGCTC 10 374 +AAGCTAACTTCGAA ref:0:14:AGCACTGAAC ref:0:14:TCAGGAGTATCT 3 192 +CGCCCTGGGG ref:0:10:GCCCCTTTCGATAT ref:0:10:TGATTGTG 5 605160 +GTAGAT ref:0:6:AGACTC ref:0:6:TAGGCTGGT 2 27 +TGGCTCCTGGAGGGC ref:0:15:ACTTTGCCTAT ref:0:15:AG 8 675 +TGCGTTCA ref:0:8:AGCAGTGTCACGGC ref:0:8:CGACATTCCTAATTT 2 40 +GACGTAGCCATTCT ref:0:14:TAACGACGAG ref:0:14:CC 8 606 +TTAAATCTGGTTGGGC ref:0:16:GCTTCATCCAGATG ref:0:16:GTTTTTGCGAG 6 6552 +ACCGA ref:0:5:TTTATGACATT ref:1:4:G 2 13 +TTCAGCGGCCAGGT ref:0:14:GTGG ref:0:14:CAGTAGGC 9 1920 +CCCG ref:0:3:CA ref:1:3:ACCGCACCC 1 6 +GATGAATAG ref:0:9:ACCGA ref:0:9:GG 5 27 +AGAGTGCGTGTGGAAT ref:0:16:ACCGAG ref:0:16:TTGGCCGTT 9 191688 +GCCC ref:0:4:AGTCGATGCCA ref:0:4:ACATGAATCT 4 42 +TAACGGCCAATATGG ref:1:14:GT ref:0:15:GCCCAATGGCCGTCAG 5 240 +TCTTC ref:0:5:AAGG ref:0:5:CTACGCGCCGGCACG 5 36288 +ACGAGCCGACCTGCTG ref:0:16:TAGCAGCATGA ref:0:16:TAACGAAGCGC 7 3312 +TAA ref:0:3:GGGG ref:0:3:CCCGA 3 700 +T ref:0:1:TCCGATGACAGTCGT ref:0:1:TTATAGT 5 16 +GTTTTA ref:0:5:TACT ref:0:6:TACCTTTTTTTCTAA 3 13860 +TGGCTCATAAGAGAG ref:0:15:GA ref:0:15:CCGAGGCGGC 9 1378 +GGAGCCTAACCAGT ref:0:13:CGTATC ref:0:14:AAGG 7 2816 +CTTGCTTAAACAGGAG ref:0:16:GATATCT ref:0:16:TGGTTCTTTC 11 16416 +ACAATCTGCGGGG ref:0:13:TTCACCCC ref:0:13:CGCGGCCATGCGAGA 7 1822472 +TTG ref:0:3:CAGAA ref:0:3:AGGT 3 84 +GCGT ref:0:4:GCACGCCAGATTCAG ref:0:4:ACAAA 4 320 +CAA ref:0:3:GT ref:0:3:TCACAGGGTTACT 2 40 +CCAG ref:0:4:TGCGGTGAGAAAGAA ref:0:4:CATGTGGGTATT 3 392 +AGTCTGTGC ref:0:9:CAAGCCCGCCTGT ref:0:9:TC 2 320 +TGAGTAGTGCGGACT ref:0:15:TTCAAGA ref:0:15:G 10 306 +AACAGGACCTCAT ref:0:13:GGATTTATTTACTCAC ref:0:13:A 6 5360 +TGGGATC ref:0:7:G ref:0:7:AGAG 5 108 +CGCGGTGGTTTTG ref:0:13:TCCCAGAGCT ref:0:13:AT 9 55776 +GGAATTCCA ref:0:9:CGCCGGAGTTG ref:0:9:TCATAAGCTT 5 1080 +TTTGGCA ref:0:7:GATGAGAAACTG ref:0:7:CCTTCG 3 2430 +GGAACACGTCAC ref:0:12:GGGTATA ref:0:12:GTTAACGGCAACCA 3 10500 +GGACTGC ref:2:5:TAT ref:0:7:GGGCGAATCACC 2 314 +CTAATCTAAACAGCTA ref:0:16:AGCC ref:0:16:ATAACGGAGCTAGGGC 7 660 +GG ref:0:2:CCAAGTAAACCTCGTT ref:0:2:CGCT 3 5 +CGAGAACAGTAGG ref:0:13:GGTTATA ref:0:13:CCACAGCA 4 392 +CGCACCGG ref:0:8:AC ref:0:8:AAAAAGCGCCCTACC 2 6 +GGCTGTGGACCTAAG ref:0:15:TGTCGAGTACAGTA ref:0:15:TC 6 96 +AGTACGAAGCTT ref:0:12:TGCCAAC ref:0:12:GCGAGGTCCCTTCTCG 3 810 +AATT ref:0:4:ATGC ref:0:4:GAAGTTCGCCATGAAG 2 24 +GCCCTGCCG ref:0:9:GGCACATATTCAGA ref:0:9:GGAGACGTGAA 6 335238 +T ref:0:1:GTCACG ref:0:1:CAC 3 4 +GAAAGTGGCATT ref:0:12:CTAACCCACTCT ref:0:12:GGATCTTTTTT 4 100800 +GTTGTCTGCGCATGAG ref:0:16:TCGTACGGTG ref:0:16:CTG 8 60 +AGTCCCCG ref:0:8:TATAATCCTAGGTATG ref:0:8:GATCTGATGCACAGA 6 34787 +CTGCGAAC ref:0:8:TGAGTGCA ref:0:8:CGCTTCA 4 2812 +GTCCGAA ref:0:7:CGG ref:0:7:TGCAC 3 210 +GGCCGTTGGTAT ref:2:10:C ref:0:12:CCTCTACACC 5 182 +GCGTAAC ref:1:5:G ref:0:7:ACCGCTACATTTA 1 54 +AAT ref:0:3:GGCTTAGGCAAC ref:0:3:ACGTAAGACA 5 231 +ACCGCCCC ref:0:8:G ref:0:8:CCGAGC 4 24 +ATGTTCAAACG ref:0:11:GGC ref:0:11:GTAAT 6 340 +ATAAGACA ref:0:8:AACTAAAAGTGGT ref:0:7:GAAATACAAGGTTCC 2 300 +ATCCGATTCG ref:0:10:CACAGGAAGCCTCTC ref:0:10:TCGCCCCAT 2 792 +CCT ref:0:3:TGAGCGACG ref:0:3:TCGACTCCTCACG 4 14 +GCCC ref:1:3:ACTGCGTTA ref:0:4:AT 3 150 +GGAGTG ref:0:6:GAGTGAGACGC ref:0:6:CTCCAG 2 525 +CATCATGG ref:0:8:ACTCTTTTTCCTACG ref:0:8:GGTCAGCCATCACCA 5 267526 +GTGT ref:0:4:ATACACCCG ref:0:4:GCC 3 26 +CTGGGTCGGA ref:2:8:CCCGGGG ref:0:10:GTATAA 2 1464 +CGGCTCACCATGC ref:0:13:GGCTG ref:0:11:A 6 10 +CGTGA ref:0:5:CCAGTC ref:0:2:GCCGAGA 2 24 +GGAACATTC ref:0:9:ATACAT ref:0:9:TGCTTTGAGA 2 138 +TGT ref:0:3:CCATCA ref:0:3:AGCAA 4 128 +GACGATCTCCC ref:0:11:TTCCA ref:0:11:AGGAT 4 32 +AAGAAACGTTTGGGTA ref:0:16:GG ref:0:16:TTGGCTTGCG 10 5040 +CATTTACATCTGATT ref:0:15:CGTGCTG ref:0:13:GCTGTAACGGGAAC 5 5376 +TACAC ref:0:5:TCCGTGACCGCGCCC ref:1:4:GCCCGCTTCG 6 12688 +TCGGAT ref:0:6:AATGTTTAA ref:0:6:C 2 32 +CTAGTAGG ref:1:7:TAC ref:0:8:AAGGAAGCAC 3 2148 +GTCCAATATTA ref:0:11:GGACCCG ref:0:11:CAACGTCGGGG 7 215280 +TCTATCCAC ref:0:9:CCAGTAAACCCACTGA ref:0:9:GGCCATTA 3 3525 +GCAGGCTTTAGGGT ref:0:14:CACT ref:0:14:TAGACC 9 1192 +ACTACC ref:0:6:GCGGATTGAG ref:0:6:CGCAT 5 777 +CGTTCG ref:0:6:GTATTTAACAGCCT ref:0:4:TTT 2 30 +ATCCAACA ref:0:8:T ref:0:8:TGATCTACGGGCTCC 3 376 +AGAATCTCTC ref:0:10:GCTTGCG ref:0:10:GGGTTAATAGTCTACG 2 18 +GAAGCCCC ref:0:8:CGG ref:2:6:CTATGCCATCT 1 7 +ATCCTCATT ref:0:9:GGACTGCGTCGCC ref:0:9:G 5 1650 +GTCTG ref:0:5:T ref:0:4:GAAGC 1 10 +GG ref:0:2:GAAGCGC ref:0:2:TCAC 2 45 +CTACTCAA ref:0:8:CGGCAAGTTC ref:0:7:CAGGGCAATCTCCAC 6 4644 +CTCTT ref:0:5:AACCTC ref:0:5:T 2 15 +AA ref:0:2:TGCATGCGCCGG ref:0:2:TTTGATCAGCGGGGA 8 39 +CTCCCCGCAC ref:0:10:CG ref:0:10:ATCAGATATTAGCTC 5 7500 +ACCCT ref:0:5:TG ref:0:5:CCACTAAGAC 2 1 +CC ref:0:2:AGAGAGGGAACCAA ref:0:2:TTATGTCGTCAC 3 3 +GAT ref:0:3:TCAGTGCG ref:0:3:TCCATACAA 4 16 +CCACCTCCC ref:0:9:TCGTTAGAGGATAAC ref:0:9:GAACGGTCAAGT 9 1816290 +ACAGTTAACGCAGAT ref:0:15:CGACGTAATACC ref:0:15:AGC 7 176 +TCAGA ref:0:5:CGAATCAGT ref:0:5:AGAGAGGTT 2 18 +CGAGGATTTAGC ref:0:12:AACTGCTCCAATG ref:0:12:TGAGCCGA 5 84 +AGGGTCGTGATT ref:0:12:GGAAAGAGAACAA ref:0:12:GAAAAGTATTCAATGT 10 16418560 +GTGGCGCAGTTAT ref:0:13:ATCTG ref:0:11:CCAGTATT 5 162 +GTAAGGTAGT ref:0:10:A ref:0:10:TCAA 7 12 +TTGAGCA ref:0:7:CCCTACATGCG ref:0:7:CATATAGCCTTCCC 4 1083 +GGAGGTTACTAAACC ref:0:15:TTGACTAAAC ref:0:15:TGTTGAAGC 6 2188 +CTACCTGAAGAGGAAT ref:0:16:CC ref:0:16:AAAATGCGC 8 12 +GTCACGCATAGTGATG ref:0:16:ACACCAGCTAATAAT ref:0:16:CTGCAAACGTGA 4 2997 +TGGCACCGCAATCACG ref:0:16:AGACCGGACGCA ref:0:16:A 8 1880 +CCTGCGAGAACCGCC ref:0:15:GCGTTTCGGGTCAGG ref:0:15:GTTCCCGCTAAGCG 8 3598364 +TGCTGTAGCATG ref:0:12:T ref:0:12:AGCAAGGCTTGTGAC 5 1956 +CG ref:0:2:TAAAACGCAT ref:0:2:ACCGGGTCCCTT 3 6 +CGCGTGCATAC ref:0:11:CACCGTG ref:0:11:TCCATTAACTCCTT 3 1656 +CTTT ref:0:4:GAGGGA ref:0:4:GGCGGCG 7 8190 +TCGA ref:0:4:GTTCGCCGACCA ref:1:3:AC 1 32 +T ref:0:1:AGCACTTCAAGGT ref:0:1:ATTGGGCACTG 6 9 +GTGTGGGCTGCTCAC ref:0:15:GCCGGCCG ref:0:15:CAAACTCCTGGT 10 2073436 +CCGG ref:0:4:TGGG ref:0:4:GCATCA 1 36 +CGTCATAATAGGGGTG ref:1:15:TCGTTATGC ref:0:16:TCTCACCTTACAGCAG 6 1808 +GAGCATGCTG ref:0:10:GCTTTGAG ref:0:10:C 5 120 +ATCACAGTT ref:0:9:CCCC ref:0:9:GTACTCTT 4 1430 +ATTTGGGGACCACGG ref:0:15:AACT ref:0:15:TAAGTCTGCGCTATG 7 40800 +GAGAT ref:1:4:AAA ref:0:5:CTC 1 25 +AAT ref:0:3:TTTACACTAT ref:1:2:CGCCACGTAC 3 4 +CTCGCCTTCACC ref:2:10:TT ref:0:12:GCAGGCAT 6 477 +AGCACACTT ref:0:9:GA ref:1:8:ACAC 3 2 +AAAAC ref:0:5:TCTCAGAT ref:0:5:ATATAGCG 3 567 +CACTTATTTGTGG ref:0:13:CAGAG ref:1:12:CG 8 90 +TTTAA ref:0:5:AGTAGATAAAT ref:0:5:CCTCATT 1 25 +CTTGTCACGTC ref:0:9:CA ref:0:11:TACG 4 6 +GCCAAGATCGTGTCTG ref:0:16:TACGAAAATTA ref:0:16:GAGGAAACGA 10 1596420 +ATATGACAGACTT ref:0:13:CTATATCCATTGTA ref:1:12:CTCTTCCCGCTATAG 6 17690 +CTTGGAGA ref:0:8:ACGCACGGGTGC ref:0:8:TGGCG 3 2120 +CTT ref:0:3:GTTAGCT ref:0:3:T 1 18 +ACCGCAGCGATAGG ref:0:13:GAAGCGCATAGACT ref:0:14:TGCCGGATAC 4 912 +GGTCAAC ref:0:7:CAATCGAACAG ref:0:7:CAGAT 2 20 +CTT ref:0:3:TACTTCAACGCT ref:0:3:CAGGAAGCGG 4 183 +TTCAGTG ref:0:7:CGCGGGTGGCATCAC ref:0:7:A 3 142 +TGACAAT ref:0:7:CTACTTA ref:0:6:GC 2 8 +ATTC ref:1:3:G ref:1:3:GCGGTCCCGA 2 84 +CGTTCGTCC ref:0:9:AACTGC ref:0:9:GTA 4 76 +CCGTGTAGCCCAC ref:0:13:TTAGCGTCGG ref:0:13:TTTTGCTAACGGCA 8 64978 +ATTTCGTCTAC ref:0:11:CGA ref:1:9:TGGATAAGGA 4 477 +AGTGT ref:1:4:CGCGAACGCAA ref:0:5:TGACACTAGTCCA 5 448 +GGGTTCACCA ref:0:10:CGCCCATCCTG ref:0:10:TGCAATCG 7 38097 +TATCACAG ref:0:8:ATGCGTAA ref:0:8:ATTC 3 8 +TCGTGTCGAGA ref:0:11:GCTCTTGTTC ref:0:11:TCGAT 5 231 +AGAACCGAAGCG ref:0:12:GGCTT ref:0:12:CCCACAGATT 7 945 +ACCATGCCAGGCGAG ref:3:12:GCAGGGTTAA ref:0:15:GGT 6 174 +ATT ref:0:3:GTTTTA ref:0:3:AAGAGC 2 672 +CCGGTTAC ref:0:7:AGGGAGGGTGG ref:0:8:TCCTGTAGCG 2 11592 +GGGGCGTAG ref:0:9:CGCCA ref:0:9:TA 5 53 +AAG ref:0:3:C ref:0:3:GCAACTTTT 2 24 +GTATACCTT ref:0:9:TAGT ref:1:8:CAG 6 1300 +CTTCCTTCAATTGGAG ref:0:16:ATGCCAGTTACGGTGT ref:1:15:TCTAGCTAT 7 167232 +CT ref:0:2:GGGCGTCACTTAGTC ref:0:2:CCTTAAGTCCATAGT 7 140 +TAA ref:0:3:AT ref:0:3:GCCCA 2 80 +GAGCGG ref:0:6:TTGTCTTGTCCA ref:0:6:CATAGGAGTGATCAA 6 11700 +ACTT ref:0:4:CACCAGACAGCAGCG ref:0:4:CCACCTCTTACAT 6 5280 +CGACCGTCCGT ref:0:11:TAGTAATGGGAAA ref:0:11:G 7 6768 +AGGAAACCA ref:0:9:CCGAAGGGAGGA ref:0:9:GCCACTTTCGACTAA 5 282504 +AGTAAAGA ref:0:8:CG ref:0:8:TGTTACTTGGTCC 5 6768 +CTTCTGGGGCTAC ref:0:13:CGGCGT ref:0:13:AGTGACACTC 7 46508 +TACTGAGCGTGA ref:0:12:GGATGT ref:0:12:CA 7 174 +GTTTTCGTGACAT ref:1:12:CATAC ref:0:13:TGT 6 26 +GTCTGCCCAA ref:0:10:TATGTCT ref:0:10:CAAGCGA 5 2115 +AGCCTA ref:0:6:GACCAC ref:0:6:CGTTC 2 88 +TGACTGG ref:1:6:CCCCGCCGT ref:0:7:GTCG 3 459 +CCGTCGCA ref:0:8:GCTCCAGTC ref:0:8:CCGCCGCAGCGAAGC 3 779 +CGAGCGCTGTCCGACG ref:0:16:GTTCACATGAGGCA ref:0:16:AGGGAGCGACGACT 6 14295 +GGCGAGTGGAT ref:0:11:GGGTCGG ref:0:11:GATCGGTGA 3 32 +CGCCCTTATCCGCT ref:0:14:CCGATTACCTCGTC ref:0:14:CA 5 1288 +A ref:0:1:ATAGGAG ref:0:1:T 1 6 +CAAG ref:0:4:AAATCCATTTCT ref:0:4:GAGTAAA 4 5206 +GTTGCTACCTCGCTT ref:0:15:ATGGGAGCCAGGGGG ref:1:14:ATGATGAGGTATC 8 4333560 +AGTAGATAAG ref:0:10:AGC ref:1:9:CTTCGGACCT 6 780 +CGCCTATCCAGG ref:0:12:GGCGAAGTCGGCA ref:1:11:AGTATTAGGGGGCA 5 6240 +ATAAGTAGCTCGGG ref:0:14:GTAGGTATA ref:0:14:CGGCTCGTCGATGTT 3 250 +GGGATA ref:0:6:TATAGACACGCGAGAC ref:0:6:GGATG 1 12 +GACAAC ref:1:5:TAGGCGTATTGCT ref:1:5:TC 2 49 +TATCT ref:0:5:CCACACTGCATGGTC ref:0:5:AATGAGTCGCCC 5 231 +GCGACCACATCGGAC ref:0:15:AGTGCCACTTGTATT ref:0:15:ATCACGGCTGTTAA 7 84162 +ACAAAAGTATC ref:0:10:CTTT ref:0:11:AAGCGCGGACG 4 5760 +GCTCATCATAAGCTA ref:0:15:CTC ref:0:15:CGCTCACCAG 7 150 +AAACGGGGC ref:0:9:ATGGGGCATTGTC ref:0:9:TGAATCCGGAGGGGGT 4 76544 +AATGATCTAGC ref:0:11:ACAAAAGTAAACCCTG ref:0:10:GCCA 3 5715 +GCTGTTATACAC ref:0:11:CCGCACCTACAGT ref:0:12:AAGTGAATGTTCATA 1 390 +GTACTTG ref:0:7:TACTACGTCCCC ref:0:7:ACACTTGGAGA 2 216 +ACCTACGCCACGAC ref:0:14:TTCAGAGACAA ref:0:14:CCGAATAGCACGTGA 3 80 +CGCCCAATGCTCGG ref:0:14:TCGATCAAAC ref:0:12:CTTCGGTCC 7 124752 +TC ref:0:2:TTGTCGTG ref:0:2:TCTATTGGAAAATC 3 18 +ACGACACTCAACTTGG ref:0:16:GGTTAA ref:0:16:GGAAAGACAATG 8 51336 +AGCTCCCCAC ref:0:10:GCTATCGAAGAA ref:0:10:TCGCCAGA 6 24882 +A ref:0:1:GCGGCTG ref:0:1:TATACGCTTCA 4 24 +TGATGGACGAAATTT ref:0:15:TCTGCTAAAGCAT ref:0:15:TA 7 3186 +GCGCACG ref:0:5:ATTTAATTT ref:0:7:ACTAATTGGCGAT 8 12017 +CGAAGGTACGC ref:0:10:AAGGC ref:0:11:TGGGT 3 2 +TCG ref:0:3:GGA ref:0:3:ACCTGATGCACC 3 120 +CTAGTGT ref:0:7:GTCTTTGGCAAG ref:0:7:GTCAACGGC 5 2450 +GCGCTGATTC ref:0:10:TCCCGGGGATACGTT ref:0:10:CG 4 6858 +GGGC ref:0:4:ATA ref:0:4:CTTTGCTAACTTG 4 3150 +CTCCCCTAAA ref:0:10:CCTTGGAGGCGCCA ref:0:10:C 4 645 +GGAACATCACA ref:0:11:ACGACGTATGCCGG ref:0:8:TCTAGTTGTTCTT 4 1350 +TATTTGCAC ref:0:9:AT ref:0:9:AGATGTCCCCCAATCT 3 2670 +CGG ref:0:3:CTGTGACGAACGCCC ref:0:3:ATC 1 7 +CTAGGCTGT ref:0:9:GAAAAGAGT ref:0:9:CCGC 3 4422 +CTAATATGAAGG ref:0:12:GACT ref:1:11: 10 59 +CCGCGTGAGAC ref:0:11:CTTG ref:2:9:CTACCCC 4 816 +CATTA ref:0:4:TGAGTTT ref:0:5:TACGTGTTCTC 4 846 +CATCCGAGGTCC ref:0:12:CCTGCGT ref:0:12:GTTTAA 7 73866 +ACCGTTTGTTC ref:0:10:CAAACCGGTGGGGA ref:0:11:TCAAACGCACA 8 705600 +CTGACCTCACCCTCA ref:0:15:GCTGTGA ref:0:15:ATATACCTTACAC 4 504 +TTTACCTAAA ref:0:10:TCTGATGC ref:0:10:CA 6 1206 +GACCGCCTCGGGAC ref:0:14:ACACCTAATATGGCG ref:0:14:TGTT 7 44745 +TCCAAATGTGTCGTC ref:0:15:GCCCCTGAAGCG ref:0:15:CTC 8 4875 +TGAATTTTCCCACA ref:0:14:TTGTTTA ref:1:13:GGCTTGCCCGT 5 43722 +CGCCTAAAGGTAA ref:0:11:CAAA ref:0:13:ATACATGACTTCTA 6 6801 +AGAAGT ref:0:6:CGGCGCAGTTGGCCAT ref:0:6:G 2 648 +CATACGCG ref:0:8:TATCCATCACTCGTC ref:0:8:TTTCTC 4 256 +TGTGTGGTTCGTAG ref:0:14:TTGACCT ref:0:14:CTGCTCGT 8 15867 +TCAGGCATACATCG ref:0:14:TATAGGGCCGATACA ref:1:13:ATCAA 5 630 +GCCTAACGC ref:1:7:AC ref:0:9:TTCGATT 3 56 +CCGGCCGCACTCCC ref:0:14:ACTTGCTT ref:0:14:A 10 1427 +AC ref:0:2:TAAGTGAACCCCC ref:0:2:CGCCCACGT 1 20 +GCGTAAACCAGATC ref:0:14:CGGGGCTTCCTGG ref:0:14:AATTTAGGAA 7 455336 +TAACGGTCTAAAAGAT ref:0:16:GTCGGCAACTCAA ref:0:15:GACGACCGGTCTC 4 224 +AAAGGAAGT ref:0:9:CCAACTC ref:0:9:AGGGAAA 3 7380 +CTGG ref:0:4:AGTATGCCTCGGCC ref:0:4:AATATCACTG 5 8 +CAAATG ref:0:6:AGCAGGCCCCGCTTC ref:1:5:GTGGAAGAATGTAC 3 2268 +GTAATG ref:0:6:ATTCGAGCGTA ref:0:6:CTCTCGTCT 6 2133 +GTTTGATACGACC ref:0:13:ACTTTGTCCAGA ref:0:12:GGGCATCACGGACGT 1 144 +GATGCTGACGTTC ref:0:13:CGAATCGTAGCAAA ref:0:13:CTGTTCT 3 12 +TCCCGTAA ref:0:8:ATCGTGACTTGAAGAG ref:0:8:AATCAAGGTGTAT 5 56232 +CTACATGTCCTACTGA ref:1:15:ACACCA ref:0:16:CCCTGCATGAATACT 3 264 +CAAAGACGCCTTAA ref:0:14:GGAGGAGGGCC ref:0:14:CCGCTCCCACTGCTGG 5 463740 +CCC ref:1:0:TGAGGA ref:0:3:CTCG 1 5 +T ref:0:1:CTCACTATACCGATA ref:0:1:AA 2 12 +AC ref:0:2:AAG ref:0:2:GAAGTATCGTTGA 2 15 +GTAT ref:0:4:CGTGAGTCAA ref:0:4:CCCCACTAGGTAA 4 13 +GTCGTCAC ref:0:8:CTTGTTGAATGATG ref:0:8:CTAGTG 5 450 +GATTCGTGCAGGTGAC ref:0:16:AATGGG ref:0:16:TCT 9 693 +C ref:0:1:TGGACATGT ref:0:1:TGA 3 4 +TTGCC ref:0:5:CTACAGAATGTAC ref:0:5:TTTAC 3 76 +TCTGTCGAAC ref:0:10:AAACT ref:0:10:TTC 5 60 +TAGTT ref:0:5:CTGTACTGTA ref:0:5:GT 1 26 +AATTACCTGGCGCCC ref:0:15:AGTGATA ref:0:15:TA 11 186 +GACCTT ref:0:6:GGCCGCTCC ref:0:6:TAGCA 2 1400 +ATGGCGTGTTG ref:0:11:GTTTACTTTA ref:0:11:TTCCGGTTGCAGCT 5 3876 +C ref:1:0:GAGGAGTTT ref:0:1:GTAGTTACTACT 2 2 +GACC ref:0:4:AGCCGACTCGGCG ref:0:4:GCGGTA 2 54 +C ref:0:1:AGGCCAACA ref:0:1:CGATGCA 3 6 +GTACTGCCT ref:0:9:GGTGTCGTCC ref:1:8:AGCCGGCATTT 2 2808 +CTATAGCAC ref:0:9:CCTCCTTTACTTCGAT ref:0:9:G 3 852 +GCGTCT ref:1:5:CACTGT ref:0:6:CGTCGA 1 54 +TAT ref:0:3:CCGACTGCGAGTGT ref:0:3:GCGTCTCGTC 5 20 +T ref:0:1:GCAACGACCGATAC ref:0:1:C 1 2 +CAC ref:0:3:ATT ref:0:3:CCGGTA 1 9 +ACG ref:0:3:GTCACGC ref:0:3:TGCTTATGGGACGA 2 2 +ACCGG ref:0:5:TCGCGATGGTCTCCA ref:0:5:GGAAAACACGAGTTA 4 24 +CTCTAGCAATAC ref:0:12:TAGGACTAA ref:0:12:GCAAGACTCCATCGG 5 25004 +A ref:0:1:TGTAGCTTT ref:0:1:GGCATC 2 1 +ACAGCGGTTTACTCTG ref:0:16:TGGAAC ref:0:14:CAAATTTACTG 5 10208 +TTTTAG ref:0:6:GCACAAACCC ref:0:6:AGGTTTCATGG 3 38209 +CCCAAG ref:1:4:TATCC ref:0:6:GTTGTAGCTA 3 393 +CACGACAGACTTC ref:0:13:CC ref:0:13:CTGTTGGACCGT 7 14680 +ACCAGAGGTTCA ref:0:11:GTCGTAG ref:1:11:CTC 4 72 +GTCTCTA ref:0:7:ACATGCCCAAGGAGG ref:0:7:ATAG 5 3384 +TCCTCGGTCACAATA ref:0:15:ACGGCGAAT ref:0:13:TGGATCGTGACAG 5 9360 +TAGATACGA ref:0:9:TATAAAATGTC ref:0:9:TTACAACCAAAGAT 5 5472 +GAGCAGGCCACTAAC ref:1:14:GCGAGTTTCGG ref:0:15:TATGTG 9 27889 +AGAT ref:0:4:C ref:0:4:GACAA 3 75 +CAGAGCCCGCCGTTC ref:0:15:ACGACGGAAACGTAT ref:0:15:GCTCG 6 9010 +TACAAT ref:0:6:CCTTTCCGTTGTG ref:0:5:TGTAG 5 14454 +CAACCGGTTTC ref:0:11:TGCGATCAT ref:0:11:GGGT 7 29025 +AGCAC ref:0:5:GCCACAACTGTTACAT ref:0:5:TGCTACATTGTGAT 7 98 +AT ref:0:2:GTC ref:0:2:CGTGGTG 2 18 +G ref:0:1:TACGATGGGG ref:0:1:TC 2 15 +TTTATTTCGA ref:0:10:GCGGATGC ref:0:10:TATCATGTTTTGGTCC 5 711988 +ATTATGC ref:0:7:TGAAGCGTTTTA ref:0:7:TAAGCCCACTGAATA 7 25842 +AAGCGCGTTTCGTC ref:0:14:GTTGGA ref:0:14:CGTC 8 2808 +GTATCGC ref:0:7:CCTTCTAACATCTCC ref:0:7:A 2 273 +CT ref:0:2:CGTACCAGATC ref:0:2:TGCGGG 2 20 +CCCTTCAGAC ref:0:10:CGTTAGTACGTT ref:0:10:GTAGA 4 54 +ACTGC ref:0:5:GCGCAGAGCGG ref:0:5:GCT 2 192 +GGGGC ref:0:5:ATA ref:0:5:AGTCGCCTAC 5 5824 +TCCCATCGT ref:1:8:CCTTGGGGTG ref:0:9:GATTTCATAG 2 4256 +CGGCCGGACC ref:0:10:AGTAGCTCCAC ref:0:10:TTAC 6 1584 +TATAAA ref:0:6:CCCAAAAATCAAG ref:0:6:GTCCG 4 46632 +CCTCTGA ref:0:7:GATATGACAGG ref:0:6:GCAGT 4 1248 +AGC ref:0:3:GTATTA ref:1:2:CAA 2 17 +A ref:0:1:CTTATGGAGTGAC ref:0:1:AGGCTGCGCGCAGT 6 6 +AATGTACGTC ref:0:10:GCCCTTT ref:0:10:TT 7 477 +CA ref:0:2:TATA ref:1:1:GAGATACCGTC 2 18 +CCTTCGC ref:0:7:ATATTTGACCTT ref:0:7:CCACACTTCA 3 4104 +AT ref:0:2:TCAGTACGC ref:0:2:AATCGTTGCATT 3 12 +TCTGCCA ref:2:5:AGAA ref:0:7:AGGG 4 808 +AGC ref:0:3:GGGTACTTAGCCA ref:0:0:TGCGCG 3 4 +CGAAGTAAA ref:0:9:TTAGTTATGTGCCC ref:0:9:GGTCGGCCCCGTAGA 4 371480 +ATG ref:0:3:T ref:0:3:AAGCCAATA 1 11 +CT ref:1:1:TTAC ref:0:2:GTAAGAG 1 4 +GATCTTATGT ref:0:10:TTCGG ref:1:9:TCTGATAC 4 2212 +GGAAC ref:1:3:TGT ref:0:5:AACGAAAGCCCACAG 1 267 +TTATAGTCTGGTGCA ref:0:15:CAGCCTATAGAAC ref:0:15:GAATCGCTCCAAC 6 15552 +GT ref:0:2:GGCCG ref:0:2:TCCTC 2 50 +CGAGCCCTTTCATGCA ref:0:16:ACGC ref:0:16:TCATTCCGGCTCCTC 6 144 +GTGTTTGAGTATCG ref:0:14:AACTGAGCCCACGA ref:0:14:CCCCACT 11 2686068 +TCAGTCCAACA ref:0:11:TGGTCTCTAGTCTCCT ref:0:11:ACGTTAGGCAAGGGAA 2 7690 +ATAACCCACCA ref:0:11:CACGT ref:0:11:TACGTCTGCCCT 4 108 +TG ref:0:2:CC ref:0:2:CGCTCCGG 2 12 +TGAGTATC ref:0:7:CGCAA ref:0:7:CTGG 3 2 +AGATATAT ref:0:8:GCGG ref:1:7:GGTCCAATT 3 1526 +GTT ref:0:3:A ref:0:3:AATGCGGCACACC 3 632 +AGGTAAGTAG ref:0:8:CGTTGGACTTTG ref:0:10:GCCTCCGGAGTGG 6 197235 +CGATTTTTAAAGG ref:0:11:TAT ref:0:13:TGATGAA 7 6500 +GAGTGTTAACAA ref:1:11:CAAACCC ref:0:12:GGCGTGCTACCAG 4 3400 +TCCTAAATATGGTAG ref:0:15:GGTGCTTTCACCA ref:0:15:CGTACCT 10 266616 +CTACGATGC ref:0:8:AAGCGTCAAATAGT ref:0:9:GTCCAGA 3 690 +GTTCCGGCCTCCTT ref:0:14:TTGGT ref:1:13:TCCGAAGTATAGCCC 4 312 +CAATTGCGCGTACTT ref:0:13:TGCAGTACACC ref:0:15:ACAGTCGGATA 3 3584 +CCTA ref:0:4:CAGGGTGT ref:0:4:GAGAAGGTGAG 6 1008 +ACCCTTCACACGTCA ref:0:15:AGAGTTGCCTTTC ref:0:15:TGTCCATAACG 7 78064 +ATAGCCCTCAG ref:0:11:CCAGGAGACATGCAAT ref:0:11:AGAC 5 5100 +TTTAT ref:0:5:TTCAGCGCA ref:0:5:ATTC 3 693 +GATGTCATAC ref:0:10:TCTTGT ref:0:9:CCCGGATGATAGGGA 3 1644 +AGGAAGAA ref:0:8:TCA ref:0:8:TACACCCAT 7 27360 +CGGTAACGTCACATC ref:0:15:TGCGACGGCTCG ref:0:15:GGACGTTTAT 5 2688 +ACTTTCGGCG ref:0:10:TGCCGGAAGCA ref:0:10:TCCCTCA 7 129447 +TGGGCTGGGGAA ref:0:12:T ref:0:12:CCC 10 182 +TGACTGC ref:0:7:CGAGTAATCCCCC ref:0:7:TTCGGCGCTGAATG 5 225335 +CC ref:0:2:GTT ref:0:2:GTGCTTTGG 4 100 +CTAGGCTTT ref:0:9:TCA ref:0:9:TGCAAC 7 324 +ACTGA ref:0:5:CTTGGGACGAC ref:0:5:AGAACGCGAGAA 3 1395 +TGGA ref:0:4:GCTACTGAATACGT ref:0:4:G 1 72 +AGTCAA ref:0:6:GTGCCTCCGCCGTTG ref:0:6:G 3 729 +ACC ref:0:3:TCTAACAATCT ref:0:2:GACAT 2 2 +ACC ref:0:3:GGGGGGGTTTAGAG ref:0:3:TGAGG 5 78 +CAGTCTGATCAAT ref:0:13:TA ref:0:13:TATGCTTAGTCATGT 4 1152 +GGACAAGCCTCTAAG ref:0:15:TC ref:0:15:GGGGTGCATATC 8 146 +TCAAA ref:0:5:GTGGCGACTTCTAGCG ref:0:5:AAAGGTGTGA 2 72 +AG ref:0:2:GCGGAGCG ref:0:2:GACGCCG 3 4 +AACATG ref:1:5:TGTACCAGATAA ref:0:6:CTATGTTA 2 14 +TGCC ref:0:4:CGTAGTAGCGCTTT ref:0:4:TTCTGA 2 75 +TCCTGAGGA ref:0:9:ATGCCTCG ref:0:9:CAAAGGTACTCCA 1 400 +TGTG ref:1:3:CGGAT ref:0:4:TATGAAAGCGTA 2 126 +TACCGACGGCACA ref:0:13:ATCGTCATTCTC ref:0:13:A 7 2720 +CAA ref:0:3:GCGAGCAAAAGTAGC ref:0:3:ACTATT 2 150 +AATGAGC ref:0:6:GCCTTG ref:0:7:G 4 150 +A ref:0:1:GATA ref:0:1:ACTACACGAGCACCT 2 10 +TGTGCAACTGT ref:0:11:CCTCCC ref:0:11:CTTCGGGGTC 7 9272 +GAG ref:0:3:CAACCGC ref:0:3:AT 1 10 +GAGGGTTAGTG ref:0:11:TGGTCACACTAGGGGA ref:0:11:CCCATTTA 4 4160 +CCAGCGAGTTATTGC ref:0:15:AGGGCCATGAGGTGG ref:0:15:TCA 7 39312 +ATCGCT ref:0:6:GGGGTTAAT ref:0:6:GAAAG 5 5160 +GATTCAGAAAAC ref:0:12:TAAAT ref:1:11:TACGTTTTC 6 24050 +TAACGATACCCTTT ref:0:14:ATGAGTGCGTCCCCC ref:0:14:AACATT 4 2268 +GTGACAATT ref:0:9:AGA ref:0:9:TTCGGCGGATGGGAT 4 1080 +AACAGT ref:0:6:GTCCGAAAA ref:0:6:TGTGGACACA 5 7 +TAACACCCTGGG ref:0:12:GAACGAGAGAGGG ref:0:12:ACCAGTGAGC 6 89320 +CAGTGA ref:0:6:AT ref:0:6:G 3 2 +TTGAAGTGGCT ref:0:9: ref:0:9:CATGAAGCGGA 2 8 +GGACCCT ref:0:7:CCATGTCGGAAGTG ref:0:7:C 3 129 +AGACTATGCAT ref:0:11:CAGGGACAC ref:0:11:ACAGCAC 3 12 +GTATTATCCCCACGC ref:0:15:TAAC ref:0:15:CCG 9 140 +TTACCGTCCCAC ref:0:10:CTATACCACG ref:0:12:TCAAGCAGTCGGACG 5 12870 +ATACTTAAAGA ref:0:11:GGAGACGATCAAAGC ref:3:8:CCCAGGCAT 3 2540 +TTCGTCAGAG ref:0:10:CTCCCCTAGTC ref:0:10:CCTACGACCTGTG 7 167184 +TCCAAAATGC ref:0:10:GGGGTAGCAC ref:0:10:GGGGCAA 9 4680 +ATCGAAGAGTCCC ref:0:13:C ref:0:13:CGAAGGCGG 6 40 +TTGGCTGGAGGTTA ref:0:14:TATCTA ref:0:14:CACGAACATCAGGTG 6 5250 +CTTG ref:0:4:ATTATATC ref:0:4:ACGGCGC 2 780 +AAA ref:0:3:TTACCACTGTATTT ref:0:3:GAATTT 3 7 +GTTATGACCCGTCCT ref:0:15:CCCTAA ref:0:15:AAACTGCGT 8 8720 +CTCTCAACATACCGTG ref:0:16:TGTGCAGTCGTCTGA ref:0:16:TCCCT 7 2280 +GCCGGTAA ref:0:8:TAGGCCCGCTCC ref:1:7:CCCCATGCTA 4 8160 +TACTAGGGTTGT ref:0:12:GAGTGTCGAACGAA ref:0:12:GACGGGCTCG 7 24096 +TCCTCCCGTTAACGTA ref:0:16:ATAGGGCAGCCCT ref:0:16:TAAGTGT 9 20384 +TGCTAA ref:0:6:G ref:0:4:C 2 1 +AAACT ref:0:5:ACACAAC ref:0:5:AGC 1 24 +CATAGGA ref:0:7:GCTTCCTAAAT ref:0:6:AGGCGCCACTG 4 348 +ATTGCTATAATCAGAT ref:0:16:TAGGTTA ref:0:16:GCCCGAC 8 2840 +TG ref:0:2:AGCC ref:0:2:TCACCTCAGAAT 1 4 +AACCCGTT ref:0:8:TCA ref:0:7:TCCGAATAAG 5 660 +AGAGAATAA ref:0:9:CGGCAT ref:0:9:GATTTTCCCCCTCTGA 4 18780 +CA ref:0:2:TCATC ref:0:1:AGAGACTGC 1 2 +GCA ref:0:3:AGCGTTGGGGT ref:0:3:CCAGTGGT 5 27 +ATACTACTA ref:0:9:ACATATGTCGCCCT ref:0:9:GGCTGATAA 2 4416 +GG ref:0:1:TCCCTAAGTTTC ref:0:2:AC 2 6 +CTCGCTCATCTCGTC ref:1:14:CGG ref:2:13:GAACAGG 8 178 +CGTGG ref:0:5:ACA ref:1:4:TGGACGTA 2 20 +GTTTAGAAC ref:0:9:TTGAGTTGTCGT ref:0:9:CTCAG 4 2448 +C ref:0:1:CCGATTTCTTCCCCA ref:0:1:GAATGCCC 5 21 +TC ref:0:2:GCG ref:0:2:CTCGGCCCGGTC 2 12 +ACGACGTC ref:0:8:ACTTTGCAAA ref:0:8:TAC 4 1164 +CTTGGTATG ref:1:8:AGTGA ref:0:7:AA 5 264 +TTGTGTCCGCTGT ref:3:10:CATTTCACA ref:0:13:CCAGGACCAGGCCTC 3 47040 +ATTG ref:1:3:GCGT ref:1:3:GGCT 4 108 +CCTCA ref:0:3:GCTTATGA ref:0:5:CTTCTGAAA 4 312 +CGTTGGA ref:0:6:ACAG ref:0:7:TGTGAAG 2 340 +TAGCGACTA ref:0:9:CTTAGAGCCAGGTC ref:3:6:G 3 396 +CCCTA ref:0:5:CTTATAGAG ref:0:4:GTTCTCGGTCTTCCG 3 114 +AGTTA ref:0:4:CAGCAGGTC ref:0:5:CGTCCTAGTTTGG 3 252 +A ref:0:1:TAACGCGCAAAGGCA ref:0:1:GCGCTACGTATGGGA 8 18 +GATGGAGTTCC ref:0:11:TCATAAAA ref:0:9:CACTTG 6 32250 +CAGG ref:0:4:CCCT ref:0:4:TAGTGCG 1 204 +G ref:0:1:T ref:0:1:CTTTATGAAATAA 1 2 +CGC ref:0:3:GGGGTTCCGGTGG ref:0:2:AATACTGGGTAAG 4 180 +TAGGGTGGATA ref:0:11:TA ref:0:11:AAGGAGTGCGG 3 108 +CGTAACTCTTGAG ref:0:13:GGTCTACGAC ref:0:13:T 6 24 +AGGTTGTACCCAATTG ref:1:14:TAAC ref:0:16:CCTCCTTCTC 8 189432 +TAATTTAATCTGG ref:0:13:CCAAATCCCT ref:0:13:CGCC 6 180 +TGCG ref:0:4:TCTAAC ref:0:4:AG 2 78 +GCT ref:0:3:TTG ref:0:3:CGAGTGTAGGCCAG 3 250 +C ref:0:1:GATTTTGGCG ref:0:1:AGTTAAGTATT 5 12 +TAGCTGAACAAC ref:0:12:CC ref:0:12:ACCTTCACACGG 5 297 +CGCTATGT ref:0:8:AAGTTCGAAGATT ref:0:8:CCGCAACTTAT 3 11400 +GTAATACTCT ref:0:10:CT ref:0:10:GGTCG 6 174 +TAC ref:0:3:ACCCATCATGTTGAA ref:0:3:GGTGACGGG 2 30 +CACTGTAGGGTAG ref:0:13:CA ref:0:13:T 10 15 +ATTGTCACAGAA ref:1:11:TGATGACCCATAAT ref:0:12:A 3 320 +AAGACCACTGTCA ref:0:13:TCGCACCACTCACCT ref:0:13:CCCAGCACGTAAAT 4 720 +TAGTATCG ref:0:8:GTTGCTGC ref:0:8:TCTTCGCAGCTA 4 12 +GTTCAG ref:0:6:TCTTT ref:0:6:GGAGTATTGGACCTAT 3 1944 +ACAGAAATCTCCTAGC ref:0:16:ATGTCGGACT ref:0:16:AGCGGTC 11 67284 +CA ref:0:2:GACGATT ref:0:2:CATCATAGG 2 5 +CGTCTGGTAACCCATC ref:2:14:TGACATTAT ref:0:16:AGGTGTAGCGAA 8 1278000 +GATACATGTCG ref:0:11:GTC ref:0:11:GGTTATGTCTC 4 550 +GTTGAGC ref:0:7:CCGT ref:0:7:CC 5 16 +GGAAC ref:0:5:CGCTTTCCTACTCC ref:1:4:CGAGCCAGCTT 4 236 +GAACCGA ref:0:7:TC ref:0:7:AT 6 108 +AACGTTGGGCAAC ref:0:13:CGGGGTTC ref:0:13:C 7 33 +TGAGC ref:0:5:TCTCTACCAAGG ref:0:5:TTCTCA 6 8178 +TGATT ref:3:2:GCGCG ref:0:5:TACTGAATCCGCAA 4 735 +GAAGTCTTTGTTGTT ref:0:15:T ref:0:15:GGGA 11 120 +GA ref:0:1:ATGG ref:0:2:ACACCGAAATATAT 1 10 +C ref:0:1:CTCTTCACTCG ref:0:1:AGGACTAGC 3 10 +TCGTTGAAGATC ref:0:12:CA ref:0:12:TTCT 8 96 +TTCAGGTAGGGTTA ref:0:14:GAAGCGAAG ref:0:14:TGT 7 11640 +A ref:0:1:ATATATGGCT ref:0:1:TTTGTAAGA 3 9 +TATCGGGT ref:0:8:GACGGCGTGA ref:0:8:CTTGATACAACC 2 316 +GGTGAT ref:0:5:GGAATGGTGTGAAA ref:0:6:TTTGTGATCTTGA 3 1404 +TGGAATATTCTTT ref:0:13:GGGAAGGGCTG ref:0:13:GCTCGCCGCGGTGACA 8 104880 +CTGGGCGCACTAA ref:0:13:A ref:0:13:AGTGTGGC 7 117 +CGAGCGGCAA ref:1:9:GTGAAGCAACTGC ref:0:10:ATCACTACTTTTT 5 19694 +CCTGACA ref:0:6:TGAGTTGACGC ref:0:7:TGTGGCTACAAGA 5 5280 +AGAATGA ref:0:7:CGATCGTAGC ref:0:7:ATTTTATTTACT 3 604 +TAATATG ref:0:6:GCAA ref:0:7:ATTTC 2 264 +AAAG ref:0:4:CGCCGTCC ref:0:4:TTGTCT 5 390 +CGCGCTCCCAA ref:0:11:CGTACGGGAT ref:0:11:TACGT 8 3088 +CCATCAG ref:0:7:GGGACACTTAA ref:0:7:C 3 300 +T ref:0:1:GTTCCGAGC ref:0:1:CACACCG 4 16 +AAGAGCTCACG ref:0:11:CAA ref:0:11:AAAAGAGTGTTCAA 4 5544 +TGGGGACTCCG ref:0:11:AACACA ref:0:11:AATA 9 3366 +TCGTCGC ref:0:7:ACCCTG ref:0:7:GGTGCT 2 116 +AAATGTGGGGCACGCG ref:0:16:TGCGTAGC ref:0:16:TTCAGCACGCGAA 7 2100 +CCT ref:0:3:TTTCAGCCTATTACC ref:0:3:G 1 36 +CCG ref:0:3:AAGGCGTTACACTGTT ref:0:3:CCTACTT 4 36 +GGTGGGTCG ref:0:9:ACTATCGACAC ref:0:9:C 5 24 +CAACT ref:0:5:TATGGAGGCACTCA ref:0:5:CTGCTCGGTCAA 5 476 +TCCCCAGTCTATGCA ref:0:15:TTTTTAGTC ref:0:15:TTGT 10 7105 +ATGGGAGGGATCCGCA ref:0:16:A ref:0:16:T 14 8 +CTTT ref:0:4:TCAAAACTTAGA ref:0:4:CAAGAGAGGCC 6 5238 +GAACATTATTT ref:0:11:TTCTTTGG ref:0:11:ACTCACTCTAATTG 3 126 +GC ref:0:1:A ref:1:1:ATACAC 1 4 +G ref:0:1:TGCAC ref:0:1:CACCCCAAGGTAGTGC 2 4 +G ref:0:1:CAAA ref:0:1:ACT 2 20 +GCCAGAGGCC ref:0:10:GTGAATTGAAT ref:0:10:GGTCCACACCTTTCA 4 23800 +CATCG ref:1:4:GTCCGCAGCC ref:0:5:TTGACAAA 3 520 +CACGCGA ref:0:7:GTT ref:0:7:AGACCC 4 481 +TTGTTGCTCACA ref:0:12:AAT ref:0:12:AGA 10 20 +CCCTGCCC ref:0:8:GCTCATC ref:0:8:TGACTC 4 245 +GTAACGTAGCGGTT ref:0:14:TAGCGATATG ref:0:14:ATGCGCTTAG 7 324 +CCC ref:0:3:TCCTTGCTCCTCGT ref:0:3:ATGAAGACAA 2 1320 +CCACCTATGTAC ref:0:11:CACGGGGTTGGTT ref:0:12:CACAGCT 3 576 +ATGCAACCTCT ref:0:11:GTCGTAACGTTG ref:0:11:ATAGAGTTTAAGAAT 5 29148 +ATATGGGAGAATCGA ref:0:15:TGTGGAAGTATC ref:0:15:TATTCGGG 5 3534 +CAACTT ref:0:6:A ref:1:5:GGA 4 8 +GTAA ref:1:3:ATTC ref:0:4:TACCGCGTACCGG 2 182 +GT ref:0:2:GTCCGAGGATTCC ref:0:2:CTCGA 3 36 +GAGATACGTTTTT ref:0:13:GC ref:0:13:GTTTCTTATTTA 5 62 +TCGATAAA ref:2:6:TATA ref:0:8:C 3 10 +AGCC ref:0:4:CGAAGCATAGCATCA ref:0:4:CTCGGAC 3 410 +TCCGTTGT ref:0:8:ATCGGATTGCGTGCC ref:0:8:ACATGTACTCGCG 4 460 +GTATAACCATAC ref:0:12:ACCTGAAT ref:0:12:CCG 8 217 +G ref:0:1:AGGATCCATTGTCGTG ref:0:1:CCATCGAAGACAT 6 10 +GTAC ref:0:4:CACGCAATCCCGCCG ref:0:4:ACAATAAAAGA 5 4074 +TAGGAGGATA ref:0:10:AT ref:0:10:CCGAACAATGG 6 6669 +CG ref:0:2:GACACCCATGGCGTT ref:0:2:AGGTTGACATTTGGG 6 39 +ACCA ref:0:4:CGAATGGG ref:0:4:TA 2 40 +CC ref:0:2:GGGCA ref:0:2:ATTAGTATAACACACG 2 18 +GTCCGGGATGAG ref:1:11:CGTTGTT ref:0:12:C 7 484 +AATTACACCAT ref:0:10:TT ref:0:11:TCAG 6 22 +GACCATG ref:0:7:CAGGATCACAAGGC ref:0:7:GGTGTTAATGTGC 3 144 +GGCT ref:0:4:GTACGGCGGGAGTG ref:0:4:AAACTCGTTGC 2 3 +GTCTGCAT ref:0:8:ATA ref:0:8:CCACGGATCGCCGG 3 224 +AAACCTTCTGTACACG ref:0:16:TACTCCCTCTAAAATT ref:0:16:GTTGGC 6 15837942 +TGTAGCGTCTATAT ref:0:14:CGTCC ref:0:14:CCTGTTGTTCA 7 846 +AAGGCGCAT ref:0:9:GACCGTGTG ref:0:9:GCACTCC 5 2268 +AC ref:0:2:TGCTTCCGA ref:0:2:TATATTCAACT 4 102 +CGT ref:0:3:GAAGATG ref:0:3:TTATATCTTCG 3 25 +TTT ref:0:3:CTG ref:0:3:CAGCCACCCTAT 2 130 +CCGCGGATAG ref:0:9:CCTT ref:0:9:CT 6 60 +GCTCGCGTCTTAGC ref:0:14:ACTTC ref:0:14:TTTGCG 8 212 +CATTCCGTCTGG ref:0:12:CCG ref:0:12:ACCTGATGAAA 6 585 +GCC ref:0:3:TGTTTCGATCTT ref:0:3:TCTAATTTGGAACTAT 5 17 +TCAACGATTC ref:0:10:GAAGCTAGTACCGG ref:0:10:AGCCTTTTT 5 115500 +GATGCCGCGATG ref:0:12:G ref:0:12:AGCACGTAGC 5 80 +CACCGC ref:0:6:TATAGTAGCAAACCT ref:0:6:GAG 2 62 +TTCTACAGC ref:0:9:GAAGATGA ref:0:9:CCACGGAGTA 6 1875 +TGTCGTAGAGCAC ref:0:13:AATGAGG ref:0:13:GGACGG 7 8 +ATCCAGTTTTC ref:0:11:TCGCAA ref:1:10:CGTGTGCA 5 300 +CGAGGGTCAATTCGGC ref:0:16:TCGACG ref:0:16:TAG 11 104 +TACGAGTCCGGTTT ref:0:14:AGTGAGTCAA ref:0:14:GAAGTCG 7 4640 +CTCACATCGTCA ref:0:11:AGAAGCGGGCGCG ref:2:10:ATTGC 3 10100 +GC ref:0:2:CGCCATA ref:0:2:CAAGTCAAGTCCCGCG 3 20 +AGAATACAAAGCACAC ref:0:16:GAGCCCCGCCGCC ref:0:16:CAGATTGCCGG 8 804000 +CCGCACAATGCAAACG ref:0:16:A ref:0:16:CTT 13 330 +GAGCTCGA ref:1:6:TAGCTTGATTCGG ref:0:8:AATAATTAGGGTCC 2 4512 +T ref:0:1:CCGAACCGTGC ref:0:1:ATACATTTCTGC 6 5 +AAACGTGGCTAT ref:0:10:GCTTC ref:0:12:CTATATTCAACG 7 15120 +ATTTTATTCT ref:0:10:CAATGCACCACGG ref:0:10:CATACACACTCTAA 8 1043400 +CAGAG ref:0:5:AGTGCG ref:0:5:GAACGCCTCG 4 304 +AGAGCCAGTATCC ref:2:11:GCCATATTTATT ref:0:13:TGTCCA 4 6300 +TGCTCCTCATC ref:0:10:GGCGCATTCCTC ref:0:10:GCCTATAGCATA 2 280 +GAACGGTACATGCGCT ref:0:16:CTCTTACCTGGGCCTT ref:0:16:CG 7 26488 +GCTTT ref:0:5:TGCCATG ref:0:5:TCGATAGT 4 650 +CATCCACAAA ref:0:10:GCAATGGGAT ref:0:10:ACGGCACCT 6 12418 +T ref:0:1:GCCGTTGTATTAC ref:0:1:CATGCGCC 3 5 +GAGAAAGAAGAGA ref:0:13:AACCGGAAT ref:0:13:GGC 7 675 +GCTGC ref:0:5:TTCGCACGACCTACTA ref:2:3:AGTTCCTTATTA 7 288 +AACACACGTAACTTT ref:0:15:GC ref:0:15:CTACCCTGACCTGACC 7 4482 +ATCGAAACGGCTT ref:0:13:GCTGCGG ref:0:13:CAAATGGGTTCCG 3 54 +TC ref:0:2:GA ref:0:2:GAAATGTATA 3 72 +CGCTTGGAATGTATGG ref:0:16:AAAGT ref:0:16:AAG 12 182 +TCGAGAGTGCTGTC ref:0:14:GAATCGTCCGGTGTT ref:0:14:CTCGTGAGTC 4 644 +AGAAGGTTAGTCTTAC ref:0:16:TTGCCA ref:0:16:TGAAGCGA 8 312 +ATGGTGCAGAG ref:0:11:TTGGTAGTGGATGGT ref:0:10:TATCCGGTTTCTG 4 1728 +AACTGAAGACCGCC ref:0:14:GACGTTAGCCAC ref:0:14:ATCGGCCTT 6 27951 +ACACCCCT ref:0:8:TG ref:0:8:TCTT 6 86 +GAGGTCCGAGAGCGAT ref:0:16:GCCG ref:2:14:TACA 8 36 +TTGCTGAACGCTT ref:0:11:TGAAG ref:0:13:TCACCTGC 3 130 +CGTGTTACGGC ref:0:11:ATCTGCA ref:0:11:TGCATAACGGG 4 3564 +GCCGAGG ref:0:7:C ref:0:7:G 5 8 +AT ref:0:2:CGCATGGAGAAGTGA ref:0:2:GATTCG 3 10 +TGAGGGTGAAGT ref:0:12:GTGGGGT ref:0:12:C 6 364 +TAA ref:0:3:ACATTGGGATCGGTT ref:0:3:CGAGG 5 420 +C ref:0:1:TCAAGCCACCAGGCAT ref:0:1:AGTTT 3 36 +GGGTGCACCAGTG ref:0:13:ACAATTGCA ref:0:13:CACATAGAACTA 9 518 +TTATCCAC ref:0:8:GTAGGCTCTGC ref:0:8:ACCATCCC 3 798 +CAACGTGTTCCGGCG ref:0:15:GCTAATCAGAAAAGC ref:0:15:GACGTGTTTGTT 3 4230 +TCGGAGTCACCACTT ref:0:15:GTCTG ref:0:15:CCGCCGAGTG 9 14904 +ATGGCCAATGTCCG ref:0:14:GGTTCAACTATAC ref:0:14:CTCAC 6 576 +TGTTCTAAGATTGT ref:0:14:CC ref:0:14:CACCCACTCTTTGGCA 9 31515 +AGTCTC ref:0:6:GTTGGGTCGTATACCC ref:0:6:T 1 216 +AGATTATCCACCAGCC ref:0:16:AC ref:0:16:CTGTTTTC 10 4248 +GCGATTTCATTC ref:0:12:CAG ref:1:11:ACGGTAAG 8 4752 +T ref:0:1:CGTGTTATGTG ref:0:1:GTGTTCAAT 6 20 +CTAAAAAAC ref:0:9:GGGGCCCCTGCG ref:0:9:GCCAA 6 1820 +TACTCTGTACGAAA ref:0:14:CAGAT ref:0:14:GGCGCACATGCT 9 30240 +CGCCGTTTGTAT ref:0:12:GGGCAA ref:0:12:GCCCAGCGC 7 448 +AGCATTACTTCGG ref:1:12:GCCGCGGCCCATTC ref:0:13:ACTTGA 5 54124 +ACC ref:0:3:AAATCTCCGAA ref:0:3:TTGGTCAGC 2 81 +AA ref:0:2:GCATC ref:0:2:TCTGTACCGTAGATCG 4 18 +C ref:0:0:GGGAAG ref:0:1:TCGCC 1 3 +ATCTCGTTCGCGTTTT ref:1:15:TGGGAGCATGTG ref:0:16:AATCTTCCAATTA 6 4843248 +AGGTTGCA ref:1:7:CCTGAATCTG ref:0:8:GGACAA 1 84 +AACTGCCAT ref:0:8:AGCATGCC ref:0:9:A 2 12 +G ref:0:1:CCC ref:0:1:AGGATCC 2 8 +TCCTCC ref:0:6:CCTAAATAGTGCTA ref:0:6:AACCTTCG 3 525 +AGGA ref:0:3:GCCTT ref:0:3:GTCATAAGCGTG 2 54 +AT ref:0:2:TTTGTCCA ref:0:1:TAACCC 1 24 +CCACTCACA ref:0:9:CAT ref:0:9:TGGAGG 5 56 +TGAGCGATCTTC ref:0:11:CAACGCACTTG ref:1:11:GCTATTTACCTGAGA 2 168 +AGG ref:0:3:GA ref:0:3:CGGTCGGA 2 72 +GCCGCTTGGT ref:0:10:CAGTTGCGAGAGC ref:0:10:AGGTGTTGCA 5 8760 +GAAAGAAGTTGTTC ref:0:14:AGGTGTAAA ref:0:14:CTAGCCGCAG 8 191268 +CATGCTAGC ref:0:9:ATAGA ref:1:7:AACTGGGATGG 2 510 +AAGAC ref:0:4:A ref:0:5:CGGATATAATATCT 1 72 +ATCCGCCCCGG ref:0:11:TTT ref:1:10: 9 78 +TTAGTTGTGTGCG ref:0:13:GGAAACGTCAGCACAC ref:0:13:GAAAGACCGTCGGGA 6 9500 +CGAACTTAGGTTTATA ref:0:16:AAAGAACC ref:0:16:ACTCCCCGAGG 7 28 +TGGATAGTCTAAACAC ref:0:16:TTGGGCCAG ref:0:16:AGTCG 8 128 +TTGTAGTG ref:2:6:CGTGACAAT ref:0:8:GAGGGCAGCCATAT 5 3680 +CAAC ref:0:4:AAGCAGCGAA ref:0:4:AGCCGGATGGAGATCC 5 156 +TGAGCATC ref:0:8:GCGCCA ref:0:8:G 4 12 +ACACACGACTCC ref:0:12:CGGATGGAAGGAAGA ref:0:12:TTGTTC 6 705600 +ACATGGAGCCTCGG ref:0:14:TGCCGATCAGTTGT ref:0:14:TCTATTAGAGCGC 3 840 +AA ref:0:2:GATGGGGAGT ref:0:2:GCTAGAATACAATTTT 3 15 +CCTTATA ref:0:7:A ref:0:7:C 5 4 +GGCTGCGCTATAAA ref:0:14:AGGTGTTCTTTT ref:0:14:TTATC 6 964 +ATATGA ref:0:6:CGCGCGGACATACAA ref:0:6:GGGCGGCTAAAT 9 2484 +ACATGG ref:0:6:ATTATATTT ref:0:5:TCGGGTCACGAGCC 2 145 +AATGTAAG ref:0:8:GGTCGTTGT ref:1:7:CCATA 1 96 +CCT ref:0:3:GTGCAGAGTAAGT ref:0:3:CTGTTCTACACTGT 6 286 +GGGCTGG ref:0:7:G ref:0:7:ACCCGTGGAAGGA 2 30 +ACTG ref:0:4:GCGAGCGGGG ref:0:4:CCTCACACTTCTTAA 1 740 +GACCGAAT ref:0:8:CTTGGGGC ref:0:8:ATTATAGATTTATCAC 5 25500 +AGGG ref:0:4:CCAATCAATACAAGT ref:0:4:TTTAG 4 861 +CATTGTGTAAGA ref:0:12:GAGCCAACCCAGATCG ref:1:11:GG 5 366 +TACCGGGGTAAGGG ref:2:11:GAAAAGCATCGC ref:0:14:CCTG 3 222 +TCCTGCCGGATTTGAC ref:0:16:CCACG ref:0:15:AAA 11 1008 +TCATCCA ref:0:6:CGAGCGTTGG ref:0:7:AAT 3 155 +AAGGATC ref:2:5:GATCTTAGCGA ref:0:7:AACG 2 48 +TTCATTTGAGAG ref:0:12:GGTC ref:0:12:CGCAG 8 72 +TAGG ref:0:4:ACTAAATATGGGC ref:0:4:CGTCATTCGC 4 90 +AGCAGCCAACCTCG ref:0:14:CAGAAA ref:0:14:ATCCGATGT 6 561 +TAAGACCGGCCC ref:0:12:GTAGTGGAATTACCCC ref:0:12:TTGAATCTCTA 7 1272449 +TCACTTATGA ref:0:10:AGGCGG ref:0:10:GGCCCGTTTCGT 4 182 +TCCATGGTTTAGGC ref:0:14:GCCGCTGCGAGTACTG ref:0:14:TGTCCTCATA 8 130900 +AGTAAC ref:0:6:TCCCTGCTG ref:0:5: 4 106 +ACTGAAAGTTCT ref:0:12:C ref:0:11:GCAAAGGCCG 5 78 +AGCGCGAAC ref:0:8:CCTCGGGTTT ref:0:5:GTGAACGCTC 3 20520 +CCG ref:0:2:CAA ref:0:3:TGTT 1 12 +CTAAGTCGATTCG ref:0:13:TGTCCCCAGACCTT ref:0:12:TTTCAGGAGATACC 4 10100 +TACTTCGTCGG ref:0:11:TTAA ref:0:11:AGTA 8 576 +AATAGTGATAAGA ref:0:13:ATGTCCTA ref:0:13:TAATACGGCG 4 180 +TATCG ref:0:5:GCAGAG ref:1:4:AGGAAGATTGTG 4 1496 +CTGATCACTAATCA ref:0:14:A ref:0:14:GTCGAC 9 80 +TTGGTAGA ref:0:8:AACACATCTTGG ref:1:7:CCTCAGACAGAG 3 280 +G ref:0:1:TATGCCTCACTG ref:0:1:AACT 4 10 +CACGTTCGGG ref:0:10:CGGGTT ref:1:7:TAAATATGTA 3 260 +GTGACGATACGCCGC ref:0:15:CAGT ref:2:13:ATGC 8 160 +CGATAGCCTAAAGGG ref:0:15:GTA ref:0:15:GCATGGTATG 8 2700 +AGTACCTGCGTGTC ref:0:14:TGAGA ref:0:14:CGG 10 714 +ACGTTGAAT ref:0:9:GTCG ref:0:9:TCGACCCTAGC 5 1356 +TGCCACCCTATATG ref:0:14:AGTGCTTGCTT ref:2:12:A 7 1362 +CCCGCCCCG ref:0:9:AAGGCGGTGC ref:0:9:GT 7 32977 +ACGCA ref:0:5:CAATCCTGCAATTC ref:0:5:CAGTATGGCGACCG 4 256 +CGCTTGGCGGG ref:0:11:C ref:0:11:TTGCTAAAG 6 126 +GATCTAGACACA ref:0:12:AGCATCTCAAGA ref:0:12:GGAT 4 338 +GGCCGATAAAGC ref:0:12:TAGCGTTGGGGGT ref:0:12:CGT 7 12208 +CCGTAG ref:0:6:TCTGGGGGG ref:0:4:CTGAGAGCTT 4 13167 +CTCGCAGCCAG ref:0:11:AACTA ref:0:11:GAAGGTCCCGATTC 6 2592 +GGGAGTTATGGATA ref:0:14:CTCGG ref:0:14:CGGGGTACCTCATAC 4 324 +GTACGGCCGCATGGA ref:0:15:CTTGACCA ref:0:14:CTAGGGA 7 648 +GT ref:0:2:TTG ref:0:2:TGATCATAGGCA 2 8 +CCTAAACTTATT ref:0:12:TTAGGACCTACAGT ref:0:12:CTAGTT 5 175346 +TGGCCGGC ref:1:7:AGGTGTCTAC ref:0:8:GACCCCCCAG 2 54056 +GTTAGCTCCCGGAAA ref:0:15:TTGCCCC ref:0:15:GGGCCTCATCTG 6 222 +CCGTCAAGTCTG ref:0:12:AGAGATT ref:0:12:TGT 6 20 +TTGGCCTTTTAACC ref:0:14:CTTATAGGCCTT ref:0:14:TGTG 6 1944 +TTCCT ref:0:5:ACC ref:0:5:CCTAGCAAGGAGTCTA 2 24 +GTGCATACCA ref:0:10:GAGTCGTCT ref:0:10:TGCGCACAACTGTAAT 4 28200 +GGTACAA ref:0:7:ATGAGG ref:0:7:C 4 149 +CCGCCTGATGG ref:0:11:AGATA ref:0:11:GTCGCAACCTCT 5 1755 +TACGT ref:0:5:AACGGCGAAC ref:0:5:ATG 2 252 +AGCCCTCTCCCCCTCG ref:0:16:TGGGGTCTACT ref:0:16:CACCC 9 1046955 +GGACG ref:0:5:AAGAGACCA ref:0:5:CCACCTAGTCTC 2 60 +AAATTCCACAACGA ref:0:14:TTGGATTATAAAG ref:0:14:GCCCAGTTTGGTC 5 473184 +GTGTTCGGAAACAAA ref:0:15:CGCCCATA ref:0:15:AGCGTGTCGATCCTGC 8 1735804 +GGGTACAAGCGTTT ref:0:14:GGG ref:0:14:TGGTCTTTG 6 80 +TT ref:0:2:TCATCTTCG ref:0:2:CTCTTAGGG 4 18 +GTAGTCTTTAGCCTAT ref:1:15:CACTGGGGTTAT ref:0:16:TGGGTGGAC 8 3959968 +T ref:0:1:GTGT ref:0:1:CATTCCC 1 4 +TATACGGTTGACGAC ref:0:15:ATTT ref:0:15:CTCGG 8 35 +CACTGGCG ref:0:8:CAGAACACT ref:0:8:TTTTCTCGGGAC 3 4440 +AAGAGGGTCTCTTCGA ref:0:16:CATTAAGGGT ref:0:16:CATT 9 192 +ATGGGTCTCGATA ref:0:13:CACTCCATG ref:0:13:CG 6 36 +AGCGGTTCTCTG ref:0:12:CG ref:0:12:TTGTCTAGTA 6 10 +GTGAGAAAGTACC ref:0:13:TAC ref:0:13:ATGT 8 216 +TCAGCGCCA ref:0:9:GGTAACGCACTGG ref:0:9:ATCTATAA 3 672 +TAGTCCATGT ref:0:10:CAGTCAGC ref:0:10:T 4 32 +CAG ref:0:3:TGTGATCAATAGAG ref:0:3:CGCGTGGTGGCCCGA 5 616 +TGACGCACCGCAA ref:0:13:AATAGCCCCACT ref:0:13:GATTGAA 3 196 +ATATTATCTTTG ref:0:12:GACCCTAATT ref:0:12:CCGCACTTATCTTCGG 4 1080 +C ref:0:1:GTCGT ref:0:1:ATAACTTAGCGA 2 2 +CGTCGC ref:0:6:G ref:1:5:GGGTG 2 6 +ATCC ref:0:4:GCGCCT ref:0:4:GCTCTCTAT 4 48 +CGTTTCC ref:0:6:ATATCCTATTTCG ref:0:7:TCGCCGAACATATAA 3 3712 +CGGAA ref:1:4:ATTGTCCTTCCTT ref:0:5:AATTAAATCA 6 147096 +ACCGATGGC ref:0:8:TACCCG ref:0:9:CCACGTACAC 4 2976 +GCTTACATGCTTAC ref:0:14:GGCCCCGTCA ref:0:14:TG 7 2022 +ATACAGT ref:0:7:GTCCACATG ref:0:7:CCGA 3 68 +AACG ref:0:4:ACCGTCGAA ref:1:3:CCAGGTCTCCGCTG 4 112 +ACGTCCCTG ref:0:9:GGATACACCTTGCTAC ref:2:7:TC 1 30 +TGCTTCCGCTA ref:0:11:CCCG ref:0:11:ATCTCCAC 4 10 +TAGAAACGAAA ref:1:10:A ref:0:11:GAC 7 21 +TTAGTG ref:0:6:AGGGGG ref:1:5:CCTAGGTTGGGGAC 3 320 +TGTTCCCCGACTG ref:0:13:GTAATGTGGG ref:0:13:AACTCCTT 7 7968 +TAGTTTA ref:0:7:GCAA ref:0:7:C 6 136 +CGAATGATTGGTGC ref:0:14:AACCTCCTTAAGCCCC ref:0:14:GGAG 5 2766 +AA ref:0:2:GTGAGTAT ref:0:2:AGTGGATTACAAA 4 15 +TCGGAGCGAAGGG ref:1:12:CG ref:0:13:GTCTGTGG 8 4664 +TGCACCGCAAGTT ref:2:11:TCGCG ref:0:13:GGT 6 48 +GGCGA ref:0:5:CAT ref:0:5:ATTCTCGGCCC 1 10 +GGGCTTTCG ref:0:9:G ref:0:9:CTTATGG 4 12 +AACGTACAGGG ref:0:11:ATCGGATAA ref:0:11:CATCGCACA 5 48 +GTAGGAATG ref:0:9:TTAACGCTGG ref:0:9:T 4 372 +TTACAAAAAGAA ref:0:12:ATCAATCAAATTGGC ref:2:10:GGAT 3 1008 +ATACCTTCC ref:0:9:TCCCA ref:0:9:GCAAA 4 50 +GGCTAACGCTTTC ref:0:13:ACCCTGATTAG ref:2:11:CCCCCTCG 5 4896 +CACAGCTTTGCAAGT ref:0:15:GGAACACGTGC ref:0:15:CGCCCAATTATGTC 6 73062 +CTCACGCATT ref:0:10:C ref:0:10:TGATGCAT 4 32 +TACCC ref:0:5:CTC ref:0:5:TTCTTAGACCTAAT 2 469 +CATTTTCTTTAG ref:0:12:GATAACGGCCGC ref:1:11:AACGCTGCCCGGGGA 11 601039222 +TCATTGT ref:0:7:TGGGTGCGAA ref:0:7:CGATCACACCACA 6 328944 +GTGCGCTTTAGTA ref:3:10:TACGCAATCCTTG ref:0:13:TAATTC 5 563 +TGTAGCTTG ref:0:9:AAATGTCTGTGCCA ref:0:9:GATTTTCCGTA 4 23 +GCTAGAAAGCCC ref:0:12:TTCGTAACGTG ref:1:11:TGGTC 6 13680 +TGAAGAAGAGCGGTAT ref:0:16:CGGGCT ref:0:16:CCGCATG 11 3762 +TAGCGCGAGATAGTTA ref:0:15:CACCGGATTAG ref:0:16:A 6 20 +ACAAGTCT ref:0:8:TATGACGCGTT ref:0:8:CACTCACCGCC 4 3784 +AACCGCGCTCTGGAA ref:0:15:GTTGTAGATATCGG ref:0:15:CGGCC 4 4 +ACCAA ref:0:5:CTACGCAAAGCAGGC ref:0:5:TTACGG 3 96 +CATATGC ref:1:6:AACTTAAT ref:0:7:TGCGAGCTAAGCGTC 3 120 +TAGGCTTTAA ref:0:10:A ref:0:10:TTACCGGTACTCGGG 4 1434 +CTCAATCCAACAT ref:0:12:TTCTATTCAGTA ref:0:13:AAATAAGC 3 3780 +TTATTCCCG ref:0:9:TCATCTTATGAG ref:0:9:T 4 5072 +GCCTAAACACCTG ref:0:11:TATAA ref:0:13:TGTAAACGGGG 5 880 +TGGCAC ref:0:6:AAGCTCA ref:0:6:GCTAA 4 258 +ATCACTGGAGTA ref:0:12:ATGAAG ref:0:12:CTCGTACCCGCAGGC 5 9936 +CGTTGTCCC ref:0:9:TACTTTGAGATA ref:0:9:ACTCACGGCTCCTT 4 2848 +TATTGGGTCTACTAA ref:0:15:GTAG ref:0:15:GC 11 360 +TGCCAGTCA ref:0:9:ATCAAAACC ref:0:9:CGAGTC 3 1315 +T ref:0:1:TGTCTCT ref:0:1:TCATT 3 12 +GCTCGGGGGA ref:0:10:ACTGTCTGTCGTCGT ref:0:10:GTATCTGCATTCGACT 8 765033 +TC ref:0:2:ATATCACTACGTTCGT ref:0:2:TCGTTCTAAGTA 6 48 +TTACCTTGAAG ref:0:11:GTGAACTCTT ref:0:11:T 5 36 +GCGGGAC ref:0:7:TGCGACCCAAAT ref:0:7:T 3 72 +TAGCCTGAGTCCG ref:0:12:GGAT ref:0:13:ATCATAGGCCAT 4 138 +GTGC ref:0:4:ACGCGAAAGCGG ref:0:4:CAGCGTA 4 228 +AG ref:0:2:GCGCCGGGT ref:0:2:CATACACCAA 3 600 +AATACTCTCAGGAGAC ref:0:16:ACATCCA ref:0:16:GAA 8 72 +TTTACTTACCCAA ref:0:13:CCGCTTGTGTGT ref:0:13:TGTGCCTCTGACTC 6 324 +TAAGTCA ref:0:6:GGTCGTTACGGCGC ref:0:7:CACATATTTTTTC 2 52689 +GGTCAAC ref:0:7:CGGATTA ref:0:6:TTTCTA 2 240 +TTTTGCGTAG ref:0:10:CCGTCGG ref:0:10:GTGGGTCAT 4 8500 +AA ref:0:2:TGCCTGGGGGA ref:0:2:TACATCACCGGTCGAA 6 120 +TCCCGATTGCGTG ref:0:13:GAA ref:0:13:CACTACCTAGT 7 6534 +TCAAAGC ref:0:7:CAAGGTTAGGCGT ref:0:7:CG 1 2 +GGTAATACGGACTT ref:0:14:T ref:0:14:CCTAGAACTG 8 2988 +TA ref:0:2:GGGTCTGATTGGTGTT ref:0:2:AAG 1 6 +ACGAGCGTTGAATGTA ref:0:16:TCCG ref:0:16:TACACAGACG 10 174 +T ref:0:1:AATGACTTCGAAT ref:0:1:TGGGTCATCA 5 12 +TCGATGATCTGA ref:0:12:CCGACTAT ref:0:12:TC 5 72 +TACTGAATC ref:0:8:CTCCGCTG ref:0:9:C 4 44 +AG ref:2:0:CCT ref:0:2:TTGTTAGTCGCC 2 2 +CCCCGAG ref:0:7:ACGAGCCAGTTGATCC ref:0:7:CAAGCC 5 3175 +CGCTAGAATAAGATGA ref:0:16:TAAC ref:0:16:ATCC 13 16820 +C ref:0:1:GGACTCAGATGAAGAA ref:0:1:GCCAGGCC 5 8 +GTCTGATG ref:0:8:ACCAGGT ref:0:7:TA 4 308 +TGGAGTGATGGAGCG ref:0:15:GATAGTGGAAC ref:0:15:GAGCTCCGAC 6 1224 +GTGAGCCG ref:0:8:TAAACCATTCCGTGA ref:0:8:TGA 2 240 +CGTAACCCGCTCTGAA ref:1:15:GGGGGATTGAGGGTC ref:0:16:ACACTT 8 158270 +GGG ref:0:3:TCGTCACG ref:0:3:CAGGGCTGCGGTGA 3 315 +TTACTTTCCTGCG ref:0:12:AGATTGA ref:2:11:CAAGAGATAATTGA 8 69680 +AGATGCTT ref:0:8:AGCCA ref:2:6:AATGA 3 296 +ACGAGCATGTTTGT ref:0:14:G ref:0:14:GTGGGC 10 120 +GG ref:1:0:TATACATTCCC ref:0:2:GCGAACTCGATGCCCA 5 6 +AGGTTTA ref:1:6:CTGTTG ref:1:6:T 3 102 +CGATAGGCGCGTCAGG ref:0:16:T ref:0:16:TTT 14 34 +TAGGGCCTTTACAG ref:0:14:CATA ref:0:12:TTTACACATCG 7 966 +CA ref:1:1:TT ref:0:2:GACCGAATAGAC 1 24 +AACGATGATCGCC ref:0:13:GTCAT ref:0:13:TACCAGTAA 7 744 +GCCGATTGACGGGA ref:0:14:CTTGCTGATTTCAAA ref:0:13:TGTTCGAGC 6 32512 +GAG ref:0:3:GGGCTCCGCGG ref:0:3:G 1 158 +GGTT ref:0:4:C ref:0:4:TTGGAT 1 15 +CCCTGGTTACTGACCT ref:0:16:ACGTGGGTCAGC ref:0:16:A 8 1380 +T ref:0:1:TAGCCTGC ref:0:1:CGGTG 2 2 +AGCGAT ref:1:4:CCCAA ref:1:3: 2 26 +AGCTTATAAATGATTT ref:1:15:TTTGGGGTA ref:0:16:AGACGCATG 7 244025 +A ref:0:1:GC ref:0:1:GACGC 2 3 +ATAGCGTCCTCAGCGA ref:0:16:GACGAAAA ref:0:16:CGTGGG 8 5746 +TCGGGA ref:0:6:CTCTGTCGTTGTAGT ref:0:6:TTAATC 2 29 +TAATGTCAGTGTA ref:0:13:AAC ref:0:13:CATGTAAGGGCGACG 3 330 +TCGC ref:0:4:CACGCGG ref:0:4:GGTTACGACCAGACA 2 48 +GTTCAACCCGT ref:1:9:ACTGTGAGACTAGA ref:0:11:TGGCCCGATTT 4 3360 +AGGCCACTTTAGG ref:0:13:TCGCCAGTTG ref:0:13:GCTAGA 5 6804 +TTAGTCATGTGTG ref:0:13:ATTCAGTCCCTAT ref:0:13:TCATTGCGT 4 2250 +ATGGTG ref:0:6:TGACCGTTAC ref:0:6:CAGTGACAGGACGGGA 4 371 +AACTGTCG ref:0:8:GAGACTGCAT ref:0:8:CA 3 44 +TA ref:0:2:ACCCGT ref:0:2:ACCGTGGCTACAAT 4 12 +CTTTCCAACAA ref:0:11:TACTGTGTAG ref:0:11:GTGATTATAAATA 5 372 +G ref:0:1:GGGGCC ref:0:1:ATCACACT 2 36 +ATCTGCGTGAGT ref:0:12:CTGCACAATG ref:0:12:CATATTCT 4 2652 +GACCCGGTAAGGG ref:0:13:TT ref:0:13:CTAGTTA 10 4116 +GG ref:0:2:TAGAAACGATAATTGT ref:0:2:T 1 9 +AGCAGCCCCAC ref:1:10:TGGTAAACCGGCA ref:0:11:GAATGGGATT 6 79560 +TAACG ref:0:4: ref:1:4:AGGTTA 2 8 +AGGTGACGCCCTG ref:0:13:CA ref:0:13:GAA 11 858 +TGTCTTTCGTACCCAG ref:0:16:ACGATA ref:0:16:CTTACAGA 8 1296 +CGT ref:0:3:TCGGTGC ref:0:3:CACGCTG 1 4 +TGCCCC ref:0:6:AGGCGACATG ref:0:6:AATT 4 1386 +CGGCAGGCAGGA ref:0:12:CAACGTGC ref:0:12:TGC 8 897 +CGGGGAACGTTG ref:0:12:G ref:0:12:A 10 12 +GATACTC ref:4:3:TCC ref:0:7:CTAAT 1 36 +GATAACATCTTCTG ref:1:13:TCCCACACCCGG ref:0:14:TAAACGGAAT 6 14523 +CA ref:0:2:TTCACGTTACAATC ref:0:2:GACTTCGCTGC 6 198 +GAGAGC ref:0:6:GGAGACGGAGACTCA ref:0:6:GT 1 432 +CTCCT ref:0:5:ATTAGGAGGTGCTACG ref:0:5:AT 3 833 +CTGGGACACCTCG ref:0:13:AAT ref:0:13:GATCAA 8 39 +CCCTT ref:0:5:CGGAGACAAATGTGCA ref:0:5:GAGA 5 1386 +TCATCGATCCCCG ref:0:13:TTTGACCCGT ref:1:12:GCTACGGGTAGT 4 1728 +AACGACTTCA ref:0:10:T ref:0:10:CCACAGGACAACCAT 2 436 +ACTAGTAGCCCTATTT ref:2:14:ATCGACGCGCACTG ref:0:16:GTCGGGAT 8 137016 +AGACCTAACAC ref:3:8:TATGTGCTT ref:0:11:CTAGACTGCCA 4 2175 +ATTGGCGACTTG ref:1:11:GTAAAGGA ref:0:9:GCA 3 62 +CTTAA ref:0:5:CACAGTACGACAATCT ref:0:5:TCA 2 820 +ACGAG ref:0:5:A ref:1:4:GGCCTGAC 1 8 +AGTAACATAATCGT ref:0:14:CATGTCA ref:0:14:ACATGATGGTAACA 8 432 +TGCCAAC ref:0:7:ACCCAATTGCGGCAG ref:0:7:AAAACGCTCTCTAT 5 5950 +AACAG ref:3:2:AATAGCTTCTGTC ref:0:5:GGTAGGGGAAAATC 4 366 +CGATGGATCGTCGG ref:0:14:TGAACG ref:0:14:GACGAAAAGTT 7 52155 +ACCA ref:1:3:CGTATAGTTTT ref:0:4:TGTCTGAGAGATTCGG 6 1810 +CTCAC ref:0:5:GCAAAAGGTGGTGC ref:0:5:TATACGAATCGTGAA 5 572 +CCACTCGGAGTCAC ref:0:14:GCGTACCCT ref:0:14:AAGGCAGCTTC 7 45612 +GTA ref:0:3:ACGCACAAGAAA ref:1:2:CTAGGTCCCGGGTC 3 41 +TAT ref:0:3:AG ref:0:3:CCTTCTG 1 12 +TCGGAAT ref:1:6:GGAAA ref:0:7:GTAACGGA 1 8 +GTGGCTT ref:0:7:CATATGTGAGATGCC ref:0:7:AT 3 345 +CTGTATCAGT ref:0:10:AGAGTGG ref:0:10:ACCTCA 4 312 +GTG ref:0:2:AGTTTTTA ref:0:2:CGTT 1 10 +CCCGTCTGTTGCGCT ref:0:15:CGG ref:0:15:ACAGTTGGG 8 210 +AGCGGCGAA ref:0:9:GTG ref:0:9:AATCGTTTTTAAATC 4 22480 +CTGTTTTCA ref:0:7:TGCTCATTTG ref:0:7:GTT 1 6 +TGCAACGACTA ref:1:10:CCGC ref:0:11:GTCT 5 17 +C ref:0:1:CATGCAGCAGTGCGT ref:0:1:GCTCATCT 6 12 +CCTAG ref:0:5:GTTCACGGAACATAGA ref:0:5:ATCGACCA 3 12 +GAAAAGTGCCAC ref:0:12:C ref:0:12:ACTAGTCAACTACATT 4 45 +CGCCCG ref:0:6:GGTGTATTCAAA ref:0:6:GAACCTGGT 4 15431 +G ref:0:1:ATCGCTACGCGTT ref:0:1:CATGACACTAGGCT 8 9 +A ref:0:1:AATTAACCGCAACCAC ref:0:1:CTCCCGCAG 5 7 +CGAACCAT ref:0:8:TTCAAGACTCCGCGA ref:0:8:AACATG 1 86 +CCAGTGAGCTT ref:0:11:CTGCTGTG ref:0:11:GTGAAGCTCG 3 32 +ATGACTTTGCCTT ref:0:13:TAGGACCTTGTCT ref:0:13:AC 4 1710 +TGTTGC ref:0:6:CGACGGTACGG ref:0:5: 3 337 +A ref:0:1:AGCCA ref:1:0:TGT 1 2 +GGG ref:0:3:GCA ref:0:3:CTGTGC 2 70 +CCTGAGAGCCAT ref:0:12:TCTTGCCAGTGGCCA ref:0:12:CACCC 3 1218 +CTCTACCTTTG ref:0:11:AAAGTTTGGTATA ref:0:11:CCT 4 3420 +GGTCGCTTGCTCTGT ref:1:14:AGACCGTGGG ref:0:15:TTTCC 4 177 +GCACGG ref:0:6:ACTAGCG ref:0:6:TC 3 42 +GCTAAGGAAGAG ref:0:12:TGCCAAATAGTTGTT ref:1:10:TAGCCCGGC 1 36 +ACAA ref:0:4:GCTCCCCAACGGG ref:0:4:GGCCCA 4 816 +AT ref:0:2:TATAGG ref:0:2:GCCAATCACTT 1 8 +CATAATTATTTGGAAT ref:0:16:ACGGAATAGCGGAC ref:0:16:GACATAAAAGCGAAGG 7 40176 +CGTG ref:0:4:GTCAAGTTA ref:0:4:A 2 30 +ACACGCGTTGTGATG ref:0:15:GAGC ref:0:15:GCACGCGGCCATT 7 400 +CAAATCTATAC ref:0:10:ATCGGCGGAAG ref:0:11:GCGATGCATGA 4 162 +AC ref:0:2:AAGCTTCA ref:0:2:CAATTCGA 4 8 +AAAC ref:0:4:CGTTCGGGACGCTATA ref:0:4:T 2 5 +CTCATCAGGCGG ref:0:12:ATATTCTGTTCGTAT ref:0:12:CGAAACAA 5 81000 +CCGGAAGTAAG ref:0:11:TGAGGTTTGA ref:0:11:GGCGCTCCGCGCA 7 431376 +ACTCTATT ref:0:8:GCGGACACCTAAC ref:0:8:GGAGGACTAATTTGTG 5 14994 +TTCAATGTGCT ref:0:11:CCTGC ref:0:11:ACA 6 220 +GCTTCCCATCTATCT ref:0:15:GGTT ref:0:15:TATTAAC 8 558 +GAGTCTCGTCAGTCG ref:0:13:CCA ref:0:13:TAGCA 8 42 +ATGAT ref:0:5:TGGCC ref:0:5:CC 5 336 +GTGGGCCTGGTA ref:0:12:GAACG ref:0:12:CCCGATCCAAGT 7 1170 +TCAAGACGCCG ref:0:11:GCGTGTCTCTGATG ref:0:11:GCGACC 5 112 +T ref:0:1:CAATGTTTAACACG ref:0:1:ATTGCTACCTGA 7 16 +CGTCGAAA ref:0:8:ATTCTCTGGTG ref:0:8:ACTGGCTAAGTC 6 3395 +GGCCTAG ref:0:7:ACATGGGGGAGGTA ref:1:6:TGTCTAT 2 1848 +AACTGATT ref:0:8:GATAC ref:0:8:TTTGCACTAAT 4 896 +ACGATCCAGCGTCCTC ref:0:16:CGTACGCAGAGC ref:0:16:TG 7 24 +ACTATTTCCCAC ref:0:12:GAGTAATGCAA ref:0:12:TAG 7 9588 +CTGATGCACAT ref:0:11:CCTGATG ref:0:11:ATGGATTTACGTCC 3 184 +CAT ref:0:3:GATTTT ref:0:3:ATTACGCATCT 2 32 +A ref:0:1:AACTGCCGCGTAATTC ref:0:1:ATGCCGCGTCAGGC 10 8 +AGCATAG ref:0:7:TTCTATGCATCGTCG ref:0:7:GTCTGAGACGTCACTT 6 369 +CTTGACATGC ref:0:10:TAAA ref:0:10:GCTTCGCACCA 3 119 +GTTGAACTG ref:0:9:CTCATACA ref:0:8:A 4 100 +CACACATAAAAT ref:0:12:CCGCGTGACTAGTC ref:0:12:GGTGACCGACTAAA 4 12288 +AGTCCTCC ref:0:8:CCA ref:0:8:CT 5 22 +GGTAGAT ref:0:7:GCCCTGCACTTTCCA ref:0:7:G 2 45 +TTGTAATACGAG ref:0:12:TCATAAC ref:0:12:CTT 7 1254 +ACC ref:0:3:TTCCGATTGTT ref:0:3:TA 1 3 +TATGA ref:0:4:GAGT ref:0:5:TGCTATATCGTCATA 2 56 +TGCCTAA ref:0:7:ATG ref:0:7:CTGA 4 8 +CGTGTATGAAA ref:0:11:ACCGCTCCC ref:0:11:AAAAGGC 5 1940 +CTGTACCGGCACTCAG ref:1:15:GTTT ref:0:16:GGCTTGAATCATA 8 2490 +TCTATGTCGCCGAA ref:0:14:CA ref:0:14:TGGGTCATTTTAAAC 7 14544 +G ref:0:1:TTTCAGCGGTCC ref:0:0:AA 1 3 +CACGAATA ref:0:8:TAGGACA ref:0:8:GGCGAAGTTTC 3 2520 +AGTTGCAATTG ref:0:11:CACCCCCACGGTGC ref:0:11:GGAA 4 2833 +AATAATCCGTGCA ref:0:13:CGAGGCTATGTC ref:0:13:CTG 4 28 +CGTTAAAAC ref:1:8:GAGCTACCTCAATCT ref:0:8:CCATCAGCATCAG 5 19570 +CCGTTGTTCAAGTAC ref:2:13:ATCGAGCG ref:0:15:ACC 9 2262 +CACG ref:0:4:TAC ref:0:3:GTGTTGAGCC 2 30 +TTTTCGAGGCGAGG ref:0:14:TGCGG ref:0:14:GCCTGCTCTGCCTATG 6 229392 +AGACGCAGAACA ref:0:12:GAGGCAC ref:0:12:GCCCGTCTCGGATA 3 6528 +ACTG ref:0:4:GTATCGGTGTCTAC ref:0:4:TCTCTGTCAGCCCATC 6 28 +A ref:0:1:CCGTATGGTATTGGGC ref:0:1:TCCAGAACATAGATGA 8 14 +AGAATCGCGGTTGCCC ref:0:16:TCGCATCTATGG ref:0:16:TATACCGG 8 8400 +GACGACCTTAAGGAG ref:0:15:TGCGTCCG ref:0:15:TAGCGACAG 8 252 +CGGAAGT ref:0:7:GTGTAGAGCAATGGG ref:0:7:GATCGCCGACTTC 1 14 +CAGCTGTGAAGC ref:1:10:CTA ref:0:12:ACGCAATGATG 4 220 +TCATCA ref:0:6:CCGGCCTGTTT ref:0:6:C 4 3214 +GTTGAACATTGCCCAT ref:0:16:TTGAGCTGATCA ref:0:16:CTAAA 7 1860 +CAAAATTCA ref:0:9:ATCCAC ref:0:9:AC 5 80 +ACCTGAACTAGG ref:0:12:CTTTCCATACG ref:0:12:TTTTACTCTAGGTA 5 1788 +GCGCATT ref:0:7:AGCT ref:0:7:TAATAA 4 860 +TGGCGTATAAGT ref:0:12:CAATTTAATA ref:0:12:ACGGTACTTGATTGAG 4 3536 +GGGTTATATCT ref:0:11:ACGGCTCTGTGAT ref:0:11:A 4 48 +AAATTTA ref:0:7:GCGCCG ref:0:7:TATCCTT 5 10296 +TGCAT ref:2:3:ATCAAA ref:0:5:TCATCTTGTGCGTA 2 224 +GCAGAAG ref:0:7:GAA ref:0:7:C 3 4 +GTTAAAGTGACCCCGG ref:0:16:ACCG ref:1:15:GCTGCCTGTTA 8 2688 +TAT ref:0:3:C ref:0:3:GG 3 40 +TGTCA ref:0:5:CTTGTGGAA ref:0:5:GGG 3 294 +TGTCA ref:0:5:ATGAAACTTAGGAGAA ref:0:5:CCGAT 2 616 +TCACT ref:0:5:CC ref:1:4:AACCGAA 2 39 +GTAACGTACAGAAC ref:0:14:CGCCTTAGGTGG ref:0:14:GA 8 1632 +TTGGTCCC ref:0:8:GGGACATTAAGGGCTG ref:0:8:CTTAATATTACCATGG 6 30951 +CGCTTCCA ref:0:8:C ref:0:8:AGGG 6 328 +CATAATTTAGCA ref:0:11:CGCGACTCG ref:0:12:GGCCCACGCCTAG 8 2176450 +TTAAGTGGGACCGTC ref:0:15:T ref:0:15:ACTGGGCG 8 40 +CACAAGTTCGACAAC ref:0:15:TTACG ref:0:15:ACGGGATATGACTA 6 408 +GTTACGAACCCGGGC ref:0:15:CACCTACCTTAG ref:1:14:TACGT 7 771400 +CTCGGA ref:0:6:ATCTAAGACATCCCTA ref:1:5:TTACACAG 5 6176 +TACGGGGGTC ref:0:10:GGTACAAGA ref:0:10:G 6 750 +TGCA ref:0:4:GTTTGGGAAA ref:0:4:GAGTCCTCCCAAA 4 10692 +CATGGTCCTTACC ref:0:13:TACAGGCAGT ref:0:13:AGAT 8 725 +TGTCTCT ref:0:7:ACAATCG ref:0:7:ACCTGTA 5 360 +GTGATAC ref:0:7:AACCGCTACCGATGG ref:1:6:CCGTCG 4 18 +ACAAG ref:0:5:TGG ref:0:5:GTC 4 80 +CCATGTCA ref:0:8:GGATGTTAGTCTT ref:0:8:GAGTGCAGCTGGCT 7 12096 +AC ref:0:2:G ref:0:2:TAGTTGG 2 18 +TACGCTGGAT ref:0:10:TG ref:0:10:AATC 5 5 +CAAGGAT ref:0:7:GCAGTCGCTGTG ref:0:7:TGC 4 627 +TATCCACC ref:0:8:CTATATATCA ref:0:8:GTGAGTTAG 4 864 +AAG ref:0:2:CCT ref:0:2:GGTTTAT 2 80 +TCTATAAAATGC ref:0:10:GTA ref:0:12:T 8 160 +CGT ref:0:3:GCCCTAGGC ref:0:3:TTAG 3 176 +CTCTGAATTT ref:0:10:CGA ref:0:10:ACACCCTTGGTT 3 1612 +AGAGTGT ref:2:5:CAG ref:0:7:GCAGGACGTGCAG 1 20 +TATCATCTGT ref:0:10:AACTATGA ref:0:10:CACTCG 4 216 +AATTGTAAGT ref:0:10:TTCCCT ref:0:10:TTGTAATGATTAGGAT 2 5500 +AATGA ref:0:5:CCGTAATCTAGCTC ref:0:5:CAAAGCAAGGCATTCG 6 1248 +GGTGG ref:0:5:AAAACGCTGGAAGAT ref:0:5:ACGGGCGCTGGGCG 4 900 +ATAACAATTCC ref:0:11:GACACTCG ref:0:11:CCTACG 8 58368 +TGTTGAGGCCCATA ref:0:14:CCG ref:0:14:GTGCCGTGCTT 8 1482 +CTACCCGTACTTG ref:0:13:CT ref:0:12:GGAC 8 135 +T ref:0:1:TTTGGATTAGACCGA ref:0:1:TGCCTCAGCAG 6 10 +TGAACA ref:0:5:ACCTAAT ref:1:5:AAAAGCCGCT 2 232 +CC ref:0:2:T ref:0:2:CGTGGCTGCGCTAGA 1 18 +TCG ref:0:3:TGTC ref:0:3:TATGCGGCTTAG 1 24 +TGTTGAGGA ref:0:9:CCTCCGCACCTATTG ref:0:8:GGCGATGTCGT 4 494 +GTGA ref:0:4:ATGTTCCCTT ref:0:4:TTTGTCCCGATATC 6 138 +CAAC ref:1:3:CT ref:0:4:A 1 2 +CTCTAGTTA ref:0:9:ATGACCCTTC ref:0:9:TCAACA 4 4142 +A ref:0:1:GTAGACCTCACA ref:0:1:GATGATGTCTGT 5 8 +CAAC ref:0:4:GAGTGCGTTCT ref:0:4:GGAACAAGTTT 6 320 +AACATTTTTACTCGA ref:0:15:CCTC ref:0:15:GCGCCGGCATTTCCGC 6 1280 +GCCACATACCGCTGG ref:1:14:ACGAACCAA ref:1:14:TATTG 5 1189 +TTTCGTCTTACTA ref:0:13:GCTGAGTTTCAACTAA ref:0:12:GATTA 5 1320 +CTGGTT ref:0:6:TGGGA ref:0:6:TTA 3 48 +TTTCGCAGCCAGGA ref:0:14:TACCGCGTACG ref:0:14:GGATAAGT 8 406002 +ACAGACCCTG ref:1:9:TTTCGACCCGCCC ref:0:10:AT 1 3 +GAC ref:0:3:ATGTAGTTATTT ref:0:3:GCGCCCAGCA 2 32 +CGTCGCAAGC ref:0:10:TCTA ref:0:10:TTAGCTGTTTG 6 7596 +GATGAT ref:0:6:AGGAAAA ref:0:6:CTA 2 246 +CCAATGCACC ref:0:10:TGTTGTTGCGGCGAT ref:0:10:AATAAAGTT 6 1965822 +CTA ref:0:3:GGCTCTACCATTCGGC ref:0:3:GGAT 3 60 +TAGTGTTTTGCTCA ref:0:14:T ref:0:14:GTAC 11 735 +TTGTAGTTAGTCAC ref:0:14:CAGGTCGA ref:0:14:GCCTTCGGC 7 2085 +CTCCAGGCGCCCTGA ref:0:14:GACCCGCTTACC ref:0:15:GAATCGAC 9 91509 +TACCT ref:1:4:CGCGTGG ref:0:5:AACGCA 1 6 +TCTAAGTGCCCTCG ref:0:14:GGTT ref:0:14:CCGTCCTA 8 756 +GGAGACAG ref:0:8:TATTTATCC ref:0:8:GAATGAGGCT 4 3216 +CAACGTAGACG ref:0:11:AGGGACCCA ref:1:10:CTCACCA 5 3159 +CGAGTAGTACCTAA ref:1:13:AGTGACGCCAGTTA ref:0:14:GAGTCGTG 4 1625 +GTACCTCTAGACCCT ref:0:15:ATCCGTATCGAC ref:0:15:TTTCAGCGCCTA 4 960 +GAC ref:0:3:GCCTTGGGC ref:0:3:TGTAGGTGGGCT 5 17 +CGCTATAATT ref:1:9:CTCAACTAGC ref:0:10:T 4 316 +GAGCT ref:0:5:TAGTCA ref:0:5:TAAC 3 42 +A ref:0:1:AAGCAAGTAAGAT ref:0:1:CCAAAC 3 21 +CTAAGCTGATTACTTC ref:0:15:TCGCT ref:0:16:TAACGGTCA 8 180 +CAGAC ref:0:5:A ref:0:5:C 3 4 +CACCTGTAGGCGGC ref:0:14:GGCT ref:0:14:AG 10 198 +CGCGGGATGCTCCC ref:0:14:TGTCTTAGTTTATA ref:0:14:AGCCGCCTCAACATGT 8 48777352 +TGGAGTGGCCAAAC ref:0:14:CGAGGTGCGTCG ref:0:14:GGCCCT 6 11340 +ATTGTGCAGGAC ref:0:12:TAGTTAGTACCAGTTA ref:1:11:TCTATCGAATCGCTA 5 3700 +AGTCCCGG ref:1:7: ref:0:8:ATATGACT 5 355 +AGCTAAAAAGCCTT ref:0:14:CCCCGAGTTGTCC ref:0:14:CA 6 40 +C ref:0:1:A ref:0:1:ATGCCTTGCTTTAGT 1 6 +GTTGA ref:1:4:CG ref:0:5:CAAAC 3 165 +CCGGAGAAGA ref:0:10:TATGT ref:0:10:CGGT 7 5014 +CTTCTG ref:0:6:TAATCTGTG ref:0:6:T 1 9 +ACTGATGTCAA ref:0:11:TCAAC ref:0:11:CA 7 15 +AGGAGTA ref:0:7:CTG ref:0:7:CGTATTCT 5 3888 +G ref:0:1:ACGGCGCCTCTGGACT ref:0:1:ATCAGTCTGAGGTCA 8 20 +CCGA ref:0:4:CGTAG ref:0:4:GTAGACCACGC 1 14 +TTG ref:0:3:ATCTA ref:0:3:GTCGA 2 8 +CGAT ref:0:4:GTTACGTT ref:0:4:GTTTGCCGCATCGCT 4 20 +AACGTTAAGCTCG ref:0:9:TGAAA ref:0:12:AGCCACT 5 2881 +CTGTTCT ref:0:5:AAGGTCAGGCTTA ref:0:7:AGCC 3 240 +ACATTGTTGGTATC ref:0:14:GATAGCTGGAAGA ref:0:14:GGG 7 1206 +TAAAGCAAGGGA ref:0:12:GAATGCCATG ref:0:12:TCCCTCCTCCGGCT 7 22577616 +TAATAATTCCGGGT ref:0:14:TCTGAGAGATTCGTA ref:0:14:TACCTGGGTTATATGC 3 5328 +CAGCCTA ref:0:7:G ref:0:7:TCG 5 1 +CCTACAACATC ref:0:11:T ref:0:11:TTGTAGAGAG 7 1744 +GTT ref:0:3:ATTAGTGTTCCTT ref:0:3:ACAATTGAAAA 2 80 +ATC ref:0:3:CACACCGAA ref:0:3:TTTTGTG 1 682 +AG ref:0:2:CAAAATGCTC ref:0:2:ACCCACAAATC 6 120 +CTCCGCGACT ref:0:10:TGATGTTATGCA ref:0:10:A 5 9 +AGAGTCCACTGCGAA ref:2:13:AAGACCGGGCC ref:0:15:AGTCACG 5 27792 +CTGTAG ref:0:6:TCTCTTGTAGCC ref:0:6:CACCGTAAC 2 175 +AGGATGGTGTGA ref:0:11:CCTTTCT ref:0:12:CGGATATT 6 1500 +CATCAAGCCCAG ref:0:11:TTTCAATCATT ref:0:12:CGCTTACGGCCCCGAA 2 286110 +TGTACTCAG ref:0:9:C ref:0:9:CCGCA 6 42 +GCTTGCGACAG ref:0:11:TAGT ref:0:11:CCGAAGA 4 4 +GAAATT ref:0:6:CATATCA ref:1:3:ATTCTTTCAGCG 3 611 +TTCCAT ref:0:6:GGGTAAGTTGTTTA ref:0:6:CAGAGAA 5 16168 +GACCGTTG ref:0:8:CGTGTAACAACGT ref:0:8:AGGTCCTACAACTA 6 176 +TCCATCCT ref:0:8:GACTTAGCACCCTA ref:0:8:CAGTTTAG 2 500 +GCTGCTAACC ref:0:10:TA ref:0:10:CTCGCAGGCT 4 68 +ACATTCCT ref:0:8:TAGGGCTGGTCG ref:3:4:TTTTGAATCGCG 2 50 +CTGCAT ref:0:6:CGCCTGATTA ref:1:5:G 1 10 +CAGTCCGCGAT ref:0:11:ATTTTGC ref:0:11:TCTGCCAGAC 5 2065 +GAAGA ref:0:5:TGCCAGACCAA ref:0:5:A 1 66 +TCA ref:0:3:GGATTAAATGTT ref:0:2:AATTTACGCC 3 135 +TAGTGCGGCGCG ref:0:12:GCGTCAGGA ref:0:12:CTGCGCCAACGAT 6 720 +T ref:0:1:CGTAATGCCGGACCC ref:0:1:GCATTCTCT 4 8 +ACCGACTCGTACAC ref:0:14:CCAGTAGGAAAGGCT ref:0:14:GCTTTGGACCCC 5 40896 +CAAACAACCAGC ref:0:12:ACGGTCGTCGTCA ref:1:11:TTGAAGGAAGATAAT 3 1980 +ATCATACCGTATTC ref:0:14:CA ref:0:14:GATAGCCGGTCCTTA 4 540 +CCTATC ref:0:6:CAAGA ref:0:6:TA 3 64 +TCAC ref:0:4:AGACTTCTTCCAGT ref:0:4:ATGCCGCTA 4 432 +CGG ref:0:3:GGTTCCTGGGCC ref:0:3:ACAAGCGAGGAG 2 96 +CCAGGCT ref:0:7:GCGGTATC ref:0:6: 3 15 +CTGTCCCAAAGATAC ref:0:15:TGAGTAATTACCC ref:0:15:GTCCATA 5 2304 +AT ref:0:2:CCTTGGGTACATAACG ref:1:1:GGCTCTAACGG 5 4 +CATGAGC ref:0:7:ATGCTCGCCCTTA ref:0:7:CCAGTTTGTTGCACTA 5 624 +TGCGCTACACATGCAG ref:0:15:AGAAGCTACATAAC ref:0:16:TACAATACGCGAT 5 1440 +ATGGAACACGG ref:0:11:GGACATTGCAAA ref:0:11:GATTCATGCA 8 20566 +ACGTGC ref:1:3:TTAAAA ref:0:6:CAT 2 12 +A ref:0:1:ACGTCGCTCA ref:0:1:AATCTGTATCGGG 5 6 +CGCATGAGATATCAGT ref:0:16:ACC ref:0:16:TCGACTGA 10 588 +ACGCA ref:0:4:GAGACGTGTG ref:0:5:CCATGACTCCTAAG 4 1026 +AGATTAG ref:0:7:AC ref:0:7:ATTATCCAACAAAGG 3 3948 +G ref:0:1:ACACGCCGCCGGCG ref:0:1:AAA 2 20 +ATTCCC ref:0:6:TG ref:0:6:AGAATGATT 4 171 +TGATGTGCTCACGTG ref:0:14:GCTGGGGAGCTGAG ref:0:15:GGCCAACAGTTT 3 7272 +GTGTTAGG ref:0:8:ATGATACCTA ref:0:8:AGCGCCACA 5 206 +CTG ref:0:3:AGAAT ref:0:3:TGATAGTGGTTG 4 504 +CCTAAAGCCC ref:0:10:TTTCGGATACTCTG ref:0:10:G 4 1122 +CAAATACCGA ref:0:10:GCG ref:0:10:GAACCTG 6 256 +CTTATCGGTATATGA ref:0:15:CCCG ref:1:14:TGATGCTACCAG 7 1044 +AGATGT ref:0:4:CACGGGTTAATA ref:0:6:ATACC 1 252 +GG ref:0:2:TATCCA ref:0:2:AATGTAAGAATC 4 28 +CGGCAGGGCAAGC ref:0:13:AGCACTGAT ref:0:13:CTCAG 7 22484 +TGAACCTAAGTCTGA ref:0:15:AGACGCAGTTC ref:0:15:TGTCATG 5 1900 +GCCCAC ref:0:6:CCCTCGCGTTAG ref:0:6:GGCGAG 4 1408 +CACGTCGGTCGAAGA ref:0:15:A ref:0:15:ACTATTCACCCTTGG 8 9436 +GGCCAAGCAGCGCC ref:0:14:TACCTAATTGCGCAG ref:0:14:TTCTGC 7 8556 +AGGTTAGGAG ref:1:9:TCGATGCA ref:0:10:TTCCCTCAC 7 17108 +TGTGGTCCTT ref:0:10:CACAAATAA ref:0:10:ATGTTCTCC 3 154 +GAATTGGGGCCCGCA ref:0:15:AAAATAACAAGGTTC ref:0:15:AATAGACCGTCAT 9 11607540 +AGT ref:0:3:TA ref:0:3:CTCTC 2 26 +T ref:0:1:CCACTCCTCTGG ref:0:1:CGTC 2 3 +TTCGGAGGTCGTTT ref:0:14:CACCAGTCTTTTTCTA ref:0:14:CCTGTCGTATGCACAA 8 6855030 +T ref:0:1:TATGGTTCTGTTTTA ref:0:1:CCCTCGCCCC 2 9 +TGTGGGT ref:0:7:GCGAAGTGCTTAGATA ref:0:7:GTCTTGACATT 6 53019 +TGGCTGTATCTTA ref:0:13:GAAATAC ref:1:12:CGC 7 397 +GCACCGC ref:0:7:TAAGGAGACGACCGGG ref:0:7:AAT 2 540 +CCAGTG ref:0:6:CTAGTCAC ref:0:6:GGCTGTGGCATA 4 240 +GAGCG ref:0:5:GCCGGCTTTTTGG ref:0:5:TCTCGGTGAG 5 352 +CCCCCTTGTCCGC ref:0:13:CCTGTCAGTTTTCACA ref:0:13:CCATGCTGT 6 1223320 +CCTCAGTGCT ref:0:10:TAATTTCTAAAGAT ref:0:10:TGGATGTAAA 7 16555 +GACTCCGAGGGATA ref:0:14:TCCGCATATAC ref:0:14:TGATG 6 80 +TCGACATGACAGAGAT ref:0:15:CAGCGCTTCTG ref:0:16:CTACGCATTT 10 89804 +TCGCTGGGCAATGTT ref:0:15:GAATGACAG ref:0:15:TTAGCAGGGGAAAA 6 88740 +ATACGCAGCTATGAG ref:0:15:AAGATTTAGCAAACGT ref:0:15:T 6 279 +CAAAGTGCTAGAG ref:0:13:GGCTCCACAATCAGCT ref:0:13:A 5 135 +TTGTGC ref:0:6:GAAATTTCCATGTA ref:0:6:T 2 189 +GCTGTATAACACTG ref:0:14:ATGTCCACA ref:0:14:AC 8 1071 +TAACAATCGCTCGA ref:0:14:GGGATCTG ref:0:14:TTCATATTTG 6 5880 +CATTAT ref:0:6:TGTG ref:0:6:GTTAGCGCGG 4 168 +CCGTTGGAT ref:0:9:ATCCGCGC ref:0:9:TCCGTGACGTG 4 162 +TGCCTTCTAGGTA ref:0:12:AGGTTGGGGGTGGG ref:0:13:GGTATGGAATACT 7 59874 +CTAA ref:0:4:CGTCACTGATGTCA ref:0:4:ACCCTGCT 4 204 +ACTGATTGGTC ref:0:11:GATATCGGCTGATGCG ref:0:11:TTCTTCAAT 4 45 +CGTTAATCA ref:0:9:AAGTTCTCGCTGG ref:0:9:TCCT 6 5580 +TTATGTAACAGGT ref:0:13:AC ref:0:13:GATCAGCGCCCG 7 375 +TACCGCCA ref:0:8:G ref:1:7:A 5 2 +GTGTA ref:0:5:CGGTCAAGGTC ref:0:5:TG 1 10 +CTAAGTCCCATGTTGT ref:0:16:TAGAATTCCCAGA ref:0:16:AGGGGGCGAG 7 227325 +AACGCCCCCTATACGC ref:0:16:CGCCTTACAGCTGATA ref:0:16:GACTTTGAAGGCC 7 127440 +AGTAATTGA ref:0:9:TCCTGG ref:0:9:TCT 7 456 +AGT ref:0:3:CACATG ref:0:1:GTTCACCTTAA 3 18 +GTCTAATATAGAT ref:0:13:C ref:0:13:TTATACG 6 13 +A ref:0:1:C ref:0:1:TATC 1 2 +TGCTTCATAAAC ref:0:12:ATCGGTGCCG ref:0:12:CT 7 60 +CCTC ref:0:4:TAGTGAAAGTTAGGCT ref:0:4:G 3 740 +TC ref:0:2:CCCGCTTTCCAGC ref:0:2:CC 1 27 +GAGCTTCG ref:0:7:TGGCAGTA ref:2:6:GGCTTCGTCG 1 190 +G ref:0:1:AAAGGA ref:0:1:TTCTCACGGAACT 3 4 +CGGCT ref:3:2:CCACCATG ref:0:5:GAATA 2 36 +AG ref:0:2:CTATCCGACCAGTT ref:0:2:TTGTTAAA 4 36 +TTCA ref:0:4:AGGTCC ref:0:4:TTCTTGAAGCGTCCA 4 464 +A ref:0:1:AATCTGCTCATGGCC ref:0:1:TGGGGTT 4 24 +TGGA ref:0:4:GTCCTTATTAGTACAC ref:0:4:AGTCCCACGGAATATC 6 246 +GGTAT ref:0:5:TCGAG ref:0:5:T 3 22 +TCTGCATAGGAACA ref:0:14:CC ref:0:14:GAGAGACAATCAG 5 66 +TC ref:0:2:G ref:0:2:ACACCTTGCTAG 1 6 +TTCGGGGGGCCATAG ref:0:15:TAAGATCAC ref:0:14:CTCCCTAGTCAA 7 2388 +AA ref:0:2:CAGACTTTTCG ref:0:2:CGCTGGAAGCGTG 4 1 +GGTGCGC ref:0:6:GACA ref:0:7:TTTGTATGCTT 3 2576 +A ref:0:0:CTT ref:0:1:CAGTGATC 2 2 +TGGTCCATACACAAG ref:0:14:TC ref:0:15:TTGTT 9 50 +ATG ref:0:3:CGTAAGTCCACGGTG ref:0:3:TACATTATAT 4 315 +TGCTTCT ref:1:6:CTGTGTG ref:0:7:GGTTGGTGTCA 1 24 +GACTGAATGGGATATC ref:0:16:CA ref:0:16:ATATCAATATGCCA 6 232 +CGTACAACTCG ref:0:11:ATACC ref:0:11:GCAGAC 5 42 +ATCCATCTACGGTT ref:1:9:CAAGACA ref:0:14:G 5 112 +TCGGGGGATATT ref:0:12:ACCAAACCAAC ref:0:12:AGCTGACTTG 8 20964060 +TG ref:0:2:GAGCAGTATAC ref:0:2:CTATGT 3 36 +TGGATAAG ref:0:8:CCTCGTAC ref:0:8:GTGTAAACGTT 3 195 +G ref:0:1:TCGGGTGTCTCGGCTG ref:0:1:GTCCGCAGCGACGAT 7 35 +GTACACCATAC ref:0:11:TCCTTA ref:0:11:CTCGAGGCA 5 160 +TCCCTG ref:0:6:TTGGTGCGCGGTACT ref:0:5:TGTAGGAGGACTA 7 333 +TCTCGGGATTAG ref:0:12:TAATTAGA ref:0:12:ATTT 6 154 +CCGCACTACTC ref:0:10:CAAC ref:0:11:CCCGCAGT 2 111 +CAACTCCTGTGAG ref:0:13:TCCTCCAGT ref:0:13:CGCGGGTAGTGTC 6 5538 +CACGTTAG ref:1:7:TCTCTGCCC ref:0:7:GAT 2 16 +TGCC ref:0:4:GCAACGAGGG ref:0:4:AACATACACACG 3 8 +CTTGGGTATT ref:0:10:TGCACCAAGC ref:1:9: 6 2692 +GAGCAGC ref:0:7:TCCAATAGTGAG ref:0:7:CCAAGTAAAG 7 4488 +CAATGTA ref:0:7:TTCGCGTTAAT ref:0:7:CCCAAATTACTC 3 1062 +ATA ref:0:3:GGTAGTC ref:0:3:AG 2 20 +ACTCAGAGGGGC ref:0:12:CTTCGGCACGCCT ref:0:12:CTTCCCGGCTT 8 85624 +ACTGTAAG ref:0:8:TCCGA ref:1:7:TTAGTCGCT 2 256 +TCTA ref:0:4:T ref:0:3: 2 2 +CATGTCCGTTCCT ref:1:12:GGCGGCCGA ref:0:13:ATTTCTACG 4 29106 +CTG ref:0:3:GTCGCGGATCGAG ref:0:3:CCCGACAGGCTAT 5 280 +GCCCAAC ref:0:7:GGCGCCGCCTCC ref:0:7:CTAGCCCTACACCAC 3 2968 +ATATGAAGGGTA ref:0:12:TGTGATCCATGCAGCT ref:0:12:GTGGCCTCCGTAC 5 1824 +TTTAAGTGTGGCT ref:0:13:AATCTTTA ref:0:12:GGCAATTCCGGG 6 3080 +TGGCGAGCCTGCACG ref:1:14:CCGTG ref:0:15:TTTCAAGA 8 5840 +GGCGCGTGCCTTT ref:0:13:AAGTGGTT ref:0:13:CC 6 3972 +ACATTTGGCAT ref:1:10:AG ref:0:11:CTTCTGGAC 2 6 +CAG ref:0:3:GCCAGCT ref:1:2:GTTAACGGACC 1 8 +TGAGTGTTTAGAC ref:0:13:ATTTCCT ref:1:12:GTGAGG 3 176 +CACAA ref:0:5:TCCTCATTGCTGATTG ref:0:5:GTCTCAGGATGCAGCT 7 864 +CCGGGTAACG ref:0:10:CGCAGGTATACGTTG ref:0:10:GCCGCGACGG 2 192 +GGCTCTACAC ref:0:10:TCGTC ref:0:9:CAATG 4 4 +ATAGCGGAAGGT ref:0:12:AAACTG ref:2:10:GCACTAGA 6 545 +A ref:0:1:CTGAGCCCCACTACTA ref:0:1:ATTGCATAAAGATG 6 24 +ATTGTGTG ref:0:8:CCGAC ref:0:8:CCTGTGATTTTA 6 64960 +CAGTCGCATAA ref:1:10:GGTTTGCATCAACTA ref:0:11:GAGGAGGCCCG 4 262440 +ACCCG ref:0:5:CCTGTGGAAGCC ref:0:4:AGAACT 3 1554 +CTCACTCC ref:3:5:ATTGGACTGAC ref:0:8:CCTTGAC 4 836 +TGTGTAG ref:0:7:GACGTCGAGA ref:0:7:ATTAAAGTTA 1 32 +CCGCTAGTAACCCT ref:0:14:G ref:0:14:ACCACGTAAG 7 60 +GTCACC ref:0:6:CCTCCG ref:0:6:TGT 2 23 +GCTCTGCAATCA ref:0:12:T ref:0:12:TTGATCG 6 12 +GACATA ref:0:6:CTAGTTACTCG ref:0:6:CCTATATGA 5 120 +AAACT ref:0:5:CCCTGTT ref:0:4:CATCA 3 720 +GTCAGACTTGA ref:0:11:AATTTGG ref:0:11:GTATGGTAGAGTGGGC 4 15660 +ACGCCAGG ref:0:8:GTTCTTCCC ref:1:7:GCTTTATGAAGC 4 520 +AGCCTTCATTCAATT ref:2:13:CCAGG ref:0:15:C 10 816 +ACTTGGATGA ref:0:10:TTGC ref:0:10:AAGATGAAAACT 4 748 +TGAG ref:0:4:AGAGTCCACTAGGATT ref:0:4:CCTCTCATGGGCCG 5 4608 +T ref:0:1:ATGGCGGTGTGTAGAA ref:0:1:TTACTTGCGTGGTTTT 8 36 +TTGCCCCGAT ref:0:10:GTTA ref:0:10:AG 7 13 +ATCTCGTTACGAAA ref:0:14:C ref:0:14:TGTAGTAAGCT 6 84 +CGTGTTCCTCAATTGT ref:2:14:GCTGG ref:0:16:ACAATCTCTGCGACAC 6 14430 +TCCGGACCCAAAACC ref:0:15:GCGCGCTGAGGGG ref:0:15:AACTG 9 3226800 +CTA ref:0:3:TAAACACGAGAAGT ref:0:3:TCTTAAACGTATAT 7 608 +TACTCTCCATCGCCC ref:0:15:A ref:0:15:ACTACTGTACCG 7 690 +CCACGCCCGCA ref:0:11:ATGATA ref:0:11:AGAGACCGCTCGT 6 82008 +AAGTCTCTTAA ref:0:11:GATTTGGGAAGGGCT ref:0:11:GAAGTGTTTGTAT 5 1290 +AATTAC ref:0:6:ACACCCATGCC ref:0:5:GAGGATATGTT 3 1722 +CTACCGTGTCTTAAA ref:0:15:GCCT ref:0:15:CCTAGAGAGCAG 8 19778 +CGCT ref:1:3:AGGTTC ref:0:4:C 1 20 +TACCACAGACCAC ref:0:13:CCTTGTAGC ref:0:13:AGTGGTGTGGTAACCG 9 16095630 +TTTTGCCTCA ref:0:10:CCCAACAACT ref:0:10:TAATAGGG 6 39636 +TTACGT ref:0:6:TGTCA ref:0:6:CATGCTCTCA 4 6 +TCACGTATAG ref:0:10:GCAAGATATA ref:0:10:GTAGCCGGT 2 126 +GATCGCGCATGTC ref:0:10:CTAA ref:0:13:AC 8 350 +ATTATCCTAAATA ref:0:13:GACTGCTTTAAGAC ref:0:13:AAT 4 120 +CGTTGTGCCTAAGT ref:0:14:GATTTGGTCT ref:0:14:CCTGGAGC 5 2408 +ACCCGCA ref:0:7:CAATTAAGG ref:0:7:GAATTGTAAGGT 10 179700 +CCGAATACATGCCC ref:0:14:ATGAAAGTTTAAT ref:0:14:CTC 5 918 +AGGGACAACCC ref:0:11:TATCGGT ref:0:11:ATAGG 9 328 +CCACAGCTGAACTGAC ref:0:16:CGGTCGCGA ref:0:15:AGCGAAC 5 62 +GACGACCCCAGGCGC ref:0:15:AGACCAGAC ref:0:15:TC 7 4026 +TT ref:0:1:GTGG ref:0:2:AGCCTTCACTCGTTAG 2 10 +CAACT ref:0:5:GTGGC ref:0:4:AATTAACCTAAGTCG 2 82 +TGAATATA ref:0:8:GCACTG ref:0:8:TCATCACATTTCC 4 14124 +GCTTG ref:1:4:TGT ref:1:4:ATTTGGAA 1 42 +TCTCTCTTTCCTGA ref:0:12:GCTA ref:0:12:TCTGGAGGGCTAT 8 148368 +GTAGGCTAA ref:0:9:CGCCCAAATTGGAAAC ref:0:9:CT 1 90 +AAACATACCACT ref:0:12:ACCAGATGGT ref:0:12:CCGCTGTCAGCACC 7 3445424 +CAAT ref:0:4:GCGGGGGCTCGATGC ref:0:4:CCGCACAGG 4 171 +GTG ref:0:3:A ref:0:3:AGCGTAA 2 32 +A ref:0:1:GAGAGTACTTAAGCCT ref:0:1:TATGGCCATCCGA 6 15 +TTCCATAGCTTTA ref:0:13:AG ref:0:13:GACTAATTCAGAAAT 7 25682 +AGCGGAAGGAAGTG ref:0:14:GGTTCTTAACGTAA ref:0:13:GTCAACTAGC 8 3744 +CCCTCCAGCCGCC ref:0:13:ATCCGTAAG ref:0:13:ATTC 9 30686 +GTTGAAT ref:0:7:GATCGGTTGTTCGT ref:0:7:TGTTGGAG 3 1416 +GGGCG ref:0:5:CTGTCC ref:0:5:G 3 208 +G ref:0:1:GAGGTCG ref:0:0:CCC 1 4 +CGGTAGCATATTCGTC ref:0:16:GAGGGTAAGCT ref:0:14:TAATCTAGG 6 106312 +TCTGAGGACGTAGC ref:0:14:CGACTT ref:0:14:GAATACAC 6 360 +GTT ref:0:3:TGCTAGGACAGCA ref:0:3:CTGTTCAGTG 4 39 +ATATGA ref:0:5:CGGGCGTTCTAAGG ref:0:6:GTATGGCTGAATT 4 6984 +CCAA ref:0:4:GCAATGCATG ref:0:4:CTTACACGTACA 3 70 +GCGTATAACT ref:0:10:CTCAG ref:0:10:CCTAGACTGTCG 5 2760 +TG ref:1:1:GGGACCGAGGGA ref:0:2:TTGCTGGTGTTGAG 6 168 +TGGGAGGCACTC ref:0:12:GTCTTTTATACTTGG ref:1:11:GGAACCAAT 5 579991 +ACCATGAGGTG ref:0:11:CATT ref:0:10:GTCGGTGGTTTAGTA 3 360 +GTG ref:0:3:CCCAAGCGC ref:0:3:CATGACTC 4 10 +GGCCGTCGGTT ref:0:11:TGACAAGG ref:0:11:GGGGCTCATTCGGT 3 11700 +TAT ref:0:3:AGGCGACTGATGCG ref:0:1:GG 2 3 +A ref:0:1:ACTTACG ref:0:1:CGCAGGCGTCG 4 2 +GTATCAAT ref:0:8:CTATTAGTG ref:0:8:A 3 60 +TG ref:0:2:CGTTGACATCTGGGA ref:0:2:TTTCGATCACCTAT 7 42 +ACCTAAAC ref:0:8:CACCTGGTTA ref:0:8:T 3 30 +CTCTGCTGTCTATCTG ref:0:16:AGATCACGGAGTCCA ref:0:16:AAAA 12 2494206 +CAGAGCTTGT ref:0:10:GATACGATAATCTT ref:0:10:TTCCCTAGGTC 5 59534 +CAGCGTTT ref:0:8:TTTGTGCAGAG ref:0:8:GGCTCAACGCAGCG 6 112 +ACTGGATGAAAGGAT ref:0:15:A ref:0:15:TT 12 18 +TC ref:0:2:CGTCCC ref:1:1:CCCT 2 9 +TCGTTGAGG ref:0:9:GGTGTCACGC ref:0:9:TTGTATTCTCG 5 42328 +TTAAC ref:0:5:CGCA ref:0:5:GAAGGCC 3 276 +AA ref:0:2:GTTTAAGTAATCA ref:0:2:GCCGTCCG 4 450 +GAGTTTTTGGT ref:0:11:ACATGTC ref:0:11:GGCCGTCACC 7 7140 +GTTATGACTGTCTCGT ref:1:15:ACTCGAACTGCCGGG ref:0:16:ATA 5 12 +ACGGTACAG ref:0:7:CCCGTTAGGG ref:1:7:GC 1 304 +CACAGGACGGT ref:0:11:TAGAGGATAA ref:0:10:GAC 4 32 +GCATGCACAGGCGCG ref:0:15:AGTTG ref:0:15:CCGATTATGGTTT 10 1984528 +TCTCTTAGTAGCTG ref:0:14:CATAACGTGGATGAG ref:0:13:GGATGACC 8 593806 +ATAAAACGA ref:2:7:AGGCGCAG ref:0:9:TCGAGGGGGA 5 14060 +CATATTCCTAAATCAC ref:0:16:CAAGAGC ref:0:16:CC 11 2990 +TCAGAGCTCAGGA ref:0:13:AAAGCTGTAT ref:0:13:T 6 36 +TCATGCGCTCA ref:0:11:ACGAATTCGGTGGGAG ref:0:11:ACCT 3 176 +C ref:1:0:TT ref:0:1:AGT 1 4 +GCTATTTCT ref:0:9:TGGA ref:0:9:TCTCGAACTT 5 350 +CTTTGGC ref:0:7:CCGTGCGAGCT ref:0:7:ATAGGCACCTTT 4 3468 +ACTAC ref:0:5:ATAAGAGAGTCTAA ref:1:4:CCCGCCAGTT 4 2812 +CC ref:0:2:AGCGGCTCCTAAATAT ref:0:2:CGTGACATGCCA 6 36 +CGGGAG ref:1:5:G ref:0:6:TTGGGGTGAT 1 408 +ACT ref:0:3:CGTTC ref:0:3:CACTCTTCGTG 2 16 +GTACTTCAG ref:0:9:GGTGAGAATGAT ref:0:9:AAT 5 3822 +GGAAACAACTTTTGCG ref:0:16:CTGATGAC ref:0:16:ATTACTAT 10 85050 +GGC ref:1:2:CCTTGATACTG ref:0:3:AGAGTTAACACCC 2 4 +GCAAAGGGCGCT ref:0:12:CATCCTGTAGTTCC ref:0:12:TCAAAGGAGCCCAG 4 8672 +TAATAAAGCATAACT ref:0:13:GCGTTCTGCTTGT ref:0:15:GTGTGTAACATGCGC 10 547846 +GGCGCT ref:0:6:TGGGTGTACCCTGTC ref:0:6:CCACGA 3 9768 +GATC ref:0:4:TTTTTTTA ref:0:3:TATCTCTTTGATTA 7 604 +AC ref:0:2:CGGCCCGGCT ref:0:2:CATCAAA 1 25 +GGACGTTCCAGGACT ref:3:12:TTCACAGAATT ref:0:15:AGTCCTGTA 3 456 +GGCAC ref:0:5:AGCCGCGTGCCTTTCT ref:0:5:GTCTAT 3 468 +C ref:0:1:GG ref:0:1:TCAGTC 1 6 +TACCCGCAAGCGGGA ref:0:15:AGTATCTGAGACGG ref:0:15:TTTCGAAGCGCAG 6 30690 +CACAAA ref:0:6:CGTTGGAA ref:0:6:AAGCCCCCACATTTC 2 46979 +T ref:0:1:CGGACGTGCTATTTTA ref:0:1:CTAGAA 4 6 +TGCGGCCCTGTAG ref:0:13:GCAAGAA ref:0:13:GTTTCCATATCGGAT 9 5542488 +CGGTAAGGTCCG ref:0:12:TTAATCTGTACGATAT ref:0:12:TGA 6 2080 +GCCATTA ref:0:7:CTGAGTCGTGGAGG ref:1:6:CCCTGGAGGAGAC 5 775 +CCAAGG ref:0:6:AGCTAACGAAAAATAC ref:0:6:TTCTTTCCGCAGTTA 5 23850 +GGGCTAGGAA ref:0:10:GCACGCCCCTCCTCT ref:0:10:CGTGACTTT 8 2578452 +TCT ref:0:3:TTAAAAGTTCGGGGA ref:0:3:GGG 4 1080 +CGACTTGCCAGC ref:0:11:GACCTCCCCTGGGCC ref:0:12:TGTGGA 3 192 +C ref:0:1:ATCCCTT ref:0:1:CCCTCACGAGG 3 15 +GATACTAC ref:0:7:CACCTGATG ref:0:7:CTGGGGGCCGTAT 5 5300 +CCGAGACAC ref:2:7:GTACTCATT ref:0:9:ACCATATATCGCCCA 4 17545 +GGC ref:0:3:CTACAAAAAATATCA ref:0:3:AGTATATTGCC 5 232 +T ref:0:1:CAACCCAATCGGCCA ref:0:1:GCCAGCTAT 4 2 +GACCA ref:0:5:GG ref:0:5:TCTC 2 18 +TCTG ref:0:4:AAATGACTGGCCGG ref:1:3:CCAACT 1 12 +GTAACACT ref:0:8:TGCTTGTCC ref:0:8:GAAGGTACGCTTGCC 3 1008 +TAA ref:1:2:CGGG ref:0:3:GGTAGTT 2 75 +ATTTAGCGCGGTGA ref:0:13:GAATC ref:0:14:CGCCGGCTATTTG 5 1040 +GCCCATTGAC ref:0:9:AACATGGGT ref:1:9:CTTCTG 4 13832 +ATGCT ref:0:5:GGGAGGACAATGAA ref:1:4:T 1 6 +TCAGCG ref:0:6:TGCCATCACATTTC ref:0:6:AG 1 340 +AATACCCTCATCTCAC ref:0:16:AGATCTGTCACT ref:0:16:CTCCATTAAGGCG 5 5742 +AGCGTGGGCGT ref:0:11:TCTAGTGATCTT ref:0:11:TACAGTTCCGA 6 8322 +CCTGACCCAGGGA ref:0:13:AG ref:0:13:ATGGATAACTCC 6 108 +TTGTATA ref:0:7:AGCA ref:0:7:ACTCACGAGCCGCACG 5 882 +ACTATGGCTGAATTT ref:0:15:TCTACTAATGAT ref:0:15:GCTCCCGA 5 1760 +TCGCGCACCG ref:0:10:CTTAGCAGA ref:0:10:GGAAAAATCCAC 3 4042 +TCTGGGATAACT ref:0:12:GACATTAC ref:0:11:GACTCTTTTGCTAG 6 39560 +A ref:0:0:CGGC ref:0:1:TAACCATGC 2 3 +GGCCATGC ref:0:8:TCCTTGAGCGTC ref:0:8:GATAAAAAATG 2 31150 +GCGGAACGAACGTG ref:0:14:CCG ref:0:14:CGTAAACT 6 98 +AAAATAGGGGTA ref:0:12:TTCGGGAGCTC ref:0:12:CTTCGCCT 9 35880 +CTAACA ref:0:4:CCTA ref:0:6:CGG 1 96 +AGTAGCGTGACACA ref:0:14:GATCGA ref:0:14:TGAA 8 384 +CCACGCTGTCCATGGG ref:0:16:CAT ref:0:16:GGGATTC 11 4404 +A ref:0:1:GT ref:0:1:AAACTC 1 9 +CGCGAAATTGT ref:0:11:CTGC ref:0:11:AACATCATTGGAGCA 6 6813 +ACCGGG ref:1:5: ref:0:6:GAGC 4 14 +AGAGGCATA ref:0:9:TAGTAC ref:0:8:TATGCAGAGCA 2 10 +AAGTTCAATTCAGGT ref:0:15:TGGAATAAGC ref:0:15:CCGAATAGGGCA 9 283140 +ATTCCGAGCTGC ref:0:12:T ref:0:12:TGATTGTACTAGA 4 6 +GTGATGTTCGG ref:0:11:ACTAATCCCGAGC ref:0:11:CTACTGAAACGCCACC 8 45360 +AATTAAGTTCGGAG ref:0:14:GTCG ref:0:14:ACCT 9 2046 +ATTAATACT ref:0:9:CGCTCTT ref:0:9:CCCTATAGAAA 5 8536 +CGATTGCACAAGCTCA ref:0:15:AGGTAATTCAT ref:1:15:TGTATTGTTC 6 600 +TATTGCTTC ref:1:8:ACAAGAGATTGT ref:0:9:T 3 50 +GATTG ref:0:5:ATACAAAAAAGGGGG ref:0:5:GGGG 3 1260 +GGTCCTGAG ref:0:9:ACTGA ref:0:9:TTGCGTTC 3 99 +CC ref:0:2:CTAA ref:0:2:A 2 15 +CATTAGCGCGCATGTC ref:0:15:GCCCCCTCTG ref:0:16:GGAAGTCCCCTTAGAG 9 298410 +GGCTGTTGCCTGCCTA ref:0:16:AGAC ref:0:16:GCGTGAG 10 11984 +TTCACACTCC ref:0:10:GCTGAGGCAAC ref:0:10:CTACATCGCC 4 3120 +TATACTTCTCCAT ref:0:13:GATAGGA ref:0:13:GCGTACGAC 10 139968 +TACC ref:0:4:CCAATACACCCTCTGG ref:0:4:ATTTATCTGTTAG 5 432 +AT ref:0:2:AACATTCTA ref:0:1:GCGGACAC 3 18 +CACGGTCATCTA ref:0:11:TCC ref:0:11:GGCAT 4 2 +CG ref:0:2:CTGCATTTGCCT ref:0:2:AA 1 18 +TGTTTTGTATTA ref:1:11:CGGTTATGTACT ref:0:12:GCCGCGATCCTGCTA 5 123552 +CACGTACCAAGA ref:0:12:CTT ref:0:12:AG 8 110 +AATTTCGGGACTAG ref:0:14:TTATT ref:0:14:GAGATATA 7 48 +GGTT ref:0:4:AAGATTCATATGCTC ref:0:4:TGAC 3 1917 +CCCTAGTTGTCGCA ref:0:12:AC ref:0:13:GGCAAGGAT 6 35 +T ref:0:1:TTCTGACTTACTAACT ref:0:1:ACCTCCCAGGG 4 7 +CAACA ref:0:5:AGTATCAT ref:0:4:AGCGC 2 11 +CGATAGCCATCGCC ref:0:14:TCCATTG ref:0:14:GGCGTTGGTGCCAT 5 165 +ACCCCT ref:0:6:GTACCTT ref:0:6:CTACCTACATTTTAAA 3 608 +CCTCGCGCAAGCGG ref:0:14:AATA ref:0:14:C 11 222 +ATTTTCA ref:0:7:TATTGAAA ref:0:7:GGTCCCCTGTCAG 2 4620 +GAT ref:0:3:GAAAGATTAAGTAC ref:0:3:AACCGATCCG 3 19 +TGATGT ref:1:4:CATGG ref:0:6:CTATGGTTGG 2 16 +C ref:0:1:TCCGACTTTCT ref:0:1:GT 2 12 +CACC ref:0:4:TAGC ref:0:4:ATTCCCGGAA 1 24 +TGAAGCA ref:0:7:GG ref:0:7:AATCCTCATTGTA 2 108 +ATC ref:0:3:CATTTTTCCAGATAT ref:0:3:G 1 40 +ACGCCAGAA ref:1:8:TTCCAC ref:0:9:AAC 6 1254 +TTA ref:0:2:TCACACTTGGTC ref:0:1:CTACCC 3 6 +TATCT ref:0:5:CCGAGT ref:0:5:TCTGTT 3 462 +TGAG ref:0:4:CAACCTCTTGTC ref:1:3:CAACGTCCA 6 246 +CACGACCATACC ref:0:12:AGGAG ref:0:12:GG 10 1014 +C ref:0:1:AG ref:0:1:TAATCTAGTCAT 2 6 +GGGAGACGAAATTG ref:0:14:TGCCGCTTTCCATGG ref:0:14:GGTCT 9 2794704 +ATGCGGGTT ref:0:9:CGCG ref:0:9:GGCACTGA 6 8749 +AGAC ref:0:4:CAATAAATGAGCGT ref:0:4:TTGGCAG 4 125 +ACC ref:0:3:CCGTTAG ref:0:3:ACCACCGTTTT 3 7 +TACTATCATAAATG ref:0:14:GTATGG ref:0:14:TTCGCTTCAC 7 60990 +AGGGCGCCGAGTAAA ref:0:15:CTA ref:0:15:GAAGAAG 8 1197 +CTTTCGTGT ref:0:9:TGAT ref:0:9:C 5 32 +CCAGCCACT ref:0:9:CCCGCCAAAACCG ref:0:9:GGATGGCCCGAA 2 15360 +TTCACGTG ref:0:8:AGCGAGCCTAAGTAA ref:0:8:GAGC 5 1364 +ACCGACCGAACGC ref:0:13:TGTTG ref:0:13:TAGCAC 8 2112 +TGT ref:0:3:GTGCACCCAGCC ref:0:3:ACGCCCGGAGAACTAT 6 812 +CAAATGTGTACCG ref:0:13:CCTTACA ref:0:13:TGAGACGG 5 850 +CCGTTTTTCGCCCT ref:0:14:CC ref:0:14:GGTTGGGTC 8 88530 +TGACCAGATTA ref:2:9:CT ref:0:11:CAAG 5 80 +AGGCAGCTACG ref:0:11:CAGAGTACTGT ref:0:11:GCCT 1 4 +GAGAATCCCAGTCTTT ref:0:16:TTATCGGCACG ref:0:16:GTCTGTCGCTTGTG 7 43680 +CCAATGACCACAG ref:0:13:TATAGCCGGCCAAGA ref:0:13:TGACA 4 3324 +ATAT ref:0:4:TGGTAGGA ref:0:4:TATGTTATGAGAGCCG 5 93 +TGGCGCA ref:0:7:CGTCCGTTGACGCC ref:0:7:GTGAACCTGTTCC 4 102 +T ref:0:1:AA ref:0:1:AACCCCCCCCCTAT 2 6 +AAAGCGG ref:0:7:ATCTA ref:0:7:CTTAT 7 5760 +CGTCTCAC ref:0:8:TTCA ref:0:8:GAAGAGCAATG 3 1167 +GGGGCAGGGA ref:1:9:TGGGTCCAGAAAGC ref:0:10:CACCTGTCCC 3 9280 +GCT ref:0:2:GGCGGG ref:0:3:AACGACTAAAGTTT 1 8 +AGCAGACT ref:0:8:C ref:0:6:TATCGCGTGTT 2 28 +CACAAAGAAAGCA ref:0:13:CTAACCCC ref:0:12:GATTTAACG 7 11140 +TAGGG ref:0:5:AAAAGCCA ref:0:5:ATT 3 3440 +AGTAATGCAAGCC ref:0:13:G ref:2:11:ATGCCT 6 30 +C ref:0:0:AGA ref:0:1:CACGTGC 2 3 +CGGCGTCCTTTCTGAA ref:0:16:CCCTAAA ref:0:16:CGATACGTGTCAC 6 93372 +ACCGG ref:0:5:TTACACTTAGACCT ref:0:5:GGAGATAGCA 3 9 +TATCGTCTAGG ref:0:11:G ref:0:11:TTAAGTTTACCATGGA 3 1155 +CGTCACG ref:0:7:TTTC ref:0:7:TTTGCCCGACCCTCT 5 43307 +TTAAATCCCCGC ref:0:12:TAATGGTTTCC ref:0:12:TCCT 6 128856 +CGACGTTAGATCG ref:0:13:TGAACGTTAACA ref:0:13:TACATGGTGGAGTGG 2 4320 +AAACCACA ref:0:8:AGCAAA ref:0:8:CA 4 365 +CGTAGATTT ref:0:9:TTCG ref:0:9:ACCTATTTCCCCGCAC 5 156 +TAAACTCG ref:0:8:GAAAGAAACGC ref:0:8:TATAGAAAGGA 5 41789 +CGT ref:0:3:ACGTCTC ref:0:3:TCGACTGCCAG 2 2 +AACAGC ref:0:6:TA ref:0:6:CT 5 35 +AAG ref:0:3:A ref:0:3:ACTTGAC 1 14 +GCTTGTCAGCTCATG ref:0:14:AGCC ref:0:15:CCCCTT 7 15 +GGACG ref:0:5:TTGGATTCTA ref:0:4:TCTGCGGGA 2 18 +TTGTCTACAGGAGG ref:0:14:C ref:0:14:CCGTGTCGCCTTC 8 110 +TCCAGCCCGAGTAGTA ref:0:16:CTTTCTGGGTGGCGG ref:0:15:AACATA 4 25116 +GCCG ref:0:4:GTTTGAG ref:0:4:CATCGTGAGGC 4 136 +CTA ref:0:3:GTTGATATTCCT ref:0:3:G 2 72 +TGGCTAGACGTAAAC ref:0:15:CTGAG ref:0:15:GGGTCCCGGGTGGG 8 23871 +AC ref:0:2:ACGGTATTTCCCGG ref:0:2:TCGAATATAGT 5 175 +AACGTATT ref:0:8:CCTCAGCCTTA ref:0:8:AGGAATTAAGTGGG 2 2465 +AGGTATAAAGTG ref:0:12:AAATAGCCAAAG ref:1:11:ATCCGAA 7 840 +CGG ref:0:3:ATAGCCAAA ref:1:2:ATTGTTACTGTAAT 5 59 +ATTCGCGCTC ref:1:9:CTCGGACAGCGTAAA ref:0:10:CCTTTATCGGAGT 4 4608 +AGAGGTAGC ref:1:8:GCCTTCGGGGGAA ref:0:9:GTCCTCAGGCC 6 142296 +CCCTTTGGGCAGGAT ref:0:15:TGGGGCTTT ref:0:14:A 8 960 +AAGAGGACA ref:0:9:GCTCATTCGAAC ref:0:8:GCT 3 75 +T ref:0:1:GACAGA ref:0:1:GTAGGGTTGACGGC 4 21 +CTATGGTATC ref:0:10:GGACCTTTAATAGATT ref:1:9:ATTGGCTA 1 468 +CAGGGCTGAGTGGGG ref:0:15:CCCGGAATA ref:0:15:GACTGCTG 7 207872 +AGAGCCCTCCGCTA ref:0:14:GCCTGGGGACCCCGT ref:1:13:ACGTCCTTGTGGC 5 299145 +TATTTGAGAG ref:0:10:C ref:0:10:ACTGC 8 594 +GCAGGCAAGC ref:0:10:GTGATCTGTGCGCCG ref:0:10:CCCC 4 176 +TCGGT ref:0:5:CGCAACCTAACAAGCC ref:0:4:CTTG 2 275 +CACGTGCCGCAGGGTT ref:0:16:GC ref:0:16:ATC 12 21 +CTCAGCTG ref:0:7:ATCCC ref:0:8:TGA 4 104 +CCACAT ref:0:6:AGTTGCCCTGGTACAA ref:0:6:AGTGTTCGAGTTATC 5 360 +CCAGTCAC ref:0:8:CACGGGGA ref:0:8:GGATGATA 4 462 +CCTGACGTTGATC ref:0:13:AAGTAACA ref:0:13:TA 8 252 +GAGAAGGGCGAAAAG ref:0:15:ACC ref:0:15:CTGTGG 11 28897 +GACGT ref:0:5:CGCA ref:0:5:TGACCGAA 2 42 +ATAT ref:0:4:TTGGGA ref:0:4:GTAGTTGT 2 48 +CT ref:0:2:TCAACTG ref:1:1:GG 1 6 +CTAATCCTCCT ref:0:11:GCCG ref:2:8:GTGCGGTGGAC 5 9675 +GGTT ref:0:4:TGGCCATG ref:0:4:CCCAGCACAGGC 2 72 +AA ref:0:2:ATTCTTCAATAATAG ref:0:2:GATTGTTGTTG 7 180 +CCGAGGGGTTTGGC ref:0:14:TTACAATGG ref:0:13:GTAGGCGT 4 1860 +T ref:0:1:AGACCCGTCAACG ref:0:1:GGACGGTTGGCCTA 6 3 +CCTATCTAACCCG ref:0:12:AACGGGAAGACAA ref:0:13:TCTAAAGTCTTAGGG 6 1167453 +ACCGAGGTTTGTGC ref:0:14:GAGTGATG ref:0:14:CAGCG 6 348 +ATAGAAACTA ref:0:10:CCG ref:0:10:TCGGGCTCCC 7 5760 +ACTATCTT ref:0:8:TATG ref:2:6:TGTAACCT 2 336 +GCCGCTGTGTGT ref:0:12:CGGGC ref:0:12:GGGGGTGTAATG 4 8096 +AATGC ref:0:5:CGCTCATTGT ref:0:5:GGCTCGTTGCGCTA 7 7260 +GAGGTCGTACCTT ref:0:13:TTTCTTTAACCTGC ref:0:13:AG 4 3024 +AGATTCTTCTGAAAG ref:1:14:TGCGAGTCCAAGG ref:0:15:CGTCCCGCT 7 23268 +TGTGCCCTACAGTTCA ref:0:15:ACCCCCAT ref:0:16:G 8 270 +GGACG ref:0:5:CCATAC ref:0:5:ATTAGTAC 4 147 +AACTGAA ref:0:7:GACACCCA ref:0:7:CTCCTTGC 4 2940 +TGATTTTACGTCC ref:0:13:CCGATGGAACCTT ref:0:13:GCGTCCACGGAGAA 5 10689 +AAGCGTACCCGG ref:0:12:CTAGTGAGCC ref:0:12:TTAGGACAG 6 4080 +GTACATCCTTCT ref:0:12:TAACG ref:0:12:T 8 65 +AAGATGGAAGCTTT ref:0:14:CTGCGTGTAACACT ref:0:14:GTCGCA 8 146157 +CGCGGAGAGGCATACC ref:0:16:GGCCAGTTGC ref:0:16:TCAAGTTACTAAAGGC 9 10154936 +TCGTGCCGTTCCAG ref:2:12:TGGTGAACA ref:0:14:GCTATCGCAGAGGGAA 3 532 +GCGAAGTT ref:0:8:CCCGCTG ref:1:7:TCCAACC 5 6180 +CTATGA ref:0:6:AGCGATGAC ref:0:6:ACTAGAAACTCGCC 3 30 +TTTCCATAGTAG ref:0:12:CAAGCCT ref:0:12:GGATCTATCCC 5 620 +CGTAGTCTGT ref:0:10:GGTA ref:1:8:ATGCT 3 56 +GGTA ref:0:4:AAGCTGGCTGCC ref:0:4:TT 2 60 +ATAGC ref:0:5:AGACCCGGG ref:0:4:GGGGG 4 2100 +ATTAGCCCCAGAGT ref:1:13:CTCTCAGAGATGTC ref:0:14:GCGTCATGAAAAAACA 3 1755 +TTGCGCAGA ref:0:9:AT ref:0:9:CCTGCCAGCATACTGT 3 392 +CCGGCTAAAGCGT ref:0:13:TGACAG ref:0:13:TCCCGAGTTCGTA 6 7854 +TT ref:0:2:ACCG ref:0:1:AGCGAATGGC 3 15 +AG ref:0:2:CCCCTTACTTCAAATT ref:0:1:GACA 2 44 +TCACTCCAC ref:0:9:GCTGTGACCACAA ref:0:7:CGAG 4 370 +TGGCCGACCATTT ref:0:13:GGCC ref:0:13:CTAAGGGAAA 5 64 +CACTAGTTCTACCCG ref:0:15:GAC ref:0:15:CTTAGCGTAT 7 90 +AAGGGA ref:0:6:G ref:0:6:GTAGGTCGGCATCCC 1 51 +GTGTAGAAT ref:0:9:CAGCATTTAAGGAC ref:0:9:CAAGATCAGCAAAC 6 12064 +TGCCAG ref:0:6:GCGCTTTCGCCCT ref:0:6:ACTGGGTGCGTGGAA 4 14674 +C ref:0:1:GCAGT ref:0:1:ACATTAG 2 1 +GGCCGG ref:0:6:GCCGTAC ref:0:6:ATGGGCTGGCGTGT 1 30 +GCACTGC ref:0:7:AATCGCGTGCGCT ref:0:7:GTAGGACCGTCT 5 3584 +TAT ref:0:3:ATAA ref:0:3:TC 1 16 +CAGTGTTATATTT ref:0:13:ACCGCAA ref:0:13:GCGCGT 8 636 +TGA ref:1:2:AGACGTTACCGG ref:0:3:TATAA 2 33 +CTAAGAC ref:0:7:GCTCACG ref:0:7:CTCTGCCGAGGTT 4 6677 +A ref:0:1:CC ref:0:1:CATTGCCGA 2 6 +ACAGCCACGTT ref:0:10:GCCCTCAAAAGATA ref:0:11:AC 3 1616 +TAGGT ref:0:5:GATTCGGGGAAGAC ref:0:5:GCAACTAACAG 5 5412 +AT ref:0:2:CTCAATGAATA ref:0:2:TGTGTG 3 54 +AAAGCCTA ref:0:8:C ref:0:8:TAGAGTTAGAGGTG 2 186 +CGCTG ref:0:4:AGCTCCGTCTC ref:1:4:TAATGCTTGTTC 1 6 +CCCAGAAGGA ref:0:10:CGGGCAAGCCTCACAG ref:0:10:AATCCGAAGGGG 2 1560 +CGGGCGCTGGATAAG ref:0:15:TGTTAATCGTAT ref:0:15:GCAAGTGTGCT 7 1032 +CA ref:0:2:AGCGCATTTT ref:0:2:GTTTCAGTGCAT 4 6 +GATTAGAACTGCACG ref:0:15:CCC ref:0:15:A 11 5 +CAACTATGATCCAGAA ref:1:15:TATATATATGGGATT ref:0:16:GCTGGACCCTATT 6 358308 +AAGCGGCT ref:0:8:AGTCAACG ref:0:8:GTGGGAA 5 3956 +CCCCGGTTAA ref:0:10:GTTATTTCGT ref:0:10:ACTTAAGCTGAA 6 30272 +TT ref:1:1:ACGTAGC ref:0:2:CAGAGGAG 4 45 +GCGG ref:0:4:C ref:0:4:CAGAAGC 1 1 +TGAGC ref:1:4: ref:1:4:ATGT 2 2 +TCGCTTA ref:0:7:TTGATTCCTGCGGTAT ref:0:7:GG 2 400 +CATATCGT ref:0:8:GCTTGACGAGAGTTTT ref:0:8:GATCGACAA 5 2496 +AGGAAAAA ref:0:8:TATCCCTCGTGG ref:0:8:CCTAATAGTCGATGT 8 4504 +ACGAG ref:1:3:GCGCTCATT ref:0:4:TTCTTGCC 2 9 +TATAATTGCCGGG ref:0:13:AG ref:0:13:TTG 9 288 +AAAGCAT ref:0:7:TCAGCTGTCAGCATAC ref:0:7:GGCTCTG 3 275 +CGACTACTACC ref:0:11:T ref:0:11:GTTCGCT 6 2 +AGTCTC ref:0:5:CGCAAAACTCCTAT ref:0:5:TATAACAGGG 2 320 +AAT ref:0:3:AAAG ref:0:3:A 1 14 +GCCGTAACGT ref:0:10:TGCACTCTCGCA ref:0:8:ACAGCTCATGT 3 37 +ATTACGTTTGGCCT ref:0:14:CAGAATTACATGGTA ref:0:14:G 5 81 +C ref:0:1:CTACCGCT ref:1:0:GGAAGTAGGTT 4 4 +TCTAGGGAGTCG ref:0:12:CTAGTACTTCGT ref:0:9:CACTAG 4 900 +TA ref:0:2:AAAAATAA ref:0:2:GAAGAGTCGCCCCC 3 36 +ACG ref:0:3:AACGCACA ref:0:3:CAGTCTCCTCCGTAG 1 20 +AAATCATTC ref:0:9:ATGACGTCAAGTGGGT ref:0:9:CAGCATCAACAGTTCC 4 812 +ACGCCCACGGTC ref:0:12:ACACATTGGAAAGGG ref:0:12:GTATCTAATCGCTAAT 8 19489344 +TGTAGA ref:0:6:CGCCGCGCG ref:0:6:CTTGGATCCG 6 7728 +ACCTGCAATATACTAC ref:1:15:CTGGTAGTT ref:0:16:TCAG 8 390 +AGATGAGTTTC ref:0:11:TCATCACTAGTG ref:0:11:GCGGTGTAGCAGGCTG 6 153981 +TCCCTTACT ref:0:9:CGTGAGGTGGA ref:0:9:GCACACTAG 4 1449 +ATTGCTGTCA ref:0:9:AAAAGAACTCCCG ref:0:10:TGTTGGGAC 3 65240 +CGAGTCATCCTC ref:0:12:TGTGCTAG ref:0:12:GGTCCACGCATGGTTT 6 12744 +AAGACTACGGCTCCCA ref:0:16:TGCGGACATGACT ref:0:15:ACCCACGGCGG 7 643650 +AAACACGC ref:0:8:A ref:0:8:CACTGTGCATAC 3 16 +GCAGTG ref:0:6:CCCC ref:0:6:TTCT 4 252 +CGCT ref:0:4:GTCGTGAGTGTC ref:1:3:AAAGGCGATCCAC 3 66 +GGTATAGAGC ref:0:9:A ref:0:9:GTGGGA 5 225 +AAATGCGCGTCCATT ref:0:15:GCCGAGTCG ref:1:14:CATATCCAGACCGAT 4 236 +GTTACCACCTGTTCA ref:1:14:TCGATAAGGGC ref:0:15:TAGAACCGCAATCCT 6 84480 +TAG ref:0:3:GT ref:0:3:GTCACCTTCAA 2 34 +TACGTACAGCTGC ref:0:13:ATTACCCCC ref:0:13:CGCTGGGAAG 3 408 +GAAGCGCGGGAC ref:1:11:AAAAAAGGT ref:0:12:CGG 6 32265 +GTTCGTAACCCAGGT ref:0:15:TTCTAAAAGTCGTA ref:0:15:TGAC 3 84 +ACGGCGTTAGG ref:0:11:CCCAT ref:0:11:CCTAAGGCGAGAA 5 1464 +C ref:0:1:ACGGTGTA ref:0:1:GACTGTATGCCG 5 3 +TGCC ref:1:3:GGAG ref:0:4:CATGCGTTT 2 102 +GGGGATGC ref:0:8:CAGTTGTGACTTAG ref:0:8:GAATA 3 756 +GCTAGTGGGT ref:1:9:ATAAC ref:0:10:TGAGGGGTACACGC 6 212 +ATTGGATGACCCA ref:0:13:TAAGA ref:0:13:GAAT 8 672 +TGCCAGGATAC ref:0:11:TATACCAAAAAGGTCG ref:0:11:ACCCTA 3 720 +C ref:0:1:ACTTGCGCGATCTGCA ref:0:1:TAGATGTT 5 45 +T ref:0:1:CCGAACTAAGTGTTA ref:0:1:A 1 8 +GTCTAC ref:0:6:TTGACCGTGTC ref:0:6:TAG 3 204 +G ref:0:0:TAT ref:0:1:AACAGTCGCATACAC 2 2 +GGGAAGCGATTCAAA ref:0:15:TGTCGTGCCATTTA ref:0:15:CCTCACATTTTG 10 8116605 +AAGACCCCGCCAACG ref:0:15:GAAGT ref:0:15:CCCTTAACTCCTA 5 24 +TACCCACGTCCTA ref:0:12:AAGT ref:0:13:TTCCAACCCCAGGT 4 954 +TGTGGTGGCATAA ref:0:13:TGACGCCCCATGCGC ref:0:13:GGAAT 5 2158 +GAATCC ref:0:6:AGAAGGTAA ref:0:6:TGGTCT 2 72 +CCGCGTGCACAAG ref:0:13:ATCGACCACGTGCAT ref:0:13:GCTTCGGCTCTC 5 1800 +GAGGACTCCGATCAAG ref:0:15:ATGCTAGTCC ref:0:16:GTCTCT 7 2256 +G ref:0:1:CACGAGTAAT ref:0:1:AAGCACTCTTCCAA 5 2 +TGGCCTATACTTGT ref:0:14:TCTCCCCA ref:0:14:TAAACC 9 180336 +GTTG ref:0:4:C ref:1:3:GA 2 5 +TCGAACGACTCAG ref:0:13:GCA ref:0:13:AACA 8 48 +CCTTTTTCCAGCA ref:0:12:ACGG ref:0:11:CGGGTTAAAGGG 7 791388 +CATCTTACATCCT ref:0:13:ATGCA ref:0:13:CCATACGCCAGTGGTA 6 4752 +ACCCGCGAATAA ref:0:12:GTAATGTTACTTCCCG ref:0:12:AAGC 6 15 +ATACGTAGC ref:0:8:CAGTGT ref:0:9:GTCATCTG 3 18 +GCT ref:0:3:GCGGGGAAC ref:0:3:GTCTAACGCGTCGC 4 65 +GGCCTCGCTAAGCTA ref:0:15:CCGC ref:0:15:GTTCAT 7 648 +CGACCCCT ref:0:7:ATATGGTAGA ref:0:8:ATGTGTGCCGC 7 44585 +TGCTTTACG ref:0:9:CGGC ref:0:9:TTC 5 276 +ACGGTGCTC ref:0:9:G ref:0:9:CAGTGCACAACGGGGG 3 150 +CGCGACTT ref:0:8:TCGCAAAGACCAT ref:0:8:TGTTTATATG 2 168 +CTGGTATCTAC ref:0:11:TTCCCAGACAAGCC ref:1:9:GTGAATACAA 4 17442 +CATTGCT ref:1:6:AAGCGTCCC ref:0:7:TAG 2 20 +AGTCTCTGCG ref:0:10:G ref:0:10:CAAAGA 8 1017 +GGGGGTAGTGCAA ref:0:13:CTTTCTGTATTTAAA ref:3:10:AGGATGT 3 120780 +TAAGGTAACCATGCA ref:0:15:TTGTCCCAATCT ref:0:15:A 7 1080 +ACCGGCGGCTATTA ref:0:14:T ref:0:14:CGGTGCAAGATACAG 6 3693 +CCTCGAGAGTATT ref:0:13:TATTACGTTAAGT ref:0:13:ACGAAGCAG 6 5376 +AGCATG ref:0:6:CCTC ref:0:6:TCGCCGAACGCTAGG 2 340 +ACG ref:0:3:AATCGA ref:0:3:GTTGGGTCATCATGG 1 4 +AACGGGCCCC ref:0:10:AGCGGGGG ref:0:10:TACGG 5 972 +CACACGGAGGGG ref:0:12:TTCAGCCCACGA ref:0:12:GCGCTACGGCTGC 4 1368 +GGCCCAGCGTAG ref:0:12:CA ref:0:12:CCGCGATCTCA 5 63 +TGTCTGCCAGCGCGCA ref:0:16:G ref:0:16:ACGGACAACCCCAG 8 5500 +ACTTCTCTCGT ref:0:11:CTAGATTGGTTCGCTT ref:0:11:GGATCCAT 3 1160 +AGAGGACA ref:0:8:TACCC ref:0:8:GCCCTATA 6 22140 +AATCTCATGC ref:0:10:ACA ref:0:10:TGCGTGGCC 3 236 +CGAACCA ref:0:7:AGAGGA ref:0:7:GGTCTTAGTCGAATCT 3 840 +GAGTAAATCTGGG ref:0:13:AGTG ref:0:13:TAGA 8 252 +GTTTAGAT ref:0:7:GGACCGGTAAAAAA ref:0:7:TGG 3 56624 +CTACT ref:0:5:C ref:0:5:TTTT 2 42 +CCTCTAACAGA ref:0:11:AA ref:0:11:GATAAATAGGTACA 5 4896 +GTCTGGAG ref:0:8:TA ref:0:8:TCTTTGCAGATCGTC 1 6 +AGGCTAT ref:0:5:GCTTGGCATCCTC ref:0:7:CAACGGGTGAATC 1 448 +TCCAAAT ref:0:6:C ref:0:7:CGAG 4 82 +TCTCTA ref:0:6:CAAT ref:0:4:GGACGGGTA 3 128 +TCGGTCCCTTG ref:0:11:CTT ref:0:11:TAAG 7 534 +GAGCAAGCGTT ref:0:11:GGTACTACTACCA ref:0:11:CTTCC 7 250 +GGGGACCTTTACT ref:0:13:GTAGTTAAA ref:0:13:CAGAGACATTTTCC 5 2304960 +GTCTCTGTAACCCTG ref:0:15:AGACCCTCC ref:0:15:TCCGATACCCCT 5 1547 +CGTCGGGAAA ref:1:9:AATTGGGCAGGCG ref:0:10:TCCCTTCA 4 13185 +AA ref:0:2:CGT ref:0:2:TCGACT 4 70 +GCCTTGC ref:0:7:TTCATC ref:0:7:CGCGCGTAATTCTC 3 731 +TTGCGAAACAGAT ref:0:13:CCGGCTGTTCATC ref:0:13:AGC 7 11078 +TT ref:0:2:CCAGCA ref:0:2:ATGACTCTATTAA 4 280 +TCACCTCAATCCA ref:0:13:ACGGCGTGCACT ref:0:13:TG 7 325 +GACGCTATTACGCGAG ref:0:16:AAGGCAA ref:1:15:TCACAGAGGCCTATA 9 2616 +CGGATGCCGGCGAGC ref:0:15:GGCACAGTACTTGG ref:1:14:ATCGCTTACAAGT 6 12992 +GACTCTGTATG ref:1:10:CCCC ref:0:10:TAAGTA 3 1320 +GTA ref:0:3:TCTACTAG ref:0:3:AGTCCG 3 56 +ATGG ref:0:4:GTGGACC ref:0:4:CTGTTAGGAG 3 86 +TTAAGTACCAAT ref:0:12:AGATAAAGTGC ref:0:12:CATTA 5 471 +TATAGTACTGGT ref:0:12:CCCG ref:0:12:ACATTGTAGAAGGGG 5 560109 +GAA ref:0:3:CGTAATCTACC ref:0:3:TGCCCG 3 48 +GTC ref:0:3:GCAGGTTCCCC ref:0:3:TATCCGGCGCCTA 4 1152 +GGAA ref:0:4:A ref:0:4:TGCA 2 22 +GTTTCC ref:0:6:CGGGATTTGGA ref:0:6:TAGTC 1 480 +CCAGGT ref:0:5:C ref:0:6:ACACC 3 74 +TTGCTGCCGTGAATTA ref:0:16:GCGGGTTGTACCATAG ref:0:16:GTAAG 7 576 +CTCCCGTGTCGGG ref:2:10:CGTGCGGC ref:0:13:AAAGCGTGAAT 2 363 +AAG ref:0:3:AGTCACTATGGC ref:0:3:ATAATCTCGTATTTTC 4 18 +TATAATTGT ref:0:8:GC ref:1:8:GTAACGAC 4 18 +TCTTATCACCGCGAGG ref:0:16:AGACGTCTAT ref:0:16:GCTGATGTAAAGACG 7 192672 +TTTATAC ref:0:7:CAT ref:0:7:CGAAGAACG 4 944 +AGAATAAAATTG ref:0:12:ACAAAAGGGCT ref:0:12:GTAGGAGTA 6 196840 +CCATTC ref:0:6:CTGTCCCCAAAGAAA ref:0:6:GCAGCCTATTA 1 48 +GGCAAAAGTAAGCAAA ref:0:16:CTTGCCGTAAC ref:0:16:TTTCG 11 18073 +GTTGGTC ref:0:6:T ref:0:7:GG 3 9 +AGAGTATGG ref:0:9:CAACTCTAGGG ref:0:9:CTCG 5 2016 +T ref:0:1:CGCTAGCT ref:0:1:GATATGTTTG 4 10 +AACCCTA ref:0:7:CTCTGCAACATAGACG ref:0:7:TTGCTCAG 6 3450 +GTGT ref:0:4:AATTGACATCGA ref:0:4:CC 3 135 +TTCTTTTCTTGATGG ref:0:15:AATCAG ref:0:15:GTCCCCTCGA 8 91840 +GACTAGGCAG ref:0:10:TTAAC ref:0:10:AT 6 33 +TTCCCATGATGTTTAT ref:0:16:CGAGCAGGCATACTTC ref:0:16:ATTAAAAAGT 7 1664640 +CACGAA ref:0:6:GGACTG ref:0:6:C 3 6 +CT ref:0:2:ATCGACAGAGGCAATT ref:0:2:GGTTTTTCC 3 168 +CAGATTATGTTA ref:0:12:TAAA ref:1:11:ATTAACAACTCC 7 35850 +GGTGCGGGT ref:0:9:AGCGGTTAT ref:0:9:GT 4 728 +GTGTGTTACCATT ref:0:13:CGTCGC ref:0:13:G 9 117 +GTACATTTGGT ref:0:8:CACTCA ref:1:10:ACTAAAGATGG 4 7095 +GGCC ref:0:4:TCCAAAGCGCCCTGG ref:1:3:CGACCATCTTAA 3 9 +CAATGCCATCC ref:1:10:TTATACACTG ref:1:10:TACTGGATTGCT 5 28416 +CCTTTAGCCCGAATAT ref:0:16:TCCCCGGA ref:0:16:TGAC 10 27846 +AA ref:0:2:AGTTTCGTCCCTC ref:0:2:CTTCTACC 6 126 +TTTAAAGTCAGTGGCG ref:0:16:GCGCTA ref:0:16:CACTATT 10 6608 +TCCAGGATCGCGACCA ref:0:15:AATCCAGCCTCTT ref:0:16:AGGGA 5 328 +CTGGTAGTTGCCTCTA ref:0:15:TAAATATAG ref:0:15:TTGTGCCGAGC 6 456 +G ref:0:1:CGC ref:1:0:ACAA 1 1 +CC ref:0:2:TCG ref:0:2:G 2 12 +CTACGGAT ref:0:8:GAAGACCA ref:0:8:CA 5 819 +AACGGGCCTCGTT ref:0:13:ACTCTGT ref:0:13:GGTTCC 5 6090 +ATA ref:0:3:TCACGT ref:0:2:GGGAG 1 4 +GGACTGTATATCCTC ref:0:15:GT ref:0:15:GCAGCGAACTTGAT 7 6412 +CATGA ref:0:5:GCCCTCTTGCCACTC ref:0:5:TGGGAGGTTGC 3 828 +CTAGAATATGACCTG ref:0:15:ACGGAAGC ref:0:15:T 8 160 +ACCTCG ref:0:6:CACAGAGTAGTGT ref:0:4:TGTG 3 572 +TAGGTGGCGATCAACC ref:0:16:ACAAGG ref:0:16:CGAACAC 9 578 +GCAGGTTAGCCGGC ref:0:14:CCTA ref:0:14:TCG 9 104 +GCT ref:2:1:TTGCACAGAGGG ref:1:2:TC 1 4 +A ref:0:1:CGTGCTCTGAAG ref:1:0:TCCCG 1 2 +TACAT ref:0:5:ATGGCTCA ref:0:5:GGTGTGC 4 150 +TTCGATGTGTGCTCCT ref:0:16:CTTCGGAGACGTTGG ref:0:16:TACCTC 6 16974 +TCATGTAACAGTTG ref:0:14:GT ref:0:14:ACCTATTTCTCAGA 6 7200 +TCCTGCGCATTGGTTA ref:0:16:A ref:0:16:TGC 12 12 +CTAGCG ref:0:5:GAACTCCTTGTCTC ref:0:6:GC 1 28 +GTCAGACGG ref:0:9:G ref:0:9:GGTGGGATCGGGTT 2 240 +CATGCGC ref:0:7:ACAG ref:0:7:ATGCTCTTC 1 30 +A ref:0:1:AAAAAAGGCC ref:1:0:GT 1 6 +T ref:0:1:TATAAATTATCCA ref:0:1:TTCGGGGAACCGTAGT 6 20 +GCTAG ref:0:5:GTGTTAAGCCACAG ref:0:5:AA 2 594 +TACACGTAATCC ref:0:12:GCTTTGATTTTGCCAG ref:0:10:CTGCCTTGG 7 8182 +ACTT ref:0:3:CTAACGGTGGGGAC ref:0:4:CTCGATGGA 2 2 +GATCGCTACC ref:0:10:CCCCC ref:0:7:ACTTTCGC 3 33 +TTATTTTAACGTTCA ref:0:15:AGACAGGC ref:0:15:GGGAGACCCAC 10 104390 +GCAGCTCATCAGGT ref:0:13:TTA ref:0:13:TTCTCGCGGA 6 96 +TAGTACCT ref:0:8:GTGA ref:0:7:CCACTTATC 2 104 +GAGGGTGA ref:0:8:GA ref:0:8:TGGTAT 4 78 +CCAACTGAGCTATAA ref:0:15:GATCGGGG ref:0:14:TTTTTAG 8 109725 +CTCCTTA ref:0:7:AAATGCAT ref:0:7:TACGGG 4 4368 +ATTGCGTGAATTGGT ref:0:15:AACACT ref:0:15:TCAACGTGG 8 824 +AACCGC ref:0:6:TGGCGACGAT ref:2:4:GCGT 3 714 +CCCGGAGTAC ref:0:10:CGCTAGGTCGCT ref:0:10:TCGCTTTCC 7 645428 +CAGAC ref:0:5:A ref:0:5:GCTGCTC 1 16 +ACCCGAATGCTCC ref:0:13:TG ref:0:13:ATGGGTACCGGC 7 499 +GAACTTACAATCC ref:0:13:ACATATCA ref:0:13:T 7 417 +AGGCAGTGTTC ref:0:11:CTTCCCATAA ref:0:10:GTACCATCCCT 7 2925 +GAGGACTAA ref:0:9:G ref:0:7:CACAAC 3 66 +GTAAATTC ref:0:7:TCAAA ref:0:7:CAGCCCCTGTCGTGT 1 63 +AGCGGTGTTCTCTTG ref:0:15:CTCAGTCTTTC ref:0:14:TGAAGGGAATTT 3 2176 +TTGGTAATTGTC ref:0:12:AAGGGGGTTAT ref:0:11: 6 3119 +TGGCTGACCATT ref:0:12:CACACA ref:0:12:C 7 3 +AAATCTATGAACG ref:0:13:CGA ref:0:13:TACTCGCGACTTGT 6 1076 +CGTAAG ref:0:6:A ref:0:6:GCTA 3 8 +TGTGAACCGGT ref:0:10:CC ref:0:11:GCAAAG 4 50 +CGATAACA ref:0:8:CAAGACGAGCCCAACT ref:0:8:ATGATAG 3 7276 +ACGATTACGCGGAGAC ref:0:16:CGTGACTCAGTG ref:0:16:ATAGC 6 2160 +TAGCTCGGTAC ref:0:11:ACGCTCGGACTTTCCT ref:0:11:CC 2 54 +CCTTTGACGAT ref:0:10:TGCATCTCGCAG ref:0:11:TATTGAGGTGGTTT 5 16756 +CACCATATATGGCC ref:0:14:AGCATTCCTGC ref:0:14:GTACTTGTT 6 18360 +TCTGAT ref:0:6:GAAGGATTTTGCCTT ref:0:6:ACCTGATCTCTAGTT 6 6084 +TGTCACCTGGCTG ref:0:13:TTGTACC ref:0:13:ATTTAGC 7 78 +GTAACGTT ref:0:8:TCCCTCGT ref:1:7:CTATCTACGCG 3 600 +GCAAGCCAT ref:0:9:TGCC ref:0:9:TTGTAAATCATG 3 344 +AGTGGTGATCGTCC ref:0:14:GTGA ref:0:14:TCTAGACATGAATATC 6 5808 +ATCATTATCGCAGCC ref:0:15:TGGATTACGTAGC ref:0:15:TGTA 6 420 +TAGCCCAAAAATGT ref:0:14:CTACACGTCAC ref:0:14:CGAGGGA 9 337272 +GCGGACCTCTCAA ref:0:13:AATACCCCAGTG ref:0:13:CTGTA 5 4920 +GCTTCGATCCTAT ref:0:13:CAACAGTGAATCG ref:0:13:GGCCGCTACCAG 6 12276 +TCACTACATTCTCTAT ref:0:16:TAGT ref:0:16:TTCGA 11 8374 +TTGCA ref:0:5:ATCG ref:2:3:CTAA 1 20 +GGTAGCTGAT ref:0:10:TCT ref:0:10:TCCGG 6 54 +AGAAATA ref:0:7:ACC ref:0:7:TG 5 240 +T ref:0:1:A ref:0:1:AATTACG 1 4 +GGCACAT ref:0:7:AGCTAA ref:0:7:AGATCAG 3 18 +GATGGCCCTG ref:0:10:ATAATA ref:0:10:AAACCGAAGGCT 4 378 +GCTTGCATC ref:0:9:CGGG ref:0:9:A 6 46 +CGA ref:0:3:TAAGTACATG ref:0:3:AGGGATCGCATCAC 4 20 +ATTGTTA ref:0:7:GGGAAGAGCTAT ref:0:7:TTTACC 1 368 +GA ref:0:2:AGCTAAAATTTG ref:0:2:TGAGCACTC 3 12 +AGCGA ref:0:5:CG ref:0:5:CACTTTCGTCCC 2 40 +GTGACAGTCC ref:0:8:TACAGGG ref:0:10:AGTTAAGCCG 2 18 +GGT ref:0:3:TTGAAGTGG ref:0:3:CTTTC 2 19 +GAGTTGCATTACGAGA ref:0:16:CTTACTCA ref:0:16:TGTGCAGCGCAT 7 24921 +TTTCT ref:0:5:TAATGTA ref:0:5:TCACTAGTCTCTA 3 84 +ACA ref:0:3:G ref:0:3:GCATGTCTGT 2 24 +AACTATTATT ref:0:10:TTCATGGATA ref:0:10:GTA 6 3612 +AATAACATCTCAGTCA ref:0:16:GTTAGT ref:0:15:AAAG 8 280 +TAAATCTTT ref:0:9:CTACCGCTG ref:0:9:TCTGCGACGGTACG 8 809628 +TCC ref:1:2:A ref:0:3:CTCTATTTATCG 1 3 +GATAAACGATCTG ref:0:13:CTTGTGTTGCAC ref:0:13:CACTTT 7 132 +CTAGAA ref:0:6:TTGACCTT ref:0:5:ATTATTGCCACG 3 120 +TG ref:0:2:A ref:1:1:GACCG 1 6 +AGGGCTATC ref:0:9:CTTAGA ref:0:9:AAAATTGCG 5 2688 +ACCAG ref:0:5:GCGTGGCTACCTTGTG ref:1:3:GGTCGGC 3 12 +GCGGGTTCTA ref:0:9:TCTGTCCTCGCC ref:0:9: 4 148 +CCTAGGCTCACAAGCA ref:0:15:AACATTGG ref:0:16:A 10 65 +GCCCGAA ref:0:7:CCTCTTAGAGTAA ref:0:7:AGCAAATTA 2 184 +TCGTTAAC ref:0:8:GCT ref:0:8:CATAGCTCCGACTT 4 968 +GTCCGCTGTC ref:0:10:GGTTAGAATGGGGA ref:0:10:TGTATCCTCGTAGTTA 4 93300 +CCCAACAC ref:0:8:CGAACAGGTTGTGTA ref:0:8:CACACCGAAGGTTCAA 3 792 +ACTGACAAGTG ref:0:11:GATCCTGCAGT ref:0:11:GCC 4 40 +ACT ref:0:3:CAGCCACATGAGTCTC ref:0:3:CTTAGA 2 32 +AGCGTTTCTATCTGAC ref:0:15:TATAGTAG ref:0:16:TCGA 9 2424 +CGATTACGG ref:0:9:CCAACTAC ref:0:9:AAGAGGTCCCACG 3 1134 +ACCTATCCCCGTTGA ref:1:14:GCCGGCCATCCTC ref:0:15:T 7 2536 +C ref:0:1:CCAGATAG ref:0:1:GTTCCGC 2 6 +CA ref:0:2:GACCATACCCTA ref:1:1:ATTAGCGC 4 18 +TTCAGCA ref:0:7:ACCGTCGCTGTG ref:0:7:AGCAACCC 1 60 +TGGG ref:0:4:GCTAGCGACCAGATT ref:0:4:CCGCCCGGTAAG 4 16 +AA ref:0:2:GATTTAGTCGGG ref:1:1:TAGGGCCGCT 5 1 +GTAGCACACACTGGAC ref:0:15:AGCTAGCGTG ref:0:16:AGCTGCGCCT 9 4872 +AGTATGCTCGCC ref:0:12:CGTTCAATTTG ref:0:12:TA 6 60 +GGACC ref:0:5:CGGCAGAC ref:0:5:TACATACACTAG 2 440 +AGAGAACGCTATTTTT ref:0:16:CTCAACCGT ref:0:16:T 11 13728 +TGA ref:0:3:ACAC ref:0:2:CC 3 42 +AAGAC ref:0:5:CGAGACTCAAGTTT ref:0:5:GCTAGT 5 152 +GCAGT ref:0:5:TCAGGATGCCGG ref:0:5:TTACACCGGTTT 3 96 +GTATGCAGACCAAT ref:1:13:GGTA ref:0:13:C 9 33 +AAACGGACGCAGAGCA ref:0:16:AA ref:0:16:AGCGGTGTCGTGGCTC 6 24192 +GAAATTAGTA ref:0:9:TAGTTGTACTTTATT ref:0:10:CTACACCTCCTT 5 11718 +AATGGGGG ref:0:8:A ref:3:5:C 5 12 +TCCCTGTTATGCACCT ref:0:16:GTAAACGAATC ref:0:16:GTTCCCC 8 22310 +CCTGATG ref:0:7:ACCCGCCCCCA ref:0:7:CGCCCTTGAATGGA 1 192 +TCTTCCTTGGTCT ref:0:13:CAAGGAT ref:0:13:CTAC 8 9680 +GTT ref:0:2:CACAGTCG ref:0:3:TCGGA 2 15 +TACTAGTTTGAAAA ref:0:14:TTTTACACGGTCG ref:1:13:CTGTGTGGTCC 6 30464 +GGGATGAG ref:0:8:TC ref:0:8:AAGCGGACC 4 144 +G ref:0:1:CGTAGCGGGATTTCGC ref:0:1:AACAATA 4 48 +ACTCCCGTCGGCTTG ref:0:15:TAG ref:0:15:CGGGCACCGGCT 7 3500 +TAGTGGTG ref:0:8:AA ref:0:8:CGTC 5 387 +ATCCAGG ref:0:6:GTAGCAGATT ref:0:7:GTAGTAAATCCA 3 65 +GCATATGTGGCAGT ref:0:14:CATCAACGTGC ref:0:13:CACGAAGTCC 7 900 +GGCGGTAGTTGC ref:0:12:CTCATA ref:0:12:AA 9 91 +TCAGCCGCAC ref:1:9:GCTTGTAGCACAG ref:2:8:GGAGGT 4 368 +ACATAAAGAACTTT ref:1:13:GAGTGAGC ref:0:14:AGCT 7 270 +ATGTG ref:0:5:GGAGTGTTAATTCC ref:0:5:TTGGCAGTTCAC 6 2783 +CACCAGGA ref:0:8:AGCGCGGCCAGG ref:0:8:TA 2 285 +TGTTAATAAA ref:0:10:AGGGCAGATC ref:0:10:ACTATTGACC 7 379200 +CCGCAGGG ref:0:8:TGGCTGA ref:0:8:GCTGTCG 5 4209 +GGGG ref:0:4:TTTAGAGAGATTGTG ref:0:4:AGTCCGAT 3 225 +CATCATGCTTT ref:0:11:TTAGTCATC ref:0:11:ATACATATCAA 5 378 +GCTCGGTAGTC ref:0:11:AGGGT ref:0:11:GAA 6 216 +ACACTT ref:1:5:TTTCCTC ref:0:6:CACTTATCCCCA 1 9 +ATCACCCT ref:0:8:AGCG ref:0:8:TCTTCCCCCGA 3 19383 +CGAGTTTTGT ref:0:10:CCC ref:0:10:TACGCGTGAGCCTT 6 23826 +TCCTAGCTAGATT ref:0:13:GGGGCGCATACAAG ref:0:13:TGT 5 360 +AGGAGACG ref:0:8:CTAGGA ref:0:8:GTCC 3 200 +ACAA ref:0:4:CAGCTGGA ref:0:4:TCACAT 2 30 +TACCATTGGCC ref:0:11:ACACCCAGGGACCGG ref:0:11:ACAAAGTAACACAGG 4 150 +ACCAGGCTACTT ref:0:12:CGGTTATGCGCGA ref:0:12:CCCAAGGGGCTGTGTG 4 27072 +ATGTCTGTAAC ref:0:11:TACAAAATATA ref:1:10:CCACA 6 2500 +CTCC ref:0:4:CAGCTA ref:0:4:ACTGCCGCCCTGGTCA 3 330 +TACGAGTAGGTAGTC ref:0:15:GATCCCGAGGACCTG ref:0:15:ACCATCCGATCC 7 68688 +AGCCGTTAA ref:0:9:TCCTTCGTGCCTCCGA ref:0:9:GGCATC 4 11820 +GACAG ref:0:5:AATTGGT ref:0:5:TGCTC 1 18 +GTACCACCTTCGAG ref:0:14:CTAACCTGAGCGC ref:0:14:CAGATCCCG 5 672 +TTC ref:0:3:G ref:0:3:CGACA 3 44 +CGGATCCACGCAGTG ref:0:15:GAAT ref:0:15:GTTCACAAAGATCC 7 5544 +TTCCCACGT ref:0:8:ACGGTCTACC ref:0:9:AGGA 3 1582 +CCCAAAGG ref:0:8:AGCAAGCTGA ref:0:8:CTTATGATGCTGC 5 2139 +TACTCACG ref:0:8:GCTA ref:0:7:GTTT 4 24 +GCCGCTCACGG ref:1:10:CGTA ref:2:9:ACCTTAACGTTGG 1 48 +GTTGGC ref:0:5:CGGGT ref:0:6:CGCG 3 21 +TAATTT ref:0:6:GGATCGTGTAG ref:0:6:CACAT 1 54 +CATGCAAGCGTGCC ref:0:14:AGAGGACT ref:0:14:AGAGCAACGCCC 4 2772 +ACC ref:0:3:GGCACT ref:0:3:GCCAAGCCTGTATTG 3 12 +CTTCATCGGGCATCA ref:0:14:CTGTGAGATACC ref:0:15:TGTGTTCATTAGC 7 141792 +TGCTTAGCCGCATG ref:0:14:TATAAAA ref:0:14:CAACGGGAAAAA 10 2982265 +TCTGTC ref:0:6:TTTCCAGCT ref:0:6:TGTT 2 328 +AGAACTGTTACTG ref:0:13:GTGCGGCGCT ref:1:12:GGGTGAGC 8 53354 +GGCGAGACCGAC ref:0:12:ATCG ref:0:12:C 9 40 +ATAGGCGTGACATAA ref:0:15:TCATCTTA ref:0:15:CCCG 9 5148 +CAAATACCTA ref:1:9:GCCGGGTAT ref:0:10:TTCGGACAGCGCGCAC 5 1626 +ACCCCTGGATTTGTA ref:0:15:GTCGATC ref:0:15:CGGGC 10 18180 +AAGAGATTTTGAGTC ref:0:14:CTCATTGTTG ref:0:15:GTGAGCGCCTTACAAG 7 2471796 +ATACGC ref:0:6:CTCCCACTG ref:0:6:GTAGTGTCCCGA 3 202 +ACCTGG ref:1:5: ref:0:6:CGTTGTGGT 1 27 +GCTAGA ref:0:6:CATGC ref:0:6:TGTTTCCCTC 3 48 +GTG ref:0:3:ACCGTAGGCGTCTAGG ref:0:3:ACTGTTCT 5 231 +C ref:0:1:AGTTGAATGT ref:0:1:TTCTTGCCTGAGGGTA 6 33 +ACTAGT ref:0:6:AT ref:0:6:CAACTTCACC 2 78 +GTTCAGTTA ref:0:9:GGAGTCGCACTCAG ref:0:9:CGGTCAACTGG 6 91800 +GTAAGG ref:1:5:ACGGGTGTTAT ref:0:4:ATCTTGTA 1 44 +TCTCAAAGTGTAT ref:0:13:GAAAGTTACAG ref:0:13:A 6 120 +GCAGCCAGGAGC ref:0:12:CC ref:0:12:GCGA 7 72 +CGGTTTTCAA ref:0:10:GTAG ref:0:10:AACGGCCCATAC 3 504 +TTAGAAGCGACGAGA ref:0:15:ATGCATCTTCC ref:0:15:CCGAATTTTA 9 130188 +GCAGGGCAATT ref:0:11:GGATCGA ref:0:11:CGTGGATAAGGA 7 17941 +TTGGTAGACC ref:0:10:TCAGTTGTT ref:2:8:CGAACAACCG 2 43160 +TGATGTCTCCCGGGA ref:1:14:CAATACTGTAGTT ref:0:15:CCGGCC 7 52416 +TTTGTTTGTA ref:0:10:GGAAA ref:1:8:CCTTGTTAGGCCG 2 288 +CC ref:0:2:GCCTTTCTCGGAAGA ref:0:2:CGGTT 2 36 +CTGCATATTGAAGAAG ref:1:15:GGCGCG ref:0:16:TGAGAATGCAC 7 630 +TGGTTCAT ref:0:8:GTGGCTTCAGG ref:0:8:GT 1 18 +CAGA ref:0:3:GCGCTGTC ref:0:3:GG 2 28 +TTGCTTCCCG ref:0:9:AATCATT ref:3:7:TAC 2 60 +TGGACCGTT ref:0:9:TTAAT ref:0:9:ACTCTGTGTT 2 220 +TGGTAAGCGTT ref:0:11:AA ref:0:11:CTGAGT 5 16 +GG ref:0:2:AAAATGTGGACCAAC ref:0:2:CA 2 18 +GGGAG ref:0:5:GGATGGTTGG ref:0:5:CCGGA 1 245 +GCATAGT ref:0:7:T ref:0:7:GCCAGGCACA 2 312 +TTATAATGG ref:0:9:A ref:0:9:GGGTGAGCTAACCGT 3 234 +CCTGCGGTTGGTGGAA ref:0:16:TT ref:0:16:CC 12 18 +GAC ref:0:2:GGG ref:0:3:GGAAGAACACCACGTA 2 312 +AAA ref:0:3:GCTCCCATCATGCCT ref:0:3:CTAG 4 240 +GAACGAGGCAATA ref:1:12:CAGTCTGTTCTAAG ref:0:13:ACACAAGCAGGGGGCG 3 400 +TC ref:0:2:AGCTAAAGTGCCAGCC ref:0:2:GCTTAATA 6 120 +TGATTGATAAGGGTC ref:0:15:CC ref:0:15:GTGAACTATTCTA 8 1152 +CA ref:0:2:ATGACAGAG ref:0:2:TCG 2 4 +TTATTTCCCCAGCTTA ref:0:16:CGGGAATCGCTGAG ref:0:16:CTTAGT 8 88128 +AACCCCGAACCGGCTG ref:0:16:GTCC ref:0:16:TGAAAAGC 8 20 +TAACTCACTTT ref:0:11:CGGTGACGCTGTAGA ref:1:10:ACATAGCT 4 1926 +GAGCGAATTATCGGAA ref:0:16:CATTT ref:0:16:AGGTTCAGCTAGGC 5 24 +AACAAGTGGACA ref:0:12:TATACCCAAG ref:0:12:ACTATTA 4 738 +CCCGCGTAAAGCT ref:1:11:GACACTGGCATG ref:0:13:GCGTTGTCAG 6 5808 +A ref:0:1:AAACGCGCA ref:0:1:GCGGGGCACATCC 4 8 +CTTAGAGA ref:0:8:GTCCGTTTA ref:1:7:T 4 60 +CCAGTTACGCTTC ref:0:13:CGTC ref:0:13:CTGAT 8 924 +TTCGGTAC ref:0:8:CAAAGA ref:0:7:ACGGAA 3 45 +TTG ref:0:3:CCATTGCAATGT ref:0:3:ATATCAAGCGGTAGT 6 24 +TCTGCGG ref:0:7:AGAAATAGCTTTTAA ref:0:7:CCAGATCATTG 7 56916 +ACCTGTAAATC ref:0:11:AAAATCACTAAA ref:0:11:GGCGCT 4 576 +TCCTTGAGGCCGTAC ref:0:15:CTGATG ref:0:15:AATT 10 6292 +A ref:0:1:CGAATGCTGATA ref:0:1:CCGTCTTGCT 7 44 +T ref:0:1:CCACCTGCACTTGC ref:0:1:TCGGTTGCGACGC 7 9 +CGTCTCG ref:0:6:ATGGGAGC ref:0:7:GCGCGGCGGA 5 2196 +GTATAAGAATAG ref:0:12:TCATTTATCGA ref:0:12:CA 7 7896 +CCCCTGAGG ref:0:9:CTTTTA ref:0:9:GTAAG 5 4840 +CCAGTAGGAT ref:0:7:GGATCAGCC ref:0:10:AG 3 55 +A ref:0:1:TCTCTTAACAAAT ref:0:1:GCAAACTAGTCCGC 5 20 +TCTCACCGGAAATCGG ref:0:16:TCAAA ref:1:15:CGCTAAAGATGCCT 7 896 +TTCG ref:0:4:GACGGA ref:0:4:CCAACT 3 696 +C ref:0:1:TCACGTGTTATGGTA ref:0:1:TTCGAGTGCTGACGT 9 6 +TCCAAATTCT ref:0:10:ACGAT ref:0:10:TTTCCAC 4 1134 +AAGGCCCCT ref:0:9:GCTACCC ref:0:8:GCCGCG 3 24 +CT ref:0:2:AGTGCCCTCAC ref:2:0:GGAAAA 1 3 +TTGGGGAC ref:0:8:AATATCATAAGTGCGT ref:0:8:CATATTTTCC 7 77463 +GGGAGAG ref:0:7:TAGCCGAA ref:0:7:GTTACATATCA 5 5117 +CGTT ref:1:3:TAATGTCCCG ref:0:4:AAGA 3 108 +AAAGGCC ref:0:7:TTC ref:0:7:GACAATATGGACCC 2 588 +TGTTATGGGG ref:0:8:GAGAAGTC ref:0:10:GAA 5 9 +AGCTAGTTTAGCGAAC ref:0:16:TCCGCGGGCAG ref:0:15:CGCGCTTTGG 8 496 +CTAGTCGAG ref:0:9:ACTGCT ref:0:9:CGCGAGTACCA 3 95 +CGTGTCG ref:1:6:GTAACAGAGG ref:0:7:ACATGAGTTTGGGA 3 8364 +TGTCG ref:0:5:TCCAACGC ref:0:5:ATGACTCTA 2 69 +GCACGCATACT ref:0:11:CGGA ref:0:11:TGTGGCGATGGTA 6 6226 +CGTTCATCA ref:0:9:AGGAGCGCAATCTCGG ref:0:8:GTTCGGTTAGAGATG 3 1554 +CATTCGGATGATA ref:2:11:CGCATGTGCTAGG ref:0:13:GTT 4 58 +ACGGG ref:0:5:CTC ref:1:4:CCT 4 182 +GGTCCCTAATGAAC ref:0:14:GATCATTGGTCC ref:0:14:C 7 6300 +CT ref:0:2:ATATA ref:0:2:GTGATG 3 42 +CGCCCAGGCCTCTTAG ref:0:16:ACGAACCCAATTCC ref:0:16:ATAAGCC 9 222200 +ACTACGTCGCTTA ref:0:13:GTCGGACC ref:0:13:TCCTCAACCAAGAA 5 2400 +TAGCC ref:0:5:TTCA ref:0:5:GTCGCTAGTCCCGTT 1 90 +GTACCTCCGAAACA ref:0:14:CGG ref:0:14:TGTGGTTG 10 1961 +TCAGGC ref:2:4:GGAATGTTGAGGT ref:0:6:GCATT 3 792 +CAA ref:0:3:ACGCCAAA ref:1:2:TTG 1 90 +CAG ref:1:2:GTATAGTACG ref:0:3:AGTA 2 5 +TGAAA ref:0:5:GATGGCGCCAAGGG ref:0:5:CAGAGT 3 1470 +GGCGC ref:0:5:GTGATCTA ref:0:5:AAACAAAGTTGGCCGG 2 391 +ACGCAGAGCGTGACAC ref:0:16:GGATTT ref:0:16:CCAGAACTTTGCATT 7 2970 +TTTTGATCCGTATGAA ref:0:16:CTGTCATGGG ref:0:16:A 9 800 +GCGTG ref:0:5:ACT ref:0:5:ACTTTAATAAAGTAT 3 64 +CCGGCATCC ref:0:9:CCTCTCATAC ref:0:9:TAGCT 3 960 +GGGGTTGTGTCGCG ref:0:14:A ref:0:14:GGTACCGCTGCA 8 24630 +CACGATGGGTTC ref:0:12:TTTCGATGTA ref:0:12:ACCTGCGCGCG 2 825 +TCGTTTAAGGAC ref:0:12:ATCGAACA ref:0:12:CGATACTA 7 912 +TGGG ref:0:4:GGCACAAGGA ref:0:4:C 2 25 +CTGCAGGGAAAC ref:0:12:GGTTAGA ref:0:12:CAGCTGTCTGAA 7 45678 +CT ref:0:2:CCTTGAGT ref:0:2:GTA 1 12 +AACGGA ref:0:6:CTCACCGAG ref:0:6:GGACCCAC 3 1824 +CCCAAGGCGC ref:0:10:GCGCGGCTGGGCT ref:0:5: 3 18 +GGCTTTTAGGACGAG ref:0:15:TGACGTCTC ref:0:14:AAGGGTTACTAAGT 6 10100 +CTC ref:0:3:CAGGCTAG ref:0:3:GGAACCTGGCAC 3 40 +TTGTAT ref:0:6:GGGGTTCTGGTCC ref:0:6:AAAGACAACTCGGGA 4 8964 +TAGCCCCACTTGGC ref:0:14:A ref:0:13:CCTATCCGT 8 1488 +T ref:0:1:TTTATC ref:0:1:GCTTCACCGTTTTT 3 28 +CTTGGCACTGCTGGT ref:1:14:TGTCAGGCCAT ref:0:15:TTGGATTCAT 6 14586 +GAAGTGCCGCGATGA ref:0:15:CAGAA ref:0:15:GTGAGACAATCCAAGG 7 107448 +CTGTTCTTTCCA ref:0:11:AGATATGTGACG ref:0:12:AAT 8 145800 +GTGAG ref:0:5:CGTCACAAAAGGG ref:0:5:TGCGCTCCGAGATTCG 4 608 +GTATCACAGACGC ref:0:13:AATTG ref:0:13:AATAAGTGCGCGA 7 1984 +CCTGCTTCCGG ref:0:10:GACCCTATATAAGA ref:0:11:AAGCCTCA 5 38718 +GTGGAAGGTTCGGC ref:0:14:GCGCGCGAA ref:0:14:TCTGACTC 8 282720 +TTACAGATGTAC ref:0:11:CTTCTG ref:0:12:GTGA 4 1 +CCCATCCTACCT ref:0:12:CGAGGGCGCCCCTTAC ref:0:12:A 4 64 +ACTGCTCCATGG ref:0:12:TA ref:0:12:TAAGGCACTGAGG 5 1566 +TAGTCA ref:0:6:TTGCAGGACTTTGC ref:1:4:GGCGTTG 4 468 +ACCGGCATGCGCGAAG ref:0:16:GGATCGCTGCTCCG ref:0:16:G 7 978 +CCCCCGAGCGCG ref:0:12:G ref:0:12:TAGA 10 336 +AGAACCAAACTTT ref:0:13:CCAGCCTAGAATA ref:0:13:GCGGATCCTT 4 4518 +TCTCTATTT ref:2:7:CT ref:0:9:ACTTACCCTC 2 168 +CCCAACGGGGCCGT ref:0:14:TTGCCCGTCTC ref:0:14:GG 7 2380 +AGTGGGCCCATCA ref:1:12:TGCACTGTCCCAAGG ref:0:13:CCAT 3 42 +ATGCA ref:0:5:GT ref:0:5:C 3 5 +ACCTACCT ref:1:7:TGGGCTC ref:0:8:CT 4 180 +GT ref:0:2:CACC ref:0:2:TT 1 45 +C ref:1:0:AAG ref:0:1:TATTGGCGTC 1 2 +ATACGGGCCGCGT ref:2:10:GGCGGTTCGG ref:0:13:CTCTCCGTAGC 4 11544 +TTAAAAGTCCC ref:0:11:AGCTTCACAAC ref:0:11:GCGACTAG 7 6526 +ACTTCTATGTACTCA ref:0:15:AGAAACATCGTTGTG ref:0:15:CTTAGTGCACCGAG 3 972 +AATTGAACTACG ref:0:12:GCAGCTTT ref:0:12:TACTCGTTCTG 7 42313 +CCAAAGGTTT ref:0:10:GTCGGATATA ref:0:10:GC 6 288 +AGGT ref:1:3: ref:0:4:GCTT 1 7 +AACCAG ref:0:6:ACGTCAATGACCCGG ref:0:6:TACCTAGGCCG 4 820 +ACATGCTA ref:0:8:TCTAAACCC ref:0:5:C 3 3 +GG ref:0:2:ATAATGGGTATA ref:0:2:AC 1 18 +TAGAA ref:0:5:CCCGAAGACACTGC ref:0:5:GGTAA 2 77 +ATAGGC ref:0:6:GCGTGGTTCCGTACA ref:0:6:GGA 3 48 +AGGGTAAGGTGATGAC ref:0:15: ref:0:16:GAAGCTAGTT 8 244 +TAA ref:0:3:CGGATATACTCTATGG ref:0:3:TAGTCGATCACCGTG 6 16 +AGTTAAG ref:0:7:TAAGCATTTACAGT ref:1:6:CTCTAGAT 2 48 +CACCTGA ref:0:7:ATTAGGCCTAAACA ref:0:4:TCG 2 770 +CACCGGGGCGAAGT ref:0:14:GTA ref:0:14:CC 10 294 +CTGGCCGGAGTGG ref:0:13:GCGTCCTCCATT ref:0:13:TCGGAA 5 7320 +ATAGCTG ref:1:6:GTATTTCTGAAT ref:0:7:TATACGTACAGCAAC 3 16 +CCCAACGT ref:0:8:TGCGCCCCGGGGCGAA ref:0:7: 2 766 +GACA ref:0:4:CGATTGCCTT ref:0:4:C 1 7 +TAGCTTC ref:0:7:AACGATATTTTAGCAG ref:0:7:TTATGACATTGGA 4 1304 +GTTCGTCAAC ref:1:9:TACTCGCGG ref:0:10:CAAAA 2 760 +CTTGTTCTT ref:1:8:AGTCTGTTA ref:0:9:GCTTT 4 980 +GCTT ref:0:4:ATGGCCCGCGTCTC ref:0:4:GGAACATTGGA 1 18 +TTAGTATTTGTTA ref:0:13:CGTG ref:0:13:ATATGGGAAGCTG 7 44432 +CT ref:0:2:CGACATTTGCGCTGTG ref:0:2:ATG 2 28 +GTGTGGC ref:0:7:GGATGT ref:0:7:TACT 3 77 +AGACATCGCGG ref:0:11:TGTATA ref:0:11:GAAACTACCTCT 6 29796 +ATAAATGG ref:0:8:ACAGAGCCAGTTCC ref:0:8:CACTGGTGCAGGACC 7 3672 +GTTC ref:0:4:GGATGTT ref:1:3:CTGAGGT 2 9 +TGCGGGCTGACGA ref:0:13:GTAATCTACACAGGTG ref:1:12:AATAG 9 234304 +AC ref:0:2:CTATCACATAC ref:0:2:AGTTGTTTGCGGTGAC 4 21 +ATCATACCAGG ref:0:11:TTGAAGGTAG ref:1:10:CAAG 3 18 +AACGGGACGCGGATTG ref:1:15:TATCTTAACTCGTA ref:0:16:CGAT 7 21840 +GCC ref:0:3:CTTCGCTCC ref:0:3:ATGCGAGGTGGCCGCT 3 63 +AATGATA ref:0:7:TGGC ref:0:5:TTAC 3 70 +TAACCCTTTTCTACCC ref:0:16:AACGCTAGCAG ref:0:16:CGATCAGGG 11 2527600 +G ref:0:1:TTTAACATTGTGGCA ref:0:1:TATGGGCTCGGTTA 7 15 +AC ref:0:2:CTAAAGGG ref:0:2:CC 1 48 +A ref:0:1:GGAACGATCGGCACCA ref:0:1:TCCAAAACCG 5 20 +TCTT ref:1:3:ACG ref:1:3:GCGGAGGTAAC 2 30 +C ref:0:1:AAGGGACTAA ref:0:1:CAAGCGTGGCTGAA 8 3 +TCTGTTTTGATCGG ref:0:14:ATATACG ref:0:14:TTTTGTC 5 4530 +C ref:0:1:TGGCG ref:0:1:TGCAAG 3 1 +AAATTGAA ref:0:7:TGGGAGGTCCTAT ref:0:6:GGG 4 1008 +A ref:0:1:AGTAGTCCAACGG ref:0:1:GT 2 12 +GCGTGGGCGCTCT ref:2:11:GGGAGATG ref:0:13:CACTGCAAT 6 70374 +TAAAATGGC ref:0:9:ACATTCC ref:0:9:CTTCGGCTTTGG 3 150 +TATTGAGCCGG ref:1:10:GATCATGTCA ref:0:11:TACA 6 2720 +CGTT ref:0:4:GGCGCCGAC ref:0:4:T 1 78 +CTAACCTAGATTGGCC ref:0:16:AGTTTGTAG ref:0:16:GACTTGGAGATGGTC 5 4104 +GTGAGCGGTACTG ref:1:12:GATA ref:0:12:CCTGATAA 6 12 +CCTA ref:0:4:TCAATCCAACT ref:0:4:AA 2 135 +AAGC ref:0:4:GGCACAGGCCC ref:0:4:TGCTATCCCA 4 462 +GGCATT ref:0:6:AACCGGACG ref:0:6:GCGATA 2 90 +GGA ref:0:3:TCTTCTATGGATTCTA ref:0:3:TAT 2 6 +CTCGCCGAAAGGCGTG ref:0:16:GCCTATTTC ref:0:16:GGA 10 2160 +CGAGA ref:0:5:ACGTCTC ref:0:5:ATCCCAT 5 1710 +GACGAGC ref:1:6:TAACTATAGGCAT ref:0:7:TCGTGAACTC 4 3276 +TAAAACCGGGCATATC ref:0:16:AAG ref:0:16:C 12 72 +GCCT ref:0:4:ACAAGAGCTAA ref:0:4:TGAAGGAAGTCCACCA 6 544 +GAACCCGCTGCTG ref:0:13:GTGTAGATGCTA ref:0:13:GCAGGATACGTTACA 7 19800 +A ref:0:1:CTTCGACGGGA ref:0:1:GTAAGTAAT 3 8 +AGGCCA ref:0:6:CAATC ref:0:6:GCGTTGCCAC 2 150 +TACACTCCTGCAAG ref:0:14:CGAC ref:0:14:CACGTCCC 7 28 +G ref:0:1:CCTT ref:0:0:AAACT 2 5 +GTGACG ref:0:6:CACT ref:2:4:CCGCTA 3 64 +CTACTGTAA ref:3:4: ref:0:9:TCGACGAACG 2 3 +CGCAAATA ref:0:8:ACTTTTGCCAGGAGC ref:0:8:GCAG 4 1612 +ACTTGCGGACG ref:0:11:CATGGAT ref:0:11:CCAT 6 135 +CATCGCCGCTGCA ref:0:13:AC ref:0:13:GCATGTGGAAG 5 125 +TTGGGCCGA ref:0:9:CCG ref:0:9:CGCATGTAGTACCG 3 60 +CAGG ref:1:3:TACGTGGCATA ref:0:4:GTACGC 3 48 +ATATCG ref:2:4:GGCACCCGA ref:0:6:GACGGGAACGCA 4 102 +CTT ref:0:2:TAATTACGTG ref:0:3:G 1 4 +AGATC ref:0:5:TCAAGTCTA ref:0:5:TCGTATGG 2 27 +TATCACATCCT ref:0:11:ATTAAGGGCTTCC ref:0:11:CCC 4 188 +C ref:0:1:GGTAATTTTCGGTCG ref:0:1:A 1 4 +TCC ref:0:3:ATCTAAACTTTCCC ref:0:3:CTGTA 2 475 +TGAACACGTATTTT ref:0:14:AAGTCTTAC ref:0:14:ATATAAATA 6 2580 +AC ref:0:2:AAACGACAATAAGTAA ref:0:2:ATGAAGT 5 98 +GTTGAAATCACTT ref:0:13:CTCCAGTGGGC ref:0:13:GC 9 13600 +AACTTACTA ref:0:9:GACTAGTACAGATTTT ref:0:9:TTCCCACGATG 4 168 +CCTGGACA ref:0:7:GGGCTGTGTCGG ref:2:6:G 1 20 +CCGAAAGGAT ref:0:10:TATCTGGCTACAG ref:0:9:GTTA 5 6510 +CCTAATAGACCCTAG ref:0:15:TAATTCGGGTGT ref:0:15:CGTGGCTCT 6 48000 +GTTT ref:0:4:TGCATGACTG ref:0:4:AGTCAAGGT 3 80 +GGCCTCAATCTTTA ref:0:14:GCATGCCAGGACC ref:0:14:AGTGAA 8 2856 +GAATATTAAAGTA ref:0:13:CGCAGGG ref:0:13:AGGTGTGT 9 47061 +A ref:0:1:GAGTTC ref:0:1:ACGAACAGCAGGC 3 5 +AGACGAGACTCAT ref:0:13:GATATTGGCT ref:0:13:GT 7 702 +TCGTACAGACT ref:0:10:ATA ref:0:11:G 7 46 +CGCCG ref:0:5:TAGTGCAAAGGCAT ref:0:5:A 3 876 +TTTAGCAGTTAG ref:0:11:CCG ref:0:12:TTGA 6 72 +TAAAGATACCCACA ref:0:14:TTGGGAGCCAAGTG ref:1:13:GTTT 7 55550 +GCTTACGCTC ref:0:8:CCATTCGACC ref:0:10:AAAGCTAAC 2 495 +CCGAGATATGCT ref:0:12:CGCCGGTACATC ref:0:12:C 4 45 +GCTCCGTTT ref:0:9:CA ref:0:9:TGCT 6 475 +AGTGATTC ref:0:8:TTCATGGCTGA ref:0:8:ATCAGGTACTTCACT 3 32 +GCCC ref:1:3:ACCCGTCT ref:1:3:CTGTTGGCTTGA 3 52 +TGGCACACCGAT ref:0:12:AAAGA ref:0:12:CCGCTGACTGTT 4 10470 +GG ref:0:2:GAATTC ref:0:1:CCGA 1 7 +GCTATCGATCT ref:0:8:AGAATTTATAA ref:0:11:TAG 2 48 +A ref:0:1:TCCCT ref:0:1:GTCTAGTCCCGTTT 5 6 +CA ref:0:2:CCGCAT ref:0:2:GT 2 18 +GCGATTTCGT ref:0:10:ACGAAGTT ref:0:7:TCCACCGGTG 5 40996 +GTGAGCTCCCCGACC ref:0:15:GCCGGGTGGTCAGGA ref:0:15:CC 6 2520 +CATACCT ref:0:7:ATCGCCCGAC ref:0:7:TCTA 3 219 +AGGA ref:0:4:TTAGCCAA ref:0:4:GGTCAATCCA 2 27 +GCGGCTACAAAAGTCG ref:0:15:TTGAGAGTCTT ref:2:14:GTT 8 1740 +TTGCG ref:0:5:ACGAG ref:0:5:TA 3 180 +TGTGGAAATA ref:0:10:CGC ref:0:10:GGTCCTACGCGTAAGA 5 6840 +CGGCCGTG ref:0:8:GTTAGGGA ref:0:8:TCCC 1 1 +ACACAACTACGGCT ref:0:14:TCTGGCGG ref:0:14:CGATTT 7 8586 +CC ref:0:2:TTTCGGCTACCATCTA ref:0:2:A 1 30 +AGACG ref:0:5:ACCGTTCT ref:0:5:GAGGGTTT 4 132 +CTCGCAAAGTA ref:0:11:CGATGTTGCG ref:0:11:TATGCAA 5 4176 +AGTCCAGTA ref:0:9:TTGCTGATCTTTTAC ref:1:8:CTAT 4 14511 +GCTT ref:1:3:TGAG ref:0:4:GGTTGG 3 15 +CTC ref:0:3:ATACAAG ref:0:3:AGCAG 4 24 +GATATGGCA ref:0:9:TGTAG ref:1:8:CAGC 4 16 +CGTATGACGCCGCAT ref:0:15:ACAG ref:0:15:TAGGGAATGAGGAA 7 10148 +AGGAA ref:0:5:ATGTACCGGCACCATG ref:0:3:CTTAGTT 2 16 +GGCGGGGTACTAT ref:0:13:A ref:0:13:AATCTCCCAG 9 584 +GGATAATC ref:0:8:CTAAATCGCCC ref:0:7:GAG 3 1512 +GC ref:0:1:ACGTGTA ref:0:2:CATGGGGCGT 2 8 +CTCCATCGAGT ref:0:11:AGTCTGTAGTTTCACG ref:0:11:CAAAGCGCGA 5 47676 +ATATCC ref:0:6:AAA ref:0:6:A 4 14 +T ref:0:1:TTACGTGCAG ref:0:1:CCATCACTAC 4 6 +TCAACCCGATGGGATT ref:0:16:AAAATATTTA ref:0:16:CCTGCCTATC 5 90 +CCCTATGAAA ref:0:10:GAATAGA ref:0:10:A 6 836 +ACG ref:0:3:ATAATT ref:0:3:TTCTAACGAGGCAGA 2 407 +AGCGGGAGACTCCGT ref:0:15:CCCTGCCGTAC ref:0:15:GGACACTCGC 6 660 +TG ref:0:2:CATGGTCCACAGAC ref:1:1:CAGCACCAC 5 4 +ACTAGATCCTGGGCGT ref:0:16:GTGGCTGTGTAG ref:0:16:CTTGCCTTTCC 8 381060 +GGAATTGAATGG ref:0:12:TCTTGGGAGAAGACTC ref:0:12:TAGGGG 6 40020 +ATGACCT ref:0:7:CA ref:0:7:ACTG 4 50 +GCTTG ref:0:5:TACC ref:0:5:GCGAACTCCGGGTT 3 2190 +CTCTTGTGCGC ref:1:10:ACT ref:0:11:ACG 8 126 +TCCG ref:1:3:CAA ref:0:4:ACC 1 18 +AGC ref:0:3:T ref:2:1:ACCACAT 1 12 +GAATCGTCATT ref:0:11:CGTA ref:0:11:AGCCTTGTG 4 81 +GATCACGCG ref:0:9:CGT ref:0:9:AAATCTTGT 6 3330 +C ref:0:1:GGGTGAG ref:0:1:CACTTGAGCCTGC 4 40 +TGAGCGTCCT ref:0:10:ATGGTACACC ref:0:10:AGGCGGGTAAAAGACC 5 300 +TTCTGTGGC ref:0:9:TTGAGACTCACATGT ref:0:9:CCGAG 4 1056 +ACTT ref:1:3:CGCA ref:0:4:CT 1 26 +GGACTGCGTTCCCGTG ref:0:16:CGAAGAAACCGT ref:0:16:A 9 2768 +TTTT ref:0:4:AGATC ref:0:4:CACTGTT 3 448 +CGTTGAA ref:0:7:CCCTCCAATGG ref:0:7:TAGGGCTGAGC 4 17640 +TGCCGCAAAGTGCTAG ref:0:16:CC ref:0:16:GCCAGACGC 9 1020 +ACAACTAGTGAGCTA ref:0:15:CTGCTGAAC ref:0:15:AGGACGATGG 5 240 +AG ref:0:2:TAAGCCCGACATG ref:0:2:CCTTACAGAG 4 40 +ACTACGAGCCTGGACG ref:0:16:GATGATAGGCCGCA ref:0:16:GCTGC 6 1088 +CGATACCGTGAAG ref:0:13:ATATA ref:0:13:GTTGCA 6 6 +GAATTACATCATGGA ref:0:15:AGTAT ref:0:15:ACGACTGTCTAACTGC 7 15640 +C ref:0:1:AAAA ref:0:1:TGAA 3 25 +GGTG ref:0:4:AAAGTGCGT ref:0:4:GATGC 2 45 +GCGCTTG ref:1:6:TTACTGACT ref:0:7:G 2 6 +AGGTGATCGACCTGCC ref:0:16:TTAGCGAGAGTTCGG ref:0:16:GGAGACTTTCA 3 684 +TAACC ref:0:5:TGTGTAAGCTACGTC ref:0:5:GCAAGG 3 270 +CCACCTCACGCTAGC ref:0:15:TTAGCTGCATA ref:0:15:AATCTGCGTT 8 38792 +CGAAGTAGCCGA ref:0:11:ACTGGCTCTGCGCCC ref:0:12:TTGGCTTC 7 5751 +AGGGAACCAGTTA ref:0:13:AA ref:0:12:ATTTTTCCAGT 6 5180 +CGTGTGCCCA ref:0:10:TAGAGCAGGTCGAAG ref:0:10:CCTACAGAC 6 43395 +AATGACGTTGGTGTGC ref:0:16:GATTCGAT ref:0:16:TC 9 120 +GGTCACAATGTTCTT ref:0:15:TCCA ref:0:15:ACTT 8 26 +T ref:0:1:AATT ref:0:1:CTCTC 1 4 +CAACAAT ref:0:7:ACGGAATGACTTGA ref:0:7:GA 3 1296 +ACCGTAAGAGG ref:0:11:TTCTGACGC ref:0:11:CA 6 216 +CTTTTATCTTGGGCT ref:0:15:GAACG ref:0:15:G 12 297 +ATCATGTCGGTTTA ref:0:14:TACTCCCAAGGGC ref:0:14:TACGACTTCCACG 5 4995 +CTATCCGTTTAGCT ref:0:14:TCTCACG ref:0:14:GGGGTT 7 138054 +GC ref:0:2:CTCCCTCGAGGCT ref:0:2:CCAG 3 12 +GTATCCGTTCGTAAGT ref:0:14:AATCTTTTAGCAC ref:0:16:ACT 6 600 +GACACTCCATATGAGA ref:0:16:GGCTGTACCTGTG ref:0:16:CCCCCAAAAACT 3 31104 +ATCCTCCGTGC ref:1:9:CCTCCCATTCGGA ref:1:10:GTGTATCT 2 3976 +CTGTGGGACTTGGGC ref:0:15:ACTAACTGTGACTT ref:0:15:TCGGGAAGACGGCGTT 2 300 +ACATAGTCC ref:0:9:TTTAGTTATA ref:0:9:CAGAGGA 5 14308 +CCCTGCTTTGTCGT ref:0:12:ACCGACAG ref:0:14:CCTCAG 7 960 +GTCGCAGTAGATGAGA ref:0:16:CCCATATTTGAATG ref:1:15:CCATC 6 6336 +AC ref:0:2:GTCTTTAA ref:0:2:GCGTA 4 18 +ATCCTAGTGAACC ref:0:13:TGACT ref:0:13:TCTCCGAT 8 10650 +CGTCGCCATAGTAC ref:0:14:GT ref:0:14:CTGC 9 48 +TTCTTTGTGAATCGC ref:3:12:GTATA ref:0:15:TCACCCACATACGCCC 5 15579 +CGAG ref:0:4:ATTTACGC ref:0:4:AAA 3 300 +AATTAAAAA ref:0:9:CAC ref:0:9:ACAGAACGACTTA 5 4560 +AATTTGGCCGAAGTT ref:0:15:AAG ref:0:15:GACTCAGGTTCGCAT 7 17496 +ACCTTGGTGACTAA ref:0:14:CAAAGGAAGAGGCGT ref:0:14:CGA 7 2754 +CCCTGAACGA ref:0:10:ACCGAATGGGTTTAT ref:0:10:ATAGG 4 1584 +AGAATCTTAT ref:0:10:GTCACG ref:0:10:GTG 7 42 +ATCGAC ref:0:6:CTAGTGG ref:0:6:GTAGTAATGGTT 6 1130 +TACTATATCGT ref:0:11:AC ref:1:10:CGTCGTG 4 36 +CGTAAGGCT ref:0:9:CCTAATGCTC ref:0:9:GTATTGTTTGCCTGC 2 72 +AAGGGCTGT ref:0:9:GTACCGTGGGCTTGGA ref:0:9:GACTTG 4 7722 +TCAGTTAAGC ref:0:10:CG ref:2:8:TAGTGG 4 22 +GTACCAACG ref:0:9:AT ref:0:9:AGGCAGGCATCCC 5 10960 +TTCGC ref:0:5:ACTCGTCCAA ref:0:5:ACAACAGACTATATGT 5 252 +CGGCCGGTAAGCGG ref:0:14:G ref:0:14:TGGGGGC 8 14 +TTA ref:0:3:CCAACGGC ref:0:3:ACCAAGACG 7 864 +TA ref:0:2:GCTTGCGACTAT ref:0:2:AT 1 10 +AAAGG ref:0:5:CGAACTTGCCATAT ref:0:4:GTT 3 101 +AACGAATGACAATGAC ref:0:16:TGACGATAAGTA ref:0:16:AGGGCTCTGACTAA 5 168896 +TTGGCGTGCTTTAACT ref:0:16:GTTTAG ref:0:16:AAACACCACAA 8 2026115 +GCGTACCGAAAGCAAT ref:0:16:A ref:0:16:ATAA 13 798 +CGCTACGCGG ref:0:10:CCGTGACCTCCATTTA ref:0:10:GGT 5 18405 +CAGCAAATT ref:1:8:TTACAGGGATGGC ref:0:9:GAGA 3 300 +TCAGACAACGGGG ref:0:13:GT ref:0:13:C 11 63 +TTCT ref:0:4:GCAGACCTTCGCA ref:0:4:CCCTCG 5 120 +GTCTGGTATC ref:0:10:AGCAA ref:1:7:ATCCAA 5 208 +TGCACA ref:0:6:AGCCGGTTGTCAG ref:0:6:G 2 46 +TATA ref:0:3:TCTCTTG ref:0:4:ACGGCCTG 3 34 +CA ref:0:2:AACCTGATCCTTA ref:1:1:TTAAG 2 12 +CCCAAGGCCAACAG ref:0:14:GAGGGCAGGTCTCAA ref:0:14:TCCTATATAAGCGGC 3 13500 +CCTCGTATCACATCT ref:0:15:GGCT ref:0:15:ACC 10 216 +CCATGGG ref:0:6:ATGATTGT ref:0:7:TATTCCG 3 78 +GAAATT ref:1:5:CCACATAGCACGA ref:0:6:GAAGTACGCAGCA 8 13688 +ATTTGGGGCCATATT ref:0:15:CT ref:0:15:CCGAG 11 84 +AAATAAAAAGCCC ref:0:13:GCGGGAGGCTATCT ref:0:13:ACTTACACG 9 284765532 +TGGGTACTCCGC ref:0:12:GG ref:0:12:AG 9 6 +AAGACGATTAGTAGC ref:0:15:TGCTCATGCTT ref:0:14:T 8 27 +GATGTGGGCCTTAG ref:0:14:CTATTGCGCCCGGCAC ref:0:14:CCCATGGAGA 7 85140 +CGGAGACCGA ref:1:9:ATCTCTGAT ref:0:10:A 4 12 +ATTACGTAACAT ref:0:12:CC ref:0:12:TTTTC 7 11 +GTTCGATGCCCGAA ref:0:14:TTGCCCACAAAGCT ref:0:14:CAACTG 5 4640 +TTACGCGGTAGATC ref:0:14:TG ref:0:14:TCAGGCGGG 7 117 +GTCACGAG ref:0:8:CGATAGT ref:0:7:TCTCTTCACTGT 3 600 +GAAGAGACTGTGA ref:0:13:TAACGAAAAGAC ref:0:13:C 6 129 +TCAAAGA ref:0:7:CAAAGT ref:0:7:ATTCCACAGTACGT 2 52 +GTA ref:0:3:AAGCTCGAGGGGTTC ref:2:1:CCGG 3 5 +GTTCCTAGGCGA ref:0:12:ATTGAATGCTGTG ref:0:12:TGTAAGCCCTGTATG 9 1102100 +CGAA ref:0:4:AT ref:0:4:AGGGCCTGT 2 18 +ATATGTTTGCAAA ref:0:13:GCTACACGTAGTAA ref:0:13:TAGC 5 2820 +CGGTGGACG ref:0:8:GTATATTGATA ref:0:9:TTACAATCAC 4 5454 +TCTCGCGCGGTG ref:0:12:CCAAATC ref:0:12:TCG 8 12383 +GC ref:0:2:GAGGCGTAACCCCAG ref:0:2:AGCAATA 4 19 +CGTAGTCAT ref:0:9:AAGA ref:0:9:GCCCTGTCCA 2 70 +CCGTCGTCATG ref:0:10:GGACC ref:0:11:TGGGAT 6 819 +CGATT ref:0:5:ATTACGCCTTCGCAC ref:0:5:TATCCTACACCGTAC 8 489 +CAAATGATACAAA ref:0:13:CCATTAATAGC ref:0:13:GCCGCCACA 5 45108 +ATGCCGGAGTTGTGT ref:0:15:GAAGT ref:0:15:GAAATTGTGTAC 8 6318 +ATGGTC ref:1:5:CGGT ref:1:5:CAA 1 2 +CACTCGA ref:0:7:ATTAGATGTCTA ref:0:7:TCC 3 1899 +GAATTCCGCCAGC ref:0:13:CCCACATCTA ref:1:12:TT 4 2 +ATTTCAACATCCTG ref:0:14:A ref:0:14:TGGTACTTAAAT 7 144 +GTCGT ref:0:5:AG ref:0:5:AT 4 35 +GC ref:0:2:CGGTCTTCCGA ref:0:2:TCATCCGTAGCGAAG 4 12 +TCTGCA ref:0:6:GGAGACCTTATGCGC ref:0:6:ACTACCCTCTACTAG 6 6384 +TCATTTCATCG ref:0:11:CCCT ref:0:10: 7 11 +TCAACAATTATA ref:0:12:CACAAGCCTGTTAA ref:0:12:TTTTGAA 3 120 +GT ref:0:2:CTACTAGGACGA ref:0:2:TTTTATTGCCCCCA 6 600 +TATTTTCGAC ref:0:10:GTACACTGGTGTC ref:0:10:TT 4 1500 +AGTGAACTGGCCAGTT ref:0:16:GCC ref:0:16:CTTCAACAT 9 1120 +T ref:0:1:CCTGGCTCG ref:0:1:GGC 3 8 +G ref:1:0:TTCCATA ref:0:1:ACGA 1 1 +CTCATACAACGCC ref:0:13:ACTAGGAGGA ref:0:13:TC 7 11214 +ATGAGTAGAGCTCTAT ref:0:16:CAAACCTGGGTTTGG ref:0:16:CGACCGAGACGGACTT 7 11682 +GACGGGATCT ref:1:9:TATACTGACGAT ref:0:10:CGC 3 108 +TTCTAATC ref:0:8:CGAGTGCTGGACAGCA ref:0:8:TACAAGCTG 3 168 +GAGTAATCGA ref:0:9:TGTGTT ref:0:10:TGTTATACGTT 4 216 +GACCCCCAAGC ref:0:11:GGTGA ref:0:11:AATCTGTCCT 7 559405 +TAAGGGTT ref:0:8:TCTGGAATGAGTAGTG ref:1:7:CGAGGCGT 3 128 +TATA ref:0:4:GCTCGCGTT ref:0:4:ATTCGCTCGGC 5 1326 +GCGAGCAC ref:0:7:ATATCTACGGTC ref:0:7:CCAAAAA 2 6864 +GTGG ref:0:2:TCGGGAATCTTA ref:0:4:GGTCGGGACGCCTGAT 3 180 +TGGCT ref:0:5:AGCTAAGTAAG ref:0:5:CAACAGTCCTTTCGAC 5 4386 +TGTGTAGTTTG ref:0:11:TTAGGTGGGAGTAT ref:0:11:TGATTTGG 1 672 +GAGCTGTGATACCAG ref:0:15:CGAGAAGGGATA ref:0:15:TT 6 198 +CGATGGGGA ref:3:6:TTGCTCCCTAA ref:0:9:T 3 670 +AGAAGGGG ref:0:8:GC ref:0:8:AA 5 51 +CGACTGGAGGTTATG ref:0:15:GATGCATAGGGCAA ref:0:15:AGTAATTGCACC 8 292146 +AACGTCACCGGTCACC ref:0:16:AGTCTATAG ref:0:16:ACAACAGC 8 4398 +TT ref:0:2:TTTAGGGAATA ref:0:2:CCGACCCGA 3 330 +GCTAA ref:0:5:CCCCC ref:0:5:AAACGCGG 4 2016 +CC ref:0:2:TGTAAAT ref:0:2:AGCCACGTATCG 4 216 +TAAGGCCCC ref:1:8:G ref:0:9:AG 6 8 +TGACC ref:0:5:CGGATGCGTATTAG ref:0:5:CACGGAGGGGAGCA 7 25600 +AGTTCCTT ref:2:6:CTGTG ref:0:8:TCG 3 28 +TCAAACGACT ref:0:10:AGAGCATT ref:0:10:TCCTCTGCGGAGTAG 3 22509 +GGAAAGTGCTC ref:0:11:GATTTTT ref:0:11:GTAATAGGTTT 6 48708 +GAGAGAAGCGT ref:0:11:ATCC ref:0:11:C 9 107 +GCTGCGACGCA ref:0:11:GGATGGACTGAACTC ref:3:8:CAGAC 2 300 +TT ref:0:2:AACGATCAGCAAGTGC ref:0:0:ACCCGAG 4 1 +CCGGTCCAG ref:0:9:GTAGCGCCGTCTTGTC ref:0:9:GGAA 2 816 +CAGT ref:0:4:CTGAGCAGACTTCTC ref:0:4:ATTAAA 1 36 +GGGCTAGC ref:0:8:TAAA ref:0:8:TTGGATGGGTTG 2 550 +TTTATCTAATGGC ref:0:13:TCT ref:0:13:TACTCTAT 6 48 +CGCACCGTAGT ref:0:11:CCAT ref:0:11:AGGAGTGTCACACCTC 5 9248 +TCATCTGGTAGCTG ref:0:14:CAT ref:0:12:TTGCCATGGGG 5 552 +GACCGCAGCGCT ref:0:12:CGG ref:2:10:CCTATGTA 4 140 +C ref:0:1:GCGT ref:0:1:TGCTCCTGG 2 3 +TGCG ref:0:4:CGCAGCGCTACTG ref:0:4:ACGCAAAGGCTT 7 300 +GTAG ref:0:4:CGCAGA ref:1:3:A 1 2 +GGACA ref:0:5:CCAA ref:0:5:TCGTCTGACCCCGG 2 288 +CGTCACACTCGACGA ref:0:15:TCTCT ref:0:15:AGATGGGG 7 6384 +CAAGATTGGTTCCACT ref:0:16:AGAAAACTGAC ref:0:16:TAAAGGC 8 1464 +TGACCCG ref:0:7:CACATTTCGAGATC ref:0:7:GCCTC 3 137 +GATCTGTATT ref:0:10:ATGTTAGGAGGA ref:0:10:AATCTCCAAT 4 70692 +TAACAC ref:0:6:ACAG ref:0:6:GTTC 2 40 +CCAAA ref:0:5:GTCCCGAC ref:0:5:TCATTATAGACTTCG 3 525 +TTGGAGAGAC ref:0:10:TCGCTCG ref:0:10:CCAGGGT 7 259120 +TGAAATTAGC ref:0:10:TGCCCC ref:1:9:GCGCTAACCTG 6 10266 +AGCGGCCCCT ref:0:10:TA ref:1:9:CGCGCGCGA 4 428 +ATAC ref:0:4:T ref:0:3: 2 1 +GTGATAA ref:0:7:AC ref:0:7:GGCGTTCGTATCAGCC 2 294 +GTGGAGTACTTTG ref:1:12:TTGGTGGT ref:0:12:CCGCCCTTC 6 1305552 +CGACAGCGTCCCAT ref:0:12:TTTGAGAGG ref:0:14:CCATTTAGTCC 3 1008 +ATCCGTAAGTAA ref:1:8:CGTCTCTGC ref:0:12:GTTAAATCG 3 140 +ACATACATACTCTTG ref:0:15:TACGTTCATGG ref:0:14: 7 14 +TACGGTCCCAAACCGG ref:0:16:T ref:0:16:GGATGTACATACCG 7 2580 +TACATGGAAACCGCGA ref:0:16:TTTAGATC ref:1:15:CAGCC 9 10224 +GTCA ref:0:4:CCACTT ref:0:4:GGTATAGAGATAT 2 344 +CTCC ref:0:4:AATGCGGGGTC ref:0:4:GGC 3 85 +CACCATACATTC ref:0:11:CTGCAGAAGTATT ref:0:12:ACT 3 5112 +GGCCAATCC ref:0:9:TTCGAAAGGGAT ref:0:9:GAAACCATG 6 11739 +TTT ref:0:3:GGGTATTGC ref:0:3:GCCGTGG 3 36 +GTCCTGTATGTT ref:0:12:GACGT ref:0:12:CCGAGAGAGCCTA 6 10716 +T ref:0:1:CCCTGACTCATA ref:0:1:GCACCTTC 5 6 +TCACGAAGC ref:0:9:GT ref:0:9:GTCTCGGG 5 96 +T ref:0:1:TTAAACCAACGCATT ref:0:1:TCGGCTTTA 5 16 +TCCAATGTA ref:1:8:GCCAAGCACACGGGC ref:0:9:TTGAAACCTCTCAA 3 864 +TCAGTACCGATTTA ref:0:14:AGACTTTGAAACGGAA ref:0:14:AGGTATAGAGGGAGTG 8 587100 +GGATGG ref:0:6:TGTCTTATCAG ref:0:6:TT 3 196 +ATCACG ref:0:6:TCTAAA ref:0:6:CACACGCAAAC 2 10 +TCTGAGTTGTGG ref:0:12:T ref:0:12:ATGAGGAGT 6 380 +TAAAGGTCCTG ref:1:10:TTA ref:0:10:AACAC 3 10 +ACGTTCCCATC ref:0:11:GAGATA ref:0:11:GGAGACCTCGTT 5 155 +TTGCCGCAATGT ref:0:10:ATGTGG ref:0:11:TCTCTAT 3 63 +CTGAACGACAT ref:0:11:T ref:0:11:GATGCCGC 6 42 +GTCACTACTATCCCA ref:0:15:CTGGCGGACGTAACC ref:0:15:A 6 60 +ACAAAT ref:0:6:GGACAGCGTTAACCA ref:0:5:CGGCTTAGC 5 1170 +GGCATC ref:0:6:TCGCTAGGAT ref:0:6:GTGTTGACCGGA 4 420 +TGTC ref:0:4:CCGGCCAGAAGCTCAG ref:0:4:TCCTTACCGCCA 6 1066 +GAGCTGTAACC ref:0:11:AA ref:0:11:CCGATCGGGT 5 60 +TTTCCGTTT ref:0:9:ATT ref:0:9:GGAGTTCACA 6 1540 +CAGACA ref:0:6:TCCCCTAGGTCCGCCT ref:0:6:AAGTGTGAATAC 4 42444 +A ref:0:1:GTCCTCCCAATAGT ref:0:1:TCGCG 4 18 +CTTTGATGGACT ref:0:12:ACCATTGAGATGC ref:0:12:AAA 5 1391 +TAGAGAACG ref:0:9:TTAACGGTC ref:0:9:GAACTGAGGG 4 8856 +AACGAACAGG ref:1:9:CGGGACCGGGAAAGC ref:0:10:AGAGGAGC 5 2520 +TACCAA ref:0:6:AGTGGCGA ref:2:4:CGT 3 848 +TACATACACAACA ref:0:12:GGCGAAATCGAGTAG ref:0:13:GGAAATC 8 4428 +CGA ref:0:2:GTCTGGCTGCCTCT ref:0:3:TTCGAT 2 4 +TCTTAAAC ref:0:8:CAAAA ref:0:8:CGTGGCCTGCGAGTAA 2 126 +TAGTGGTA ref:0:8:CTGGACCGTAGATAC ref:0:8:G 1 12 +TAACAACGGAGCC ref:0:13:ATGGTACT ref:0:13:CTTCAGATTAAACCCG 4 2448 +CT ref:0:2:CTTATGCATA ref:0:2:GACTGGG 1 5 +TGTAACA ref:0:7:CAGG ref:0:7:GGAAGT 4 33 +TG ref:0:2:CTATACAAT ref:0:2:A 2 45 +GCCGGCCGTA ref:0:10:ATCTCGATGTACA ref:0:10:CGGCGCC 3 6156 +TCTCAGTCGACATGGT ref:1:15:TGGTGGAA ref:0:16:CGGGGTA 8 30 +CGCGTG ref:0:6:A ref:0:6:GCTGGA 3 21 +TGCCGACGCGGTGA ref:1:12:T ref:0:14:GCT 9 7 +GTAATGTC ref:0:8:ACGCGTATTT ref:0:8:ATGGGT 2 132 +GGCTCTCGTAGT ref:0:11:TGCAGCGT ref:0:12:CTCACACGCA 5 1188 +TAAG ref:0:4:GGATCTT ref:0:3:GCGT 4 105 +CTCACTAGTGAAGAC ref:0:15:TGAT ref:1:14:GGGAGTCACCGTGCT 6 584 +GT ref:0:2:CCACACGGTTGGTTTC ref:0:2:AGACGAC 4 144 +AAATCCTTCTGCCG ref:0:14:AGACCCGGGA ref:0:14:CAAGGTA 8 96 +AGCA ref:0:4:CCAGTAGTCAC ref:0:3:TGCAATGCTTCTCT 3 18 +TGTATGAATCTT ref:0:12:GCTAAAAATCCGCT ref:1:11:GGGGAGTTGTCAGA 2 82005 +GGCGTATCAA ref:0:10:GGTTAACCCGGATG ref:0:10:CTCAGTTGA 4 47277 +AGAGTTTC ref:1:7:TCGGTG ref:0:8:CGCTCTTCCAGGTG 3 180 +CATCTCATCACG ref:0:12:CGTACACCAT ref:0:12:CAGCAC 6 8339 +CGTG ref:0:4:ACCACGACCTCCGCG ref:0:4:CCCACG 4 216 +AAGGTTGTAGA ref:0:11:G ref:0:11:TAGTTGGGCCCAA 4 600 +CATAAAATTCCGGG ref:1:13:TGACTTATGTTTAT ref:0:14:GCA 8 139570 +AGC ref:0:3:TCCCCTAGCCTCCG ref:0:3:ACCCACGAGAT 5 124 +TCGTTGG ref:0:7:AAATCCCT ref:0:7:CTGTA 3 400 +TTCTGACGC ref:0:9:ACG ref:0:9:TATTCCTTG 3 50 +GATCTGGTCGTTATAT ref:0:16:TGTATGGCGACGGTAC ref:0:16:GGCAGGTTTCAT 3 888 +T ref:0:1:TTGC ref:0:1:AGTTCTCACCATT 2 10 +AGAGTCCCCCATGG ref:2:12:CATACAATGGA ref:0:14:TCCAGACC 5 3400 +CCCTCGA ref:0:7:CGAAGAAAG ref:0:7:TCGTATA 4 436 +AGAAATCCTACGGTTA ref:0:16:GCTGGCTTCTCAGT ref:0:16:ACTCACGACCTGC 8 208518 +GTTAGCGTAGGGGCA ref:0:15:ATAGGC ref:0:15:CCCCTCAGTGAG 7 22200 +TTTTGCTCAC ref:0:10:ACCAGTCCTAGACAG ref:0:10:GCACGCGA 7 61728 +TGCCG ref:0:4:ATTATGATC ref:0:5:GCGGAATCTTTCA 3 372 +ACTGTAGAGG ref:0:10:A ref:0:10:GTAAAGACGTAC 4 66 +TGTCGACTGCAGGACG ref:0:16:CTTTA ref:0:16:AACTCTTT 9 1232 +AT ref:0:2:CCCACGTCA ref:0:2:CCGCTACCATA 5 2 +CCAAGTCGGACAG ref:0:13:TGTCAATATTAGTC ref:0:13:TTCGGAACAAAGTGT 4 1260 +GCCCGCGT ref:1:7:CTTGACC ref:0:8:TGGTAGTAAAC 4 144 +T ref:0:1:GGAAGCCA ref:0:1:CCACTGGTACAAGT 5 27 +AAC ref:0:3:GATGCTACC ref:0:3:AGG 1 18 +CCCGCAATG ref:0:9:CGTGG ref:0:9:GGCGCAAT 2 60 +TCAG ref:0:3:GTTAA ref:1:3:AGAGTCCT 2 40 +TACACGGT ref:0:8:ACCTCGCC ref:1:6: 3 61 +TGTACTAC ref:0:8:AATCTA ref:0:8:CGCATCG 2 96 +GACTC ref:2:3:TTCTA ref:0:5:AGGAGTCC 1 50 +CCGTG ref:0:5:AGCGTGTCGGTC ref:0:5:TTGATCAATTATTC 5 29119 +AAGATGGAG ref:0:9:ACC ref:0:9:AACCACAGGTGCGC 5 47880 +AGG ref:0:3:TTGCCCCCCCATA ref:0:3:GCTGGATCTA 5 276 +TTCCCTCTACG ref:0:11:GTCTGATTAATGATGC ref:0:11:TCGG 6 290532 +TCATCCTATTCG ref:0:12:ATCTAGAGACTC ref:0:12:ATTC 5 210 +GGATCT ref:0:6:TGAACTTAT ref:0:6:GC 2 144 +C ref:0:1:CGCTGTATC ref:0:1:ATTCG 2 3 +ACAAACGAG ref:0:9:GCCCTC ref:0:9:AGATACTCCT 7 130744 +TGTT ref:0:3:CGTGCGCGTGCCAC ref:0:4:GAAAACTGTTGTCCAA 2 9 +ACAGAACACGCC ref:0:12:ACCG ref:0:12:CAGGTCTG 6 312 +ATGACACTA ref:0:9:GGATAG ref:0:9:TATC 4 110 +TATG ref:0:4:AGCGATGTCACAC ref:0:4:ATAT 1 6 +TATAATCGGAT ref:0:11:ACAC ref:0:11:CAACCCTGATATGAAA 4 1344 +CCTCATCTCTTAA ref:0:13:TA ref:0:13:ACTGTA 8 154 +AGA ref:0:2:TGCTGAGC ref:0:3:CCGTAACGCAGG 3 2 +TTCACGT ref:0:7:C ref:0:7:GATACCGTAGTTAAG 2 178 +TGA ref:0:3:CTATG ref:0:3:ATACTGTGCTAACGT 2 30 +G ref:0:1:CGACACTCACGAT ref:0:1:GTACACTACTG 8 4 +TTTTAGG ref:0:7:CGGAAGTTTAGTGAC ref:0:7:CCTACGTTCC 4 2350 +AT ref:0:2:GGGAGGAGATAACCC ref:0:2:AGGCGAAATTGAAAG 7 24 +G ref:0:1:CTGAATGGT ref:0:1:GTCCTGTGATGTTT 6 12 +ATACAACACATG ref:0:12:TCATCGGC ref:0:12:CATTAC 7 3234 +T ref:0:1:CTAGGTC ref:0:1:TGATCATT 3 8 +CAAC ref:0:4:CCACGTAGATA ref:0:4:AGTACCAAGTGCTGGG 3 76 +TAA ref:0:2:AGTTACGGGCCGT ref:0:3:TATCGAGGA 4 8 +GTAGGATCACAGT ref:0:13:TATCTACAA ref:0:13:AAAGGGTCAGGGGCCC 4 53416 +TCCAACAG ref:0:8:CTCCAGACCCA ref:0:8:GGCTCC 2 18 +TTC ref:0:3:CC ref:1:2:AGGCTACGT 1 4 +AAGAATCACCCA ref:0:12:AACCTGT ref:0:12:GAAGTCCGGAAGAA 6 164395 +GGGCTTTAT ref:0:9:CCATGGCTGGACGG ref:0:9:TAATCCCCCA 4 5320 +AGC ref:0:3:CCC ref:0:3:GAGCGCCCAGC 2 110 +GCTGGAAAA ref:1:8:ATAAAGTTATTT ref:0:9:AC 3 24 +TAAAGTAT ref:0:8:CGGCATTATG ref:0:8:GCAAGCCTTGCTGAA 6 65835 +ATCGAGGA ref:1:7:CG ref:0:8:CGACGGATTCTAG 1 6 +CAGCCAGTGTACT ref:0:13:ACAC ref:1:12:TGACCATCGCGA 5 108 +TCTGCCCCTTACG ref:0:13:T ref:0:13:GCCTGTCCCTGCACTT 4 1360 +GTTTCAGCCTCCTATG ref:1:15:CATTGCAGATTT ref:0:16:TTATCAACTATATAGA 4 378 +ACAACTTACCTCTATA ref:1:15:AACATTAGACCCAAC ref:0:16:AGTAAGTTGGAGGGG 5 29268 +TAAAA ref:1:4:GAACATCACAA ref:0:5:CTTGACG 2 1365 +TCTTAGGCA ref:0:8:GGGCTCTGTTTAT ref:1:8:GCCTATCG 3 1536 +T ref:0:1:GCCTCAGTTGCA ref:0:1:AGA 3 12 +ACGGAACACTCGAGC ref:1:14:GTATTGAAAGTC ref:0:15:CGCGTG 5 8250 +ACAT ref:0:4:GGGTT ref:0:4:GAAC 2 220 +GCCTGTAATCC ref:1:10:AGTAAATGTG ref:0:11:G 5 312 +T ref:0:1:TTCTAATGCAAGCTT ref:0:1:GTGAGCCACAT 6 12 +GTA ref:1:1:ACCTC ref:0:3:TTTTAGCTGT 1 15 +CA ref:0:2:TTCATTTG ref:0:2:TACGAT 2 1 +AG ref:0:2:CTAGCA ref:0:2:AAAAGTTGATT 1 8 +CACGCTTAT ref:0:7:G ref:0:9:GCC 5 11 +CGAGGT ref:0:6:ATTGCAATCAGTCTC ref:0:5: 2 204 +AATGCGGCAAAGC ref:0:12:ACGTTCACAGTAT ref:0:13:ACA 5 576 +GCGACTA ref:0:7:TTCAAGGA ref:0:7:ATCCT 3 460 +CGCCAG ref:0:6:AAGTGGT ref:0:5:ACCTGAACCTATCT 2 130 +CAAGAAAC ref:0:8:TTCGACTATAT ref:0:8:TATTTGTCGCGAAAT 6 228 +TGCCCTTA ref:0:6:AGCCTAA ref:0:8:AAAGCCGTATAA 4 192 +AAAT ref:0:4:GTCAAC ref:0:4:CGAC 4 325 +CATCGACCCT ref:0:10:GG ref:0:10:AAGCCTAGC 6 275 +AGTCCTTG ref:0:8:TCCTGCGA ref:0:8:GCGTTTGATCCAA 3 84 +GTTCTAA ref:0:7:AT ref:0:7:ACGGCGATCGA 4 1222 +AATTA ref:0:5:GAAGTCTGTAGCC ref:0:3:TCG 2 3 +AGTATCACCC ref:0:10:CGAAATATAGGGGA ref:0:10:CTAGC 6 54064 +CAAATATC ref:0:8:ACCCGTAGGTTGGCC ref:0:8:CACCGTGGAAAAT 4 3280 +GAAAGCGTCAACGA ref:0:14:CTTCCACTCCCCCT ref:0:14:T 9 16943 +TTTCG ref:0:5:GGCT ref:0:5:TCCGATGG 3 2009 +TCTTTTCA ref:0:8:ACAGTGGTGCTAAC ref:0:8:GCTGAA 5 22080 +AGAAGTCGCGAAAGTC ref:0:16:TCATAACTTCCCTT ref:0:16:ATCAGA 8 75030 +CCCG ref:0:4:A ref:0:3:GAC 3 50 +CTCCGCG ref:0:7:GACACAAGATTGAAA ref:0:7:GTAGCCGCA 4 240 +AATCGGATTCTA ref:0:12:GCGCACCG ref:0:12:CGGCCGGCGGT 9 21624 +TAACTAGA ref:0:8:T ref:0:8:ATTATTAAAGCGTATG 1 36 +CACTCTGTAG ref:0:10:TG ref:0:10:CAG 6 25 +GTGGTCGTG ref:0:9:GAAGGGTACGGTTTGA ref:0:9:TTGAATTC 2 4026 +TCACCGT ref:0:7:TGCGTGTTTCGAGC ref:0:7:GTACTCCGA 4 3940 +ACCGCACAGG ref:0:10:CAAA ref:1:9:CGAGCATTCAT 4 432 +A ref:0:1:GCTAA ref:0:1:GCTGAG 3 2 +GCTTCCTAG ref:0:9:AATTGTAAGTCCGG ref:0:9:TGCAGGAC 4 88 +GACCTGAC ref:1:7:AATGAACCAT ref:0:8:ACCTGACC 1 32 +TGTAATGG ref:0:8:AAATCT ref:1:7:GACGGAATCCCAT 6 10920 +AACTG ref:0:5:GCGCGCTTGTCTGCA ref:0:5:TTGCA 5 1350 +GG ref:0:2:ATCACATGTTGGC ref:0:2:CGTCGCTGTGCGCGTC 7 45 +GACTGTT ref:0:7:GGTTAACCGCCCGCA ref:0:7:CCT 3 12665 +CCCGGC ref:0:6:CGGAGTTGAGGCT ref:0:6:T 3 1477 +CATACGG ref:0:7:ACAAAATGTAATGTCG ref:0:7:GTCGAAGGCTAGAC 4 1584 +GCTTGCCTGCACCT ref:0:14:CAGAAATCCATT ref:0:14:AGTCTGTCTCTAC 5 39060 +CTCCTTTCGTGTATAT ref:0:16:TTACGCG ref:0:16:AG 12 520 +TGG ref:0:3:ATTGAAA ref:0:3:G 1 22 +CGCGATGGCGTGCTGA ref:0:16:CGTCGCGCCTT ref:0:16:AT 7 1284 +T ref:0:1:TAACAATCC ref:0:1:C 1 4 +CT ref:0:2:TCACTACAATC ref:0:2:GACCTTAATCT 5 45 +TGGCCCTAGTT ref:0:11:TCATACCACAT ref:0:11:GTAA 4 550 +ACGGTTGC ref:0:8:GGGTAGTTCCGGA ref:0:8:GTTCCGGGCAA 6 3870 +GTTTTTTATGTCGC ref:0:14:AGGCCATATAAAGC ref:0:14:TTGGTCTAACTG 7 23249538 +TAGGTTCA ref:0:8:C ref:0:7:AGAAACAAGTGCT 2 4 +TTCTATGCTCTTCAGG ref:0:16:ACTGTTTCGAAT ref:0:16:CTTTTGCGACCAGAC 3 1176 +GCCA ref:0:4:CATCATTGATTGCGA ref:0:4:GGCTTTAGGAGGG 6 504 +TAGAATCGG ref:0:9:GATAGCTA ref:1:8:GAATTACAAAGGT 3 154 +AG ref:0:2:TAGAACCACGT ref:0:2:GG 1 15 +ACCCGAACCGC ref:0:11:CAATAGCTAGT ref:0:11:CTAACGGCAAA 6 9135 +GCCCGCATCGC ref:0:10:TCGCGGGAC ref:0:11:CATGTT 3 1224 +TGAACCCACGCGG ref:1:12:GGTTT ref:0:13:TTAGAACGG 6 1674 +TCGCCGACCTAATC ref:1:13:GGCAGAGTTGT ref:0:14:ACAGAACAA 5 59182 +GATACGGAAT ref:1:9:TTCGGTGTGCTGTC ref:0:10:AGATAGAAC 1 2736 +GAGGTGTTGCAAAAC ref:0:15:AGAATTGGTGCT ref:0:15:GTTCTCCATTG 8 801840 +GCGAGAACAACATACT ref:0:15:CGTACCACCCAT ref:0:16:AGTGA 5 362 +GAGGGAA ref:0:7:TCCAATGATCAGTAC ref:0:7:TCGTTAGACT 7 9564 +GGA ref:0:3:ACCT ref:0:3:AGTTCCCAGTT 2 11 +GTCTTGACT ref:0:9:TT ref:0:9:G 6 12 +ACCCGCTAGGC ref:0:11:AAAGGTT ref:0:11:GGAATTACGTTCTT 8 23166 +ATAC ref:0:4:CT ref:0:2:GCTT 2 21 +GGAGT ref:0:5:AG ref:0:5:AGCCTAGGGGCCC 2 199 +CATCGACGAACC ref:0:12:GACC ref:3:9:CCAGGGCGA 2 210 +AC ref:0:2:AGAAACGATCGTTTT ref:0:2:GCGCAATAGGACCT 6 72 +CCT ref:0:3:CGGTGGCGGG ref:0:3:GGTTATATTTTTA 3 2536 +TTATAGA ref:2:5:CCCCATTAAACG ref:0:7:TGAACAAATGGCAAAG 4 14742 +TAGAGTA ref:0:7:GCCAGGACTGT ref:0:7:TTCTTAGCCTTTTTCG 4 17928 +CTTGGCGGGAATCAT ref:1:14:GTCTAGAAAAAG ref:0:15:CGC 8 47260 +GACGGCC ref:0:7:GTGATTGAC ref:0:7:AGAAATGATCAAGTG 5 375 +GGCGAGT ref:0:6:GC ref:0:7:GCTGCGGCGCGCGAC 1 1116 +GA ref:0:2:TGCGGATAGA ref:0:2:CTTC 2 150 +CGGTCCACAC ref:1:9:AGTTG ref:0:10:GGGTACG 5 2260 +A ref:0:1:GTCAGGTCGCTTATG ref:0:1:TTTCTAGTAAGCT 7 6 +CATTATCA ref:0:8:TGCAACAT ref:0:8:TCTCTGTTACTGG 3 242 +TTTGCAAAG ref:0:9:CCCCACTTA ref:1:8:GTTAGCA 3 1173 +GGCTTCGGCTACGAA ref:0:15:ACCCCGCTAC ref:0:15:CCACTTAAAGAACAAC 6 161814 +CTGAC ref:1:4:AT ref:0:5:ACGACTGTA 2 9 +TCC ref:0:1:GATAAGTA ref:0:3:CGGTAAGTGTATCAG 6 62 +GTTGGACCT ref:0:9:C ref:0:9:ATGCTGCGC 4 50 +T ref:0:1:CGGGGAGAATCCT ref:0:1:TAT 1 4 +GTGGGATGACTCG ref:0:13:TGTAA ref:0:12:TCTGAAAGATGC 5 6328 +TCCGCGTTG ref:0:9:GCAGATCCCATTCGGA ref:0:9:ACAGAAGATCTTAC 3 1080 +TTGA ref:0:4:CCCTGTGT ref:0:4:TGCCCTCGTTAGCAC 4 16 +TCTGACATTACA ref:0:12:GTGCTAACT ref:0:12:GGGATAC 6 6106 +ATTA ref:0:4:GTGTC ref:0:4:CTCGAGCTAGTG 3 32 +TGCCGCCGGTCGCGC ref:0:15:CGTGACAAGA ref:1:14:GGTGTCACTCTTGA 7 7200 +TTTCCGCG ref:0:8:CTTCTT ref:0:5: 3 121 +TAAAATCAACG ref:0:11:GTCCCGCAGAT ref:0:11:CGCCGGCGTA 11 1242096 +GGACACAAG ref:0:9:TC ref:0:9:AAATACTCTAGGGT 5 15750 +CACAAGCG ref:0:8:AGGAGGCGTACGAC ref:0:8:TTTGGAG 5 130356 +GGACTTTG ref:0:8:ACGACAATGGCCGGAG ref:0:8:A 3 688 +AGTCCTATTGGCTTCT ref:0:16:T ref:0:15:GTTTGTGACACC 7 504 +ACGGTT ref:0:6:GACGT ref:0:6:AACAAT 2 128 +A ref:0:1:CAGGCCGCT ref:0:1:GAGCCGTCTTTGA 6 2 +GC ref:0:2:GGTCGCTCTAC ref:0:2:CC 1 33 +CCTCTAGAGAATAGC ref:0:15:CTAAACTTA ref:0:15:CTCACAGATGGGCA 4 2640 +ATAGGAGCTT ref:0:10:ATT ref:0:10:TTCTTACAGAATGTAC 4 6770 +GCTAGAAATA ref:0:10:AGACTGATGAG ref:0:10:AAGCA 4 291 +GTCCTAAGCA ref:0:10:TT ref:0:10:CAAGTTCGCTGT 4 6 +GTACCCCTAAGCAA ref:0:14:AGGGGCTTAAAAC ref:2:12:CATCGAGCCCTA 4 2880 +TCATGGGAATC ref:0:10:AT ref:0:11:CGTG 6 64 +C ref:0:1:GCAAGGGAT ref:0:1:ACGAGCA 3 2 +ACTGCGCCCG ref:0:9:GCGGCCTATAGCCTT ref:0:10:CACGCGCGGCGCTCA 3 3198 +CTTCGCCTCGAGC ref:0:13:TC ref:0:13:CGCTCCTTTAGTGCCT 5 33408 +GC ref:0:1:TTCTAGTG ref:0:2:GCGCTGA 1 6 +GACTAACTCCCT ref:0:12:ACG ref:0:12:CTGATG 8 990 +AAGTGAT ref:0:5:AGTT ref:0:7:T 2 12 +GGCTGCACCCTTTTA ref:0:15:TTGGGGT ref:0:15:GCACG 9 5250 +AAGCGG ref:1:5:TATCGGGT ref:0:6:CATTCG 3 168 +GTCA ref:0:4:CCGCGATCT ref:0:4:GCTTGGCCCTTTCC 3 375 +CGGACCATTTA ref:0:11:AATCGGCGTGT ref:0:11:CTT 5 198 +CCCCTGGCGCC ref:0:11:TGAGAAAA ref:0:11:GCGTTCCA 6 290 +CCCTTCATGG ref:0:10:GAATGATTATATTC ref:0:10:CAAATGCTGCT 7 3258000 +CCACGCCA ref:0:8:GGAA ref:1:7:GCTTAGTCGTTTTCC 1 35 +GCGGCA ref:0:6:TCTACTCGAGCG ref:0:6:TC 3 196 +TAAGTGAAAA ref:0:10:GAT ref:0:10:GAAACACATTCGCT 6 1066 +ATGTGTG ref:0:6:GCACCGCTCTC ref:0:7:CTTACCACAA 4 1728 +TGGGGTTCTA ref:0:10:GCAT ref:0:10:GGGGGCTCTC 3 352 +AGACTGCGCTTA ref:0:12:CAAACAAATACT ref:0:12:CTG 5 96 +CACT ref:0:4:CTCAAGATAGGTAGGT ref:1:3:GTTTGACTA 3 152 +CAT ref:0:3:TTGAACGTA ref:0:3:GTG 2 36 +G ref:0:1:GTAAGGAGGGCGAGC ref:0:1:AGTGTTTGGCCCC 6 32 +TTCAGCTATAG ref:0:11:TAG ref:0:10:CAAAGCTTATC 3 165 +CG ref:0:2:GCCTTTCAGGGAC ref:0:2:TAGAT 3 27 +TTAAGACGGGTGTGCC ref:0:16:C ref:0:16:AAGTGATCCCAGATG 8 1767 +CCA ref:0:3:AGTCCCTGCC ref:0:3:TACTCCTGT 5 338 +AGTAT ref:0:5:ATGC ref:0:5:GTCCTG 2 36 +TGATCCATC ref:0:9:TCTCCGGTCGAGCCCG ref:0:9:ACT 2 658 +TGATGAGCTAGGAAAA ref:0:16:CGCTT ref:0:16:TGA 11 6890 +GCGCTCAATCACAAA ref:0:15:AAGTAAGAAGTTAG ref:0:15:GTC 7 2200 +CTTTTTAATACAGT ref:0:14:TCGCGCCGCTTAGG ref:1:13:AAATAATCGGG 7 19002420 +AAAACGAGAAACCAA ref:0:15:TATTCCTC ref:0:15:CGTCG 11 2765 +T ref:0:1:GGGCTACCGCCCGGG ref:0:1:TTACGGGCTCAAATTG 6 5 +GCAATG ref:0:6:CTATTAGCATTAGGC ref:0:6:CCTGTCGCGT 4 2250 +TGTCGCAGCACGAC ref:0:14:TG ref:0:14:CATCGGACTAAG 7 1757 +TTCA ref:0:4:GCAACC ref:0:4:ATCGAGAAAGTAAA 2 162 +TTGAGGTTAACCAGG ref:0:15:ATGGCCTGGCCT ref:0:15:TCAC 8 2360 +CGTAAG ref:0:6:GCGGTCAACTGTATCT ref:0:6:TCATGCCTTTACACTC 3 24 +CTAGTACTGG ref:0:10:GG ref:0:10:A 7 6 +CGGAC ref:0:5:TCGAAA ref:0:5:CTTGCGATAGGCCACC 3 416 +TACGTCG ref:0:7:ACGTCTT ref:0:6:AAGTCA 1 12 +CAAA ref:1:3:TTTTATGGCGCCTCG ref:0:4:AAAC 1 136 +TGCGTACAATATCC ref:0:14:AAG ref:0:14:C 11 124 +TCT ref:0:3:TTTTTAGA ref:0:3:GGGA 3 700 +GCATAA ref:0:6:TAT ref:0:4:TATGACA 1 6 +AGCTCTCTTCACTGA ref:0:15:TGAGTCA ref:0:15:CCTGAGGCTCCAGTTA 8 3420 +CGCAGTAC ref:0:8:GGA ref:0:8:AGT 3 1 +TACGTAAGC ref:0:9:CACGGCTA ref:0:9:ACCCCCAGTCTTA 5 1600 +GGCCGCATAA ref:0:10:GTCAT ref:0:10:ACCGCACCCCAT 4 3276 +CTAGCACTACTGGTT ref:0:15:TGCCTCCA ref:0:15:GAGCACCACGCAG 6 306 +TTCTAAAGG ref:0:7: ref:0:9:CAGCTGGACT 5 32 +CCCCTAA ref:0:7:GCCCGATG ref:0:7:ACGCCTT 3 1750 +ATCGG ref:0:5:GTCGTATGGATT ref:0:5:TGC 1 28 +GAACTATTCG ref:0:10:G ref:0:9:GGTTCC 5 78 +TTTAGGATTTT ref:0:11:CCGGTCT ref:0:11:ACCGCAAGTATT 7 12300 +AGCACCCAGTA ref:0:11:GGAAACAGCGG ref:1:10:AAT 5 2882 +TTAGGCTGAAG ref:0:11:TGCTTCACGA ref:0:11:TCTTCTG 6 1416 +CCGAGT ref:0:6:TCGGAGTAAGT ref:0:6:GGTGCGATGTGG 3 282 +GATGCGCCCCAA ref:0:12:ACTT ref:0:12:TCTTCATC 9 26532 +TACT ref:0:4:GAATGGCAATCGTGC ref:0:4:GACCAC 3 42 +TAGGGTAGTATTAGG ref:0:15:GTTGGA ref:1:12:TACTATTGAAAA 4 168 +TGTACG ref:0:6:ATGAGAGGTGTCTT ref:0:6:CTTTGGGGGGT 6 74405 +CCCACAGGA ref:0:9:GCACA ref:0:9:AGATATCAGC 5 2760 +ATGACCCCCC ref:0:10:GGAGCCCTCT ref:0:10:CTGTCTGC 4 67424 +ACGCACTGGAGCAAGG ref:0:16:AAAT ref:0:16:GACCTA 10 924 +TGTG ref:0:4:GTGGG ref:0:4:C 1 35 +TGGATGATAG ref:3:6:CTATTTT ref:0:10:ACTGTGG 2 205 +GGTC ref:0:4:CGAG ref:0:4:CTACTGATGAGTAT 3 12 +CACAGATGAC ref:0:10:CCCGTAGGGGGCG ref:0:10:TATAA 3 34488 +CT ref:0:2:TTGTAAAGACACCATA ref:2:0:AAA 1 3 +GATT ref:0:4:CTTTCGAGGTGG ref:1:3:TAGC 2 66 +CTACCTTC ref:0:8:TACTTCTATCG ref:0:8:TGATTTTGTTCATTAG 4 106 +TT ref:0:2:GGC ref:0:1:CGAGTG 2 10 +TTGTCGCGAGA ref:0:11:GAG ref:0:11:CATGTGTACGTCCC 2 63 +CTACGA ref:0:6:TGAC ref:0:6:AGCATTTCTATCTGTT 1 30 +ATGCTAT ref:0:7:TAC ref:4:3:GAGAA 2 147 +GCTTCGTATT ref:0:10:T ref:0:10:G 8 10 +ACACCCCACTGGCCGA ref:0:16:A ref:0:16:GGCGATGGAGC 10 11968 +TAGCTTCCCTGTG ref:0:13:C ref:0:12:ATTAGGCG 7 220 +TTGATATAGAG ref:0:11:T ref:0:11:CGCTCTTTACCGAGCA 3 4 +TTACGAT ref:0:7:GGTCTTTGCTTT ref:0:7:CGCGAGCTGCCCATCA 5 4965 +TTTGAGACTA ref:0:10:AAACCGTGTGTCTTGC ref:0:8:ACACGG 2 3040 +AA ref:0:2:AATGAAGTGGAGCAGT ref:0:2:GCCATGGCGTTCCTT 7 240 +GGACGCTAACTCACC ref:0:15:TCTAGAATA ref:0:15:CGTTACGAG 7 4968 +GGGGTACTCACTGAC ref:0:15:TGTGAGTT ref:0:15:GATTCCCC 8 15620 +GACACCG ref:0:7:TAGC ref:0:7:GTGGCATGTGCATCA 4 1295 +ATCTATGCGCC ref:0:11:GGAAGAGA ref:0:11:TCGGTTCTCT 3 54 +CCCTGCCTGGTGT ref:0:13:AACCACAC ref:0:13:CCTCCAA 8 1932 +GTCGTGTTC ref:0:8:CTCAT ref:0:9:GGTAGCTCCAGACCCC 4 7968 +CGGGTGGTCAT ref:0:11:GT ref:0:8:GACCCTCAG 5 1872 +GACATTTATGTCAC ref:0:14:GGTGTACCATCGG ref:0:14:GTGCAGGCGAAT 8 71232 +AATGGGT ref:0:7:TTTTCGCCAGATTA ref:0:7:CCCA 6 1855 +AGGGTAGGCTAC ref:0:12:GCGAGTTGACT ref:0:12:CTCCTGGC 6 14280 +AGGGCAGC ref:0:8:TAGGCCA ref:0:7:CA 2 10 +ACACT ref:0:5:G ref:0:5:GAACTAGAGCTCC 1 24 +CAGC ref:0:4:GTG ref:0:4:TCGTTCC 2 18 +TGGAT ref:0:4:ACC ref:0:5:TCTTCAACTACCCCAA 3 61 +ATAGTGCAT ref:0:9:CCATTGGCAG ref:0:7:ATAACATGAGCTGT 2 440 +CCAGTG ref:0:6:AAAGTTGGAC ref:0:6:CA 1 80 +CGTA ref:0:4:TCGGGCCTTACG ref:0:4:TCCAT 2 60 +TCCA ref:0:4:CTTCT ref:0:4:GGCAAATGA 2 882 +GGTGAGGT ref:0:8:TGTATAAGAC ref:0:8:ATCCGG 4 12375 +GAAGTTCCCACGAGGA ref:0:16:CCGCCTTTCCTTC ref:0:16:TCTCAGC 9 262870 +CGACGAAAC ref:0:9:TAGGAT ref:0:9:AAATGACAA 4 5289 +ATAACCAA ref:0:8:AAC ref:0:8:TA 4 24 +GAATAATGAA ref:0:10:CGACGC ref:0:10:CGAGCGGTTTATTCT 7 115728 +TTCCCC ref:0:6:GATTTTGT ref:0:6:TCCGGCCTGTTACG 3 2079 +CCGTTCACCCGAAAT ref:0:15:AGAGATCGA ref:0:14:GTCAGG 8 22832 +AGGGACAGGTTTTAC ref:1:14:ATCATTCAA ref:0:14:CTCATGT 9 20131 +CTCA ref:0:4:TTAGTAC ref:0:4:GCCAGTAATGAAAA 3 2790 +AATCTCAAAGCAACT ref:0:15:TGCCGGGTTCATACA ref:0:15:CGTGTC 7 372 +ATGGGCCCAGGATAG ref:0:15:CATC ref:0:14:CCGCCTCTACGGCAT 5 651 +AATA ref:0:4:GCGCA ref:0:4:GAGGT 3 205 +CGCATT ref:0:6:TCTCATCTCCC ref:0:6:GATAGTGTTCCCATCC 4 400 +TGCTTCTGGGGGAA ref:0:14:AACGAGACCCCTGTG ref:0:14:CTGGCTGTCA 6 12000 +AGTTAGATGGT ref:1:10:GGTTCTGTG ref:0:11:TCACG 4 2860 +A ref:0:1:ACAGAACAACTTCCC ref:0:1:TGCTGCGAACTAGTA 7 24 +TC ref:0:2:CTTCCCACTAAACAC ref:0:2:TCCAGGCCTGC 5 84 +GA ref:0:1:T ref:0:2:CAATGGTAA 1 8 +TTCGGC ref:0:6:CTTAGG ref:0:6:GCACT 1 30 +ATCTACCTTGAGCT ref:0:14:TCCTATGAGCGC ref:0:14:CCCTTTC 4 280 +GAGGTGCT ref:1:7:TCCAGAAATTC ref:0:8:TTGCAGCAGCGACAAA 3 168 +AT ref:0:2:TTTCA ref:0:2:GAAGACCTCCGTG 1 42 +TGCTTAAAG ref:0:9:GCGATGCGAATTGCT ref:0:9:TACATGCG 5 10920 +CAACTGGGTAG ref:0:11:ACCCGTTCTCGTGT ref:0:11:GGGT 5 1670 +ATGGAGCACGTACATC ref:0:16:CGCTATCGCTGCGAT ref:0:16:GTACGCGGTCGT 7 2600 +TCGACCTTGTGAGTCG ref:0:16:AACAAA ref:1:15:AACC 12 15030 +GGAAGGCTACGATT ref:0:14:AC ref:0:14:G 11 25 +GCGCTGTCT ref:0:9:CAG ref:1:8:TAGACATGAGGCTA 3 147 +TCGCCCTACGCGAAC ref:0:15:GCAATAGTAG ref:0:15:CTTGAGCCTTCTGAT 6 1123200 +ACAGTGA ref:0:7:GAA ref:0:7:GCCAGC 4 330 +TTTGT ref:0:5:AATTCCAGG ref:0:5:GCCAGG 6 3300 +ACCCGGGCGTGCTTGA ref:0:15:TCAAAT ref:1:15:GGCTGATTCCTCCTC 6 450 +AGATTGAGTTTTAAG ref:0:15:GATAT ref:0:15:TTATCGTCTTC 6 200 +AGAAACAGCCAAT ref:0:13:CAAATCTATAAG ref:0:12:GTGATATATTTA 7 173376 +CTTCGGAAT ref:0:9:TTGCAGCGTCGCG ref:0:9:CAGA 3 26 +ATGGAAAGACCGAT ref:0:14:TGGAGAAGGGAACAC ref:0:14:CAGCC 4 756 +GAATGGGATACT ref:0:12:AGCA ref:0:12:TTAACATAGC 6 720 +GCAGCCAGTAGCTGG ref:0:15:GCCAGGCGGATC ref:0:15:ACGGAATCATCC 5 15140 +ATAATCCCTGTG ref:0:12:TCGAAGCATTCTAGA ref:0:12:ATC 5 5580 +TGTAGGATACAT ref:0:12:TCCACGGCTTCC ref:0:12:ACCAC 7 13300 +CTGAATTA ref:0:8:GA ref:1:7:AGAGA 4 57 +CCTTAATAT ref:0:9:ACCAAGATCCCTGC ref:2:7:AAGTTACCA 5 504 +GCTG ref:0:4:TCACCTCGG ref:1:2:ACATTAT 1 66 +TGCCGCGTTAGAC ref:0:13:TACATGTCCATCTAT ref:0:13:AAGTGCCGA 7 5412 +AGATGCCTCCT ref:0:11:ATC ref:1:10:GTTGTTGCGTCTC 3 2844 +TTGATAGTTCAGT ref:0:13:AGAACGTTTTAC ref:0:13:TCGGGAAAGTG 4 13932 +GGTAGCTCTGCTCTA ref:0:15:TCTTTTGCATGAAGTC ref:0:15:CAACT 8 119556 +CCTCTAG ref:0:7:CGTGAGTCCGCTCC ref:0:7:CGGCGACGCGAC 7 49446 +GATACTTGGCCAT ref:0:13:CTCCTCCGAAA ref:0:13:CAGGCTG 4 2376 +CACGGTGGGACAG ref:0:13:GGACAAGACA ref:0:11:GGAGTATGCT 7 61104 +AATTCAT ref:0:7:GGGGTGTTTGGAAGA ref:0:7:TGCAATAG 5 48010 +ACAACTCAACGTTCT ref:0:15:GTTGTTGTGTCCC ref:0:15:CCC 8 145680 +AGGATCCCGTGTTG ref:0:13:GACGACGTACAT ref:0:14:AGTA 7 27010 +ACGGCAGCACTTCCGT ref:0:16:TA ref:0:16:AATCTAC 12 2716 +GAACGAAGCCACG ref:0:13:CA ref:0:13:AGAT 9 240 +TAC ref:0:2:CAAGAGGGAGAGAAT ref:0:3:TTGCAAA 3 986 +ATAGGCGTA ref:0:9:TTATAGTTAC ref:1:7:AGAAG 2 110 +GG ref:0:2:GTTCCGGGA ref:0:2:ATCCCTAG 3 54 +GAATTCGTCAGC ref:0:12:GG ref:1:8:CTGTGGAT 4 27 +A ref:0:1:GGTTAGC ref:0:1:TCCATTTGTCGCC 3 1 +CCCCGTTGCG ref:1:9:GTACACCTA ref:0:10:CG 4 117 +GGCTCCCGTG ref:0:10:CTCATAGGGAAG ref:0:10:CTCAGCC 5 345 +GAACGGGAG ref:0:9:CGAGGCGGAGAA ref:0:9:CCGGCTCT 3 12530 +TA ref:0:1:GAGACTT ref:0:2:GCACGA 3 18 +GCCCTCAATTA ref:0:11:TCCGTGATGGCTAAC ref:0:11:ATCTGCAACGAGG 5 10260 +TAAGAAA ref:0:7:GAACTACCTCGA ref:0:7:C 4 816 +G ref:0:1:ACA ref:0:1:AGGCGGGC 2 20 +CTA ref:0:3:TTGCCTCTAC ref:0:3:CCATCATGCG 3 10 +TCAATCAACTGCC ref:0:13:CATTGCGGTGATTC ref:0:13:CTGCCTGA 7 2076 +CTAAAGCCTTTGGA ref:0:14:AGGCATTT ref:0:14:CA 7 180 +CCCCTGAGCA ref:0:10:CGT ref:0:10:GAACCATC 6 3276 +GATGCCG ref:1:6:CCACC ref:0:7:TTATTCCCGGTGACTG 1 303 +GGCGAATC ref:0:8:GC ref:0:8:AGTGTTTATCTG 3 325 +TAGATTAAATACTT ref:0:14:CGAT ref:0:14:CCGCAAACCACG 8 21600 +GGAAGGCCACTT ref:0:12:ACTAC ref:0:12:CTCTGC 8 180 +TGCCCTTTT ref:0:9:GTCTCCCCT ref:0:9:CGGGT 4 101010 +GTAGGAT ref:0:7:CATGGGTCTA ref:0:7:GT 3 488 +TGACGGAAC ref:1:8:CG ref:0:9:CAGAAG 4 36 +GC ref:0:2:GATCCTGTTTAGGCC ref:0:2:TT 2 60 +GGGG ref:0:4:GC ref:0:4:CCAGTTGTC 3 550 +GAAATTCAA ref:0:9:ATTACCTGCGGTT ref:0:9:GGCCCGATCGGCA 6 1022320 +ACCAATGA ref:0:8:CCTGGGAACCG ref:0:8:GACAGCTGGGCG 6 1053 +GCAATCACCGCT ref:0:11:CCTTTA ref:0:12:ATACGCACA 4 1984 +GGACCTCTGAACCTG ref:0:15:TTACTCTTGT ref:0:15:AACTCCCGCTC 7 25346 +T ref:0:1:ACTAGTCTGCCCAAAC ref:0:1:ACCTGCTCCGAT 8 9 +GCTGGTAATGGGC ref:0:13:TAGG ref:0:13:CCTTCCCC 6 8100 +AAT ref:0:3:CTGCCT ref:0:3:GTGGTGCTCATA 5 288 +CACATGCTTTTTTCA ref:0:15:GAATG ref:0:15:C 10 8 +G ref:0:1:CTCGACCCCGC ref:0:1:CGGCTGATCCG 6 8 +GTCTA ref:0:5:CCGGACGAACACTGCG ref:0:5:GTAGTGGTGT 5 20254 +GATGGCCCT ref:1:8:TCAAGGTGCA ref:2:7:G 4 460 +ATATACTTTGTAC ref:0:13:GCGATGCACTGCC ref:0:13:CTTCCATCC 8 126576 +CTCTCGCCG ref:1:8:GCTAGGCCTC ref:0:9:TGCCGCCC 3 208 +AGTGATTACCTT ref:0:12:GCGCTTACGATGTTA ref:0:12:GAGACTAGGCGGCTG 5 2016 +CTCTTTA ref:0:7:TAC ref:0:7:AACAA 5 185 +GGGAGAACTTAC ref:0:12:GATCTCGGTACTGTT ref:1:11:ACGGGCATCGTT 7 1160 +CAGAATATCCCCTTC ref:0:15:GCC ref:3:12:CTCCTA 8 2650 +ACGTCCC ref:0:7:CTTA ref:0:7:TTATTTATTGTAGTCG 4 6696 +T ref:0:1:AATCGCGTCAAACGG ref:0:1:CCGGTTA 4 4 +GAGTCCG ref:0:6:T ref:0:7:AGGGGGGTA 3 410 +GCATC ref:0:5:CAGTGTG ref:0:5:CAAATTCACGCCTTC 3 360 +AGCCATAAGGATC ref:0:13:CGTTAAGCCAT ref:0:13:CCTTGGAACAG 4 1440 +ATGCTTAG ref:0:7:GGC ref:0:8:TCTCGTGCTC 2 4 +AGAAGGTTTAT ref:0:11:TAACCGCT ref:0:11:A 7 1212 +TCTGCTTCACTAGGT ref:0:15:GCATGATAGG ref:0:15:CTTCCGG 4 36 +ACCCGTAGGTGTC ref:0:13:CTCGGCC ref:0:12:CGGCTTGCGAAT 6 123200 +CCGAGTGTCCCTAA ref:0:14:T ref:0:14:TGCGAGCAC 7 312 +TTGCT ref:2:3:CTTGG ref:0:5:GTAGGGGGTG 1 162 +GG ref:0:2:TTGCAGG ref:0:2:CGGCGTACATAATTT 1 9 +GCAGTTGCATCAT ref:0:13:GGATGCTTTAGTCA ref:0:13:CATCCTTGTGCAAGA 5 11088 +CGGTTCCC ref:0:8:AGGACGTCGCCTGGTC ref:0:8:AC 3 2596 +T ref:0:0:GGC ref:0:1:ACAATACTGCT 2 3 +AGCCACAAGGTG ref:0:12:TAGCGCAGGCAAT ref:0:12:CTC 3 12 +TTGTCCAGACT ref:0:11:GA ref:0:11:GT 8 9 +TGG ref:0:3:AAC ref:0:3:CGCCTTGTGCC 1 40 +CTAACGAGGCATACAT ref:0:16:GCTTCTTG ref:0:16:GTCCCTCACACAC 7 1872 +GCCTACCACTC ref:0:11:CG ref:0:11:AGGAATTGGTG 7 4550 +TTTTCTACCACACAGG ref:0:16:C ref:0:16:CGCTGTGAG 12 80865 +TAGTGCACTACAC ref:0:13:CACGGGCGCTCAA ref:0:13:CATT 5 576 +TA ref:0:2:AGTGAACACCAC ref:0:2:AACTCCTTTC 5 76 +ACAAACTGAGGGGTC ref:0:15:ATTG ref:0:15:GGCGAAGAAGCAA 7 28620 +AACATA ref:0:6:TTTGTAGCTGGGAT ref:0:6:TGTTGGCA 7 1712 +AGGTC ref:0:5:GGTGTGCCCGCG ref:0:5:GGCAAGGAT 1 40 +ACT ref:0:3:CTATGCGA ref:0:3:CCGTAACTGGT 4 24 +CCG ref:0:3:AAAAA ref:0:3:TTATGCTCC 2 224 +TGG ref:0:3:ACCACTCTAAACTA ref:0:3:TTGCCTCGAACTC 6 152 +CAGCAAGGTG ref:0:9:GGCACGGA ref:0:10:AAGACGTCGCCACGCG 5 60996 +GT ref:1:1:ATTGCG ref:0:2:ACCTCTCA 3 20 +ATTAAGGAATAAC ref:0:12:GGTTAAGAT ref:0:13:CCCTGAGACTCTCAGT 6 205800 +TTAACCCCCTCAAGCT ref:0:16:GTTACTCGTGAACAGG ref:0:16:GCACGGTGATCTCCG 10 118554270 +GCG ref:0:3:T ref:0:3:GATACGAAGCGTGC 1 40 +TGCCACT ref:0:7:GGTCAATTTCAG ref:0:7:GGTACGGCGACCAA 5 35400 +ACTTAGA ref:0:7:GGTCTGAGGCTTGCC ref:0:7:TGGTA 1 27 +TCCTTTGAA ref:0:9:GGACCAGGAATAAGC ref:0:9:AGTGC 6 64512 +TGGCAGC ref:0:7:AGA ref:0:7:GCTCATGA 4 98 +AGGCGTGAGTG ref:0:11:CAAGGTC ref:0:11:ATTTAGCCCA 7 96538 +TAATAACAACGATG ref:0:14:GCTCCTATCCTGTTGA ref:0:13:TCG 6 300 +AAG ref:0:3:TATAGAATTTT ref:1:2:GCACGTCCATTT 4 1 +TATCCCCACCCCC ref:0:13:GTCGATAGCAT ref:0:13:ATGGTTC 9 415340 +TCGATTGCCG ref:0:10:CCTCTCAATAGGG ref:0:10:GGGACGGGATGGGGGG 4 699720 +G ref:0:1:CACA ref:0:1:CTCATAGAGATCTAA 4 10 +CCGTCCC ref:2:5:GGAGT ref:0:7:GT 3 3 +ATTTGTCTGT ref:0:10:AA ref:0:10:TCG 6 44 +GTCCGAAATCT ref:1:10:TTCACAG ref:0:9:CGCAGTG 4 6804 +TGTCGGGGCTCATGG ref:0:15:CAACC ref:0:15:CTAGCATA 10 9150 +CCCACG ref:0:5:T ref:0:6:AAACCCTCGTCATAA 2 12 +CACAA ref:0:5:T ref:0:5:GGAAATCTGCG 3 18 +TACCTGCTCAAGG ref:0:13:GTTTTT ref:0:13:GCGGAA 7 5670 +CACTTTTTATAAAT ref:0:14:GATC ref:0:14:TAGGCTTTTT 7 8148 +ACATTCGTTGACTG ref:0:13:AACCA ref:0:14:TTC 7 84 +T ref:0:0:AGACGCAGCGA ref:0:1:CCGCGCAAACGAAAC 8 16 +GATTACCTGTTTTAA ref:0:15:TA ref:1:14:ACTGGTCTCCAGTC 7 28256 +C ref:0:1:CCGCC ref:0:1:G 1 8 +ACCTAGGAA ref:1:8:CGCGCCTGG ref:0:9:GGAAAT 1 18 +GCGGCGAGTATAA ref:0:13:AGTATGGGATC ref:0:13:GCGTTTAGTTCT 6 42636 +TCCA ref:0:4:ATATAGGTGCGAG ref:0:4:ATGTCGCCATTAAGT 5 396 +TGGTAACCGG ref:0:10:GCGCTCTCCG ref:0:10:CTGCCAATAT 5 10222 +GCTCGCC ref:0:7:G ref:0:7:TAG 5 4 +ATACTTCAC ref:0:9:GAATTGCAAT ref:0:9:CAATTGTGTCAGCACC 4 1155 +TGC ref:0:3:CGGCGTACTGT ref:0:3:ACC 2 189 +CATAACAGCCTGGGTG ref:0:16:AGAGTAG ref:0:16:TCCCAAGTAAGA 9 6004 +TCATTCCCATG ref:0:11:GGCCTCC ref:0:11:A 6 144 +CGCCGCG ref:1:6:AGGTCGGGGC ref:0:7:AGACA 3 6448 +TTCTAAGATTAGATGT ref:0:16:GATCGATTA ref:0:16:TGTTATGATTG 6 507 +CTTCCTAGCA ref:0:10:ATTAAAGCACCACTG ref:0:10:CGGCT 4 13362 +AACCTAATTAAT ref:0:12:CCTCA ref:0:12:TATCCTG 7 2464 +AAG ref:0:3:GGGCTCA ref:0:3:CTGT 3 108 +CATGACTCTAA ref:0:11:T ref:0:11:TTGCGAGCGCGCG 6 2040 +TGCCGTTGTT ref:1:9:TATGTG ref:0:10:TATGCG 3 24 +CGAGACTCCG ref:0:10:GATATCCA ref:0:9:GATACA 5 104 +TCTTT ref:0:5:ACTACGGCAC ref:1:4:AAGGAACGCCCC 7 14287 +TCTAC ref:0:4:CAGCTCCTCATTT ref:0:5:GTTCAATGGTCTT 4 36 +CTAATTATCGATCTAT ref:0:16:GTAGA ref:0:16:CGGTCTACTGT 9 26860 +AGGCTCACTGAT ref:0:12:A ref:0:12:GACAA 8 66 +GTGAGCT ref:0:4:CAC ref:0:7:TTTTG 2 324 +TAG ref:0:3:CGACCACTACAC ref:0:3:CCCCTTTCCCAGTAAA 5 18 +A ref:0:1:CG ref:0:1:GC 2 9 +CTTGTTTGC ref:0:8:T ref:1:6:GATGAT 3 150 +GGGCCATGG ref:0:9:CCCCGCAATCACAC ref:0:9:TGATCTTTCGCGTA 6 2011875 +AGAGTTGCTTGGCC ref:0:14:TGTATGTGTGCG ref:0:14:GTTGGTTGAC 6 10464 +GTACTCGGTAG ref:0:11:CTAGGGCCGC ref:0:11:CAATAAGAACCTACC 7 8778 +GAGCTGGTATAT ref:0:12:CGAGGCCTTC ref:0:12:TAT 5 924 +CAATATGGTAGTA ref:0:13:TACGTGT ref:0:13:TCTTAC 7 190 +GTGTTGAGTGC ref:0:11:GGCACGGTCAG ref:0:11:TACGTTACGA 4 600 +GGGGTTCAG ref:0:8:GATGCGTTC ref:0:9:CGTCGGTAGTCT 3 294 +CGCATAAC ref:0:8:TGAAACAAAGTTTG ref:0:8:CC 2 42 +GCCATGTG ref:0:8:CAGGATTCTGGTGT ref:0:8:ATA 2 540 +TCATT ref:0:5:CA ref:0:5:ATGTA 1 1 +GAACGGATTTGTTCCA ref:0:16:GCAGAAGCTCGCCTAG ref:0:16:C 7 3729 +AT ref:0:2:GCTTGTGCCACATG ref:0:2:CTGC 2 4 +GACTC ref:0:5:TCTGGCGG ref:0:5:AGCTTGTGGCT 3 18 +GAACATGGTCCT ref:1:11:ATATTAGCTGG ref:3:9:TCTATTACAGG 7 2760 +GATCTCCCTGCACTT ref:1:14:TGCTCGACAGG ref:0:15:CCTACGGGCGTGGACA 6 27060 +AACGTGA ref:0:7:TTAGCTG ref:0:6:AGT 2 18 +TA ref:0:2:ATT ref:0:2:AC 1 4 +CAGAG ref:1:4:GT ref:0:5:TTTACTCCTTG 3 940 +AGCCATT ref:0:7:CAGTCTA ref:1:6:TCC 3 32 +GTGGCCGTATCA ref:1:11:GGCACACCACCTTC ref:0:12:TC 4 425 +TTCGC ref:0:5:AG ref:0:5:GGCATTTAGTGAGG 3 784 +ACTACCTGCGACTC ref:0:13:AATCTGAC ref:0:14:TCGGCGCTA 3 266 +GGGCACGTGTGCCCT ref:0:15:ATG ref:0:15:C 11 15 +GCGAGTGTTTAGA ref:0:13:GA ref:0:13:ACGT 9 385 +CTAACCACA ref:0:9:AGTGCCCAATGGTC ref:1:8:GACCCCTGTAT 4 5049 +TAC ref:0:3:TTGG ref:0:3:CTCCGAA 2 96 +ACA ref:0:2:TAGTGG ref:0:3:GTGGCTAGTC 4 30 +AGCTTTACCATAACT ref:1:14:GGGGTGGTTCCTC ref:2:13:CCCCAATT 3 1020 +GCAGC ref:0:5:TACGTTGGTG ref:0:5:GGCA 2 810 +TTAA ref:0:4:ATCAGTGA ref:0:4:TAGCATCTGT 2 14 +GCAGAACATGCCG ref:0:13:TCGGCAACGCGGGCAT ref:0:13:TTCACAGTCTGG 6 35100 +ACT ref:0:3:TGCCAATATG ref:1:2:GCGA 2 75 +GCTACGTAC ref:0:9:CC ref:0:9:CTGCTTATACCGCCG 2 144 +GTCACCACAT ref:0:10:TCGCAATTGCCGT ref:1:9:CACTAAGAACAGG 4 11820 +T ref:0:1:ATTAC ref:0:1:GTGGAAATGCCCAT 2 6 +TAATTAC ref:0:7:CAAGACGACCCT ref:0:6:T 2 612 +TTCTAGGAAGTCTG ref:0:14:CCGATT ref:0:14:CCATCCGTTC 9 63830 +ACCAC ref:0:4:CCCCTGAAGTTA ref:1:4:CTGGACT 3 150 +CTATCGAA ref:0:8:GGTTAAACTAG ref:0:8:GCTATATCCGCG 4 33600 +AGTT ref:0:4:CCTATTGGAGTCACG ref:0:4:CCGGGTCGGGG 7 3102 +ACAAAA ref:0:6:AAATGCCCTATGG ref:0:6:AGGA 3 686 +AATTG ref:2:3:GACCCC ref:0:5:CCGGAA 2 1 +CGTTTTT ref:0:7:GGCAT ref:1:6:TAACC 5 20160 +TCAA ref:0:4:A ref:0:4:ACACACATGAACAG 1 232 +CAAATAGAATT ref:0:11:GGGGGAAGTTC ref:0:11:TCCAGTTTAAGTGTTG 4 892 +CGGCCGACTGG ref:0:11:GATATCTAGTGATTC ref:0:11:AGGTGCGAA 5 4031 +GTTTCACAAACG ref:0:12:AACGCGAAA ref:2:10:CTTCAAATGATGC 2 153 +GAGGACGTGTGTACT ref:0:15:CCCGCTATGCAGGG ref:0:15:ATGATCGCACGAG 9 5026 +TAACC ref:0:5:CCCCG ref:0:4:GAGCGGTT 2 147 +ATACAGGTAGGTA ref:0:13:CCCT ref:0:13:GCGGTCC 10 20862 +GCGTAC ref:0:6:AGTGCC ref:0:6:GAATTACTGAA 2 750 +GTGTACCTCTAGTAC ref:0:15:TCCGTCTATGCAAGT ref:1:13:CTGCCTTCA 4 1352 +CAAAGGTT ref:0:8:GTGGAACTGAT ref:1:7:GGT 3 1104 +CGAGCGCCCG ref:0:9:TCCGC ref:1:9:TAAGTATG 4 1473 +TATTTGGTC ref:0:9:CGGGAGCCCCACTAAT ref:1:8:AGCAGTGTGGCGTCT 6 228616 +ACACC ref:0:5:TAG ref:0:5:TTAGTCGACATGACA 2 14 +CTCAGATATATGAT ref:0:14:AGCGACTTAAA ref:0:14:A 7 360 +CTCAGGGTTGGC ref:1:10:TGTCAGT ref:0:12:GACG 6 2628 +TACAACCTACTTCGA ref:0:12:CCTGGTATCT ref:0:15:GCGAAAT 4 162 +TC ref:0:2:GAAGGACTATTTGG ref:0:2:TATGGCGCCC 4 208 +TGTAGGTTACAACT ref:0:14:TTAC ref:0:14:CTCAAAGTAGTTTC 6 676 +A ref:0:1:CCCAGTATGAATCC ref:0:0:GTTCG 4 4 +TACTCTGGGAGAAT ref:0:13:TTGAGAAGA ref:1:13:GCCAAG 5 2418 +TGGCTTCGGTT ref:0:11:CAGTC ref:0:11:GATCATGTCTG 7 6844 +CACA ref:1:3:GATCCCTGGTG ref:0:4:GGACTGG 5 252 +GAACGTCATGG ref:0:11:AAATCTC ref:0:11:TTCGATTACGA 3 22 +TTATTGCAGGT ref:0:11:TTGAGTGAAA ref:0:11:AGTTTGTTGTAGAG 4 1782 +ATAGCTAACTATTTT ref:0:15:CTCCGCGCCCGATTA ref:0:15:TAGAGAAAACTCG 7 59259400 +CCCCCGCTGTTCACGA ref:0:16:CAAATCTCA ref:0:16:CACACGGT 10 428274 +TATGGCAGGTTA ref:0:12:TA ref:0:12:TCCAG 8 140 +AGAACA ref:0:6:TTGATG ref:0:6:GTAATCAGTGTGCACC 3 312 +TACTT ref:0:5:ATCTCCACCAC ref:0:5:GATCTGCTTTCTGAT 5 8085 +TCGGGCCGAGTA ref:0:12:TTTCCGCA ref:1:11:ACCCTTCC 6 4848 +ACTATA ref:0:6:TAGGGG ref:0:6:AACCCATATC 1 408 +TTAAGCCCTAGCGC ref:0:14:CTAGACTAAGTCCAAC ref:0:14:AGGGTTT 4 6096 +TC ref:0:2:CCGTCCT ref:0:2:GCA 1 4 +GAGGGTGACA ref:0:9:ACTCCTCACT ref:0:10:AAAG 5 90 +G ref:0:1:CCCATT ref:0:1:GGTTGTTTTACT 2 21 +CACTTGAT ref:0:8:CCGACCCGCGG ref:0:8:GTTAACCTG 5 29382 +TGACCTACCTACG ref:0:13:CAATAACCTCACATAA ref:0:13:GAGGA 3 3696 +GAACTTGGATTTAAGG ref:0:16:TCAC ref:0:16:T 14 1435 +GGACACCGCCTTAGAA ref:2:14:CGCTGC ref:0:16:CAGCAGCTATGCAAA 6 8280 +TCGCGCGACC ref:0:10:A ref:1:9:AACA 7 47 +AGTTTAT ref:0:7:A ref:0:7:GCACACGCT 4 102 +CACATGGACCTGGTT ref:0:15:TCCCCTCTAAG ref:0:15:AGGT 6 5236 +GATCCGCTG ref:0:9:CGTGAAGCGG ref:0:9:AGA 4 582 +TCCCAA ref:0:6:CAAGAGGAAGTTA ref:0:6:GAGC 5 11055 +TCAATGGTAC ref:0:10:CGTTGT ref:0:10:ACAATACGACCCTATG 3 1728 +TCCA ref:0:4:TGCGGGTCTACATTTT ref:0:4:CAGTTACCTC 3 50 +AAGT ref:0:4:CAGAGGAGCTT ref:0:4:CTGAACACAA 3 540 +GGCCCACAGC ref:0:10:T ref:0:10:TACATG 7 66 +AGCCGATCGTACAAC ref:0:13:GACGACCAT ref:0:15:TGGCTTCCTGTAAT 4 9828 +CGATTGGAGCG ref:0:10:AGCT ref:0:11:T 6 8 +GTCCGGG ref:1:6:CCGGGCCTTTCA ref:0:7:TAGAA 1 35 +AATGGCAT ref:0:8:TCCAAAGCTCCGTAC ref:0:8:CATGGCCGG 4 19200 +ACTGCTCGATAGGAT ref:2:11:GCCGTGAAATA ref:0:15:CGCT 4 60 +AA ref:0:2:CAGCTC ref:0:2:TCTGTGGTTTT 4 546 +TCCAATCGTGGTGACT ref:0:16:TGGACGC ref:0:16:C 11 612 +GGAGGTTC ref:0:8:ATTGGATGGGGAA ref:0:8:GTTGGGGTTGGACATA 6 630 +ACGGTGGCCT ref:0:10:CCAGAGTGCACCC ref:1:9: 3 116 +GCTAT ref:0:5:CTACGGAAAGG ref:0:5:CTATCTCGAAAA 6 42 +GAGAGGTTAAG ref:0:11:AAGAAACAAT ref:0:8:T 4 1594 +CCTTACCGACTTA ref:0:13:GC ref:0:13:CTCATCCT 6 142 +TAGCTCTTTTGCACT ref:0:15:AAGTTCTA ref:0:15:GGGAGAACA 9 421686 +G ref:0:1:ACAGAAGATAGTTGGA ref:0:1:T 1 10 +CTACAGA ref:0:7:TAGGG ref:0:7:GCCCAGCTC 2 420 +GTTCATGAT ref:0:9:ATAGAGCG ref:0:9:GGTTC 2 48 +AAGATA ref:0:6:GTCCAAATCACACA ref:0:6:CAAC 3 63 +C ref:1:0:AAA ref:1:0:AGGTTGGA 2 1 +CGAT ref:0:4:CCACCGTGGGCTGA ref:0:4:GTACAATCATCTGC 5 2912 +TATGTAT ref:0:7:GGA ref:1:6:GCGATTTGGTTG 1 36 +AGATCAAG ref:0:8:TTTCCCA ref:0:8:CCTCTCA 6 17550 +CG ref:0:2:CATACC ref:0:2:CCTAGAGCTAGCGTC 5 99 +TCAACAAGGTATC ref:0:13:GTATA ref:0:13:ATTCCTCTGCATCA 6 3968 +GATTGTACAGAAGCG ref:0:15:GGTGTTC ref:0:15:CCGGCCATCT 9 10504 +GAGGGTTGG ref:0:9:A ref:0:9:CCGACATAGCC 5 179 +GCTGTCGTAT ref:0:10:GAGACGGTTCGTTACA ref:0:10:AAACGG 4 504 +CAACCTCAACA ref:0:11:GATATCG ref:0:11:AAGGAGC 6 2332 +ATGAGCATAAGTG ref:0:13:GCT ref:0:13:CCGATCTTTATT 7 3692 +CGTCACCTGCGGCTTA ref:0:16:TCCCGGGTACCTCACA ref:0:16:GCTAG 6 2538 +GGAGTCATCTTATCTC ref:0:16:AAA ref:0:16:TA 12 5 +AAGTTCGGCAGAT ref:0:13:GGGGGGCAG ref:0:13:TG 6 990 +AAGGT ref:0:5:TAAC ref:0:3:CTGC 2 24 +C ref:0:1:CTCGCGAACCCCATCC ref:0:1:TA 2 27 +TAAAAGAT ref:0:8:GCAGAATAGAATTTAG ref:0:8:CATGAGTA 4 2214 +ATTCAACTGCTA ref:1:11:CCAACGGATT ref:0:12:ACGATCCCAG 4 7440 +TTTTT ref:0:5:GGC ref:0:5:CACACGTAACATACT 4 7616 +GGAACA ref:0:6:AATAT ref:0:6:TTAA 3 44 +TCAGCACGTTAAAGGT ref:0:16:AAGGCCCCCACGC ref:0:16:GTGACT 8 98232 +GTCTTG ref:0:6:GGTCCACC ref:0:5:CACTAAACCGCAAT 4 9480 +ACTA ref:0:4:TAGAGCGATTAAGT ref:0:4:CTGACTAAGTAACTTC 5 48 +CTGAGAGT ref:1:7: ref:1:6:TTTGACTCA 2 12 +G ref:0:1:TCAGCTAGGCCA ref:0:1:T 1 6 +GCCAT ref:0:5:GTTTGTCGCG ref:0:5:GGGCAATTAGTGCG 3 504 +AA ref:0:2:GAGGTACGCTTTCGA ref:0:2:AATACATAGG 4 30 +AATTGGACCTTCGC ref:0:14:AGCCTT ref:0:14:CAGGC 7 72 +CA ref:0:2:TCCGTAGCTA ref:0:2:GAACTGGTCCAA 3 30 +CGCAGAGAGC ref:0:10:TTGGCCTTAG ref:0:10:TCTACCTCG 9 1579435 +CGCCAGAG ref:2:6:CAT ref:0:8:CAGTGG 3 264 +G ref:0:1:CGCAGGCCGAC ref:0:1:CGGT 2 8 +AACGCGG ref:0:7:GATATCTGCAAG ref:0:7:ACC 1 8 +GTGGGGTGAGAACCA ref:0:15:TAGGGACAG ref:0:15:ACGCTTCGACG 7 7820 +CTGATTACGTGGA ref:0:12:CGGC ref:1:11:GACGGGCG 6 220 +ACGCT ref:0:5:AATTTTATCATCCCG ref:0:5:TGCATGG 4 687 +TC ref:0:2:GCTCACAT ref:0:2:GGAATCGGAGGA 3 2 +GCTAGTGACTCAACAG ref:0:16:C ref:0:16:CAACAAGACGCT 8 48 +TTT ref:0:3:GTGTCTC ref:0:3:GAG 2 20 +TTCAGCG ref:0:7:GCTTGAGCACCGC ref:0:7:CACTC 2 60 +CAGAG ref:0:4:GACACCAA ref:0:5:ACCCCCTTTGTACGTA 3 360 +AC ref:0:2:CTTTG ref:2:0:TAGGTTAAG 4 1 +AATCTCAATCTCA ref:2:11:TTGTTGGAGCT ref:0:13:CGTTCTTTCCACCT 6 685762 +TTATATTGTC ref:0:10:CATGGGTAAT ref:0:10:CTAGACCATAA 7 5277 +CAAGTACGGTACTTAA ref:0:16:GGTTCGATACGTCAGT ref:0:16:CA 7 11044 +TGCGA ref:0:5:CAGTACTATGG ref:0:5:CGTGTATATGAT 6 180 +AGAGCTGGCC ref:1:9:AGCGTCCGCGTCCGG ref:0:10:GATTCT 1 22 +GGCTACCAGAT ref:0:11:CACAGGCACAATAA ref:0:11:TGAGCCCCA 2 28 +TAACCCT ref:0:6:ATTAACTTTCGAGA ref:0:7:TTCCC 1 80 +GCCTT ref:0:5:AGTGCCCGATATACG ref:0:5:TTAGG 2 6 +GGAAGTGCAGTT ref:0:12:T ref:0:12:AGAAAGATC 6 300 +GCGACGGCTGGGG ref:0:13:ATTCGGTAG ref:0:13:CTTACTGTATC 7 8490 +C ref:0:1:A ref:0:1:T 1 4 +TTAT ref:0:3:TTCTAA ref:0:4:GCCAGTCTAC 1 12 +CTGGG ref:0:5:GCG ref:0:5:AAACACAT 2 14 +TGACTAA ref:0:7:GT ref:2:5: 4 1 +TTCGCT ref:0:6:AGAAGTA ref:0:6:TCAAATTCATACGCAG 4 1377 +CAGAAAGG ref:0:8:GCTCAGGTA ref:1:5:GTC 5 910 +TGTAGA ref:0:6:AT ref:0:6:G 4 16 +GTGAAACCAACAATGA ref:0:16:GGGCCTCTACTTACG ref:1:15:GG 8 2736 +GATGTCTACTGGCGG ref:0:15:GAGATTCAAACGT ref:0:15:GAGCGAGT 8 76788 +GTATGCACCGGCTTC ref:0:15:ACCGCT ref:0:15:AAGCTGCAAG 7 1248 +ACTCCACAAAT ref:3:7: ref:0:11:GCGGTCACGCACGAG 2 244 +GCTACAAGTACGC ref:0:13:CT ref:0:13:CTCTGTGAACAACC 5 405 +AAATGGATACTGTA ref:0:14:ACGTCGACTCTAC ref:0:13:TGCCG 6 3588 +TGTTTGC ref:0:7:ATAATGGCTG ref:0:7:GA 3 1144 +GCC ref:0:2:CCGTCA ref:1:2:CAAGT 1 6 +CAGCTAGGTCAT ref:0:12:CCACGCGCCCTGCA ref:0:12:ATGCCATAGCATGAGT 3 1290 +TAC ref:0:3:CCAGA ref:0:2:CCCCGTGTCGCAT 3 36 +GCGAGAACA ref:1:8:TCGCTAA ref:0:9:C 4 68 +TGACGTCAGC ref:0:10:AAGCTTGTCG ref:0:10:CC 4 21 +AGTG ref:0:4:GGTAA ref:0:4:TGCGCTATT 4 520 +CTTCTGCG ref:0:8:GTCGCCCT ref:0:8:TTCAATAAAAG 2 720 +AATTTGAGTTGGAC ref:0:14:TACGAG ref:0:14:CCCGCGG 10 139968 +ATAGGGCGTG ref:0:10:TCC ref:0:6:AGCATA 3 18 +AACGGTACATC ref:0:11:TTATTAATTTG ref:0:11:CCTTTCA 5 24003 +C ref:0:1:GCGGCTTCGTTTAA ref:0:0:TAAG 1 3 +G ref:0:1:GCACAAGCG ref:0:1:TTCCCGATATCCC 3 3 +TGACAT ref:0:6:TATGGCAGCGAATGC ref:0:6:GACCACTGCGGTATC 4 104 +CT ref:0:2:ATCCGGGCTCCTC ref:0:2:CGGCCATACCT 6 64 +ATGTTCCC ref:0:8:CCTCACCGTCAGG ref:0:8:CCTCCAAAA 7 69700 +TCCTC ref:0:5:AAGACCTAA ref:0:3:CAGCC 3 90 +CCGAAGTCGT ref:0:10:ACTGGGAA ref:0:10:TGGGTGCTC 5 972 +TA ref:0:2:ATTTGACCCCCGTT ref:0:2:ATCCCAATCGCG 4 6 +CCAC ref:0:4:CTTC ref:0:4:TCCTTGGAAT 2 50 +CTGTGGTCAACTG ref:0:13:ACA ref:0:12:TTCC 7 75 +ATATC ref:0:5:AAATGGGCTT ref:0:5:GT 1 24 +CGCTCGTA ref:0:7:GTGTGT ref:0:8:AGG 3 22 +CTTACAGTGAGAA ref:0:13:CGAGGAT ref:0:13:GTTG 7 3454 +AAGCGGTATGTTTCG ref:0:15:ATAGTGTTGCGT ref:0:15:ACTTTTATTCTAGC 4 800 +TGGAAGCG ref:0:7:GATCTTTT ref:0:8:GCTGA 5 90 +CTGGCTCTTTAGCACC ref:0:16:CTTTAGGA ref:0:16:TGACGGCCTTGGA 6 2340 +CTATTTGAGACTTCCT ref:0:16:GAATTCCCGTAC ref:0:15:AATTTACGCAAATAT 4 144 +ATTAACGTGTG ref:0:11:CC ref:0:11:TGTGGAACGAG 4 96 +CCCAG ref:0:5:TCAAA ref:0:5:TGAACA 5 1113 +GCCA ref:0:4:CAATGTTCATTGCGGC ref:0:4:TTCTTGTAGA 6 744 +TCT ref:0:2:ACTGCG ref:0:3:GGC 1 3 +AAG ref:0:3:GACTAGTAATTT ref:0:3:TTGATAGT 3 1 +AAGTAGGCGCCTAC ref:0:14:GTCCCG ref:0:14:CATAATGCAG 6 2968 +GACTTC ref:0:6:AGG ref:0:6:CCGCAGGAT 5 572 +AACGAGGTC ref:0:9:GCAGTGGATTGGGCTT ref:0:9:TTAA 3 3570 +TCTAATGAGAAA ref:0:12:GATAAGG ref:0:12:GC 7 84 +C ref:0:1:GCGAACT ref:0:1:CAGGGGCGCGAGTA 4 6 +GATTCGAGTGCATT ref:0:14:CGAGGAATGAGTAA ref:0:14:GCA 5 1314 +GTCATATG ref:0:8:ATTGCAAGT ref:0:8:TC 3 12 +GGGGCTATAGAT ref:0:11:GACTAAGGAACAAG ref:0:12:GG 4 910 +AGAGT ref:0:5:ACTCATAGTCAGAA ref:0:4:CC 3 315 +GGCAGTTTAA ref:0:10:ATTCG ref:0:10:CCCCCTGG 7 148478 +AACTCTACT ref:0:9:TA ref:0:9:TTGTTCGATGATGA 4 120 +ATAACCGTATTT ref:1:11:TTGCCTGTGTC ref:0:12:T 5 1485 +TTGC ref:0:4:CGTCGGCAGTCCCTGT ref:0:4:ACAAGAG 4 6391 +GTAGTAA ref:0:7:TTTGCGTA ref:0:7:ACCAGTCA 3 2310 +TGGTGA ref:0:6:ATTCTGAGG ref:0:6:AGAGGCTT 4 520 +TTGTGG ref:0:6:TCCAG ref:0:6:CGGGTGGTCG 3 9690 +C ref:1:0:TTAT ref:0:1:GCGATGTT 3 1 +TTCCATA ref:0:7:CGTCG ref:0:7:CGGA 6 1100 +CGATTTAATAGAAAT ref:0:15:GAT ref:1:14:ACTTG 9 160 +TAT ref:2:1:GGTTAACCCC ref:0:3:ACATGGGCA 1 10 +CGGCCTTCACGT ref:0:8:TTGCCGTAT ref:0:12:GCTGAGGGC 3 3060 +CCGTGATCT ref:0:9:CGCTAT ref:0:9:AGAGGGAAAACG 2 8640 +TAAAAGTCGCAAT ref:0:13:A ref:0:13:GACACCGGTGCGAG 6 8136 +CTC ref:0:3:CCAGGGTGGCTATTGC ref:0:3:GCGACGGGCTG 6 260 +GGTGGTGACCTTA ref:0:13:CATGCATTGGAA ref:0:13:GAAGCTCCAAACCC 7 2168256 +C ref:0:1:AGTCA ref:0:1:TTCATCTAGTGGCT 3 3 +CCTCCGGTTGAC ref:0:12:TCGTCTATACGTAACG ref:0:12:GCGCAGAAGGT 6 92432 +CGGGACGCAT ref:0:10:GATCG ref:0:10:C 6 9 +ATGCCCG ref:2:5:G ref:0:7:TCGTGAAGCGCAC 1 28 +CGGACGTGGCAAC ref:0:13:CCGGACATC ref:0:13:ATAGGGGCTCTA 5 49770 +CTGCGTGG ref:0:8:TC ref:0:8:TGTACGGCGA 2 1 +ATCTTTTATTCCG ref:0:13:TACAGGCTACATT ref:0:13:CAAGTACAAAAGTGCC 8 287280 +TGTTATCC ref:0:8:ACACACAGTATTTTCA ref:0:8:A 3 734 +TCTCATA ref:1:6:AGCAACAGGAG ref:0:7:CAGTGGCACCC 3 117 +AAGCTCTAGGATTCC ref:0:15:ATGG ref:0:13:CAGTTAGCT 5 144 +CGT ref:0:3:GAGGTTT ref:0:3:TGGCGTCTCCGTG 4 168 +CTTAGATCAAGT ref:0:12:GCATATCTAC ref:0:12:G 5 176 +AAACTATTTTGTCACC ref:0:16:ATTTCAT ref:0:16:CCTTATCTGGCAA 7 391440 +GG ref:2:0:ACTTC ref:0:2:ATCTCA 4 28 +GCTTCAAG ref:0:8:TAT ref:0:8:C 5 22 +CTGT ref:0:3:GTGAGCAC ref:0:4:ACCC 2 60 +G ref:0:1:GAGGCTAG ref:0:1:GAGGGATGGGTCTGGT 6 36 +CGCGAGA ref:0:6:ACTCCAGCATTGCGG ref:0:7:CACGCG 3 416 +AAGTCCACTCCCACTG ref:0:15:TTAGC ref:0:16:CGAGC 11 212 +GATATTTGTGGA ref:1:11:TGTAGAT ref:0:12:CATCAAT 5 384 +CGATGGTCC ref:0:9:T ref:0:9:GGATATCAA 4 72 +CTAC ref:0:4:GACGGTAGCCGTC ref:0:4:GGAGGATGTAGGCGTG 7 48 +GGTC ref:0:4:ACTGAGAGCA ref:0:4:TCCCCAACAC 2 30 +TAGGTACGCTCCC ref:0:13:CGACATGTTTTCTGA ref:0:13:CCCC 5 7875 +GCCTGGTTGCCAATCG ref:0:16:C ref:0:16:CTGTGCGCC 8 40 +TGACTACGT ref:1:7:CGTATTC ref:0:9:AAACTTACTTCT 4 1014 +ATGAAGTGTAGGCACT ref:0:14:GTCAAGGCCCGC ref:0:16:GCTCGCCAA 8 216800 +C ref:0:1:AT ref:0:1:TTATACCAA 2 6 +GGTGGCGGACC ref:0:11:TGTCCGTACCA ref:0:11:TCAAGCAGC 4 4410 +AA ref:0:2:T ref:0:2:GCATTTTATGAATT 1 18 +A ref:0:0:CTTCCT ref:0:1:TCT 3 4 +T ref:0:1:CTCTCCCGCTTT ref:0:1:TCTTCATCATCT 6 30 +ATAGTCAT ref:0:8:TGAGGAC ref:0:8:CATGTTGAC 4 169 +TTTCGATAACGCT ref:0:13:ACCCTGATCCTGG ref:0:13:GTGCGCTACTTGCCGG 5 15400 +TAGAGGCTGTTGT ref:0:13:CTTAT ref:0:13:CCGAGGCTTCCGAATG 5 672 +AACAAGCTTAACC ref:0:13:GTAAAGGCGT ref:0:13:CCG 7 780 +CGTCGGCAATGTCC ref:0:14:GGCACGA ref:0:14:TCGTCTAATGCTTAAT 5 24012 +CTGGAA ref:0:6:TTATTC ref:0:6:CACAGAGAATCCAG 2 468 +ACTCATG ref:1:6:GAT ref:0:7:GTGGGT 4 372 +GAG ref:0:3:ACTCCGGAATA ref:0:3:CATCCAAATAATCC 8 5434 +GCATGT ref:1:5:TCACACCCGGAAAGG ref:0:4:CGTTCCC 4 7505 +CGGGTACAGCCGCAGT ref:0:16:G ref:0:16:GGTTTAACG 9 360 +ACGCTGTACGGG ref:1:11:TGCTTACT ref:0:12:AG 5 64 +GTTTGAGTGTATA ref:0:13:GGGATATGGGC ref:0:13:GGA 7 2457 +AGCTTATGGCCTT ref:0:13:TTACCAGGTCT ref:1:12:TACCGTCCGAAGTA 7 13490 +TTTCAGCGG ref:0:9:CACAATAGT ref:0:7:ATAGGAACA 3 84 +CACGCCGAC ref:1:8:TACGTCGCCTTA ref:0:9:CGCAGATGGCA 2 174 +GAAACTGCCCTCTCGA ref:0:16:ACGAGGG ref:0:16:TG 11 3516 +GGCTGCCCTGGGCGGA ref:0:16:TAA ref:0:16:AAGCACTTTGAATTGC 9 177618 +CCGTCTAATCT ref:0:11:TATAACGTAAAC ref:0:11:TACGTA 7 2596 +GACATGCTACCTCT ref:0:14:GGGGAGCCGTAT ref:1:13:CCTGAGGG 7 117040 +CA ref:0:2:G ref:0:2:GCACCTAGGGAGTCAT 1 33 +TAACCTAATTCA ref:0:12:GGCTCACAGCAGGCT ref:0:12:TTCGAGG 7 3528 +GATTCAT ref:0:7:AAAATATACCGTT ref:0:7:GGATGTGCTCA 1 1400 +CACTTATACCGCCTTG ref:0:16:GTATAAGCCTGACCA ref:0:16:GAGGTCATTCT 7 245208 +TAGAAGCTCGGC ref:0:12:TCTTTATTG ref:0:12:T 8 2022 +TCCTCCATCCCAACC ref:4:11:ATAAA ref:1:14:TAAGGGGACCATG 6 8 +GC ref:1:1:T ref:0:2:GGGGACGTCGGGCAG 1 34 +GGTGGCT ref:0:7:CGCCTGCACCAC ref:0:5:GAT 2 750 +TGC ref:0:3:CATGA ref:0:3:TTGTTGTTGCAATA 1 24 +GGTTACACTAGGC ref:0:13:CACGCAG ref:2:11:TGGCCAGGCGCGAC 5 3503 +CGAGACTACCCTTACG ref:0:16:TTCACCC ref:0:16:ACA 10 1937 +C ref:0:1:GAAGGGGAAG ref:0:1:CCCTTCGGCGAGAG 6 55 +GG ref:0:2:ACTATCCGTGCAGCC ref:0:2:ATATAAT 5 108 +GGCA ref:0:4:ACACTCGTGTGGCG ref:0:4:CTCAACGAAGCCAA 3 48 +CTC ref:0:2:AGATGGCCCAATTGG ref:0:3:GG 2 60 +TCTCAAGAGATAGACG ref:0:16:CGTGCAGGAA ref:0:15:TATATTGCGGAAGAA 5 1458 +CGACGCGT ref:0:8:CTA ref:0:8:CTTCGCCGACG 2 30 +G ref:1:0:TCCCCTATACCAA ref:0:1:GATATG 3 2 +CGGCTTGGAAACGCC ref:0:15:TGTCTAACA ref:0:15:AAAGCCAAGCGTTTG 8 3407118 +TCATTGG ref:0:7:A ref:0:7:ATCAGGCAGATATGA 1 15 +ACGTCGC ref:0:7:GC ref:0:6:AACGAGGAG 2 204 +ATAAAACA ref:0:8:TCGGTGATGT ref:0:8:TTAG 7 84 +GA ref:0:2:TCAGATTTCTTA ref:0:2:GTGTCAG 3 4 +TACGTCTATTGAA ref:0:13:GGCT ref:0:13:GCGGATCTCAGGATGA 5 1944 +AACACCGG ref:0:8:GAGCTGCG ref:0:8:ATTC 5 8085 +CAGCAATGATTGCAG ref:0:15:ACAATGCAGGGGATCA ref:0:15:C 5 471 +CTA ref:0:3:GGAAC ref:0:3:ATCGAGTTTG 2 221 +AATG ref:0:4:ATAC ref:0:4:AGCACACGATCAC 3 288 +AGAGAGGTG ref:2:7:AAAAAAAATGAG ref:1:8:TCCTAAGGCACTA 3 18720 +CTTCCCTCC ref:2:7:AGAGTCCATTC ref:0:9:TTG 2 286 +TAT ref:0:3:CCATCC ref:1:2:GCCAAA 2 18 +TGATAAACTTC ref:0:11:GCAT ref:0:11:AGTGAGG 7 13620 +GCATAATTGCTTCCA ref:1:14:TCGTTTTT ref:0:15:TCTATCAGAGGCC 3 60 +AGAG ref:0:4:GCCCACGTGCG ref:0:4:AAAAATCA 2 1320 +GTGAGTAC ref:0:8:G ref:0:8:ATTTCTTAATCC 3 5748 +AGATGACG ref:1:7:GTGATGACGGTAG ref:0:8:TAGCTAGTTCCTT 2 786 +AGAGAAGT ref:3:4:GCCGAGCGGCCC ref:0:8:AGCC 3 2170 +CGCTTACAGCAA ref:0:12:AACAATTGGTGAGC ref:1:11:ACACATCGCATAAT 2 2028 +ACACGTG ref:0:7:TCATGA ref:0:7:GGAAAAAACTAAGGTC 1 718 +TACTTGCACAGGC ref:0:13:ATTACCTTATAAG ref:0:13:CCCGATG 3 448 +GACATG ref:0:6:AGT ref:0:6:ACA 2 7 +CGGCTCTTGAAATGC ref:0:15:ATG ref:0:15:AGGTATCGCG 8 54 +TTGACCCGT ref:0:9:GCCGATC ref:0:9:CG 4 9 +ACAA ref:0:4:CAATATGCACGGGCT ref:1:3:TCGCAATAAA 3 740 +TGGTAAGAGCG ref:0:11:GACGATCCCAGTA ref:0:11:CGGATCTCAA 8 1320 +CCACTCG ref:0:7:ATTATAGTGTGT ref:0:7:CGAGTGGCTTGATTA 6 11010 +ATTAGCCGCA ref:0:10:GAACC ref:0:10:ACCAAAAGGACTCC 4 402 +CACCATGCATAACC ref:1:13:TGTCGCGATGCAC ref:0:14:CTTAAAGG 4 4320 +TAGTG ref:1:4:AGAGAGCGAATTC ref:0:5:ATA 1 225 +AATGGTCAAATTATC ref:0:15:GAGTTTG ref:1:14:CATTTCTTGA 7 470 +ACGAAGA ref:0:7:ATCTTCTAGCGGCG ref:0:6:CTAAGGTCGGAAGTC 4 2568 +TGGAGAAT ref:0:8:ATTATCCATCC ref:1:7:AGAAAGGCAGGTCC 5 11115 +GAAGAGATG ref:0:9:GCGCGTACGAACC ref:0:9:GTAA 5 4584 +TGCGATGAAGTCAA ref:0:14:GCGC ref:1:13:GTATG 7 90 +TAAGGTCCACCCCAC ref:0:15:AGTC ref:0:15:AGTTGTCTGTGTTC 9 231168 +GG ref:0:2:AA ref:0:2:ATG 2 24 +TCAGTC ref:0:5:ACGGAAA ref:0:6:GTCTGACAATTGATA 3 770 +CAAATCTTAGACG ref:0:12:GGGCTCAGT ref:0:13:CTGACGGA 5 30 +CCAGCTACCGTAGG ref:2:12:GAAGGAGCGGGG ref:0:14:GCAT 3 152 +CAAAACT ref:0:7:AA ref:0:7:TAAAGATT 2 36 +GGGCACAAGTAACC ref:0:14:TCG ref:0:14:CGTCCATCCG 8 260 +CATGGCCCCGTTGGG ref:0:15:TGCACCAGACCTGG ref:1:13:GCTGTTTTTGCTGT 3 55200 +CGATAGT ref:0:7:AACGATCGATAT ref:0:7:AGCCGC 3 1248 +ACGA ref:0:4:AAGTCTGCAG ref:0:4:TGCGATCGATTCGT 2 2 +AGGCACAGCGGAAGA ref:0:15:CA ref:0:15:TCACGCCCATTGGGC 7 3636 +AC ref:0:2:TTCCGAAAAA ref:0:2:CTATGGGTCGG 3 22 +CTTAAT ref:0:5:TCAGCGTGT ref:0:6:ACACGCC 2 50 +GGGCAAGCAGCAACC ref:0:15:CAGTTCCTTAA ref:0:15:CAAGACGG 6 132 +CTGC ref:0:2:TCACTAT ref:0:4:TGCTCTTGAAT 3 92 +TTGACAGC ref:0:8:GTAGAGGATATG ref:0:8:TGA 3 264 +GAGTA ref:0:5:AGAAACTGGG ref:0:5:GGGGGAGGGAGT 3 4698 +T ref:0:1:GCGCTAGTGCGCCA ref:0:1:TGGTAGAA 5 4 +GAAAT ref:0:4:CCCA ref:0:5:CCATTTGTGTT 5 17646 +GCCCGGCCCACA ref:0:12:TAGCAGCCAAT ref:0:12:C 5 315 +TAGCTGTAT ref:1:8:CAAGG ref:0:9:TG 5 6 +GTAATTTTATACTCGA ref:0:16:CGTAAT ref:0:15:CGG 10 119 +AGTAGGAGGTCAGTC ref:0:14:CCCTCGCA ref:1:14:TTGACAATGCA 7 7200 +GTA ref:0:3:TCGCATTTG ref:0:3:AACACTGAC 3 84 +T ref:0:1:A ref:0:1:TTTTTTGCTGCGAAAT 1 16 +TCATTTGCGGAG ref:0:12:CATCC ref:0:12:AAACGTCTAAGTAGT 5 113040 +G ref:0:1:ATGCTCCGTTGATGC ref:0:1:TCT 3 16 +ATTTCAGCTAGCC ref:1:12:TTGCAGAGGGTTTG ref:1:12:CCCGCCGTT 5 7800 +CT ref:0:2:ATGTCCCGTGGCTT ref:0:2:TCTGCTGGTTCCTG 6 121 +TCGAACAATGTCCCT ref:0:15:AATCTAAGGGTACC ref:0:15:GGCCTGCA 4 7896 +GC ref:0:2:ACAAT ref:0:2:TCACGAAACGTTAT 3 2 +GCAAT ref:0:5:AGCCCGAAATAGTATA ref:0:5:TTTCCACACTA 2 513 +TTCTTAC ref:0:6:GTAAGTAACGTGATT ref:0:7:GAAA 4 928 +CCACATATGACGAC ref:0:14:GAT ref:0:14:CCACGCT 8 512 +AGCGCTTAGTAT ref:0:12:GTTA ref:0:9:CGTAACACC 5 360 +AGACAGACGGTAAGC ref:0:15:AAGACGATA ref:0:15:CATTCGA 6 784 +GCA ref:0:3:ATCGGATTTTT ref:0:2: 1 6 +TACG ref:0:4:GAAACAATCCTCGTA ref:0:4:AAACGCAG 4 1494 +CAATCTG ref:0:7:TGTCTATTTGAAG ref:0:7:A 2 52 +GGTACATTAATGTG ref:0:14:TTATTTGTAAGG ref:0:14:GATGTTG 5 8352 +CTTTTACAGTGCGTCT ref:0:16:TTCCAA ref:0:16:TCCGAGCCTA 10 31332 +ACGCGGAA ref:0:8:CCAGCACACTAA ref:2:6:TAACGGCCAC 4 5700 +T ref:0:1:CTTGCTTGA ref:0:1:ATAACTGGTTTGCCT 5 24 +AATCGTCGTTGCTCT ref:0:15:GTCGTTTGAATAGGAG ref:0:15:CGGACCAA 8 9282 +ACGGACAACTT ref:0:11:CCACACATGTGT ref:0:11:CCGCGT 5 7029 +GCTAAGATCTAA ref:0:12:AACGAGAT ref:0:12:CTGCTCT 4 150 +GCTCACCG ref:1:7:CCTGATTCGCGAC ref:1:7:AC 1 10 +TCATCGTTAGCG ref:0:12:GCCCGGCGCTTGC ref:1:11:ACAGCGA 1 117 +A ref:0:1:CGGGG ref:1:0:GTCCGTC 2 6 +AG ref:0:2:AAGTCGCGC ref:1:1:GGTTACC 3 12 +ATCTGATTTGGA ref:0:12:AATCTAGATTCTGG ref:0:12:TGTGCTTCGTTCTT 2 128 +GGGGAGGACCC ref:0:11:CCTTAGCGTGCA ref:0:11:AGGTCCCGTAC 7 68094 +ACGCCTGGGTCT ref:1:11:CACGGGATCGGG ref:0:12:CTTAACCAGCAACG 3 288 +GGAATTCCTAATAGA ref:0:15:TC ref:0:15:TTCCTGGAGTGTTG 7 248 +CGCGCAGA ref:0:7:TGGA ref:0:8:ACGAGCGTGAC 1 28 +CGTAATCCCAAAGA ref:0:14:GACGCATTACCGTC ref:0:14:GGGC 9 62238 +GGGAAGGTCG ref:0:10:AACAGGGGAG ref:0:10:TTGCAATTCC 2 50040 +C ref:0:1:AGACTG ref:0:1:CATCTCTGACGAC 4 5 +CTTCCTTTCCAACCT ref:0:15:GCACCACCAACGCAAG ref:0:15:GT 6 1968 +GTGTGAGTC ref:0:9:G ref:1:7:ATGATAGGTAAAA 1 12 +TCAGACCTAG ref:0:10:CGGCATTGC ref:0:10:GAAAAGTCATTGTT 7 167500 +GTACGTTT ref:0:8:TCCTCTGGA ref:0:8:ACCCGA 4 348 +AGCTGG ref:0:5:CCTTGC ref:0:6:ATCATACATACGA 3 624 +CT ref:0:2:CCGTGACCTTA ref:0:2:TG 1 10 +GGATCGTAATAGTGCG ref:0:16:CAGCAGGATTA ref:0:16:ACAAATTCACTT 10 255320 +TGTCTTCACTTTG ref:0:13:GCTTATATTGTGCACG ref:0:13:C 4 75 +TGGAGCGTGC ref:0:7:GCA ref:1:9:GGCCAAGGCCCCTT 3 3276 +TGTATG ref:0:6:TCCATGGAC ref:0:6:TGCAGTGCTTGGC 4 700 +ATGGT ref:0:5:TAAGGCGGCGCGTGGG ref:0:4:GTCCTGTTGA 3 854 +CCCTCGACACTATAC ref:0:15:CGG ref:0:15:CCATAGCAT 8 3816 +TTTT ref:0:4:AG ref:0:4:CGTGG 4 840 +CGGACCACCAATG ref:0:13:ATCTTCATTATT ref:0:13:ACCAGTCGTTT 9 30450 +GCCCTTGGCACGCCC ref:0:15:T ref:1:14:CGTATTGTAAGT 8 4440 +CACCCTAAGACC ref:0:12:CTGGCTAAGGATGGA ref:0:12:TC 4 3040 +ACT ref:1:2:GCAAATTACA ref:0:3:TACTTATAGG 3 6 +AA ref:0:2:TGACAAGTCTCG ref:0:2:CT 2 18 +AGCGTCTCCCGGTGA ref:0:15:CTGT ref:1:14:G 10 30 +CCACC ref:0:5:TCTCTG ref:0:5:AGGGCGTACCT 3 360 +GTTCAGG ref:0:7:CGGCACGGAG ref:0:7:TTGACCGTGGTACAGA 3 72 +AC ref:0:2:TTCAAG ref:0:2:CTA 2 16 +GGCCGTCGGGAGTC ref:0:13:TCCCCCATATTGGGG ref:1:13:AGCTCTGAGAGTCAG 2 24808 +TCGGT ref:0:5:ACTGTGAGTTATAGCG ref:0:5:AATGAGCAGCGC 3 72 +TTTGTAGGTGTTAT ref:0:13:AGAACCCGTAA ref:0:14:CCTCAAGGAAGT 8 8130030 +TTTCATAA ref:0:8:TACCATC ref:0:7:ACGGTTAAC 3 336 +A ref:0:1:GGCTT ref:0:1:TTCGGGCTATA 5 12 +CTAATCAACGT ref:1:9:GGACGGCGAAA ref:0:11:C 5 1116 +GGCTATAC ref:0:7:CTAGT ref:0:8:A 3 2 +CCG ref:0:3:GGAAC ref:0:3:AAATCAGG 3 150 +T ref:0:1:AATCAAATGCAC ref:0:1:AGAAGGG 4 16 +CTCACAGGCGGG ref:0:12:CC ref:0:12:A 9 12 +AGTTGCA ref:0:7:CC ref:0:7:CAACCTCGACCGGC 4 4232 +CAGACACATG ref:0:10:GAGGGC ref:0:10:GGAATGGCGC 8 5566 +CTCAGTACGCCTA ref:0:13:TCGTCGAA ref:0:13:TGAGGAAGTCAG 3 440 +GGC ref:0:3:CT ref:0:3:CCAG 2 9 +CCGCACA ref:2:5:TTTTG ref:0:7:ATGTG 6 121 +CATAATGGCGACCTA ref:0:15:GAC ref:0:15:GGGCGTAAAGA 8 2916 +CGAATGTGACTCTTC ref:0:14:TGTCTGC ref:1:14:CTCTAT 5 1 +TGGTTTATTG ref:0:10:CTTT ref:1:9:GAGTC 5 2145 +GACTCAC ref:0:7:TCATGGCCCGCC ref:0:7:GGCTATGAACGGT 4 20735 +CCGAACCGCAATA ref:0:13:AGCTGGTGC ref:2:11:TATATGCATAT 5 10782 +A ref:0:1:TAAAGGA ref:0:1:AATGCCCCAAGGC 4 16 +AGGACG ref:0:6:GCCATCAGGAACCT ref:0:6:CTTGGGTCTGACTATC 4 4520 +CACA ref:0:4:GCATCACA ref:0:4:TTTC 1 55 +ATGATAGTCTGACAGA ref:0:16:AGCAGAAG ref:0:16:CCCCCTTGTACAGGCC 5 1344 +GGTAAGCCAG ref:0:10:ATGCGTCTTGAAACAA ref:0:10:CTTCCT 4 5022 +T ref:0:1:TGGTAGAA ref:0:1:ACACGTCC 1 2 +TCTTTA ref:0:6:GCAAGGTACC ref:2:4:TAATAATTCAG 2 168 +CAAGGCTGA ref:0:9:GGAGTC ref:0:9:TGAACTCTGAC 4 2952 +AGGAT ref:0:5:TGGTCTCGAATAA ref:0:5:GCATGTGTCAC 3 42 +T ref:0:1:TGAGCTGT ref:0:1:AAGTTAAC 3 6 +AGTC ref:0:4:ATATTACGAAC ref:2:2:ACG 2 62 +TGCGTGTCGA ref:0:10:GATTTTAG ref:0:10:CGGAAGTTGC 6 59496 +TAGTGAGTCTCGTC ref:0:14:TTGCGTGCGGCCGGG ref:0:14:GCTAGACGCCAGAA 7 19332 +GTAGCC ref:0:6:ACACATCCATAGCACG ref:0:6:GAGTAATATG 4 176 +GAA ref:0:3:ACGGG ref:0:3:GAACAGCGGAATCG 4 208 +ATGGCTAAAAAGT ref:0:13:CT ref:2:11:GA 7 20 +TCTCCTGG ref:0:8:CCCGCGTGA ref:0:8:AGGTGGAGTA 5 6608 +GCTTCTTGGG ref:1:9:ACCAGC ref:1:9:TTACGTTGGGAGTC 2 88 +ACGCT ref:0:5:TTAGAA ref:0:5:CA 3 42 +CGAAGAAAACAG ref:0:12:GTATGTGTCGTCTCGC ref:1:11:AGC 6 17320 +TAAT ref:3:1:GGTAAGCCAA ref:1:3:GGTC 3 6 +CGGATATGAACA ref:0:12:TAT ref:0:12:AGTAGCTAGAATG 5 148 +CTGAGCATCCGT ref:0:12:GCGTGCCGG ref:1:11:GTGGATAA 4 1024 +GTGACCTA ref:0:8:AC ref:0:8:TGCACTATCTAGA 1 4 +ATCAAAGA ref:0:8:GTGACCT ref:0:8:TC 4 2 +CTCCATCTCGT ref:0:11:CGAGGC ref:0:11:TGCAG 7 546 +TCCCTCCCCGC ref:0:9:GACGACCT ref:0:10:CTACTTGT 6 528 +CGAACGGCAAACTC ref:0:14:A ref:4:10:GTGTTCCTGG 5 15 +T ref:0:1:TTGAGGTGCC ref:0:1:AC 2 9 +GG ref:0:2:TATAGGACGA ref:0:2:ATA 3 30 +TGTGCCGTTTTTC ref:2:11:TCTCCAAAATAT ref:0:13:CACCTCACC 7 4586139 +CGCC ref:1:3:TGGGCCTTAGAAGT ref:0:4:AAAGCT 1 36 +TAT ref:0:3:CGGGCTATTCCCGATA ref:0:3:CCGGTAACTATCTGT 7 84 +CATTCCC ref:0:7:GGAGAAAGAATG ref:0:7:AGTAGACAAGC 7 36480 +TCGCCGTGACGA ref:1:11:GCCTGAAC ref:0:12:GAGG 3 75 +GTCCCCATAGA ref:0:11:GGACCCACACC ref:1:10:CCTCGGGAA 5 190784 +C ref:0:1:GTTACA ref:0:1:TGAGCCCTCG 2 4 +GGA ref:0:3:ACAACA ref:0:3:TCACGTAGGGAT 3 228 +GCTCAC ref:0:5:TTCGCTATCTAAA ref:0:6:ATCGCAT 3 210 +C ref:0:1:TACCGG ref:0:1:CTCCAACGGTG 4 8 +GTCGCCACCGACT ref:0:13:AG ref:0:13:GA 10 5 +CA ref:0:2:GTGCGTCACTAGATA ref:0:2:AGTGGCAT 5 11 +CGCGGCCGCGGTC ref:0:11:TC ref:0:13:AAGACGGAGGTCG 5 1170 +TCTTGCTCGGA ref:0:11:TG ref:0:11:TATCAGCACCC 6 9614 +CCACCAGAAATCT ref:0:13:CCAATATA ref:0:13:TTC 7 3484 +TC ref:0:2:TTGCCTGAGAAACT ref:0:2:TGGGTCTAACTA 6 35 +GCAAACCCACAATG ref:0:14:GGACGCC ref:0:13:C 8 300 +TGGTACCCCC ref:0:10:ACGCTTTGGTAGCTAA ref:0:10:CACTAATGACCAG 7 171990 +TCACATGTTTA ref:0:11:CTTCTGGAAA ref:0:11:CGTCTTGCTTAC 5 35843 +GAGAC ref:0:5:TCCAGT ref:0:5:TT 5 252 +GTTATTACACA ref:0:11:CACCGACC ref:0:10:TCGCGACTCCCCCT 7 257166 +GTCAAATC ref:0:8:AATGA ref:0:8:TAAGTTAGCAAACCGT 1 80 +CG ref:0:1:TGCAA ref:0:2:ACCCTAGGT 1 6 +CCGAT ref:0:5:CTTA ref:0:5:ACCGGTCTAGCTGGG 2 36 +CTGTGAT ref:1:3:GTCT ref:0:7:GGGCTAGATAGGC 2 112 +CTAAT ref:0:4:TAC ref:0:5:CCAGCCA 1 9 +GGGTGACCAGT ref:0:11:CTCAGAGAGCTTTAG ref:0:11:CTCGCGACAC 8 212175 +AAGACCCCGATATA ref:0:14:TTATCATCCCCGAATT ref:3:11:AAATCGTG 3 40050 +AT ref:0:2:TCAACACAAA ref:0:2:ATGGCGACCCTTCCT 4 189 +ACTGTGAGTAAC ref:0:12:AACCGCAT ref:0:12:CATTGCCTACTCTG 5 2744 +AATCGCCGAGGTG ref:0:13:AGT ref:0:11:AGTCCACC 6 990 +CGGAC ref:0:5:AGGAGGCTGC ref:0:5:AGCA 2 56 +GCTAACCATGGTAT ref:0:14:CGGCTCGCAACGAGG ref:0:14:GGGTAGCAATCCTGA 5 264 +GAGCCGTTCGTA ref:0:12:TTGCTATC ref:0:12:ACTAAGTAGTACCAC 6 1248 +AGCATGGCGAACAAG ref:0:15:TTGGTCCGCCCT ref:0:15:GAACACATGTCTTTT 7 45594 +TCCAC ref:0:5:GTAAGG ref:0:5:GACCGGTGGA 3 39 +AGGAGGACATATGTTT ref:0:16:TAGGCCCGTACCCAG ref:0:16:CAGCTAGCTTA 5 15600 +ATTACA ref:0:6:TCTTAGT ref:0:6:GAACGCACTCGTGTC 4 663 +CCGAGCACTGTGAC ref:0:14:CGTAGAT ref:0:13:TCAATCAACTGCCG 3 564 +TTTATTCCACG ref:0:11:TCATATTTGCAGTCA ref:0:10: 3 175 +CAGCGAAAATC ref:0:10:TGC ref:0:11:TGCTCTTAC 8 2574 +GTA ref:0:3:CTTAGACTACGCGG ref:0:1:C 1 2 +TTTAAGCACAATTGAG ref:0:16:CGTCTATAACCCTGCA ref:0:16:GGTGTCAAG 5 4320 +GGCACCACAGTGTTT ref:0:15:TTCTTCCAGTCATT ref:0:15:CAGCGATACTGCGTA 6 2456946 +CTGTG ref:0:5:GTTGAACTGTAGAC ref:0:3:TTATATCAGACG 4 34 +AGACGCGAAACAGCA ref:0:14:TATGCTTAG ref:0:15:ACCCCG 7 14326 +CAGTATGG ref:0:8:CCGGCACAGCTCTAG ref:0:8:TCCTGCGATCCGCTGC 3 2030 +GATTCCGCAGTATGA ref:0:15:ATCTCGTA ref:0:15:ATGGTCC 7 2565 +TCCAGCATTCCCCGTG ref:0:16:ATTCTGACTTAGAGGG ref:1:15:GACTCGAGGGATAC 7 1048320 +AGCACTTCT ref:0:9:TCCCGTTTCTCTT ref:0:9:CTT 3 1890 +CT ref:0:2:GTTAACCAGCTAAC ref:0:2:TACAGGATGAGGG 5 3 +CTTCTGTAAA ref:0:10:GGTG ref:0:10:TCACAGGACGTTT 4 104 +ACTACAACGGAATC ref:0:14:GCGAT ref:0:14:TAGCGATAACTGTA 6 10540 +TCTGT ref:1:4:GCGGGAATCCG ref:0:5:ACCGTTATGATACGC 4 147 +TATTATG ref:0:7:CCTTCGTCCAT ref:0:7:CGGGTCTACAATCTGT 4 248 +TAAGGGATTGCCAGC ref:0:15:GTC ref:0:15:GGAGAGG 7 180 +C ref:0:1:GT ref:0:1:GATCG 2 3 +GGACGA ref:0:5:CTGCGG ref:0:6:A 2 18 +GGGTGCATGAACTTC ref:0:15:CTAGCTGTTTACGCC ref:0:15:CT 7 1400 +GCT ref:0:3:TCAGGCCTGT ref:0:3:CACTTGT 4 104 +TCGGATTT ref:0:8:CA ref:1:7:CCGG 3 2 +CCATAGTGAATAA ref:1:12:GCAAG ref:0:13:AACTTCTCATACTT 5 38 +CCGATTTGAACAGA ref:0:14:GCTTGCGTTAG ref:0:14:GGTAAGGGCGGATAGG 7 10906 +TGCCAG ref:0:6:CTACA ref:1:4:ACGGACTAC 2 78 +CTGATCAGTT ref:0:10:C ref:0:10:CCAAAGCGCT 5 952 +CTTCAGTG ref:0:8:AGCAATTGTGTTAT ref:1:7:GGCGACCG 1 66 +ATGTACAC ref:0:7:CTGTTAAG ref:0:7:GTAAAAT 2 40 +AGAGTAAATCTAGA ref:0:14:GCGCGCCATCA ref:0:13:CTACAATTGTGTCCG 6 327600 +C ref:0:1:ACTGTCGCGCTAACC ref:0:1:TCCCTCCCCTGA 6 42 +CGCAATTTACTGCGGA ref:1:15:CTTGGATCGCACT ref:0:16:TACGATTAC 5 312 +GGGCAGGCGAC ref:0:11:TTCCCCGGCG ref:0:10:AGATGC 4 4294 +GCCTGGCCACCTAAAG ref:0:16:T ref:2:14:TCATTGACC 8 10 +ACTTAGAAAAG ref:0:11:GCGCCAAACGTTAC ref:0:11:CGAACCAGT 6 108 +G ref:0:1:ATTCGG ref:0:1:CCGTTTGTTCT 2 4 +GCC ref:0:3:TTGGGCCTGGGA ref:0:3:CATGGGAC 3 39 +T ref:0:1:GC ref:0:1:CTGAAGTGCCACAATA 2 9 +AGAAATCGCGTCT ref:0:13:GCC ref:1:10:ATAATTACACCG 2 48 +GCCTGTATTAAC ref:0:12:GTAGAAGTGCCGGG ref:0:12:CCCGACCGGTAA 4 6800 +GGTGACCGTCAAT ref:0:13:TGT ref:0:13:GATC 8 12 +TACGACGCTACTGA ref:0:14:ACGA ref:0:14:CGTTAC 8 255 +AGTCT ref:0:5:ATAAAGACGGA ref:0:3:CCTTTTAAACTGA 5 540 +CT ref:0:2:AATCCGTACATGTACT ref:0:1:CGCGGGAGCCC 5 60 +ACGACGGT ref:0:8:CACACGTTAGTAA ref:0:8:GGGAA 2 3 +TGGGAAA ref:0:7:TTATAAGGC ref:0:7:AGTCCTC 5 6795 +TCTGCCGCTC ref:0:10:TTCAACAACACGGC ref:0:10:CGCCGC 3 1428 +CGGT ref:1:3:TTGGGTCCTCGA ref:0:4:CTGATTCCGCGCGA 6 282 +AAAGACTCCCACG ref:0:13:CCTTCGCTCA ref:0:13:C 7 70 +CAATTTC ref:0:7:GGCCCGG ref:0:7:TGCTGA 6 376 +AAACC ref:0:5:AAGAGCAGTGCC ref:0:5:AAAAACTTGAGA 2 510 +TGTAGTTA ref:0:8:GACCAGCG ref:0:8:TCCTCAAGCAAGT 6 8710 +CGGTTAACAAACGGA ref:1:14:TAG ref:0:15:ACATTCCCTCCG 8 36540 +CGCTGG ref:0:6:C ref:0:6:TACGACCATCTCC 2 96 +G ref:0:1:TTACTTC ref:0:1:TTAAGGTGA 4 24 +AATGCAAGAACT ref:0:12:CAAGCTAATAGC ref:0:12:TTCC 3 65 +CGGTATTCCTTGCCT ref:0:15:GCAGTCCCCGACAC ref:0:15:GA 7 1188 +TCGGATT ref:0:7:ATGGCGC ref:0:7:TGTTACGCTCC 5 4592 +GATG ref:0:4:CGCGTGCTACACGAC ref:0:4:CGCCGCAACTCGCT 7 152 +CGCATGCGATCAACAG ref:0:16:CGC ref:0:16:TATC 10 32 +TTCACGAGCTTAGAG ref:0:15:GCCATTAGCTGTT ref:0:15:TC 6 54 +AGG ref:0:3:AAGCGCCGT ref:1:2:GATT 1 30 +CAGTTGACTCAT ref:0:11:TGAAACCCAGATGCC ref:0:12:C 4 27 +CTCGTAAACGGCCAGG ref:0:15:GAAGTGCCACAGCC ref:0:16:TCAC 4 108 +CCGACGGCTTCCCAT ref:0:15:CTTTGACGTG ref:0:15:TC 8 870 +CGCTTACTCCG ref:0:11:GTGAGGCTCCGAAAA ref:0:11:GATCGTA 4 6 +TGTTAGATTTATAAGA ref:0:16:ATAACGGTGGTT ref:0:16:CGCCGCTA 10 699840 +ACCCTTACCG ref:0:10:TATACAAACTGCATAA ref:0:10:TCTCTCGCT 6 13335 +GACTAGGCCA ref:1:9:CAGGGT ref:0:10:CCCG 4 36 +GCAC ref:0:3:AATTCTTTAGAT ref:0:4:GGA 1 33 +CCTTGGCA ref:0:7:T ref:0:8:TTCT 4 4 +GAGATCGT ref:0:8:CGTGCGCAGAC ref:0:7:TGTAATTC 2 6 +GTTGACATCCAGCA ref:0:14:CGGG ref:0:14:ACTAGTTTGTGC 8 3 +TTCCATG ref:0:7:GAGGAGTGCTGT ref:0:7:GGAGGTT 7 2548 +AAACCACTT ref:0:9:GATGGC ref:0:9:GT 8 5525 +TATGTGT ref:0:7:AGTGTGAGGTCCATT ref:0:7:TG 1 45 +TCGGAAAT ref:1:6:GAGGCAC ref:0:7:GTC 2 69 +CACTTTAGGGGCTA ref:0:14:AAAGTTATACT ref:0:14:ATTGGTCCTTCACGG 4 2400 +CGGCACCTG ref:0:9:TT ref:0:9:CGCGGGAATTT 5 8710 +GGAGCCTAGTATTCA ref:0:15:GTGGATCTTGTG ref:0:15:TCGT 9 53313 +GTGTGATGA ref:0:9:CGTAGT ref:0:9:AACATATGACGACTC 4 480 +GA ref:0:1:GGTC ref:0:2:T 1 6 +ACGCGCG ref:0:7:CTATCAACCTATTAT ref:0:7:AATCCA 5 630 +ACGAGTC ref:0:7:CAGCATTTCCGT ref:0:7:GCGTA 3 630 +CTGAACTTT ref:0:9:GGAC ref:0:9:TAACGCCTGGCCCA 3 1323 +CATGTCGTAG ref:0:10:GTCG ref:0:10:GTCTTCTAAAAGTTGG 2 40 +GCCGGAAGTTA ref:0:10:GATGTTCGTATTT ref:0:11:GAATGG 3 19446 +ATATAGGTCTC ref:0:11:A ref:0:11:CAACA 8 66 +CGGAGCTTG ref:0:9:ATCC ref:1:8:TGAAG 4 546 +CTCGC ref:0:5:GCTACA ref:0:5:CCGTGTAGCTTATACT 3 348 +CCA ref:0:3:T ref:1:2:AATTAAGCAGAT 1 8 +GGCAGCAGCACAGCGA ref:0:16:GTGAATGGTTT ref:0:16:TGGTTTATGTCCTCTT 11 513216 +CAGGTTAG ref:0:8:ATACGAGCG ref:0:8:TATGTAA 4 3744 +TTGGTGAATTT ref:0:11:C ref:0:11:ATAC 10 1152 +TCCGCTAT ref:0:8:ACCCGCA ref:0:8:CCAGT 2 35 +TATTCTGTC ref:0:9:CTCCT ref:0:9:GTGGCAAA 5 5005 +AACGGTACGTTCC ref:0:13:ACTGA ref:0:13:TTCGTCCTAGAAG 6 288 +ATCCATGTTC ref:2:8:CTAAAA ref:0:10:CTCTCA 6 13572 +A ref:0:1:CGATCGG ref:0:1:AGAA 1 3 +TAATGA ref:0:6:GTTTG ref:0:6:GC 3 10 +CTGTC ref:0:5:AA ref:0:5:GAATAGGCTCGCCAGT 3 609 +CTATAACCC ref:0:9:AGTACCTGCTCG ref:0:9:C 3 36 +CAGAAGCCCCCGG ref:0:13:GCGTAGC ref:0:13:CTGG 8 630 +CGGCAG ref:0:6:GTTAGTCCTCTTAAC ref:1:5:TTCTT 5 540 +TCC ref:0:3:A ref:0:3:GGCTTCTTTGGCTCAC 1 88 +TCAAA ref:1:4: ref:0:5:GGGCACGGCCACCCGC 1 52 +TCCGTGATAGA ref:0:11:TAT ref:0:11:GTAGAGGTTTCA 5 64 +GGCCGTGGC ref:0:9:CGATGGATGTATA ref:2:7:CC 2 168 +GGCG ref:0:4:GGGACTATAAAGCT ref:0:4:GATACT 2 30 +AAACCCGA ref:0:8:ATCAATCACTCCGATT ref:0:8:AT 1 154 +CACCGGAATG ref:0:9:GGTGACGTTTT ref:0:10:GGAAGTGCGCCCCA 5 1424 +CAGGT ref:0:5:TTTAA ref:0:4:GCTCCCTGACG 3 1134 +AACGGAGGT ref:0:9:TTAGATAT ref:0:9:CCTC 4 684 +GA ref:0:2:AGCGAGCCATTC ref:1:1:TTAGT 2 5 +CCAAACTC ref:0:8:GTCA ref:0:8:ATGGCCCGT 4 19 +GCTTTCATCGCA ref:0:12:GTAGATACTTCCCGG ref:0:12:ACG 5 1226 +TGGAGAGACACGGGT ref:0:15:GC ref:0:15:T 12 16 +CCC ref:0:1:TGCGGAAGA ref:0:3:ACAGTAGCCGCAG 3 4 +CCGTGG ref:0:6:AGTTAAGGAAA ref:0:6:A 3 42 +GCTATAAATATT ref:1:11:CCATACACGGCACA ref:0:12:TAGT 4 576 +CCAACAT ref:0:7:TACTTGTC ref:0:7:A 4 147 +AGATAATC ref:0:8:TGTTGAG ref:0:7:CAGATTA 3 444 +GTAGAAAA ref:1:7:TTAATCGATA ref:0:8:GAATTGTCTAGAG 4 17400 +GGTACGCTCAGAGTGA ref:0:16:GGGTG ref:0:16:CCCG 8 39 +ACAGT ref:0:4:CTTGGCCGCGCCC ref:0:5:TAAGGTCGTGAC 4 672 +GCCTC ref:0:5:AACAAGA ref:0:5:AAACATGTCC 6 21070 +C ref:0:1:AAGCACTCAGGCTT ref:0:1:CCCCTCCCGGCTCC 7 40 +T ref:0:1:ATTGAGATCCGG ref:0:1:TCTGCCT 4 9 +GGGTCACGTATCT ref:0:13:C ref:0:13:TGCCCGGC 8 570 +GA ref:0:2:TCTCAACCGAGTG ref:0:1:CGTGC 2 2 +CGGACCAACC ref:0:10:TTCAAACCGGAAT ref:0:10:TTGAGTTT 7 83700 +GGTAATTGACA ref:0:11:ATCCCTCGG ref:0:11:AAC 6 48 +CATTAAGCTCCGCC ref:0:14:CACCGAAAACTAG ref:1:13:GCGTGC 5 882 +TT ref:1:1:CCCTAA ref:0:2:TAGTGGCTCTGA 3 6 +GCGTTACCCAGAT ref:0:13:TGTTCTAGCAGAGAG ref:0:12:CTTTG 4 13536 +TGTGCTT ref:0:7:CGTC ref:0:7:GG 3 2 +CCGCATGACAGCT ref:0:13:GTTATAAGTGA ref:0:13:GTTG 7 39 +AATTTCGAATTGACGT ref:0:16:CTT ref:0:16:TC 12 24 +TCGA ref:0:4:GGCTT ref:0:4:TATGAGCTGACCGC 3 80 +GCTCCACGCGTTAGGA ref:0:16:CAGGTCACATA ref:0:16:ACG 8 3192 +TGAGCT ref:1:5:CGGGCCATACAAG ref:0:6:G 1 16 +ACCACCG ref:0:7:TTCTCTTTT ref:0:7:GCTGAACT 6 92250 +ATTAAC ref:1:5:GAACAAGG ref:0:6:GCTTCGCTCGT 3 219 +AATAATTATGA ref:0:11:TGGTGG ref:0:10:GGCC 8 1991 +TGTGA ref:0:5:TCTCGAGCCGTCA ref:0:5:ATTGCTATGACTT 3 160 +AGAGCGGGGC ref:0:10:ACA ref:0:10:GCGGTTCACACT 5 2816 +TGCTTAA ref:0:7:CGCATCATCTTC ref:0:7:TATATCTGTGGGC 7 26055 +G ref:0:1:TTAA ref:0:1:AT 2 15 +AGAT ref:0:4:TGTATC ref:0:3:CGGAGGTGGAC 1 8 +G ref:0:1:CAGGACTGG ref:0:1:AATGTAAACACTC 4 4 +GTTCCCTGTATGCAGC ref:0:16:GGGCTTAGTGGGG ref:0:15:CCTTC 5 8694 +CCAGTTAGTCA ref:0:11:GTCCCTAATTGACCC ref:0:11:TTTCAATAGATATG 4 10656 +ATACGCTGTTTCGT ref:0:14:GACATC ref:0:14:GT 10 1570 +GGACA ref:0:5:CGG ref:0:5:CCGGGCTGTGTACG 2 24 +TTAGCGATCCAAT ref:0:12:ACTCA ref:0:13:AAGCC 6 80 +GAGGAG ref:0:6:A ref:0:6:AATGCGA 2 6 +AACCTGGGGTAGAG ref:0:14:CACCCTTTTTA ref:0:14:CAAATAGAT 6 74700 +GAGATGA ref:0:7:CGTCACTG ref:0:7:TAACGTCGTACATCGC 6 888 +CA ref:0:2:CTAAGGGTTCCATA ref:0:2:GAGCTCGCATCCTAA 6 104 +TGAAACT ref:0:6:ATA ref:0:7:TTGGCTCCCCGCTT 2 17080 +TG ref:0:2:TGTTGT ref:0:2:ACATGTACGGACTCAA 3 20 +TTCG ref:0:4:CACTCA ref:0:2:AGCT 3 50 +TTCCGATCTAAT ref:0:12:TTTCAGC ref:0:12:CATA 5 264 +TGGCG ref:0:5:CAGCTC ref:0:5:GTAAA 4 3784 +CCGCCGGTTTCCCG ref:0:14:G ref:0:14:GTCTC 10 396 +CCGCTTCAGG ref:0:10:GCTA ref:0:10:GCCATACCCTGGTGA 4 3738 +GGAGATTAG ref:0:8:ATCT ref:0:8:T 5 4 +TCGCCCAAAATGCG ref:0:14:CTGGAGGA ref:0:14:TTCGAGTCCCTACCT 5 35168 +CTATCATCT ref:0:9:ATCAAGAGAGC ref:0:9:TTTATGGACGTGG 4 456 +GACATTGCGCCCCT ref:0:14:T ref:1:13:CAACTCC 8 831 +TCCCCCTGA ref:0:9:GGGGCCAATGGTCGG ref:0:9:AGATAAGTC 9 10626000 +GGA ref:0:3:CCTTGTTAGCTGT ref:0:3:AAACAGAGTATGT 5 17 +CGCAACAGGTT ref:0:11:TCCCAAACGACCGATG ref:0:11:T 3 608 +CC ref:0:2:CAA ref:0:2:GCA 2 16 +AG ref:0:2:TAAACACACCTA ref:0:2:TGT 2 86 +CGCGGTACCCCTGGGG ref:0:16:AGCT ref:0:16:CAAAGTGCCG 10 155904 +TTAGCTACTTCA ref:0:12:CACACGAGCCTCTGG ref:2:10:CCGGCCTG 8 230202 +ATCTCGGA ref:0:8:CTGCACGTCGATG ref:0:8:TTCGTTGGCC 3 777 +TAATCAGTTATCCT ref:0:14:ATT ref:0:14:CCCCCCTATTA 9 65394 +GATCCT ref:1:5:C ref:0:6:CCGGGCTTAG 3 162 +GAACTG ref:0:5:TGCTCT ref:0:6:ATTGC 2 56 +TA ref:0:2:AGCTAACCGATCTCCC ref:0:1:CACATTC 3 6 +GGCCTTACTATG ref:0:12:CAGCAATTC ref:0:12:AGCAAGGAAC 8 3492 +TTAGCTAT ref:0:8:CTCC ref:0:8:GCGTAATTGGCCAGCG 5 11948 +ACAAGAATGTCGCG ref:0:14:C ref:0:14:AACTGGA 9 540 +GTGGAAGATCGGAC ref:0:14:GGAAGAATC ref:0:14:ATGATGCTGCCCCC 4 70260 +TTTTCT ref:0:5:GATTCAGCGA ref:0:6:CGTCAGCGTGT 7 17391 +GATTTAC ref:0:7:ATCATGCG ref:0:7:GGTGAGTTTAAATT 1 612 +CAAC ref:0:4:CTTTCTATAA ref:0:4:TATTCAACGGAGTA 4 8 +ATT ref:0:3:TAAGAGTGG ref:0:3:TGCCACG 4 294 +CGTGTGGCCGTTTC ref:1:13:GCTTCT ref:0:14:GG 7 380 +CGTTCTTCACGCTCCA ref:0:16:ACCGGGT ref:0:16:TGGGACCTTG 11 679744 +T ref:0:1:TCGTAAGTCAGCATC ref:0:1:GTTACCAAGGCG 6 8 +AATGGTTGGCTAAT ref:0:14:AGA ref:0:14:AACAGGCA 8 1728 +CGTACGTGCATTACA ref:0:14:TCTCAACGAATA ref:1:14:CCAAGAG 5 72 +CCGC ref:0:4:ATC ref:0:4:AG 3 42 +GCGA ref:0:4:TGTTCTCCGG ref:0:4:CCCGAGCTA 3 216 +GTCATTAATAG ref:0:10:ACATTTGGGAATAAC ref:0:11:AGCGCCTTGCTGTGAC 5 37278 +CGACTAAGTAT ref:0:11:CCATTTTACGCAG ref:1:10:CA 5 1770 +GGGATCAGCCCTA ref:0:13:TACGGACG ref:0:13:GAAGGT 6 90 +GA ref:0:2:TATTACTGACCGCG ref:1:1:CAAC 1 2 +GCTTGTGACCATATGG ref:0:16:ACCTTATG ref:0:14:ACT 8 24 +ACATCG ref:0:6:GCAACTATCCAAA ref:0:6:GGCTA 3 216 +GAGTTTAGGA ref:0:10:TTCCGCAACCCTGG ref:0:10:AAACCACACATTC 8 869518 +AAAGACTATCGGAA ref:0:14:CCAGTGAGCCACGTC ref:0:14:CAGAGGCCTCGGCT 9 1993068 +AGTGC ref:0:5:CCAA ref:0:5:GAGTATAATCGGG 2 348 +GTCGCAT ref:0:7:G ref:0:7:CTAA 4 58 +TAACCTG ref:1:6:TGTA ref:0:6:GCTGGCCTT 2 12 +GTGCC ref:0:5:ATTCGGGGCCAATA ref:0:5:C 1 60 +AGAATTTCGT ref:0:10:TCAATG ref:0:10:T 6 96 +CACCGTGT ref:0:8:ATATCCTTTCG ref:0:8:CCGTTA 2 132 +TTCTGGGC ref:0:8:AGCCTGACT ref:0:8:GTTGGAG 3 384 +TG ref:0:2:GGATCC ref:0:2:ACGA 2 18 +ACTTA ref:1:4:GTGC ref:0:5:GGCTTACTA 2 308 +TGATGCAACCGACA ref:0:14:CAGCACG ref:0:14:ACATCACCGCTAGA 5 720 +GTGGAAGCTCATAA ref:0:14:TCGCGACTGGAC ref:0:14:GG 7 696 +GGCCCT ref:0:6:GAACCCGTCGGCTACG ref:0:6:TGAAGTAACGCGCG 6 114 +CCTTAGATCGGAT ref:0:7:TA ref:0:13:ACAGGG 3 12 +AG ref:0:2:GTCCGCA ref:0:2:ACCAGGCGCTTGCTG 4 70 +GGGACG ref:0:6:G ref:0:6:AATTCGGATCGCGGCC 1 168 +AATCATTAC ref:0:9:ATATGAA ref:0:9:GCGAATTGCGGACT 3 1056 +ACTTCGATGGACAGA ref:0:15:CTTTGATACCATG ref:0:15:TGTAGAGAG 4 560 +CCGTCAGTGGC ref:0:11:CCCCATGAGATAATT ref:0:10:GCCACCTTCTTAA 6 39984 +AGAAGCGT ref:0:8:CCGAGCCAAAGCTG ref:0:8:CTGTGATGGTTGAT 3 1962 +GCAT ref:1:3:ACTACGTACTAACC ref:0:4:GACTCGGCTCTCTCCT 8 708 +GCATTT ref:0:6:AACGTAGCCAG ref:0:6:CCAAC 4 672 +TCAGTGATGA ref:0:10:CTTCTACCT ref:0:10:T 5 6 +TGGATTATCAGTACG ref:0:15:GCTGGG ref:0:15:GG 11 1584 +CTC ref:1:0:AGA ref:0:3:CCAACCGTCTGG 2 4 +TA ref:0:2:CTGTCT ref:0:2:TAATAC 2 36 +CGCTGAGAGTGCGCG ref:0:15:T ref:0:15:AGATGATCAGTC 7 90 +TTGT ref:0:4:GGCGTTCGGCGC ref:0:2:TAGATTC 2 33 +GGTAGACA ref:1:7:AATTGAATAGAT ref:0:8:GT 2 8 +GTAAA ref:0:5:CGCA ref:0:5:TGCTGTCATCAT 3 207 +TC ref:0:2:AGTAATT ref:0:2:ATGTCGCGATGG 4 32 +GGGT ref:0:4:ACACCAAACAC ref:0:4:CGACTAGAGTACTA 8 2730 +ACGATATG ref:0:8:CGGCGAC ref:1:7:GACTCAAACGCCCAC 4 1071 +AAGAGGACCCCGAA ref:0:14:AC ref:0:14:ACCGTCTATCTA 8 1536 +AA ref:0:2:TCAATTGTTGCGCA ref:0:2:GTCGAT 4 21 +GAATTTAATTAGCGAG ref:0:16:ACC ref:0:16:CAGAA 12 27162 +CCCAAA ref:2:4:TCA ref:0:6:TCCGGGCCCCTGG 2 1986 +CGGGTTTCATATCAC ref:0:15:GGTATGAACAT ref:0:15:TCCCTGGTT 6 17550 +CC ref:0:2:TAGA ref:0:2:ATA 4 150 +GAGATAAGCAC ref:0:11:CGACTAA ref:0:11:TCGATGAT 6 357 +TA ref:0:2:CAATAGTAAAATCTAT ref:0:2:AACCTATAAGACTG 8 91 +CAGC ref:0:4:GCTACAA ref:0:4:ATAAACTCA 3 85 +TTAAATTCGCG ref:0:11:AAGT ref:1:10:ACTAAAGCCAAGAG 3 644 +ACT ref:0:3:TGCGTCGTCGAGG ref:1:2:CTCCATGTT 4 120 +TCACG ref:0:5:GACCTATACGC ref:0:5:GGTCGTGA 2 190 +TGACACACGC ref:0:9:AAATACGAAGGT ref:2:8:TATTAACTAT 2 195 +ACGTTTTTC ref:1:8:TGCCCCG ref:0:9:AACACCCACG 9 722743 +ACGTCG ref:0:6:CAATATTATTTCT ref:0:5:CCGGCATA 3 14364 +GTGAGCCCCTCATAA ref:0:15:CCCTTAACGAGCCG ref:0:15:GGCATGACACT 7 5000 +CAGCTA ref:0:6:ACAT ref:0:6:ATATCTCTTGGCTTC 2 390 +CCCCGAATTGTTCTC ref:0:15:ATGTCCAGATT ref:0:15:CAACGTCGT 8 31296 +AA ref:0:2:CGCCA ref:0:2:ACTTAGTAAG 2 36 +GGACGGACAGAAGCGT ref:0:16:AGACATGTTTA ref:0:16:CCCCTTGAACCCTATA 8 1317760 +ATGAGGGGCCTA ref:0:12:AGATACTGCACT ref:0:12:AACATCGGGCGG 3 348 +G ref:0:1:C ref:0:1:CATCGTTTT 1 2 +AGATAGCGGTACTTAG ref:1:14:CGATGATGT ref:1:15:CATTGCATCC 7 774 +TGGCTT ref:0:6:GTTT ref:1:5:AGAT 2 170 +GTTCTTCATTCGT ref:1:11:CCTAGA ref:0:13:TCAGTCTTCCAG 4 375 +CCCTATCGGCAGG ref:0:13:AAG ref:0:13:AGCGGATAAACGTCG 6 2624 +TGAG ref:0:4:AGTCCAGACTA ref:0:4:GACTAATTAC 5 540 +TTTTA ref:0:5:CGCGAA ref:0:5:TCCAACTAGT 5 9212 +TACGTCGACA ref:0:10:GATACAATTCGCTTGG ref:0:10:CCTCAAACTGCTTAA 4 1365 +TCAAGG ref:0:6:ACCTGCG ref:0:6:GT 3 116 +CTCACGA ref:0:7:CCTCAAAGCCCCACA ref:0:7:ACTCAAGCACGTATT 4 1248 +TAACTTGATCG ref:0:11:GTAGGTGTGGGTGG ref:0:9:GTGAG 4 4374 +CTCC ref:0:4:GCCAAAAA ref:0:4:TCTAGGAGGGTCCT 1 20 +T ref:0:1:TATATGGT ref:0:1:CTG 1 4 +AGGAGCGGCGAA ref:0:12:GA ref:0:12:GGTACCATAGCGTATC 4 1120 +AAGACCCAAGAA ref:0:12:TATCAA ref:0:12:G 7 756 +CGCTTGGGGTA ref:0:11:ATGAGCTGATGGTT ref:1:9:AGCTGACTC 4 19200 +GCAGACTACGC ref:0:11:AAGAAA ref:0:11:TTAA 7 2211 +CGTGGAAGGGCAAAG ref:0:15:CACAGGGGAAGGCCCA ref:0:15:ATCTGGTATAA 5 59340 +CCAGTCTAGCCTTA ref:0:14:TGTGAAGCTACCTCCT ref:0:14:GG 4 40 +GGAGTACTGCCACA ref:0:14:GTGCTGCC ref:0:14:TTTGTGGT 7 72 +TGGGGAGGTCTAAT ref:0:14:GCAGGCATGTATCG ref:1:13:AC 5 222 +AGCTTTCCTG ref:0:8:TCGTTGGCAGTATT ref:0:10:TAATGTGCTGTTTA 5 136 +GTGGAAATGT ref:0:10:CCGGTGAAGCGA ref:0:10:CTTTACGGCTCAGATA 4 79920 +CGTGG ref:0:5:TTAGCCTATACAGTG ref:0:5:TTCGTA 3 72 +A ref:0:1:TATTTAGCTGCCC ref:0:1:TGGCGGCAGCCGAGAT 4 6 +CCATTGGCCACGAG ref:0:14:GCTGTCTCAGGGCAA ref:0:14:GCGTCCGACTT 8 476280 +CATTGAC ref:0:7:TGACGTGGG ref:0:7:ATAGGGA 2 24 +CCCACCTC ref:0:8:T ref:0:8:TCCATGTCTACG 2 20 +CTG ref:0:3:TGATCGC ref:0:3:AGAAGACCCCTAA 2 84 +AAAGAGCATTTCCC ref:0:14:GTGTGAGTA ref:0:14:C 9 6720 +ATAGCCCGACTCG ref:0:11:TCATATCCTCC ref:0:13:ACGCCATACAGCT 2 44 +GGGG ref:0:4:ATCCCTGTA ref:0:4:GACTGCTCA 7 12100 +TGATCTA ref:0:7:ATACCT ref:0:7:CGCCCGCC 3 2100 +TCGATCCATCCCTTG ref:0:15:TAGC ref:0:15:ACTGGG 10 7296 +ATAGATAACCAACC ref:0:14:GGCATGCA ref:0:14:CC 8 444 +AAG ref:0:3:GGCTAC ref:0:3:CCCAC 4 187 +CCGACTCT ref:0:8:GCCAGGCG ref:0:8:TGATCTAG 2 114 +ACATGGGATTT ref:0:11:TCG ref:0:11:AAATGTAT 5 1452 +GCGAGTGTCACGT ref:0:13:GAAATAGATCTCCCG ref:2:11:TTAATAGACA 6 31850 +GCATTGACG ref:2:7:TCGTG ref:0:9:ACC 4 180 +AAGC ref:0:4:GCCTGGAG ref:1:3:CATGGCCCGGCGGAC 4 160 +TTGCGA ref:0:6:CACCCGTCACGTGCTT ref:0:6:TTTG 2 48 +CTAGATTCTTTGTTAA ref:0:16:GGTACGTG ref:0:16:GTTTAGATCT 9 42525 +TATA ref:0:4:CCGGGTGGCTGGG ref:0:3:GTA 1 16 +ACACGCCGCGGCAT ref:0:14:TCGTGTC ref:0:13:GCACCGTACCG 7 55954 +GT ref:0:2:GGGTTTTG ref:0:2:ATTC 1 60 +TAGAAGAAAC ref:0:10:CCGACCATAT ref:0:10:ATGAAAACGTA 4 9288 +CCTCGTGGTT ref:0:10:ACTCCT ref:0:10:CTATAGGGAAAGT 3 19686 +GCAGTAA ref:0:7:TTGC ref:0:7:CTTAAAGAAAGG 1 12 +CT ref:0:2:AGTTTACTGCCT ref:0:2:AATTATGGGT 6 92 +TTCGTAATACAAA ref:0:13:TAAAGGT ref:0:13:GAAAGCGCCA 8 7680 +AG ref:0:2:AGAGAATCA ref:0:2:TCGCCACGGGGA 2 12 +GGTTATA ref:0:7:TA ref:0:7:AGCCCCGATTCCCC 2 305 +AC ref:0:2:GTGT ref:0:2:GACTACCT 3 75 +CGATC ref:0:5:TTCTGTTATCTGC ref:0:5:AGCACGCACAAAATGG 2 96 +ATTGGTTGAC ref:1:9:CGATAGCCC ref:0:10:GAGAT 6 9999 +TCAGTTTTA ref:2:7:AC ref:0:9:CGGTAGGC 5 144 +TCCGGGGCAGGCA ref:0:13:AACGACCTTCCGCG ref:1:12:CTCAAC 5 1040 +TGCATTTCATAGACGG ref:0:16:CGACTGATT ref:0:16:CGGTGGGATTTGT 9 6300 +TGGCGC ref:0:6:CAGTGGAGCGTCAAG ref:0:6:CTGCAGAGCTATG 4 27 +AAAGCTACAGTGCAG ref:0:15:TGATAACGGCA ref:0:15:C 7 186 +CTTTCACTGTGAC ref:0:13:TG ref:0:13:ATCGG 9 180 +GTAGGGACTCATCTCC ref:0:16:CCCGACC ref:0:16:GATCCTGTC 8 4680 +AATATCGGGGTAACTG ref:0:16:CAAATACGT ref:0:16:GATACATTATGG 7 12320 +ACGAGCGTTAAAGG ref:0:14:AGTGACCCACTTC ref:0:14:AAAACATT 9 46800 +GGTCAGCAGTCCT ref:0:13:T ref:0:13:A 11 6 +A ref:0:1:ACTAG ref:0:1:TGC 2 8 +CATGTCACGG ref:0:10:CC ref:0:10:CACATCACT 4 99 +GGCAATGTGTTA ref:0:12:ATGAGCAGCCTGGC ref:0:12:GAGCG 6 480 +TGAGTC ref:0:5: ref:0:6:ACATG 4 28 +TGGCTGACGAATATAG ref:0:16:GTATATTT ref:0:16:CGTGCT 8 1944 +ACTGC ref:1:4:TCGTA ref:0:5:TCC 2 50 +T ref:0:1:GATGGAGC ref:0:1:GTCTGGACTT 5 4 +GCCT ref:0:4:TTCAC ref:0:4:TCACTCC 3 6 +CGAATCCTACGCG ref:0:13:GCTGCCCCGACT ref:0:13:AC 5 710 +GAGCACTGCATGAC ref:0:14:AACA ref:0:14:CTTAGATGCCC 6 280 +TGACTGCG ref:0:8:GAGCTCCCACAT ref:2:6:TA 3 245 +AGGA ref:0:2:GACATGCAACTACC ref:0:4:CTGG 2 6 +AGTCGC ref:1:5:TCCAAATCA ref:0:6:GCAAGCGACCTC 2 72 +CTT ref:1:2:TAATGTCGCT ref:0:3:AGT 2 54 +TTCTATCCACCGACTA ref:1:15:AAATTAAAGGACAT ref:0:16:TCAAGTCGAAGATAT 5 4524 +GAGGATTGTTGTGGGA ref:0:16:AGGGTCCCTAACA ref:0:16:G 9 3304 +TGGCTCAATGCTAG ref:0:14:CCCCTGGGTT ref:0:14:ACC 9 45762 +GTTGCTCTTT ref:1:9:GACCAT ref:2:8:GTAGACCA 5 24 +TAACGGACATTA ref:0:12:CA ref:0:12:CGCTT 6 10 +TAA ref:0:3:CGACAAGTTG ref:0:3:ACAGTTA 5 110 +ATACTCACT ref:0:9:CATTTAATT ref:0:9:TGAAA 4 729 +C ref:0:1:GGATAG ref:0:1:GACGAC 3 14 +GGGTTAA ref:0:7:TTTCGCC ref:0:7:TTCTT 6 4800 +CATTTAAA ref:0:8:A ref:0:8:TGCGCACTCAGC 4 1040 +GTCACCCGTACCACA ref:0:15:TCCGC ref:0:15:CACAGCCAAT 6 162 +AACGATT ref:0:7:TGCCCTGAGCCATCCA ref:0:7:TC 4 4752 +GTGGCTCG ref:2:6:AGATTTAGAG ref:1:7:GCGCTGATTT 2 278 +ATGC ref:0:4:CGACC ref:0:4:GCTCTTCCACGA 3 1810 +CTTTTCTTACTTG ref:0:13:CCTGA ref:0:13:AT 8 22 +GGAC ref:0:4:TCGTTAAACGCGGGT ref:0:4:TGATGTCTTGGAGTA 7 1677 +TA ref:0:2:GTGCATAAGGCTTAT ref:1:1:CC 2 27 +GTCAACCGAGGACG ref:0:14:TCTCGATTCCAGTTA ref:0:14:TCAACCCCTTCTTC 6 412992 +CGGATACCT ref:1:8:ATG ref:0:9:GAACCAGG 3 56 +GTACGCC ref:0:7:CACAAGGTAATC ref:0:7:AGTTTG 4 890 +CGAGCT ref:0:6:GCGA ref:0:6:AATTGAGAGCGGG 2 88 +TCA ref:0:3:ATG ref:0:3:CCGTGGCGGCCCGGT 2 96 +GAAGCATCAACGT ref:0:13:GGT ref:0:13:GCTGGGTTTACCG 7 27936 +TCGTGTCTCC ref:0:10:AAGAGGG ref:0:10:GCTAGAGCGGAT 9 12600 +AAAGCGTTTGG ref:0:11:AGGAGACATATAAC ref:0:11:CC 6 7920 +TGACGC ref:0:6:AGAAAA ref:0:6:TATGTCCTTAACGG 3 900 +CCAAACTTGGC ref:0:11:ACATTTCA ref:0:11:GATCTAA 7 74160 +TACCAG ref:0:6:CCTAGAACC ref:0:6:GGAGAAA 4 568 +ACAGCGCCATTG ref:0:12:GTGACCAGG ref:0:12:GGC 6 16 +CATGCT ref:0:6:ACCA ref:0:6:AATAGGGTTGGGC 2 1365 +AGCTGTT ref:1:6:GA ref:0:7:AAACG 4 54 +GGGTAATGCCCTATG ref:0:15:C ref:0:15:GCACAGAACTCC 8 111 +TCGACTGATGTGAA ref:0:14:ACAAAGTGGTGCTG ref:0:14:TTTA 5 840 +CTTA ref:0:3:ATGACGTG ref:0:4:TCTCTATTA 1 60 +GCACCG ref:0:6:G ref:0:5:ATCTGGGTCCAAT 2 218 +AGAT ref:0:4:TATGCTGCA ref:0:4:AACGGTGTCAA 4 168 +CATTGACATGG ref:1:10:GCCCCATT ref:1:10:TGCAGCCTC 6 1440 +TATTCATGGGC ref:0:11:AAACTTACTCG ref:1:10:GGACCTTATGAAT 5 2856 +TCTGGGT ref:0:7:CATGCTCGTACCTTC ref:0:6:GGGACGACGGA 3 485 +ATC ref:0:3:TCAC ref:0:3:TG 1 6 +ATTAGTTGTGGC ref:0:12:GTTGGTTTGAGAAT ref:0:12:AT 3 192 +CATATGCTCA ref:0:10:GTCCGAAGAAGAGAAA ref:0:10:GGCTAAAACGAGATCC 9 7068384 +GATGCATTCTACGA ref:0:14:AGTCAGCGT ref:0:14:TAAATTGACT 6 1932 +GTGCGGGGTATCGTC ref:0:15:ACAACAGCGTACACAC ref:0:15:AGTGCGATTACAAA 7 78500 +TGATAGGGAA ref:0:10:GAGCCCC ref:0:10:AAGGCTC 7 9600 +CAATT ref:0:5:CCTTTCTGAG ref:0:5:AC 2 368 +ATCCTCCACAC ref:0:11:G ref:0:11:GTACCAA 7 396 +ACCGCAAAGAAGCG ref:0:14:GCTTATTTTA ref:0:14:C 10 1596 +CAGCCCGTCTTCTTC ref:2:13: ref:0:15:AGAG 11 4 +GGACCT ref:0:6:CTGTCATCACTG ref:0:6:C 1 12 +CCTCC ref:0:5:GAGGTGAGAGC ref:0:5:CCGCTC 2 840 +GTTT ref:0:4:AAGCTTGTTAGTGTG ref:0:4:TA 1 144 +GATACTATATCACTCG ref:0:16:TTCTGAGAT ref:0:16:C 10 444 +CAGCTCCTGA ref:0:9:ATGCCTTTGC ref:0:10:AAACGGCCCG 2 375 +ACACGTGCTACCAGG ref:1:14:AGATC ref:0:15:CT 9 105 +CTAATGTTCTCTC ref:0:11:GGTCGT ref:0:13:TC 7 225 +CGGGACGTGTCGTTGG ref:0:16:GCCAAG ref:1:15:AGTCG 8 702 +GCGTATAAC ref:0:9:TAACTGGTTTTGAAAG ref:0:9:ATGAA 3 702 +GGTGCATAGAG ref:0:11:TAGAATCTT ref:0:11:CCCCTA 6 43680 +G ref:0:1:TAACCAATTTCC ref:0:1:ATCCCCGCAC 5 13 +AAGTTG ref:0:6:CCT ref:0:6:GTTGCGCGGTTGG 4 6000 +AGGCCGTGTCAA ref:0:12:CGGCGCGCTGTCT ref:0:12:GTACCTC 3 60 +TTCTATAATC ref:0:10:G ref:0:10:CACGCC 8 836 +CGCCGATACCTAA ref:0:13:ATAG ref:0:13:GGGAACAACAAT 4 90 +GTAGCCTAGCC ref:0:11:ATA ref:0:11:CAGTACACGCTCTAA 3 13 +CTGGTATTCACTGG ref:0:14:TA ref:0:14:ACGAT 9 54 +TT ref:0:2:TCTTCCACTTGCGC ref:0:2:TACGCTGACTCCC 6 30 +TCGAAGTGCAATACTT ref:0:16:TTCCGTG ref:0:16:CAAGGAAAACTATG 3 108 +A ref:0:1:CGACTTC ref:0:1:CCCTTG 4 7 +ATTTTCGAC ref:2:7:ATAAAAGCTTAA ref:0:9:GAAATGCTCCC 4 1705 +GTGCCT ref:0:6:AATACA ref:0:6:AA 6 1008 +CGGC ref:0:4:GTGACGATCCTCGAT ref:0:4:ATATCCCGGAAG 4 630 +AATTAGTGACGTC ref:0:13:G ref:0:13:GAACTTGGCA 6 33 +ATACCTTTG ref:0:9:CACTAGCC ref:0:9:CCGCACTTAC 6 802 +CAAAGCCTAAATG ref:0:13:GGCTCCA ref:0:13:G 9 470 +GTTCACCTAAAAGCGG ref:0:16:CGGCACACCA ref:0:16:TGACACTA 10 66240 +TACG ref:0:4:GAACGGTC ref:0:3:CT 1 20 +GCCTCTCATC ref:0:10:TAAGCCGCT ref:0:10:C 5 60 +G ref:0:1:CGCTTGGTC ref:0:1:CCCGAAATTTCGCG 5 9 +G ref:0:1:CCA ref:0:1:GTCTATTTGGGA 2 16 +GTCACCTACCCCGCGT ref:0:15:AACGACAGC ref:0:16:CCTTCCAGATGGCA 7 2120128 +TTA ref:0:3:GCTGGGT ref:0:3:TAGATCAGCCGTGA 3 4 +TGTCCTACTGGCCGTA ref:0:16:ACT ref:0:16:GGATCCTAC 9 64 +TAGCGCTTC ref:0:9:GAATGCACTTTTTG ref:4:5:AGACATG 3 2520 +TTAGGGGTTACTGGG ref:0:15:GCCCCAATCTG ref:0:15:GAAAAGA 11 22858524 +CTCGTGTGTCTA ref:0:12:T ref:0:11:TTGCCG 7 175 +CGAC ref:0:4:T ref:0:4:ACTCGCTCAATAA 2 160 +CAGAGCAT ref:0:8:GTATTCACGTG ref:0:7: 3 3 +AAA ref:0:3:TCGTGTGAGTATAG ref:0:3:TATTTTCTGGAT 3 13 +CTGGATCT ref:0:8:GG ref:0:8:C 5 2 +AGTCGGGCTAGG ref:1:9:CCGTGCAGTCTT ref:0:12:TGTCCCAG 2 1680 +GCGGGTCACATAC ref:0:13:CAAAGCGCCA ref:0:13:GTTTAGTCGCTCACTG 5 5660 +GACATGCATTACACAA ref:0:16:CCT ref:0:16:AGA 10 20 +CG ref:0:1:CTTACCTACT ref:0:2:AGGTTTGT 3 48 +GCGGTACATGAGTT ref:0:14:GTGCGCC ref:0:14:CCGCCCTGA 8 51352 +CAGTCTCCG ref:0:8:TCCT ref:0:9:GAAGAAA 4 3664 +T ref:0:1:ACTACAACTGCC ref:0:1:GTTTCAAGACTAA 5 8 +CATCTGCA ref:1:7:CTGC ref:0:7:GTC 2 12 +AATAGCTGG ref:3:6:GTGTA ref:0:9:GTACGCATTAGT 2 116 +TCACTCCATCA ref:0:11:TTGTAGCTTCACCAGT ref:0:11:TG 4 3864 +AATCGCCGCAAGGG ref:0:14:G ref:0:14:CTGCCGGATCGATGCC 6 5560 +CGGCGTGGCCGCTT ref:0:14:GGTGGG ref:0:14:TATC 7 369 +GGCATATAGCCTC ref:0:13:AATGCACTCTA ref:0:13:ATACTCGACTG 5 18 +GGGAAAAACTAGATC ref:0:15:CTTCTGGCACGCGCAG ref:0:15:TGCGCGGTATAG 10 879120 +GAC ref:0:3:CGTTTCACCCC ref:0:3:T 1 16 +CTTTAGTATGC ref:1:8:TCCTCGGAGA ref:1:9:TCTGTA 3 32 +AACC ref:0:4:AAA ref:0:4:ATAACGTATGTCT 1 15 +AACCGGTATACA ref:2:10:CGTAGCACAT ref:0:10:CGGCTGGG 3 852 +CCCAATCAAC ref:0:10:CACGGACCCG ref:0:10:T 4 241 +ATTTTTGGG ref:0:9:GTTAA ref:0:9:CAG 5 1308 +TTAAGTGG ref:0:8:GTCCGT ref:0:8:TGGGGCGTGTT 5 21357 +CGTCT ref:0:5:TGCTCAGTT ref:0:5:GCAGTACCTTTTA 2 64 +AGTGCGATCGGCCCGA ref:3:13:GAAAATCTG ref:0:16:CCACTCTTTTAGGAT 6 192960 +TGCAC ref:0:5:TTTCA ref:0:4:TTTGATAT 2 72 +TAAAGTC ref:0:4:CGAGGTTTGAA ref:1:6:ATAGATTCTGT 1 216 +GCAGGCGCAACTT ref:0:13:CCCTCGA ref:0:13:TATGTGCCATA 6 4326 +AGC ref:0:3:GCCGG ref:0:3:CGTGCGTT 2 12 +CGTGATTAGGTCT ref:0:13:AGGTATATGCACGT ref:0:13:AGGCTTC 6 10656 +CGGGTGCCAGGCA ref:0:13:C ref:0:13:ACACAGTCTAATAGC 6 3612 +GTATTGAGTCAGGAC ref:0:14:GCATCAAG ref:0:15:GC 8 784 +ACCTCC ref:0:6:TACGA ref:0:6:CAGCACGTATCAATGA 4 544 +TCCTTACCCGAC ref:0:12:ATGGACCAGGCC ref:0:12:GTAT 6 141728 +GGAGACATCCGCCGAT ref:0:16:ATAGAGGGGACG ref:0:16:C 10 39740 +TTGAGATC ref:0:8:T ref:0:8:GCGTCACGGGCC 4 2178 +TCTCTATCAGTGTGG ref:0:15:GACACGCAAGG ref:0:10:AGTAA 7 62816 +GTGCGAAGGTTT ref:0:12:TCCCGCCA ref:0:12:ATGTAGGAACAG 5 248 +TCCCCCGTGCGTCT ref:0:14:CGGGAAC ref:0:14:TTCAGGCTAAC 8 750 +GGCCGTAGTC ref:0:10:CTGA ref:0:10:AGCCAATGGCTCCC 3 1782 +CCGACTCGGGTCA ref:0:13:GAAACAACCCAC ref:0:13:AATTCG 6 5670 +GGAACCATCGGGCGAT ref:0:16:TAAGACA ref:0:16:TCTTGCAATC 9 44460 +TGTTAGATTGC ref:0:11:CG ref:0:11:GGCTAT 7 836 +ATCCGCTGC ref:0:9:GGTAT ref:0:9:GTTTTGT 7 16646 +CGGGTAGG ref:0:8:CCGACAAGT ref:0:8:ATTCAGCCGT 5 14229 +CACAGTTCTA ref:0:10:C ref:0:10:ACCAAC 6 69 +AACCAAACGA ref:2:8:TAAGGGATCGCG ref:0:10:T 4 165 +GCCAGG ref:0:6:A ref:0:6:GTGCA 3 6 +AGGGACCGCGTTAAT ref:0:14:TCGCCAAAA ref:0:15:CACCAGTG 9 1122523 +TCAATACTCGAGAG ref:0:14:AAACCCCG ref:0:14:ACCGAAAATC 6 9045 +GTCCCATGCGCAGT ref:0:14:ACGGAAACACTCA ref:0:12:TGGGAGGCGGGC 6 220662 +CCTGACAT ref:0:8:ATATCTTC ref:0:8:GACTATACGGAGG 4 603 +TTTATGACAGGCGCC ref:0:15:GATAGCTTACC ref:0:15:TCCTCTCTTCTTAC 7 4824 +CGGAGAAAGAATAAA ref:0:15:AGCGTCATGATTA ref:0:15:TCTCTCGA 11 33946616 +TCA ref:0:3:CAGTCGGTCTT ref:0:3:CTGGAGCCGGT 6 182 +CCGACATCCG ref:0:10:ACCCTAGGG ref:0:10:GGAAGCAAAC 3 5032 +TGGTGTCGAATC ref:0:12:AACTTATAAG ref:0:12:ACTTATCCCGTTG 8 324 +CCTAGACGGCGGGAGT ref:0:16:TAGTACGCCTGTGATG ref:0:16:GCCGGG 5 216 +CG ref:0:2:CTTCAGACGGC ref:0:2:TTACGTCTAAAT 4 8 +ACCTCAAGG ref:0:9:TAGGCGCTTAGCGG ref:0:9:GTTTGTCACGTAATA 4 2610 +TAGCTTT ref:0:7:TTATACC ref:0:7:GGGAGTTGATAATAG 4 1760 +CCC ref:0:3:ACTAGGAACTACT ref:0:3:CTGGTA 5 28 +GGACCCCTCCGCATAG ref:0:16:TCG ref:0:16:GCTCCGTTA 8 160 +TTGGCGGT ref:0:8:TGATAAGCTGA ref:0:8:TCGTAGGATATGTT 4 2736 +CTCTTGGAT ref:0:9:T ref:0:9:ACCTAACTGCCTG 3 216 +AGCGCGTCGAGG ref:0:12:CACTTACATGATCGTA ref:0:12:GAATCCTCGGC 3 96 +ATGCCAAAC ref:0:9:TACCA ref:0:9:GCCGCGCGCTGC 3 12762 +GCCACGG ref:0:7:AG ref:0:7:TTGTGGACCCCGTT 1 126 +CC ref:1:1:AACAAGGA ref:0:2:ACT 1 4 +GCATACGTGA ref:0:10:CAGACC ref:0:10:TGGAGGT 4 832 +CCTTCGCCCTTGCGAC ref:0:16:GCCCGCCACT ref:0:16:ATCTAT 7 1540 +CGGCCT ref:0:6:TCTTATAGGCATT ref:0:6:GTGAGTAT 3 343 +TA ref:0:2:TACACCGCTCA ref:0:2:CTAGGAATTGT 3 12 +CAGAGGGAT ref:0:9:GC ref:1:8:TATG 6 840 +GTATCTGAG ref:0:9:TAACACAACTCCCC ref:0:9:GCCGCT 6 138670 +ATGCG ref:0:5:GCCAAAAAACGAG ref:0:5:GTATGCGCT 1 172 +GGAAGA ref:0:6:CGGTTA ref:0:6:CGAAG 2 51 +TAAAGATAG ref:0:9:CAGGATATA ref:0:9:A 4 880 +TA ref:0:2:TGT ref:0:2:AACGAG 1 32 +CAAGAGATCCAAGGTA ref:0:15:TACTACACCACG ref:0:16:TCTTCAGGGAGCGGGC 7 2611512 +GTAGTCGTCTGGGA ref:0:13:TATTTAGCCAG ref:1:13:CAATCAAGAGCTAC 2 238 +AGTGAAGTCCCG ref:0:11:TGCGATCACTTT ref:0:12:TCTACAACAGGTA 7 331177 +GGTCCAACTACTGTC ref:0:15:TGTGTTCTGGCG ref:0:15:TAGGATGGGAGCTA 6 204 +ACATAA ref:0:6:TGCC ref:0:6:GAGCATGA 2 87 +GAGGCCCTTTAT ref:0:11:ATGAAA ref:0:12:AGTATGCG 7 954 +TTTCCACCATCATCA ref:0:15:CTCAACTGG ref:0:15:AATGCAGTAGTT 7 78 +G ref:0:1:CTAAAATGGC ref:0:1:ATTTTCTGAA 2 2 +CCGGG ref:0:5:CGCCCAAGTATTC ref:2:3: 2 337 +A ref:0:1:C ref:0:1:TG 1 6 +TGCGCAAA ref:0:8:GCACTCAACTACACTA ref:0:8:GGCGGATGTGTGGT 3 59388 +TGTCAG ref:0:6:CTCTCACCCTCGGA ref:0:6:TCCA 2 24 +C ref:0:1:TAAAGCC ref:0:1:ACATCG 2 4 +GTAAGTATAC ref:0:10:TGGGTTTGTAACC ref:2:8:GTTT 2 360 +TTGGCCAGTCTGGCAG ref:0:16:ATACAATTTGGCATC ref:0:16:CCGGAT 7 11160 +GTTCAGACCTCCGG ref:1:13:TCACAGACCATCA ref:0:14:CTCTAATTTGCGC 3 53312 +ACTCCA ref:0:6:T ref:0:6:GCTTT 4 30 +ATATG ref:0:5:TATTGTGCCAACAC ref:0:5:C 2 72 +AGCCGGAAGA ref:0:10:CGGATAATCGAG ref:0:10:TAGT 4 312 +TAATA ref:0:5:CCAC ref:0:5:AGCC 5 1395 +AGGAAGGCACC ref:0:11:TGTGCGTAA ref:0:11:GCACCT 5 2156 +TATACGTTGTATAAAG ref:0:15:CTATCCTGGTCGCAA ref:0:15:AACCGAT 5 12656 +TCC ref:0:3:GTTGGACTGCC ref:1:2:GGGCGCGAAT 3 7 +AACCAAAATAAG ref:0:11:AGGAT ref:0:12:T 8 142 +ATAAGCCAG ref:0:9:GTTATG ref:1:8:TTAT 7 4830 +ATTTTA ref:0:6:GTCTTGGCGCTGG ref:0:6:AGCCATCTTAG 3 84 +ATATGCAGCA ref:0:10:ATGGGTGTTCT ref:0:8:TCTGAGGGCTAAGG 4 39680 +TGTATGCGA ref:0:7:GCGCAGGACAAAAT ref:0:9:CGGAGCGCTAGGCAA 7 12120 +G ref:0:1:GCAGGTGTT ref:0:1:CTGATGCGTGGCCCA 5 20 +TCTCCGAGGTGTTAT ref:0:15:CCTATG ref:0:13:ATAT 8 342 +C ref:0:1:TCACATATGTCTGTTA ref:0:1:TTATTATAAACGAG 7 3 +CA ref:0:1:TCCGTG ref:1:1:TGTGGTATTGG 3 2 +GTGT ref:0:4:GGCGTGAATGCTTA ref:0:4:GGCGACTGAACTTACT 8 207 +TTTGCTAATA ref:0:10:AACGTG ref:0:10:GATCCC 6 16 +GGGT ref:0:4:ATCGCAATCAGCGACA ref:0:4:GTA 1 12 +GCAAATTGACCATGA ref:0:15:CAAC ref:0:15:GGAGGCTTGAATG 4 660 +CGCTCGGC ref:2:6:TATCGCG ref:0:8:AGTTTGTGTGATTGT 3 13344 +AATTA ref:0:2:TGCGGAACGGCC ref:0:5:G 1 6 +TGCTTGTGGGCATGC ref:0:15:AAGAGGTGCG ref:0:14:GGAAGTAGT 10 297675 +GTGCGTGCAC ref:0:10:TTTTCT ref:0:10:GT 6 732 +GATGCCACTGGTCA ref:0:14:GCCGGAG ref:0:14:GC 8 60 +CTTGTAAGGAATC ref:0:12:GCGCA ref:0:13:GCGATCAGTTG 8 5376 +GTCTGTCA ref:0:8:TTAAGGCAAC ref:0:8:TAG 4 42 +AATGAATAGCT ref:0:11:GCGA ref:0:10:TGCATCACGTGAAT 5 65 +GGCCTGGCAGACTGGC ref:0:16:A ref:0:16:TTCTTCC 11 1612 +CTAGAATGAT ref:1:9: ref:0:10:AAGGGTTGTAG 4 387 +GGCCGGG ref:4:3:TTGGGT ref:0:7:GATAG 1 183 +TTGGGACGTGACCCCT ref:0:16:C ref:0:16:CGCTGGGCTCCCG 7 225 +GGAGCGAAACCCTAC ref:0:15:TCTGTT ref:0:15:CGTTGTAGTAAC 8 3900 +CCGACC ref:1:5:ATTCTGTAGGTG ref:0:6:GGATGGTT 5 1260 +TCAAACAC ref:0:8:CTGATAACACGATCCT ref:0:8:GTTCCATCA 2 1530 +GAGCTTCGGGATC ref:0:13:CCA ref:0:13:CAACTATGAT 5 21 +AAGTCCACTACAAA ref:0:14:AGC ref:0:14:TCCC 8 32 +TT ref:0:2:GTGGC ref:0:2:GGGTGTGA 3 6 +CTAGTGGGG ref:0:9:TTCTAACCTCCACC ref:1:8:TTAGAGATCTT 6 704718 +GGGGTATATTGGA ref:0:13:CAGAG ref:0:13:ACTGGGCTCC 9 314922 +AGCCTGCGAC ref:0:10:CGCA ref:1:9:CC 5 12 +TATCATCCTGAGGC ref:0:13:GGCCCGGATATTGA ref:0:14:GGGTTCAGGCGACACA 6 616 +CCGAACC ref:0:7:GCCGGAAGGTTGCCCG ref:0:7:ACAGAGACCCCAA 1 144 +GTCAGTTT ref:0:8:CTGCTAC ref:0:8:ACCG 5 1534 +CACTAAC ref:0:6:TCT ref:0:6:GGCCCCTCAG 2 160 +A ref:0:1:CCTGCGGTC ref:0:0:GCTGTTTCT 5 10 +TTAGACGTGTT ref:0:11:ACATGATA ref:0:11:GGATTTAT 5 960 +GGCACCG ref:0:4:TAAAA ref:0:7:TGGTGCGCTGCGG 1 828 +TTCAAAT ref:0:7:TGGCTCGTCAATC ref:0:7:CAATCCCGCGCTG 2 210 +AT ref:0:2:CATACGTTGATC ref:0:2:TCAGCAG 3 64 +G ref:0:1:GTCATTTTAGTACGGT ref:0:1:TATTGACGGATC 9 12 +CAAATAGCT ref:0:7:TATGCTGAGGT ref:0:9:GGGTCAT 6 10396 +CATAACCGG ref:0:9:TTGATGACCC ref:0:9:TTCTCAC 5 588 +TAAACTAGTAGAC ref:0:13:CAACAGAGGTCGCA ref:0:12:CTCAGCT 5 852 +CTAG ref:0:4:AACCAGGAGCTC ref:0:4:ACT 1 18 +ATTGTCGTGCCT ref:0:12:CTTCCGCGC ref:1:11:TCTCCTGCTC 5 7800 +CT ref:0:2:TTTC ref:0:2:ACTCGCGTTC 3 49 +CATTTCA ref:0:7:T ref:0:7:TCCACGGCCGCAAAT 2 2520 +GAGGCCAGCC ref:0:10:ATCATCCG ref:0:10:ACGACGAACCA 4 1526 +GCGGAC ref:0:6:GTAGTGGCT ref:0:6:TGGGAGCTCAGAGGGC 4 2208 +TT ref:0:2:ACAAAACTAGGTGTC ref:0:2:TACGTGTCTTT 5 45 +GGCTCCATGCGACAG ref:0:15:C ref:0:15:CCGTGAATAAC 9 9545 +TCA ref:1:2:GC ref:1:2:GCACTCC 1 1 +T ref:0:1:CCTGTAGCCCCTGA ref:0:1:G 1 6 +TGTGTGG ref:0:7:ATAGGC ref:0:7:G 4 176 +CTTCACCTC ref:1:8:CAAGCGCTACCCAA ref:0:9:AGCAGGACTCC 5 1638 +CGAGG ref:0:5:TCGAGGTAGGAC ref:0:5:GAAGGATGCAATTGT 3 198 +AAG ref:1:2:GTTTGGAGGGT ref:0:3:GAAACCGGACTAAACC 2 18 +TTCAGAGGCGGT ref:0:12:TATC ref:0:12:AGGAGTT 6 2200 +AGGAATACGAAGCTG ref:0:15:T ref:0:15:TACTGCGTC 9 48 +AGTGACCTTG ref:0:10:TATCCGAATAC ref:0:10:GTAGGTACGG 5 4050 +CG ref:2:0:AA ref:0:2:AATCA 1 2 +TCTCCTT ref:0:7:TA ref:0:7:ACTTGA 5 285 +TCT ref:0:3:AAGCGGCGTCACTC ref:0:3:G 1 8 +GTGCAT ref:0:6:ACAAG ref:0:5:C 3 20 +GG ref:0:2:TT ref:0:2:TGTC 3 30 +GTT ref:0:3:TTT ref:0:0:TTCTTAC 1 4 +ATGAGCCTC ref:0:7:AGAACAATCCACAC ref:0:9:GAGGCCAAGCGCGGAT 4 864 +CGCCCCGGCGTT ref:0:12:GCTGCGTATTAC ref:0:12:TTGACACTCGA 6 54216 +CCTATAGGAA ref:0:10:GCAACAT ref:0:10:C 6 74 +TCACCAAATGCAAG ref:0:14:AGCGCTCGCGGTGG ref:0:14:GCCAGTAGTTAATCTT 6 87000 +CTTACCCCT ref:0:9:AGAACCCGA ref:0:9:TGGGGAA 6 21672 +AACGACATCTG ref:0:11:ACG ref:0:11:TTT 6 132 +CACCAGC ref:0:7:ATTATCT ref:2:5:TA 4 36 +AA ref:0:2:TTCAGGATTTAA ref:0:2:TACGC 2 36 +GAGTC ref:0:5:CAACAATTTATT ref:0:5:ACCGGTA 4 6894 +CGTACATTTCT ref:0:11:TTCTGTGAAAATG ref:0:11:AGTGCGGGAAC 6 5852 +TTC ref:1:2:AAGTGCGAGCAGGAG ref:0:3:CGT 1 10 +CATT ref:0:4:GTTTCACTCGGC ref:0:4:TGAGTGAGGA 4 175 +AGCTTGA ref:1:6:CATAAAGTGTAATCA ref:0:7:TT 1 3 +CCCTGCAGT ref:0:9:GAGACGCGGGGCTGG ref:0:8:TG 2 2 +TCGTCAATT ref:3:6:AAGA ref:0:9:AACGA 4 60 +TATAGA ref:0:6:C ref:0:6:ACTGAT 3 7 +AGCAGCG ref:0:7:TATCCCTGGTATTCTC ref:0:6:TATAAAACGACACC 5 7335 +CC ref:0:2:CTCGTAGGTCCTTAAC ref:0:2:AAGGCTTCA 5 10 +TTGCT ref:0:5:CG ref:0:5:GCGTGACCACA 3 280 +GACCA ref:0:5:CGCGTATCCAC ref:0:5:TGGAAAATTACACGCT 3 280 +G ref:0:1:GGTACAGCTACACTGT ref:0:1:AGTGCGATTGGC 6 20 +ATAGG ref:0:5:GCAGCTGA ref:0:5:AG 2 44 +TTGGACCGAT ref:0:10:GCAGACAAGTGGTGC ref:0:10:TTTTAAAACAGGAATC 5 167798 +CGTTCCAAAT ref:0:10:CACCC ref:2:8:ACTGGT 6 10885 +GTCTGATC ref:0:8:ACGAA ref:1:6:CTTGGTGAG 2 516 +ACTC ref:1:2:TGT ref:0:4:C 1 8 +CCATGGTGCTATTTC ref:0:15:GACTTGC ref:0:15:CTTCTGA 8 278 +TTATGAGCAGGGCGTA ref:0:16:CACTGTCTTC ref:0:16:GTTGATCCGAA 8 52029 +TTCGGCT ref:0:6:ATCGATAACAA ref:0:7:GAA 4 288 +T ref:0:1:AACATGACACGAG ref:0:1:CC 2 3 +ATCAGCAAGGCCC ref:0:13:GGGTCGTTTT ref:0:13:TA 7 108 +TTGTAGGA ref:0:7:CA ref:0:8:CATGATATCTTCGCAG 3 180 +CTCCAGCGC ref:0:9:TGCTTTCCAACCGGA ref:0:9:GTAAGCT 3 6204 +CC ref:0:2:CT ref:0:2:GAGTTGGTACGAAGGA 1 51 +ACGCG ref:2:2:TTG ref:0:5:TTCTTC 2 9 +CCGGTA ref:0:5:AGCCG ref:0:6:TCACAGGATCT 1 10 +AGCCA ref:0:5:A ref:0:5:TC 3 14 +CTT ref:0:3:G ref:0:3:AATTAATCAT 1 108 +TCTC ref:0:4:T ref:0:4:AAATTTTA 2 50 +TCTGTGTCCGCAC ref:0:13:CACTTGCTTGA ref:0:13:CACGGCGCATCCAAG 5 984 +T ref:1:0:AGAACG ref:0:1:CAAGTTATCAAGA 4 3 +AAGCAGTTGGT ref:0:11:AATATTGCGTTTCAT ref:0:11:GG 3 486 +CC ref:0:2:CGAGGCCCGCAGCTCT ref:0:2:ATAAG 3 441 +AA ref:0:2:GATCCACGG ref:0:2:AATATGAGCGTA 3 10 +GTTTTTTCG ref:1:7: ref:0:9:TC 5 6 +TTCA ref:0:4:CTAGA ref:0:4:AAACAGGA 4 340 +CCCATGG ref:2:5:GCATGCGGTAG ref:0:7:CAGTGGAGAGGCTA 3 180 +AAA ref:0:3:TACGACGCTTCCTATC ref:0:3:TGGGGCTATGCACCAG 4 1 +CACCGCCGA ref:1:8:TAGGAACTGTCAAAC ref:0:9:TC 4 8589 +TCTATAACGGATGGG ref:0:15:CCTCCCCGGGTTTCA ref:0:15:CAGGCTGAGGATAT 8 5565630 +AGTCGATCT ref:0:9:ACTGAAGTAACCGCAT ref:1:8:TCCATGAATC 3 168 +ACGGCACCT ref:0:9:AAGTT ref:0:8:CGCGGGGGACAG 3 28242 +AG ref:0:2:CGGTTGATGTGCAGCT ref:0:2:TAGCTCTTTACCAT 6 4 +TATGATAGCGA ref:0:10:TTACGAGCCGCTG ref:0:10:ACTCTA 2 369 +TTTCTTGT ref:0:8:GGGGCCCT ref:0:8:CCATCGCAA 6 180576 +ACG ref:0:3:CTGCACTGAAGGCGA ref:2:1:AATA 3 35 +ACTGGGCAACCATTA ref:2:13:GTACCAACGC ref:0:15:CCTG 7 2418 +TGGTCGA ref:0:7:AGCCGTCTTTTT ref:0:7:GCGGTGGTCTTCAATA 4 1554 +CACTTAGCGAATCTT ref:0:15:CCA ref:0:15:GATTTGCTGGCCCTC 5 14560 +TAACCTTTG ref:0:9:C ref:0:9:GAC 7 20 +CAACAGGATCGCG ref:0:12:TTGTGGCTA ref:0:12:ACATTGGACAAG 5 336 +CGAC ref:0:4:TAATT ref:0:4:ATAAA 5 1740 +TAGCTCAGCTCGA ref:0:13:ATAGAGCGAGTTAT ref:0:13:TCCCTTGCCCTAT 4 87800 +ACCAG ref:0:5:TTGTAACGTTAGCA ref:0:5:TAA 2 13 +TGGGACCG ref:0:8:CACATGCGG ref:0:7:TTCAATAATCACC 5 37920 +ATTCACAGT ref:0:9:CGG ref:0:9:TATTTGACCAGCCGG 3 2020 +TGGGGAT ref:0:7:GTTG ref:0:7:CGGTATTGAC 5 4032 +AACAGAA ref:0:7:GTTCAGGCC ref:0:7:CAAGCTTCC 6 33760 +GCAATAGGGTACAGC ref:0:15:CTGAGACCT ref:0:15:GGTAC 7 126 +GAG ref:0:3:GTATGAGCGATGCCG ref:0:3:CACACACTAC 5 1974 +TATTCACAGCCCG ref:0:10:GAACGTCTG ref:0:13:CCAGTCTGCAC 6 2 +ACGGT ref:0:5:TGCGAGGCC ref:0:5:TAGTATT 2 363 +AGAGTTGCACATCT ref:0:14:CGCATCTT ref:0:14:CTTGGGT 7 30179 +CCGCGCTGGTGAA ref:0:13:CCGATTGA ref:0:13:CCAGT 6 1160 +CA ref:0:2:TCCTGGGCCGAG ref:0:2:TG 2 24 +ATGTCCCACT ref:0:10:GTGGGC ref:0:10:TTCCTAG 4 3024 +A ref:0:1:GGATCTGATGG ref:0:0:CCCTGCCCTTGCTC 4 2 +CG ref:0:2:A ref:0:2:AGGATGTCTTGGGT 1 9 +TA ref:0:2:GG ref:0:2:GCGACTAA 2 12 +ATTCTAATTAA ref:0:11:CGAAGGGGTGCATGTC ref:0:11:GGCAGATG 7 6300 +GACG ref:0:4:ATATGTCCGGTT ref:0:3:CATAGGTAGCT 4 52 +AAGTG ref:0:5:CCAAATT ref:0:5:CGACCCACTTGTTTC 3 210 +ATCTAAGCATTTGAG ref:0:15:TACCATCG ref:0:15:TTATA 7 2592 +TGCTAGTCGCAC ref:0:12:AGATAA ref:0:12:ACCTAG 7 440 +TCTTTAGTGT ref:0:10:CAT ref:0:10:GTCTGGTT 3 36 +GACCGCCGGCC ref:0:11:CACCAAA ref:0:11:GTGCTGCTCTAATG 7 130784 +CACGAATTCTG ref:0:10:CT ref:0:11:GTCTCTACGTAAAAT 3 518 +ATT ref:0:3:GGTCATGCGTAT ref:0:3:GTG 2 21 +GCTGGACG ref:0:8:TTCGAATCGTATA ref:0:8:TCGCCCGCGCCC 3 3555 +CAGTCATTCTCCGGC ref:0:15:GT ref:0:15:GCAATTGTCCT 7 144 +GGCTCTGT ref:0:8:TAGCGCACTGC ref:0:8:TATAAGATAACCGATA 3 224 +AAGCCGCAC ref:0:9:CGGAATATTTGTTCCT ref:0:9:CAAGTAGAAGATCG 5 15309 +AGGAGGAGGGA ref:0:11:AGGATCTC ref:1:10:TGTTCAAGGT 5 35868 +GAGAGTTAGTAG ref:0:12:CTTAA ref:0:12:TTAGAT 7 18 +GACTA ref:0:5:TGCGTGAGTGTGTG ref:0:5:TTCCGCTACGATTG 6 9 +GGGTGCCGATC ref:0:10:AAAGCCA ref:0:11:TCTCGCTGCAT 4 5900 +GTCTCCGG ref:0:8:GTGTGCATGGA ref:2:6:GCTGGC 3 13 +TCCATCGGGGTAAGTG ref:0:16:TGTAGATTGGATGCGG ref:0:15:AGTAAG 7 134224 +CTCGCC ref:0:6:TAAAGT ref:0:6:ATCCGA 3 300 +CTTCACTCG ref:0:9:GCTGCAGATAGTTT ref:0:9:CCCACTCGGGTG 2 480 +GAGCA ref:0:5:CACACC ref:0:5:CGAATCTT 3 32 +TGGCCTAGAGACGCG ref:0:15:TAAGAAT ref:0:15:TTTTCCACCGATGA 7 1700 +CG ref:0:2:ACCTT ref:0:2:GTACACGC 2 14 +C ref:0:1:TAGAACATGCGG ref:0:1:AATGTG 5 14 +AGTTTCATGTT ref:0:11:GTGT ref:0:9:GAGCGGG 4 80 +TGGCATTT ref:0:8:CAGAGATGTGCGTG ref:0:8:CGTG 4 150 +CTACTCGAAGTGC ref:0:13:GCTACT ref:0:13:GAAGTTTACACCGCG 2 9 +AGGACCAACACAGA ref:0:14:CTGCCAG ref:1:12:GGGGAGTGATGG 6 1740736 +G ref:0:0:CCAT ref:0:1:TCGCCACGT 3 2 +GGACTCGTACT ref:2:9:CTGATACTTAGAGA ref:0:11:CCCA 2 22 +CATTAGAT ref:0:8:GAGGCAGAGTGG ref:0:8:AAGTTCTTC 3 1500 +CAGGT ref:0:5:ATATGAA ref:0:5:GCGCACGTCGCGCTGT 2 1152 +GCCAAGAGGGG ref:0:11:CACGTTGA ref:0:11:CC 7 883 +GTT ref:0:3:CGATAGTCCCGAGAA ref:0:3:GCTGTAAAGGATT 4 11 +TC ref:0:2:GTGGAACAAACCTGC ref:0:2:GGCT 3 20 +CCCGA ref:0:5:CACGC ref:0:5:CCAAA 1 198 +ATTGTAATATCCTCAC ref:0:16:CGCGAATGACC ref:0:16:GGCTTCC 9 67008 +CATC ref:0:4:GAGACT ref:0:4:GAGTTCGCA 3 136 +TCGATAATA ref:2:7:AACAGTCCG ref:0:9:GGCGTAG 2 108 +ATTCCCCTTATCTGT ref:0:15:TTTCCTTGCGC ref:0:15:CCTATGATC 6 8400 +TACCCCTTA ref:2:7:CGCCATCTACG ref:1:8:GATCTCTTGC 2 360 +CTC ref:0:3:AGACCGTCGAAC ref:0:3:AGACT 3 4 +GAGAAGCATT ref:0:10:TTGGC ref:0:10:CA 6 8 +ACCG ref:0:4:TACC ref:0:4:C 1 2 +CTAATTAGTCGT ref:0:12:GGACG ref:0:12:GCGGGCG 9 2835 +GCCATTGCCAGATACC ref:0:16:AC ref:0:16:CGGG 11 300 +AT ref:0:1:CACA ref:0:2:CCCAGTAGTTCG 2 10 +CCAA ref:0:4:TTACACTTCTAGTT ref:0:4:TTGCC 3 26 +AACATATGCCGCGCGA ref:0:16:CGGTTGCATC ref:0:16:AGTCATGGAGCC 8 60564 +CTACGGAGAAGCA ref:0:13:AGAGCAATCCGCT ref:0:13:GCAG 6 212 +AATAC ref:0:5:GACCT ref:1:4:GATGCCGCC 3 416 +GCGCGTGAA ref:0:9:CATTGTAATCAA ref:0:9:GGGCGGCTA 2 15050 +AAATTGATATT ref:0:11:TCAAGCGGT ref:0:11:TAGTAGGAACTAG 7 1056558 +T ref:0:1:AACAGCTT ref:0:1:AGAC 3 10 +ACATC ref:0:5:GGATTGCTTGG ref:3:1:TGT 1 52 +GTGGACGCAGTTAGG ref:0:15:CTGCTAGCT ref:0:15:GCGGTTGCTAAACTGC 8 377055 +TG ref:0:2:TATTGCAA ref:1:1:GAGAAGT 3 9 +GTACAAATAAAAT ref:0:13:TCA ref:0:13:CAAGTTGAG 7 2618 +CTTGC ref:0:5:T ref:0:5:TTGATA 2 8 +AGATCATCGATA ref:0:12:TG ref:0:12:TTATG 8 16 +GTGGTATGTT ref:2:8:CCTCATAG ref:0:10:CT 5 198 +GCGGGTCGACTG ref:0:12:CCTGTTTTGGACTAGC ref:0:12:GTTC 5 46800 +AGTCGCCACT ref:0:10:AAAAA ref:1:9:TTACGACC 5 6006 +TAGGTCAGCAAGTC ref:0:14:CCCGTTTTGTAGGT ref:0:14:AAAG 5 160 +ATCCGACG ref:0:8:GGGAGT ref:0:7:TCTACGCA 2 42 +GTATGT ref:1:5:A ref:0:6:CTGTACAAAGCCTT 1 26 +GG ref:0:2:TACGAT ref:2:0:ATA 2 7 +TACTTTTGTGC ref:0:11:GTG ref:0:11:ATGGCCTCACGGGGAA 6 20300 +CTTCG ref:0:5:TCGTAAGCATAATGT ref:0:4:GTCGCGCACGGCCTT 6 84 +TGTGGATGTCAAGTT ref:0:15:GCGCGAAA ref:0:15:CGTG 8 104 +G ref:0:1:GCGAATGAGCG ref:1:0:TAACTTAC 5 5 +GCGGTTACTACCCCAA ref:0:16:TC ref:0:16:AGGTACAAG 9 1960 +C ref:0:0:GTTA ref:0:1:GTTG 3 5 +C ref:1:0:AGG ref:0:1:AGGCACACA 1 3 +TCTACTCCTGCT ref:0:12:CACGCAAA ref:0:12:TAGAATA 8 72 +ATATTGCACAACCCG ref:0:15:GCCACTAGGTGAC ref:0:15:CGCT 9 12144 +ATGAGATGACATCC ref:0:14:CTCGAGCTCAGCTT ref:0:14:TGGCTTCTC 6 3886 +TTGTCTTCT ref:0:9:T ref:0:9:GAATTCTT 4 246 +TGATGCGCG ref:0:7:GGGA ref:0:9:GAGACAAGACAA 3 3 +G ref:0:1:ATAGGG ref:0:1:CATACAAAGTG 4 6 +ACAGT ref:0:5:GAACAGCTCGA ref:0:5:GC 1 8 +ACTG ref:0:3:AATA ref:0:4:GCA 1 24 +CACCTTGC ref:0:8:GGTCCCATGCAA ref:0:8:AT 1 6 +GTTTCGTTA ref:0:8:TTACACGCGCCTC ref:0:8:ACTTGCCG 4 5280 +GATTTACGTTATG ref:0:13:TTTGTGAGCCT ref:0:13:AGC 7 132 +CATCGCGT ref:0:8:GACCAACTGTAAA ref:0:8:ACGAACTCGG 4 134 +TCCAGTGG ref:0:8:CTTTGAGCTGTAGGG ref:0:8:GCCC 2 7667 +GACGAGCCT ref:0:9:CGACCTACT ref:0:9:ATGGCTTCAGATC 2 32 +GGCCGGTTCAAAT ref:0:13:TGAACGGCGCC ref:0:13:ACTT 7 37842 +GTTAGGGGAGCTTTTA ref:0:16:GTA ref:1:14:AGGACCGCTT 6 1080 +GACATGCAAGAGGC ref:0:14:CAAGCTGCCCC ref:0:14:CT 8 1597 +TTCACTAGGCCTCTAG ref:0:16:TGGCA ref:0:16:ACGGAAGGACCGGA 7 3330 +TACAAGATTACT ref:0:12:GGTGC ref:0:12:GCGG 10 1419 +ATGTTTTTGA ref:0:10:CGTTCGACG ref:0:10:AACCG 6 9840 +GAGCAGGCCATGTT ref:0:14:AGGCCGG ref:0:14:CCCATCACCAGCTTT 3 768 +ATTATTTTCCTATAG ref:1:14:CTGGTACGCGC ref:0:15:GTGTCTATTGATAAC 6 4032 +CGTTCCGAGTACTAG ref:1:14:GAGTGAGAC ref:0:15:GGA 7 42 +CCCTGAGGGTACCGCG ref:0:16:CGAAGGGAGCGATG ref:0:16:GGGGCAAATTAC 5 396 +GGGAGA ref:0:6:AAT ref:0:6:TTGTTAAC 3 21 +GAATCCC ref:0:7:TA ref:0:7:CATGTAG 6 2709 +G ref:0:1:TTCAGG ref:0:1:AAGTATAAGCTTAT 3 4 +GTGACCAGCGCAGACA ref:2:14: ref:0:16:ATCCACAACTCAT 6 12 +AAGTAAA ref:1:6:TGAGTAC ref:0:7:TCGCGT 4 126 +G ref:0:1:CTTTTTGTG ref:0:1:CTATTTGAGAAACAC 6 4 +TAGGGTGAG ref:1:8:TG ref:0:9:GAGTCAACAGGT 3 452 +TGT ref:0:2:CAGGGGAAGGC ref:0:3:CAGGTTC 4 555 +ACAGCCAACA ref:0:10:GAA ref:0:10:AGTCCGATAT 4 60 +GGCGAGTGGTCGGCGC ref:0:16:AACAGCGAGAT ref:0:16:CAGTTG 8 1530 +TCAATTAGCCGTAGTG ref:0:16:CTTAG ref:0:16:ATTAG 10 200 +GTGTCTGGCTGGAT ref:0:14:TAAAATACTCG ref:0:14:AGT 8 710 +CCACGCCCCACTG ref:0:13:ATTTTTAGATATA ref:0:13:AA 9 1400 +GTGGG ref:0:5:TCTGGGAA ref:1:4:CCTTCCTTCGAATAC 4 1000 +AACGT ref:0:4: ref:0:5:TACTGACTGCGG 1 14 +GTCGCATAGATTTACA ref:0:16:TTAAAAGGAC ref:0:16:AGCTCCCCTGCCG 7 410625 +ATCGTAGTAT ref:0:10:GGAGCT ref:0:10:AACCAACGA 3 1175 +TAGGCGCCTGC ref:0:11:CCTTTAATTAT ref:1:10:GTCGCGAAG 6 176396 +TGAACTAATCT ref:0:11:GG ref:0:11:AGGATATTGCGCTTTG 5 5160 +ATAGGTGCTAGCA ref:0:13:ATCAGC ref:1:12:TTCCGTTGTT 5 1782 +A ref:0:1:GG ref:0:1:GTGGCAGAATAC 2 12 +ATTATCG ref:0:5:CTGACTCTAA ref:0:7:CGTGGTATCACCTAGG 3 54 +GTTTATCTAG ref:0:9:TTT ref:0:10:CTTTCAC 4 200 +GAACCC ref:0:6:TGTAAGTTCTAAG ref:0:6:CTATATA 5 1710 +CCGGAGA ref:0:7:CA ref:0:7:AGC 4 8 +ACTAGCGGCAGTT ref:0:13:C ref:0:13:GCTC 10 57 +GACGATG ref:0:6:GTGCTTTGAACTC ref:0:6:TTGTCAGTACC 4 112 +GTAGCA ref:3:3:TTCTTGACGTG ref:0:6:TTTA 3 216 +AGCGATCTCCTTCCG ref:0:15:TTTGATCGGT ref:1:14:GT 7 40 +CAAAG ref:0:5:ATCATCCCCCGA ref:0:5:CTTCGAGCT 4 1566 +TAACCGTGCC ref:0:10:GCGGA ref:0:10:G 7 54 +AGGGCGGATTT ref:0:11:CAGAGCGCGAATCAA ref:0:11:GGGG 3 1155 +CGATTCACCTCAAA ref:0:14:AGC ref:0:14:ACGAAAG 9 1517 +AAACGCGG ref:0:8:CC ref:0:8:GTCACCT 5 45 +TCCGCT ref:0:6:TTGGTACCGTCCAC ref:0:5:GTGCAGACACC 3 513 +T ref:0:1:TAGGCATATC ref:0:1:GGAACG 5 21 +CAGACAA ref:0:7:T ref:0:7:AATTTTGGCCCCTCAT 4 4672 +CTGAGATCCT ref:0:10:TTCAA ref:1:9:GCA 6 255 +ATGGTGACGCGACGGA ref:0:16:GTAGGTA ref:0:16:CGC 8 112 +CGTGCTGCTTCTCCA ref:3:12:GGCGACGGAAGA ref:0:15:TCTCGAGCAG 9 1035348 +TCTT ref:0:4:GCATCCAGGTTGC ref:0:4:TTGAGATCATTACCTC 4 18 +CTC ref:0:3:CTCTATCTTTTTCA ref:0:3:ACTCCTTGTGTG 5 52 +AAAGCAAACACCTCT ref:0:15:TTGCGCGCCATG ref:0:15:GGTGTG 10 19760 +CAGGACTTGTGATG ref:0:14:CTA ref:0:14:AC 10 12 +GTACC ref:0:5:GATGTTAAGTAT ref:0:5:TGAGGAGGG 5 27744 +CG ref:1:1:GGTAATTGGTT ref:0:2:AGCATTGATAGAGA 4 12 +AGTGG ref:1:4:CCGCCGACACACTAT ref:0:5:ACCAGACTGCA 6 448 +TGATTGCATTA ref:0:11:GGCTCCGGCC ref:1:10:CCGAAT 6 958 +TGTTTCCGGAGC ref:0:12:CAGGCAATAGTAAGT ref:0:11:CGG 6 57216 +GCTTTACAAGCCTC ref:0:14:GGTGACATATTGGGG ref:0:14:CGC 6 10824 +GAGCCTGATTTGTT ref:0:11:TAAGAGTGATA ref:0:14:TC 4 216 +TAAGAAAAG ref:0:8:GTAG ref:0:8:TTTCTCATAACA 2 812 +CCCCT ref:0:5:TGATAAGACCAG ref:0:4:GGC 4 4700 +C ref:0:1:TCGCCGAGTAGGGA ref:0:1:CCAGGTCAGGGC 8 12 +CTGTGTTCGGCCCA ref:0:14:TTTCACACATT ref:0:13:T 7 224 +A ref:0:1:GGCAAGGTGATT ref:0:1:AACCCTAA 3 12 +GAA ref:0:3:TACCGCCGGAAGCATG ref:1:2:CACGTTTCGTGTG 5 126 +TGGT ref:0:4:ACTCGA ref:0:4:AATCGC 4 49 +TCGG ref:0:4:GTCACTTTTATT ref:0:4:GTTAAAATTTGGC 5 2093 +GGTCTAGGAACGTGA ref:0:15:TTCTAGGTCTGT ref:0:15:ACGCACGCTTATG 5 20664 +TTACGCGGGAGACGG ref:0:15:TCGCCATCTTGGCCTC ref:0:15:CCTA 7 440 +TTAA ref:0:4:GGTACTTGAT ref:0:4:ATTGCAT 4 85 +G ref:0:1:AATTCGTA ref:0:1:GGTAAGGGCTCGAG 5 7 +TCG ref:0:2: ref:0:3:CTGT 1 2 +TCATACTCTACGCC ref:0:14:GG ref:0:14:CTGACCCAA 8 1110 +CA ref:0:2:G ref:0:2:AAA 1 18 +ATCAAA ref:0:6:GTGCCTCGGGCGAAG ref:0:6:TCTGCCCTGGT 7 145360 +TACGCT ref:0:5:CGACGAG ref:1:5:AACAGA 2 78 +C ref:0:1:CCCGAGAG ref:0:1:AT 1 9 +GCATCTGGCAACGGA ref:0:14:AACCG ref:0:15:AAAAACCGGTGCCCG 8 803990 +CTAGAGAGAATGCCAC ref:0:16:C ref:0:14:TTTACTTACAGTC 7 576 +CATCAGATCATATG ref:0:14:GAGCTCCGGAC ref:0:14:AGTTGCGTAGTT 5 48 +GAACTC ref:0:6:TGCGGTTGTT ref:0:6:TGCGTATCAT 6 264 +ATTCCC ref:0:6:TTGTGT ref:1:5:C 2 216 +ATTCTGAAAGACAGAT ref:1:15:GATAGCA ref:1:15:AAACGTAAGGGATCT 4 48 +TCTTCTCCGG ref:0:10:CCGGGGAGTCGGG ref:0:10:T 4 28 +GCTATGTGA ref:0:8:ACAATAGGCT ref:0:9:CACTGGGAA 3 208 +CCCC ref:0:4:GAACAC ref:0:4:CATCCTATT 2 280 +ACCTG ref:0:5:ATGGGATTGTT ref:0:5:TCCCCATGGC 2 1824 +GCCGGATT ref:0:8:AAGAGCAA ref:0:8:AAGCGCCCAGATCCG 6 20570 +CAGCTCAG ref:0:8:TAAGTCTAGGGA ref:0:8:AACTCCTCTGCAAC 4 29040 +CTTCATGGTT ref:0:10:TGA ref:0:10:GCTCGT 5 208 +G ref:0:1:CCAAACGCCT ref:0:1:GGTGGTGG 1 6 +TTCTGA ref:0:6:ATCTTAG ref:0:6:ATGCT 3 68 +A ref:0:1:CG ref:0:1:CT 2 9 +TAACGGGAC ref:1:8:GTTCT ref:0:7:TCATCCAAG 3 2432 +GGGGATGCTCGTATTT ref:0:16:CAATAGCT ref:0:16:ACAACCGGATG 10 314280 +GTCCGTTGA ref:0:8:AGCATGATCCG ref:1:7:ATC 4 72 +TTGTGT ref:0:6:CTCTCTTA ref:0:6:C 3 14 +ACGACGCGCTGCCCTA ref:0:16:TAAGCT ref:1:15:ATCGTTCGTCCAC 6 60 +AGCGTGTG ref:1:7:CATAGATC ref:0:8:GGGT 1 4 +CTAGACGTGC ref:1:8:TTACAGAT ref:0:10:T 3 28 +TGGGCATAAT ref:1:9:TAC ref:0:10:G 6 15 +CGACTTTAGCGC ref:0:12:GGTGGTGC ref:0:12:TGTGCAGTCGTA 7 29972 +GCGTGGGCCCA ref:1:10:TACGTCGTCCT ref:0:10:TTTATTGTGG 4 16212 +GTATGTAGTCTT ref:0:12:GGCCTCT ref:0:12:TTCAAAGAGGTCGCTG 4 11552 +GGATAAAACGTGG ref:0:13:TTTAA ref:0:13:G 9 575 +CCATAAT ref:0:7:GTCATAAGAGTAA ref:0:7:ATCACCATTTGAGA 2 108 +TTCTCCGCTCTG ref:0:12:TT ref:0:11:GCGACGGC 5 2520 +TGTTGCAAAGGTTTA ref:0:15:GTTTTCAGGGGACC ref:0:15:TACACCAGATT 4 833680 +G ref:0:1:AGTGCATA ref:0:1:AACAATGAGATTA 5 4 +TT ref:0:2:GGTG ref:0:2:AGGACAGTGCTGACG 3 5 +TCCTGCGC ref:0:8:AC ref:0:8:CACCGGA 5 323 +ACTGGAAGTTTCCC ref:0:14:TGAAAGGCTGAGCC ref:0:14:CAGA 6 47531 +GTTAAGACCGGTCT ref:0:14:TGGAT ref:0:14:G 10 192 +GATACATAGACGTA ref:0:13:CCGGGC ref:0:14:CCTCAAAGTTAATC 6 7680 +CTTTAC ref:0:6:AA ref:0:6:C 4 14 +CCACCTCCAGTCC ref:0:13:ACGCCGGGGA ref:0:13:AGGCGTTGCGC 8 154440 +GTCGCTG ref:0:7:GACA ref:0:6:AGCCTCTT 2 575 +A ref:0:1:CTTGTTAGGTAC ref:0:1:GCC 2 8 +TTCCA ref:0:5:GCCATT ref:0:5:GCCAGACAAATGCCG 4 204 +TCATCATCACCAG ref:0:13:GGCAAAATC ref:1:12:AGGGAAGACAGATTG 8 356532 +GCCCCC ref:0:6:CG ref:0:6:AGTCCGTTGTTTCG 3 1456 +GTCGG ref:0:5:TAA ref:0:5:TACCTGTACC 4 190 +TAAA ref:0:4:CAGATGGTAGCAGG ref:0:4:G 2 135 +TATCAA ref:0:6:GTGACTACATAA ref:0:6:GTGGCCCCCC 3 2520 +GGGTGTAAGTACAG ref:0:14:CAAACTCGAGAGCA ref:0:14:GTGAGGGCC 7 71568 +GGCTAGT ref:0:7:TGCCT ref:0:7:GTCGGGACTGG 3 576 +CAAGCAACTAGGGGT ref:0:15:ACCCTTTGCA ref:0:15:GTAACA 7 9912 +T ref:1:0:CACG ref:0:1:GTTAAGAAGGGCGC 3 2 +CGGAAACTCTGAGAAA ref:0:16:TATGTGTGAC ref:0:16:TT 10 360 +ATTCACAGG ref:1:8:GTATGGTC ref:0:9:CT 4 195 +GGTGCCATGCCGTGA ref:0:13:TCAAACTGGTAT ref:0:15:AGTTGCACAC 3 1180 +GTATCTGAA ref:0:9:TAACACACAGAAAGA ref:0:8:AGGGAATAAATGGAG 5 103680 +TCCATGTTCCGAGCT ref:0:15:A ref:0:15:GGCCGAGCTG 7 18 +ATTGATTCGGAGA ref:0:13:GCGGCTACGT ref:0:13:AA 6 12 +CTTATC ref:0:6:AT ref:0:6:ACTCCATACACCCT 1 37 +CTATTCCGCTCA ref:0:12:TAACCC ref:0:12:ACACCGGATTCCACTT 4 2346 +TCAGCCGGATGCAAC ref:1:14:GGTTG ref:0:15:CGG 9 120 +AAATCG ref:0:6:TACAGTGAATCA ref:0:6:AGTCGTTTTGATT 2 96 +AATCCTATACGCAA ref:0:14:TACACCGGGTTATAAG ref:0:14:TCGGTA 6 3402 +CAAGTTTCTTATGACG ref:0:16:ACGCCT ref:0:16:ACTCTTCAAA 9 21756 +GATCCCTTAGAT ref:0:11:TCGGGTCACACCTGC ref:0:12:TATTGCGAACCTATC 5 1920 +TGGAACTAAGG ref:0:11:AGATAGCA ref:0:11:AGTAGATTG 7 29212 +ATCCCAAAA ref:0:9:CATGAGTGATAGC ref:0:9:AGAGCAC 7 25564 +GGGGTTATTA ref:0:10:ATGGAGTGCT ref:0:10:TTTCAAATC 5 43632 +ACAAAT ref:0:6:GACC ref:0:6:ATG 3 24 +GACGACAC ref:0:8:GATTTACG ref:0:8:ACGACT 2 425 +ACTGCCTTA ref:0:9:GGCAAATTTATCTCT ref:0:9:GCGAGCTTATT 6 22080 +AGGCGAACTAT ref:0:10:AATCGCATACAGGC ref:0:11:ATACAGAGTCCTGTGG 5 2880 +CAC ref:0:3:AGCAAGGACAT ref:0:3:G 1 12 +TCCCC ref:0:5:ATATTGCTCCCTCTCG ref:0:5:ATGATATAGTCGTGC 7 11850 +AACAAGCCAATA ref:0:12:AGAG ref:0:12:CTATTTTT 7 76038 +CGGT ref:0:4:GATCACTAGAC ref:0:4:CGCGGCTC 3 224 +CATAGGTA ref:0:8:TG ref:0:8:AACCCT 3 20 +ACGGCCAT ref:0:8:CC ref:0:7:CTTCGGATCGGTGAA 2 327 +ATA ref:0:3:AATGTTTTGAACTGC ref:0:3:GAGTAAGCATGCCG 6 60 +TGACAACACGTGTAA ref:1:14:CGGGTGGGGGGGCT ref:1:14:AACGTTAGC 6 12852 +TCCTTG ref:1:5:GGCCTTGAATTCC ref:1:5:GGCGATA 4 52 +GCGGGTTTTTGTATGA ref:0:16:TTCGCCCCGGC ref:0:16:AAAGCCACGGA 13 3754166 +GCTAGGTGAG ref:0:10:TGTAT ref:1:9:TTTTT 6 1100 +AGCACT ref:0:5:TAC ref:0:6:CAGACA 1 18 +GCGTGTCGT ref:0:9:TATC ref:0:8:TAGTCTATCACCGG 3 24 +CAGAGGAAA ref:0:9:AAATACGTCACCGC ref:0:9:AAGGAATTAGAT 4 4 +GTTGTT ref:0:6:ACCTAG ref:1:5:CTCGAGTGCC 4 1152 +T ref:0:1:TGTTGT ref:0:1:TTAGAT 3 12 +CTCACGAGACCT ref:0:12:CGCTGTCAA ref:0:12:TTGGTG 5 288 +TCAAACCGG ref:0:9:AATGAGCCCACCTT ref:0:9:ACATTCTGGCTG 5 153224 +AATTATTAC ref:0:9:CTGTT ref:0:9:ATCGTG 6 4577 +ACCGCTTA ref:0:8:TCAAGGAGTGTT ref:1:7:CTGGCTGGCACGAGT 6 125100 +GAGCTAGTGT ref:2:8:CGATC ref:0:10:CTAACTAAGGTGGC 3 4180 +CGACCGAGA ref:0:9:ATTTTGCCGGTGTGTC ref:0:9:ATAGCTCC 7 49140 +GTTACCAAGACC ref:0:12:TTTTCCTGC ref:0:12:AGCTCTGGTCG 6 73710 +CGACCC ref:0:6:AGGATACA ref:0:6:GTCTTCA 4 1365 +CTTTAAACTA ref:0:10:GTT ref:0:10:GTTTGGT 7 480 +TAGTTCTTAGC ref:1:9:CACCCTT ref:0:11:AT 5 60 +TGTC ref:0:4:AAGCTGACCAA ref:1:3:GAAACGTACGGTGTT 3 22 +GTAAGTCA ref:0:8:GGATTCCGAGATTATA ref:0:8:ACAACTGACGATGTAG 5 2485 +ACT ref:0:3:CAA ref:0:3:TTGT 1 98 +GTT ref:0:3:CTCCCC ref:0:3:TAAAAAGAGG 2 325 +CGCACGTAGGGTTTAA ref:2:14:CGAAAGACCAAT ref:0:16:A 8 12188 +TAAATGACTCAC ref:1:11:CAAGCAAGTGTGCT ref:0:12:GGTAAC 4 3124 +CC ref:0:2:ATATAATTAGCG ref:0:2:GAATC 4 78 +TTAGGGTTAT ref:0:9:AAC ref:0:10:CGCTCCTTCCAAGTG 5 711 +ACGCCGG ref:0:7:ACTAACTTCACGGCTT ref:0:7:CTGAGTAATCGTGTA 5 480 +CGGAGCGGGCTGAT ref:0:14:GCCTAA ref:0:14:ATG 7 12 +GGTTGTACCG ref:0:10:TGGAGTCGC ref:0:10:CTCATTA 2 27 +GCCGCGCATGGCA ref:0:13:TTG ref:0:13:CCGCATTTAAGC 6 1575 +TTAGAA ref:0:6:AAGATAACC ref:0:6:TAAAGGTG 1 24 +AATTCCCC ref:0:8:AGC ref:0:8:TC 5 320 +AG ref:1:1:CTGCTTACCAAATAC ref:0:2:CTGTA 4 4 +GAAAGTATTCGGAT ref:0:14:TTTGCGAACCG ref:0:14:CAGACTGAGCC 7 17280 +AG ref:0:2:TGATAATC ref:0:2:CTATGCGGAG 3 75 +GT ref:0:2:GTTCTCAGTCCTA ref:0:2:TTCG 3 28 +TGCACGTGTGCCCTC ref:0:15:CCGAAAACATATGA ref:0:15:GAAGGG 8 4608 +G ref:0:1:CTATA ref:0:1:GAAAACGG 2 18 +ACGGCATCGCGGAAGT ref:0:16:CCAGTGCGG ref:0:16:GGAGA 5 18 +ATGTTTGAACTAATG ref:0:15:G ref:0:15:CTA 11 6 +CGGGC ref:0:5:ACTGACCTTG ref:1:3:TT 3 340 +C ref:0:1:A ref:0:0:GAA 1 2 +GGGAA ref:0:5:ACTTGTAATTG ref:0:3:TCT 4 560 +CT ref:1:1:GGG ref:0:2:GACGA 2 12 +T ref:0:1:CTGTG ref:0:1:CG 2 6 +TTACTGTTTGAGAAC ref:0:15:A ref:0:15:GCG 12 108 +GGGCATTAAGACGTA ref:0:15:A ref:0:14:ATCCGGAGG 9 1155 +AAATTATC ref:0:8:CTGCCATCGCGCGGA ref:0:8:TCGCTACGCAA 8 252 +TCACTTGTCC ref:0:10:GA ref:0:10:TTACAAAGGGTGAC 5 15358 +ACTGCA ref:0:6:CAATAGAGGTAAT ref:0:6:CCGTCTGT 3 5856 +G ref:0:1:AT ref:0:1:TCTGTGGTCCCTGGA 1 15 +CG ref:0:2:TATCCCC ref:0:2:AAAA 2 150 +CGGAA ref:0:5:TGAGATCCTAAAACA ref:0:5:GGTTTTCCC 5 1080 +C ref:0:1:CTTTGTATC ref:0:1:CGGCCGTTGATGTGA 6 6 +GGGTAGCCAAGAGAGG ref:0:16:TGCAGTAA ref:0:16:TCCAACAG 7 88 +TTAGA ref:0:5:TCGGGATCCCTCAATT ref:0:5:TTTTATAAGAGCCTG 2 78 +TTGAG ref:0:5:CATCGGCG ref:0:5:CTTCGTTA 2 32 +CTAGGTTTGAATC ref:1:12:GTTGA ref:0:12:TCAACAGTTCA 5 6936 +TTA ref:0:3:CAACC ref:0:3:AGCAGA 4 288 +GTCGTA ref:0:6:CT ref:0:6:ACCG 3 9 +ATCCTGC ref:0:7:TCCGAGCGGGA ref:0:7:GAGAGA 4 144 +GGTGTTGGATGAC ref:0:13:GCGAA ref:0:13:TG 8 418 +GTGCTCAACCTCTC ref:1:13:TTTGACGTTAG ref:0:14:CAGCCTCGGAGAC 5 31500 +TAC ref:0:3:CGCAT ref:0:3:GCAGTTACCCGT 3 96 +AGGACTAC ref:0:8:CTA ref:0:8:CTTAACAACCATA 3 61 +AGCA ref:0:4:CGCGCTGACTAT ref:0:4:TGTATCGCAC 3 30 +GGCAGGCCGATT ref:0:12:GCACTA ref:0:12:ACACCGGCCGC 3 264 +A ref:0:1:GCATACGGA ref:0:1:AGACCTACCC 4 9 +CGCGTGTTT ref:0:9:GGTCACCGTACTGAA ref:0:9:C 2 16 +T ref:0:1:TATGTTA ref:0:1:A 1 8 +GAGGCTGCATT ref:0:11:TAGAGC ref:0:11:CCAACGACTTCGG 5 598 +AGGCTT ref:0:6:C ref:0:6:GAGCCACTCGGTC 1 13 +CGAGCGAGCACTG ref:0:13:TCAACACGAAAC ref:0:13:GT 5 528 +ACCACCACAG ref:0:10:TCTATTTAGCCCCCC ref:0:9:GCAT 3 2040 +CGG ref:0:3:AG ref:0:3:GGCTACGGCTGGGCA 1 115 +TCCCTGTCCGGGAGTC ref:0:16:GGTTCAACGCTT ref:0:16:CCTCTCTCGGT 7 261360 +GGACCGGGTAG ref:0:11:CTCAAA ref:0:11:TTGGTACCATCT 5 2000 +C ref:0:1:TCGTAAGTCTCG ref:1:0:TGGT 3 3 +ATCCTTGGAACAT ref:0:13:G ref:2:11:ACCTCGA 6 52 +GCTCTGCCCGTAGC ref:0:14:GGGAACGATTCATATG ref:0:13:TCGATGCTT 4 486 +CCAAGCGA ref:2:6:TATCCGG ref:0:8:G 3 126 +TGTGCGAAATG ref:0:11:TGAGT ref:0:11:C 6 55 +AAAGATCTCCAAT ref:0:12:TCGAAATT ref:0:13:C 6 21 +TAGGCCCGATAGT ref:0:12:GT ref:0:13:ACCCG 6 6 +CTGCGGACTTTAA ref:0:13:C ref:0:13:ATCGTTAAAGCTT 6 408 +TATC ref:0:4:CCATTGCGACGAGGTA ref:0:4:ATAAATTCGAGGTCT 6 432 +AGA ref:0:3:C ref:0:3:CAGCTGT 2 28 +GCACACTTTCGGAT ref:0:13:ATGCCCAATCGG ref:2:12:GCCGTAGCGG 5 2010 +GGTACCT ref:0:7:AGCCCATTG ref:0:6:ACGTGC 3 874 +AAGGTGGT ref:0:8:G ref:2:6:TTCGTTGTCTGAAA 2 668 +GCCCTGCAGG ref:0:10:GCG ref:0:10:ACTATGTCAAGC 4 3094 +GGCCTTTA ref:0:8:GAACAAGA ref:0:8:AAGT 6 4680 +CTCCTGGTGCGGCTCC ref:0:16:AAGCGCCGGCTG ref:0:16:ATATAGCTCCCTCT 9 974016 +TGGGCTAGG ref:2:7:TGCTCGCTCCAAA ref:0:9:GTGTATAGTA 4 2140 +GCTGC ref:0:5:CTCATCCCAACGATAA ref:0:5:TTAGACGATAATGGAA 7 1372 +TCTGCCCTCA ref:0:10:TG ref:0:10:ACTCGG 7 366 +CCTGACAAGGATT ref:0:13:GC ref:0:13:GGATCCAGATGC 6 200 +GAGCCCTCACTCT ref:0:13:GCCGGATGA ref:0:13:C 8 2244 +AATGGGGAG ref:0:9:CCAGTTTCCGC ref:0:9:CTGGTAACT 6 1192890 +TTATG ref:1:4:GCGTT ref:0:4:TGT 2 6 +GGAATCTGTCCGTC ref:2:12:TACCTGTG ref:0:14:GT 6 132 +AACCT ref:0:5:GTCCCCCTC ref:0:4: 2 105 +AAGACCTCGC ref:0:10:C ref:0:10:GGGGGTTTACGCTTT 5 8372 +CCCGGCA ref:0:6:GAAACCAC ref:0:7:TCGGGCACTT 1 506 +ATTTCGCCCTAGTCA ref:0:15:AAAAAG ref:0:13:TGTCTCTTGG 5 510500 +CATTA ref:0:5:ACATGCCATTATCATG ref:0:3:GGCACCACCAATCC 4 294 +GTCGGTAAGTG ref:0:11:TGA ref:1:8:CGAC 4 40 +GAGACA ref:1:5:GTCC ref:0:6:ATC 3 28 +TCCGCGT ref:0:7:AGACCTTCTTCAGA ref:0:7:ACTGATTG 6 33600 +ATGTCTAGGC ref:0:10:GTGCT ref:0:10:CTAAGGGAGA 3 266 +CCCCAA ref:0:6:AATTTATAGTTAGGCT ref:0:6:CTTCGTACT 8 105776 +AT ref:1:1:CTAA ref:2:0:CGCAG 1 1 +AGCGGCAGTAGCT ref:0:13:TAG ref:0:13:CTACG 9 6 +A ref:0:1:GATT ref:0:1:CAGTA 1 2 +TAGGAGAGCAGC ref:0:12:GTTCTTAAT ref:0:12:ATGCGGACCTTAG 6 11640 +GTACGT ref:0:6:GGGGATTAGCCAG ref:0:4:GGCTCCA 3 128 +TGGCTACAGCGATTC ref:0:15:CTGAATAT ref:0:15:TAAT 9 492 +GGAATCATACG ref:0:11:CGGT ref:0:11:AGGATTTT 6 162 +CT ref:0:2:CCTATCGATTCTAAT ref:1:1:GGATAGGGCGCGGCA 5 18 +TACGATAACCACC ref:0:13:G ref:0:13:GAAGTGTTGACG 8 11001 +ACTCGGGTACCA ref:0:12:GTAACCCGAGTTAG ref:0:12:CACGCGGC 4 9640 +C ref:0:1:TCTTCTCCATT ref:0:1:TGTATGCCGCATACGC 7 20 +G ref:0:1:C ref:0:1:GGTAGCAGGTGGC 1 14 +CGGAC ref:0:5:AGTATA ref:0:5:ATGCGACCATGGTTTC 3 1408 +TCCGCAAC ref:0:7:CGGC ref:0:7:AGGCCGTCCGCGTT 2 50 +TGATTACCCAACGGA ref:0:15:GTTACGAAAA ref:0:15:CACCT 6 19550 +CTCGG ref:0:5:TAGGCGTGGCTCC ref:0:5:ATCTGGCGGTATCACG 5 12 +ACCGACTGCAT ref:0:11:C ref:0:11:TCTTGATC 6 192 +CATGAAAGCA ref:0:10:TAAAGTTCGTCAGTAA ref:0:9:TCGCCCCAATCT 4 270 +TTTGG ref:0:3:CCCAATGACATATT ref:0:5:TCCAC 2 480 +AATATAGATCCAAG ref:0:14:TATACTTTAATTT ref:0:14:AACTCCTCTGCTGAC 7 2151968 +TGCACTAGAGATA ref:0:13:AGGTAAAGAGGG ref:0:13:GACTCCCCT 4 314622 +TAGAGAGCGGTAA ref:0:13:GTG ref:0:13:AAACTTACC 6 952 +CCA ref:0:3:TG ref:0:3:ACAACATGGAGCAACG 2 80 +CAGACGCAGCGTTG ref:0:14:T ref:0:14:GATAGTTTAGGCG 7 664 +TATCAATAC ref:0:9:ACA ref:1:8:CTCCGGCAGTCCG 2 288 +CGGA ref:0:4:TGTATGTAACCTACGG ref:0:3:TGCGCT 4 54 +TGAGGCGGAGCATCT ref:0:15:AGCCGAAG ref:0:15:CGAGAGC 8 1694 +CCAGC ref:0:5:CATGCCATTGCCGG ref:0:5:CTGATCATCCACCG 5 246 +TCA ref:0:3:AGT ref:2:1:ATAT 1 4 +AGTACTGCGCCACA ref:0:14:TTATAGA ref:0:14:CGGCGTTCGAAGAC 7 69872 +ATCCAGTACAACTGGG ref:0:16:TGTCTGAAAGTGA ref:0:16:CTATATC 8 113212 +GGCGAAC ref:0:7:TTCCATCC ref:1:6:AAGCCTAATA 3 4482 +AGTAGAGATCATATG ref:0:15:GT ref:0:15:C 12 10 +GTTTTTAT ref:0:8:TCACCTC ref:0:8:ACGT 6 105 +CGAAACAGACAAG ref:0:13:CA ref:2:11:ACCATAA 6 1482 +CA ref:0:2:CCTCCAACGCGT ref:0:2:GATGCCGAACAC 5 56 +GGTGCC ref:0:6:TTCTGTTGATTCTG ref:0:6:ACCT 3 535 +GAATATATGC ref:0:10:TATTCTACGCT ref:0:10:TCCGTCTGCAC 5 3060 +AGG ref:0:3:TC ref:0:3:AGACAGCGGCTGTCTG 2 350 +CAGGC ref:0:5:TTCGACCAACTACG ref:0:5:TTGCTTTAGTCA 5 696 +GTTGCTTATCCTAGCC ref:1:15:GA ref:0:16:TGATGGTAGTCTGTTC 6 544 +ATTAAAACAAATATT ref:0:15:AAGCAG ref:0:13:AGATG 10 94920 +CAGACTCTTATT ref:0:12:TTAACGAG ref:0:12:TTTG 6 1152 +TAGTCACTA ref:0:9:ATGCCCCCCC ref:0:9:CCGCGCAAAAGGCCGC 7 5427240 +TTAAA ref:0:5:AGCTAACG ref:0:5:GTCGC 5 1950 +CGCCCATGCT ref:0:10:CCTAA ref:0:10:AGA 7 675 +CTGATGGACGTAGT ref:0:14:T ref:0:14:CCGTGTATC 7 36 +CGATGACAACCAGTG ref:0:15:AATCAT ref:0:15:C 10 204 +GTACCA ref:1:5:A ref:0:6:ACCCG 2 14 +TCTGAAGATTT ref:0:11:AATGAC ref:0:11:A 7 12 +TGGTCGCGAC ref:0:10:AAGTGGTGTATCAGA ref:0:10:TA 2 2 +TC ref:0:2:A ref:0:2:CGGCTCAC 1 6 +TTACGTCACTTACG ref:0:14:TCTGTTGGGT ref:2:12:CCCCAATTC 4 13348 +CGAACGTGACT ref:0:11:TCA ref:0:11:GA 8 60 +GGTGCTAAGACTA ref:0:13:CTAGTTCCTTAGA ref:0:13:CCAACAGGGGCCT 6 373464 +GGCGTAAATCT ref:0:10:CCAGCAT ref:0:11:ATTTGAGACGG 5 125460 +GCTATCCA ref:0:8:TTGAGCAGCTCG ref:0:8:AATTCCAGACT 3 576 +CGATGAGGTTAATC ref:1:13:TTCCCGCC ref:1:13:GGTCACCCGCGCGGA 11 1060827 +TGG ref:0:3:ATTACT ref:0:3:CCA 3 520 +TCCCA ref:1:3:G ref:0:5:CTC 2 28 +TGCT ref:0:4:CGAAAAAC ref:0:4:CACAGCGTGAG 2 10 +ATACACGGT ref:1:8:CTTGGCCGGGCGG ref:0:9:GGAATGCA 3 1160 +ACGTAGTGCCCTT ref:0:13:G ref:0:13:TGATCTATGAAC 6 30 +GTTCC ref:0:5:TTACAAA ref:0:5:CGT 1 12 +TAATGGTGGGGCGACA ref:0:15:ATTA ref:0:16:ACTCTGGCA 8 396 +GCTAGACCATC ref:0:11:CGCCCC ref:0:11:TGGAAT 2 32 +T ref:0:1:GGTCCAGTACATTTAG ref:0:1:CAGG 4 25 +GGCCTT ref:0:6:CCCAAGAC ref:0:6:C 4 290 +TAGTC ref:0:5:AACAGA ref:0:5:CCGATACCCC 3 1560 +CCAGC ref:0:5:GTTTGACCG ref:0:4:ATTCGAATTCAAGA 2 2 +GCTATCTGAGAG ref:0:12:GGATTCCAA ref:0:12:TACCTTAGTACGG 3 1728 +GAAACGGCAGGCT ref:1:12:CTCGATGGAATAT ref:0:13:TTGGCATGGC 5 4968 +GTGCAAGGTGATG ref:0:13:ATCCTGTGT ref:0:13:AGC 7 3034 +TTTATTCTTCAAC ref:0:13:GGCTTAAA ref:5:8:GAGTGGCTG 4 1606 +TGCTTACAGCTTGA ref:0:14:CCGGCCCGGTT ref:0:14:C 8 615 +TATAGAGCCCACAGT ref:2:13:ACGGC ref:0:15:CGCA 9 404 +AACACCGGTGGG ref:0:12:TATCCGAA ref:0:12:GGCCTGCTGCTGA 6 1175944 +AGTCAG ref:0:6:GTCTTTGCTAATAACA ref:0:6:CCATCCACTGCGAAC 5 528 +TATCAACCG ref:0:9:ACCCACCACTGTGC ref:0:9:CACCCACTAGAGACC 6 26406 +CCTGCTAGTG ref:0:10:CAG ref:0:10:GAGCACA 6 1122 +C ref:1:0:TTATTGAGGG ref:0:1:ACACGGGGTACCTGGA 5 4 +ATCCT ref:0:4:T ref:0:5:GC 2 7 +TCGGTCG ref:0:7:G ref:0:7:GACGACGAAGATAC 2 45 +CA ref:0:2:ACCGC ref:0:2:GCCAGTTAGGGT 2 36 +ACAG ref:0:4:CCATGCATA ref:0:4:CAGCCGCTCAT 4 91 +C ref:1:0:TGGA ref:0:1:TTGTAGCCGCA 2 3 +ACTTTCAGTTACGCTT ref:0:15:TTAACCTGA ref:0:16:CTGTCA 6 195 +GA ref:0:2:GTTTGATGGACAGTA ref:0:2:CAGACACGCCTATA 6 90 +TATCCAC ref:0:7:GAACACGTTTTGCA ref:0:7:ATACTAGCG 4 2656 +AGTACATGTCTTTGG ref:0:15:GGGTATTGGCGTCTC ref:0:15:GTA 7 6576 +ATC ref:0:3:GCGTTGAAAGGTT ref:0:3:GTACACCTGGCCGG 3 36 +GTATGAACCCCTTGTG ref:0:16:CGTAACGACTCG ref:0:16:TATATCACCTCTCGTT 6 224016 +ACTCTAGTTC ref:1:9:CCGTTGAGAAGT ref:0:10:TCCAGCCCTCCTGGG 5 8844 +A ref:0:1:TTCGTACATGTGGG ref:0:1:TCCAGTAAAC 5 8 +CGC ref:0:1:CACAC ref:0:3:GGGAGA 1 114 +AACCGCGCGT ref:1:9:TAGCGGTTCGATAG ref:0:10:TAGGCATGTACGCTGC 5 590 +TGCGTCCGTAGCTG ref:0:14:CGATT ref:0:14:GACTATGAAGCTCGT 6 1050 +GCACGTATG ref:0:9:CATGAGGAGCCG ref:0:8:AACGGGCGGCCTTT 3 96384 +CGAGGCACCAATGGT ref:0:15:AC ref:1:14:CATCCTTTGATAAA 7 175 +T ref:0:1:GTCCTT ref:0:1:GTTGCCCGGAAA 3 6 +TGGTCGGGT ref:0:8:CA ref:0:9:CACACGAGACTCGAC 4 456 +GCGGT ref:0:5:TGCTTC ref:0:5:CTTGCTAGTATGTCCA 3 4 +GCCGCTTCC ref:0:9:CCTGCCCAGAAGC ref:0:9:AGCCGG 3 42 +CTTCC ref:0:5:AATTCTAATATCATAA ref:0:5:AATATCCGACCACCAT 7 1035 +TGCTCGAGGGCTTGT ref:0:15:TTATTTTTCCAGACC ref:0:15:GATA 9 458082 +AAGGGACGG ref:0:9:ATGCCTATC ref:0:9:AAAACCGACAGA 4 19266 +CATACATCTG ref:0:10:T ref:1:8:GAGGTTC 4 3 +GCTAGATTACGGGTCT ref:0:16:TAGTG ref:0:15:AGTTAAGCA 7 72 +CCG ref:0:3:GAACCTGTAGTTGGCC ref:0:2:GCTAT 4 24 +GGTGCT ref:2:4:CTAGGCTG ref:0:6:TTGATCGTCCCCGG 1 296 +ACACTGCATATACA ref:0:14:CG ref:0:14:CCT 10 14 +A ref:0:1:GAATTAACATTAG ref:0:1:ATAACAATTTATCCT 8 36 +CTCCGATACGTCC ref:0:13:GTGT ref:0:13:GGGAGTGGTGAC 7 336 +GTGACCCTGGTC ref:0:12:G ref:0:11:GCCTGTAAG 5 72 +AG ref:0:2:CGCCC ref:0:1:CCAAA 1 6 +ATCTAG ref:0:6:C ref:0:6:AGATTGCT 2 6 +CCACGC ref:0:6:GCGATGACCCATTCTT ref:3:3: 2 335 +CACTATCGCGT ref:0:11:TTA ref:0:11:GAGTACCATGGTC 4 650 +CCAACCATTAG ref:0:11:TCTAGAG ref:0:11:TCAGTTGGGACACTT 5 2898 +CATAAGTCCATCTA ref:0:14:TAGGAGA ref:0:14:AGCGAGACTCCTTG 6 4508 +TACCA ref:0:5:CTTGAGTTCGCATACG ref:0:5:GGA 2 72 +GCGTA ref:0:5:TGCGTGC ref:0:5:AGG 1 3 +GCCTCAAATCG ref:0:11:TTTTCAACC ref:0:11:GCGACCCTCTCC 3 12285 +GG ref:0:2:GAACAACTAA ref:0:2:TCTCCAGGTGCA 2 33 +AAATGGAGACCCACGA ref:0:16:GGGGCCAT ref:0:16:AGACG 7 13912 +TCCGGAACATTT ref:0:12:AG ref:0:12:CCTGATGCG 8 5200 +AACTTCGGTCAC ref:0:12:A ref:0:12:TAGACCCCC 6 33 +TG ref:0:2:ATAGCACATGGG ref:0:2:ATGGAGAA 4 21 +CAGGCAATATCAGAG ref:0:15:ACCAGACACGTGTA ref:0:15:A 7 4704 +CC ref:0:2:ATTTGTCCATTTC ref:0:2:TGAGTGTCA 5 30 +GGGG ref:0:4:CCTCACTTC ref:1:2:AAGTATGTC 5 715 +ATCGACCGGCCG ref:0:12:TCTTATGTTT ref:0:12:AATGCGACAACGCGAA 2 4608 +AGGTGACCGCCTA ref:0:13:AACAACTGGTAACG ref:0:13:GATGATCTCATCATGG 5 15120 +GGTCAAATGGTTCAG ref:0:15:G ref:0:15:CACTGC 10 60 +TATCTTAGGT ref:0:10:GTCTTCGAC ref:0:10:TGAGCT 5 5200 +CTTC ref:0:4:GGTGCAGTGGTATAG ref:0:4:GTCGG 2 55 +AGTCACTCGTTCGTGG ref:0:14:GACGG ref:0:16:TTCTAAAAT 5 102 +GGGACTACCG ref:0:10:TAGCGGGAATCTTT ref:0:10:CGGGC 5 1224 +GT ref:0:2:CAGCC ref:0:2:CCCATGACTCTTG 4 9 +AGG ref:0:3:CGCTAAAGGAAAC ref:0:3:AGCGCAGACGC 4 21 +ACTGGGTGATC ref:0:11:TCAGGATCT ref:0:11:CGCGGAAAGTACAAG 4 2067 +AACGTCAGG ref:0:9:CCGTATC ref:0:9:TATCCCCGAACATC 6 13568 +CATGCC ref:0:6:ACGAGAC ref:1:5:AGATAAT 3 195 +AGACG ref:0:4:GATAGTAAT ref:0:5:TTAG 3 80 +C ref:0:1:TCTGCGTTTAGGG ref:0:1:GCGCCA 3 6 +TCCACCCATCCGAT ref:0:13:CCTACGGGTTAG ref:0:14:C 7 6937 +CGTGAACAA ref:0:9:GTGGGACTTGAACAG ref:0:9:GGAAATATG 3 147 +GTCAAGTTCCAA ref:0:12:TGACAAGGGTT ref:0:12:ATTCGCGGGGCTC 7 41202 +GTGATT ref:0:6:TCGATTCCTT ref:0:6:ACCTCCACTGGGGTC 3 72 +TTACAC ref:0:6:CCCGG ref:0:6:ACAGCTTTAGTATCGC 2 252 +G ref:0:1:CCCTTAAGGGGTG ref:0:1:GGTCCTCACAGAG 6 20 +CTCCTGATATTAGAC ref:0:15:ACGACCTCTTACGG ref:0:15:AGCATTGCATTTGGGA 6 1980 +TCAATATTGCCCGA ref:0:14:A ref:0:13:AGGGCGC 9 1984 +CAACGTGATAA ref:0:11:CGGCCATGGCA ref:0:11:A 5 50 +GAAGCGCA ref:0:8:GGAGCCAGGACAAC ref:0:8:T 1 396 +TCTTAC ref:0:6:AGCACGCTTCCCCG ref:0:6:TGATGG 4 15000 +CTACAAT ref:0:7:GGG ref:0:7:TTAATGC 4 1320 +ATTCTTG ref:0:7:CGCCTTAGTGTTAT ref:1:6:GCTT 2 3 +GGACCCTG ref:0:7:ATAC ref:1:5:CTGA 3 29 +T ref:0:1:TAATA ref:0:1:GCCCGGCCAAA 3 24 +AGTCTATCAATTAT ref:0:14:GTGGG ref:0:12:GTTCTGCTG 8 24255 +CGTGTAGTGG ref:0:10:TCC ref:0:10:GTTGATAGCAGTCCG 4 2220 +CCGGCAGCGCCCGACG ref:0:13:TGCCTC ref:0:16:GCGACCAGGAGTA 7 98430 +TAACGTTAGATA ref:1:11:AC ref:0:11:CAGCGTATAGATGG 1 14 +GATCTTGA ref:0:8:TTG ref:1:6:CTGGGGGGTAAGTT 2 3 +GTCGACTTCTACACTG ref:0:16:ACGA ref:0:16:G 13 108 +ATGGAAGCGAGA ref:0:12:GTGGGTGTAAGTCTCA ref:0:12:GACCAAGAAG 3 58280 +CACG ref:1:3:TTAAGTAGTA ref:3:1:AGAGGAT 4 39 +TTGAATCCAAT ref:0:10:CGGCCACCGCA ref:0:11:C 5 852 +CACCAGATTATT ref:0:12:CATTA ref:0:12:GAA 6 7 +GTCGATGGTGACG ref:0:13:ATTTC ref:0:11:GAGCGTTTAG 5 630 +TGCCTACCCA ref:0:10:CT ref:0:10:ACGCT 7 36 +TCGGAGAGGTTCGTA ref:0:15:GA ref:0:15:CAAAGGC 8 66 +GACTTATAGGTCGG ref:0:14:ACAGAAATTTA ref:0:14:AACC 7 182 +GATTGCAAACC ref:0:11:ATATCGACGCCCAGCT ref:0:11:TCCGGAGT 8 836293 +GCCT ref:0:3: ref:0:3:TAC 2 9 +GATGTTGTAGCCGTT ref:0:15:TCAAGGCTTCGAACT ref:0:15:TGAGTGAGT 6 4320 +TAACAATAAATGCG ref:0:14:GTACA ref:0:13:TTCTAAACGAATG 3 40 +CTATCTTGTACG ref:0:12:ACCCGTCCGTTTA ref:1:11:AATGGACCT 3 14560 +TTACCGG ref:0:7:GACTCATC ref:0:7:GGTACTGTTC 6 4392 +CGAAAGATATCGTGCC ref:0:16:AGTGGCGTTC ref:0:16:GGGTA 8 1836 +GAGTATTTCTC ref:0:11:ATTCTT ref:0:11:TGAAGTCGT 4 476 +CGAGCA ref:0:6:CCC ref:0:6:GTCTGCATC 3 70 +TGAA ref:0:4:CCACCAGGCGGAGAC ref:0:4:GGAATGTGC 3 108 +GGACATCTGCTTT ref:0:13:A ref:0:13:GAAACCCGCACGAT 6 10338 +TAAATTTGTC ref:0:9:CTACGAATG ref:0:10:GAGTTAATT 3 210 +CAGAATCTG ref:0:9:GCCTTCAATTATA ref:0:9:TGGTGCAAGTTTT 7 237144 +GTCCGGAAAGA ref:1:10:TTCATCA ref:1:10:ATGATGT 5 3072 +ATATTCGGT ref:0:9:CACAGAAATA ref:1:8:TTACTAGTCTATA 3 476 +GGCCCGCAACCG ref:0:12:GATAAAA ref:0:12:GAGATA 9 19460 +GGTCC ref:0:5:CCCGGCGAGTTAC ref:0:5:TGATCTAT 3 860 +TATTGGTTAG ref:0:10:TGG ref:0:10:CCTCGTGT 6 2871 +TATGTCAGCTCGTAT ref:2:13:GTAAAGCTCTCCTG ref:0:15:TGAACAGC 5 396 +CG ref:0:2:TATGGTATG ref:1:1:TTTTGGTGCA 5 54 +AAATT ref:0:3:TAAAACGC ref:0:4:TAATGGCG 1 16 +AGCGATACCTCA ref:0:12:CCTCTGTC ref:0:12:GCGTTC 5 38 +CAGGGAGAGTGTC ref:0:13:GAGCAATTTAGCG ref:0:12:A 6 822 +TCACGCT ref:0:7:CACGATGAACTA ref:0:7:TAGTCCCGTGC 2 84 +TGCAAAGT ref:1:6: ref:0:8:GTCGCAA 2 3 +TCATC ref:0:5:ACT ref:0:5:GATGACAAGGA 2 124 +GAGCGTTTTTA ref:0:11:TAACGCAGAAACA ref:0:10:C 6 771 +GGTCTGTAAGGG ref:0:12:CACGCGTCA ref:0:12:TAATGG 4 204 +GGTTGTGGAAGA ref:0:12:ATCTGACT ref:0:12:ATATGCG 9 145522 +AAGGCGCCCA ref:0:10:TCTCATATT ref:0:10:TTG 8 8954 +ATCTCAATGTGCAG ref:0:14:GTTCTGCTCCCGCT ref:0:14:AA 4 156 +GT ref:0:1:ATGCCAACACAG ref:0:2:TAAGATG 3 2 +TCAGTTGC ref:1:7:CCCAGTGTTACCCG ref:0:8:GCCACGTGTTTT 4 44100 +AAGGATGTCTTA ref:0:12:CCCGC ref:0:12:GT 9 1254 +AGGTT ref:0:5:CGA ref:0:5:CATCATTGTCTC 2 198 +TGCCGA ref:0:6:C ref:0:6:CGGCTTCTC 3 86 +GCGATGTGC ref:0:9:TACAATCC ref:0:9:TCTGCCATCGCCAAG 5 8010 +TG ref:0:2:TCGGGAAGGTG ref:0:2:AGTGCGGGTTGAG 5 70 +GTTAATTTCG ref:0:10:TTCATTCATA ref:0:10:GGAAAT 3 2835 +TGCGTCGGGTC ref:0:11:AGTGTGCCCAT ref:0:11:TTAGCGGCG 5 92610 +ATAAG ref:0:5:CTAGGAAAC ref:0:5:TTACT 3 2077 +CGCGAA ref:0:6:CATG ref:0:6:ACGAGATCG 4 272 +GCCG ref:0:4:CAGGTTCTCTTACGA ref:0:4:TAAAACGGCTATT 5 816 +CCAGTA ref:1:5:GCTTGAATCCTAT ref:1:5:GCGTAGTAAG 2 36 +CGCCGGG ref:0:7:CTTATA ref:0:7:TACTTGCTGT 6 16744 +CTGTACCTAACGAACG ref:0:16:TCCACTAAGAC ref:0:16:TGGTCTAAA 5 1120 +GT ref:0:2:AGATAGCCACTACCGT ref:0:2:CTATA 3 36 +TCTACGGCC ref:2:7:AGTGATGTA ref:0:9:CTAT 5 534 +ATTCTAAGTAATGTT ref:0:15:CCGTG ref:1:14:TCAACC 8 4224 +GCCTTCACT ref:0:8:AGCATAGTGTAGGG ref:0:8:GGTGTCAACACG 4 1728 +GTATGTTTTAGAA ref:0:13:AGCATGATAGCGT ref:0:13:CCTGGCCCGTTCTC 6 1276860 +CATTG ref:1:4:TTGGTCGGGT ref:1:4:T 1 28 +CCTCAAATACTCTCC ref:0:15:CTT ref:0:15:AGC 11 1536 +CCATGTTC ref:0:8:CGAGAACA ref:0:8:TATTGCACTAGTCCAT 4 1188 +TACTCAG ref:0:7:GAAGC ref:0:7:CATTCCGG 2 174 +AACTTCC ref:0:7:CCAAGGGAC ref:0:7:GTGACG 6 12769 +ACGAAAGGTATGCG ref:0:14:CCTGCCCTGCCCAT ref:0:14:G 9 103915 +GATTC ref:0:5:CAAATGTCACGTAC ref:2:3: 1 51 +GCAACGACC ref:0:9:CT ref:0:9:ACAACGTTTCATCA 3 256 +G ref:0:1:CTCTCGAAGGCTCCGG ref:0:1:TGTACTTCAAGGCTA 9 15 +GGCCCA ref:0:6:TGACG ref:0:6:CATCCAACGGGCTAT 4 4575 +AC ref:0:2:CATTTTTGT ref:0:2:GTCCACCCCATA 2 36 +AGCGAACAGGCGC ref:0:13:TCAATTTTAT ref:0:11:GACCC 4 2520 +CGAG ref:0:4:CCG ref:0:4:GACCCTCCATGGAAGC 1 120 +ACCC ref:0:4:TCGCAGCCCTACTGC ref:0:4:GGCGACTAG 5 420 +TACGCGC ref:0:7:ATAAGTAGTATATT ref:0:7:CCT 2 315 +CGTCTGTGC ref:0:9:CAGA ref:0:9:GCGCCGAG 5 464 +TCTCAGAGTTTTGTTC ref:0:16:AACGTTA ref:1:14:ATAGAT 7 816 +AGTAAGGGAATAA ref:0:13:AGAC ref:0:13:CGCGATT 8 68805 +TATAGCCTACGCG ref:0:12:ACGAAG ref:2:11:CTGTACAC 5 130 +TCGTGAA ref:0:7:GCGAGTAAGTCGA ref:0:7:TTTAT 2 1406 +GCCCCTGTATAACGC ref:0:15:AGCGACACCCTAA ref:0:15:CCGAA 6 936 +GA ref:0:2:AAGAAAATTTGGGCAC ref:0:2:CATTTT 3 16 +AGTC ref:0:4:AATGAGTAGATCTTC ref:0:4:ATGTATGGAGTTGA 6 3496 +TAGGAACGAGGTC ref:1:10:GGAGACTGG ref:0:13:CGGTGGTCTTC 4 2310 +GTTTTGTCCGG ref:0:11:CCTATGAATTCGGGC ref:0:11:GGATGGTG 5 203975 +CGTCACAG ref:0:8:TTCCAACCTC ref:0:8:TCGTTTTCTA 3 14220 +AAC ref:0:3:ATTCTTCTTGTA ref:0:3:TTA 3 48 +CCACCCGTGTAGGT ref:0:14:TTTAATGAGG ref:0:14:GGTTCA 6 715 +CTC ref:0:3:TAA ref:0:3:GGTGACGTTAGCT 1 6 +GG ref:0:2:GGCCCAGTACCAGG ref:0:2:GTCATACAGG 7 30 +TTCTGC ref:0:4:GTGCCACC ref:0:6:CTAGCA 2 62 +TGTTCGGG ref:0:8:G ref:0:8:GATTGT 4 24 +GGACACTA ref:0:8:C ref:0:8:TAGCGAGGGCGC 3 4 +GATC ref:0:4:CGCTAGG ref:0:4:GAGGCAGCATTCC 2 480 +CAAGCTCCCGGCCC ref:0:14:GTGACGCAG ref:0:14:TATACAAGTCCGC 5 4680 +T ref:0:1:GATCTAAGGGAAATG ref:0:1:CGTTGGGTGCG 7 9 +GGTGACCAG ref:0:7:TGTCCTTG ref:0:9:TCCGCTC 3 10 +GGTATCCCTC ref:0:10:TGAGATGGTAAATA ref:0:10:TCCAG 4 40400 +GCCCCGCGAACGG ref:0:13:AGT ref:0:13:ACATC 9 384 +GGCATCTCGATCCGGT ref:0:16:AATGTGCACTCAG ref:0:16:A 7 4 +CTCCCGCTACCACC ref:0:14:AATACATAGGCT ref:0:14:TAAATAGCAGCAGC 11 6730980 +ATGTTGATTTA ref:0:11:ACATGGA ref:1:10:TTGAGATAA 4 804 +CGGCTA ref:0:6:T ref:0:6:GCTCTAATTAGT 2 51 +GTAAAACAAACGCGTT ref:0:16:ATGTCTCATCGGAC ref:0:16:AATTCC 9 187368 +TTCAACATTATCTGT ref:0:15:GGGA ref:0:15:TAGATGAGGTCCTTCT 8 273060 +TAGACTGTTC ref:0:10:GAGTAT ref:0:10:AAAAATT 4 232 +GTCCTT ref:0:6:ACAGATCGCGT ref:1:5:TCTCCTG 1 45 +CGCTGG ref:0:6:CT ref:0:4:AGTGCTAACCAC 1 12 +GACGT ref:0:5:TGTCCCAA ref:0:5:GTAGTAGTGGT 3 3948 +AACCGAGGGGGGCT ref:0:14:ATCAATT ref:0:14:GTGTCTAGGGTCGA 8 15437044 +TACATAGG ref:0:8:TTGCCTTATG ref:1:7:GGAAGAGGTCGACC 2 972 +AA ref:0:2:T ref:0:2:TATGTGGCGC 2 33 +C ref:0:0:AGGGTTT ref:0:1:TCGCGGAGT 1 2 +TCCACAAGGCGA ref:0:12:CGAATGAGAAAGTC ref:3:9:CCT 2 9 +GCTGATGGA ref:0:9:CCTC ref:0:8:CA 5 45 +GACCGATAGA ref:0:10:GGATATAGG ref:2:8:GCAGCACCTCCA 2 1330 +TTTATTTCCAGGG ref:0:13:AGTCAGGGATCGAAA ref:0:13:TTTTGT 4 4656 +GACTGGGACACACT ref:0:14:TAGTACCCCCTTC ref:0:14:AACGTAA 6 94956 +G ref:0:1:CAATATTGGC ref:0:1:GTCACTTG 4 4 +ATGGG ref:0:5:TGCGCTTC ref:0:5:TCTGTCGTTAGAA 4 32 +AGAC ref:1:3:GG ref:0:4:A 2 8 +TCTGGTGCCTGCCTTT ref:0:16:GCGACGCACCCGG ref:0:16:GAGCTTT 7 21620 +T ref:0:1:ACAAGCTGATGTTTC ref:0:1:ACTATAAGGGG 5 10 +AGCCGATGTAGCTCTT ref:0:16:CGGCAGTTCAGATGGG ref:0:16:CTTGGCTAA 8 1463748 +CGC ref:0:3:TGCTTA ref:0:3:ATCTTGCCGCCA 2 20 +AGGAACCAAGT ref:0:11:TATTTTTATTCCAGCC ref:0:11:CCTGCTTGACGTTAC 6 23616 +CACCTCAAACTTC ref:0:13:T ref:0:13:CA 10 39 +G ref:0:1:GATCTCAGA ref:0:1:CGCTTATCATAATTC 6 2 +GTT ref:0:3:GCG ref:0:3:TA 1 21 +GGACGTAGCTATCC ref:0:14:TGTCAATCTACGGCG ref:0:14:TTCTGACGTAGG 5 7440 +AGCAGCGAGAATGCC ref:0:15:CAACG ref:0:15:GCG 10 640 +CTAGGAGGGGCCCCCT ref:2:14:GATTCCCGACAAA ref:0:16:GCATAA 7 1068 +ACAGAAATCCC ref:0:11:G ref:0:11:GTTGG 9 60 +CATTCCCCTGTCACC ref:0:15:GCCTCTGCAGCTT ref:2:13:CCCG 5 1280 +CGATTT ref:0:6:GGAT ref:0:4:AAATGTATGACG 1 45 +ATATTGACAT ref:0:10:GG ref:0:10:GAAGGGA 7 341 +TAAGCTG ref:0:7:CAG ref:0:7:GGGAACAGTACCTCA 3 936 +ACGGAAT ref:0:7:CGGTTTGTAATGAC ref:0:6:TTCATTGAAC 3 72 +TTTTCCGCCTAACACT ref:0:16:CTACAACCCGG ref:0:16:AAATTCACTTG 10 4545816 +CTGTCGGCATACA ref:0:11:AGTTTAAA ref:0:13:CCAAAACGTACCT 6 830060 +TCCAGAGTGGGCC ref:0:13:ATCTTCA ref:0:13:GAC 8 126 +GCACACGGAGG ref:0:11:TGGCG ref:0:11:CACTTGCTCA 6 9744 +AGA ref:0:3:AAGTTTCGAGTAA ref:0:3:CTGATT 2 54 +TGTGCTCCACTTCGC ref:0:15:CTCGATACGCTCA ref:0:15:TAAGCT 9 2880 +GATGCTACCTGTCTC ref:0:15:GGGATCCGGCAAG ref:1:14:CATTTTGGCTCTA 6 93312 +GCTACGTCAT ref:0:10:ACGTACC ref:2:8:AACGGATTAAC 4 1560 +T ref:0:1:ACCGTAACGCTTAGG ref:0:1:CTAGGCTG 6 6 +GCCATGCGTCTAG ref:0:13:ATACGCT ref:0:13:TTA 6 6 +GAAGTTTACGGCGAT ref:0:15:CTGGCTGCCTGGGCCC ref:0:14:TGTAAACATAGG 6 795555 +CGGTGCTTGTAACG ref:0:14:ATG ref:0:14:ATGAGTATTGCCCCCC 8 129276 +CCAGAGCG ref:0:6:CA ref:0:8:CATGTGAT 3 256 +AGGGAACG ref:0:6:CGA ref:1:7:CCAACTTC 3 900 +GGCAT ref:0:5:TCGCACTCGTCG ref:0:5:AGGTCTTTA 1 56 +AGGACT ref:0:6:CTTGCTTAAGTAG ref:0:5:TAAAGAAATGTACC 4 1356 +TAAACCGAGT ref:0:10:TGGTGTTTACG ref:0:10:GAAGGCTTTATC 9 125028 +AG ref:0:2:GTGTGACGAATATG ref:0:2:TGAATATCTCCTA 6 160 +TGACACAGGAT ref:0:10:CCTCGGGCTCAGGC ref:0:10:CAAGCCC 3 336 +CGTCAATTTG ref:0:10:TATGTC ref:0:10:TC 5 24 +TTACCGCCTTT ref:0:11:CTACGGATTAC ref:0:11:GAATGTCTAC 7 565848 +CT ref:0:2:TCTTGC ref:0:0:TGTA 1 2 +CGTTCCTGAGA ref:0:11:AGAAA ref:0:11:AGCGTTGTC 5 3410 +AAACTTCCCAGTT ref:0:13:GGTACAAAGAGCGACA ref:0:13:TGACGCGCGG 9 743250 +TCT ref:0:3:GTGGCCTCAGAG ref:0:3:CTCAGATCGTA 3 8 +C ref:0:1:ACCCTCTCTCG ref:0:1:ACGATAGGACCGTCAC 6 30 +ATAACTT ref:0:7:T ref:0:7:GCGCGACAGTGGGCC 4 4026 +GGCACACGGG ref:0:10:GTTA ref:0:10:GCC 6 204 +AACGCAGAGCACCA ref:0:14:AGCGTCGCGATTC ref:0:14:GTG 7 720 +GAGAA ref:1:4:CTCATTGGCAATT ref:0:5:TATTGGCA 5 34 +ACCGTGA ref:0:7:CCGAAACCCTACC ref:0:7:GGAA 1 26 +ACTATGTGAC ref:0:10:TCTTGGGTCCC ref:0:10:GTTGGGATG 5 6210 +AGCCATCGTTA ref:0:11:CAGCTATCTCCC ref:2:9:ACCCGGCCGGGC 5 95676 +A ref:0:1:GCCACGATTGAGAG ref:0:1:CGTTCATC 4 4 +GAGCA ref:1:4:G ref:0:5:TTCTTGAGACTG 1 4 +AGTAGGGTA ref:0:9:CCCTC ref:0:9:CCGCCC 11 491350 +ACTCACCCGGGTTGA ref:0:15:TCAACTCC ref:1:14:CACCGAA 6 240 +AGA ref:0:3:GTGGTGACGGCCT ref:0:3:GGCCTT 5 368 +GGGCGCAGAAATCAT ref:0:15:G ref:0:15:TAACGGCG 11 710 +ACCGCTCAGAATT ref:0:13:GAATAG ref:1:12:AGACT 7 224 +GAAGCTCGTTAG ref:0:12:ACCTGAAAATCC ref:0:12:ATGT 7 6160 +TA ref:0:2:TTC ref:0:2:TTTTAGTG 1 20 +CTC ref:0:3:TCACGCCGT ref:0:3:TACTTTCACGGG 4 150 +TCT ref:0:3:CATACACGCAAGGAC ref:0:3:GCAAAAGAA 7 464 +CTGG ref:0:4:GACCTCGTAT ref:1:3:AGA 2 84 +GTGCACCCCG ref:0:10:AGTTTTTATAGCC ref:0:10:AGCGGGGACTGTGCGG 5 5033280 +GTC ref:0:3:TTTTCGCCAA ref:0:3:GTGACGGCATTGTATC 4 693 +GA ref:0:2:AGTAATAG ref:0:2:TATTTCCTGGGAGATA 4 33 +ACA ref:0:3:CGCGGAGAGT ref:1:2:TCG 1 20 +ACTAAGCA ref:0:8:GATGCCCTCCTAACTG ref:1:7:TGTTCTACCC 5 832 +GTA ref:0:3:GTTTTTTGTT ref:0:3:GGGGGGAA 1 2160 +GT ref:0:2:GGGGTACCAC ref:0:2:AACAACTACGTA 1 4 +A ref:0:1:CTAATGCT ref:1:0:CGCCCG 2 2 +TCGATCCTTTCA ref:1:11:GTAGTTAG ref:0:12:TCTAACAG 6 4212 +ATCTGTCATCTTA ref:0:13:CTCACTAATCTC ref:0:13:TTGGTAGGGGAC 5 107092 +AAGCCGTTCCT ref:0:11:CTGCGATCG ref:0:11:CTCACCTGGCTAAGAC 6 103350 +TAC ref:0:3:ACTTAG ref:0:3:G 2 20 +CACCGACGTTCCAG ref:0:14:TATCGAT ref:0:14:GGAT 9 204 +TTCTCTCGATAGAT ref:0:11:GAT ref:2:12:GGCTTCCTGG 2 38 +TATCGAGA ref:0:8:CGGGAC ref:0:8:AAAACGTATCAGGACT 2 12 +GCGACATCCGCTGCGT ref:2:14:TAAGCAC ref:0:16:ATGTGAGAAATC 5 24 +CACGTCGCAACC ref:0:12:TTA ref:0:12:TG 9 19 +GTGAAACAAACC ref:0:12:GAGTAGA ref:0:12:CGGC 7 1680 +AAATCCTACT ref:0:10:GCATCATCCGAATA ref:0:10:GTCAGTT 4 3136 +TTTTAGCGC ref:0:9:TTGACTCTCAA ref:0:9:GCCTCCGCTA 6 32175 +GTTGTGT ref:1:6:AGCTTCC ref:1:6:GAACAACGA 3 42 +GACGCATAGATGGAAG ref:0:15:CGGTAC ref:0:16:AAAGA 7 57 +GCTAACGAGTCGT ref:0:11:TGGTAT ref:0:13:TGAGTATTACACCA 5 1140 +GAAGGAGACCAAT ref:0:13:GCGAAGAGATGACGC ref:0:13:CAAGTCCTCGACGAC 4 8 +ATGATT ref:0:6:TGCATTG ref:0:6:TAATCGCAACAGATC 1 52 +CCGAACCGGAAGG ref:0:13:GGGACTTTG ref:0:11:CGACTCTACT 5 1352 +GTAT ref:0:3:ACTTGTGG ref:0:4:CAAA 1 93 +AGATA ref:0:5:AAGCATGTGCAT ref:0:5:GCAGAAACCCT 1 28 +GCCCGTCTTGGGAC ref:0:14:AACAT ref:1:13:CCGGTTACA 7 11799 +CAACAACCACCT ref:0:12:CCAAAACGGAGCCCCC ref:0:12:TACGAA 3 14360 +TTAGTGCATGCCA ref:0:13:TGGTCGGCT ref:0:12:GGGGGTGC 6 91410 +CGTACTTGTAC ref:0:11:GAATACCC ref:0:11:GCTATTTCGT 3 560 +TA ref:0:2:CACGTC ref:0:2:GAG 2 8 +GGAGGACCC ref:0:9:TAA ref:0:9:G 6 12 +CCCTGGATATTTTAT ref:0:15:GCGTTGTGCGAGG ref:0:15:CT 9 29484 +G ref:0:1:CACTTACCCCTATGTC ref:0:1:CGTCAGTATTGACC 7 3 +AGTTG ref:0:5:CGAGTTAACT ref:0:5:G 1 14 +AGCGGGCCTTACGC ref:0:14:TTAAACTTGTA ref:1:13:TTTATAA 10 288325 +AGGCTACGTCTGGGC ref:0:15:GATGCCAAGTTCT ref:0:15:GTACTTCGG 4 4056 +ACCGTGTTAACA ref:0:12:TACACGTGAACCT ref:1:11:TCC 4 115 +CG ref:0:2:ATGACA ref:0:2:TACGGTCTGA 3 20 +CGCCATGA ref:0:8:CTATC ref:0:8:CAATTTTC 6 8232 +TG ref:1:1:GGCGCAGGGGC ref:0:2:GACAACT 3 14 +ACGG ref:1:3:CCCATTT ref:1:3:GTC 2 320 +CGAACGTCAA ref:0:10:CT ref:0:10:GCGCGATCCTTTAGT 3 30 +TCAT ref:0:4:ATGCAACCCCTT ref:1:3:GCTTT 2 24 +G ref:0:1:ATGTAGTCACT ref:0:1:AGGG 2 6 +TTGA ref:0:4:ATAA ref:0:4:AGGAGCGAGTCT 3 620 +C ref:0:1:TG ref:0:1:CTTCCCTC 1 15 +GAAAAGTGGGTGCAC ref:0:15:CTCAACAG ref:0:15:CTA 12 5130 +AAGCAGGGATGTCGG ref:0:15:TAAGGTGGGCGGG ref:0:15:ACGCCTAACGAACAC 2 21708 +ATGACGCGTGCACG ref:0:14:A ref:0:14:GTTG 10 126 +TTGGCATCAATCC ref:0:13:ATTCATTCACCAA ref:0:13:AAGT 3 16 +AGCTTAATGATGTGGA ref:0:16:GTGC ref:0:16:GGA 12 979 +TTCACCCC ref:0:8:CTCGGGGGATGCAT ref:0:8:A 4 173 +ATTCCGGTGCTCGCGG ref:0:16:CACGCAAGG ref:0:16:GGGACCCCGCCG 7 21777 +CGAGT ref:0:5:TG ref:1:4:TC 3 7 +ATGG ref:0:2:CA ref:0:4:CACAATC 1 9 +AA ref:0:2:AAGAC ref:0:2:GGGCA 1 18 +TC ref:0:2:AGACCCCTCATCAG ref:0:2:ATGGCAGCCAG 5 9 +CGATGACGTACCCGAA ref:0:16:CG ref:1:15:TTGGCGGAAG 8 441 +GCAGCGGTGGA ref:0:11:CCCGGAAAAACCCA ref:0:11:GT 5 7416 +ACACA ref:0:5:CGAGCTAACTAGAG ref:0:5:GGGTGG 5 1848 +T ref:0:1:CCACTCTA ref:0:1:ATTGCAAGTAA 4 6 +CGACGTTTATTCATT ref:0:15:G ref:0:15:GCGGC 11 18 +TGAGGCG ref:1:6:GCC ref:0:7:TTCCGAT 4 468 +GAAATAATCTTTA ref:0:13:CAGCCGTTTTGAGTCG ref:0:13:TC 6 5200 +GGTCGTAGCTA ref:0:11:GTCAACACGGT ref:1:10:CGCGAGGAGGAGACT 4 7380 +GACGTTCCATA ref:0:11:TCCCAGGTGGGT ref:0:11:AGTGTAGACTCTGG 5 180 +ATA ref:0:3:CCAG ref:0:3:CCATTGGCCTGTAACA 3 108 +GCTAAAG ref:0:6:AACCGGCAT ref:0:7:TGT 3 30 +CAC ref:0:3:AGAAA ref:0:3:G 3 108 +CTAAAAAG ref:0:8:ATGCACAAA ref:1:7:AGACTTCATC 4 3818 +GAGAAGT ref:0:6: ref:0:7:ACTAAGATAT 2 16 +ACTCCGGGGCCG ref:0:12:TGGTAA ref:0:12:GC 8 1520 +AGTG ref:0:4:GGACACGACGAG ref:0:4:CTAG 2 110 +GATCGTCCAGCTAT ref:0:12:GGACGGC ref:0:14:CAGCTCG 5 80 +GGTGATAGTCGAGT ref:0:14:GGCCGTCGTATCTATC ref:0:14:GGT 4 150 +ACGCAAAGCGGAT ref:0:13:CCTAAGATGGC ref:0:13:GCACACACAAC 5 726 +G ref:0:1:GCGAGACAAA ref:0:1:C 1 6 +GCCTG ref:0:5:ATGATATGTCC ref:1:4:CGG 1 105 +GGAATGCGT ref:0:9:CGAAAACATCTTCAA ref:2:7:ATAATCGAC 3 1440 +GGGAATACCCGCAGGA ref:0:15:AGTGTATGTA ref:0:16:CCTT 9 10138 +ACCGCGATGCG ref:0:11:TGCCATAA ref:0:11:AAGCCCTACGTTCCGA 5 70560 +ACGATGCGTTTCTCTC ref:0:16:C ref:2:14:ATAGGGC 9 135 +AGGTCGCATC ref:0:10:TTTACTTGCA ref:0:10:A 5 56 +TAGAACA ref:1:5:CCATGGGCTGCCT ref:0:7:GAGT 3 3348 +CGCGTGCCT ref:0:9:ACCTACGTGGCTC ref:0:9:CA 3 1176 +AACGAAATTG ref:0:10:TAGGCT ref:0:10:CATCCAGCTGACC 7 92865 +CT ref:0:2:G ref:0:2:AGCTGGCGCAATC 1 12 +TGAATATTAT ref:0:10:GCGTTGGAA ref:0:10:ATGCGAAGTTG 6 19656 +TACAATAGGCA ref:0:11:TTTGAGATTTTCATGT ref:0:11:CT 5 3219 +AAATAC ref:0:5:TTCCAT ref:0:6:TCGCTTGG 4 104 +TAAATC ref:0:6:AGA ref:0:5:CGACCATAAGA 2 4 +GTCTTATAAGATCCTA ref:1:15:ACAACGATCG ref:0:16:ATGCTG 7 280 +CAGACGGGGCAA ref:0:12:AATTGCCCATG ref:0:12:GGTAGAGG 5 49545 +AT ref:0:2:C ref:0:0:TTGGGTC 1 3 +CATATCATG ref:0:9:TCTGCCGCATGC ref:0:8:T 3 99 +GGTAGCATAC ref:0:10:ATTCCAACT ref:0:9:GC 4 174 +AGCTCGT ref:0:7:TTCG ref:0:7:AAAAGGG 2 140 +TCTGC ref:0:5:G ref:0:5:ACCTGGCACTAT 1 20 +AAACTGATGCA ref:0:11:TCTCGGGTG ref:0:11:GATGCATA 3 192 +TAGAACCCGGGTTAAT ref:0:16:GAGATAATAT ref:0:16:G 9 1156 +GGGTAATAT ref:0:9:AGAAG ref:0:9:CGCACAATGACCCGTT 4 8400 +TC ref:0:1:AGGAGATGTT ref:0:2:AAGCTAA 3 21 +GGC ref:0:3:TATTTA ref:0:3:CTTCGAT 5 2688 +GGCTAGTCGAGGAATT ref:0:16:CGAGTTCCTTCATATC ref:0:16:GCCCTCCTTG 8 20898 +CAGAAAAACGTAGC ref:1:13:GCCTCT ref:0:14:TGGAGTTATG 5 1200 +TACTCACCGG ref:0:10:TTCCA ref:0:10:TG 5 60 +GCACCCAAGAGAG ref:1:12:AGCGGCCG ref:1:12:TATGCGGAC 8 840 +CTTCTACCATAC ref:0:12:TCTA ref:0:12:CGTATATGTCC 5 10836 +TTTTGGT ref:0:7:AC ref:0:7:GTGAGA 5 720 +CTTATCATCTTTG ref:0:13:AGCAGGGCGGATAGA ref:1:12:AAA 8 2756 +TTTATACCACACCGGT ref:0:16:TTT ref:0:16:ACCCGCCACGGCTCTG 5 3000 +CAATCGCGATG ref:0:11:CGAGAACTGT ref:0:11:ACCTGCGGATA 3 5680 +AAGGGATCGATGTGA ref:0:15:TCCGG ref:0:15:AGACCGCGTTATT 7 3627 +CGTCTCACG ref:0:9:AATAGTTATAGC ref:2:5:AG 3 100 +AATATTT ref:0:7:CAGACTGCTTTTATTC ref:0:7:T 1 464 +CGAGTTATC ref:3:6:AT ref:0:9:TATCACGCATGATAAG 3 139 +GGTCGAAAG ref:0:9:GTGCGACTGATCA ref:0:9:GTTATTTTTCCCG 4 4431 +GACGTTG ref:0:7:CCTAGC ref:1:6:CCGTTTT 2 480 +T ref:0:1:TGAATACG ref:0:1:CTATCACGAAATG 5 6 +GACACTGTTTTGAA ref:1:13:CCTTGACG ref:0:14:CTTGCGAG 8 16000 +ATTCTATGTCACAT ref:1:12:CCCTTCGAAGCG ref:0:14:AACTTCATACGCGC 7 4200 +CAAC ref:0:4:CCAAGAGCCTTATC ref:1:3:TAACGGACTA 4 96 +GTCTCGGT ref:0:8:GGCGGCCGTCAGCTC ref:0:8:ATTCTGGCTTATA 1 3297 +CGGGCGACGCCTAAGC ref:0:15:GAGTGT ref:1:15:CGAGTTCCACGT 6 32 +TGACCTCAGAC ref:0:11:ATCAATCCGG ref:0:11:CGGTATGGAGTT 4 648 +GACGGGA ref:0:7:CGAA ref:0:6:CCTCC 4 1500 +CGCAGCGAGG ref:0:10:CAGCCATCCGC ref:0:10:AGGGAACGAGGGG 2 61912 +TTCCCCCACGA ref:0:11:ACGCTCAAATTGTGGG ref:0:11:AATGAAA 8 4314700 +TTCACGTTCAGCCCCT ref:0:16:GAGAACAA ref:0:16:CCTCAGTA 8 2486 +AGGG ref:0:4:CGTCTCAACTTT ref:0:4:ACAAGTACGATC 6 8060 +TACCCATC ref:0:8:ATCCGCTTT ref:0:8:ATGT 5 560 +TGCTCTTT ref:0:8:CCATCGC ref:0:8:CCGTCATGCTTGACTC 5 276 +GAGCTGTGCCA ref:0:11:AAACTGAT ref:0:11:TGC 5 240 +TACCCCGAGCTACA ref:0:14:GAGATTCAAC ref:0:14:TC 8 721 +GCCCCCATGGTG ref:0:11:ATAAAAATCT ref:0:12:TCTT 8 103680 +CCCTGCTG ref:0:7:ACTGC ref:0:8:GGGCCGGT 2 186 +AAGAACTTTGCGATG ref:0:15:GAGCCTTA ref:0:15:ACGGTTTGG 6 3780 +ACAAAGTCCTTGA ref:0:13:GTGGATATTTTG ref:0:11:TATCACGGGTCAA 5 319920 +ATGTGT ref:0:6:GCCC ref:0:6:GTATCCGAAA 5 1776 +GTTTCCTCGTCAAC ref:0:14:ATCA ref:0:14:ATGAGGGCCGAG 10 310800 +AG ref:0:2:GAAGTACGCAGAG ref:0:2:CACTTGTCCG 4 28 +G ref:0:1:CACTGCGGCT ref:0:1:TAGGTACT 4 6 +G ref:0:1:GTTTCGGCT ref:0:1:CTGACGGTAGCGCCAC 4 15 +ACTCGCGTAT ref:0:10:TGAACTA ref:0:10:CGGCCCTA 4 58 +GATAGG ref:0:6:TGGTATCCG ref:2:4:TT 2 165 +GGTTACTCCGAA ref:0:12:TCAACGTAAT ref:0:12:AACCGCTGGAGGT 6 4224 +TTAGTTCGC ref:0:9:ACCTCCTAAGTCTT ref:0:7:ACCGTGT 1 40 +CCACCCTA ref:0:8:GCCTGCC ref:0:8:CTAAGG 3 195 +CCTGGATTAGA ref:0:11:GACTG ref:0:11:GCACAGGGACA 4 516 +CCTCG ref:0:5:GTCATC ref:0:5:AGA 2 25 +GAAAGGAATGTATC ref:0:14:GGGTTAAGAATT ref:0:14:ACCTGCAAA 5 7552 +AGCAGAGTAA ref:0:10:TAAAATAAACT ref:0:10:TACTTA 4 312 +GCAACTCT ref:0:7:GGATCC ref:0:8:TTTTAGGCGCT 4 4608 +TTC ref:0:3:TCTCTCTACGGCTTC ref:0:3:TCCGACAAA 3 341 +TT ref:0:2:CAAGAGCACC ref:0:2:AGCG 5 990 +GAGGC ref:0:5:TTTGTCCAGACGCTG ref:0:5:ATCGCCCA 1 15 +TTG ref:0:3:CAAGCA ref:0:3:CCAACTTCCCCCC 4 70 +GGATG ref:0:5:AAGG ref:0:5:ACCTTGCA 2 38 +ACCCCCCATCATCAA ref:0:15:TC ref:0:15:GAAGGTATCAAA 7 9 +CTACGAGTGCAGGA ref:0:14:ACACCACGAA ref:0:14:ATACCTTCTTATC 7 72720 +G ref:0:1:CA ref:0:1:CGCCGCCCTTGAA 2 9 +TCC ref:0:3:G ref:0:3:ACGGT 3 48 +TCACCC ref:0:6:CAGATCTCATT ref:0:6:GCCAATAA 5 7110 +CATGGTGTTACG ref:0:12:GCGC ref:0:12:GTGTTTCTCTGTA 5 1116 +ACATGTG ref:0:7:TTTA ref:0:7:TCCA 4 75 +ATGT ref:0:4:GGTCAATTCCCTTGCG ref:0:4:GGGTCTG 5 2888 +AGCATGGATTGGGA ref:0:14:T ref:0:14:A 12 12 +TG ref:0:2:CACCATTGG ref:0:2:CCTGACCTCG 4 12 +ATCCACTCAGA ref:0:11:CAG ref:0:9:TTAAGTC 4 246 +ACCC ref:0:4:AGTACCAGGCA ref:0:4:TGCCTTGTG 3 54 +TGAGATT ref:0:7:TATATTTGTCTACCA ref:0:7:GATACATC 4 925 +AAATAAAGGGTTGG ref:0:14:CAGTATGATTCCG ref:0:14:TATGGCGTCGTA 7 491232 +AAGATAGCT ref:0:9:TTCGTTGCGGTTGT ref:0:9:CTTTTAGGTTC 8 168360 +ACGGTTACAGGT ref:0:12:GGACAC ref:1:10:GCGCA 5 12 +CGTTCCA ref:0:6:C ref:0:7:TGG 4 120 +GAT ref:0:3:AAGACCCAGTATTTAC ref:0:3:TGATC 1 14 +CCCTTACTTT ref:0:10:TAAAT ref:0:10:CGT 6 6468 +CCTT ref:0:4:CGTCGACGA ref:0:4:GT 3 413 +GCT ref:0:3:AAGGATAAGTATTT ref:0:3:TACGTA 4 352 +GAACAATTGGCC ref:0:12:CAGCGGCAGGAGTAC ref:0:12:ACTG 5 28144 +TATCCTTCGATCG ref:0:13:A ref:0:13:TTCCG 7 28 +AAGGCCCAATAATGT ref:0:15:CGTCCTACAGAGTTGA ref:0:15:CGTTA 8 6380 +GTG ref:0:3:ACT ref:0:3:TCCTTC 3 84 +TTGACTATAT ref:0:10:CAGTACTAACGGCAAG ref:0:10:ACA 4 1590 +GTAGTACAACTGTTA ref:0:15:TACGGAATAA ref:0:14:ATCC 6 143 +C ref:0:1:GCAACCATGAACACG ref:0:1:GACACTTACGAAGAAC 9 20 +CGGT ref:1:3:G ref:0:3: 1 2 +GAGCAGGTAGG ref:0:11:ACTCTAAATCCTT ref:2:9:GTGTCGGGTAAACG 6 394944 +ATTCTCCAG ref:0:9:TGCA ref:0:9:AAGAAGG 5 6578 +CGGGCTTGAGACA ref:1:12:GTCC ref:0:13:AG 7 51 +GTGCCTAGAAG ref:0:11:ACCC ref:0:11:GCTCTATTCAAT 5 1344 +ATGTTCGGTTG ref:1:9:GTGAGGCT ref:0:11:GTCCGAACTGTC 5 9752 +AGAAATCCTCCG ref:0:12:GTGCGCGGTCGAACC ref:0:12:TATA 6 1062 +TCCTTTGGTAAA ref:0:12:AGCCTCTAG ref:0:12:T 7 1650 +TAGAGAAG ref:0:8:ATTAATGCTA ref:0:8:GTCGGGGGGGGCTGC 3 38928 +AGCTCATAATTTTGA ref:1:12:GGCCAACATT ref:0:15:GGCTCATGC 4 936 +GTG ref:0:3:ATGGACT ref:0:3:ACGCTATCATAACAGC 3 21 +CTAGGGTTCTTCTTT ref:0:15:AAGGCCGCCCAT ref:0:15:TCCAGG 7 2208 +TCCGAT ref:0:6:T ref:0:6:CTGC 4 36 +CGTACGATCAGGC ref:1:12:ATGAAGAATT ref:1:12:AAACCCGTGT 8 142080 +CCC ref:0:3:ACTTGCTCTCCTGGTC ref:0:3:AAG 2 400 +TGCAAA ref:0:6:GCAAGCCAG ref:1:5:GCGC 2 12 +TGACCCCCAC ref:0:10:CGCTCA ref:1:9:CAACGGCGATTTA 6 196908 +GACTCAATGG ref:0:10:AACGGGGAGAGCGTA ref:0:10:TACTTGCGAC 4 100 +TCT ref:0:2:CGGGAGGGCAAGAA ref:0:3:TCTCGTACAATAGC 5 100 +TTGTGCATCTTATCG ref:0:15:ACTTAGCTGTGAAAAA ref:0:15:GATTTCCA 7 512193 +CCGCC ref:0:5:AAGCCAGTGAAAT ref:0:5:TCATCAGCAGA 5 245 +TCGGT ref:0:5:GGCG ref:1:4:GCTGAGGA 2 91 +AG ref:0:1:TC ref:0:2:CGACTACCA 2 42 +CAAATTTGTGA ref:0:11:AACCAGTTCGT ref:1:10:AAACC 4 195 +TTCATTGCTA ref:0:10:ACT ref:0:10:CA 6 3 +AGACTGTAACACAG ref:0:14:G ref:0:13:CCTC 10 78 +CGGTT ref:0:5:TGCTGTCCA ref:0:5:GACGCTCGC 5 858 +CTGGAACAGAGCC ref:0:13:CCCTCCGAAACAG ref:0:13:GCCTTTTTCAG 6 106596 +AATGGAGCTCACAAA ref:0:15:ATGATCCAT ref:0:15:TA 7 216 +CGTGCTCCTA ref:0:10:CCCTGTAG ref:0:10:TTTC 4 680 +ACTGTACAACC ref:0:11:G ref:0:11:TCGGTAATCGCTGG 4 32 +TGACGTATTATGGTAG ref:0:15:ACTTCTAGT ref:0:16:CGAGTCAACACGCTA 4 324 +A ref:0:0:GTG ref:0:1:GGAGGAAGTC 2 3 +AGCGCGTACCAATGG ref:0:15:TTG ref:1:14:AC 9 4 +GGGTGCGG ref:0:8:CTCTTCGACCGAAATA ref:0:8:TAGTACTGTCACAC 8 1339660 +TA ref:0:2:TCTACGTATACCAT ref:0:2:CAATG 3 91 +CATCTAGAC ref:0:8:TCCAATA ref:0:9:CCCGCGCGTTC 4 97216 +CGGCCCTCACT ref:0:11:G ref:0:11:CTGAATT 7 366 +CCGAAT ref:0:6:TG ref:0:6:CTC 4 12 +C ref:0:1:AACGGCTATCGGGGCA ref:0:1:GTTTAGGCCC 5 12 +ACCGCTA ref:1:5:CTTG ref:0:7:CTCCTCAGATG 3 30 +AATCAAGGT ref:0:9:GTCTCCTAAATCGCAC ref:0:8:GTTTA 7 176715 +CTGCGCCCGAGAAGAG ref:0:16:TAACGAGGTAGCTC ref:0:16:AAGCCCG 7 8112 +GTTGAACGT ref:0:9:ACTTCACCGCAGG ref:0:9:GATCACA 6 29376 +TTAGTCAGGCGGCG ref:3:10:GGTCACCTCAC ref:0:14:TTCTTGATGGT 4 782236 +TATTACGTTTTG ref:0:12:ATACC ref:0:12:GGATCAATACAAGCA 7 5376 +GGTGGATAGTTA ref:0:12:TGATCAGCGGAGC ref:0:12:CTGAAGACCCATTG 5 1008 +GGCGACAGAT ref:0:10:GAATTAGGTGGTGTC ref:0:10:CGTCCGACTAG 3 15120 +CCTCAAAGCGGGCC ref:0:14:TCT ref:0:14:CAGTCTAAA 9 115 +GAACCTGGGTA ref:0:11:AC ref:0:10:ATCTC 7 236 +TAGATGG ref:0:7:GTTGC ref:0:7:GGCCC 5 78 +CGGGGGGACAAGA ref:0:13:AC ref:0:13:CG 10 8 +AATACTGTA ref:0:9:AGAAACT ref:0:9:TCCATGTGACGATAAA 2 360 +AGGGTAAACACCGTT ref:0:15:GTGACCCGTCGCTT ref:1:14:TAAGTCTG 5 1584 +TCATGAAG ref:0:8:TGACC ref:0:8:ATCATA 2 36 +ATTT ref:0:4:AATCATTATCTTCCGT ref:0:4:TCAGTCGCAGAA 5 6392 +AGAAGGAGC ref:0:8: ref:2:7:AGCCTGAGAAAAA 1 12 +TTGTACTCA ref:0:9:AC ref:0:9:GT 5 4 +GGCG ref:0:4:TATTCACAGTGGCCCC ref:0:4:AT 3 465 +GGGAAGTGGCTTGG ref:0:14:AACTTTCCCC ref:0:14:AC 9 162 +ACTACTGGAGATTG ref:1:13:TCGCCGG ref:0:14:GCGCTTTTA 4 1386 +AT ref:0:2:GATTTGAGTGTCAGT ref:0:2:TTATGATAG 6 30 +TCGCTGGCGGGA ref:0:12:AT ref:0:12:ACACCTTGTGGC 7 12796 +CTCTTATCAA ref:0:10:GCTTTGGCAAGGAGTT ref:0:10:TGTGGTTTT 5 6586 +AGCCGA ref:0:6:CCGTAGGACTG ref:0:6:GTGAG 3 42 +TCTTTGTCCTT ref:0:11:GCGCTCTGCGGGA ref:0:11:TGAGGG 9 2318860 +GATGCGGC ref:0:8:TTTGT ref:0:8:ATCGCCCTTA 4 2380 +AGGCCTGGAG ref:0:9:TGTCGTCCCGACC ref:1:9:CAC 3 90 +TCTGAC ref:0:6:AAAAAAG ref:0:6:ACCTGGTCCTT 3 47880 +GCTGCAGAAGACTAG ref:0:15:GGCTTTCAGTCTA ref:0:15:CCAAAACC 3 660 +TACTGGTCTGATCC ref:0:14:TGT ref:0:14:AGCCA 8 336 +TAGGACAG ref:0:8:C ref:0:8:AT 6 14 +TACGTTTC ref:0:7:CCTAAGCGAATA ref:0:8:ACAAAAG 2 30 +ATTTAG ref:0:6:GGAAGT ref:1:5:TAA 2 12 +AGCCCG ref:0:6:TG ref:0:6:GTGCGATG 4 736 +TTAAGTTATACTCTTT ref:0:16:CGCCGTTACCATTCC ref:0:16:ACTACATGAGCTT 7 4463694 +GACCA ref:0:5:CGCT ref:0:5:ATCGAA 2 70 +GCCGATAGCCTAA ref:0:13:T ref:0:13:A 11 8 +TTTCTTA ref:0:7:TTACAGCCAG ref:0:7:AAATAC 4 11811 +ACATTGTAGC ref:0:10:CGAGAGTGGATATA ref:1:9:AGT 4 264 +TCGTCTCTATCGCGC ref:0:15:GAGTCGAGT ref:0:15:CTTATTT 7 560 +TGCTTGGTTCCC ref:0:12:T ref:1:11:AAGTTCGGGG 6 180 +TTGTAACAGC ref:0:10:CATGGAGCATAT ref:0:10:CAATGTAAGA 6 27680 +ACGAAAGAAGG ref:0:11:CG ref:0:11:GA 8 28 +GATAACGGACTACCC ref:0:15:CGTCTCGGGGAT ref:0:15:GGTTGCCC 6 11220 +ACA ref:0:3:GGAACAGACCCCAAGG ref:0:2:CGC 2 160 +GTGTGACG ref:0:8:TCCGAGTCACTAC ref:0:8:TCGTCCT 6 756 +CCGGACCAGATAC ref:0:13:TACC ref:0:12:T 10 17 +CCGGTTTGCG ref:0:9:CGAGTCTCTGAA ref:0:10:TA 3 90 +TGTAG ref:1:4:CTATCCCCT ref:0:4:GGGCGCGCACCTTT 4 2618 +GT ref:0:2:TAGTC ref:0:2:TGTTGAG 1 2 +CAGG ref:0:4:GTTTAGAGG ref:0:4:GA 2 110 +TACCAC ref:0:6:TCAATATTACGGAT ref:0:6:CGCTTGT 5 3520 +TTGAATAT ref:0:8:CCCACGTTGCATGTGA ref:0:8:GTGCT 4 378 +CGGGATGTGTAGCC ref:0:14:ACCCTCTTCAGCA ref:0:14:TAACGCGTCGACCC 6 16896 +GCGGCATGACTGTTA ref:0:15:CGGTACGTAC ref:0:15:AACTGGCCGCC 6 252 +C ref:0:1:GTAG ref:0:1:TGCGG 2 5 +GATCT ref:0:5:ATTGTGTCTCG ref:0:4:CACAC 1 108 +AGGGGA ref:0:6:CGGAGC ref:1:5:TGGTGTTGAAGTT 1 80 +ATGAGCAATCGTTTG ref:1:14:CTCACAATAGCT ref:0:15:TCC 6 30 +CCT ref:0:3:TCCCAAAA ref:0:3:TCTCGCGTCG 2 48 +GGATTAGTTCCC ref:0:12:AACC ref:0:12:CGACTTAGGTGCC 3 234 +GACCTCTCAAGGGT ref:0:14:CGATAACCC ref:0:14:CTCCAGTT 5 3456 +ATTGACCCCTCTCGGA ref:0:16:TA ref:0:16:ATAATTCGGAATCGAT 7 3702 +CTAGCTCCATCTCA ref:0:14:ATGGAATT ref:0:14:ATTAAT 10 11772 +CC ref:1:1:GGCA ref:0:2:TG 1 6 +TG ref:0:2:CCAAAATATCCTGCCA ref:0:2:TTCGGCGT 3 18 +TTGCGA ref:2:4:ACGGGCTCTTTT ref:0:6:C 2 216 +A ref:0:1:AAGTCT ref:0:1:CTCCAA 1 4 +ATGCGTCG ref:0:7:CCTATCTTACA ref:0:8:CTTTACAACTGT 6 1386 +ATACGGGCCGG ref:0:11:GTTC ref:0:11:GAACCAGTGGA 5 7752 +CCCCCTAGTGTC ref:0:11:GAAG ref:0:12:TCGG 8 1479 +TACAGA ref:0:6:CGCCTACCGAG ref:0:6:TTCCAATC 1 40 +A ref:0:1:GGACCCC ref:0:1:TAGTCTGG 1 1 +AG ref:0:2:TCGC ref:0:2:GATCGAGATTCACCT 3 9 +GAATTCTGTGCCAATC ref:0:16:A ref:0:16:AGTTAAGATAAA 9 1120 +CAGTAAA ref:0:7:ATGGTCAAGTC ref:0:7:AGC 3 70 +TATAGTATT ref:0:9:CGG ref:0:9:AGTCTTA 4 160 +A ref:0:1:GACTAGCGTCGCTAT ref:0:1:ATGCATT 5 6 +AGCCGCACCCCACA ref:0:14:GCACAAA ref:0:14:GCGAAACTGACCC 5 12596 +CGCTCAGCAGCATG ref:0:14:GTATAACCC ref:0:14:TTATCACCGGAT 8 308881 +GT ref:0:2:CATTGG ref:0:2:CCG 2 10 +GGAT ref:0:4:GTTGCGTAAG ref:2:2:AACCTAGAG 4 40 +ACACC ref:0:5:TACTTTTAA ref:1:4:GTGACCTGGAGT 2 16 +GAA ref:0:3:GTCTGAGCCATTTCA ref:0:3:GG 1 28 +GCTTAA ref:0:6:CCCGCCCGCTTTAGTG ref:0:6:C 1 80 +AGGTATCTAG ref:0:10:CGTTATCCCACGGC ref:0:10:AATAAACGCAGAGCT 5 76320 +CTTGGATCTGGGTTG ref:0:15:ACGGAGGA ref:0:14:ACTATCTAAGTGG 5 34 +CCCGGGGTTC ref:0:9:GCGTG ref:0:10:TCGACCGCCC 5 12432 +AG ref:0:2:CATCATTCC ref:0:2:GTTA 2 26 +GATAC ref:0:5:AGCATTCTGCGTAAGG ref:0:5:CACACAAAATTT 4 168 +TAAGCT ref:0:6:GTCTA ref:0:6:GTGAGC 2 6 +AGCG ref:0:4:TTTACGG ref:0:4:ATAA 2 75 +CATGGAAAACATATT ref:0:15:TGTAAAAACTAGA ref:0:15:GACCGTGTGCCAAAAG 6 115500 +AGGAAATTG ref:0:9:CCGAGTGATTCTTCAC ref:0:8:CGCCT 4 23814 +CAAGCTCGAAATACT ref:0:15:TCCTCAGA ref:0:15:AGTAAATCGTGCTAA 3 306 +ATCCAGCAAATCACTA ref:0:16:A ref:1:15:CGATATGTG 9 868 +AGCT ref:2:2:CACCAACG ref:0:4:TCTGCTCCT 2 336 +GTGGAATGGAGGTTTT ref:0:16:ACCGGAGCA ref:0:16:AAGCAGAGCCGCTT 8 3960 +CTCCTATAAATTAGT ref:0:14:CCATTATAAATAGGG ref:0:15:GGCACTAGATCGA 3 235620 +T ref:0:1:CCACCTAG ref:0:1:GCCCGGTCACT 4 2 +G ref:0:1:GGATGGACGACTCGGT ref:0:1:TCATATTA 5 63 +GTCAT ref:1:4:TACTGCATA ref:0:5:CCGGAAGTCCCCCGTT 1 405 +CCCCGCTTTCAGTA ref:0:14:GGCC ref:0:14:CTTGG 8 570 +TTTATTTTCCAGTT ref:0:14:GTTTAGTTC ref:0:14:C 7 190 +GCCGATCAGGGTGC ref:0:14:TAGGGCCAAGCGAG ref:0:14:GA 6 120 +TTCCGCGCTTAAAG ref:0:14:TTTGCACCAGTACA ref:0:13:ACACGTTTCAGGCCA 5 26784 +CGACAGT ref:0:7:GTAG ref:0:7:GGCGCTCAAAAGGATG 2 208 +GCC ref:0:3:TAGAAATCCTA ref:0:3:ACTTACACATGTC 3 29 +CGG ref:0:3:TGC ref:0:3:AGA 2 56 +CCACGC ref:0:6:GG ref:0:6:CCTTCACGGGCA 1 63 +ACTCGAAGT ref:1:7:TGTGAAGG ref:1:8:GTCATTAACGCCTT 2 448 +AGT ref:0:3:GGCCGTGAGGTA ref:0:3:CCGGCGGTGTA 6 98 +AGCGCATTGTGAATA ref:2:13:AACCGATCTTC ref:1:14:CAGATAAAT 5 1620 +TCCCCTTTTGACA ref:1:12:GCGTCAGATCCG ref:0:13:CGCTACG 8 264880 +CATAATAGATATTC ref:0:14:GATTAGTAGG ref:0:14:AACCCGCGTCCTGA 7 308520 +G ref:0:1:CGGA ref:0:1:AAAC 1 10 +CTACATGTG ref:1:8:GTGATCCCATGT ref:0:9:GGACCGCA 5 645 +CACCCATAAAC ref:0:10:ACACTCAT ref:0:11:C 4 25 +TGCAGTGCGACGCTTC ref:0:16:CA ref:0:15:GGATTGACCCGTAA 6 4812 +GGACGTGCTGCC ref:0:12:CAGTTGCCAC ref:0:12:ACCATCCGAGAGTGTA 4 80 +CTGAGCAGTC ref:0:10:GAGCCGTCTT ref:1:9:GGGGTCGACCG 2 537 +CGGGTGCAAATGGCT ref:1:14:TGGCGTGGACTT ref:0:15:CCGAGGAAAGCATC 3 3784 +TCTCTAGGC ref:0:9:GGCTGGTCAC ref:0:9:GTTCCCACTTAATG 3 23800 +GTGCAACATCGAC ref:0:13:CAGCT ref:0:13:TAGAATCACTGTT 5 112 +GACTACGGTA ref:0:10:TATGGTTG ref:2:8:TCGCATGTGGCG 4 100 +GACTGGTCC ref:0:9:CGGGAC ref:0:9:TAC 5 522 +AGAAAACTGG ref:0:10:CC ref:0:10:ATC 8 341 +CACTGATACTCTCC ref:0:14:TCG ref:0:14:AGCGGGACAGAACGG 7 2870 +CTAATTGATCGGC ref:0:13:C ref:0:13:GTCCA 9 3 +GTGCCTGCGG ref:1:9:GTAG ref:0:10:CTCCGC 2 16 +GGGCATGCGAACAGGG ref:0:16:ATCCTAGGCTCACT ref:0:16:CACCATATTAAA 8 156915 +GAATTTTAATAGGCGT ref:1:15:ATTA ref:0:16:TCAACCCAA 9 184844 +GCA ref:0:3:CACTACTCCACCCAGA ref:0:2:GGCT 1 318 +ATGAACCTACGCAATT ref:0:16:TTCGATAA ref:0:16:ACG 9 330 +TTCCCATCGCGT ref:0:11:TCAGGCATAGATCAA ref:0:12:GACTCGGC 4 10656 +CGTGT ref:0:5:TTTG ref:0:5:CACCCACCCCTCAG 2 656 +GCTAATTAACATTAG ref:0:15:TAGGTGGAGAC ref:0:15:AGAAGACCC 10 6384 +TCATTTTGCTG ref:0:11:GATCTGAA ref:0:11:AC 6 12 +TCAGGA ref:0:6:AGCGTGAGCC ref:2:4:GGGAGTTAG 2 114 +CAGA ref:0:4:GGAT ref:0:4:GTAAGTGCG 3 276 +GACGCGGACATAGCTA ref:0:15:GGATCCATCCGGG ref:0:16:CAGTTAC 7 269700 +GAGATGA ref:0:7:ATGAGGTCTGCCTT ref:3:4:TATGAATT 3 120 +ACAATC ref:1:5:CCTCACTGT ref:0:6:TTGCCCTGATGGTCA 5 15471 +AATATA ref:0:6:GTATCAG ref:0:6:CATTGTTTAGCGAGGA 4 2112 +CTCGCACGAAGC ref:0:12:AGTAAAATTCTGGCG ref:1:11:TTT 7 25818 +AGGGCT ref:0:6:TGAGGCATCGTA ref:0:6:GTGACCCCGC 2 19 +ATATACAGACGGT ref:0:12:GGCCGGAAAA ref:0:13:ACAGATAGTG 5 3690 +TC ref:1:1:GGAGCGTT ref:2:0:GGGA 1 1 +AGTTT ref:0:5:CCCTCGCAGCAC ref:0:5:ACAATTAAGAATCG 3 140 +GCTAGA ref:0:6:AG ref:0:6:CACCCC 3 16 +ATAGTCTAC ref:0:9:GAAGTTAAAACGAGCT ref:0:9:ACATCGTGTAGTG 4 832 +GTGTTCACTAG ref:0:11:CCTT ref:0:11:ACGCCC 7 264 +CAGA ref:0:4:GGT ref:0:4:TGAGGATCTG 3 54 +AATCGCGAT ref:0:9:CGTATTGGGTT ref:0:9:CCAAGCTAG 3 1542 +CGCCATGAACC ref:0:11:TAACTGGTAACG ref:0:11:C 5 1620 +TGT ref:0:3:TCCTGATACCAGAGA ref:0:3:ATGGAGC 3 22 +AGATTACATC ref:0:10:GTCGCGCGAGG ref:0:10:TTAGGAACCA 4 1434 +T ref:0:1:TGTACCATG ref:0:0:CAA 2 3 +GAAG ref:0:4:TG ref:0:4:ATGTGGGG 3 390 +GCTCCGCG ref:1:7:TCCATCGTTTCC ref:0:8:AAGCTTAATCATC 4 1479 +GGACTACCGTTGATAA ref:0:16:CAATCATACGAA ref:0:16:TAG 8 216 +ACCTCTCCGCATAT ref:0:14:AAC ref:0:14:TCAAACAAC 10 6794 +CAGGCCCGAGGTT ref:1:12:GTGA ref:0:13:GGCG 7 90 +TCTTGTAGCTCAC ref:0:13:CGGAG ref:0:13:AACGC 8 840 +TAT ref:0:3:GTTTCTCGGTAGTAC ref:0:3:GCTAATGTGCGGGCAG 4 20 +TAGCGAACGT ref:0:10:CCCTTTTGACAGTACC ref:0:10:AAGACACAGTT 3 15164 +C ref:0:1:AACGTGGGC ref:0:1:GTGA 3 10 +ATTACTTTTCG ref:0:11:CGTCCT ref:0:11:GAGAGTTCTTAATAA 5 22640 +GGGAT ref:0:4:CAAG ref:0:5:CCTAGCATCGCAAGG 4 3509 +GAAGTCTACATCCCGG ref:0:16:CTCGGGAGGT ref:0:16:AGATTACGCAGTTT 8 1265 +CATTATCTA ref:0:9:GGCGAATCAC ref:0:8:TTC 2 3 +AGAC ref:0:3:CTTGTCCATAG ref:0:4:CTCCTCTCAAACGGA 6 120 +GACGA ref:0:5:TCACGTATGGTAC ref:0:5:CATCTTATCAACT 6 1003 +TATTTAGA ref:0:8:CGTTACGCCGAT ref:0:8:TCTAGGC 4 3250 +CGAC ref:0:4:GATCCCTCCCCATTA ref:0:4:TAA 2 84 +TCTCTGTGTGCCTCTC ref:0:16:GGTTCT ref:0:16:GAACTCAGTGTTG 6 148 +CGGCAGGTA ref:0:9:TCCTGCGG ref:0:9:AGGGCTAACCCTC 2 2793 +CTCCTTCTTC ref:0:10:AAGGC ref:2:8:GCGAGTCCTAA 6 576816 +TTTCGAGGT ref:0:9:CTCATTTCA ref:0:9:CACGTTGGCGAGTG 3 108 +GACGCAGAGAATCGTA ref:0:16:TTATGAA ref:0:16:AGCCCAAT 10 282960 +TGGCACACTTTC ref:0:12:T ref:0:12:CTGCCG 8 160 +ACAGA ref:0:5:C ref:0:5:GGTAGCGGCGGGTGAC 1 37 +ACCGCCTTTAGGTGAG ref:0:16:TCCCGAA ref:0:16:AACCT 9 11628 +CAATTAGGC ref:0:9:TACG ref:0:9:ACGTTGCGATAGGCG 3 448 +CATTCTGTCACAT ref:1:11:CGGGGGACC ref:0:13:ATTCACCCACTT 4 54080 +GATCCGATTAT ref:1:10:TCTTACTG ref:2:9:GTTTGGTC 3 34 +GGGGATCGA ref:0:9:TGC ref:0:9:ACG 5 13 +ACAAATAT ref:0:8:GCATTTAC ref:2:6:TTAA 4 3286 +TTGGT ref:0:5:TAGAAAAGGGAAATCG ref:0:5:GCGA 2 68 +CCT ref:0:3:ATATTAACA ref:0:3:TGTACAGGCTTTAC 5 141 +TGGGAATCTC ref:0:10:TATTGCCCCAGAA ref:0:10:CTCGGT 4 688 +GCTATCTC ref:0:8:TCGTTGTCACCAGAA ref:0:8:CAGGTACAGGTA 5 1540 +AC ref:0:2:AAGCCCCGTTCAGCGG ref:0:2:TCCGAGGGGCGCA 5 26 +CCACACCCTGCGCC ref:0:14:GGACAGTTCGGA ref:0:14:T 8 1548 +G ref:0:1:TTTGATACCCTC ref:0:1:AGGTT 2 2 +GCC ref:0:3:GTTAAATGGGC ref:0:3:C 1 40 +TAACCCAGATTCG ref:0:13:CCGACGGGGATAAA ref:0:13:TT 6 2376 +AAGATAATATG ref:0:11:A ref:0:10:GGTTTT 5 234 +GTC ref:0:3:CACA ref:0:3:CAGAT 2 7 +GGC ref:0:3:GGTAGTTCACAAGA ref:0:3:TCGGTCGCG 3 24 +CACCGGAGTCTTG ref:0:13:AGT ref:0:13:GTATCTATTCAAGACA 5 108 +GATAGG ref:0:6:CACAGGATGCT ref:0:6:AGACCCCCTTGTGCC 3 60 +TATGTAATC ref:0:9:CT ref:0:9:ACG 7 90 +TAGTTAGCCTCTTTT ref:1:14:GAAACTACTCGAA ref:0:15:TGCAA 10 2120118 +GGT ref:0:3:ATCGGCTCCACCATAC ref:0:3:CGCGATGATCTC 5 14 +GCTAAACGCTCGCG ref:1:13:TCCACCTGGGC ref:0:14:C 6 1210 +TAAATTAGCGT ref:0:11:AGAA ref:1:10:AGAACGTCTATTAT 4 170 +GCTTTTG ref:0:7:GGCCTTCTAA ref:1:6:TATCC 3 3588 +TCACACTT ref:0:8:ATGATCCAT ref:0:8:GTAAATATGCGCACAT 5 1836 +TTGTGCGAACTT ref:0:12:TACAATC ref:0:12:TCA 7 264 +CA ref:0:2:GCTACGTGCAT ref:0:2:ATGACTGACC 4 4 +TAGCGCT ref:0:7:ACGAACTAATAGT ref:0:7:CGTTGTTTCG 1 12 +C ref:0:1:G ref:0:1:GAAAGGCC 1 4 +A ref:0:1:TCAGCT ref:0:1:CTAGCAA 3 3 +TATAAGTA ref:0:7:GCGC ref:0:8:CAAGC 6 1104 +TGTTCATCATACGGC ref:0:15:CTTA ref:0:15:GGCTTTACAACTTAT 7 1636 +CAGGTTGGA ref:0:9:ACATT ref:0:9:GTATTTTGTCCC 4 1855 +GGTTTCACT ref:0:9:TCTA ref:0:9:TAACTCTTCAGGC 4 234 +CTCAT ref:0:5:CCGGACAA ref:2:3:GGGCTTAACCCTT 3 136 +CCGCAG ref:0:4:TGCT ref:0:4:AAAGGCATTCCGTT 2 30 +AAGCTCAGGCT ref:0:11:GTAGGTGG ref:0:11:ATAATGTGGA 3 9 +CCGAAAGCGTACTGG ref:0:15:TA ref:0:15:GAG 11 18 +CAGTGAACCAGGCGGG ref:0:16:GATCCTAAATGAGC ref:0:16:CAC 8 624 +ATAAGGGACCCGCCGT ref:0:16:CGAAGTCG ref:0:16:C 11 6645 +GGAG ref:0:4:GAAAACGA ref:0:4:TCATGGAACC 2 105 +GAA ref:0:3:GTTCGCTCCTGACATG ref:0:3:AGATCCTTATCAGT 7 9 +TAAACTT ref:0:7:GCGCGCTGAAG ref:0:7:CC 4 136 +TGAAGGACAT ref:0:10:ACATTCCA ref:0:10:TCTGGTCCATCT 6 9350 +AACAAAGTT ref:0:9:AAGTC ref:0:9:GTTATCTTGAGC 5 8280 +GTTACCTCA ref:0:9:CTCCTGTGGTTTCG ref:0:9:AGGTA 4 1564 +GCAAACGGAAATCTCA ref:0:16:ACCGCCCGC ref:1:14:AACTGCCT 8 157350 +CTGTGAGGTCA ref:0:11:GT ref:0:11:AGGTAGAGTTAT 4 495 +TCATTTTCCCAGTGGG ref:0:16:GAGTAATGG ref:0:16:TG 10 14559 +TGACACGTAGGGC ref:0:13:CATCTG ref:0:13:AC 8 18 +TTTTGTAGAC ref:0:10:GTGCGG ref:0:10:GATTT 4 21 +CCA ref:0:3:GACACGCCCAAAGT ref:0:3:CGGAACCAC 3 90 +TTT ref:0:3:ACA ref:0:3:CGGGAGAA 5 3300 +GACTTTCC ref:1:7:C ref:1:7:CGTTGGTT 3 18 +TTTGTGGGT ref:0:9:CTCACTGTA ref:0:8:TATGATCAC 6 17520 +GC ref:0:2:ACCATGCGTA ref:0:2:AGAGA 3 6 +GACGAATTCGT ref:0:11:GTGGTGG ref:0:11:AAACCCAATATGA 3 13032 +GTCAACTAGAGAGATA ref:0:16:C ref:1:15:ACAGCGGT 8 8 +TAATCAACGCCTGACA ref:0:16:TCCGAT ref:0:16:CACGG 9 124 +CCCTGAACGAGTCAG ref:0:15:GCGAAACAGAGTGT ref:0:15:TCGGC 3 18 +AACCAGTAG ref:0:9:TTATTGG ref:0:9:CACAATTGACCGCGGA 5 153576 +TCATCTTTAAA ref:0:11:GGACAG ref:0:11:CGTGCGGGTGCCC 7 59616 +GATTTTTC ref:0:8:ACCGAAACATGA ref:0:7:CGACCGGTGCCGCT 6 504504 +CAAATACCGGGC ref:0:12:CGCGCCATAAAAA ref:0:12:TACG 4 1872 +TCACTATTTTCC ref:0:12:ACT ref:0:12:TTCGCCGTGTATATAG 4 16320 +CGGC ref:0:3:CTAGACTTTGTAGA ref:0:4:ACGACTA 2 12 +GAT ref:1:2:TACTCCAG ref:0:3:TGTTTAACGCTCTCTC 4 6 +CTGTATCA ref:0:8:AACCGCCATAAAGCT ref:1:5:TCA 2 600 +GG ref:0:1:TAGCACTTCATA ref:0:2:CTGAACGAT 3 1 +TGGGTAGTAGCG ref:0:12:TTTCTATAGTGC ref:0:12:CGC 6 9585 +CAGTTACTCGATACA ref:0:15:TGTAGC ref:0:15:TTCACCGGTC 7 30 +TA ref:1:1:CGG ref:0:2:GCG 3 40 +ACTGGAAAACAGAA ref:0:14:TGCCAGTCATGTTGG ref:0:14:AACA 7 101970 +GTCTTCCATCAAAAAT ref:0:16:AAACTACAA ref:0:16:TCCAGCCTCGATTG 6 241200 +CGGAG ref:0:5:AA ref:0:5:GATAAGGAGTTC 2 48 +GGGC ref:0:4:CTGCC ref:0:3:GCACAAGAAGAGG 1 250 +GTCCTTGCGACG ref:0:12:GAGG ref:0:12:AACA 8 2294 +CCCTCGCGGCCTCC ref:0:14:CCTATCTCATAAC ref:0:14:CTGCGTTAAT 8 1022400 +CGAAGAAAA ref:1:8:AATTCGTCCATACT ref:0:9:GACGAC 4 1350 +ATTGTT ref:0:6:CCGTTCTGGAAGTG ref:0:6:GAGCAAG 5 7344 +CAGCTATTGAA ref:0:11:GCCGCTAAT ref:0:11:ACAG 3 33 +ATGTCGGTTAA ref:0:11:TGGA ref:0:11:CACGGCGCCTGAGCG 4 7024 +GCAGTAGAAGCAG ref:1:12:TTATACTGAATGAC ref:0:12:AGGCTCGCGC 3 270 +TGTAAGGTGAA ref:0:11:A ref:0:11:AGAGGGGCGTTAGACC 4 3580 +GGTTCGTACTGTA ref:0:13:TGAGGTCTTAGGAT ref:0:13:TCCTAGGCTGCCG 4 20251 +GTATTTTAGCG ref:1:10:ATTAGGTGTTATCA ref:0:9:TAGAT 4 3784 +AATCTCTTC ref:0:9:GTGCGCAAGCGG ref:0:9:TGCTTGATCG 5 60 +TCCTAAAGCATAGG ref:0:14:GCGCAGAGT ref:0:14:CGTTC 8 7020 +AGAATGAGTGGTTCT ref:0:15:CA ref:2:13:CACATG 10 442 +GTGGC ref:0:5:ACTAGGATCCGAAT ref:0:5:GGTTAAGCATGGACT 4 90 +ATAAATAA ref:0:8:GTTCACCG ref:0:8:G 6 108 +C ref:0:1:ATTGTACGACCGAAGC ref:0:1:ACACAGGTTG 5 8 +TTGGATTGCTCTT ref:0:13:CT ref:0:13:CCTAGT 9 65 +TT ref:0:2:TATGAGGAAGTTAC ref:0:2:AGGTTTGGGG 4 18 +TGTTAGA ref:0:7:CCCGAGGTTCG ref:0:7:AGCGGGTAACT 4 1870 +CCTC ref:0:4:TAAAACGAGT ref:0:4:TACTCGCCTAT 5 473 +ATCGTT ref:0:6:CCATCTTAGCTAG ref:0:6:TCTTTTTCAGC 4 180 +C ref:0:1:TCCCGAGACG ref:0:1:CACCCGGGAT 5 16 +CGAGCG ref:2:4:TATATACC ref:0:6:ACTGCCC 3 1200 +GACCATTGGATA ref:0:12:GGAGTGCCTA ref:0:12:AGA 6 2624 +ATA ref:1:2:CGTGGTACA ref:0:3:ATCGATACG 3 16 +CAGTGTGT ref:0:6:TGACGTCGATCA ref:0:8:ATTCACCCTGA 3 440 +CATAGT ref:0:6:GCATGACATAA ref:0:6:CTCATGGGCA 3 295 +GATGT ref:0:5:TTCT ref:0:5:CGA 1 10 +TTGAAAGAAGGAGTCC ref:0:16:TGGAC ref:0:16:AACGTATTT 8 62496 +GGATAGAAGGATTG ref:0:14:AC ref:0:14:CATAGCTTTCTGGCA 8 66666 +ATC ref:0:3:CCAATCCACAGACTC ref:0:3:AACGAAG 4 45 +GTGCCAC ref:0:7:CGGCGT ref:0:7:CAACCCTG 4 663 +TTGGTCT ref:0:7:CTCTCGA ref:2:5:GAACACA 4 4104 +GGTAGGCTATGGCACC ref:0:16:TACGAACA ref:0:16:GAGCCCTACAGAG 7 68025 +CCAAT ref:0:5:GCAG ref:1:4:GTCAGTGTGTG 3 225 +GAACTAAGGCAT ref:0:12:TCTGTCCCG ref:0:12:CAATTTTGCCTCGAG 9 743328 +TGAATC ref:0:6:TTCGCCATCCCCA ref:0:6:GAGTCGACA 3 320 +CATCCATGTTCCT ref:0:13:ACTCCCATT ref:0:13:TCG 5 72 +CGCTAGG ref:0:7:GAGTAGGTCGGT ref:0:7:GCTGA 1 144 +CACCCTCGC ref:0:9:TC ref:0:9:CGCCGCCAAA 3 164 +CAACAATTCAT ref:1:10:GCAA ref:0:10:CCGACC 5 207 +CACCCAGCTAGGGTAT ref:0:15:ACAACAGTCGTC ref:0:16:AGGGCCA 6 15378 +CTAGAGA ref:0:7:GCTCACGAATCACT ref:0:7:GA 1 24 +C ref:0:1:CGTACAAA ref:0:1:TATAAGTTCGCTTGG 2 4 +TAAAGGCCCAA ref:0:11:CC ref:0:11:ACGAACG 6 144 +GCTATCCCACTTAAG ref:0:15:CTAAACGCGGGC ref:0:15:CTTCATGAGACGTT 7 36063 +ACGGGGGCTCTGAC ref:0:14:GTGTACCC ref:0:14:TACCGGATATTATGA 5 1122824 +ATCTACG ref:0:7:GAT ref:0:6:A 4 4 +AGTCCCAGCGGG ref:0:12:A ref:1:11:TCGGCATTCATT 6 642 +GGT ref:0:3:TA ref:0:3:ACCGC 1 11 +GTTTA ref:0:5:CCAGTCTTTAGATCGT ref:0:5:TACGAAC 3 352 +ACATGGTAATATTCAG ref:0:16:GGTTCCCTTT ref:0:16:GC 9 100 +TCTGCGCTTGACCCT ref:0:15:CAAG ref:0:15:GTAGGG 11 1266 +CAATAGTCT ref:2:7:CAAG ref:0:9:TAAGCAAC 4 106 +GCGTAAGGATCA ref:1:11:CCCCC ref:0:11:TTCAAT 5 10920 +CGATTCCG ref:0:8:TTCCCTGG ref:0:8:T 3 12 +GTGCGGTCGGA ref:0:11:TTTGGAGAACAGT ref:0:11:CAAAT 7 8064 +T ref:0:1:A ref:0:1:CCGCCC 1 14 +TCATGTCATCTGCCC ref:0:15:TTTT ref:0:15:ATATGCTTGTGTAAT 7 2170 +AAAAAATGA ref:0:9:TTTCAAA ref:0:9:GGACACCGTC 5 1149390 +TCATACGCGGCGACG ref:0:15:GGCATTCCA ref:0:15:TA 9 165 +GCCTTGAACCCATTTA ref:0:16:A ref:0:16:AGCAGGCTTCCAAC 7 12 +C ref:0:1:ACAC ref:0:1:ATACGCC 2 6 +TCGTCTG ref:0:7:CACGACCAGG ref:0:7:C 3 232 +TACTTAAGCT ref:0:10:GAAC ref:1:9:CA 5 20 +TCAATCTCCTTCG ref:1:12:ATC ref:0:13:CTGAGAGC 8 1080 +GTGGCCT ref:0:7:GAGTAAGGTAC ref:0:7:ACTGGGGGTC 4 3040 +TGT ref:0:3:GAATGCAGCA ref:0:3:CCTA 3 90 +TATAGGAT ref:0:8:GATGCTATT ref:0:8:AGGCACTGAC 3 32 +CTATGGTTGAAAA ref:0:13:GACTGG ref:0:13:GGAAG 7 450 +AGACAAGCGGAGAGCA ref:0:16:ACGAGGCCCTATATG ref:0:16:GCTGTTGATGATG 8 39848 +ACAA ref:0:4:CAATAA ref:0:4:ACAACGTGAAGCGCT 3 117 +GACATAGA ref:0:8:G ref:0:8:ATAAGG 4 40 +TTTGTGCT ref:0:8:GGGCCGA ref:0:8:GTCCGCAATCGA 6 49 +CTCGTAAGTG ref:0:10:C ref:0:10:TAATCATGATAA 4 12 +C ref:0:1:ATACT ref:0:1:GTGGTAAAGT 3 11 +GATGGGATAC ref:1:9:TCCCACCGTAGT ref:0:10:ATTAGGACGTCGC 4 14828 +ACTAGTGATAACATA ref:0:14:CTTGGAAACGCAC ref:0:15:AACAGCGGAAATGCA 4 1600 +CCCAATAGTCCAT ref:0:13:GTTGGCAATTACTCTT ref:0:13:ACAA 5 66304 +CGTCCA ref:0:6:TACGCGTG ref:0:5:GCTGCT 3 390 +TTTGGATCTGAATCC ref:0:15:AGACT ref:0:15:CAAT 9 27 +ATGGGGTG ref:0:8:CCGAT ref:0:8:AAACCCATA 8 182970 +GAATTCATCT ref:0:10:AGACTATCAT ref:0:10:AGTTGATATTCAAA 4 780 +ATGG ref:0:4:G ref:0:4:TATGCTT 1 10 +CGAACAC ref:0:7:AGAAGC ref:0:7:G 3 13 +G ref:0:0:TCTCAT ref:0:1:AGGTGCTTGAAAAAC 4 4 +TTGTC ref:0:5:AATCGA ref:0:5:CTGGGT 2 348 +GGGGCGGTATTGG ref:0:13:TTGACGGCGGAGA ref:0:13:TGCATCGGCTGTCC 7 192384 +TGGCGTGCAAGGGA ref:0:14:AGAGTGGGT ref:0:14:GGCGACGTCG 6 10206 +CGCA ref:1:3:TGGGGGC ref:0:4:AGTAGTCCACCCAA 1 685 +GATC ref:0:4:TCACGATGCAGGA ref:0:4:ATATGCAGGTTCG 3 2 +GTC ref:0:3:A ref:0:3:CTGCAGGGCCGATT 2 200 +TGCCTGCCGTC ref:1:10:CCCAATGG ref:0:11:GGCACACAACT 2 36 +CGTAC ref:0:5:CCGCGCAGAA ref:0:4:G 2 166 +TCGGTC ref:0:5:CATTGCGGA ref:0:6:GCTCATACCCAATTCG 3 1064 +GAGAGCA ref:0:7:TGAACTAAAT ref:0:7:CGATTCAC 2 78 +CGAATTGCGGCGA ref:0:13:TTCTTAGATT ref:1:12:GGTAGATACC 7 450 +GGTTTTAT ref:0:8:CGTCTTTCCGTCGGC ref:0:7:TCAAGGTGTCTAG 2 72 +TTTGA ref:0:5:AGCAAAC ref:0:5:AC 4 12 +GGGGGGGAGAC ref:0:11:GTGAGCTTGG ref:0:11:AACATAATCGC 8 1924776 +C ref:0:1:GTACCCCGA ref:0:1:TAGAGCTAATAAGTA 4 4 +TACACGCGTT ref:1:9:AACTACGTAGTGCG ref:0:10:A 2 90 +TGAGTA ref:0:6:GAGGTTATAC ref:0:6:CGTAACCATAACTTTA 3 6660 +GC ref:0:2:CCAAAAGCG ref:0:2:GCACTGGTCG 3 5 +AGGAACTAGTAGC ref:0:13:GTCACAGTTT ref:0:13:TGGCCTCTGCA 4 4680 +CGGGA ref:0:5:GGT ref:0:5:ATGCTCGAGGC 1 28 +ACAAGATCGCTG ref:0:12:GG ref:0:12:T 9 6 +ATGCAGCGCCTTCT ref:0:13:CAAGTT ref:1:13:GCTTACAGTCTGC 5 96 +TGGTAA ref:0:6:TCTG ref:0:6:AATCTCCCAGCT 5 600 +CTAGTCG ref:0:7:ATGGCGGCGCGTT ref:0:7:GGAA 3 348 +CCAGC ref:0:5:T ref:0:5:CATCTGATTACTCAAA 2 132 +ATCGAA ref:0:6:AAGGGAAAACGACAGA ref:0:6:TGCTAAAGAAGATTCT 3 243 +TATCCGTCACTT ref:0:12:CTTCGTG ref:0:11:CGCTGAGGGACTG 5 1476 +TGC ref:0:3:AAGCGAGAGGAGCCT ref:0:3:CAATGATCATTAAAT 6 95 +ATCCGGGGAC ref:0:10:GACGAATCGCT ref:0:9:GCTACC 6 560 +AGT ref:0:3:CTGAAGATTA ref:0:3:GGTCGGCGTGGACA 3 100 +ATAATCGGAC ref:0:10:GATTGATCTA ref:0:10:GGTTCCATTG 6 7291 +ACTT ref:0:4:ATTGTAAGATGGTC ref:0:4:G 2 175 +GCTA ref:0:2:CCTTGCC ref:0:4:TTATCCC 1 8 +CATGTGTGCAAT ref:0:12:TGCACTGG ref:0:12:GCGCTATCA 5 100 +GTGCGTTTACGACGAG ref:0:16:ACTA ref:0:16:CT 13 141 +CTGTGGTG ref:0:8:TGC ref:1:7:GTGCATAGGCCAA 3 621 +CAGCTGATCGTA ref:0:12:A ref:0:12:GCACAG 7 9 +TAAGCTGAAC ref:1:9:CGGA ref:0:10:CAAACCGTG 4 416 +CT ref:0:2:GGAGGCGGGGTG ref:0:2:TAC 1 2 +TCCAAGTGGATTG ref:0:12:GTGCAATCGA ref:0:13:GATA 6 225 +GGACTTGA ref:0:7:TTAACCAACAGTTGC ref:0:7:ACCACTGCGCG 6 19264 +CACCCGGATG ref:0:9:CGTA ref:0:10:TCCTTGT 5 3100 +TGGGTCA ref:0:7:TATGAGCCGGAGTGAG ref:1:6:AACCAGGGAGAGT 7 800 +GCGATGTGCT ref:0:10:GTACGGCCAGAAT ref:0:10:GGTA 4 1700 +ATATCTTA ref:0:8:ACAC ref:0:8:TTGCTAT 2 12 +CT ref:0:2:GAGCCCGGTCT ref:0:2:GGCTAGGAGGG 2 7 +TAT ref:0:3:CCATCG ref:0:3:GCTGAATCTT 2 18 +TATAACA ref:0:7:TCCTGTAAAACTGG ref:0:7:ACCTCTCCAAACAT 5 4942 +AGCAGATTCCTAATCC ref:0:16:TACAGGCGTGAGTG ref:0:16:CTGTAGACGCATT 7 13440 +ACAG ref:0:4:CACCCTTTAGAGG ref:0:4:T 1 75 +GTT ref:0:3:TTTGACCGCCTAAG ref:0:3:ATTACGT 5 252 +AAACCACCATGAT ref:0:13:A ref:0:13:TCGCGTA 9 1740 +GAAGGGCCGCATCC ref:0:14:GGC ref:0:14:CTGAC 9 252 +GGAAGCAAGCGGAATC ref:0:16:GAAT ref:0:16:ATTATAAAG 9 6786 +TCAAGGCAAGGAGCCG ref:0:16:A ref:0:16:ACACCAACCCGCCGG 7 6010 +GTATTCCAGAGTTCCG ref:1:15:TTT ref:0:16:CGGTTCATTGA 8 320 +TATTTGCAGCCTACG ref:0:15:CTTAAAT ref:0:14:GCACTAACAGCTTCT 8 672408 +TTG ref:0:3:GCGGAGTATATGTG ref:0:3:GTTATCTC 4 180 +GACGTCCAATG ref:0:11:A ref:0:11:ACTGTCGATAAAA 4 543 +TACGTCTCCGTGAGCT ref:0:16:GGT ref:0:16:CGCTTGCAAA 8 161 +AACGAAC ref:0:7:GGTTACTCTT ref:0:7:GACCCCG 5 7752 +GC ref:0:2:ATTCTC ref:0:2:TCGT 3 40 +CGCGGAAGCAGACAT ref:0:15:CGTGTA ref:0:15:GA 11 13000 +GTCTAGCTGCT ref:0:9:TCAAC ref:1:10:TATCGGTTGGCG 2 1648 +TCAAAT ref:0:5:CCGGA ref:1:5:CCACTGCT 3 2275 +CCTAA ref:0:5:TGGGTCGATTTCGCTG ref:0:5:TTTGCCCCTTTGAC 5 810 +CCCCCGGAGAGCCT ref:0:14:CTATAAAGCTTG ref:0:14:TG 9 220320 +CCCTTC ref:0:6:ACTCC ref:0:6:GGTTCAGGGTG 2 360 +CTCACATGGAG ref:0:11:GCAC ref:0:11:GCG 8 132 +CACTA ref:0:5:TGCCTAATT ref:0:5:A 1 4 +TACTCGATCACTG ref:0:13:GTGACA ref:1:12:AAGCGGAGTTGA 3 130 +ATTTACGATAAAAG ref:0:14:TCGCC ref:0:14:TTTTCAATAGCCC 8 20868 +ATTGCCGGGCAGC ref:0:13:GTTAGCAAAT ref:0:13:GAGCAAAGTG 10 634728 +TGGT ref:0:4:TATATAA ref:0:4:AATGCACCGA 3 32 +TGTTG ref:0:5:ACACCCTTCAC ref:0:5:A 4 756 +GCCCC ref:0:5:CTC ref:0:5:AATCCGAAGAAC 2 460 +GT ref:0:1:AGGGCCCCAG ref:0:2:GAAGAAAGGTGC 3 16 +AAGCTATGGGGCC ref:0:13:CCCGA ref:0:13:TTCGATGAA 8 2027 +CTCCCGTCA ref:0:8:TCCCCCTGG ref:0:8:TATCGAGCACTGGCC 4 5520 +GCCGTACAGTGCCAGG ref:0:16:TAGCTAGC ref:0:16:TCCGCAATCACTGAAT 6 51830 +TTCTCTCCGACAAC ref:0:13:TCGGCAGGG ref:0:14:ATAAA 6 4030 +AGGG ref:0:4:CTGTA ref:0:4:CACTACCCAGGCCC 3 1363 +TTGTTCCAGTAAC ref:3:10:CAAT ref:0:12:GGTGAACCTCTAGT 4 5103 +GAAGAT ref:0:6:CCGCTATGCC ref:0:6:CAATATGCACTAT 5 1134 +CGCGGGTGGAGAG ref:1:12:C ref:0:12:TCGCCTCCACAA 6 225 +GAAAGGACCGCTT ref:0:13:GGCGGACC ref:0:13:TTTCCGGGACAGCT 5 288 +GTCCGGGTTA ref:0:8:GGTAAAA ref:0:10:GAGGGGGGAAGTGTCC 3 10098 +CGATGCGCGAATTTCC ref:0:16:GGGGTACTC ref:0:16:TGCCTGTG 6 1525 +CCTATAAAATCGT ref:0:13:GACGGTT ref:0:13:AA 8 1360 +GAGCTCCTACAAAA ref:0:14:AAAGAGCGCTTCGA ref:0:14:TCCAGGTTTCAG 7 216200 +AAAG ref:0:4:ATAT ref:0:4:GTTATTCAAT 3 18 +CGCCTGGGGCTG ref:0:12:CGGTAAAATAAGA ref:0:12:G 7 6498 +GCATCAGGACCC ref:1:11:TGTGATA ref:0:12:CGTCA 6 66 +TGC ref:0:3:CCCACTTCTTAA ref:0:3:AAAAGAAGA 3 123 +TCCGA ref:1:4:CGTTAAGAAC ref:0:5:CAGT 2 176 +TGCCACACGTCTTTAG ref:0:15:TATGGAGTGTGGAA ref:0:15:CCGCGCCGAGAAATT 6 229104 +CG ref:0:2:CCCGTG ref:1:1:T 1 12 +GGCCCGTGG ref:0:9:GCAAACTAATCAAGAA ref:0:9:CCTAT 6 18480 +CGGGC ref:0:5:GCAAGAGGCCTAAC ref:1:4:GATATACTGCC 2 63 +GACTAACC ref:0:8:TAAC ref:1:7:CG 3 18 +CG ref:0:1:AGTTCACCTCT ref:0:2:TTCC 3 12 +GCGTGGGGACAC ref:0:12:CATTCAAGAGACACG ref:0:12:GATTACGG 6 68796 +GGCCTCTAGGTGCC ref:0:14:ACTGCTTACCT ref:0:14:CTCACGCTC 6 1230 +CCGT ref:0:4:ACTGG ref:0:4:ACTTTAGAATTTC 3 336 +CTCGGCC ref:1:5:CCT ref:0:7:C 3 4 +AAATAGTT ref:0:8:CCAGAT ref:0:8:GTAGATC 5 2288 +CTTACATTTGGAA ref:0:13:TATACGGAC ref:0:13:TTTCG 6 150 +GCCA ref:0:4:GG ref:0:4:AAGGCTGTACACAGAA 1 115 +CCATCGGGATCG ref:1:11:ACATACCCATTATCC ref:0:12:GGGTTTCCACCATC 5 2808 +ATTCCAC ref:0:7:CTAATGGATCCCCGGG ref:1:4:CTGACGGCC 3 180 +GAT ref:0:3:ATCAAA ref:0:3:A 1 1 +TTAGCTTTCATTATCC ref:0:16:GTCTAAG ref:0:16:CCCTGCACTCAGC 9 1100972 +GGGGCCAA ref:0:8:CTGTGCCACGCAAC ref:0:8:TATCATCT 5 129276 +CCCTAGTGC ref:0:9:AAA ref:0:9:ATGGCCATGTG 4 825 +CATTGAGGAATTGG ref:1:13:GATGTT ref:0:14:A 8 36 +GAC ref:0:3:GCACGGCCACTA ref:0:3:AAGTCCTGCTGTCTAT 6 329 +CGTTTCCGCGAACA ref:0:14:C ref:1:12:AAGAATGGACC 6 250 +GGTAGCGAAAA ref:0:11:TAAGAAGCATG ref:0:11:ACTTACTTGCGAAC 4 7840 +CAA ref:0:3:TACCATTGAGGATA ref:0:3:GCAGGGCCG 3 96 +ATG ref:0:2:CGGA ref:0:3:TGTAG 2 6 +AGC ref:0:3:ATTCCATGCG ref:0:3:GATT 2 20 +ACGTAAT ref:0:7:TTAAAATTGAGTCGA ref:0:7:TTTTG 6 25344 +CCGATGTTAGA ref:0:11:GGGAAATTATACGG ref:0:10:CTTGTGG 3 6570 +GGTTATCACTACAACA ref:0:16:C ref:0:15:CCATAGATAGTGT 9 360 +TTATTTAGTG ref:0:10:TTGCAGTAAAA ref:0:10:TGGAGGAAGAA 9 717002 +T ref:0:1:GTAACCTAG ref:0:1:CATTGCTGCT 3 8 +ATTCTAGGC ref:0:9:A ref:1:8:CGTGACCAATTG 4 694 +CG ref:1:1:ATAA ref:0:2:AACCCTGAAC 3 15 +CATCACGAGGCA ref:0:12:TAA ref:0:12:AAACCGAATATGCCC 4 6336 +CCTTACTGTAC ref:0:11:A ref:0:11:ACTAA 7 28 +TGTTGT ref:0:6:T ref:1:5:ATCTGTAT 1 16 +CTAGTCT ref:0:7:AT ref:0:7:CGCCACGG 3 168 +TTGGGG ref:0:6:ACTGTATGTC ref:0:6:CCTGC 5 9600 +ACTCCATTA ref:0:9:CC ref:0:7:GATTAGATGAAC 1 81 +CGGGATGATCTTAAAG ref:0:16:TAACGTGCTGAT ref:0:16:GGT 9 3339 +CATATCATGCCGATTT ref:0:16:AAA ref:1:15:CGC 9 8 +ACC ref:0:3:TATTAG ref:0:3:GGCA 2 234 +GCCTAGATAGA ref:0:11:CATA ref:0:11:TGCGTCTG 4 216 +CCTA ref:0:4:AGCTTGTCCGCGTACG ref:0:4:GGTTG 4 228 +AAGGTCCAAAGA ref:0:10:GCACA ref:0:12:TAATTTTGCCAGACTA 4 12584 +CAGGCGGC ref:0:8:GTG ref:1:7:AAACGTA 4 1260 +CGGCCTGTCTCACACT ref:0:16:AGTTTG ref:0:16:AAGGCCG 9 171 +GAAAAT ref:0:6:TCGA ref:0:6:AAC 3 64 +TC ref:0:2:GTAA ref:0:2:TAGT 2 15 +CGGAG ref:0:5:GACAACCGAGG ref:0:5:GAC 1 108 +ATCTAAGAGCA ref:0:11:CGTCCGA ref:0:11:ACAGCTTTGAGAA 5 39552 +TGAT ref:1:3:ACGCAAC ref:0:4:GCGTTGCTG 1 20 +GACGAAGTATT ref:0:11:TGTAATGCTCTCAC ref:0:11:TG 6 4750 +CCAAG ref:0:5:CAAGTA ref:0:5:GACCGGTGC 1 28 +CTCTTCGTCCTA ref:0:12:ATCAACCAGGTATGAA ref:0:12:ACTAAAGCGAGTCTG 8 229104 +CGTAGCGAGGTC ref:0:12:TTATACGACGCTATA ref:2:10:TTGGTTCGGACAGG 4 27136 +CAT ref:1:2:GTA ref:0:3:CAAAGGTGAGGGCACT 2 27 +CACCGC ref:0:6:TCTTTCCGGCAACCT ref:0:6:TGTCA 3 144 +GTCT ref:0:4:TTTTGT ref:0:4:CTGTCTTAGCC 3 94 +ATCGTCAGCATCC ref:1:12:GGAAAAAG ref:0:13:GGGCCAGGCGAGC 7 2332940 +TTTGAGCAT ref:0:9:CAATACG ref:0:9:AGAGTAAG 7 3551 +TCTTGGCGATC ref:2:9:GCA ref:0:11:CATGAGCTCCGTG 2 48 +AAGGATACCAGAAAA ref:0:15:AGTGGGATAACTCCA ref:0:15:CTTGA 6 264480 +CTCAGGCA ref:0:8:TAAGTAGAAGTGTAA ref:0:8:GGGGTTTTAATC 7 610790 +CTACGTTTCCCAGC ref:0:14:CGCTC ref:2:12:ACACGCCACTG 5 3944 +CCAG ref:0:4:CTTTCGTGTCAAT ref:0:4:TTACGAA 5 570 +CTTCGATT ref:0:8:TCA ref:0:8:GAGTATCCGT 2 32 +GGGCGGCCTAA ref:0:11:AGGCCCATC ref:0:11:AGTACCCCC 7 20608 +TCTAAA ref:0:6:CGAGATATAT ref:0:6:CATGACTTACGGT 6 915 +TATATCAGGC ref:0:10:AAAGA ref:0:10:CCGACAAGTGAT 6 840 +TACGTT ref:0:6:CCTAAATGGCTGCA ref:0:6:TGGGTCGACTTT 3 4628 +GCCC ref:0:4:T ref:0:4:CA 3 30 +GTCTCTCACGGG ref:0:12:GTATGGTTTTGGACT ref:0:12:AGCAGATACA 7 346122 +TTTCTGTAT ref:0:9:T ref:0:9:TCCG 6 72 +ACCCCCAG ref:0:8:GC ref:0:8:CCTCAGAAAAGAG 3 9471 +TAATGCCAGGA ref:1:9:TCGACATT ref:0:11:GGGCGGGGCG 4 67032 +CGC ref:0:3:GATTTTAACCAATG ref:0:3:TTACCACCTTAGCGCT 6 65 +GACATCCCAGCCGA ref:0:14:AAAC ref:0:14:CGTATCTCGTATCG 5 630 +GT ref:0:2:GACGCC ref:0:2:AATGG 2 54 +TCCTGTTTCTCGG ref:0:13:T ref:0:13:CCC 9 24 +CA ref:1:1:TGAAAGCCTG ref:0:2:TGACTACTG 4 3 +CTAC ref:0:4:ACCGGC ref:0:3:GTG 3 80 +CCTTTCGATATT ref:0:12:G ref:0:12:TCAGGTCCGGCA 7 1926 +TGCATTCGTCGC ref:0:12:CAG ref:3:9:TACCTGACGCC 3 202 +ACTATGACC ref:2:7:GTGGGACCAGA ref:0:9:AACGTCCAT 4 361 +TCGCTAGGCCCTG ref:0:13:CTTCTACCA ref:0:13:CCATGCACGAG 6 8550 +GCTCGG ref:0:6:CACGGGA ref:0:6:TTGGAAGG 2 516 +CTGCACTAT ref:0:9:A ref:0:9:CC 6 6 +ATTAGGAGGA ref:0:10:CTAAGTC ref:0:10:TCATATTG 6 7335 +TCTAGAT ref:0:7:GCGCAAAAA ref:0:7:C 4 506 +TCTGCTT ref:0:7:ATGGTTCTC ref:0:7:AGCAGAGGGGCGT 4 26136 +CCTCTC ref:0:6:GGGCCAGT ref:0:6:CGTATACTTAAAT 3 1392 +GCACCCTTACTAGG ref:0:14:T ref:0:14:ATCACACATTCGT 6 192 +TATCTGCCCGCTGG ref:1:13:AGATTGGGTC ref:0:14:CTTGCTACCGCCA 4 13464 +GAACGAAGGG ref:0:10:GTGGAGCATTCGATCC ref:0:10:AAGTGAGTT 5 20625 +CGACGTTGATCTGT ref:0:14:A ref:0:12:CCAATTGTTCA 5 238 +TTGAGCACGCA ref:0:11:AC ref:0:11:GCGAGGCT 6 190 +GCGCCC ref:0:6:TTGACG ref:0:6:ATCTACCGG 2 64 +AAAGAGTGT ref:0:9:TGAA ref:0:9:TAACATCATGGAGA 5 5838 +CG ref:0:2:GCGCGT ref:1:1:TTAA 1 15 +TGCT ref:0:4:TCATGTCAC ref:0:4:CGAGTTGAAACGA 4 72 +A ref:0:1:GTTCTAAAT ref:0:1:CTCTTTCCAAGGAG 5 9 +ATATTCCAAAGGTC ref:0:14:CGCTAGAGTCTATA ref:0:14:G 7 32 +TCTCTAAGAAATT ref:0:13:AAGTTCGCTTAACACG ref:0:13:GTC 7 21328 +T ref:0:1:GTGG ref:0:1:TGTAAATTC 1 4 +TGCGTGACTCT ref:0:11:CTGCCGACAGATCC ref:0:11:T 3 200 +GATCTAAAATGA ref:0:12:TGCGTTCTA ref:0:12:CCCTCTACTTTCT 8 811440 +AAACG ref:0:5:CGAAACGCTC ref:0:5:CATCGGTAGGTT 2 68 +TGG ref:0:3:GAATGGGCG ref:0:3:GTGTATCTC 2 54 +ATTATGCAAAAGG ref:0:13:GAATTGGTTTATAC ref:0:13:TTGCTCACGGCTT 6 1792395 +CTGACGT ref:0:7:TTTCTTGTTA ref:0:7:GGTACGTGCAGAATTC 3 208 +AATCAGATTCGAATG ref:0:15:GACTCT ref:0:14:ACATA 7 144 +AAAGGCTAGT ref:0:10:CCG ref:0:10:CCCTATATGGGCT 4 585 +GTACCGC ref:0:7:C ref:0:7:TTCTTCAAGT 3 24 +GTAAGG ref:0:6:TTACTACCT ref:0:6:CCAAATACAATTG 4 2340 +A ref:0:1:TAAGAGTT ref:0:1:GGAATAG 3 9 +GGATAA ref:0:5:TTGACAGC ref:0:6:GTGAG 3 120 +AGTCGCACATAA ref:0:12:CCTTGTT ref:0:12:TATACGTTA 8 11875 +AGTCAGC ref:0:7:TGGTCA ref:0:7:TCGCGAATAAA 1 5 +TTGT ref:0:4:ATAGTTGCCTCTG ref:0:4:ATGGTCGGCGTATGC 5 36 +AAAAAAT ref:0:7:GCG ref:0:7:TCGTCTAGATTC 7 205920 +CAACGTGA ref:0:8:GCCCGTGGACTGCACT ref:0:8:ACAGCCTTACG 4 6710 +GGCCCA ref:0:6:AGATTGGGCTGAGAC ref:0:4:CCAAG 2 288 +ACCGCGAAA ref:1:8:GCCGA ref:0:9:CACGGTAAAGCGCCG 1 63 +AGTGCGAA ref:0:8:CAC ref:0:8:GTCGC 4 16 +CCTACA ref:0:6:AACGCCAT ref:0:6:TTTTGTACATTATGCT 2 124 +CGCTCTGAG ref:0:9:TTGTGCA ref:0:9:G 5 72 +TATCT ref:1:4:ACGAACGTC ref:0:5:GCCCTAGGCTTCG 3 132 +ATCGA ref:0:5:CTATCCTCGGAGCCTT ref:0:4:CGACTGCTAATGT 2 8 +AG ref:0:2:AGCAGTCCGGCAC ref:0:2:TACTCGTTAAACAACT 6 7 +AACAGGAT ref:0:8:CATCGATTGAGACA ref:0:8:CCA 3 176 +ACTGTTTAACTGTA ref:0:12:GCAACCGGA ref:0:14:AACCATTTATT 2 2880 +TAA ref:0:3:TCTTCGGCCTCACTG ref:0:3:CCTCTCCGC 7 1978 +GC ref:0:2:ATGAGCAAAAG ref:0:2:TACATT 3 6 +TAGATATTTC ref:0:10:GCTA ref:0:10:AAACCGAAAAT 4 552 +G ref:0:1:GAGCTGGC ref:0:1:GTAGATCC 4 8 +TGG ref:0:3:GGGCGCCC ref:0:3:CCGT 2 130 +TGCTGACACC ref:0:10:CTAA ref:0:10:CCTCTGT 4 6 +TTGATGCGGG ref:0:10:C ref:0:10:CTCTTTGCGAGATAA 3 48 +CGGTAGTGTCA ref:0:11:CCCTA ref:0:11:ATCTCGGGGC 5 208 +TCC ref:0:3:GCCAT ref:0:3:CTATCCGCC 1 24 +TAAACTAAAGA ref:0:11:CTATACGC ref:1:10:TGTAC 6 54 +CCGA ref:0:4:GCT ref:0:4:ATTTAG 3 741 +TC ref:0:2:AAGA ref:0:1:CGCGTATAA 3 30 +TTTT ref:0:4:TGCCCGCTAT ref:0:4:CCAACGA 6 3630 +AGCTCGTGTATAAC ref:0:13:TAT ref:0:13:CCTGT 7 6 +CCAAACATTATC ref:0:12:ACCGAACAATCG ref:0:12:CACAAAGACGCCCG 4 3464 +TGTCCCCGTAGGGTGT ref:0:16:GAAG ref:0:16:CTGTTCTCTAAGTC 8 65100 +CGGCC ref:0:5:AAAGACTCGGGCGAT ref:1:4:TAGGC 2 64 +AACGAAAATGGCC ref:0:13:CCAGAAT ref:0:13:GCAACGT 7 74 +TGAGCTGCGTAGCAGA ref:0:16:CGTTAGAAC ref:0:16:CTGCGTA 6 45 +GACTTGTTCTG ref:1:10:GCT ref:0:11:TAAGTGG 5 201 +TTCTGGTTCA ref:0:8:TACTGGGTAATG ref:0:9:ACCATAGGAGCGC 4 3078 +ATGATACCGT ref:0:10:GTTACTCACTA ref:5:5:GATG 2 245 +GGAACC ref:0:6:GACAGTTACG ref:0:6:TGCTACG 5 2592 +CGCTGA ref:0:6:AAAAGGTTC ref:0:6:AAAC 7 8112 +ATGGGACTTTAC ref:0:12:GATTTATTG ref:1:11:CGGTCTTACAT 4 660 +G ref:0:1:AA ref:0:1:ATGTGGTTATCGTC 2 12 +CCATA ref:0:5:AGTCAATTCGT ref:0:5:AGCC 4 119 +AAGGT ref:0:5:CCGGAC ref:0:5:AACTGAGGA 3 198 +CCTTTTTAAG ref:0:10:TTTGTTCCA ref:1:9:ACGGGTAGGTTT 2 44 +GATGTTTGTGTT ref:1:11:AAGCA ref:0:10:ATAATGAACT 6 7056 +CAGGCAC ref:0:7:CCAG ref:0:7:CCCAGCAA 3 108 +CGG ref:0:3:GTACCGGGG ref:0:3:CCGATATTTTCC 1 276 +ACTTACTGCCT ref:0:11:T ref:0:11:GCGGA 8 808 +GTTCAATGATGT ref:0:12:AACCA ref:0:12:TGTTGGTC 3 24 +AGCCAGCGCTCGTCAG ref:0:16:GTCGTTCGAGA ref:0:16:TC 8 180 +CTCGTTTTAAT ref:0:11:C ref:0:11:GAGACGTCAGCCTGA 5 180 +GGTTA ref:0:4:GATG ref:0:5:TCCCGGGC 2 216 +TTTAAGGGTATTCGC ref:0:15:TCCAGGGAGATC ref:0:15:GAGTTCCAGTATATG 6 86739 +GATATTTCT ref:0:9:CTCCTCGCAG ref:0:9:AC 5 2014 +GACCTTACCAC ref:0:11:CCAAGTCTGCT ref:0:11:CCGAGATAGGAGTTAC 8 332151 +CGCGTCTATGATGT ref:0:14:CACGGTCGTCC ref:0:14:ACGCATAAC 6 7600 +TAGCGTTAAACTA ref:0:13:AAT ref:0:13:C 9 12 +GGACCCAACTCAGCGC ref:0:16:GTTCTTTA ref:0:16:TTCTTCAGAC 12 3017500 +GCACTCGGTGG ref:0:11:ATGCGC ref:0:11:CGTGTCGACCTACC 5 1680 +AACACT ref:0:6:CAAGCGTACG ref:0:5:AGTCCGGCGGAAAA 3 452 +CCCCCC ref:0:6:AAGTGAGTTTGCA ref:0:6:AGGGCTT 10 6785856 +TTACGGGCAGAGCT ref:0:14:ACAACGG ref:0:14:GACTAGCTGG 9 6240 +T ref:0:1:CATCCCTGGTATG ref:0:1:CGCCCATTAT 7 12 +TATGAGATCGAG ref:0:12:TAATCCTTGACGA ref:0:12:GCCCC 5 14691 +TTTCGCT ref:0:6:AGGCA ref:1:6:ATGGCCATCCTG 2 20 +ACATGGGTGG ref:0:10:GAATCAGTCCAGAC ref:0:10:GTC 5 1008 +GCGAGAGTTGAGA ref:0:13:TACTAGG ref:0:13:TCCAAAATACGCAAA 7 1421869 +TACATTTCG ref:0:9:AATGTGCCCCC ref:0:9:GACTTGGGC 4 5544 +GAGA ref:0:4:CTGCTCCTGCCC ref:1:2:CCTTATAGGC 4 96 +TCACTAATGTCTAGT ref:0:15:AAAAAAAA ref:0:15:GATAGTGACGCATTGA 8 7069824 +CACCGCTTA ref:0:9:C ref:0:9:TAGGGAACATCCATC 4 1220 +AGCGGGGCTTTCTTTC ref:0:16:GGTATCCGTGAGTT ref:0:16:CAAGAAAGTT 7 357750 +GAAGTACGTTATAG ref:0:14:GCGAAACAACCTCC ref:0:14:AAG 6 1008 +GGGTAGCGTTACC ref:0:13:TAATCA ref:0:13:ATAAA 10 3770 +CGGCCTT ref:0:7:CTCAT ref:0:7:GA 4 363 +TTGACCTGTGAA ref:0:12:AA ref:0:12:CGCTCCGATC 6 1680 +TGAAGA ref:1:5:CGCGTCATA ref:0:6:ACTTAC 4 1410 +GACGCTTAACATTTG ref:0:15:TTA ref:0:15:AA 11 18 +CGG ref:0:3:G ref:0:3:CCCCACGAACT 1 88 +CCTGCTTCACA ref:0:11:GGAACGAGGAC ref:0:11:CC 7 10120 +CTATTGCCCGATG ref:0:13:A ref:0:13:AAGAC 10 170 +CCG ref:0:3:AGCC ref:0:3:T 1 4 +TTC ref:0:3:CC ref:0:3:CGGCTTCTCATAT 1 16 +GTAATAGTCTCATATT ref:0:16:GCACA ref:0:16:ATCATGG 10 13104 +CATTA ref:0:5:GCACAGGTAACCAGA ref:0:5:TG 2 445 +GAGAGTCAGTC ref:0:11:CACTAGAGCTT ref:0:10:CCAAAG 6 198 +AGGCAAC ref:0:7:TCTCCT ref:0:7:CCGCCACCAG 4 9240 +CGA ref:0:3:GGCCTTCACAAAAG ref:0:3:GCTT 4 1210 +TATCGCATT ref:0:9:GGACCGAG ref:0:9:GCAT 3 72 +CGC ref:0:3:TCATGTCAATC ref:0:3:TAGTATG 5 44 +CGCGGGGCGGAGGG ref:0:14:TAACTT ref:0:14:GGCGCGCGA 7 648550 +CCAATTGAC ref:0:9:AAAACTACGTTT ref:1:8:GCGTAT 3 1377 +CGGACGAC ref:0:8:TGATC ref:0:7:GAGCGGACCTGGAGT 2 144 +TGTAACTTTG ref:0:10:A ref:0:10:CGAACT 5 12 +TCGCATATGCGCG ref:0:13:GGAGCGGGA ref:0:13:GTGGTCATTCGGCAA 5 1440 +ACTAAGCGTCACCGTG ref:0:15:CTTTTCTCGAGA ref:0:16:TATCAGC 7 980 +AAAACCGTGAGCG ref:0:13:TCAAGGACAGGTGGGG ref:0:13:ATAGT 4 9360 +GGCTTTCCCATA ref:0:10:CATCAGCGC ref:0:12:ACC 6 186 +TACCGA ref:0:6:GCCTACTGATA ref:0:5:CTTCTGGCC 3 288 +TTGAACAAATCCCAAG ref:0:16:TGTACGTAC ref:0:16:ATTCATTC 9 21312 +GCTCCATGGTCG ref:0:12:TTTT ref:0:12:CGTCCGGCCAAT 4 364 +AA ref:0:2:ACATTTTGAC ref:0:2:CCCCGCAAC 2 3 +CAGAC ref:0:5:GGCATTTTACGTCG ref:0:5:TTTTTGATACCGT 6 1568 +TCACCACTA ref:0:9:CC ref:2:6:TTAGGCCCTT 1 12 +CCATAGCTTTGTCGA ref:0:14:TCGTATC ref:0:15:TCTGGTAAGCG 8 17864 +G ref:0:1:GTGGCGTCAATGT ref:0:1:ACTCTGTTGT 6 10 +CGTGTGCACATG ref:0:12:GTAGGGCA ref:0:12:GTACCCATCA 5 2786 +GA ref:0:2:CAGCGGGAC ref:0:2:ATGGAGG 2 8 +CCGGTAACT ref:0:9:GTGCTCCTTA ref:0:9:GTATTCATGGACTT 5 528 +CTTGAGAGCCGAT ref:0:13:GCACCTCA ref:1:11:ATGTGTAGTG 3 2120 +ACTGAC ref:0:5:TCT ref:0:6:TAT 3 6 +GTATGC ref:0:6:T ref:0:5:TTCGA 2 2 +CTTCCGAGTACTAC ref:0:14:GAAGATA ref:0:14:GCTAAAG 6 8 +AGGGATCTAAAGGCC ref:0:15:A ref:0:15:TGGACCAAGATTT 8 27650 +GTTAGTAA ref:0:8:CAACATGAGTG ref:0:8:GTAGTGTGCCCCTTT 4 49674 +ACCCTCGG ref:0:8:G ref:0:8:CTGATGCCT 4 18 +GC ref:0:2:CCTA ref:0:2:TTATGATAAT 2 18 +ATGTTACTGATC ref:0:10:TTCGCCGGTTG ref:0:11:GAGCT 4 834 +CTACCTGA ref:0:8:AAAAGACCTTT ref:1:7:AC 3 820 +TTAGCCCC ref:0:8:AGCCAACAAGT ref:0:8:TTTCAGTTCAAT 4 2520 +T ref:0:1:AGGTCGTGGGC ref:0:0:CC 1 2 +AGATGCATGCTACCGA ref:0:16:GCCATC ref:0:16:GGCCTCTGGTAAAAA 8 178830 +CAGAAAG ref:0:7:TCCCCCT ref:4:2:CGTGACATT 3 791 +GATGTTAACAACGAA ref:0:15:TTTGCATTCCGG ref:0:15:CCCTTTAGAACAT 6 38640 +GTGCCTG ref:0:7:CATGAGGGGGTAGAC ref:0:6:ATTTATAA 6 36432 +T ref:0:1:CACGTA ref:0:1:TTCTGTACTCTTTCTT 3 10 +TCTACGCTTGTAAT ref:0:14:GGTC ref:0:14:CACGAACGTAG 6 25 +CGA ref:0:3:AAGCCAC ref:1:2:TTTTGAGCACTTAAC 4 42 +CTGAATT ref:0:7:CCCCGGAGGAA ref:1:6:GTGC 3 1512 +CTACGGACCAA ref:0:11:TAATTAGTATCT ref:0:11:G 6 1472 +AACTTCTCAGATA ref:0:13:CGGACCGCCAAC ref:0:13:CCA 7 3690 +TA ref:0:2:AGTTCTCACACT ref:0:2:ACTGATGTC 3 6 +TCCTGCACT ref:0:9:C ref:0:9:CTCG 6 68 +GTAACTCAGGT ref:0:10:ATACGTGGACC ref:0:11:ACTTGTT 4 220 +ACGGACGCTAC ref:0:11:TCCGCTATCCGG ref:0:11:GAAGGTGGCTG 2 420 +TATATTCG ref:0:6:GG ref:0:8:GGAGATC 5 336 +AG ref:0:2:TCTCATCCGC ref:0:2:CGTTAAATGTAGCATA 4 7 +ATCACAGTCT ref:0:10:C ref:0:10:TACTATAACAC 4 72 +ACGTACGT ref:0:8:CACGACGTGGAGGCTC ref:1:7:CCCTCCCAGTGT 3 3168 +ACTAG ref:0:5:A ref:0:5:ATTAATCCTCACTCA 1 98 +ATAGTGGC ref:0:8:TGAGTGCC ref:0:7:AGCTT 2 45 +GAAGTTGAGTG ref:0:11:TACTTATATC ref:0:11:ATC 7 8512 +TACAC ref:0:5:AATTACAGTGCGTTAA ref:0:5:GTTTGGCACGGG 2 24 +CAAGCTGGTC ref:0:8:T ref:0:10:TCTGTGCCATTTT 5 849 +CGCCCGATACACG ref:0:13:GGA ref:0:13:CTGTA 8 72 +TCCAGCAC ref:0:8:AATTTTAGCCAGCTCC ref:0:8:CTATTAT 1 1152 +G ref:0:1:CGCGTG ref:0:1:GAATCCAAGCCGGT 4 12 +GTGTTCAAA ref:0:9:GGGATTTG ref:2:7:GGCA 3 1380 +CTCA ref:1:3:GGT ref:0:4:CCGGTAGCATATAA 2 8 +CACGAGCAAGAAATT ref:0:15:CTGTGTG ref:0:15:TGAGATATTGGA 9 60180 +ATCGGCG ref:0:7:TGCCTTGCGTGCCA ref:0:7:GCCATTC 5 798 +ATTAGTAT ref:0:8:GAACCCTACAATAG ref:0:8:ATACTTTAATCT 4 53320 +ACGGACTTAAA ref:0:11:G ref:0:11:CAAAAGATATC 6 1862 +CTCG ref:0:4:GACACCAGATTAC ref:0:4:ATTT 3 300 +CCAACTGAGGCG ref:0:12:GCTTGTGCAACGCAG ref:0:12:T 3 6 +CCGTA ref:1:4:AACGGAATAGGAGA ref:0:5:AGATG 3 54 +CAAGCGATT ref:0:9:GGGCTGCGCT ref:0:8:CTCGCCGAGCAATG 4 1995 +AGTGAAAG ref:0:8:GT ref:0:8:GGATACCAAAGCG 2 76 +ACTACTCCTATG ref:0:12:AA ref:1:11:TCCACCAGTTA 5 840 +CTGTAGTT ref:0:8:TAC ref:0:8:TACGAG 4 16 +ACCTTTACGT ref:0:10:TAGTTGAGTCAC ref:0:10:CGCT 3 306 +C ref:0:1:GGTTCCTACTG ref:0:1:ACAGACTCGA 4 9 +TTCTTATAAATTCG ref:0:14:GTCGCAAGATACTTCA ref:0:13:AAATTTCA 6 598 +TTGATCTTCCGTGGCG ref:0:16:TATGCTCG ref:0:16:ACTCGGGTCAGG 5 792 +TCGTGCC ref:0:7:ATCCCCAAC ref:0:7:CGAGTCTACCTGT 3 672 +TCGGATCTCT ref:0:10:CGACTCTGTAT ref:0:10:TT 3 132 +TCGTACAGC ref:0:9:CAACGGA ref:2:7:TTACTACGGTT 4 912 +TCATCCCG ref:0:8:AACCAGG ref:0:8:GT 4 282 +GCGATCTG ref:0:8:AAATAAATTAAGGAA ref:0:8:AGCAGGCCGTGGAAT 5 26000 +TCGAGGGGCCC ref:0:11:GTTTTGCGGT ref:0:11:CTAGC 5 68328 +CGACCGGT ref:0:7:AGAGTCGAGGAGGGA ref:0:8:ACACGTATCTATCTGG 3 498 +GGAGCACTG ref:0:9:ATATC ref:0:9:ATGG 5 45 +AAAACAAAGTTT ref:0:12:TTGACCCT ref:0:12:GATAG 8 560160 +GATA ref:0:4:ACTTAGTCGAGTGAGA ref:0:4:TTACGGGGTTTTCGT 6 1760 +GGATCAAC ref:0:8:CTTCATATAGCCCGCG ref:0:8:AAAAGGCTCTATAGTA 5 2964 +GC ref:0:2:ATACCA ref:0:2:TCGAGAG 3 99 +AGATTAACTTCTAAAC ref:0:16:CTCGGGAGAGTCAA ref:0:16:GGCTAG 9 1040445 +CACCTTTCTATGCAAC ref:0:16:ACGACTT ref:0:16:TACACA 9 2232 +TC ref:0:2:GTGGTTAACG ref:0:2:GCCCCACTTAACAGGC 5 12 +GACTGCGCA ref:0:9:CTATGC ref:2:7:GAAG 3 220 +A ref:0:1:AAAATGT ref:0:1:GCCGTTT 2 32 +TAGGCCC ref:0:7:GCAGAAGCTT ref:0:7:AGAAAG 5 30 +TTTTACTAGC ref:0:10:ATCGCC ref:0:10:C 6 52 +G ref:0:1:GGTCCCCAGCTTGGGT ref:0:1:CCAGAGAGAACA 5 18 +GTAATTCTCTTACTTA ref:0:16:AGGCTGTTGAGACCC ref:0:16:AGCGCACAAG 9 100992 +AACCGATGGTATC ref:0:13:GT ref:0:13:GCATTTGCACCGC 7 10605 +A ref:0:1:TTTCCT ref:0:1:ACACTGGACTGC 3 21 +GACC ref:0:4:CATTTAGTCTCGGTTG ref:0:4:GGTATCAAAT 3 140 +GCGACTCTTGA ref:0:11:CA ref:0:11:T 8 12 +CTA ref:0:3:ACTTACCGGGACCT ref:0:3:AAACCTTGGAG 4 16 +ATTAGCT ref:0:7:TGTGGCTTGTCGT ref:0:7:TGAGGGAGGATCTAGG 5 2440 +TAGGGAGGGTGGCCG ref:0:15:TCTCTGTGGA ref:0:15:CCA 9 10356 +TATGGCTCCT ref:0:10:ATAGCGGAGGGAG ref:0:10:GAGACGATAA 8 2682863 +CGTCATGACGCGGT ref:0:14:ATAGGGG ref:1:13:CAGCCGGG 5 77 +CGTTG ref:0:5:GGCGAGCTGCAGT ref:0:5:AT 2 168 +GCATGGCCGAAC ref:0:12:TCGTTGGAT ref:0:12:AGCACCTCT 3 1000 +GTCGCT ref:1:5:ACTTCGATGCGTC ref:0:6:TTCG 1 12 +GG ref:0:2:ATGACACTTACGC ref:0:2:TCTGCAACACCGTT 6 1 +GTCCTA ref:1:5:TCTGCTGAACGGTAA ref:0:6:TAG 1 24 +CGCT ref:0:4:G ref:0:4:AGGAGTGCATCTGTGA 1 93 +GTTCTCGACATGCGT ref:0:15:AGAAGG ref:0:15:GG 10 48 +AGGCTC ref:0:6:GTT ref:0:6:TG 4 63 +TCTCTTGCACTCGTC ref:0:15:TAATTAA ref:0:15:TATGCACC 8 14280 +GCT ref:0:3:ACGACGA ref:0:3:CGCTT 1 6 +TACCG ref:0:5:TGCTATACTGGAGGT ref:0:5:CCACGATTATAAG 5 9672 +ATCCGTT ref:0:7:GGACGA ref:0:7:GTCCTGTAATG 2 12 +TCGTGCCTCCAGTCC ref:0:15:CCT ref:0:15:ATATAA 10 3874 +GGGCGGCGCCG ref:0:11:GGCCGCTGC ref:0:11:AGATCAA 5 213624 +TAG ref:0:3:CGGGAGTAC ref:0:3:ACCGAACCGCTTGC 5 196 +AGTTAGTCTAG ref:2:8:CTGGCGAT ref:0:11:A 4 117 +GCGCTA ref:0:6:AAATGGGCT ref:0:5:AGTTTCCGG 2 44 +G ref:0:1:CGATTAGATGCGAT ref:0:1:TGCAG 3 8 +CA ref:0:2:AAGTAAAATTG ref:0:2:TTATAATTCGTAGCGC 5 29 +CTTT ref:0:4:ACGGGCGCGCGTAGA ref:0:4:TGCATCAG 5 6510 +ATAGTTCCTAA ref:0:11:ACCTCCATCAATAGT ref:0:11:CTCAGAGAAGCGCTG 5 59055 +GAG ref:0:3:A ref:0:3:CCCTTGCTA 1 1 +TACAAG ref:0:6:GCCACCGGTTA ref:0:6:GCCTAGATAGAGAC 5 2400 +GGTGCCGGAG ref:0:9:TCCATTTAGCTACA ref:0:9:ACGCATT 5 5610 +GGAATCTTAAAATC ref:0:14:ACACCCGGGCC ref:0:14:GA 9 94512 +CG ref:0:2:ATGAGCGTCCCA ref:1:1:GGGCAC 2 3 +TTCCCATTTAGACCG ref:0:15:AGCCCTTCCA ref:0:15:TATT 6 216 +ACAACGAACAGAACC ref:0:15:GAGT ref:0:13:GATTGACTCTCACG 7 27855 +TGAAGCATCGCCCA ref:0:14:ATGGCGATGAA ref:0:13:ATACCGTC 4 90 +ACTATTAC ref:0:7:TACCTACT ref:0:8:TT 2 18 +GT ref:0:2:TTAG ref:0:2:AACTCC 1 16 +CTATTTGC ref:0:7:GTAATATCAGAT ref:0:8:CCTGACAA 2 570 +GTGGCAAGAAT ref:0:11:CCCCAGTCCGTTC ref:0:11:GA 5 336 +GG ref:0:2:CGGGTCA ref:0:2:TTACAAA 3 108 +TCGCATCGG ref:0:9:GAGCGGC ref:0:9:GGGTCATC 2 24 +CTATCCCGGGTCT ref:0:13:ACGCGGG ref:0:13:AATCTATAAGG 4 140 +AGG ref:0:3:GAGGGTGT ref:0:3:TAACTTTTTGATACAA 2 174 +CGATCGCGGACGG ref:0:13:CTCATTAGCGCCGT ref:0:13:GTATTTAC 5 14196 +TTTCTGACGACAGCCC ref:0:16:ACGTCGTG ref:0:16:ACAAT 10 370 +CTT ref:0:2:AACTAC ref:0:3:AAATCGTAAAG 3 11 +ATCGTGAACGT ref:1:10:GACTC ref:0:11:TCTAAGCGG 1 12 +GGG ref:0:3:GCGCCAGCCATGGG ref:0:3:GCAGACGCCGACCCC 5 80 +GGGC ref:0:4:AAAGTTCGAA ref:0:4:ACACC 4 3422 +AATGGTAGATAT ref:0:12:TTAGGATCTCTAAC ref:0:12:TATGAGCGGGTGCAT 4 19412 +AA ref:0:2:CCGAAACTC ref:0:2:CATATATTTGCGGAA 4 30 +GGTAACCATGTGT ref:0:11:TGTCATCTCC ref:0:13:GCC 4 24 +GTCCAGATG ref:0:9:TGGCTCATCCTGAAAA ref:0:9:AGCTGTAAAGT 5 212784 +GT ref:0:2:AATTTGTGCTCATT ref:0:2:GCCGCCTTG 4 28 +CAGTCCAGAAG ref:1:10:TGAGGGAT ref:0:11:ATTCCT 4 3222 +ATCACAA ref:1:6:CAGAATC ref:2:5:AAATGCGA 3 48 +CCG ref:0:3:AGC ref:0:3:TTTACGCGA 2 7 +CCTCAGCTAA ref:0:10:AGAG ref:0:10:TAACCCAATTC 4 336 +GGTACTAC ref:0:8:TTGCGGTTT ref:0:8:GT 4 84 +CCCGCTCCTAGCGTA ref:0:14:AGCCTGGC ref:0:15:GTA 8 420 +CACAACACA ref:0:7:ATATCCGAT ref:0:9:T 4 220 +GGTCGAGCGAC ref:0:11:AAAGTGATGTCGGA ref:0:11:AAGTCGGG 4 40 +CAGGACATAATCCAA ref:0:15:ATTTTACTAAGTAC ref:0:15:TTACCCATTAATCCC 7 87300 +GTGAGTTTAGCTC ref:0:13:CTACGTCCTACTATCC ref:0:13:AGACACATGTGTCAG 5 32544 +TGCC ref:0:4:AACGAA ref:0:4:GTAACCTGAGGT 5 232 +CTACGCCT ref:2:6:GAGC ref:0:7:GG 3 16 +GACGTTTTTCCGATT ref:0:15:CGA ref:0:15:TATATCCTTGATGTTG 6 944 +CACCTCAT ref:0:8:TTGCTGTGCCC ref:0:8:AACTTA 1 155 +CCTAAATCAAG ref:0:11:GTCTC ref:0:10:ATCACATAAAT 3 20 +GTTG ref:0:4:TGGTCCTGCTGCC ref:0:3:GACGGT 2 88 +GGTTTGTTAGTCAA ref:0:14:GGTA ref:0:14:GTTCGGTACTGTCGTA 4 9672 +TTTGA ref:1:3:CTT ref:0:5:TTGTCT 1 21 +AGACTAGTCTACT ref:0:13:GTTAGCA ref:0:13:CCCGAATCCTTATT 3 192 +TAGGAA ref:2:4:GAGCTAG ref:0:6:GA 1 28 +TATTG ref:0:5:CCACGCG ref:0:5:ATTACCAAA 3 273 +CCACTTGG ref:0:8:TACGTCCACG ref:0:8:AGATAATGTGTCT 2 54 +CTCG ref:0:4:AAGTGT ref:0:4:ATCGCT 3 8 +CGAGACCAC ref:0:9:CCCCCGGTCCG ref:0:9:TG 4 330 +ATGGTTGCAATATT ref:0:14:GATCTC ref:0:14:CCAA 9 3892 +C ref:0:1:CACTCCCGCTAGCTGT ref:0:1:CGCCCCTGACCTATCC 9 63 +CGTGGAATGCAGAGCA ref:0:16:AATCTGGATC ref:0:16:ACGT 10 440 +GTAGGGCCAT ref:0:10:A ref:0:10:AAA 8 22 +AGCTACC ref:0:7:TCTAAATA ref:0:5:CGGGTCAGGT 3 4142 +ATGCTAGTTCAACCC ref:0:15:TGACGGGTAAAGCGC ref:0:15:GCAG 5 784 +CGACCTGA ref:0:8:TCCTAAT ref:0:8:TGACGCGT 3 108 +TCTTGTAATTTTTAA ref:0:15:CCA ref:0:15:TTCCGGTAC 11 99880 +TCCGGCCTGGCATTC ref:0:15:GTCA ref:0:15:CC 10 30 +CGTAGAAAG ref:0:9:ACGAC ref:0:9:TGTG 4 264 +TTCGAAAGACTGG ref:0:13:GGAC ref:0:13:CGA 8 5 +CGAACGGTGA ref:0:8:GACCCGAATTTT ref:0:10:CCGAGAAGC 4 96652 +A ref:0:1:GCCTCCACT ref:0:1:GCCCTTAAAGAGATCC 5 5 +GCTGTAA ref:0:7:CCCTGACATTG ref:0:7:GTGACTGACTGTTA 2 348 +CC ref:0:2:ACGACGGCGTGTT ref:0:2:GGGATAAGAGC 4 36 +GGCAAGTACTACAC ref:0:14:ATGAC ref:0:14:GGTAACGACGGA 6 3953 +T ref:0:1:TTTTTGGCCCACCCTA ref:0:1:ACTGTAAG 3 12 +ACCTAACTACT ref:0:11:TCA ref:0:11:GTATGGCGACTTC 5 269 +GCGATCTC ref:0:8:TGGTCCGATTGCGG ref:0:8:CTAGGGAGCACAGAC 4 1296 +TCTCCTAGATCGGCAC ref:0:16:CAGTCGTAGCG ref:0:15:TGACGGAGAAA 6 2475 +CTCAG ref:1:4:GTACGTT ref:0:5:CGGCGGGATCCA 1 8 +GTCTGATTATGCG ref:0:13:ATT ref:0:13:TG 9 36 +GTA ref:0:3:ATTTTAGACA ref:0:3:TGCTAA 2 92 +TGACCG ref:0:6:CTCA ref:0:5:GC 2 18 +CACTCCTAACCGTA ref:0:14:TTAGTAGTACC ref:0:14:CTCGCACCTGCT 2 4 +CTCTT ref:0:5:TTGCATGTGTAA ref:0:5:TATGACT 3 110 +GTGCTA ref:0:5:CCCTGTGCCTCCCT ref:0:6:ACAATAAAGCGTG 1 70 +GGGACG ref:0:6:TTGG ref:0:6:TGCGTGTTAT 3 45 +TGTAGGCA ref:0:7:TCGCCCCC ref:0:8:AT 4 2560 +CATC ref:0:4:GACCTTTTAA ref:0:4:CCTTTCGTCGAGG 6 6705 +ACAG ref:0:4:TCGTCTAGTCGCATC ref:0:4:CAT 2 42 +GTCGAATCAGC ref:0:10:CTTTATAGTT ref:0:11:CTGACA 4 450 +GCATCCATGTTGG ref:0:13:TT ref:1:12:TACAGTATT 6 312 +GAGGCGGCGGA ref:0:11:GCTGGCCCTCTT ref:0:11:GCGGAT 6 39399 +AAAGCAGGGTGCAT ref:0:14:CTGTC ref:0:14:AAATAGCTTGAG 5 1584 +TGTTCCAGAC ref:0:10:AAGTGGGCGAA ref:0:10:A 5 706 +CCGGG ref:0:5:TCAGCGGATGCA ref:0:5:GACCACT 2 28 +CCACTGGGGATTCT ref:0:14:GGTTCAGCCCTCTAA ref:0:14:CGCTGCGTGG 5 12012 +AGCCC ref:0:5:GACCTAG ref:0:5:GCCCGTAA 3 13 +CGGT ref:1:3:ATGCCGACTGGCAG ref:0:4:AGA 2 12 +TCCC ref:0:4:ACTCTT ref:1:3: 2 23 +TGAACCGTCAGGAGC ref:0:15:AACCCTATTT ref:1:13:AATTGTATCAT 7 56160 +TGCCTCGCGGT ref:0:11:CT ref:0:11:AGAGAG 6 468 +CACG ref:0:4:GGTGACCGA ref:0:4:ATGGC 1 66 +CGTGAGA ref:0:7:GTC ref:0:7:AGACGTGC 4 30 +AGTCTGACCAACTGTT ref:0:16:CTACCGTACAGTAGG ref:0:16:GGGGTTTCCCTTA 5 16560 +TCAATTGAC ref:0:7:CTGT ref:0:9:GATCAACC 2 30 +GATAATTATT ref:0:10:GGTTTGAAGCT ref:0:10:TGTCCATG 4 3969 +TTTTTTGTTGTCCTCG ref:0:16:TCTACTTTA ref:0:16:TTTCATGGGTTT 9 11633032 +TG ref:0:2:GACTCCTAGATTT ref:0:1:GCGTCTCCTACC 6 6 +TGCCTGGACAAAACG ref:0:15:C ref:0:15:GCCAACCCGGGC 8 1944 +GAGACGATCGCC ref:0:12:ATTTATTGTGTTC ref:0:12:TCGCTATG 5 912 +CAAGCTAACACT ref:0:12:AA ref:3:9:CTCCG 5 20 +CATTTACGCCCA ref:0:12:AGTGATACATAAACT ref:0:11:TCAAGGTCCACC 5 93822 +GGTGGAAC ref:0:8:CGAAGGTGCCTCTTC ref:0:8:CTCCAA 4 8910 +C ref:0:1:TGGTTTCGTT ref:0:1:GCTATCCCAATGACT 5 5 +ACAGC ref:0:5:GAGAG ref:0:5:TATTATGTGTCATA 1 12 +CGGCGA ref:0:6:GTTAAACGATAT ref:0:6:GACGTCTGAGTA 4 196 +ACGACCT ref:0:7:AAAGGGTAGG ref:0:6:GAG 4 1732 +TC ref:0:2:CTCACTCATGACCC ref:0:2:TCAGTGGTTCCGC 6 169 +TCAAACT ref:0:7:GATG ref:0:7:GAAAGGCC 3 108 +GGCTAT ref:0:6:CCCTCA ref:0:6:CATTATA 2 20 +AAACGAT ref:0:7:GGGCCGTC ref:0:7:GTTACG 4 825 +AA ref:0:2:GATAA ref:0:2:GTAGGGTCGGT 2 36 +TAGGGCGCGTCGCCTT ref:0:16:TCC ref:0:16:ATTACATCCTGTACG 8 1274 +CG ref:0:2:TAATCAT ref:0:2:ACACAATGTATCA 4 6 +AATTT ref:0:5:CGTGTATAGAAA ref:2:3:GTGTGCCAGGTGCT 4 24 +A ref:0:1:TCC ref:0:1:CACAAAGAAAAACATA 2 44 +TCGTA ref:0:5:GGGTTACTC ref:0:5:CCAGGGG 3 1625 +CCCCTGCACG ref:0:10:TCATTAC ref:0:10:ACAA 7 10767 +CTAAAAATGGGACGGC ref:0:16:GACTCGACGCCGGTG ref:0:13:GCC 9 364299 +CTCCT ref:1:2:ATTGATCAAG ref:0:5:TGCCTT 1 6 +GTC ref:0:3:TTCGGGACAACTACC ref:0:3:AAAGAGAGCTCGG 3 18 +ATCCAATC ref:0:8:GCTCAATCA ref:0:8:A 2 27 +AAG ref:0:3:AAAGGTATAGGCG ref:0:3:GGTGTGTTAGACCC 5 504 +TGAGAATATTGA ref:0:12:GCGCG ref:0:12:AGCCCGGTCGTATT 7 6734 +GGTGGGCCGTATCGTC ref:0:16:CCTGCAGCAGT ref:0:16:AACTG 9 56922 +CCTATCAGGTA ref:0:11:AGATAGAT ref:0:11:TCCCTTG 3 330 +GTCAGTTTG ref:0:9:CGACGACAGTCATAT ref:0:9:TATTAGTAAA 2 88 +AAACGC ref:0:6:CTAGGCTCTCA ref:0:6:GGCTGAGCATT 7 14832 +G ref:0:1:CTGCTGGTCTC ref:0:0:ATCAACCAC 2 3 +GTAGAGGTACC ref:0:11:AGGCT ref:0:11:GCAT 6 119 +TAT ref:0:3:C ref:0:3:AGCTAG 2 12 +ACGTCGCT ref:0:8:GTACAGAGACACAG ref:0:8:GGAGTGTAAACTTAAT 5 276 +GAATAAGGCTGC ref:0:12:TCCGGA ref:2:10:CGGAAACG 4 110 +GACT ref:0:4:CCGG ref:0:4:TGTGCGAGTAATA 3 738 +ATCTAGG ref:0:7:GA ref:0:7:AATCGCA 4 144 +CAATAG ref:0:6:TCATTCAACGAG ref:1:5:GAGCGCCCGCGG 4 30800 +GAAGGAACCGCCGG ref:0:14:TACCCTCCG ref:0:14:TCCTCC 10 7264 +GC ref:0:2:GGTAAG ref:0:2:TGTTGACGG 3 24 +ATAT ref:0:4:AATGAG ref:0:4:TAGCCACCCA 2 235 +TGG ref:0:3:G ref:0:3:AGCTTTAGCACCT 1 58 +G ref:0:1:ACCCT ref:0:1:GAGTGCCC 4 18 +A ref:0:1:TACGTTAATAAAACC ref:0:1:CATTCA 3 14 +ATTTAGAGTCGCCG ref:0:14:ACCGCCGTCTCCAC ref:0:14:CTCACT 9 554112 +AAA ref:0:3:GCTCGA ref:0:3:CGTCGCAGACGG 5 364 +CGTTTGT ref:1:5:AAATTAT ref:0:7:GTACAGGGGG 1 1776 +CTGG ref:0:4:ACTTAATAAACCG ref:0:4:CATCTTGTCCT 5 980 +TATGGATTT ref:0:9:TCGACACA ref:0:9:AACTTTACTCGGAC 5 7440 +G ref:0:1:ATTTACAGA ref:1:0:AC 1 1 +GGAGAAACC ref:0:9:ATTACACTTTG ref:0:9:T 6 1200 +AGTG ref:0:4:CCTTCGCGGCT ref:0:4:CGTTCATGTGTAGAT 6 436 +TGGCGACCCGCGT ref:0:13:GCCACGACAGC ref:0:11:AGGATG 4 4704 +GACGCTTAGAATTACG ref:0:16:TTCCCTCCTAGAT ref:0:16:GTAGCGC 5 560 +TATCGAT ref:0:7:G ref:0:7:GCACCCCTGTT 3 99 +GTTGGGTAC ref:0:9:AG ref:0:9:T 7 54 +GCGAACCAT ref:0:8:G ref:0:9:CCGGTCTA 5 368 +GAACATGGTGAA ref:0:12:CCCCCAGCGCCTCTA ref:1:11:CACGGC 6 44660 +CTCCTTC ref:1:6:GGGATGCCCACTAGA ref:0:7:GCTTAG 4 4125 +GTGAAGGCCAA ref:0:11:CTTGAAAGAACCGCC ref:0:11:CGTTATAA 3 660 +AGCCC ref:0:5:GGC ref:1:4: 2 12 +ACTTGGCGCGATACGA ref:0:16:TCGTACCCAT ref:0:16:T 9 108 +AGTTCCGTAC ref:0:10:TTTAACCCTTAGAACG ref:0:9:CACT 3 630 +AAAAT ref:0:4:TATAACTTACAG ref:0:5:TGTATTCA 5 680 +CCTAATGCTTC ref:0:11:TGTGCTCGCT ref:0:11:ATGCTGGACCTT 6 6069 +CTGCTCATC ref:2:7:CTATTCGGAG ref:0:9:AAGG 4 208 +ACTGAATG ref:0:8:TGTACAT ref:0:8:CAAGAACTA 2 14 +G ref:0:1:AAGCACAAAAT ref:0:1:CCTGTCGTCTT 3 2 +ATTGTAATGT ref:0:10:AATGACCAACCG ref:0:10:AA 4 285 +AT ref:0:2:TAAGGGTATCAA ref:0:2:CGCGGACAGA 6 45 +TCGAAACCG ref:0:9:CTGTGCTGTC ref:1:8:ACTAGCC 5 2944 +ACGTAGAGACCCAT ref:0:14:TCC ref:0:14:GAGATGGGCATCG 5 210 +CGACAGGT ref:0:8:ATGCC ref:0:5:G 3 72 +TACGGAAT ref:1:7:CGAATTTAATAG ref:0:8:TTAGCCAGTAGCGC 3 18700 +GTTCCGTC ref:0:8:CA ref:0:8:TCTT 5 190 +GGTT ref:0:4:AATTATAGTATTCGT ref:0:4:TAAATATCGCCGT 7 126 +CCATAGGATTAAG ref:0:13:T ref:0:13:CAAGACGG 6 330 +AAATA ref:0:5:GACGGGCCA ref:0:5:GAAAGC 4 1710 +TTTTGG ref:0:6:ACCCTCA ref:0:6:TAACCG 6 82536 +TCTC ref:0:4:G ref:0:4:GTGAACTGAAGTCAC 1 20 +GAAGGTCACA ref:0:10:CTCCG ref:0:10:C 7 24 +TA ref:0:2:CAAC ref:0:2:AGAAATTAC 2 10 +GGTATTGTAGGGTG ref:0:14:GTGCGGCT ref:0:12:TCTAATCCGCT 5 5655 +AGTTTCAGGCG ref:0:11:ATCAGTCCAC ref:0:11:CATCCACCCGC 6 16335 +AACAATGGTATCTG ref:0:14:CCTC ref:0:14:ACTCGGCCT 7 280 +GTTGTGAG ref:0:8:CCTGC ref:0:8:AATATCTATTACTGT 4 19740 +TATTTCAACCACTTAA ref:0:16:CTG ref:0:16:T 14 168 +GATATCGGACAGG ref:2:11:CTAAAAGCGAGGAT ref:0:13:GTAGAATGCGAGGA 7 15394 +TTCGTTTTAC ref:0:10:GCTGAGCG ref:0:9:C 6 57 +TGGCAA ref:0:6:TTATGCG ref:0:6:TAATGCATAC 3 252 +CT ref:0:2:ATTCTGTTGGAT ref:0:0:TATGAAA 2 4 +TTCTGATG ref:0:8:TTGCATACCA ref:0:8:AAGTA 4 3128 +CCAGGA ref:0:6:AGAGGAATT ref:0:6:TGTAAAAGGTCGGTCT 5 40824 +TGTCC ref:0:5:ATTACG ref:0:5:CAAAACTGG 3 24 +GCCAAGCCTAT ref:0:11:ACACGCAGCCA ref:1:10:ATCATCCAA 4 2552 +AGCGACGCCA ref:0:10:GTCCCATTTCCT ref:0:10:TC 6 5616 +GCTGC ref:2:3:AGTGGCA ref:0:5:ATGGCCGTAT 3 136 +GAGTTCGG ref:0:8:AGACTATTCATCAA ref:0:8:TCTGA 4 4686 +AG ref:0:2:CTAGCCCTCGG ref:0:2:GG 1 9 +A ref:0:1:CAGAA ref:0:1:AGGACAGGTGTTCGC 3 9 +TTAGGGATG ref:0:9:GTT ref:1:7:ATAAGA 3 171 +GCCCGATTCA ref:0:10:CACG ref:0:10:TT 5 10 +ACTACAAGGCCG ref:1:11:AAAT ref:0:12:GTAACAGAAA 7 7626 +GTCATCCGATC ref:0:10:TGGCGTACACTATT ref:0:11:TTCTCT 3 864 +TATGTGCAC ref:1:8:CAATAG ref:0:9:GGTAGCATGTCGGCG 3 696 +CTTTCGGTGCGTTT ref:0:14:AG ref:0:14:GGTCA 10 165 +CCAG ref:0:4:CCCGTCACGC ref:0:3:CCTCTC 3 84 +ACGGTCCATTGACTT ref:1:12:TGTTTCAG ref:0:15:AGTT 7 1958 +AAAGTAGATGT ref:0:11:ATCCA ref:0:11:CGTGTACAG 6 1596 +GTA ref:0:3:ATTGCAGCC ref:1:2:ATTTT 2 77 +GGTAACC ref:0:7:AGG ref:0:7:CATGTCA 4 30 +GCTTATATTCTTCAG ref:0:15:TGCC ref:0:13:AGCGATTTCCCCG 5 1035 +ACCCAGC ref:1:6:CGTCTGCTTT ref:0:7:TGCTCGA 3 528 +AAC ref:0:3:CG ref:0:3:CGCAGAATCTAAAGA 1 3 +CGACTG ref:0:6:ATGCAAC ref:0:6:GA 3 10 +CTCATCTAT ref:0:9:TCATATG ref:0:9:GCC 2 10 +GGTTAACCACA ref:0:11:TAGCGCCAAGAGAAGG ref:0:11:TTCGCGATCTTGTGC 7 7712 +TATCAGAG ref:2:6:C ref:0:8:CTTAGTTCAAGGG 1 44 +TTACTGCGGACCCCGC ref:0:16:GCCAATGTGGA ref:0:16:CC 9 2058 +CATA ref:0:4:GTCGCAAGTT ref:0:4:TAT 2 42 +GACCG ref:0:5:TCACCC ref:0:5:CTA 3 144 +TTTGTTTTTTG ref:0:11:GCAGGGCGACGGCA ref:0:11:TAT 8 23484012 +AACGGCCTGCTCTTA ref:0:15:GCTAAAGGCGCT ref:0:15:GCTTATATTGC 4 15480 +CACCTGTCT ref:0:9:GGA ref:0:8:AATGTTCGG 4 370 +AGCTA ref:0:5:CTGGAACACG ref:0:5:CATTTCTTCTGTT 4 1729 +CGCCGTA ref:0:7:GTTTCCCG ref:0:6:TG 3 32 +GGAGGCTTTG ref:0:10:TTT ref:0:10:ATTCACC 6 25 +TGGGA ref:0:5:AGGGTAAATTGGTC ref:0:5:CAC 2 30 +TAGGGATGTTC ref:0:11:AAGCGC ref:0:11:CAATTGGAAT 6 32361 +TCA ref:1:2:CCAGTGAT ref:0:3:AAAGAGGTT 3 116 +AGGGACCATTTA ref:0:12:GTCGA ref:1:11:AAACG 6 189 +CGAAGGTT ref:0:8:T ref:1:7:TGAAGCAT 2 26 +TTTTCCTCTATAG ref:0:12:ATATTA ref:0:13:GATT 9 71928 +AACAA ref:0:5:ATCGGAAGACTCC ref:0:5:CGTAGCAACCCCGCT 5 60 +CGCC ref:0:4:ATTGTGC ref:0:4:TAGA 3 252 +AGCTTTATACGCAGT ref:0:15:A ref:0:15:TTCTAGTTT 9 1068 +TCCACTGAACTGGG ref:0:14:AT ref:1:13:TGA 9 8 +TGCAAATGATGAC ref:1:12:ATTT ref:0:13:CTTGCACT 6 27 +AACTA ref:0:5:AGCAGGACCTTAG ref:0:5:GAACGG 2 72 +GAGTACGAAGGGT ref:0:13:TAAAGGATCAG ref:0:13:CTCCCG 6 1820 +CAGTGTTCGATAATGA ref:1:15:TGGCGC ref:0:15:AAACTTACCTTTGCC 8 228312 +CCTGATTCCCCACAT ref:0:15:GA ref:0:15:GTTTTCGGC 9 5493 +GTCCCGACCTGTTA ref:0:14:TCCTAACTGAGCGGAG ref:0:14:CAATCTAAAAACCCC 4 64 +AGATT ref:0:5:CTGAGTGTTGGCCTGC ref:0:5:CCGTAAACTATGAAT 4 2590 +C ref:0:1:GTGATTGTCCC ref:0:0:TGTAGAG 5 3 +AGTCG ref:0:5:TACCGATTGCA ref:0:5:AACAGATGTCTGGGAA 4 210 +GAGACAACA ref:0:8:TCACCCGTG ref:0:9:AACCCATACAT 3 348 +TCACAAATC ref:0:8:ACTTCTCATAAG ref:0:9:GGGTCCCCTAGAGAAG 3 1392 diff --git a/src/dfa.c b/src/dfa.c index a54f304..e4b3480 100644 --- a/src/dfa.c +++ b/src/dfa.c @@ -361,6 +361,7 @@ dfa_max_overlap(GVA_Allocator const allocator, return 0; // OOM } // if + size_t count = 0; queue_push_front(&queue, 0, 0); while (!queue_empty(&queue)) { @@ -376,7 +377,8 @@ dfa_max_overlap(GVA_Allocator const allocator, size_t const rhs_ref = rhs_idx / rhs_width + rhs_variant.start; size_t const included = queue.entries[HASH_TABLE_INDEX(queue.entries, idx)].included; - //fprintf(stderr, "{%zu, %zu} (%zu): %zu\n", lhs_idx, rhs_idx, idx, included); + count += 1; + // fprintf(stderr, "{%zu, %zu} (%zu): %zu\n", lhs_idx, rhs_idx, idx, included); if ((lhs_idx == 0 && rhs_ref < lhs_ref) || lhs_idx == lhs_size - 1) { @@ -450,10 +452,15 @@ dfa_max_overlap(GVA_Allocator const allocator, bool const rhs_match = rhs_idx % rhs_width < rhs_width - 1 && reference[rhs_variant.start + rhs_idx / rhs_width] == rhs_variant.sequence.str[rhs_idx % rhs_width]; + bool match = false; + bool deletion = false; + bool insertion = false; + if (lhs_match && rhs_match) { // .. // fprintf(stderr, " push (%zu MU) {%zu, %zu} +0 +0 (%zu)\n", lhs_ref, lhs_idx + lhs_width + 1, rhs_idx + rhs_width + 1, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx + rhs_width + 1); + match = true; queue_push_front(&queue, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx + rhs_width + 1, included); } // if @@ -465,6 +472,7 @@ dfa_max_overlap(GVA_Allocator const allocator, { break; } // if + deletion = true; queue_push_front(&queue, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width, included + 1); } // if @@ -476,41 +484,50 @@ dfa_max_overlap(GVA_Allocator const allocator, { break; } // if + insertion = true; queue_push_front(&queue, (lhs_idx + 1) * rhs_size + rhs_idx + 1, included + 1); } // if - if (lhs_deletion && rhs_match) + if (!deletion || !match) { - // D. - // fprintf(stderr, " push (%zu DELTA vs %zu MU) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, rhs_ref, lhs_idx + lhs_width, rhs_idx + rhs_width + 1, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width + 1); - queue_push_back(&queue, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width + 1, included); - } // if + if (lhs_deletion && rhs_match) + { + // D. + // fprintf(stderr, " push (%zu DELTA vs %zu MU) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, rhs_ref, lhs_idx + lhs_width, rhs_idx + rhs_width + 1, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width + 1); + queue_push_back(&queue, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width + 1, included); + } // if - if (lhs_match && rhs_deletion) - { - // .D - // fprintf(stderr, " push (%zu MU vs %zu DELTA) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, rhs_ref, lhs_idx + lhs_width + 1, rhs_idx + rhs_width, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx + rhs_width); - queue_push_back(&queue, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx + rhs_width, included); + if (lhs_match && rhs_deletion) + { + // .D + // fprintf(stderr, " push (%zu MU vs %zu DELTA) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, rhs_ref, lhs_idx + lhs_width + 1, rhs_idx + rhs_width, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx + rhs_width); + queue_push_back(&queue, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx + rhs_width, included); + } // if } // if - if (lhs_insertion && (rhs_deletion || rhs_match || (rhs_insertion && - lhs_variant.sequence.str[lhs_idx % lhs_width] != rhs_variant.sequence.str[rhs_idx % rhs_width]))) + if (!insertion || !match) { - // I. - // fprintf(stderr, " push (%zu %c vs .) {%zu, %zu} +0 +1 (%zu)\n", lhs_ref, lhs_variant.sequence.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx, (lhs_idx + 1) * rhs_size + rhs_idx); - queue_push_back(&queue, (lhs_idx + 1) * rhs_size + rhs_idx, included); - } // if + if (lhs_insertion && (rhs_deletion || rhs_match || (rhs_insertion && + lhs_variant.sequence.str[lhs_idx % lhs_width] != rhs_variant.sequence.str[rhs_idx % rhs_width]))) + { + // I. + // fprintf(stderr, " push (%zu %c vs .) {%zu, %zu} +0 +1 (%zu)\n", lhs_ref, lhs_variant.sequence.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx, (lhs_idx + 1) * rhs_size + rhs_idx); + queue_push_back(&queue, (lhs_idx + 1) * rhs_size + rhs_idx, included); + } // if - if (rhs_insertion && (lhs_deletion || lhs_match || (lhs_insertion && - lhs_variant.sequence.str[lhs_idx % lhs_width] != rhs_variant.sequence.str[rhs_idx % rhs_width]))) - { - // .I - // fprintf(stderr, " push (. vs %zu %c) {%zu, %zu} +0 +1 (%zu)\n", rhs_ref, rhs_variant.sequence.str[rhs_idx % rhs_width], lhs_idx, rhs_idx + 1, lhs_idx * rhs_size + rhs_idx + 1); - queue_push_back(&queue, lhs_idx * rhs_size + rhs_idx + 1, included); + if (rhs_insertion && (lhs_deletion || lhs_match || (lhs_insertion && + lhs_variant.sequence.str[lhs_idx % lhs_width] != rhs_variant.sequence.str[rhs_idx % rhs_width]))) + { + // .I + // fprintf(stderr, " push (. vs %zu %c) {%zu, %zu} +0 +1 (%zu)\n", rhs_ref, rhs_variant.sequence.str[rhs_idx % rhs_width], lhs_idx, rhs_idx + 1, lhs_idx * rhs_size + rhs_idx + 1); + queue_push_back(&queue, lhs_idx * rhs_size + rhs_idx + 1, included); + } // if } // if } // else } // while + // fprintf(stderr, "count: %zu\n", count); + size_t included = limit; size_t const idx = HASH_TABLE_INDEX(queue.entries, lhs_size * rhs_size - 1); if (queue.entries[idx].gva_key == lhs_size * rhs_size - 1) diff --git a/src/main.c b/src/main.c index 4f54083..4176a4b 100644 --- a/src/main.c +++ b/src/main.c @@ -548,6 +548,7 @@ overlap_main(int argc, char* argv[static argc]) uint8_t* lhs_dfa = dfa_from_alignment(gva_std_allocator, NULL, lhs_variant.end - lhs_variant.start, reference.str + lhs_variant.start, lhs_variant.sequence.len, lhs_variant.sequence.str); uint8_t* rhs_dfa = dfa_from_alignment(gva_std_allocator, NULL, rhs_variant.end - rhs_variant.start, reference.str + rhs_variant.start, rhs_variant.sequence.len, rhs_variant.sequence.str); + /* dfa_dot(stdout, reference.len, reference.str, lhs_variant, lhs_dfa); dfa_dot(stdout, reference.len, reference.str, rhs_variant, rhs_dfa); dfa_svg(stdout, reference.len, reference.str, lhs_variant, lhs_dfa); @@ -558,6 +559,11 @@ overlap_main(int argc, char* argv[static argc]) reference.len, reference.str, lhs_variant, lhs_dfa, rhs_variant, rhs_dfa, 0)); + */ + fprintf(stdout, "%zu\n", dfa_max_overlap(gva_std_allocator, + reference.len, reference.str, + lhs_variant, lhs_dfa, + rhs_variant, rhs_dfa, 0)); rhs_dfa = ARRAY_DESTROY(gva_std_allocator, rhs_dfa); lhs_dfa = ARRAY_DESTROY(gva_std_allocator, lhs_dfa); @@ -888,6 +894,6 @@ main(int argc, char* argv[static argc]) // return allele_main(argc, argv); // return index_main(argc, argv); // return supremal_main(argc, argv); - // return overlap_main(argc, argv); - return all_main(argc, argv); + return overlap_main(argc, argv); + // return all_main(argc, argv); } // main From 5feea80d18128f62e93a7fe8d2d8c70e48f4e144 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 7 May 2026 09:02:51 +0200 Subject: [PATCH 633/704] ca. 7% less on 13k --- src/dfa.c | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/src/dfa.c b/src/dfa.c index e4b3480..a266451 100644 --- a/src/dfa.c +++ b/src/dfa.c @@ -452,15 +452,10 @@ dfa_max_overlap(GVA_Allocator const allocator, bool const rhs_match = rhs_idx % rhs_width < rhs_width - 1 && reference[rhs_variant.start + rhs_idx / rhs_width] == rhs_variant.sequence.str[rhs_idx % rhs_width]; - bool match = false; - bool deletion = false; - bool insertion = false; - if (lhs_match && rhs_match) { // .. // fprintf(stderr, " push (%zu MU) {%zu, %zu} +0 +0 (%zu)\n", lhs_ref, lhs_idx + lhs_width + 1, rhs_idx + rhs_width + 1, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx + rhs_width + 1); - match = true; queue_push_front(&queue, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx + rhs_width + 1, included); } // if @@ -472,7 +467,6 @@ dfa_max_overlap(GVA_Allocator const allocator, { break; } // if - deletion = true; queue_push_front(&queue, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width, included + 1); } // if @@ -484,11 +478,10 @@ dfa_max_overlap(GVA_Allocator const allocator, { break; } // if - insertion = true; queue_push_front(&queue, (lhs_idx + 1) * rhs_size + rhs_idx + 1, included + 1); } // if - if (!deletion || !match) + if (!(lhs_match && rhs_match)) { if (lhs_deletion && rhs_match) { @@ -503,10 +496,7 @@ dfa_max_overlap(GVA_Allocator const allocator, // fprintf(stderr, " push (%zu MU vs %zu DELTA) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, rhs_ref, lhs_idx + lhs_width + 1, rhs_idx + rhs_width, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx + rhs_width); queue_push_back(&queue, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx + rhs_width, included); } // if - } // if - if (!insertion || !match) - { if (lhs_insertion && (rhs_deletion || rhs_match || (rhs_insertion && lhs_variant.sequence.str[lhs_idx % lhs_width] != rhs_variant.sequence.str[rhs_idx % rhs_width]))) { @@ -526,7 +516,7 @@ dfa_max_overlap(GVA_Allocator const allocator, } // else } // while - // fprintf(stderr, "count: %zu\n", count); + fprintf(stderr, "count: %zu\n", count); size_t included = limit; size_t const idx = HASH_TABLE_INDEX(queue.entries, lhs_size * rhs_size - 1); From be005424f2d7c4fc9e40eab7ec599fc9ed17c43b Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 7 May 2026 09:12:41 +0200 Subject: [PATCH 634/704] Reorder to simplify --- src/dfa.c | 50 ++++++++++++++++++++++++-------------------------- 1 file changed, 24 insertions(+), 26 deletions(-) diff --git a/src/dfa.c b/src/dfa.c index a266451..119cf58 100644 --- a/src/dfa.c +++ b/src/dfa.c @@ -458,30 +458,7 @@ dfa_max_overlap(GVA_Allocator const allocator, // fprintf(stderr, " push (%zu MU) {%zu, %zu} +0 +0 (%zu)\n", lhs_ref, lhs_idx + lhs_width + 1, rhs_idx + rhs_width + 1, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx + rhs_width + 1); queue_push_front(&queue, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx + rhs_width + 1, included); } // if - - if (lhs_deletion && rhs_deletion) - { - // DD - // fprintf(stderr, " push (%zu DELTA) {%zu, %zu} +1 +0 (%zu)\n", lhs_ref, lhs_idx + lhs_width, rhs_idx + rhs_width, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width); - if (limit > 0 && included + 1 >= limit) - { - break; - } // if - queue_push_front(&queue, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width, included + 1); - } // if - - if (lhs_insertion && rhs_insertion && lhs_variant.sequence.str[lhs_idx % lhs_width] == rhs_variant.sequence.str[rhs_idx % rhs_width]) - { - // II - // fprintf(stderr, " push (%zu %c) {%zu, %zu} +1 +0 (%zu)\n", lhs_ref, lhs_variant.sequence.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx + 1, (lhs_idx + 1) * rhs_size + rhs_idx + 1); - if (limit > 0 && included + 1 >= limit) - { - break; - } // if - queue_push_front(&queue, (lhs_idx + 1) * rhs_size + rhs_idx + 1, included + 1); - } // if - - if (!(lhs_match && rhs_match)) + else { if (lhs_deletion && rhs_match) { @@ -489,8 +466,7 @@ dfa_max_overlap(GVA_Allocator const allocator, // fprintf(stderr, " push (%zu DELTA vs %zu MU) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, rhs_ref, lhs_idx + lhs_width, rhs_idx + rhs_width + 1, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width + 1); queue_push_back(&queue, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width + 1, included); } // if - - if (lhs_match && rhs_deletion) + else if (lhs_match && rhs_deletion) { // .D // fprintf(stderr, " push (%zu MU vs %zu DELTA) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, rhs_ref, lhs_idx + lhs_width + 1, rhs_idx + rhs_width, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx + rhs_width); @@ -512,6 +488,28 @@ dfa_max_overlap(GVA_Allocator const allocator, // fprintf(stderr, " push (. vs %zu %c) {%zu, %zu} +0 +1 (%zu)\n", rhs_ref, rhs_variant.sequence.str[rhs_idx % rhs_width], lhs_idx, rhs_idx + 1, lhs_idx * rhs_size + rhs_idx + 1); queue_push_back(&queue, lhs_idx * rhs_size + rhs_idx + 1, included); } // if + } // else + + if (lhs_deletion && rhs_deletion) + { + // DD + // fprintf(stderr, " push (%zu DELTA) {%zu, %zu} +1 +0 (%zu)\n", lhs_ref, lhs_idx + lhs_width, rhs_idx + rhs_width, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width); + if (limit > 0 && included + 1 >= limit) + { + break; + } // if + queue_push_front(&queue, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width, included + 1); + } // if + + if (lhs_insertion && rhs_insertion && lhs_variant.sequence.str[lhs_idx % lhs_width] == rhs_variant.sequence.str[rhs_idx % rhs_width]) + { + // II + // fprintf(stderr, " push (%zu %c) {%zu, %zu} +1 +0 (%zu)\n", lhs_ref, lhs_variant.sequence.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx + 1, (lhs_idx + 1) * rhs_size + rhs_idx + 1); + if (limit > 0 && included + 1 >= limit) + { + break; + } // if + queue_push_front(&queue, (lhs_idx + 1) * rhs_size + rhs_idx + 1, included + 1); } // if } // else } // while From e02c72383e94347a8742255a7c2a287fa903ceae Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 8 May 2026 08:44:21 +0200 Subject: [PATCH 635/704] More restructuring and less states --- src/dfa.c | 146 +++++++++++++++++++++++++++--------------------------- 1 file changed, 74 insertions(+), 72 deletions(-) diff --git a/src/dfa.c b/src/dfa.c index 119cf58..4b52831 100644 --- a/src/dfa.c +++ b/src/dfa.c @@ -383,8 +383,6 @@ dfa_max_overlap(GVA_Allocator const allocator, if ((lhs_idx == 0 && rhs_ref < lhs_ref) || lhs_idx == lhs_size - 1) { uint8_t const rhs_value = get(rhs_dfa, rhs_idx); - bool const rhs_deletion = rhs_value & DFA_DELETION; - bool const rhs_insertion = rhs_value & DFA_INSERTION; bool const rhs_match = rhs_idx % rhs_width < rhs_width - 1 && reference[rhs_variant.start + rhs_idx / rhs_width] == rhs_variant.sequence.str[rhs_idx % rhs_width]; @@ -393,27 +391,30 @@ dfa_max_overlap(GVA_Allocator const allocator, // .. // fprintf(stderr, " push (. vs %zu MU) +0 +0 {%zu, %zu} (%zu)\n", rhs_ref, lhs_idx, rhs_idx + rhs_width + 1, lhs_idx * rhs_size + rhs_idx + rhs_width + 1); queue_push_front(&queue, lhs_idx * rhs_size + rhs_idx + rhs_width + 1, included); + continue; } // if + bool const rhs_deletion = rhs_value & DFA_DELETION; + bool const rhs_insertion = rhs_value & DFA_INSERTION; + if (rhs_deletion) { // .D // fprintf(stderr, " push (. vs %zu DELTA) +0 +1 {%zu, %zu} (%zu)\n", rhs_ref, lhs_idx, rhs_idx + rhs_width, lhs_idx * rhs_size + rhs_idx + rhs_width); queue_push_back(&queue, lhs_idx * rhs_size + rhs_idx + rhs_width, included); } // if - if (rhs_insertion) { // .I // fprintf(stderr, " push (. vs %zu %c) +0 +1 {%zu, %zu} (%zu)\n", rhs_ref, rhs_variant.sequence.str[rhs_idx % rhs_width], lhs_idx, rhs_idx + 1, lhs_idx * rhs_size + rhs_idx + 1); queue_push_back(&queue, lhs_idx * rhs_size + rhs_idx + 1, included); } // if + continue; } // if - else if ((rhs_idx == 0 && lhs_ref < rhs_ref) || rhs_idx == rhs_size - 1) + + if ((rhs_idx == 0 && lhs_ref < rhs_ref) || rhs_idx == rhs_size - 1) { uint8_t const lhs_value = get(lhs_dfa, lhs_idx); - bool const lhs_deletion = lhs_value & DFA_DELETION; - bool const lhs_insertion = lhs_value & DFA_INSERTION; bool const lhs_match = lhs_idx % lhs_width < lhs_width - 1 && reference[lhs_variant.start + lhs_idx / lhs_width] == lhs_variant.sequence.str[lhs_idx % lhs_width]; @@ -422,96 +423,97 @@ dfa_max_overlap(GVA_Allocator const allocator, // .. // fprintf(stderr, " push (%zu MU vs .) +0 +0 {%zu, %zu} (%zu)\n", lhs_ref, lhs_idx + lhs_width + 1, rhs_idx, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx); queue_push_front(&queue, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx, included); + continue; } // if + bool const lhs_deletion = lhs_value & DFA_DELETION; + bool const lhs_insertion = lhs_value & DFA_INSERTION; + if (lhs_deletion) { // D. // fprintf(stderr, " push (%zu DELTA vs .) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, lhs_idx + lhs_width, rhs_idx, (lhs_idx + lhs_width) * rhs_size + rhs_idx); queue_push_back(&queue, (lhs_idx + lhs_width) * rhs_size + rhs_idx, included); } // if - if (lhs_insertion) { // I. // fprintf(stderr, " push (%zu %c vs .) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, lhs_variant.sequence.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx, (lhs_idx + 1) * rhs_size + rhs_idx); queue_push_back(&queue, (lhs_idx + 1) * rhs_size + rhs_idx, included); } // if + continue; } // if - else - { - uint8_t const lhs_value = get(lhs_dfa, lhs_idx); - bool const lhs_deletion = lhs_value & DFA_DELETION; - bool const lhs_insertion = lhs_value & DFA_INSERTION; - bool const lhs_match = lhs_idx % lhs_width < lhs_width - 1 && - reference[lhs_variant.start + lhs_idx / lhs_width] == lhs_variant.sequence.str[lhs_idx % lhs_width]; - uint8_t const rhs_value = get(rhs_dfa, rhs_idx); - bool const rhs_deletion = rhs_value & DFA_DELETION; - bool const rhs_insertion = rhs_value & DFA_INSERTION; - bool const rhs_match = rhs_idx % rhs_width < rhs_width - 1 && - reference[rhs_variant.start + rhs_idx / rhs_width] == rhs_variant.sequence.str[rhs_idx % rhs_width]; + uint8_t const lhs_value = get(lhs_dfa, lhs_idx); + bool const lhs_match = lhs_idx % lhs_width < lhs_width - 1 && + reference[lhs_variant.start + lhs_idx / lhs_width] == lhs_variant.sequence.str[lhs_idx % lhs_width]; + uint8_t const rhs_value = get(rhs_dfa, rhs_idx); + bool const rhs_match = rhs_idx % rhs_width < rhs_width - 1 && + reference[rhs_variant.start + rhs_idx / rhs_width] == rhs_variant.sequence.str[rhs_idx % rhs_width]; - if (lhs_match && rhs_match) - { - // .. - // fprintf(stderr, " push (%zu MU) {%zu, %zu} +0 +0 (%zu)\n", lhs_ref, lhs_idx + lhs_width + 1, rhs_idx + rhs_width + 1, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx + rhs_width + 1); - queue_push_front(&queue, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx + rhs_width + 1, included); - } // if - else - { - if (lhs_deletion && rhs_match) - { - // D. - // fprintf(stderr, " push (%zu DELTA vs %zu MU) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, rhs_ref, lhs_idx + lhs_width, rhs_idx + rhs_width + 1, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width + 1); - queue_push_back(&queue, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width + 1, included); - } // if - else if (lhs_match && rhs_deletion) - { - // .D - // fprintf(stderr, " push (%zu MU vs %zu DELTA) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, rhs_ref, lhs_idx + lhs_width + 1, rhs_idx + rhs_width, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx + rhs_width); - queue_push_back(&queue, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx + rhs_width, included); - } // if - - if (lhs_insertion && (rhs_deletion || rhs_match || (rhs_insertion && - lhs_variant.sequence.str[lhs_idx % lhs_width] != rhs_variant.sequence.str[rhs_idx % rhs_width]))) - { - // I. - // fprintf(stderr, " push (%zu %c vs .) {%zu, %zu} +0 +1 (%zu)\n", lhs_ref, lhs_variant.sequence.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx, (lhs_idx + 1) * rhs_size + rhs_idx); - queue_push_back(&queue, (lhs_idx + 1) * rhs_size + rhs_idx, included); - } // if + if (lhs_match && rhs_match) + { + // .. + // fprintf(stderr, " push (%zu MU) {%zu, %zu} +0 +0 (%zu)\n", lhs_ref, lhs_idx + lhs_width + 1, rhs_idx + rhs_width + 1, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx + rhs_width + 1); + queue_push_front(&queue, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx + rhs_width + 1, included); + continue; + } // if - if (rhs_insertion && (lhs_deletion || lhs_match || (lhs_insertion && - lhs_variant.sequence.str[lhs_idx % lhs_width] != rhs_variant.sequence.str[rhs_idx % rhs_width]))) - { - // .I - // fprintf(stderr, " push (. vs %zu %c) {%zu, %zu} +0 +1 (%zu)\n", rhs_ref, rhs_variant.sequence.str[rhs_idx % rhs_width], lhs_idx, rhs_idx + 1, lhs_idx * rhs_size + rhs_idx + 1); - queue_push_back(&queue, lhs_idx * rhs_size + rhs_idx + 1, included); - } // if - } // else + bool const lhs_deletion = lhs_value & DFA_DELETION; + bool const lhs_insertion = lhs_value & DFA_INSERTION; + bool const rhs_deletion = rhs_value & DFA_DELETION; + bool const rhs_insertion = rhs_value & DFA_INSERTION; - if (lhs_deletion && rhs_deletion) + if (lhs_deletion && rhs_deletion) + { + // DD + // fprintf(stderr, " push (%zu DELTA) {%zu, %zu} +1 +0 (%zu)\n", lhs_ref, lhs_idx + lhs_width, rhs_idx + rhs_width, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width); + if (limit > 0 && included + 1 >= limit) { - // DD - // fprintf(stderr, " push (%zu DELTA) {%zu, %zu} +1 +0 (%zu)\n", lhs_ref, lhs_idx + lhs_width, rhs_idx + rhs_width, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width); - if (limit > 0 && included + 1 >= limit) - { - break; - } // if - queue_push_front(&queue, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width, included + 1); + break; } // if + queue_push_front(&queue, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width, included + 1); + } // if - if (lhs_insertion && rhs_insertion && lhs_variant.sequence.str[lhs_idx % lhs_width] == rhs_variant.sequence.str[rhs_idx % rhs_width]) + if (lhs_insertion && rhs_insertion && lhs_variant.sequence.str[lhs_idx % lhs_width] == rhs_variant.sequence.str[rhs_idx % rhs_width]) + { + // II + // fprintf(stderr, " push (%zu %c) {%zu, %zu} +1 +0 (%zu)\n", lhs_ref, lhs_variant.sequence.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx + 1, (lhs_idx + 1) * rhs_size + rhs_idx + 1); + if (limit > 0 && included + 1 >= limit) { - // II - // fprintf(stderr, " push (%zu %c) {%zu, %zu} +1 +0 (%zu)\n", lhs_ref, lhs_variant.sequence.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx + 1, (lhs_idx + 1) * rhs_size + rhs_idx + 1); - if (limit > 0 && included + 1 >= limit) - { - break; - } // if - queue_push_front(&queue, (lhs_idx + 1) * rhs_size + rhs_idx + 1, included + 1); + break; } // if - } // else + queue_push_front(&queue, (lhs_idx + 1) * rhs_size + rhs_idx + 1, included + 1); + } // if + + if (lhs_deletion && rhs_match) + { + // D. + // fprintf(stderr, " push (%zu DELTA vs %zu MU) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, rhs_ref, lhs_idx + lhs_width, rhs_idx + rhs_width + 1, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width + 1); + queue_push_back(&queue, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width + 1, included); + } // if + else if (lhs_match && rhs_deletion) + { + // .D + // fprintf(stderr, " push (%zu MU vs %zu DELTA) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, rhs_ref, lhs_idx + lhs_width + 1, rhs_idx + rhs_width, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx + rhs_width); + queue_push_back(&queue, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx + rhs_width, included); + } // if + + if (lhs_insertion && (rhs_deletion || rhs_match || (rhs_insertion && + lhs_variant.sequence.str[lhs_idx % lhs_width] != rhs_variant.sequence.str[rhs_idx % rhs_width]))) + { + // I. + // fprintf(stderr, " push (%zu %c vs .) {%zu, %zu} +0 +1 (%zu)\n", lhs_ref, lhs_variant.sequence.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx, (lhs_idx + 1) * rhs_size + rhs_idx); + queue_push_back(&queue, (lhs_idx + 1) * rhs_size + rhs_idx, included); + } // if + + if (rhs_insertion && (lhs_deletion || lhs_match || (lhs_insertion && + lhs_variant.sequence.str[lhs_idx % lhs_width] != rhs_variant.sequence.str[rhs_idx % rhs_width]))) + { + // .I + // fprintf(stderr, " push (. vs %zu %c) {%zu, %zu} +0 +1 (%zu)\n", rhs_ref, rhs_variant.sequence.str[rhs_idx % rhs_width], lhs_idx, rhs_idx + 1, lhs_idx * rhs_size + rhs_idx + 1); + queue_push_back(&queue, lhs_idx * rhs_size + rhs_idx + 1, included); + } // if } // while fprintf(stderr, "count: %zu\n", count); From 5b001c16ae309a610a4cc7a3b968859f7980ba8a Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 8 May 2026 10:35:03 +0200 Subject: [PATCH 636/704] dbSNP in 13m --- src/main.c | 113 ++++++++++------------------------------------------- 1 file changed, 21 insertions(+), 92 deletions(-) diff --git a/src/main.c b/src/main.c index 4176a4b..58dc25b 100644 --- a/src/main.c +++ b/src/main.c @@ -14,7 +14,7 @@ #include "../include/std_alloc.h" // gva_std_allocator #include "../include/string.h" // GVA_String, gva_string_destroy #include "../include/utils.h" // gva_fasta_sequence*, gva_lcs_graph_dot -#include "../include/variant.h" // GVA_VARIANT_*, GVA_Variant, gva_parse_spdi, gva_variant_* +#include "../include/variant.h" // GVA_VARIANT_*, GVA_Variant, gva_parse_spdi, gva_patch, gva_variant_* #include "align.h" // LCS_Matches, lcs_align_one #include "array.h" // ARRAY_*, array_length #include "bitset.h" // bitset_* @@ -580,6 +580,7 @@ typedef struct gva_uint inserted; gva_uint distance; gva_uint label; + gva_uint dfa; } Entry; @@ -665,6 +666,7 @@ all_main(int argc, char* argv[static argc]) Trie labels = trie_init(gva_std_allocator); Trie sequences = trie_init(gva_std_allocator); + Trie dfas = trie_init(gva_std_allocator); Entry* entries = NULL; size_t line_count = 0; @@ -684,8 +686,11 @@ all_main(int argc, char* argv[static argc]) if (distance == 0) { fprintf(stderr, "ERROR: DISTANCE\n"); + continue; } // if + uint8_t* dfa = dfa_from_alignment(gva_std_allocator, NULL, variant.end - variant.start, reference.str + variant.start, variant.sequence.len, variant.sequence.str); + ARRAY_APPEND(gva_std_allocator, entries, ((Entry) { @@ -694,7 +699,10 @@ all_main(int argc, char* argv[static argc]) .inserted = trie_insert(&sequences, variant.sequence.len, variant.sequence.str), .distance = distance, .label = trie_insert(&labels, id.len, id.str), + .dfa = trie_insert(&dfas, array_length(dfa), (char*) dfa), })); + + dfa = ARRAY_DESTROY(gva_std_allocator, dfa); } // while fclose(stream); @@ -710,15 +718,6 @@ all_main(int argc, char* argv[static argc]) { GVA_Variant const lhs = { entries[i].start, entries[i].end, trie_string(sequences, entries[i].inserted) }; - GVA_LCS_Graph lhs_graph = {NULL}; - size_t* lhs_dels = NULL; - size_t* lhs_as = NULL; - size_t* lhs_cs = NULL; - size_t* lhs_gs = NULL; - size_t* lhs_ts = NULL; - - uint8_t* lhs_dfa = NULL; - for (size_t j = i + 1; j < array_length(entries); ++j) { if (entries[i].end < entries[j].start) @@ -754,21 +753,8 @@ all_main(int argc, char* argv[static argc]) } // if else { - GVA_String observed_lhs = gva_string_init(gva_std_allocator, len_lhs); - GVA_String observed_rhs = gva_string_init(gva_std_allocator, len_rhs); - if (observed_lhs.str == NULL || observed_rhs.str == NULL) - { - return EXIT_FAILURE; // FIXME: OOM - } // if - - memcpy((char*) observed_lhs.str, reference.str + start, lhs.start - start); - memcpy((char*) observed_lhs.str + lhs.start - start, lhs.sequence.str, lhs.sequence.len); - memcpy((char*) observed_lhs.str + lhs.start - start + lhs.sequence.len, reference.str + lhs.end, end - lhs.end); - - memcpy((char*) observed_rhs.str, reference.str + start, rhs.start - start); - memcpy((char*) observed_rhs.str + rhs.start - start, rhs.sequence.str, rhs.sequence.len); - memcpy((char*) observed_rhs.str + rhs.start - start + rhs.sequence.len, reference.str + rhs.end, end - rhs.end); - + GVA_String observed_lhs = gva_patch(gva_std_allocator, end - start, reference.str + start, 1, &(GVA_Variant const) {lhs.start - start, lhs.end - start, lhs.sequence}); + GVA_String observed_rhs = gva_patch(gva_std_allocator, end - start, reference.str + start, 1, &(GVA_Variant const) {rhs.start - start, rhs.end - start, rhs.sequence}); distance = gva_edit_distance(gva_std_allocator, observed_lhs.len, observed_lhs.str, observed_rhs.len, observed_rhs.str); gva_string_destroy(gva_std_allocator, observed_rhs); gva_string_destroy(gva_std_allocator, observed_lhs); @@ -795,90 +781,33 @@ all_main(int argc, char* argv[static argc]) continue; // is_contained } // if - if (lhs_graph.nodes == NULL) - { - lhs_graph = gva_lcs_graph_init(gva_std_allocator, lhs.end - lhs.start, reference.str + lhs.start, lhs.sequence.len, lhs.sequence.str, lhs.start); - size_t const len = end - start + 1; - lhs_dels = bitset_init(gva_std_allocator, len); - lhs_as = bitset_init(gva_std_allocator, len); - lhs_cs = bitset_init(gva_std_allocator, len); - lhs_gs = bitset_init(gva_std_allocator, len); - lhs_ts = bitset_init(gva_std_allocator, len); - gva_lcs_graph_uniq_atomics(lhs_graph, lhs.start, lhs.start, lhs.end, lhs_dels, lhs_as, lhs_cs, lhs_gs, lhs_ts); - } // if - - if (lhs_dfa == NULL) - { - lhs_dfa = dfa_from_alignment(gva_std_allocator, NULL, lhs.end - lhs.start, reference.str + lhs.start, lhs.sequence.len, lhs.sequence.str); - } // if - - GVA_LCS_Graph rhs_graph = gva_lcs_graph_init(gva_std_allocator, rhs.end - rhs.start, reference.str + rhs.start, rhs.sequence.len, rhs.sequence.str, rhs.start); - uint8_t* rhs_dfa = dfa_from_alignment(gva_std_allocator, NULL, rhs.end - rhs.start, reference.str + rhs.start, rhs.sequence.len, rhs.sequence.str); - - size_t const len = end - start + 1; - size_t* rhs_dels = bitset_init(gva_std_allocator, len); - size_t* rhs_as = bitset_init(gva_std_allocator, len); - size_t* rhs_cs = bitset_init(gva_std_allocator, len); - size_t* rhs_gs = bitset_init(gva_std_allocator, len); - size_t* rhs_ts = bitset_init(gva_std_allocator, len); - - gva_lcs_graph_uniq_atomics(rhs_graph, lhs.start, rhs.start, rhs.end, rhs_dels, rhs_as, rhs_cs, rhs_gs, rhs_ts); - - //size_t const dfa_overlap = dfa_max_overlap(gva_std_allocator, reference.len, reference.str, lhs, lhs_dfa, rhs, rhs_dfa, 1); - bool const disjoint = dfa_disjoint(lhs, lhs_dfa, rhs, rhs_dfa); + GVA_String lhs_dfa = trie_string(dfas, entries[i].dfa); + GVA_String rhs_dfa = trie_string(dfas, entries[j].dfa); - bool const overlap = bitset_intersection_cnt(lhs_dels, rhs_dels) > 0 || - bitset_intersection_cnt(lhs_as, rhs_as) > 0 || - bitset_intersection_cnt(lhs_cs, rhs_cs) > 0 || - bitset_intersection_cnt(lhs_gs, rhs_gs) > 0 || - bitset_intersection_cnt(lhs_ts, rhs_ts) > 0; + //size_t const overlap = dfa_max_overlap(gva_std_allocator, reference.len, reference.str, lhs, (uint8_t*) lhs_dfa.str, rhs, (uint8_t*) rhs_dfa.str, 0); + bool const disjoint = dfa_disjoint(lhs, (uint8_t*) lhs_dfa.str, rhs, (uint8_t*) rhs_dfa.str); - rhs_ts = bitset_destroy(gva_std_allocator, rhs_ts); - rhs_gs = bitset_destroy(gva_std_allocator, rhs_gs); - rhs_cs = bitset_destroy(gva_std_allocator, rhs_cs); - rhs_as = bitset_destroy(gva_std_allocator, rhs_as); - rhs_dels = bitset_destroy(gva_std_allocator, rhs_dels); - - gva_lcs_graph_destroy(gva_std_allocator, rhs_graph, false); - rhs_dfa = ARRAY_DESTROY(gva_std_allocator, rhs_dfa); - - //if (overlap != (dfa_overlap > 0)) - if (overlap == disjoint) + if (disjoint) { - fprintf(stderr, GVA_STRING_FMT " vs " GVA_STRING_FMT "\n", + fprintf(stdout, GVA_STRING_FMT " disjoint " GVA_STRING_FMT "\n", GVA_STRING_PRINT(trie_string(labels, entries[i].label)), GVA_STRING_PRINT(trie_string(labels, entries[j].label))); - fprintf(stderr, "ERROR\n"); - return EXIT_FAILURE; } // if - - if (overlap) + else { fprintf(stdout, GVA_STRING_FMT " overlap " GVA_STRING_FMT " %zu\n", GVA_STRING_PRINT(trie_string(labels, entries[i].label)), GVA_STRING_PRINT(trie_string(labels, entries[j].label)), (entries[i].distance + entries[j].distance - distance) / 2); - } // if - else - { - fprintf(stdout, GVA_STRING_FMT " disjoint " GVA_STRING_FMT "\n", - GVA_STRING_PRINT(trie_string(labels, entries[i].label)), - GVA_STRING_PRINT(trie_string(labels, entries[j].label))); } // else } // for - lhs_ts = bitset_destroy(gva_std_allocator, lhs_ts); - lhs_gs = bitset_destroy(gva_std_allocator, lhs_gs); - lhs_cs = bitset_destroy(gva_std_allocator, lhs_cs); - lhs_as = bitset_destroy(gva_std_allocator, lhs_as); - lhs_dels = bitset_destroy(gva_std_allocator, lhs_dels); - gva_lcs_graph_destroy(gva_std_allocator, lhs_graph, false); - lhs_dfa = ARRAY_DESTROY(gva_std_allocator, lhs_dfa); } // for fprintf(stderr, "#combos: %zu\n", count); } // if entries = ARRAY_DESTROY(gva_std_allocator, entries); + trie_destroy(&dfas); trie_destroy(&labels); trie_destroy(&sequences); @@ -894,6 +823,6 @@ main(int argc, char* argv[static argc]) // return allele_main(argc, argv); // return index_main(argc, argv); // return supremal_main(argc, argv); - return overlap_main(argc, argv); - // return all_main(argc, argv); + // return overlap_main(argc, argv); + return all_main(argc, argv); } // main From 5608eab3bb43cae17ca448aa81d1ab583ff0e0b1 Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 8 May 2026 16:59:39 +0200 Subject: [PATCH 637/704] dbSNP max overlap --- src/dfa.c | 6 +++--- src/main.c | 7 +++---- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/dfa.c b/src/dfa.c index 4b52831..47df30b 100644 --- a/src/dfa.c +++ b/src/dfa.c @@ -361,7 +361,7 @@ dfa_max_overlap(GVA_Allocator const allocator, return 0; // OOM } // if - size_t count = 0; + //size_t count = 0; queue_push_front(&queue, 0, 0); while (!queue_empty(&queue)) { @@ -377,7 +377,7 @@ dfa_max_overlap(GVA_Allocator const allocator, size_t const rhs_ref = rhs_idx / rhs_width + rhs_variant.start; size_t const included = queue.entries[HASH_TABLE_INDEX(queue.entries, idx)].included; - count += 1; + //count += 1; // fprintf(stderr, "{%zu, %zu} (%zu): %zu\n", lhs_idx, rhs_idx, idx, included); if ((lhs_idx == 0 && rhs_ref < lhs_ref) || lhs_idx == lhs_size - 1) @@ -516,7 +516,7 @@ dfa_max_overlap(GVA_Allocator const allocator, } // if } // while - fprintf(stderr, "count: %zu\n", count); + //fprintf(stderr, "count: %zu\n", count); size_t included = limit; size_t const idx = HASH_TABLE_INDEX(queue.entries, lhs_size * rhs_size - 1); diff --git a/src/main.c b/src/main.c index 58dc25b..5937717 100644 --- a/src/main.c +++ b/src/main.c @@ -17,7 +17,6 @@ #include "../include/variant.h" // GVA_VARIANT_*, GVA_Variant, gva_parse_spdi, gva_patch, gva_variant_* #include "align.h" // LCS_Matches, lcs_align_one #include "array.h" // ARRAY_*, array_length -#include "bitset.h" // bitset_* #include "common.h" // MAX, MIN #include "dfa.h" // dfa_* #include "trie.h" // Trie, trie_* @@ -784,10 +783,10 @@ all_main(int argc, char* argv[static argc]) GVA_String lhs_dfa = trie_string(dfas, entries[i].dfa); GVA_String rhs_dfa = trie_string(dfas, entries[j].dfa); - //size_t const overlap = dfa_max_overlap(gva_std_allocator, reference.len, reference.str, lhs, (uint8_t*) lhs_dfa.str, rhs, (uint8_t*) rhs_dfa.str, 0); - bool const disjoint = dfa_disjoint(lhs, (uint8_t*) lhs_dfa.str, rhs, (uint8_t*) rhs_dfa.str); + size_t const overlap = dfa_max_overlap(gva_std_allocator, reference.len, reference.str, lhs, (uint8_t*) lhs_dfa.str, rhs, (uint8_t*) rhs_dfa.str, 0); + //bool const disjoint = dfa_disjoint(lhs, (uint8_t*) lhs_dfa.str, rhs, (uint8_t*) rhs_dfa.str); - if (disjoint) + if (overlap == 0) { fprintf(stdout, GVA_STRING_FMT " disjoint " GVA_STRING_FMT "\n", GVA_STRING_PRINT(trie_string(labels, entries[i].label)), From acb30446a5b170c4253e4f97808765d21f8a66ce Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 8 May 2026 18:23:34 +0200 Subject: [PATCH 638/704] Newline --- include/relations.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/relations.h b/include/relations.h index d4f1fe7..08a2056 100644 --- a/include/relations.h +++ b/include/relations.h @@ -22,4 +22,4 @@ static char const* const GVA_RELATION_LABELS[] = }; -#endif // GVA_RELATIONS_H \ No newline at end of file +#endif // GVA_RELATIONS_H From 5a0e6d23e53d677cd7c28b31cde5d22e37650fbb Mon Sep 17 00:00:00 2001 From: jkvis Date: Sat, 9 May 2026 12:29:55 +0200 Subject: [PATCH 639/704] WIP: index with DFAs --- src/hash_table.c | 7 ++++- src/index.c | 67 ++++++++++++++++----------------------------- src/interval_tree.h | 1 + 3 files changed, 30 insertions(+), 45 deletions(-) diff --git a/src/hash_table.c b/src/hash_table.c index a9c451d..957c9ff 100644 --- a/src/hash_table.c +++ b/src/hash_table.c @@ -10,7 +10,12 @@ void* hash_table_init(GVA_Allocator const allocator, size_t const capacity, size_t const item_size) { - void* hash_table = array_init(allocator, capacity, item_size); + void* const hash_table = array_init(allocator, capacity, item_size); + if (hash_table == NULL) + { + return NULL; // OOM + } // if + for (size_t i = 0; i < capacity; ++i) { *(uint64_t*) ((uintmax_t) hash_table + i * item_size) = HASH_TABLE_NOT_FOUND; diff --git a/src/index.c b/src/index.c index b405367..e00de44 100644 --- a/src/index.c +++ b/src/index.c @@ -1,6 +1,5 @@ #include // NULL, size_t -#include // intmax_t -#include // memcpy +#include // intmax_t, uint8_t #include "../include/allocator.h" // GVA_Allocator #include "../include/edit.h" // gva_edit_distance @@ -11,10 +10,11 @@ // GVA_IS_CONTAINED #include "../include/string.h" // GVA_String #include "../include/types.h" // GVA_NULL, GVA_Interval, gva_uint -#include "../include/variant.h" // GVA_Variant, gva_variant_dup +#include "../include/variant.h" // GVA_Variant, gva_patch, gva_variant_dup #include "array.h" // ARRAY_*, array_length #include "bitset.h" // bitset_* #include "common.h" // ABS, MAX, MIN +#include "dfa.h" // dfa_* #include "hash_table.h" // HASH_TABLE_*, hash_table_* #include "interval_tree.h" // Interval_Tree, interval_tree_* #include "trie.h" // Trie, trie_* @@ -41,6 +41,7 @@ struct GVA_Index GVA_String reference; Interval_Tree intervals; Trie inserted; + Trie dfas; Trie ids; Allele* alleles; Join* join; @@ -81,7 +82,7 @@ variant_from_index(GVA_Index const self[static 1], size_t const idx) } // variant_from_index -static size_t +static inline size_t variants_distance(GVA_Allocator const allocator, size_t const len_ref, char const reference[static len_ref], GVA_Variant const lhs, GVA_Variant const rhs) @@ -101,31 +102,9 @@ variants_distance(GVA_Allocator const allocator, return len_lhs; } // if - GVA_String observed_lhs = gva_string_init(allocator, len_lhs); - GVA_String observed_rhs = gva_string_init(allocator, len_rhs); - if (observed_lhs.str == NULL || observed_rhs.str == NULL) - { - gva_string_destroy(allocator, observed_rhs); - gva_string_destroy(allocator, observed_lhs); - return -1; // FIXME: OOM - } // if - - memcpy((char*) observed_lhs.str, reference + start, lhs.start - start); - if (lhs.sequence.str != NULL) - { - memcpy((char*) observed_lhs.str + lhs.start - start, lhs.sequence.str, lhs.sequence.len); - } // if - memcpy((char*) observed_lhs.str + lhs.start - start + lhs.sequence.len, reference + lhs.end, end - lhs.end); - - memcpy((char*) observed_rhs.str, reference + start, rhs.start - start); - if (rhs.sequence.str != NULL) - { - memcpy((char*) observed_rhs.str + rhs.start - start, rhs.sequence.str, rhs.sequence.len); - } // if - memcpy((char*) observed_rhs.str + rhs.start - start + rhs.sequence.len, reference + rhs.end, end - rhs.end); - + GVA_String observed_lhs = gva_patch(allocator, end - start, reference + start, 1, &(GVA_Variant const) {lhs.start - start, lhs.end - start, lhs.sequence}); + GVA_String observed_rhs = gva_patch(allocator, end - start, reference + start, 1, &(GVA_Variant const) {rhs.start - start, rhs.end - start, rhs.sequence}); size_t const distance = gva_edit_distance(allocator, observed_lhs.len, observed_lhs.str, observed_rhs.len, observed_rhs.str); - gva_string_destroy(allocator, observed_rhs); gva_string_destroy(allocator, observed_lhs); @@ -142,23 +121,9 @@ variants_included(GVA_Allocator const allocator, size_t const start = MIN(lhs.start, rhs.start); size_t const end = MAX(lhs.end, rhs.end); - GVA_String observed_lhs = gva_string_init(allocator, (lhs.start - start) + lhs.sequence.len + (end - lhs.end)); - GVA_String observed_rhs = gva_string_init(allocator, (rhs.start - start) + rhs.sequence.len + (end - rhs.end)); - - memcpy((char*) observed_lhs.str, reference + start, lhs.start - start); - if (lhs.sequence.str != NULL) - { - memcpy((char*) observed_lhs.str + lhs.start - start, lhs.sequence.str, lhs.sequence.len); - } // if - memcpy((char*) observed_lhs.str + lhs.start - start + lhs.sequence.len, reference + lhs.end, end - lhs.end); - - memcpy((char*) observed_rhs.str, reference + start, rhs.start - start); - if (rhs.sequence.str != NULL) - { - memcpy((char*) observed_rhs.str + rhs.start - start, rhs.sequence.str, rhs.sequence.len); - } // if - memcpy((char*) observed_rhs.str + rhs.start - start + rhs.sequence.len, reference + rhs.end, end - rhs.end); + GVA_String observed_lhs = gva_patch(allocator, end - start, reference + start, 1, &(GVA_Variant const) {lhs.start - start, lhs.end - start, lhs.sequence}); + GVA_String observed_rhs = gva_patch(allocator, end - start, reference + start, 1, &(GVA_Variant const) {rhs.start - start, rhs.end - start, rhs.sequence}); GVA_LCS_Graph lhs_graph = gva_lcs_graph_init(allocator, end - start, reference + start, observed_lhs.len, observed_lhs.str, start); GVA_LCS_Graph rhs_graph = gva_lcs_graph_init(allocator, end - start, reference + start, observed_rhs.len, observed_rhs.str, start); @@ -264,6 +229,7 @@ gva_index_init(GVA_Allocator const allocator, index->intervals = interval_tree_init(allocator); index->inserted = trie_init(allocator); + index->dfas = trie_init(allocator); index->ids = trie_init(allocator); @@ -284,6 +250,7 @@ gva_index_destroy(GVA_Index* const self) interval_tree_destroy(&self->intervals); trie_destroy(&self->inserted); + trie_destroy(&self->dfas); trie_destroy(&self->ids); self->alleles = ARRAY_DESTROY(self->allocator, self->alleles); self->join = ARRAY_DESTROY(self->allocator, self->join); @@ -332,6 +299,14 @@ gva_index_insert(GVA_Index* restrict const self, { array_header(self->intervals.nodes)->length -= 1; } // if + else + { + uint8_t* dfa = dfa_from_alignment(self->allocator, NULL, + variant.end - variant.start, self->reference.str + variant.start, + variant.sequence.len, variant.sequence.str); + self->intervals.nodes[node_idx].dfa = trie_insert(&self->dfas, array_length(dfa), (char*) dfa); + dfa = ARRAY_DESTROY(self->allocator, dfa); + } // else self->intervals.nodes[node_idx].alleles = ARRAY_APPEND(self->allocator, self->join, ((Join) { @@ -358,6 +333,10 @@ gva_index_query(GVA_Allocator const allocator, gva_uint head; // singly linked list in hits gva_uint tail; }* entries = hash_table_init(allocator, INITIAL_SIZE, sizeof(*entries)); + if (entries == NULL) + { + return (GVA_Query_Result) {NULL}; // OOM + } // if struct Hit { diff --git a/src/interval_tree.h b/src/interval_tree.h index 3199de4..51c91e5 100644 --- a/src/interval_tree.h +++ b/src/interval_tree.h @@ -23,6 +23,7 @@ typedef struct gva_uint inserted : sizeof(gva_uint) * CHAR_BIT - BALANCE_BITS; gva_uint alleles; gva_uint distance; + gva_uint dfa; } Interval_Tree_Node; From 5767636bf99d779e11e65481e662c517806cdd76 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Mon, 11 May 2026 16:19:21 +0200 Subject: [PATCH 640/704] WIP: dfa_concat --- src/main.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 91 insertions(+), 8 deletions(-) diff --git a/src/main.c b/src/main.c index 5937717..66deb7f 100644 --- a/src/main.c +++ b/src/main.c @@ -508,6 +508,75 @@ supremal_main(int argc, char* argv[static argc]) } // supremal_main +static inline uint8_t +get(uint8_t const dfa[static 1], size_t const idx) +{ + return dfa[idx / 4] >> (2 * (idx % 4)); +} // get + + +static inline void +set(uint8_t dfa[static 1], size_t const idx, uint8_t const value) +{ + dfa[idx / 4] |= value << (2 * (idx % 4)); +} // set + + +uint8_t* +dfa_concat(GVA_Allocator const allocator, size_t const len, GVA_Variant const variants[static restrict len], uint8_t const* const dfas[static restrict len]) +{ + + size_t const start = variants[0].start; + size_t const end = variants[len - 1].end; + + fprintf(stderr, "%zu\n", end - start + 1); + + size_t width = 1; + for (size_t i = 0; i < len; ++i) + { + if (i > 0) + { + width += variants[i].start - variants[i - 1].end; + } // if + width += variants[i].sequence.len; + } // for + size_t const size = (end - start + 1) * width; + + fprintf(stderr, "width: %zu\n", width); + size_t const bytes = (size + 3) / 4; + + uint8_t* dfa = allocator.allocate(allocator.context, NULL, 0, bytes); + if (dfa == NULL) + { + return NULL; // OOM + } // if + memset(dfa, 0, bytes); + + size_t offset_col = 0; + for (size_t i = 0; i < len; ++i) + { + size_t const offset_row = variants[i].start - variants[0].start; + if (i > 0) + { + offset_col += variants[i - 1].sequence.len + variants[i].start - variants[i - 1].end; + } + fprintf(stderr, "offsets %zu, %zu\n", offset_row, offset_col); + for (size_t j = 0; j <= variants[i].end - variants[i].start; ++j) + { + for (size_t k = 0; k <= variants[i].sequence.len; ++k) + { + fprintf(stderr, "j: %zu, k: %zu\n", j, k); + uint8_t const value = get(dfas[i], j * (variants[i].sequence.len + 1) + k); + set(dfa, (j + offset_row) * width + k + offset_col, value); + fprintf(stderr, "set @ %zu, %zu\n", j + offset_row, k + offset_col); + } // for + + } // for + } + + return dfa; +} + int overlap_main(int argc, char* argv[static argc]) { @@ -544,21 +613,35 @@ overlap_main(int argc, char* argv[static argc]) continue; } // if + uint8_t* vec[2] = {NULL}; + GVA_Variant vars[2]; + GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &rhs_variant); + for (size_t i = 0; i < array_length(graph.dom_nodes) - 1; ++i) + { + vars[i] = gva_variant_dup(gva_std_allocator, gva_lcs_graph_local_supremal(graph, i, i + 1)); + fprintf(stdout, GVA_VARIANT_FMT_SPDI " %u\n", + GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, vars[i]), + graph.dom_nodes[i + 1].distance - graph.dom_nodes[i].distance); + vec[i] = dfa_from_alignment(gva_std_allocator, NULL, vars[i].end - vars[i].start, reference.str + vars[i].start, vars[i].sequence.len, vars[i].sequence.str); + } // for + uint8_t* dfa = dfa_concat(gva_std_allocator, 2, vars, vec); + dfa_dot(stdout, reference.len, reference.str, rhs_variant, dfa); + + dfa = gva_std_allocator.allocate(gva_std_allocator.context, dfa, 0, 0); + uint8_t* lhs_dfa = dfa_from_alignment(gva_std_allocator, NULL, lhs_variant.end - lhs_variant.start, reference.str + lhs_variant.start, lhs_variant.sequence.len, lhs_variant.sequence.str); uint8_t* rhs_dfa = dfa_from_alignment(gva_std_allocator, NULL, rhs_variant.end - rhs_variant.start, reference.str + rhs_variant.start, rhs_variant.sequence.len, rhs_variant.sequence.str); - /* - dfa_dot(stdout, reference.len, reference.str, lhs_variant, lhs_dfa); - dfa_dot(stdout, reference.len, reference.str, rhs_variant, rhs_dfa); - dfa_svg(stdout, reference.len, reference.str, lhs_variant, lhs_dfa); - dfa_svg(stdout, reference.len, reference.str, rhs_variant, rhs_dfa); + // dfa_dot(stdout, reference.len, reference.str, lhs_variant, lhs_dfa); + // dfa_dot(stdout, reference.len, reference.str, rhs_variant, rhs_dfa); + // dfa_svg(stdout, reference.len, reference.str, lhs_variant, lhs_dfa); + // dfa_svg(stdout, reference.len, reference.str, rhs_variant, rhs_dfa); fprintf(stderr, "disjoint: %d\n", dfa_disjoint(lhs_variant, lhs_dfa, rhs_variant, rhs_dfa)); fprintf(stderr, "max_overlap: %zu\n", dfa_max_overlap(gva_std_allocator, reference.len, reference.str, lhs_variant, lhs_dfa, rhs_variant, rhs_dfa, 0)); - */ fprintf(stdout, "%zu\n", dfa_max_overlap(gva_std_allocator, reference.len, reference.str, lhs_variant, lhs_dfa, @@ -822,6 +905,6 @@ main(int argc, char* argv[static argc]) // return allele_main(argc, argv); // return index_main(argc, argv); // return supremal_main(argc, argv); - // return overlap_main(argc, argv); - return all_main(argc, argv); + return overlap_main(argc, argv); + // return all_main(argc, argv); } // main From a32932948aad25169e1449b4f4078231f3e0d95e Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 11 May 2026 19:02:07 +0200 Subject: [PATCH 641/704] WIP: DFA concat --- src/dfa.c | 59 ++++++++++++++++++++++++++++++++++++ src/dfa.h | 6 ++++ src/main.c | 89 +++++++++--------------------------------------------- 3 files changed, 79 insertions(+), 75 deletions(-) diff --git a/src/dfa.c b/src/dfa.c index 47df30b..fb5fe93 100644 --- a/src/dfa.c +++ b/src/dfa.c @@ -52,6 +52,65 @@ edge(uint8_t dfa[static 1], size_t const width, } // edge +uint8_t* +dfa_concat(GVA_Allocator const allocator, size_t const n, + GVA_Variant const variants[static restrict n], + uint8_t* const dfas[static restrict n]) +{ + if (n == 0) + { + return NULL; + } // if + if (n == 1) + { + return dfas[0]; + } // if + + size_t const start = variants[0].start; + size_t const end = variants[n - 1].end; + + size_t width = 1; + for (size_t i = 0; i < n; ++i) + { + if (i > 0) + { + width += variants[i].start - variants[i - 1].end; + } // if + width += variants[i].sequence.len; + } // for + size_t const size = (end - start + 1) * width; + size_t const len = (size + 3) / 4; + + uint8_t* dfa = allocator.allocate(allocator.context, NULL, 0, len); + if (dfa == NULL) + { + return NULL; // OOM + } // if + memset(dfa, 0, len); + + size_t offset_col = 0; + for (size_t i = 0; i < n; ++i) + { + size_t const offset_row = variants[i].start - start; + if (i > 0) + { + offset_col += variants[i - 1].sequence.len + variants[i].start - variants[i - 1].end; + } // if + for (size_t j = 0; j <= variants[i].end - variants[i].start; ++j) + { + for (size_t k = 0; k <= variants[i].sequence.len; ++k) + { + fprintf(stderr, "cpy %zu, %zu -> %zu, %zu\n", j, k, j + offset_row, k + offset_col); + set(dfa, (j + offset_row) * width + k + offset_col, + get(dfas[i], j * (variants[i].sequence.len + 1) + k)); + } // for + } // for + } // for + + return dfa; +} // dfa_concat + + uint8_t* dfa_from_alignment(GVA_Allocator const allocator, uint8_t* dfas, size_t const len_ref, char const reference[static restrict len_ref], diff --git a/src/dfa.h b/src/dfa.h index 81cd214..8a548e8 100644 --- a/src/dfa.h +++ b/src/dfa.h @@ -14,6 +14,12 @@ #include // FIXME: DEBUG +uint8_t* +dfa_concat(GVA_Allocator const allocator, size_t const n, + GVA_Variant const variants[static restrict n], + uint8_t* const dfas[static restrict n]); + + uint8_t* dfa_from_alignment(GVA_Allocator const allocator, uint8_t* dfas, size_t const len_ref, char const reference[static restrict len_ref], diff --git a/src/main.c b/src/main.c index 66deb7f..994e9e3 100644 --- a/src/main.c +++ b/src/main.c @@ -508,75 +508,6 @@ supremal_main(int argc, char* argv[static argc]) } // supremal_main -static inline uint8_t -get(uint8_t const dfa[static 1], size_t const idx) -{ - return dfa[idx / 4] >> (2 * (idx % 4)); -} // get - - -static inline void -set(uint8_t dfa[static 1], size_t const idx, uint8_t const value) -{ - dfa[idx / 4] |= value << (2 * (idx % 4)); -} // set - - -uint8_t* -dfa_concat(GVA_Allocator const allocator, size_t const len, GVA_Variant const variants[static restrict len], uint8_t const* const dfas[static restrict len]) -{ - - size_t const start = variants[0].start; - size_t const end = variants[len - 1].end; - - fprintf(stderr, "%zu\n", end - start + 1); - - size_t width = 1; - for (size_t i = 0; i < len; ++i) - { - if (i > 0) - { - width += variants[i].start - variants[i - 1].end; - } // if - width += variants[i].sequence.len; - } // for - size_t const size = (end - start + 1) * width; - - fprintf(stderr, "width: %zu\n", width); - size_t const bytes = (size + 3) / 4; - - uint8_t* dfa = allocator.allocate(allocator.context, NULL, 0, bytes); - if (dfa == NULL) - { - return NULL; // OOM - } // if - memset(dfa, 0, bytes); - - size_t offset_col = 0; - for (size_t i = 0; i < len; ++i) - { - size_t const offset_row = variants[i].start - variants[0].start; - if (i > 0) - { - offset_col += variants[i - 1].sequence.len + variants[i].start - variants[i - 1].end; - } - fprintf(stderr, "offsets %zu, %zu\n", offset_row, offset_col); - for (size_t j = 0; j <= variants[i].end - variants[i].start; ++j) - { - for (size_t k = 0; k <= variants[i].sequence.len; ++k) - { - fprintf(stderr, "j: %zu, k: %zu\n", j, k); - uint8_t const value = get(dfas[i], j * (variants[i].sequence.len + 1) + k); - set(dfa, (j + offset_row) * width + k + offset_col, value); - fprintf(stderr, "set @ %zu, %zu\n", j + offset_row, k + offset_col); - } // for - - } // for - } - - return dfa; -} - int overlap_main(int argc, char* argv[static argc]) { @@ -613,20 +544,28 @@ overlap_main(int argc, char* argv[static argc]) continue; } // if - uint8_t* vec[2] = {NULL}; - GVA_Variant vars[2]; + GVA_Variant variants[2]; + uint8_t* dfas[2] = {NULL}; + GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &rhs_variant); for (size_t i = 0; i < array_length(graph.dom_nodes) - 1; ++i) { - vars[i] = gva_variant_dup(gva_std_allocator, gva_lcs_graph_local_supremal(graph, i, i + 1)); + variants[i] = gva_variant_dup(gva_std_allocator, gva_lcs_graph_local_supremal(graph, i, i + 1)); fprintf(stdout, GVA_VARIANT_FMT_SPDI " %u\n", - GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, vars[i]), + GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, variants[i]), graph.dom_nodes[i + 1].distance - graph.dom_nodes[i].distance); - vec[i] = dfa_from_alignment(gva_std_allocator, NULL, vars[i].end - vars[i].start, reference.str + vars[i].start, vars[i].sequence.len, vars[i].sequence.str); + dfas[i] = dfa_from_alignment(gva_std_allocator, NULL, variants[i].end - variants[i].start, reference.str + variants[i].start, variants[i].sequence.len, variants[i].sequence.str); } // for - uint8_t* dfa = dfa_concat(gva_std_allocator, 2, vars, vec); + uint8_t* dfa = dfa_concat(gva_std_allocator, 2, variants, dfas); dfa_dot(stdout, reference.len, reference.str, rhs_variant, dfa); + for (size_t i = 0; i < array_length(graph.dom_nodes) - 1; ++i) + { + gva_string_destroy(gva_std_allocator, variants[i].sequence); + dfas[i] = ARRAY_DESTROY(gva_std_allocator, dfas[i]); + } // for + gva_lcs_graph_destroy(gva_std_allocator, graph, true); + dfa = gva_std_allocator.allocate(gva_std_allocator.context, dfa, 0, 0); uint8_t* lhs_dfa = dfa_from_alignment(gva_std_allocator, NULL, lhs_variant.end - lhs_variant.start, reference.str + lhs_variant.start, lhs_variant.sequence.len, lhs_variant.sequence.str); From bda1fce9fea4e1cfad10e1924ce9d90dd5e67cba Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 12 May 2026 13:59:24 +0200 Subject: [PATCH 642/704] WIP: dfa from subgraphs (not working) --- src/dfa.c | 74 ++++++++++++++++++++++++++++++++++++++++-------------- src/dfa.h | 4 +-- src/main.c | 12 ++++++--- 3 files changed, 66 insertions(+), 24 deletions(-) diff --git a/src/dfa.c b/src/dfa.c index fb5fe93..9f105e3 100644 --- a/src/dfa.c +++ b/src/dfa.c @@ -247,42 +247,78 @@ dfa_from_alignment(GVA_Allocator const allocator, uint8_t* dfas, uint8_t* -dfa_from_lcs_graph(GVA_Allocator const allocator, uint8_t* dfas, - GVA_LCS_Graph const graph) +dfa_from_lcs_graph(GVA_Allocator const allocator, + GVA_LCS_Graph const graph, size_t const start, size_t const end) { - GVA_Variant const supremal = gva_lcs_graph_supremal(graph); - size_t const width = supremal.sequence.len + 1; - size_t const size = (supremal.end - supremal.start + 1) * width; + size_t const start_dfa = graph.dom_nodes[start].match.row + graph.dom_nodes[start].match.length; + size_t const end_dfa = graph.dom_nodes[end].match.row; + size_t const width = graph.dom_nodes[end].match.col - (graph.dom_nodes[start].match.col + graph.dom_nodes[start].match.length) + 1; + size_t const size = (end_dfa - start_dfa + 1) * width; size_t const len = (size + 3) / 4; - dfas = array_ensure(allocator, dfas, 1, len); - if (dfas == NULL) + uint8_t* dfa = allocator.allocate(allocator.context, NULL, 0, len); + if (dfa == NULL) { return NULL; // OOM } // if - size_t const start = array_length(dfas); - memset(dfas + start, 0, len); - array_header(dfas)->length += len; + memset(dfa, 0, len); + + fprintf(stderr, "DFA: %zu x %zu\n", end_dfa - start_dfa + 1, width); + + struct Entry + { + gva_uint seen; + gva_uint next; + }* queue = allocator.allocate(allocator.context, NULL, 0, sizeof(*queue) * array_length(graph.nodes)); + if (queue == NULL) + { + dfa = allocator.allocate(allocator.context, dfa, len, 0); + return NULL; // OOM + } // if + + memset(queue, 0, sizeof(*queue) * array_length(graph.nodes)); - for (size_t i = 0; i < array_length(graph.nodes); ++i) + gva_uint head = graph.dom_nodes[start].link; + gva_uint tail = head; + queue[head] = (struct Entry) {true, GVA_NULL}; + while (head != GVA_NULL) { - for (gva_uint j = graph.nodes[i].edges; j != GVA_NULL; j = graph.edges[j].next) + fprintf(stderr, "POP %u\n", head); + + if (head == graph.dom_nodes[end].link) + { + break; + } // if + + for (gva_uint i = graph.nodes[head].edges; i != GVA_NULL; i = graph.edges[i].next) { GVA_Variant variant = {0}; size_t const count = gva_edges(graph.observed.str, - graph.nodes[i].match, graph.nodes[graph.edges[j].tail].match, - i == graph.source, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, + graph.nodes[head].match, graph.nodes[graph.edges[i].tail].match, + head == graph.source, graph.nodes[graph.edges[i].tail].edges == GVA_NULL, &variant); - for (size_t k = 0; k < count; ++k) + for (size_t j = 0; j < count; ++j) { - edge(dfas + start, width, variant.start + k - supremal.start, variant.end + k - supremal.start, - variant.sequence.len, variant.sequence.str - supremal.sequence.str + k); + edge(dfa, width, variant.start + j - start_dfa, variant.end + j - start_dfa, + variant.sequence.len, variant.sequence.str - graph.observed.str + j); } // for + + if (!queue[graph.edges[i].tail].seen) + { + fprintf(stderr, "PUSH %u\n", graph.edges[i].tail); + queue[graph.edges[i].tail] = (struct Entry) {true, GVA_NULL}; + queue[tail].next = graph.edges[i].tail; + tail = graph.edges[i].tail; + } // if } // for - } // for - return dfas; + head = queue[head].next; + } // while + + queue = allocator.allocate(allocator.context, queue, sizeof(*queue) * array_length(graph.nodes), 0); + + return dfa; } // dfa_from_lcs_graph diff --git a/src/dfa.h b/src/dfa.h index 8a548e8..6da1e24 100644 --- a/src/dfa.h +++ b/src/dfa.h @@ -27,8 +27,8 @@ dfa_from_alignment(GVA_Allocator const allocator, uint8_t* dfas, uint8_t* -dfa_from_lcs_graph(GVA_Allocator const allocator, uint8_t* dfas, - GVA_LCS_Graph const graph); +dfa_from_lcs_graph(GVA_Allocator const allocator, + GVA_LCS_Graph const graph, size_t const start, size_t const end); size_t diff --git a/src/main.c b/src/main.c index 994e9e3..40a732a 100644 --- a/src/main.c +++ b/src/main.c @@ -550,7 +550,7 @@ overlap_main(int argc, char* argv[static argc]) GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &rhs_variant); for (size_t i = 0; i < array_length(graph.dom_nodes) - 1; ++i) { - variants[i] = gva_variant_dup(gva_std_allocator, gva_lcs_graph_local_supremal(graph, i, i + 1)); + variants[i] = gva_lcs_graph_local_supremal(graph, i, i + 1); fprintf(stdout, GVA_VARIANT_FMT_SPDI " %u\n", GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, variants[i]), graph.dom_nodes[i + 1].distance - graph.dom_nodes[i].distance); @@ -561,9 +561,15 @@ overlap_main(int argc, char* argv[static argc]) for (size_t i = 0; i < array_length(graph.dom_nodes) - 1; ++i) { - gva_string_destroy(gva_std_allocator, variants[i].sequence); dfas[i] = ARRAY_DESTROY(gva_std_allocator, dfas[i]); } // for + + uint8_t* gdfa = dfa_from_lcs_graph(gva_std_allocator, graph, 0, 2); + + dfa_dot(stdout, reference.len, reference.str, rhs_variant, gdfa); + + gdfa = gva_std_allocator.allocate(gva_std_allocator.context, gdfa, 0, 0); + gva_lcs_graph_destroy(gva_std_allocator, graph, true); dfa = gva_std_allocator.allocate(gva_std_allocator.context, dfa, 0, 0); @@ -572,7 +578,7 @@ overlap_main(int argc, char* argv[static argc]) uint8_t* rhs_dfa = dfa_from_alignment(gva_std_allocator, NULL, rhs_variant.end - rhs_variant.start, reference.str + rhs_variant.start, rhs_variant.sequence.len, rhs_variant.sequence.str); // dfa_dot(stdout, reference.len, reference.str, lhs_variant, lhs_dfa); - // dfa_dot(stdout, reference.len, reference.str, rhs_variant, rhs_dfa); + dfa_dot(stdout, reference.len, reference.str, rhs_variant, rhs_dfa); // dfa_svg(stdout, reference.len, reference.str, lhs_variant, lhs_dfa); // dfa_svg(stdout, reference.len, reference.str, rhs_variant, rhs_dfa); From db81bc5cd1bd0bb467c17838a8f4b0bf6ee01a05 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 12 May 2026 16:50:36 +0200 Subject: [PATCH 643/704] WIP: DFA from subgraphs --- src/dfa.c | 11 +++++++++-- src/main.c | 36 ++++++++++++++++-------------------- 2 files changed, 25 insertions(+), 22 deletions(-) diff --git a/src/dfa.c b/src/dfa.c index 9f105e3..d04457a 100644 --- a/src/dfa.c +++ b/src/dfa.c @@ -45,6 +45,7 @@ edge(uint8_t dfa[static 1], size_t const width, { for (size_t j = 0; j <= len; ++j) { + fprintf(stderr, "%zu, %zu\n", i, j); set(dfa, i * width + offset + j, (i < end) * DFA_DELETION | (j < len) * DFA_INSERTION); } // for @@ -279,6 +280,8 @@ dfa_from_lcs_graph(GVA_Allocator const allocator, memset(queue, 0, sizeof(*queue) * array_length(graph.nodes)); + GVA_Variant const supremal = gva_lcs_graph_supremal(graph); + gva_uint head = graph.dom_nodes[start].link; gva_uint tail = head; queue[head] = (struct Entry) {true, GVA_NULL}; @@ -288,7 +291,8 @@ dfa_from_lcs_graph(GVA_Allocator const allocator, if (head == graph.dom_nodes[end].link) { - break; + head = queue[head].next; + continue; } // if for (gva_uint i = graph.nodes[head].edges; i != GVA_NULL; i = graph.edges[i].next) @@ -298,10 +302,13 @@ dfa_from_lcs_graph(GVA_Allocator const allocator, graph.nodes[head].match, graph.nodes[graph.edges[i].tail].match, head == graph.source, graph.nodes[graph.edges[i].tail].edges == GVA_NULL, &variant); + + fprintf(stderr, GVA_VARIANT_FMT " x %zu\n", GVA_VARIANT_PRINT(variant), count); + for (size_t j = 0; j < count; ++j) { edge(dfa, width, variant.start + j - start_dfa, variant.end + j - start_dfa, - variant.sequence.len, variant.sequence.str - graph.observed.str + j); + variant.sequence.len, variant.sequence.str - supremal.sequence.str + j); } // for if (!queue[graph.edges[i].tail].seen) diff --git a/src/main.c b/src/main.c index 40a732a..713b3af 100644 --- a/src/main.c +++ b/src/main.c @@ -554,14 +554,12 @@ overlap_main(int argc, char* argv[static argc]) fprintf(stdout, GVA_VARIANT_FMT_SPDI " %u\n", GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, variants[i]), graph.dom_nodes[i + 1].distance - graph.dom_nodes[i].distance); - dfas[i] = dfa_from_alignment(gva_std_allocator, NULL, variants[i].end - variants[i].start, reference.str + variants[i].start, variants[i].sequence.len, variants[i].sequence.str); + //dfas[i] = dfa_from_alignment(gva_std_allocator, NULL, variants[i].end - variants[i].start, reference.str + variants[i].start, variants[i].sequence.len, variants[i].sequence.str); } // for - uint8_t* dfa = dfa_concat(gva_std_allocator, 2, variants, dfas); - dfa_dot(stdout, reference.len, reference.str, rhs_variant, dfa); for (size_t i = 0; i < array_length(graph.dom_nodes) - 1; ++i) { - dfas[i] = ARRAY_DESTROY(gva_std_allocator, dfas[i]); + //dfas[i] = ARRAY_DESTROY(gva_std_allocator, dfas[i]); } // for uint8_t* gdfa = dfa_from_lcs_graph(gva_std_allocator, graph, 0, 2); @@ -572,28 +570,26 @@ overlap_main(int argc, char* argv[static argc]) gva_lcs_graph_destroy(gva_std_allocator, graph, true); - dfa = gva_std_allocator.allocate(gva_std_allocator.context, dfa, 0, 0); + //uint8_t* dfa = dfa_concat(gva_std_allocator, 2, variants, dfas); + //dfa_dot(stdout, reference.len, reference.str, rhs_variant, dfa); + //dfa = gva_std_allocator.allocate(gva_std_allocator.context, dfa, 0, 0); - uint8_t* lhs_dfa = dfa_from_alignment(gva_std_allocator, NULL, lhs_variant.end - lhs_variant.start, reference.str + lhs_variant.start, lhs_variant.sequence.len, lhs_variant.sequence.str); - uint8_t* rhs_dfa = dfa_from_alignment(gva_std_allocator, NULL, rhs_variant.end - rhs_variant.start, reference.str + rhs_variant.start, rhs_variant.sequence.len, rhs_variant.sequence.str); + //uint8_t* lhs_dfa = dfa_from_alignment(gva_std_allocator, NULL, lhs_variant.end - lhs_variant.start, reference.str + lhs_variant.start, lhs_variant.sequence.len, lhs_variant.sequence.str); + //uint8_t* rhs_dfa = dfa_from_alignment(gva_std_allocator, NULL, rhs_variant.end - rhs_variant.start, reference.str + rhs_variant.start, rhs_variant.sequence.len, rhs_variant.sequence.str); // dfa_dot(stdout, reference.len, reference.str, lhs_variant, lhs_dfa); - dfa_dot(stdout, reference.len, reference.str, rhs_variant, rhs_dfa); + //dfa_dot(stdout, reference.len, reference.str, rhs_variant, rhs_dfa); // dfa_svg(stdout, reference.len, reference.str, lhs_variant, lhs_dfa); // dfa_svg(stdout, reference.len, reference.str, rhs_variant, rhs_dfa); - fprintf(stderr, "disjoint: %d\n", dfa_disjoint(lhs_variant, lhs_dfa, rhs_variant, rhs_dfa)); - fprintf(stderr, "max_overlap: %zu\n", dfa_max_overlap(gva_std_allocator, - reference.len, reference.str, - lhs_variant, lhs_dfa, - rhs_variant, rhs_dfa, 0)); - fprintf(stdout, "%zu\n", dfa_max_overlap(gva_std_allocator, - reference.len, reference.str, - lhs_variant, lhs_dfa, - rhs_variant, rhs_dfa, 0)); - - rhs_dfa = ARRAY_DESTROY(gva_std_allocator, rhs_dfa); - lhs_dfa = ARRAY_DESTROY(gva_std_allocator, lhs_dfa); + //fprintf(stderr, "disjoint: %d\n", dfa_disjoint(lhs_variant, lhs_dfa, rhs_variant, rhs_dfa)); + //fprintf(stdout, "%zu\n", dfa_max_overlap(gva_std_allocator, + // reference.len, reference.str, + // lhs_variant, lhs_dfa, + // rhs_variant, rhs_dfa, 0)); + + //rhs_dfa = ARRAY_DESTROY(gva_std_allocator, rhs_dfa); + //lhs_dfa = ARRAY_DESTROY(gva_std_allocator, lhs_dfa); } // while return EXIT_SUCCESS; From 31d841fc820cf42a95c843b0c1a338000c2bd90b Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 12 May 2026 18:52:52 +0200 Subject: [PATCH 644/704] WIP: DFA from subgraph simplify --- src/dfa.c | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/src/dfa.c b/src/dfa.c index d04457a..f335180 100644 --- a/src/dfa.c +++ b/src/dfa.c @@ -45,7 +45,6 @@ edge(uint8_t dfa[static 1], size_t const width, { for (size_t j = 0; j <= len; ++j) { - fprintf(stderr, "%zu, %zu\n", i, j); set(dfa, i * width + offset + j, (i < end) * DFA_DELETION | (j < len) * DFA_INSERTION); } // for @@ -267,31 +266,29 @@ dfa_from_lcs_graph(GVA_Allocator const allocator, fprintf(stderr, "DFA: %zu x %zu\n", end_dfa - start_dfa + 1, width); - struct Entry - { - gva_uint seen; - gva_uint next; - }* queue = allocator.allocate(allocator.context, NULL, 0, sizeof(*queue) * array_length(graph.nodes)); + gva_uint* queue = allocator.allocate(allocator.context, NULL, 0, sizeof(*queue) * array_length(graph.nodes)); if (queue == NULL) { dfa = allocator.allocate(allocator.context, dfa, len, 0); return NULL; // OOM } // if - memset(queue, 0, sizeof(*queue) * array_length(graph.nodes)); + for (size_t i = 0; i < array_length(graph.nodes); ++i) + { + queue[i] = GVA_NULL; + } // for GVA_Variant const supremal = gva_lcs_graph_supremal(graph); gva_uint head = graph.dom_nodes[start].link; gva_uint tail = head; - queue[head] = (struct Entry) {true, GVA_NULL}; while (head != GVA_NULL) { fprintf(stderr, "POP %u\n", head); if (head == graph.dom_nodes[end].link) { - head = queue[head].next; + head = queue[head]; continue; } // if @@ -303,7 +300,7 @@ dfa_from_lcs_graph(GVA_Allocator const allocator, head == graph.source, graph.nodes[graph.edges[i].tail].edges == GVA_NULL, &variant); - fprintf(stderr, GVA_VARIANT_FMT " x %zu\n", GVA_VARIANT_PRINT(variant), count); + fprintf(stderr, " " GVA_VARIANT_FMT " x %zu\n", GVA_VARIANT_PRINT(variant), count); for (size_t j = 0; j < count; ++j) { @@ -311,16 +308,15 @@ dfa_from_lcs_graph(GVA_Allocator const allocator, variant.sequence.len, variant.sequence.str - supremal.sequence.str + j); } // for - if (!queue[graph.edges[i].tail].seen) + if (queue[graph.edges[i].tail] == GVA_NULL) { - fprintf(stderr, "PUSH %u\n", graph.edges[i].tail); - queue[graph.edges[i].tail] = (struct Entry) {true, GVA_NULL}; - queue[tail].next = graph.edges[i].tail; + fprintf(stderr, " PUSH %u\n", graph.edges[i].tail); + queue[tail] = graph.edges[i].tail; tail = graph.edges[i].tail; } // if } // for - head = queue[head].next; + head = queue[head]; } // while queue = allocator.allocate(allocator.context, queue, sizeof(*queue) * array_length(graph.nodes), 0); From 2cb6bef52805cea21e5ac9a42225e1eafcbba180 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 12 May 2026 21:22:49 +0200 Subject: [PATCH 645/704] Restrict uint8_t --- src/dfa.c | 6 +++--- src/dfa.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/dfa.c b/src/dfa.c index f335180..a71f81a 100644 --- a/src/dfa.c +++ b/src/dfa.c @@ -112,7 +112,7 @@ dfa_concat(GVA_Allocator const allocator, size_t const n, uint8_t* -dfa_from_alignment(GVA_Allocator const allocator, uint8_t* dfas, +dfa_from_alignment(GVA_Allocator const allocator, uint8_t* restrict dfas, size_t const len_ref, char const reference[static restrict len_ref], size_t const len_obs, char const observed[static restrict len_obs]) { @@ -256,7 +256,7 @@ dfa_from_lcs_graph(GVA_Allocator const allocator, size_t const size = (end_dfa - start_dfa + 1) * width; size_t const len = (size + 3) / 4; - uint8_t* dfa = allocator.allocate(allocator.context, NULL, 0, len); + uint8_t* restrict dfa = allocator.allocate(allocator.context, NULL, 0, len); if (dfa == NULL) { return NULL; // OOM @@ -266,7 +266,7 @@ dfa_from_lcs_graph(GVA_Allocator const allocator, fprintf(stderr, "DFA: %zu x %zu\n", end_dfa - start_dfa + 1, width); - gva_uint* queue = allocator.allocate(allocator.context, NULL, 0, sizeof(*queue) * array_length(graph.nodes)); + gva_uint* restrict queue = allocator.allocate(allocator.context, NULL, 0, sizeof(*queue) * array_length(graph.nodes)); if (queue == NULL) { dfa = allocator.allocate(allocator.context, dfa, len, 0); diff --git a/src/dfa.h b/src/dfa.h index 6da1e24..570416c 100644 --- a/src/dfa.h +++ b/src/dfa.h @@ -21,7 +21,7 @@ dfa_concat(GVA_Allocator const allocator, size_t const n, uint8_t* -dfa_from_alignment(GVA_Allocator const allocator, uint8_t* dfas, +dfa_from_alignment(GVA_Allocator const allocator, uint8_t* restrict dfas, size_t const len_ref, char const reference[static restrict len_ref], size_t const len_obs, char const observed[static restrict len_obs]); From e6c310a0cd9d772f27b5e79e098a3fd058186e98 Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 13 May 2026 09:33:14 +0200 Subject: [PATCH 646/704] WIP: All DFAs from local supremal parts --- src/dfa.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/dfa.h | 4 +++ src/main.c | 3 ++ 3 files changed, 87 insertions(+) diff --git a/src/dfa.c b/src/dfa.c index a71f81a..5e46c91 100644 --- a/src/dfa.c +++ b/src/dfa.c @@ -325,6 +325,86 @@ dfa_from_lcs_graph(GVA_Allocator const allocator, } // dfa_from_lcs_graph +uint8_t* +dfas_from_lcs_graph(GVA_Allocator const allocator, GVA_LCS_Graph const graph) +{ + uint8_t* restrict dfas = NULL; + + gva_uint* restrict next = allocator.allocate(allocator.context, NULL, 0, sizeof(*next) * array_length(graph.nodes)); + if (next == NULL) + { + return NULL; // OOM + } // if + + for (size_t i = 0; i < array_length(graph.nodes); ++i) + { + next[i] = GVA_NULL; + } // for + + for (size_t i = 0; i < array_length(graph.dom_nodes) - 1; ++i) + { + GVA_Variant const supremal = gva_lcs_graph_local_supremal(graph, i, i + 1); + + size_t const width = supremal.sequence.len + 1; + size_t const size = (supremal.end - supremal.start + 1) * width; + size_t const len = (size + 3) / 4; + + dfas = array_ensure(allocator, dfas, 1, len); + if (dfas == NULL) + { + next = allocator.allocate(allocator.context, next, sizeof(*next) * array_length(graph.nodes), 0); + return NULL; // OOM + } // if + + fprintf(stderr, "DFA %u x %zu\n", supremal.end - supremal.start + 1, width); + + size_t const start = array_length(dfas); + memset(dfas + start, 0, len); + array_header(dfas)->length += len; + + gva_uint head = graph.dom_nodes[i].link; + gva_uint tail = head; + while (head != GVA_NULL) + { + fprintf(stderr, "POP %u\n", head); + + if (head == graph.dom_nodes[i + 1].link) + { + head = next[head]; + continue; + } // if + + for (gva_uint j = graph.nodes[head].edges; j != GVA_NULL; j = graph.edges[j].next) + { + GVA_Variant variant = {0}; + size_t const count = gva_edges(graph.observed.str, + graph.nodes[head].match, graph.nodes[graph.edges[j].tail].match, + head == graph.source, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, + &variant); + for (size_t k = 0; k < count; ++k) + { + edge(dfas + start, width, variant.start + k - supremal.start, variant.end + k - supremal.start, + variant.sequence.len, variant.sequence.str - supremal.sequence.str + k); + } // for + + if (next[graph.edges[j].tail] == GVA_NULL) + { + fprintf(stderr, " PUSH %u\n", graph.edges[j].tail); + next[tail] = graph.edges[j].tail; + tail = graph.edges[j].tail; + } // if + } // for + + head = next[head]; + } // while + } // for + + next = allocator.allocate(allocator.context, next, sizeof(*next) * array_length(graph.nodes), 0); + + return dfas; +} // dfas_from_lcs_graph + + typedef struct { HASH_TABLE_KEY; diff --git a/src/dfa.h b/src/dfa.h index 570416c..df0dfd4 100644 --- a/src/dfa.h +++ b/src/dfa.h @@ -31,6 +31,10 @@ dfa_from_lcs_graph(GVA_Allocator const allocator, GVA_LCS_Graph const graph, size_t const start, size_t const end); +uint8_t* +dfas_from_lcs_graph(GVA_Allocator const allocator, GVA_LCS_Graph const graph); + + size_t dfa_max_overlap(GVA_Allocator const allocator, size_t const len, char const reference[static restrict len], diff --git a/src/main.c b/src/main.c index 713b3af..84e3275 100644 --- a/src/main.c +++ b/src/main.c @@ -548,6 +548,9 @@ overlap_main(int argc, char* argv[static argc]) uint8_t* dfas[2] = {NULL}; GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &rhs_variant); + + dfas_from_lcs_graph(gva_std_allocator, graph); + for (size_t i = 0; i < array_length(graph.dom_nodes) - 1; ++i) { variants[i] = gva_lcs_graph_local_supremal(graph, i, i + 1); From e7915f21eb55c626a7a9eafa46a1b5cb45ec4455 Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 13 May 2026 10:16:07 +0200 Subject: [PATCH 647/704] Pre allocation --- src/dfa.c | 67 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 35 insertions(+), 32 deletions(-) diff --git a/src/dfa.c b/src/dfa.c index 5e46c91..6d405bc 100644 --- a/src/dfa.c +++ b/src/dfa.c @@ -79,14 +79,15 @@ dfa_concat(GVA_Allocator const allocator, size_t const n, width += variants[i].sequence.len; } // for size_t const size = (end - start + 1) * width; - size_t const len = (size + 3) / 4; + size_t const bytes = (size + 3) / 4; - uint8_t* dfa = allocator.allocate(allocator.context, NULL, 0, len); + uint8_t* const restrict dfa = allocator.allocate(allocator.context, NULL, 0, bytes); if (dfa == NULL) { return NULL; // OOM } // if - memset(dfa, 0, len); + + memset(dfa, 0, bytes); size_t offset_col = 0; for (size_t i = 0; i < n; ++i) @@ -126,9 +127,9 @@ dfa_from_alignment(GVA_Allocator const allocator, uint8_t* restrict dfas, size_t const width = len_obs + 1; size_t const size = (len_ref + 1) * width; - size_t const len = (size + 3) / 4; + size_t const bytes = (size + 3) / 4; - dfas = array_ensure(allocator, dfas, 1, len); + dfas = array_ensure(allocator, dfas, 1, bytes); if (dfas == NULL) { lcs.index = allocator.allocate(allocator.context, lcs.index, lcs.length * sizeof(*lcs.index), 0); @@ -137,8 +138,8 @@ dfa_from_alignment(GVA_Allocator const allocator, uint8_t* restrict dfas, } // if size_t const start = array_length(dfas); - memset(dfas + start, 0, len); - array_header(dfas)->length += len; + memset(dfas + start, 0, bytes); + array_header(dfas)->length += bytes; if (lcs.nodes == NULL) { @@ -254,22 +255,22 @@ dfa_from_lcs_graph(GVA_Allocator const allocator, size_t const end_dfa = graph.dom_nodes[end].match.row; size_t const width = graph.dom_nodes[end].match.col - (graph.dom_nodes[start].match.col + graph.dom_nodes[start].match.length) + 1; size_t const size = (end_dfa - start_dfa + 1) * width; - size_t const len = (size + 3) / 4; + size_t const bytes = (size + 3) / 4; - uint8_t* restrict dfa = allocator.allocate(allocator.context, NULL, 0, len); + uint8_t* restrict dfa = allocator.allocate(allocator.context, NULL, 0, bytes); if (dfa == NULL) { return NULL; // OOM } // if - memset(dfa, 0, len); + memset(dfa, 0, bytes); fprintf(stderr, "DFA: %zu x %zu\n", end_dfa - start_dfa + 1, width); gva_uint* restrict queue = allocator.allocate(allocator.context, NULL, 0, sizeof(*queue) * array_length(graph.nodes)); if (queue == NULL) { - dfa = allocator.allocate(allocator.context, dfa, len, 0); + dfa = allocator.allocate(allocator.context, dfa, bytes, 0); return NULL; // OOM } // if @@ -328,39 +329,40 @@ dfa_from_lcs_graph(GVA_Allocator const allocator, uint8_t* dfas_from_lcs_graph(GVA_Allocator const allocator, GVA_LCS_Graph const graph) { - uint8_t* restrict dfas = NULL; + size_t bytes = 0; + for (size_t i = 0; i < array_length(graph.dom_nodes) - 1; ++i) + { + GVA_Variant const local = gva_lcs_graph_local_supremal(graph, i, i + 1); + bytes += ((local.end - local.start + 1) * (local.sequence.len + 1) + 3) / 4; + } // for + + uint8_t* const restrict dfas = allocator.allocate(allocator.context, NULL, 0, bytes); + if (dfas == NULL) + { + return NULL; // OOM + } // if gva_uint* restrict next = allocator.allocate(allocator.context, NULL, 0, sizeof(*next) * array_length(graph.nodes)); if (next == NULL) { - return NULL; // OOM + return allocator.allocate(allocator.context, dfas, bytes, 0); // OOM } // if + memset(dfas, 0, bytes); for (size_t i = 0; i < array_length(graph.nodes); ++i) { next[i] = GVA_NULL; } // for + fprintf(stderr, "%zu bytes\n", bytes); + + size_t start = 0; for (size_t i = 0; i < array_length(graph.dom_nodes) - 1; ++i) { - GVA_Variant const supremal = gva_lcs_graph_local_supremal(graph, i, i + 1); - - size_t const width = supremal.sequence.len + 1; - size_t const size = (supremal.end - supremal.start + 1) * width; - size_t const len = (size + 3) / 4; - - dfas = array_ensure(allocator, dfas, 1, len); - if (dfas == NULL) - { - next = allocator.allocate(allocator.context, next, sizeof(*next) * array_length(graph.nodes), 0); - return NULL; // OOM - } // if - - fprintf(stderr, "DFA %u x %zu\n", supremal.end - supremal.start + 1, width); + GVA_Variant const local = gva_lcs_graph_local_supremal(graph, i, i + 1); + size_t const width = local.sequence.len + 1; - size_t const start = array_length(dfas); - memset(dfas + start, 0, len); - array_header(dfas)->length += len; + fprintf(stderr, "DFA %u x %zu @ %zu\n", local.end - local.start + 1, width, start); gva_uint head = graph.dom_nodes[i].link; gva_uint tail = head; @@ -383,8 +385,8 @@ dfas_from_lcs_graph(GVA_Allocator const allocator, GVA_LCS_Graph const graph) &variant); for (size_t k = 0; k < count; ++k) { - edge(dfas + start, width, variant.start + k - supremal.start, variant.end + k - supremal.start, - variant.sequence.len, variant.sequence.str - supremal.sequence.str + k); + edge(dfas + start, width, variant.start + k - local.start, variant.end + k - local.start, + variant.sequence.len, variant.sequence.str - local.sequence.str + k); } // for if (next[graph.edges[j].tail] == GVA_NULL) @@ -397,6 +399,7 @@ dfas_from_lcs_graph(GVA_Allocator const allocator, GVA_LCS_Graph const graph) head = next[head]; } // while + start += ((local.end - local.start + 1) * width + 3) / 4; } // for next = allocator.allocate(allocator.context, next, sizeof(*next) * array_length(graph.nodes), 0); From 35361368210917261bec58b35e3045ac2e15cb49 Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 13 May 2026 19:55:17 +0200 Subject: [PATCH 648/704] WIP: bringing DFAs to index --- src/dfa.c | 106 +++++++++------------------------------------------- src/dfa.h | 15 +++++--- src/index.c | 28 ++++++++------ src/main.c | 27 ++----------- 4 files changed, 46 insertions(+), 130 deletions(-) diff --git a/src/dfa.c b/src/dfa.c index 6d405bc..d50c079 100644 --- a/src/dfa.c +++ b/src/dfa.c @@ -10,7 +10,7 @@ #include "align.h" // LCS_Alignment, lcs_align #include "array.h" // ARRAY_*, array_* #include "common.h" // MAX, MIN -#include "dfa.h" // dfa_* +#include "dfa.h" // DFAs, dfa_* #include "hash_table.h" // HASH_TABLE_*, hash_table_* @@ -247,86 +247,7 @@ dfa_from_alignment(GVA_Allocator const allocator, uint8_t* restrict dfas, } // dfa_from_alignment -uint8_t* -dfa_from_lcs_graph(GVA_Allocator const allocator, - GVA_LCS_Graph const graph, size_t const start, size_t const end) -{ - size_t const start_dfa = graph.dom_nodes[start].match.row + graph.dom_nodes[start].match.length; - size_t const end_dfa = graph.dom_nodes[end].match.row; - size_t const width = graph.dom_nodes[end].match.col - (graph.dom_nodes[start].match.col + graph.dom_nodes[start].match.length) + 1; - size_t const size = (end_dfa - start_dfa + 1) * width; - size_t const bytes = (size + 3) / 4; - - uint8_t* restrict dfa = allocator.allocate(allocator.context, NULL, 0, bytes); - if (dfa == NULL) - { - return NULL; // OOM - } // if - - memset(dfa, 0, bytes); - - fprintf(stderr, "DFA: %zu x %zu\n", end_dfa - start_dfa + 1, width); - - gva_uint* restrict queue = allocator.allocate(allocator.context, NULL, 0, sizeof(*queue) * array_length(graph.nodes)); - if (queue == NULL) - { - dfa = allocator.allocate(allocator.context, dfa, bytes, 0); - return NULL; // OOM - } // if - - for (size_t i = 0; i < array_length(graph.nodes); ++i) - { - queue[i] = GVA_NULL; - } // for - - GVA_Variant const supremal = gva_lcs_graph_supremal(graph); - - gva_uint head = graph.dom_nodes[start].link; - gva_uint tail = head; - while (head != GVA_NULL) - { - fprintf(stderr, "POP %u\n", head); - - if (head == graph.dom_nodes[end].link) - { - head = queue[head]; - continue; - } // if - - for (gva_uint i = graph.nodes[head].edges; i != GVA_NULL; i = graph.edges[i].next) - { - GVA_Variant variant = {0}; - size_t const count = gva_edges(graph.observed.str, - graph.nodes[head].match, graph.nodes[graph.edges[i].tail].match, - head == graph.source, graph.nodes[graph.edges[i].tail].edges == GVA_NULL, - &variant); - - fprintf(stderr, " " GVA_VARIANT_FMT " x %zu\n", GVA_VARIANT_PRINT(variant), count); - - for (size_t j = 0; j < count; ++j) - { - edge(dfa, width, variant.start + j - start_dfa, variant.end + j - start_dfa, - variant.sequence.len, variant.sequence.str - supremal.sequence.str + j); - } // for - - if (queue[graph.edges[i].tail] == GVA_NULL) - { - fprintf(stderr, " PUSH %u\n", graph.edges[i].tail); - queue[tail] = graph.edges[i].tail; - tail = graph.edges[i].tail; - } // if - } // for - - head = queue[head]; - } // while - - queue = allocator.allocate(allocator.context, queue, sizeof(*queue) * array_length(graph.nodes), 0); - - return dfa; -} // dfa_from_lcs_graph - - -uint8_t* +DFAs dfas_from_lcs_graph(GVA_Allocator const allocator, GVA_LCS_Graph const graph) { size_t bytes = 0; @@ -336,19 +257,24 @@ dfas_from_lcs_graph(GVA_Allocator const allocator, GVA_LCS_Graph const graph) bytes += ((local.end - local.start + 1) * (local.sequence.len + 1) + 3) / 4; } // for - uint8_t* const restrict dfas = allocator.allocate(allocator.context, NULL, 0, bytes); - if (dfas == NULL) + DFAs dfas = { - return NULL; // OOM - } // if + .len = array_length(graph.dom_nodes), + .starts = allocator.allocate(allocator.context, NULL, 0, sizeof(*dfas.starts) * array_length(graph.dom_nodes)), + .data = allocator.allocate(allocator.context, NULL, 0, bytes), + }; gva_uint* restrict next = allocator.allocate(allocator.context, NULL, 0, sizeof(*next) * array_length(graph.nodes)); - if (next == NULL) + + if (dfas.starts == NULL || dfas.data == NULL || next == NULL) { - return allocator.allocate(allocator.context, dfas, bytes, 0); // OOM + next = allocator.allocate(allocator.context, next, sizeof(*next) * array_length(graph.nodes), 0); + dfas.data = allocator.allocate(allocator.context, dfas.data, bytes, 0); + dfas.starts = allocator.allocate(allocator.context, dfas.starts, sizeof(*dfas.starts) * array_length(graph.dom_nodes), 0); + return (DFAs) {0}; // OOM } // if - memset(dfas, 0, bytes); + memset(dfas.data, 0, bytes); for (size_t i = 0; i < array_length(graph.nodes); ++i) { next[i] = GVA_NULL; @@ -385,7 +311,7 @@ dfas_from_lcs_graph(GVA_Allocator const allocator, GVA_LCS_Graph const graph) &variant); for (size_t k = 0; k < count; ++k) { - edge(dfas + start, width, variant.start + k - local.start, variant.end + k - local.start, + edge(dfas.data + start, width, variant.start + k - local.start, variant.end + k - local.start, variant.sequence.len, variant.sequence.str - local.sequence.str + k); } // for @@ -399,8 +325,10 @@ dfas_from_lcs_graph(GVA_Allocator const allocator, GVA_LCS_Graph const graph) head = next[head]; } // while + dfas.starts[i] = start; start += ((local.end - local.start + 1) * width + 3) / 4; } // for + dfas.starts[array_length(graph.dom_nodes) - 1] = bytes; next = allocator.allocate(allocator.context, next, sizeof(*next) * array_length(graph.nodes), 0); diff --git a/src/dfa.h b/src/dfa.h index df0dfd4..fbffc49 100644 --- a/src/dfa.h +++ b/src/dfa.h @@ -14,6 +14,14 @@ #include // FIXME: DEBUG +typedef struct +{ + size_t len; + gva_uint* restrict starts; + uint8_t* restrict data; +} DFAs; + + uint8_t* dfa_concat(GVA_Allocator const allocator, size_t const n, GVA_Variant const variants[static restrict n], @@ -26,12 +34,7 @@ dfa_from_alignment(GVA_Allocator const allocator, uint8_t* restrict dfas, size_t const len_obs, char const observed[static restrict len_obs]); -uint8_t* -dfa_from_lcs_graph(GVA_Allocator const allocator, - GVA_LCS_Graph const graph, size_t const start, size_t const end); - - -uint8_t* +DFAs dfas_from_lcs_graph(GVA_Allocator const allocator, GVA_LCS_Graph const graph); diff --git a/src/index.c b/src/index.c index e00de44..d68017d 100644 --- a/src/index.c +++ b/src/index.c @@ -102,9 +102,12 @@ variants_distance(GVA_Allocator const allocator, return len_lhs; } // if - GVA_String observed_lhs = gva_patch(allocator, end - start, reference + start, 1, &(GVA_Variant const) {lhs.start - start, lhs.end - start, lhs.sequence}); - GVA_String observed_rhs = gva_patch(allocator, end - start, reference + start, 1, &(GVA_Variant const) {rhs.start - start, rhs.end - start, rhs.sequence}); - size_t const distance = gva_edit_distance(allocator, observed_lhs.len, observed_lhs.str, observed_rhs.len, observed_rhs.str); + GVA_String observed_lhs = gva_patch(allocator, end - start, reference + start, + 1, &(GVA_Variant const) {lhs.start - start, lhs.end - start, lhs.sequence}); + GVA_String observed_rhs = gva_patch(allocator, end - start, reference + start, + 1, &(GVA_Variant const) {rhs.start - start, rhs.end - start, rhs.sequence}); + size_t const distance = gva_edit_distance(allocator, + observed_lhs.len, observed_lhs.str, observed_rhs.len, observed_rhs.str); gva_string_destroy(allocator, observed_rhs); gva_string_destroy(allocator, observed_lhs); @@ -121,9 +124,10 @@ variants_included(GVA_Allocator const allocator, size_t const start = MIN(lhs.start, rhs.start); size_t const end = MAX(lhs.end, rhs.end); - - GVA_String observed_lhs = gva_patch(allocator, end - start, reference + start, 1, &(GVA_Variant const) {lhs.start - start, lhs.end - start, lhs.sequence}); - GVA_String observed_rhs = gva_patch(allocator, end - start, reference + start, 1, &(GVA_Variant const) {rhs.start - start, rhs.end - start, rhs.sequence}); + GVA_String observed_lhs = gva_patch(allocator, end - start, reference + start, + 1, &(GVA_Variant const) {lhs.start - start, lhs.end - start, lhs.sequence}); + GVA_String observed_rhs = gva_patch(allocator, end - start, reference + start, + 1, &(GVA_Variant const) {rhs.start - start, rhs.end - start, rhs.sequence}); GVA_LCS_Graph lhs_graph = gva_lcs_graph_init(allocator, end - start, reference + start, observed_lhs.len, observed_lhs.str, start); GVA_LCS_Graph rhs_graph = gva_lcs_graph_init(allocator, end - start, reference + start, observed_rhs.len, observed_rhs.str, start); @@ -294,18 +298,18 @@ gva_index_insert(GVA_Index* restrict const self, .distance = distance, })); gva_uint const node_idx = interval_tree_insert(&self->intervals, tmp_idx); - // undo append: interval already in the tree - if (node_idx != tmp_idx) - { - array_header(self->intervals.nodes)->length -= 1; - } // if - else + if (node_idx == tmp_idx) { uint8_t* dfa = dfa_from_alignment(self->allocator, NULL, variant.end - variant.start, self->reference.str + variant.start, variant.sequence.len, variant.sequence.str); self->intervals.nodes[node_idx].dfa = trie_insert(&self->dfas, array_length(dfa), (char*) dfa); dfa = ARRAY_DESTROY(self->allocator, dfa); + } // if + else + { + // undo append: interval already in the tree + array_header(self->intervals.nodes)->length -= 1; } // else self->intervals.nodes[node_idx].alleles = ARRAY_APPEND(self->allocator, self->join, ((Join) diff --git a/src/main.c b/src/main.c index 84e3275..77f0406 100644 --- a/src/main.c +++ b/src/main.c @@ -544,35 +544,16 @@ overlap_main(int argc, char* argv[static argc]) continue; } // if - GVA_Variant variants[2]; - uint8_t* dfas[2] = {NULL}; - GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &rhs_variant); - dfas_from_lcs_graph(gva_std_allocator, graph); - - for (size_t i = 0; i < array_length(graph.dom_nodes) - 1; ++i) - { - variants[i] = gva_lcs_graph_local_supremal(graph, i, i + 1); - fprintf(stdout, GVA_VARIANT_FMT_SPDI " %u\n", - GVA_VARIANT_PRINT_SPDI(REFERENCE_ID, variants[i]), - graph.dom_nodes[i + 1].distance - graph.dom_nodes[i].distance); - //dfas[i] = dfa_from_alignment(gva_std_allocator, NULL, variants[i].end - variants[i].start, reference.str + variants[i].start, variants[i].sequence.len, variants[i].sequence.str); - } // for - - for (size_t i = 0; i < array_length(graph.dom_nodes) - 1; ++i) - { - //dfas[i] = ARRAY_DESTROY(gva_std_allocator, dfas[i]); - } // for - - uint8_t* gdfa = dfa_from_lcs_graph(gva_std_allocator, graph, 0, 2); + DFAs dfas = dfas_from_lcs_graph(gva_std_allocator, graph); - dfa_dot(stdout, reference.len, reference.str, rhs_variant, gdfa); - - gdfa = gva_std_allocator.allocate(gva_std_allocator.context, gdfa, 0, 0); + dfas.data = gva_std_allocator.allocate(gva_std_allocator.context, dfas.data, dfas.starts[dfas.len - 1], 0); + dfas.starts = gva_std_allocator.allocate(gva_std_allocator.context, dfas.starts, sizeof(*dfas.starts) * dfas.len, 0); gva_lcs_graph_destroy(gva_std_allocator, graph, true); + //uint8_t* dfa = dfa_concat(gva_std_allocator, 2, variants, dfas); //dfa_dot(stdout, reference.len, reference.str, rhs_variant, dfa); //dfa = gva_std_allocator.allocate(gva_std_allocator.context, dfa, 0, 0); From 64f4c77daa66b48a94a501e8fa5c6e9ef5cd96da Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Wed, 13 May 2026 22:11:48 +0200 Subject: [PATCH 649/704] Whitespace. --- src/index.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/index.c b/src/index.c index e00de44..238c2f7 100644 --- a/src/index.c +++ b/src/index.c @@ -121,7 +121,6 @@ variants_included(GVA_Allocator const allocator, size_t const start = MIN(lhs.start, rhs.start); size_t const end = MAX(lhs.end, rhs.end); - GVA_String observed_lhs = gva_patch(allocator, end - start, reference + start, 1, &(GVA_Variant const) {lhs.start - start, lhs.end - start, lhs.sequence}); GVA_String observed_rhs = gva_patch(allocator, end - start, reference + start, 1, &(GVA_Variant const) {rhs.start - start, rhs.end - start, rhs.sequence}); GVA_LCS_Graph lhs_graph = gva_lcs_graph_init(allocator, end - start, reference + start, observed_lhs.len, observed_lhs.str, start); From 2f33f4ff43b96610e54bd89f1e0465463a5a27f2 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 14 May 2026 10:37:18 +0200 Subject: [PATCH 650/704] WIP: separate compare module --- include/compare.h | 29 ++++++-- src/compare.c | 174 +++++++++++++++++++++------------------------- src/dfa.c | 19 ++--- src/dfa.h | 5 +- src/main.c | 47 ++++--------- 5 files changed, 123 insertions(+), 151 deletions(-) diff --git a/include/compare.h b/include/compare.h index 2dfc184..5a7f5fe 100644 --- a/include/compare.h +++ b/include/compare.h @@ -3,16 +3,37 @@ #include // size_t +#include // uint8_t #include "allocator.h" // GVA_Allocator -#include "lcs_graph.h" // GVA_LCS_Graph #include "relations.h" // GVA_Relation +#include "variant.h" // GVA_Variant + + +size_t +gva_compare_distance(GVA_Allocator const allocator, + size_t const len, char const reference[static len], + GVA_Variant const lhs, GVA_Variant const rhs); + + +size_t +gva_compare_included(GVA_Allocator const allocator, + size_t const len, char const reference[static restrict len], + GVA_Variant const lhs, size_t const lhs_distance, uint8_t lhs_dfa[static restrict 1], + GVA_Variant const rhs, size_t const rhs_distance, uint8_t rhs_dfa[static restrict 1]); + + +GVA_Relation +gva_compare_relation_from_included(size_t const included, + size_t const lhs_distance, size_t const rhs_distance, + size_t excluded[static 1]); GVA_Relation -gva_compare_graphs(GVA_Allocator const allocator, - size_t const len_ref, char const reference[static len_ref], - GVA_LCS_Graph const lhs, GVA_LCS_Graph const rhs); +gva_compare(GVA_Allocator const allocator, + size_t const len, char const reference[static restrict len], + GVA_Variant const lhs, size_t const lhs_distance, uint8_t lhs_dfa[static restrict 1], + GVA_Variant const rhs, size_t const rhs_distance, uint8_t rhs_dfa[static restrict 1]); #endif // GVA_COMPARE_H diff --git a/src/compare.c b/src/compare.c index 4da95e6..2e28077 100644 --- a/src/compare.c +++ b/src/compare.c @@ -1,126 +1,110 @@ -#include // bool #include // NULL, size_t -#include // memcpy +#include // uint8_t #include "../include/allocator.h" // GVA_Allocator -#include "../include/compare.h" // gva_compare_graphs +#include "../include/compare.h" // gva_compare* #include "../include/edit.h" // gva_edit_distance -#include "../include/lcs_graph.h" // GVA_LCS_Graph, gva_lcs_graph_* #include "../include/relations.h" // GVA_Relation, GVA_CONTAINS, GVA_DISJOINT, // GVA_EQUIVALENT GVA_IS_CONTAINED, GVA_OVERLAP -#include "../include/variant.h" // GVA_Variant, gva_variant_eq +#include "../include/variant.h" // GVA_Variant, gva_patch, gva_variant_eq #include "common.h" // MAX, MIN -#include "bitset.h" // bitset_* +#include "dfa.h" // dfa_overlap -GVA_Relation -gva_compare_graphs(GVA_Allocator const allocator, - size_t const len_ref, char const reference[static len_ref], - GVA_LCS_Graph const lhs, GVA_LCS_Graph const rhs) +size_t +gva_compare_distance(GVA_Allocator const allocator, + size_t const len, char const reference[static len], + GVA_Variant const lhs, GVA_Variant const rhs) { - GVA_Variant const supremal_lhs = gva_lcs_graph_supremal(lhs); - GVA_Variant const supremal_rhs = gva_lcs_graph_supremal(rhs); + size_t const start = MIN(lhs.start, rhs.start); + size_t const end = MAX(lhs.end, rhs.end); - if (gva_variant_eq(supremal_lhs, supremal_rhs)) + size_t const len_lhs = (lhs.start - start) + lhs.sequence.len + (end - lhs.end); + size_t const len_rhs = (rhs.start - start) + rhs.sequence.len + (end - rhs.end); + + if (len_lhs == 0) { - return GVA_EQUIVALENT; + return len_rhs; } // if - - if (supremal_lhs.start > supremal_rhs.end || supremal_rhs.start > supremal_lhs.end) + if (len_rhs == 0) { - return GVA_DISJOINT; + return len_lhs; } // if - size_t const start = MIN(supremal_lhs.start, supremal_rhs.start); - size_t const end = MAX(supremal_lhs.end, supremal_rhs.end); + GVA_String observed_lhs = gva_patch(allocator, end - start, reference + start, + 1, &(GVA_Variant const) {lhs.start - start, lhs.end - start, lhs.sequence}); + GVA_String observed_rhs = gva_patch(allocator, end - start, reference + start, + 1, &(GVA_Variant const) {rhs.start - start, rhs.end - start, rhs.sequence}); - size_t const len_lhs = (supremal_lhs.start - start) + supremal_lhs.sequence.len + (end - supremal_lhs.end); - size_t const len_rhs = (supremal_rhs.start - start) + supremal_rhs.sequence.len + (end - supremal_rhs.end); + size_t const distance = gva_edit_distance(allocator, + observed_lhs.len, observed_lhs.str, observed_rhs.len, observed_rhs.str); - size_t distance = 0; - if (len_lhs == 0) + gva_string_destroy(allocator, observed_rhs); + gva_string_destroy(allocator, observed_lhs); + + return distance; +} // gva_compare_distance + + +size_t +gva_compare_included(GVA_Allocator const allocator, + size_t const len, char const reference[static restrict len], + GVA_Variant const lhs, size_t const lhs_distance, uint8_t lhs_dfa[static restrict 1], + GVA_Variant const rhs, size_t const rhs_distance, uint8_t rhs_dfa[static restrict 1]) +{ + size_t const distance = gva_compare_distance(allocator, len, reference, lhs, rhs); + + if (distance == 0 || rhs_distance - lhs_distance == distance) { - distance = len_rhs; + return lhs_distance; } // if - else if (len_rhs == 0) + if (lhs_distance - rhs_distance == distance) { - distance = len_lhs; + return rhs_distance; } // if - else + + return dfa_overlap(allocator, len, reference, lhs, lhs_dfa, rhs, rhs_dfa); +} // gva_compare_included + + +inline GVA_Relation +gva_compare_relation_from_included(size_t const included, + size_t const lhs_distance, size_t const rhs_distance, + size_t excluded[static 1]) +{ + *excluded = lhs_distance + rhs_distance - 2 * included; + if (*excluded == 0) { - GVA_String observed_lhs = gva_string_init(allocator, len_lhs); - GVA_String observed_rhs = gva_string_init(allocator, len_rhs); - if (observed_lhs.str == NULL || observed_rhs.str == NULL) - { - gva_string_destroy(allocator, observed_rhs); - gva_string_destroy(allocator, observed_lhs); - return GVA_DISJOINT; // FIXME: OOM - } // if - - memcpy((char*) observed_lhs.str, reference + start, supremal_lhs.start - start); - memcpy((char*) observed_lhs.str + supremal_lhs.start - start, supremal_lhs.sequence.str, supremal_lhs.sequence.len); - memcpy((char*) observed_lhs.str + supremal_lhs.start - start + supremal_lhs.sequence.len, reference + supremal_lhs.end, end - supremal_lhs.end); - - memcpy((char*) observed_rhs.str, reference + start, supremal_rhs.start - start); - memcpy((char*) observed_rhs.str + supremal_rhs.start - start, supremal_rhs.sequence.str, supremal_rhs.sequence.len); - memcpy((char*) observed_rhs.str + supremal_rhs.start - start + supremal_rhs.sequence.len, reference + supremal_rhs.end, end - supremal_rhs.end); - - distance = gva_edit_distance(allocator, observed_lhs.len, observed_lhs.str, observed_rhs.len, observed_rhs.str); - gva_string_destroy(allocator, observed_rhs); - gva_string_destroy(allocator, observed_lhs); - } // else - - if (gva_lcs_graph_distance(lhs) + gva_lcs_graph_distance(rhs) == distance) + return GVA_EQUIVALENT; + } // if + if (included == 0) { return GVA_DISJOINT; } // if - - if (gva_lcs_graph_distance(lhs) - gva_lcs_graph_distance(rhs) == distance) + if (lhs_distance == included) { - return GVA_CONTAINS; + return GVA_IS_CONTAINED; } // if - - if (gva_lcs_graph_distance(rhs) - gva_lcs_graph_distance(lhs) == distance) + if (rhs_distance == included) { - return GVA_IS_CONTAINED; + return GVA_CONTAINS; } // if + return GVA_OVERLAP; +} // gva_compare_relation_from_included + - size_t const len = end - start + 1; - size_t* lhs_dels = bitset_init(allocator, len); - size_t* lhs_as = bitset_init(allocator, len); - size_t* lhs_cs = bitset_init(allocator, len); - size_t* lhs_gs = bitset_init(allocator, len); - size_t* lhs_ts = bitset_init(allocator, len); - - size_t* rhs_dels = bitset_init(allocator, len); - size_t* rhs_as = bitset_init(allocator, len); - size_t* rhs_cs = bitset_init(allocator, len); - size_t* rhs_gs = bitset_init(allocator, len); - size_t* rhs_ts = bitset_init(allocator, len); - - size_t const start_intersection = MAX(supremal_lhs.start, supremal_rhs.start); - size_t const end_intersection = MIN(supremal_lhs.end, supremal_rhs.end); - - gva_lcs_graph_uniq_atomics(lhs, start, start_intersection, end_intersection, lhs_dels, lhs_as, lhs_cs, lhs_gs, lhs_ts); - gva_lcs_graph_uniq_atomics(rhs, start, start_intersection, end_intersection, rhs_dels, rhs_as, rhs_cs, rhs_gs, rhs_ts); - - bool const overlap = bitset_intersection_cnt(lhs_dels, rhs_dels) > 0 || - bitset_intersection_cnt(lhs_as, rhs_as) > 0 || - bitset_intersection_cnt(lhs_cs, rhs_cs) > 0 || - bitset_intersection_cnt(lhs_gs, rhs_gs) > 0 || - bitset_intersection_cnt(lhs_ts, rhs_ts) > 0; - - rhs_ts = bitset_destroy(allocator, rhs_ts); - rhs_gs = bitset_destroy(allocator, rhs_gs); - rhs_cs = bitset_destroy(allocator, rhs_cs); - rhs_as = bitset_destroy(allocator, rhs_as); - rhs_dels = bitset_destroy(allocator, rhs_dels); - - lhs_ts = bitset_destroy(allocator, lhs_ts); - lhs_gs = bitset_destroy(allocator, lhs_gs); - lhs_cs = bitset_destroy(allocator, lhs_cs); - lhs_as = bitset_destroy(allocator, lhs_as); - lhs_dels = bitset_destroy(allocator, lhs_dels); - - return overlap ? GVA_OVERLAP : GVA_DISJOINT; -} // gva_compare_graphs +inline GVA_Relation +gva_compare(GVA_Allocator const allocator, + size_t const len, char const reference[static restrict len], + GVA_Variant const lhs, size_t const lhs_distance, uint8_t lhs_dfa[static restrict 1], + GVA_Variant const rhs, size_t const rhs_distance, uint8_t rhs_dfa[static restrict 1]) +{ + if (gva_variant_eq(lhs, rhs)) + { + return GVA_EQUIVALENT; + } // if + size_t const included = gva_compare_included(allocator, len, reference, + lhs, lhs_distance, lhs_dfa, + rhs, rhs_distance, rhs_dfa); + return gva_compare_relation_from_included(included, lhs_distance, rhs_distance, &(size_t) {0}); +} // gva_compare diff --git a/src/dfa.c b/src/dfa.c index d50c079..c9c2f27 100644 --- a/src/dfa.c +++ b/src/dfa.c @@ -257,7 +257,7 @@ dfas_from_lcs_graph(GVA_Allocator const allocator, GVA_LCS_Graph const graph) bytes += ((local.end - local.start + 1) * (local.sequence.len + 1) + 3) / 4; } // for - DFAs dfas = + DFAs dfas = { .len = array_length(graph.dom_nodes), .starts = allocator.allocate(allocator.context, NULL, 0, sizeof(*dfas.starts) * array_length(graph.dom_nodes)), @@ -451,11 +451,10 @@ queue_push_front(Queue self[static 1], size_t const idx, size_t const included) size_t -dfa_max_overlap(GVA_Allocator const allocator, +dfa_overlap(GVA_Allocator const allocator, size_t const len, char const reference[static restrict len], GVA_Variant const lhs_variant, uint8_t const lhs_dfa[static restrict 1], - GVA_Variant const rhs_variant, uint8_t const rhs_dfa[static restrict 1], - size_t const limit) + GVA_Variant const rhs_variant, uint8_t const rhs_dfa[static restrict 1]) { static size_t const INITIAL_SIZE = 4096; @@ -577,10 +576,6 @@ dfa_max_overlap(GVA_Allocator const allocator, { // DD // fprintf(stderr, " push (%zu DELTA) {%zu, %zu} +1 +0 (%zu)\n", lhs_ref, lhs_idx + lhs_width, rhs_idx + rhs_width, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width); - if (limit > 0 && included + 1 >= limit) - { - break; - } // if queue_push_front(&queue, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width, included + 1); } // if @@ -588,10 +583,6 @@ dfa_max_overlap(GVA_Allocator const allocator, { // II // fprintf(stderr, " push (%zu %c) {%zu, %zu} +1 +0 (%zu)\n", lhs_ref, lhs_variant.sequence.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx + 1, (lhs_idx + 1) * rhs_size + rhs_idx + 1); - if (limit > 0 && included + 1 >= limit) - { - break; - } // if queue_push_front(&queue, (lhs_idx + 1) * rhs_size + rhs_idx + 1, included + 1); } // if @@ -627,7 +618,7 @@ dfa_max_overlap(GVA_Allocator const allocator, //fprintf(stderr, "count: %zu\n", count); - size_t included = limit; + size_t included = 0; size_t const idx = HASH_TABLE_INDEX(queue.entries, lhs_size * rhs_size - 1); if (queue.entries[idx].gva_key == lhs_size * rhs_size - 1) { @@ -637,7 +628,7 @@ dfa_max_overlap(GVA_Allocator const allocator, queue_destroy(&queue); return included; -} // dfa_max_overlap +} // dfa_overlap bool diff --git a/src/dfa.h b/src/dfa.h index fbffc49..ec84c35 100644 --- a/src/dfa.h +++ b/src/dfa.h @@ -39,11 +39,10 @@ dfas_from_lcs_graph(GVA_Allocator const allocator, GVA_LCS_Graph const graph); size_t -dfa_max_overlap(GVA_Allocator const allocator, +dfa_overlap(GVA_Allocator const allocator, size_t const len, char const reference[static restrict len], GVA_Variant const lhs_variant, uint8_t const lhs_dfa[static restrict 1], - GVA_Variant const rhs_variant, uint8_t const rhs_dfa[static restrict 1], - size_t const limit); + GVA_Variant const rhs_variant, uint8_t const rhs_dfa[static restrict 1]); bool diff --git a/src/main.c b/src/main.c index 77f0406..eec9652 100644 --- a/src/main.c +++ b/src/main.c @@ -6,23 +6,21 @@ #include // EXIT_*, atoll, qsort #include // strerror, strlen -#include "../include/compare.h" // gva_compare_graphs -#include "../include/edit.h" // gva_edit_distance +#include "../include/compare.h" // gva_compare_distance #include "../include/index.h" // GVA_Index, gva_index_*, GVA_Query_Result #include "../include/lcs_graph.h" // GVA_LCS_Graph, gva_lcs_graph_* #include "../include/relations.h" // GVA_RELATION_LABELS #include "../include/std_alloc.h" // gva_std_allocator #include "../include/string.h" // GVA_String, gva_string_destroy -#include "../include/utils.h" // gva_fasta_sequence*, gva_lcs_graph_dot +#include "../include/utils.h" // gva_fasta_sequence* #include "../include/variant.h" // GVA_VARIANT_*, GVA_Variant, gva_parse_spdi, gva_patch, gva_variant_* -#include "align.h" // LCS_Matches, lcs_align_one #include "array.h" // ARRAY_*, array_length #include "common.h" // MAX, MIN #include "dfa.h" // dfa_* #include "trie.h" // Trie, trie_* -#include +#include // DEBUG #define LINE_SIZE 4096 @@ -743,29 +741,7 @@ all_main(int argc, char* argv[static argc]) GVA_Variant const rhs = { entries[j].start, entries[j].end, trie_string(sequences, entries[j].inserted) }; - size_t const start = MIN(lhs.start, rhs.start); - size_t const end = MAX(lhs.end, rhs.end); - - size_t const len_lhs = (lhs.start - start) + lhs.sequence.len + (end - lhs.end); - size_t const len_rhs = (rhs.start - start) + rhs.sequence.len + (end - rhs.end); - - size_t distance = 0; - if (len_lhs == 0) - { - distance = len_rhs; - } // if - else if (len_rhs == 0) - { - distance = len_lhs; - } // if - else - { - GVA_String observed_lhs = gva_patch(gva_std_allocator, end - start, reference.str + start, 1, &(GVA_Variant const) {lhs.start - start, lhs.end - start, lhs.sequence}); - GVA_String observed_rhs = gva_patch(gva_std_allocator, end - start, reference.str + start, 1, &(GVA_Variant const) {rhs.start - start, rhs.end - start, rhs.sequence}); - distance = gva_edit_distance(gva_std_allocator, observed_lhs.len, observed_lhs.str, observed_rhs.len, observed_rhs.str); - gva_string_destroy(gva_std_allocator, observed_rhs); - gva_string_destroy(gva_std_allocator, observed_lhs); - } // else + size_t const distance = gva_compare_distance(gva_std_allocator, reference.len, reference.str, lhs, rhs); if (entries[i].distance + entries[j].distance == distance) { @@ -791,10 +767,11 @@ all_main(int argc, char* argv[static argc]) GVA_String lhs_dfa = trie_string(dfas, entries[i].dfa); GVA_String rhs_dfa = trie_string(dfas, entries[j].dfa); - size_t const overlap = dfa_max_overlap(gva_std_allocator, reference.len, reference.str, lhs, (uint8_t*) lhs_dfa.str, rhs, (uint8_t*) rhs_dfa.str, 0); - //bool const disjoint = dfa_disjoint(lhs, (uint8_t*) lhs_dfa.str, rhs, (uint8_t*) rhs_dfa.str); + //size_t const overlap = dfa_max_overlap(gva_std_allocator, reference.len, reference.str, lhs, (uint8_t*) lhs_dfa.str, rhs, (uint8_t*) rhs_dfa.str, 0); + bool const disjoint = dfa_disjoint(lhs, (uint8_t*) lhs_dfa.str, rhs, (uint8_t*) rhs_dfa.str); - if (overlap == 0) + if (disjoint) + // if (overlap == 0) { fprintf(stdout, GVA_STRING_FMT " disjoint " GVA_STRING_FMT "\n", GVA_STRING_PRINT(trie_string(labels, entries[i].label)), @@ -802,10 +779,10 @@ all_main(int argc, char* argv[static argc]) } // if else { - fprintf(stdout, GVA_STRING_FMT " overlap " GVA_STRING_FMT " %zu\n", + fprintf(stdout, GVA_STRING_FMT " overlap " GVA_STRING_FMT " %d\n", GVA_STRING_PRINT(trie_string(labels, entries[i].label)), GVA_STRING_PRINT(trie_string(labels, entries[j].label)), - (entries[i].distance + entries[j].distance - distance) / 2); + 1); } // else } // for } // for @@ -830,6 +807,6 @@ main(int argc, char* argv[static argc]) // return allele_main(argc, argv); // return index_main(argc, argv); // return supremal_main(argc, argv); - return overlap_main(argc, argv); - // return all_main(argc, argv); + // return overlap_main(argc, argv); + return all_main(argc, argv); } // main From 9820e1df628d0a9392181c6fe628b0cb12f64270 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 14 May 2026 10:57:23 +0200 Subject: [PATCH 651/704] WIP: move to compare module --- src/index.c | 82 ++++++++++------------------------------------------- 1 file changed, 15 insertions(+), 67 deletions(-) diff --git a/src/index.c b/src/index.c index d68017d..65f847b 100644 --- a/src/index.c +++ b/src/index.c @@ -2,6 +2,7 @@ #include // intmax_t, uint8_t #include "../include/allocator.h" // GVA_Allocator +#include "../include/compare.h" // gva_compare_* #include "../include/edit.h" // gva_edit_distance #include "../include/index.h" // GVA_Index, GVA_Query_Result, gva_index_* #include "../include/lcs_graph.h" // GVA_LCS_Graph, gva_lcs_graph_* @@ -48,28 +49,6 @@ struct GVA_Index }; -static inline GVA_Relation -relation_from_included(size_t const included, - size_t const lhs_distance, size_t const rhs_distance, - size_t excluded[static 1]) -{ - *excluded = lhs_distance + rhs_distance - 2 * included; - if (*excluded == 0) - { - return GVA_EQUIVALENT; - } // if - if (lhs_distance == included) - { - return GVA_IS_CONTAINED; - } // if - if (rhs_distance == included) - { - return GVA_CONTAINS; - } // if - return GVA_OVERLAP; -} // relation_from_included - - static inline GVA_Variant variant_from_index(GVA_Index const self[static 1], size_t const idx) { @@ -82,39 +61,7 @@ variant_from_index(GVA_Index const self[static 1], size_t const idx) } // variant_from_index -static inline size_t -variants_distance(GVA_Allocator const allocator, - size_t const len_ref, char const reference[static len_ref], - GVA_Variant const lhs, GVA_Variant const rhs) -{ - size_t const start = MIN(lhs.start, rhs.start); - size_t const end = MAX(lhs.end, rhs.end); - - size_t const len_lhs = (lhs.start - start) + lhs.sequence.len + (end - lhs.end); - size_t const len_rhs = (rhs.start - start) + rhs.sequence.len + (end - rhs.end); - - if (len_lhs == 0) - { - return len_rhs; - } // if - if (len_rhs == 0) - { - return len_lhs; - } // if - - GVA_String observed_lhs = gva_patch(allocator, end - start, reference + start, - 1, &(GVA_Variant const) {lhs.start - start, lhs.end - start, lhs.sequence}); - GVA_String observed_rhs = gva_patch(allocator, end - start, reference + start, - 1, &(GVA_Variant const) {rhs.start - start, rhs.end - start, rhs.sequence}); - size_t const distance = gva_edit_distance(allocator, - observed_lhs.len, observed_lhs.str, observed_rhs.len, observed_rhs.str); - gva_string_destroy(allocator, observed_rhs); - gva_string_destroy(allocator, observed_lhs); - - return distance; -} // variants_distance - - +// FIXME: gva_compare_included static size_t variants_included(GVA_Allocator const allocator, size_t const len_ref, char const reference[static len_ref], @@ -191,13 +138,14 @@ variants_included(GVA_Allocator const allocator, } // variants_included +// FIXME: gva_compare_included static inline size_t variants_with_distance(GVA_Allocator const allocator, - size_t const len_ref, char const reference[static len_ref], + size_t const len, char const reference[static len], GVA_Variant const lhs, size_t const distance_lhs, GVA_Variant const rhs, size_t const distance_rhs) { - size_t const distance = variants_distance(allocator, len_ref, reference, lhs, rhs); + size_t const distance = gva_compare_distance(allocator, len, reference, lhs, rhs); if (distance == 0 || distance_rhs - distance_lhs == distance) { @@ -209,7 +157,7 @@ variants_with_distance(GVA_Allocator const allocator, } // if size_t excluded = 0; - size_t const included = variants_included(allocator, len_ref, reference, lhs, rhs, &excluded); + size_t const included = variants_included(allocator, len, reference, lhs, rhs, &excluded); if (included == 0) { return 0; // disjoint @@ -220,7 +168,7 @@ variants_with_distance(GVA_Allocator const allocator, inline GVA_Index* gva_index_init(GVA_Allocator const allocator, - size_t const len_ref, char const reference[static len_ref]) + size_t const len, char const reference[static len]) { GVA_Index* index = allocator.allocate(allocator.context, NULL, 0, sizeof(*index)); if (index == NULL) @@ -229,7 +177,7 @@ gva_index_init(GVA_Allocator const allocator, } // if index->allocator = allocator; - index->reference = (GVA_String) {len_ref, reference}; + index->reference = (GVA_String) {len, reference}; index->intervals = interval_tree_init(allocator); index->inserted = trie_init(allocator); @@ -265,10 +213,10 @@ gva_index_destroy(GVA_Index* const self) void gva_index_insert(GVA_Index* restrict const self, - size_t const len_id, char const id[static restrict len_id], + size_t const len, char const id[static restrict len], GVA_Variant const variant, size_t const distance) { - size_t const id_idx = trie_insert(&self->ids, len_id, id); + size_t const id_idx = trie_insert(&self->ids, len, id); size_t allele_idx = array_length(self->alleles) - 1; // new allele @@ -363,7 +311,7 @@ gva_index_query(GVA_Allocator const allocator, { gva_uint const node_idx = intervals[j]; - size_t const distance = variants_distance(allocator, self->reference.len, self->reference.str, + size_t const distance = gva_compare_distance(allocator, self->reference.len, self->reference.str, variant_from_index(self, node_idx), variant); if (self->intervals.nodes[node_idx].distance + graph.dom_nodes[i + 1].distance - graph.dom_nodes[i].distance <= distance) { @@ -473,7 +421,7 @@ gva_index_query(GVA_Allocator const allocator, gva_string_destroy(allocator, supremal.sequence); size_t excluded = 0; - GVA_Relation const relation = relation_from_included(included, self->intervals.nodes[node_idx].distance, distance, &excluded); + GVA_Relation const relation = gva_compare_relation_from_included(included, self->intervals.nodes[node_idx].distance, distance, &excluded); ARRAY_APPEND(allocator, result.hits, ((GVA_Query_Hit) { .relation = relation, @@ -515,7 +463,7 @@ gva_index_query(GVA_Allocator const allocator, gva_string_destroy(allocator, supremal.sequence); size_t excluded = 0; - GVA_Relation const relation = relation_from_included(included, distance, graph.dom_nodes[hits[i].query + 1].distance - graph.dom_nodes[hits[i].query].distance, &excluded); + GVA_Relation const relation = gva_compare_relation_from_included(included, distance, graph.dom_nodes[hits[i].query + 1].distance - graph.dom_nodes[hits[i].query].distance, &excluded); ARRAY_APPEND(allocator, result.hits, ((GVA_Query_Hit) { @@ -567,7 +515,7 @@ gva_index_query(GVA_Allocator const allocator, } // if size_t excluded = 0; - GVA_Relation const relation = relation_from_included(included, self->intervals.nodes[node_idx].distance, distance, &excluded); + GVA_Relation const relation = gva_compare_relation_from_included(included, self->intervals.nodes[node_idx].distance, distance, &excluded); ARRAY_APPEND(allocator, result.hits, ((GVA_Query_Hit) { @@ -587,7 +535,7 @@ gva_index_query(GVA_Allocator const allocator, } // if size_t excluded = 0; - GVA_Relation const relation = relation_from_included(entries[idx].included, self->alleles[entries[idx].gva_key].distance, gva_lcs_graph_distance(graph), &excluded); + GVA_Relation const relation = gva_compare_relation_from_included(entries[idx].included, self->alleles[entries[idx].gva_key].distance, gva_lcs_graph_distance(graph), &excluded); ARRAY_APPEND(allocator, result.alleles, ((GVA_Query_Allele) { From 9133d58c444062b1a8545db9ab473a28cdf5ba88 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 14 May 2026 11:07:03 +0200 Subject: [PATCH 652/704] Consistency --- src/dfa.c | 48 ++++++++++++++++++++++++------------------------ src/dfa.h | 8 ++++---- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/src/dfa.c b/src/dfa.c index c9c2f27..f95227b 100644 --- a/src/dfa.c +++ b/src/dfa.c @@ -453,15 +453,15 @@ queue_push_front(Queue self[static 1], size_t const idx, size_t const included) size_t dfa_overlap(GVA_Allocator const allocator, size_t const len, char const reference[static restrict len], - GVA_Variant const lhs_variant, uint8_t const lhs_dfa[static restrict 1], - GVA_Variant const rhs_variant, uint8_t const rhs_dfa[static restrict 1]) + GVA_Variant const lhs, uint8_t const lhs_dfa[static restrict 1], + GVA_Variant const rhs, uint8_t const rhs_dfa[static restrict 1]) { static size_t const INITIAL_SIZE = 4096; - size_t const lhs_width = lhs_variant.sequence.len + 1; - size_t const rhs_width = rhs_variant.sequence.len + 1; - size_t const lhs_size = (lhs_variant.end - lhs_variant.start + 1) * lhs_width; - size_t const rhs_size = (rhs_variant.end - rhs_variant.start + 1) * rhs_width; + size_t const lhs_width = lhs.sequence.len + 1; + size_t const rhs_width = rhs.sequence.len + 1; + size_t const lhs_size = (lhs.end - lhs.start + 1) * lhs_width; + size_t const rhs_size = (rhs.end - rhs.start + 1) * rhs_width; Queue queue = queue_init(allocator, INITIAL_SIZE); if (queue.entries == NULL) @@ -481,8 +481,8 @@ dfa_overlap(GVA_Allocator const allocator, size_t const lhs_idx = idx / rhs_size; size_t const rhs_idx = idx % rhs_size; - size_t const lhs_ref = lhs_idx / lhs_width + lhs_variant.start; - size_t const rhs_ref = rhs_idx / rhs_width + rhs_variant.start; + size_t const lhs_ref = lhs_idx / lhs_width + lhs.start; + size_t const rhs_ref = rhs_idx / rhs_width + rhs.start; size_t const included = queue.entries[HASH_TABLE_INDEX(queue.entries, idx)].included; //count += 1; @@ -492,7 +492,7 @@ dfa_overlap(GVA_Allocator const allocator, { uint8_t const rhs_value = get(rhs_dfa, rhs_idx); bool const rhs_match = rhs_idx % rhs_width < rhs_width - 1 && - reference[rhs_variant.start + rhs_idx / rhs_width] == rhs_variant.sequence.str[rhs_idx % rhs_width]; + reference[rhs.start + rhs_idx / rhs_width] == rhs.sequence.str[rhs_idx % rhs_width]; if (rhs_match) { @@ -524,7 +524,7 @@ dfa_overlap(GVA_Allocator const allocator, { uint8_t const lhs_value = get(lhs_dfa, lhs_idx); bool const lhs_match = lhs_idx % lhs_width < lhs_width - 1 && - reference[lhs_variant.start + lhs_idx / lhs_width] == lhs_variant.sequence.str[lhs_idx % lhs_width]; + reference[lhs.start + lhs_idx / lhs_width] == lhs.sequence.str[lhs_idx % lhs_width]; if (lhs_match) { @@ -554,10 +554,10 @@ dfa_overlap(GVA_Allocator const allocator, uint8_t const lhs_value = get(lhs_dfa, lhs_idx); bool const lhs_match = lhs_idx % lhs_width < lhs_width - 1 && - reference[lhs_variant.start + lhs_idx / lhs_width] == lhs_variant.sequence.str[lhs_idx % lhs_width]; + reference[lhs.start + lhs_idx / lhs_width] == lhs.sequence.str[lhs_idx % lhs_width]; uint8_t const rhs_value = get(rhs_dfa, rhs_idx); bool const rhs_match = rhs_idx % rhs_width < rhs_width - 1 && - reference[rhs_variant.start + rhs_idx / rhs_width] == rhs_variant.sequence.str[rhs_idx % rhs_width]; + reference[rhs.start + rhs_idx / rhs_width] == rhs.sequence.str[rhs_idx % rhs_width]; if (lhs_match && rhs_match) { @@ -579,7 +579,7 @@ dfa_overlap(GVA_Allocator const allocator, queue_push_front(&queue, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width, included + 1); } // if - if (lhs_insertion && rhs_insertion && lhs_variant.sequence.str[lhs_idx % lhs_width] == rhs_variant.sequence.str[rhs_idx % rhs_width]) + if (lhs_insertion && rhs_insertion && lhs.sequence.str[lhs_idx % lhs_width] == rhs.sequence.str[rhs_idx % rhs_width]) { // II // fprintf(stderr, " push (%zu %c) {%zu, %zu} +1 +0 (%zu)\n", lhs_ref, lhs_variant.sequence.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx + 1, (lhs_idx + 1) * rhs_size + rhs_idx + 1); @@ -600,7 +600,7 @@ dfa_overlap(GVA_Allocator const allocator, } // if if (lhs_insertion && (rhs_deletion || rhs_match || (rhs_insertion && - lhs_variant.sequence.str[lhs_idx % lhs_width] != rhs_variant.sequence.str[rhs_idx % rhs_width]))) + lhs.sequence.str[lhs_idx % lhs_width] != rhs.sequence.str[rhs_idx % rhs_width]))) { // I. // fprintf(stderr, " push (%zu %c vs .) {%zu, %zu} +0 +1 (%zu)\n", lhs_ref, lhs_variant.sequence.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx, (lhs_idx + 1) * rhs_size + rhs_idx); @@ -608,7 +608,7 @@ dfa_overlap(GVA_Allocator const allocator, } // if if (rhs_insertion && (lhs_deletion || lhs_match || (lhs_insertion && - lhs_variant.sequence.str[lhs_idx % lhs_width] != rhs_variant.sequence.str[rhs_idx % rhs_width]))) + lhs.sequence.str[lhs_idx % lhs_width] != rhs.sequence.str[rhs_idx % rhs_width]))) { // .I // fprintf(stderr, " push (. vs %zu %c) {%zu, %zu} +0 +1 (%zu)\n", rhs_ref, rhs_variant.sequence.str[rhs_idx % rhs_width], lhs_idx, rhs_idx + 1, lhs_idx * rhs_size + rhs_idx + 1); @@ -632,28 +632,28 @@ dfa_overlap(GVA_Allocator const allocator, bool -dfa_disjoint(GVA_Variant const lhs_variant, uint8_t const lhs_dfa[static restrict 1], - GVA_Variant const rhs_variant, uint8_t const rhs_dfa[static restrict 1]) +dfa_disjoint(GVA_Variant const lhs, uint8_t const lhs_dfa[static restrict 1], + GVA_Variant const rhs, uint8_t const rhs_dfa[static restrict 1]) { - size_t const lhs_width = lhs_variant.sequence.len + 1; - size_t const rhs_width = rhs_variant.sequence.len + 1; + size_t const lhs_width = lhs.sequence.len + 1; + size_t const rhs_width = rhs.sequence.len + 1; - size_t const start = MAX(lhs_variant.start, rhs_variant.start); - size_t const end = MIN(lhs_variant.end + 1, rhs_variant.end + 1); + size_t const start = MAX(lhs.start, rhs.start); + size_t const end = MIN(lhs.end + 1, rhs.end + 1); for (size_t i = start; i < end; ++i) { for (size_t j = 0; j < lhs_width; ++j) { - uint8_t const lhs_value = get(lhs_dfa, (i - lhs_variant.start) * lhs_width + j); + uint8_t const lhs_value = get(lhs_dfa, (i - lhs.start) * lhs_width + j); for (size_t k = 0; k < rhs_width; ++k) { - uint8_t const rhs_value = get(rhs_dfa, (i - rhs_variant.start) * rhs_width + k); + uint8_t const rhs_value = get(rhs_dfa, (i - rhs.start) * rhs_width + k); if ((lhs_value & DFA_DELETION && rhs_value & DFA_DELETION) || (lhs_value & DFA_INSERTION && rhs_value & DFA_INSERTION && - lhs_variant.sequence.str[j] == rhs_variant.sequence.str[k])) + lhs.sequence.str[j] == rhs.sequence.str[k])) { return false; } // if diff --git a/src/dfa.h b/src/dfa.h index ec84c35..c3122cd 100644 --- a/src/dfa.h +++ b/src/dfa.h @@ -41,13 +41,13 @@ dfas_from_lcs_graph(GVA_Allocator const allocator, GVA_LCS_Graph const graph); size_t dfa_overlap(GVA_Allocator const allocator, size_t const len, char const reference[static restrict len], - GVA_Variant const lhs_variant, uint8_t const lhs_dfa[static restrict 1], - GVA_Variant const rhs_variant, uint8_t const rhs_dfa[static restrict 1]); + GVA_Variant const lhs, uint8_t const lhs_dfa[static restrict 1], + GVA_Variant const rhs, uint8_t const rhs_dfa[static restrict 1]); bool -dfa_disjoint(GVA_Variant const lhs_variant, uint8_t const lhs_dfa[static restrict 1], - GVA_Variant const rhs_variant, uint8_t const rhs_dfa[static restrict 1]); +dfa_disjoint(GVA_Variant const lhs, uint8_t const lhs_dfa[static restrict 1], + GVA_Variant const rhs, uint8_t const rhs_dfa[static restrict 1]); // FIXME: DEBUG From 40e95046099ae0477b55d1952d170abaaa39b3eb Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 14 May 2026 13:31:00 +0200 Subject: [PATCH 653/704] WIP: bring DFAs to index --- src/dfa.c | 106 ++++++++++++++++++++++------------------------------ src/dfa.h | 13 ++----- src/index.c | 23 +++++++++--- src/main.c | 8 +--- 4 files changed, 65 insertions(+), 85 deletions(-) diff --git a/src/dfa.c b/src/dfa.c index f95227b..d72c89c 100644 --- a/src/dfa.c +++ b/src/dfa.c @@ -247,93 +247,75 @@ dfa_from_alignment(GVA_Allocator const allocator, uint8_t* restrict dfas, } // dfa_from_alignment -DFAs -dfas_from_lcs_graph(GVA_Allocator const allocator, GVA_LCS_Graph const graph) +uint8_t* +dfa_from_lcs_graph(GVA_Allocator const allocator, uint8_t* dfas, + GVA_LCS_Graph const graph, size_t const idx) { - size_t bytes = 0; - for (size_t i = 0; i < array_length(graph.dom_nodes) - 1; ++i) - { - GVA_Variant const local = gva_lcs_graph_local_supremal(graph, i, i + 1); - bytes += ((local.end - local.start + 1) * (local.sequence.len + 1) + 3) / 4; - } // for + GVA_Variant const supremal = gva_lcs_graph_local_supremal(graph, idx, idx + 1); + size_t const width = supremal.sequence.len + 1; + size_t const bytes = ((supremal.end - supremal.start + 1) * width + 3) / 4; - DFAs dfas = + dfas = array_ensure(allocator, dfas, 1, bytes); + if (dfas == NULL) { - .len = array_length(graph.dom_nodes), - .starts = allocator.allocate(allocator.context, NULL, 0, sizeof(*dfas.starts) * array_length(graph.dom_nodes)), - .data = allocator.allocate(allocator.context, NULL, 0, bytes), - }; - - gva_uint* restrict next = allocator.allocate(allocator.context, NULL, 0, sizeof(*next) * array_length(graph.nodes)); + return NULL; // OOM + } // if - if (dfas.starts == NULL || dfas.data == NULL || next == NULL) + gva_uint* next = allocator.allocate(allocator.context, NULL, 0, sizeof(*next) * array_length(graph.nodes)); + if (next == NULL) { - next = allocator.allocate(allocator.context, next, sizeof(*next) * array_length(graph.nodes), 0); - dfas.data = allocator.allocate(allocator.context, dfas.data, bytes, 0); - dfas.starts = allocator.allocate(allocator.context, dfas.starts, sizeof(*dfas.starts) * array_length(graph.dom_nodes), 0); - return (DFAs) {0}; // OOM + return dfas; // OOM } // if - memset(dfas.data, 0, bytes); for (size_t i = 0; i < array_length(graph.nodes); ++i) { next[i] = GVA_NULL; } // for - fprintf(stderr, "%zu bytes\n", bytes); + size_t const start = array_length(dfas); + memset(dfas + start, 0, bytes); + array_header(dfas)->length += bytes; - size_t start = 0; - for (size_t i = 0; i < array_length(graph.dom_nodes) - 1; ++i) + gva_uint head = graph.dom_nodes[idx].link; + gva_uint tail = head; + while (head != GVA_NULL) { - GVA_Variant const local = gva_lcs_graph_local_supremal(graph, i, i + 1); - size_t const width = local.sequence.len + 1; + fprintf(stderr, "POP %u\n", head); - fprintf(stderr, "DFA %u x %zu @ %zu\n", local.end - local.start + 1, width, start); - - gva_uint head = graph.dom_nodes[i].link; - gva_uint tail = head; - while (head != GVA_NULL) + if (head == graph.dom_nodes[idx + 1].link) { - fprintf(stderr, "POP %u\n", head); + head = next[head]; + continue; + } // if - if (head == graph.dom_nodes[i + 1].link) + for (gva_uint j = graph.nodes[head].edges; j != GVA_NULL; j = graph.edges[j].next) + { + GVA_Variant variant = {0}; + size_t const count = gva_edges(graph.observed.str, + graph.nodes[head].match, graph.nodes[graph.edges[j].tail].match, + head == graph.source, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, + &variant); + for (size_t k = 0; k < count; ++k) { - head = next[head]; - continue; - } // if + edge(dfas + start, width, variant.start + k - supremal.start, variant.end + k - supremal.start, + variant.sequence.len, variant.sequence.str - supremal.sequence.str + k); + } // for - for (gva_uint j = graph.nodes[head].edges; j != GVA_NULL; j = graph.edges[j].next) + if (next[graph.edges[j].tail] == GVA_NULL) { - GVA_Variant variant = {0}; - size_t const count = gva_edges(graph.observed.str, - graph.nodes[head].match, graph.nodes[graph.edges[j].tail].match, - head == graph.source, graph.nodes[graph.edges[j].tail].edges == GVA_NULL, - &variant); - for (size_t k = 0; k < count; ++k) - { - edge(dfas.data + start, width, variant.start + k - local.start, variant.end + k - local.start, - variant.sequence.len, variant.sequence.str - local.sequence.str + k); - } // for - - if (next[graph.edges[j].tail] == GVA_NULL) - { - fprintf(stderr, " PUSH %u\n", graph.edges[j].tail); - next[tail] = graph.edges[j].tail; - tail = graph.edges[j].tail; - } // if - } // for + fprintf(stderr, " PUSH %u\n", graph.edges[j].tail); + next[tail] = graph.edges[j].tail; + tail = graph.edges[j].tail; + } // if + } // for - head = next[head]; - } // while - dfas.starts[i] = start; - start += ((local.end - local.start + 1) * width + 3) / 4; - } // for - dfas.starts[array_length(graph.dom_nodes) - 1] = bytes; + head = next[head]; + } // while next = allocator.allocate(allocator.context, next, sizeof(*next) * array_length(graph.nodes), 0); return dfas; -} // dfas_from_lcs_graph +} // dfa_from_lcs_graph typedef struct diff --git a/src/dfa.h b/src/dfa.h index c3122cd..79b1070 100644 --- a/src/dfa.h +++ b/src/dfa.h @@ -14,14 +14,6 @@ #include // FIXME: DEBUG -typedef struct -{ - size_t len; - gva_uint* restrict starts; - uint8_t* restrict data; -} DFAs; - - uint8_t* dfa_concat(GVA_Allocator const allocator, size_t const n, GVA_Variant const variants[static restrict n], @@ -34,8 +26,9 @@ dfa_from_alignment(GVA_Allocator const allocator, uint8_t* restrict dfas, size_t const len_obs, char const observed[static restrict len_obs]); -DFAs -dfas_from_lcs_graph(GVA_Allocator const allocator, GVA_LCS_Graph const graph); +uint8_t* +dfa_from_lcs_graph(GVA_Allocator const allocator, uint8_t* dfas, + GVA_LCS_Graph const graph, size_t const idx); size_t diff --git a/src/index.c b/src/index.c index 65f847b..a541f05 100644 --- a/src/index.c +++ b/src/index.c @@ -298,12 +298,24 @@ gva_index_query(GVA_Allocator const allocator, gva_uint next; }* hits = NULL; + gva_uint* restrict starts = allocator.allocate(allocator.context, NULL, 0, sizeof(*starts) * (array_length(graph.dom_nodes) - 1)); + if (starts == NULL) + { + entries = HASH_TABLE_DESTROY(allocator, entries); + return (GVA_Query_Result) {NULL}; // OOM + } // if + + uint8_t* restrict dfas = NULL; + // Phase 1: for every local supremal part: // - find candidates based on interval query // - calculate the distance with the candidates, // and discard disjoint candidates early based on distance for (size_t i = 0; i < array_length(graph.dom_nodes) - 1; ++i) { + starts[i] = array_length(dfas); + dfas = dfa_from_lcs_graph(allocator, dfas, graph, i); + GVA_Variant const variant = gva_lcs_graph_local_supremal(graph, i, i + 1); gva_uint* intervals = interval_tree_intersection(allocator, self->intervals, variant.start, variant.end); @@ -484,15 +496,12 @@ gva_index_query(GVA_Allocator const allocator, // non-distance based if (ABS((intmax_t) self->intervals.nodes[node_idx].distance - (intmax_t) distance) != hits[i].distance) { - size_t excluded = 0; - size_t included = variants_included(allocator, self->reference.len, self->reference.str, - variant_from_index(self, node_idx), - gva_lcs_graph_local_supremal(graph, hits[i].query, hits[i].query + 1), - &excluded); + size_t const included = dfa_overlap(allocator, self->reference.len, self->reference.str, + variant_from_index(self, node_idx), (uint8_t*) trie_string(self->dfas, self->intervals.nodes[node_idx].dfa).str, + gva_lcs_graph_local_supremal(graph, hits[i].query, hits[i].query + 1), dfas + starts[hits[i].query]); if (included > 0) { - included = MAX(1, (double) (2 * included - 1) / excluded * MIN(self->intervals.nodes[node_idx].distance, distance)); ARRAY_APPEND(allocator, result.hits, ((GVA_Query_Hit) { .relation = GVA_OVERLAP, @@ -549,6 +558,8 @@ gva_index_query(GVA_Allocator const allocator, hits = ARRAY_DESTROY(allocator, hits); entries = HASH_TABLE_DESTROY(allocator, entries); + dfas = ARRAY_DESTROY(allocator, dfas); + starts = allocator.allocate(allocator.context, starts, sizeof(*starts) * (array_length(graph.dom_nodes) - 1), 0); return result; } // gva_index_query diff --git a/src/main.c b/src/main.c index eec9652..2e025c8 100644 --- a/src/main.c +++ b/src/main.c @@ -544,14 +544,8 @@ overlap_main(int argc, char* argv[static argc]) GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &rhs_variant); - DFAs dfas = dfas_from_lcs_graph(gva_std_allocator, graph); - - dfas.data = gva_std_allocator.allocate(gva_std_allocator.context, dfas.data, dfas.starts[dfas.len - 1], 0); - dfas.starts = gva_std_allocator.allocate(gva_std_allocator.context, dfas.starts, sizeof(*dfas.starts) * dfas.len, 0); - gva_lcs_graph_destroy(gva_std_allocator, graph, true); - //uint8_t* dfa = dfa_concat(gva_std_allocator, 2, variants, dfas); //dfa_dot(stdout, reference.len, reference.str, rhs_variant, dfa); //dfa = gva_std_allocator.allocate(gva_std_allocator.context, dfa, 0, 0); @@ -767,7 +761,7 @@ all_main(int argc, char* argv[static argc]) GVA_String lhs_dfa = trie_string(dfas, entries[i].dfa); GVA_String rhs_dfa = trie_string(dfas, entries[j].dfa); - //size_t const overlap = dfa_max_overlap(gva_std_allocator, reference.len, reference.str, lhs, (uint8_t*) lhs_dfa.str, rhs, (uint8_t*) rhs_dfa.str, 0); + //size_t const overlap = dfa_overlap(gva_std_allocator, reference.len, reference.str, lhs, (uint8_t*) lhs_dfa.str, rhs, (uint8_t*) rhs_dfa.str); bool const disjoint = dfa_disjoint(lhs, (uint8_t*) lhs_dfa.str, rhs, (uint8_t*) rhs_dfa.str); if (disjoint) From b4a1d982b89aae34f580de92543903d0571ff134 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 14 May 2026 20:47:47 +0200 Subject: [PATCH 654/704] WIP: DFA concat --- src/dfa.c | 63 ++++++++++++++++--------------------------------------- src/dfa.h | 6 +++--- 2 files changed, 21 insertions(+), 48 deletions(-) diff --git a/src/dfa.c b/src/dfa.c index d72c89c..283348d 100644 --- a/src/dfa.c +++ b/src/dfa.c @@ -14,8 +14,7 @@ #include "hash_table.h" // HASH_TABLE_*, hash_table_* -// FIXME: DEBUG -#include +#include // FIXME: DEBUG static uint8_t const DFA_DELETION = 0x1; @@ -53,62 +52,36 @@ edge(uint8_t dfa[static 1], size_t const width, uint8_t* -dfa_concat(GVA_Allocator const allocator, size_t const n, - GVA_Variant const variants[static restrict n], - uint8_t* const dfas[static restrict n]) +dfa_concat(GVA_Allocator const allocator, + GVA_Variant const lhs, uint8_t* restrict lhs_dfa, + GVA_Variant const rhs, uint8_t const rhs_dfa[static restrict 1]) { - if (n == 0) - { - return NULL; - } // if - if (n == 1) - { - return dfas[0]; - } // if - - size_t const start = variants[0].start; - size_t const end = variants[n - 1].end; - - size_t width = 1; - for (size_t i = 0; i < n; ++i) - { - if (i > 0) - { - width += variants[i].start - variants[i - 1].end; - } // if - width += variants[i].sequence.len; - } // for - size_t const size = (end - start + 1) * width; + size_t const width = lhs.sequence.len + rhs.sequence.len + rhs.start - lhs.end + 1; + size_t const size = (rhs.end - lhs.start + 1) * width; size_t const bytes = (size + 3) / 4; - uint8_t* const restrict dfa = allocator.allocate(allocator.context, NULL, 0, bytes); - if (dfa == NULL) + lhs_dfa = array_ensure(allocator, lhs_dfa, 1, bytes); + if (lhs_dfa == NULL) { return NULL; // OOM } // if - memset(dfa, 0, bytes); + size_t const start = array_length(lhs_dfa); + memset(lhs_dfa + start, 0, bytes); + array_header(lhs_dfa)->length += bytes; - size_t offset_col = 0; - for (size_t i = 0; i < n; ++i) + size_t const offset_row = rhs.start - lhs.start; + for (size_t j = 0; j <= rhs.end - rhs.start; ++j) { - size_t const offset_row = variants[i].start - start; - if (i > 0) + for (size_t k = 0; k <= rhs.sequence.len; ++k) { - offset_col += variants[i - 1].sequence.len + variants[i].start - variants[i - 1].end; - } // if - for (size_t j = 0; j <= variants[i].end - variants[i].start; ++j) - { - for (size_t k = 0; k <= variants[i].sequence.len; ++k) - { - fprintf(stderr, "cpy %zu, %zu -> %zu, %zu\n", j, k, j + offset_row, k + offset_col); - set(dfa, (j + offset_row) * width + k + offset_col, - get(dfas[i], j * (variants[i].sequence.len + 1) + k)); - } // for + fprintf(stderr, "cpy %zu, %zu -> %zu, %zu\n", j, k, j + offset_row, k); + set(lhs_dfa, (j + offset_row) * width + k, + get(rhs_dfa, j * (rhs.sequence.len + 1) + k)); } // for } // for - return dfa; + return lhs_dfa; } // dfa_concat diff --git a/src/dfa.h b/src/dfa.h index 79b1070..6b15011 100644 --- a/src/dfa.h +++ b/src/dfa.h @@ -15,9 +15,9 @@ uint8_t* -dfa_concat(GVA_Allocator const allocator, size_t const n, - GVA_Variant const variants[static restrict n], - uint8_t* const dfas[static restrict n]); +dfa_concat(GVA_Allocator const allocator, + GVA_Variant const lhs, uint8_t* restrict lhs_dfa, + GVA_Variant const rhs, uint8_t const rhs_dfa[static restrict 1]); uint8_t* From 2aba8f080068bba6459caa958840c2176f7b4039 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 14 May 2026 20:50:38 +0200 Subject: [PATCH 655/704] Fold size --- src/dfa.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/dfa.c b/src/dfa.c index 283348d..4becea3 100644 --- a/src/dfa.c +++ b/src/dfa.c @@ -57,8 +57,7 @@ dfa_concat(GVA_Allocator const allocator, GVA_Variant const rhs, uint8_t const rhs_dfa[static restrict 1]) { size_t const width = lhs.sequence.len + rhs.sequence.len + rhs.start - lhs.end + 1; - size_t const size = (rhs.end - lhs.start + 1) * width; - size_t const bytes = (size + 3) / 4; + size_t const bytes = ((rhs.end - lhs.start + 1) * width + 3) / 4; lhs_dfa = array_ensure(allocator, lhs_dfa, 1, bytes); if (lhs_dfa == NULL) @@ -99,8 +98,7 @@ dfa_from_alignment(GVA_Allocator const allocator, uint8_t* restrict dfas, } // if size_t const width = len_obs + 1; - size_t const size = (len_ref + 1) * width; - size_t const bytes = (size + 3) / 4; + size_t const bytes = ((len_ref + 1) * width + 3) / 4; dfas = array_ensure(allocator, dfas, 1, bytes); if (dfas == NULL) From 6daba47f7f17fcdfa273ddc58cef4b19c84e97b8 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Mon, 18 May 2026 11:57:52 +0200 Subject: [PATCH 656/704] Undo reporting hack. --- src/main.c | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/src/main.c b/src/main.c index 2e025c8..201200e 100644 --- a/src/main.c +++ b/src/main.c @@ -78,28 +78,11 @@ report_query_result(GVA_Index const* const index, GVA_LCS_Graph const graph, GVA for (size_t i = 0; i < array_length(result.alleles); ++i) { - - if (result.alleles[i].relation == GVA_OVERLAP && - result.alleles[i].hits.end - result.alleles[i].hits.start > 1) - { - bool overlap = false; - for (size_t j = result.alleles[i].hits.start; j < result.alleles[i].hits.end; ++j) - { - if (result.hits[j].relation == GVA_OVERLAP) - { - overlap = true; - break; - } // if - } // for - if (!overlap) - { fprintf(stdout, GVA_STRING_FMT " %s " GVA_STRING_FMT " %u %u %zu\n", GVA_STRING_PRINT(gva_index_allele_id(index, result.alleles[i].idx)), GVA_RELATION_LABELS[result.alleles[i].relation], GVA_STRING_PRINT(id), result.alleles[i].included, result.alleles[i].excluded, array_length(graph.dom_nodes) - 1); - } // if - } // if if (hits) { From fe08f61dd772ac2d00686c8afbb8d4e8ee122f5e Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 18 May 2026 13:18:04 +0200 Subject: [PATCH 657/704] WIP: use dfa in index --- src/dfa.c | 2 +- src/main.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/dfa.c b/src/dfa.c index 4becea3..8bfe093 100644 --- a/src/dfa.c +++ b/src/dfa.c @@ -272,7 +272,7 @@ dfa_from_lcs_graph(GVA_Allocator const allocator, uint8_t* dfas, variant.sequence.len, variant.sequence.str - supremal.sequence.str + k); } // for - if (next[graph.edges[j].tail] == GVA_NULL) + if (next[graph.edges[j].tail] == GVA_NULL && tail != graph.edges[j].tail) { fprintf(stderr, " PUSH %u\n", graph.edges[j].tail); next[tail] = graph.edges[j].tail; diff --git a/src/main.c b/src/main.c index 201200e..8d08a41 100644 --- a/src/main.c +++ b/src/main.c @@ -782,8 +782,8 @@ int main(int argc, char* argv[static argc]) { // return allele_main(argc, argv); - // return index_main(argc, argv); + return index_main(argc, argv); // return supremal_main(argc, argv); // return overlap_main(argc, argv); - return all_main(argc, argv); + // return all_main(argc, argv); } // main From e3b768a7e60af14b77d279208c9634b4dca7372f Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 18 May 2026 16:36:23 +0200 Subject: [PATCH 658/704] WIP: debugging DFA concat --- src/dfa.c | 27 ++++++++++++++++++++++----- src/index.c | 45 +++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 63 insertions(+), 9 deletions(-) diff --git a/src/dfa.c b/src/dfa.c index 8bfe093..8d216f6 100644 --- a/src/dfa.c +++ b/src/dfa.c @@ -56,6 +56,22 @@ dfa_concat(GVA_Allocator const allocator, GVA_Variant const lhs, uint8_t* restrict lhs_dfa, GVA_Variant const rhs, uint8_t const rhs_dfa[static restrict 1]) { + fprintf(stderr, "CONCAT: " GVA_VARIANT_FMT " " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(lhs), GVA_VARIANT_PRINT(rhs)); + + if (lhs_dfa == NULL) + { + size_t const len = array_length(rhs_dfa); + lhs_dfa = array_init(allocator, len, 1); + if (lhs_dfa == NULL) + { + return NULL; // OOM + } // if + + memcpy(lhs_dfa, rhs_dfa, len); + array_header(lhs_dfa)->length = len; + return lhs_dfa; + } // if + size_t const width = lhs.sequence.len + rhs.sequence.len + rhs.start - lhs.end + 1; size_t const bytes = ((rhs.end - lhs.start + 1) * width + 3) / 4; @@ -70,12 +86,13 @@ dfa_concat(GVA_Allocator const allocator, array_header(lhs_dfa)->length += bytes; size_t const offset_row = rhs.start - lhs.start; + size_t const offset_col = lhs.sequence.len + rhs.start - lhs.end; for (size_t j = 0; j <= rhs.end - rhs.start; ++j) { for (size_t k = 0; k <= rhs.sequence.len; ++k) { - fprintf(stderr, "cpy %zu, %zu -> %zu, %zu\n", j, k, j + offset_row, k); - set(lhs_dfa, (j + offset_row) * width + k, + fprintf(stderr, "cpy %zu, %zu -> %zu, %zu\n", j, k, j + offset_row, k + offset_col); + set(lhs_dfa, (j + offset_row) * width + k + offset_col, get(rhs_dfa, j * (rhs.sequence.len + 1) + k)); } // for } // for @@ -251,7 +268,7 @@ dfa_from_lcs_graph(GVA_Allocator const allocator, uint8_t* dfas, gva_uint tail = head; while (head != GVA_NULL) { - fprintf(stderr, "POP %u\n", head); + //fprintf(stderr, "POP %u\n", head); if (head == graph.dom_nodes[idx + 1].link) { @@ -274,7 +291,7 @@ dfa_from_lcs_graph(GVA_Allocator const allocator, uint8_t* dfas, if (next[graph.edges[j].tail] == GVA_NULL && tail != graph.edges[j].tail) { - fprintf(stderr, " PUSH %u\n", graph.edges[j].tail); + //fprintf(stderr, " PUSH %u\n", graph.edges[j].tail); next[tail] = graph.edges[j].tail; tail = graph.edges[j].tail; } // if @@ -652,7 +669,7 @@ dfa_dot(FILE* restrict const stream, next_end = MAX(next_end, j); } // if - if (i < variant.end - variant.start && + if (i < variant.end - variant.start && j < width - 1 && reference[variant.start + i] == variant.sequence.str[j]) { fprintf(stream, "%zu->%zu[label=\"%zu Μ\"]\n", i * width + j, i * width + j + width + 1, variant.start + i); diff --git a/src/index.c b/src/index.c index a541f05..0edcd95 100644 --- a/src/index.c +++ b/src/index.c @@ -61,6 +61,13 @@ variant_from_index(GVA_Index const self[static 1], size_t const idx) } // variant_from_index +static inline uint8_t* +dfa_from_index(GVA_Index const self[static 1], size_t const idx) +{ + return (uint8_t*) trie_string(self->dfas, self->intervals.nodes[idx].dfa).str; +} // dfa_from_index + + // FIXME: gva_compare_included static size_t variants_included(GVA_Allocator const allocator, @@ -251,7 +258,9 @@ gva_index_insert(GVA_Index* restrict const self, uint8_t* dfa = dfa_from_alignment(self->allocator, NULL, variant.end - variant.start, self->reference.str + variant.start, variant.sequence.len, variant.sequence.str); + self->intervals.nodes[node_idx].dfa = trie_insert(&self->dfas, array_length(dfa), (char*) dfa); + dfa = ARRAY_DESTROY(self->allocator, dfa); } // if else @@ -373,6 +382,8 @@ gva_index_query(GVA_Allocator const allocator, continue; } // if + uint8_t* restrict dfa = NULL; + size_t const start_hits = array_length(result.hits); for (gva_uint i = entries[idx].head; i != GVA_NULL; i = hits[i].next) { @@ -397,6 +408,7 @@ gva_index_query(GVA_Allocator const allocator, GVA_Variant const variant = gva_lcs_graph_local_supremal(graph, start, end); if (distance == 0) { + //dfa = dfa_concat(allocator, supremal, dfa, variant, supremal = gva_variant_dup(allocator, variant); } // if else @@ -444,6 +456,9 @@ gva_index_query(GVA_Allocator const allocator, })); entries[idx].included += included; + + dfa = ARRAY_DESTROY(allocator, dfa); + continue; } // if @@ -454,24 +469,43 @@ gva_index_query(GVA_Allocator const allocator, { ARRAY_APPEND(allocator, result.parts, hits[i].join); gva_uint const node_idx = self->join[hits[i].join].link ^ entries[idx].gva_key; + supremal = gva_variant_dup(allocator, variant_from_index(self, node_idx)); + + dfa_dot(stderr, self->reference.len, self->reference.str, supremal, dfa_from_index(self, node_idx)); + + + dfa = dfa_concat(allocator, (GVA_Variant) {0}, dfa, supremal, dfa_from_index(self, node_idx)); + dfa_dot(stderr, self->reference.len, self->reference.str, supremal, dfa); + + distance = self->intervals.nodes[node_idx].distance; } // if i = hits[i].next; ARRAY_APPEND(allocator, result.parts, hits[i].join); gva_uint const node_idx = self->join[hits[i].join].link ^ entries[idx].gva_key; GVA_Variant const variant = variant_from_index(self, node_idx); + + dfa_dot(stderr, self->reference.len, self->reference.str, variant, dfa_from_index(self, node_idx)); + + dfa = dfa_concat(allocator, supremal, dfa, variant, dfa_from_index(self, node_idx)); + supremal.sequence = gva_string_concat(allocator, supremal.sequence, (GVA_String) {variant.start - supremal.end, self->reference.str + supremal.end}); supremal.sequence = gva_string_concat(allocator, supremal.sequence, variant.sequence); supremal.end = variant.end; + + dfa_dot(stderr, self->reference.len, self->reference.str, supremal, dfa); + distance += self->intervals.nodes[node_idx].distance; } // while if (start_parts < array_length(result.parts)) { - size_t const included = variants_with_distance(allocator, self->reference.len, self->reference.str, - supremal, distance, - gva_lcs_graph_local_supremal(graph, hits[i].query, hits[i].query + 1), graph.dom_nodes[hits[i].query + 1].distance - graph.dom_nodes[hits[i].query].distance); + fprintf(stderr, "HIER!!!\n"); + dfa_dot(stderr, self->reference.len, self->reference.str, supremal, dfa); + size_t const included = gva_compare_included(allocator, self->reference.len, self->reference.str, + supremal, distance, dfa, + gva_lcs_graph_local_supremal(graph, hits[i].query, hits[i].query + 1), graph.dom_nodes[hits[i].query + 1].distance - graph.dom_nodes[hits[i].query].distance, dfas + starts[hits[i].query]); gva_string_destroy(allocator, supremal.sequence); size_t excluded = 0; @@ -487,6 +521,9 @@ gva_index_query(GVA_Allocator const allocator, })); entries[idx].included += included; + + dfa = ARRAY_DESTROY(allocator, dfa); + continue; } // if @@ -497,7 +534,7 @@ gva_index_query(GVA_Allocator const allocator, if (ABS((intmax_t) self->intervals.nodes[node_idx].distance - (intmax_t) distance) != hits[i].distance) { size_t const included = dfa_overlap(allocator, self->reference.len, self->reference.str, - variant_from_index(self, node_idx), (uint8_t*) trie_string(self->dfas, self->intervals.nodes[node_idx].dfa).str, + variant_from_index(self, node_idx), dfa_from_index(self, node_idx), gva_lcs_graph_local_supremal(graph, hits[i].query, hits[i].query + 1), dfas + starts[hits[i].query]); if (included > 0) From 28255034fdff09eacaad8dc6490922497f2e357c Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 18 May 2026 22:50:53 +0200 Subject: [PATCH 659/704] WIP: first round of concats seem ok --- src/dfa.c | 93 +++++++++++++++++++++++++++++++++++------------------ src/dfa.h | 13 ++++++-- src/index.c | 19 +++++------ 3 files changed, 81 insertions(+), 44 deletions(-) diff --git a/src/dfa.c b/src/dfa.c index 8d216f6..6678d0b 100644 --- a/src/dfa.c +++ b/src/dfa.c @@ -53,37 +53,31 @@ edge(uint8_t dfa[static 1], size_t const width, uint8_t* dfa_concat(GVA_Allocator const allocator, - GVA_Variant const lhs, uint8_t* restrict lhs_dfa, + GVA_Variant const lhs, uint8_t const lhs_dfa[static restrict 1], GVA_Variant const rhs, uint8_t const rhs_dfa[static restrict 1]) { fprintf(stderr, "CONCAT: " GVA_VARIANT_FMT " " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(lhs), GVA_VARIANT_PRINT(rhs)); - if (lhs_dfa == NULL) - { - size_t const len = array_length(rhs_dfa); - lhs_dfa = array_init(allocator, len, 1); - if (lhs_dfa == NULL) - { - return NULL; // OOM - } // if - - memcpy(lhs_dfa, rhs_dfa, len); - array_header(lhs_dfa)->length = len; - return lhs_dfa; - } // if - size_t const width = lhs.sequence.len + rhs.sequence.len + rhs.start - lhs.end + 1; size_t const bytes = ((rhs.end - lhs.start + 1) * width + 3) / 4; - lhs_dfa = array_ensure(allocator, lhs_dfa, 1, bytes); - if (lhs_dfa == NULL) + fprintf(stderr, "DFA %zu x %u\n", width, rhs.end - lhs.start + 1); + + uint8_t* const restrict dfa = array_init(allocator, bytes, 1); + if (dfa == NULL) { return NULL; // OOM } // if - size_t const start = array_length(lhs_dfa); - memset(lhs_dfa + start, 0, bytes); - array_header(lhs_dfa)->length += bytes; + memset(dfa, 0, bytes); + + for (size_t j = 0; j <= lhs.end - lhs.start; ++j) + { + for (size_t k = 0; k <= lhs.sequence.len; ++k) + { + set(dfa, j * width + k, get(lhs_dfa, j * (lhs.sequence.len + 1) + k)); + } // for + } // for size_t const offset_row = rhs.start - lhs.start; size_t const offset_col = lhs.sequence.len + rhs.start - lhs.end; @@ -92,15 +86,28 @@ dfa_concat(GVA_Allocator const allocator, for (size_t k = 0; k <= rhs.sequence.len; ++k) { fprintf(stderr, "cpy %zu, %zu -> %zu, %zu\n", j, k, j + offset_row, k + offset_col); - set(lhs_dfa, (j + offset_row) * width + k + offset_col, + set(dfa, (j + offset_row) * width + k + offset_col, get(rhs_dfa, j * (rhs.sequence.len + 1) + k)); } // for } // for - return lhs_dfa; + return dfa; } // dfa_concat +inline uint8_t* +dfa_dup(GVA_Allocator const allocator, uint8_t const self[static restrict 1]) +{ + uint8_t* const restrict dfa = array_init(allocator, array_length(self), 1); + if (dfa == NULL) + { + return NULL; // OOM; + } // if + + return memcpy(dfa, self, array_length(self)); +} // dfa_dup + + uint8_t* dfa_from_alignment(GVA_Allocator const allocator, uint8_t* restrict dfas, size_t const len_ref, char const reference[static restrict len_ref], @@ -237,11 +244,17 @@ dfa_from_alignment(GVA_Allocator const allocator, uint8_t* restrict dfas, uint8_t* dfa_from_lcs_graph(GVA_Allocator const allocator, uint8_t* dfas, - GVA_LCS_Graph const graph, size_t const idx) + GVA_LCS_Graph const graph, size_t const start, size_t const end) { - GVA_Variant const supremal = gva_lcs_graph_local_supremal(graph, idx, idx + 1); - size_t const width = supremal.sequence.len + 1; - size_t const bytes = ((supremal.end - supremal.start + 1) * width + 3) / 4; + if (end < start || end > array_length(graph.dom_nodes)) + { + return dfas; + } // if + + size_t const start_dfa = graph.dom_nodes[start].match.row + graph.dom_nodes[start].match.length; + size_t const end_dfa = graph.dom_nodes[end].match.row; + size_t const width = graph.dom_nodes[end].match.col - (graph.dom_nodes[start].match.col + graph.dom_nodes[start].match.length) + 1; + size_t const bytes = ((end_dfa - start_dfa + 1) * width + 3) / 4; dfas = array_ensure(allocator, dfas, 1, bytes); if (dfas == NULL) @@ -260,17 +273,19 @@ dfa_from_lcs_graph(GVA_Allocator const allocator, uint8_t* dfas, next[i] = GVA_NULL; } // for - size_t const start = array_length(dfas); - memset(dfas + start, 0, bytes); + size_t const offset = array_length(dfas); + memset(dfas + offset, 0, bytes); array_header(dfas)->length += bytes; - gva_uint head = graph.dom_nodes[idx].link; + GVA_Variant const supremal = gva_lcs_graph_local_supremal(graph, start, end); + + gva_uint head = graph.dom_nodes[start].link; gva_uint tail = head; while (head != GVA_NULL) { //fprintf(stderr, "POP %u\n", head); - if (head == graph.dom_nodes[idx + 1].link) + if (head == graph.dom_nodes[end].link) { head = next[head]; continue; @@ -285,7 +300,7 @@ dfa_from_lcs_graph(GVA_Allocator const allocator, uint8_t* dfas, &variant); for (size_t k = 0; k < count; ++k) { - edge(dfas + start, width, variant.start + k - supremal.start, variant.end + k - supremal.start, + edge(dfas + offset, width, variant.start + k - supremal.start, variant.end + k - supremal.start, variant.sequence.len, variant.sequence.str - supremal.sequence.str + k); } // for @@ -687,6 +702,22 @@ dfa_dot(FILE* restrict const stream, } // dfa_dot +void +dfa_raw(FILE* restrict const stream, + size_t const height, size_t const width, uint8_t const dfa[static restrict height * width]) +{ + for (size_t i = 0; i < height; ++i) + { + for (size_t j = 0; j < width; ++j) + { + uint8_t const value = get(dfa, i * width + j) & 0x3; + fprintf(stream, "%x ", value); + } // for + fprintf(stream, "\n"); + } // for +} // dfa_raw + + void dfa_svg(FILE* restrict const stream, size_t const len, char const reference[static restrict len], diff --git a/src/dfa.h b/src/dfa.h index 6b15011..ca089ea 100644 --- a/src/dfa.h +++ b/src/dfa.h @@ -16,10 +16,14 @@ uint8_t* dfa_concat(GVA_Allocator const allocator, - GVA_Variant const lhs, uint8_t* restrict lhs_dfa, + GVA_Variant const lhs, uint8_t const lhs_dfa[static restrict 1], GVA_Variant const rhs, uint8_t const rhs_dfa[static restrict 1]); +uint8_t* +dfa_dup(GVA_Allocator const allocator, uint8_t const self[static restrict 1]); + + uint8_t* dfa_from_alignment(GVA_Allocator const allocator, uint8_t* restrict dfas, size_t const len_ref, char const reference[static restrict len_ref], @@ -28,7 +32,7 @@ dfa_from_alignment(GVA_Allocator const allocator, uint8_t* restrict dfas, uint8_t* dfa_from_lcs_graph(GVA_Allocator const allocator, uint8_t* dfas, - GVA_LCS_Graph const graph, size_t const idx); + GVA_LCS_Graph const graph, size_t const start, size_t const end); size_t @@ -50,6 +54,11 @@ dfa_dot(FILE* restrict const stream, GVA_Variant const variant, uint8_t const dfa[static restrict 1]); +void +dfa_raw(FILE* restrict const stream, + size_t const height, size_t const width, uint8_t const dfa[static restrict height * width]); + + void dfa_svg(FILE* restrict const stream, size_t const len, char const reference[static restrict len], diff --git a/src/index.c b/src/index.c index 0edcd95..24182fe 100644 --- a/src/index.c +++ b/src/index.c @@ -323,7 +323,7 @@ gva_index_query(GVA_Allocator const allocator, for (size_t i = 0; i < array_length(graph.dom_nodes) - 1; ++i) { starts[i] = array_length(dfas); - dfas = dfa_from_lcs_graph(allocator, dfas, graph, i); + dfas = dfa_from_lcs_graph(allocator, dfas, graph, i, i + 1); GVA_Variant const variant = gva_lcs_graph_local_supremal(graph, i, i + 1); @@ -467,18 +467,11 @@ gva_index_query(GVA_Allocator const allocator, { if (distance == 0) { + fprintf(stderr, "START w DUP\n"); ARRAY_APPEND(allocator, result.parts, hits[i].join); gva_uint const node_idx = self->join[hits[i].join].link ^ entries[idx].gva_key; - supremal = gva_variant_dup(allocator, variant_from_index(self, node_idx)); - - dfa_dot(stderr, self->reference.len, self->reference.str, supremal, dfa_from_index(self, node_idx)); - - - dfa = dfa_concat(allocator, (GVA_Variant) {0}, dfa, supremal, dfa_from_index(self, node_idx)); - dfa_dot(stderr, self->reference.len, self->reference.str, supremal, dfa); - - + dfa = dfa_dup(allocator, dfa_from_index(self, node_idx)); distance = self->intervals.nodes[node_idx].distance; } // if i = hits[i].next; @@ -488,13 +481,17 @@ gva_index_query(GVA_Allocator const allocator, dfa_dot(stderr, self->reference.len, self->reference.str, variant, dfa_from_index(self, node_idx)); - dfa = dfa_concat(allocator, supremal, dfa, variant, dfa_from_index(self, node_idx)); + uint8_t* concat = dfa_concat(allocator, supremal, dfa, variant, dfa_from_index(self, node_idx)); + ARRAY_DESTROY(allocator, dfa); + dfa = concat; supremal.sequence = gva_string_concat(allocator, supremal.sequence, (GVA_String) {variant.start - supremal.end, self->reference.str + supremal.end}); supremal.sequence = gva_string_concat(allocator, supremal.sequence, variant.sequence); supremal.end = variant.end; + fprintf(stderr, GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(supremal)); + dfa_dot(stderr, self->reference.len, self->reference.str, supremal, dfa); distance += self->intervals.nodes[node_idx].distance; From fa088af6f78310a089d9fe8e9a37b62213ca2df3 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 19 May 2026 14:33:51 +0200 Subject: [PATCH 660/704] WIP: single query hit multiple join --- src/dfa.c | 57 +++++++++++++++-------------------------------------- src/dfa.h | 9 +++++---- src/index.c | 36 ++++++++++++++++----------------- 3 files changed, 38 insertions(+), 64 deletions(-) diff --git a/src/dfa.c b/src/dfa.c index 6678d0b..64ec4a3 100644 --- a/src/dfa.c +++ b/src/dfa.c @@ -51,63 +51,38 @@ edge(uint8_t dfa[static 1], size_t const width, } // edge -uint8_t* -dfa_concat(GVA_Allocator const allocator, - GVA_Variant const lhs, uint8_t const lhs_dfa[static restrict 1], - GVA_Variant const rhs, uint8_t const rhs_dfa[static restrict 1]) +inline uint8_t* +dfa_init(GVA_Allocator const allocator, + size_t const height, size_t const width) { - fprintf(stderr, "CONCAT: " GVA_VARIANT_FMT " " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(lhs), GVA_VARIANT_PRINT(rhs)); - - size_t const width = lhs.sequence.len + rhs.sequence.len + rhs.start - lhs.end + 1; - size_t const bytes = ((rhs.end - lhs.start + 1) * width + 3) / 4; - - fprintf(stderr, "DFA %zu x %u\n", width, rhs.end - lhs.start + 1); - - uint8_t* const restrict dfa = array_init(allocator, bytes, 1); + size_t const bytes = (height * width + 3) / 4; + uint8_t* const dfa = array_init(allocator, bytes, 1); if (dfa == NULL) { - return NULL; // OOM + return NULL; // OOM; } // if + return memset(dfa, 0, bytes); +} // dfa_init - memset(dfa, 0, bytes); - - for (size_t j = 0; j <= lhs.end - lhs.start; ++j) - { - for (size_t k = 0; k <= lhs.sequence.len; ++k) - { - set(dfa, j * width + k, get(lhs_dfa, j * (lhs.sequence.len + 1) + k)); - } // for - } // for - size_t const offset_row = rhs.start - lhs.start; - size_t const offset_col = lhs.sequence.len + rhs.start - lhs.end; +uint8_t* +dfa_concat(GVA_Variant const lhs, uint8_t lhs_dfa[static restrict 1], + GVA_Variant const rhs, uint8_t const rhs_dfa[static restrict 1], + size_t const offset) +{ for (size_t j = 0; j <= rhs.end - rhs.start; ++j) { for (size_t k = 0; k <= rhs.sequence.len; ++k) { - fprintf(stderr, "cpy %zu, %zu -> %zu, %zu\n", j, k, j + offset_row, k + offset_col); - set(dfa, (j + offset_row) * width + k + offset_col, + fprintf(stderr, "cpy %zu, %zu -> %zu, %zu\n", j, k, j + rhs.start - lhs.start, k + offset); + set(lhs_dfa, (j + rhs.start - lhs.start) * (lhs.sequence.len + 1) + k + offset, get(rhs_dfa, j * (rhs.sequence.len + 1) + k)); } // for } // for - - return dfa; + return lhs_dfa; } // dfa_concat -inline uint8_t* -dfa_dup(GVA_Allocator const allocator, uint8_t const self[static restrict 1]) -{ - uint8_t* const restrict dfa = array_init(allocator, array_length(self), 1); - if (dfa == NULL) - { - return NULL; // OOM; - } // if - - return memcpy(dfa, self, array_length(self)); -} // dfa_dup - - uint8_t* dfa_from_alignment(GVA_Allocator const allocator, uint8_t* restrict dfas, size_t const len_ref, char const reference[static restrict len_ref], diff --git a/src/dfa.h b/src/dfa.h index ca089ea..60f1a1e 100644 --- a/src/dfa.h +++ b/src/dfa.h @@ -15,13 +15,14 @@ uint8_t* -dfa_concat(GVA_Allocator const allocator, - GVA_Variant const lhs, uint8_t const lhs_dfa[static restrict 1], - GVA_Variant const rhs, uint8_t const rhs_dfa[static restrict 1]); +dfa_init(GVA_Allocator const allocator, + size_t const height, size_t const width); uint8_t* -dfa_dup(GVA_Allocator const allocator, uint8_t const self[static restrict 1]); +dfa_concat(GVA_Variant const lhs, uint8_t lhs_dfa[static restrict 1], + GVA_Variant const rhs, uint8_t const rhs_dfa[static restrict 1], + size_t const offset); uint8_t* diff --git a/src/index.c b/src/index.c index 24182fe..1f24028 100644 --- a/src/index.c +++ b/src/index.c @@ -382,8 +382,6 @@ gva_index_query(GVA_Allocator const allocator, continue; } // if - uint8_t* restrict dfa = NULL; - size_t const start_hits = array_length(result.hits); for (gva_uint i = entries[idx].head; i != GVA_NULL; i = hits[i].next) { @@ -408,7 +406,6 @@ gva_index_query(GVA_Allocator const allocator, GVA_Variant const variant = gva_lcs_graph_local_supremal(graph, start, end); if (distance == 0) { - //dfa = dfa_concat(allocator, supremal, dfa, variant, supremal = gva_variant_dup(allocator, variant); } // if else @@ -457,8 +454,6 @@ gva_index_query(GVA_Allocator const allocator, entries[idx].included += included; - dfa = ARRAY_DESTROY(allocator, dfa); - continue; } // if @@ -467,39 +462,42 @@ gva_index_query(GVA_Allocator const allocator, { if (distance == 0) { - fprintf(stderr, "START w DUP\n"); ARRAY_APPEND(allocator, result.parts, hits[i].join); gva_uint const node_idx = self->join[hits[i].join].link ^ entries[idx].gva_key; supremal = gva_variant_dup(allocator, variant_from_index(self, node_idx)); - dfa = dfa_dup(allocator, dfa_from_index(self, node_idx)); distance = self->intervals.nodes[node_idx].distance; } // if i = hits[i].next; ARRAY_APPEND(allocator, result.parts, hits[i].join); gva_uint const node_idx = self->join[hits[i].join].link ^ entries[idx].gva_key; GVA_Variant const variant = variant_from_index(self, node_idx); - - dfa_dot(stderr, self->reference.len, self->reference.str, variant, dfa_from_index(self, node_idx)); - - uint8_t* concat = dfa_concat(allocator, supremal, dfa, variant, dfa_from_index(self, node_idx)); - ARRAY_DESTROY(allocator, dfa); - dfa = concat; - supremal.sequence = gva_string_concat(allocator, supremal.sequence, (GVA_String) {variant.start - supremal.end, self->reference.str + supremal.end}); supremal.sequence = gva_string_concat(allocator, supremal.sequence, variant.sequence); supremal.end = variant.end; - fprintf(stderr, GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(supremal)); - - dfa_dot(stderr, self->reference.len, self->reference.str, supremal, dfa); - distance += self->intervals.nodes[node_idx].distance; } // while if (start_parts < array_length(result.parts)) { - fprintf(stderr, "HIER!!!\n"); + fprintf(stderr, "NU: " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(supremal)); + uint8_t* restrict dfa = dfa_init(allocator, supremal.end - supremal.start + 1, supremal.sequence.len + 1); + size_t offset = 0; + GVA_Variant prev = {0}; + for (size_t j = start_parts; j < array_length(result.parts); ++j) + { + gva_uint const node_idx = self->join[result.parts[j]].link ^ entries[idx].gva_key; + GVA_Variant const variant = variant_from_index(self, node_idx); + if (j > start_parts) + { + offset += prev.sequence.len + variant.start - prev.end; + } // if + dfa = dfa_concat(supremal, dfa, variant, dfa_from_index(self, node_idx), offset); + prev = variant; + } // for + dfa_dot(stderr, self->reference.len, self->reference.str, supremal, dfa); + size_t const included = gva_compare_included(allocator, self->reference.len, self->reference.str, supremal, distance, dfa, gva_lcs_graph_local_supremal(graph, hits[i].query, hits[i].query + 1), graph.dom_nodes[hits[i].query + 1].distance - graph.dom_nodes[hits[i].query].distance, dfas + starts[hits[i].query]); From 522245351f4f41559587a24b3c16153f1c1534e1 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 19 May 2026 15:10:26 +0200 Subject: [PATCH 661/704] WIP: removed bitset; use DFAs --- include/lcs_graph.h | 11 ---- src/bitset.c | 64 --------------------- src/bitset.h | 26 --------- src/dfa.c | 16 ------ src/dfa.h | 5 -- src/index.c | 135 +++++++++----------------------------------- src/lcs_graph.c | 85 ---------------------------- 7 files changed, 26 insertions(+), 316 deletions(-) delete mode 100644 src/bitset.c delete mode 100644 src/bitset.h diff --git a/include/lcs_graph.h b/include/lcs_graph.h index c265849..884f05a 100644 --- a/include/lcs_graph.h +++ b/include/lcs_graph.h @@ -77,17 +77,6 @@ gva_lcs_graph_from_variants(GVA_Allocator const allocator, size_t const n, GVA_Variant const variants[static restrict n]); -void -gva_lcs_graph_uniq_atomics(GVA_LCS_Graph const self, - size_t const offset, - size_t const start, size_t const end, - size_t dels[static restrict 1], - size_t as[static restrict 1], - size_t cs[static restrict 1], - size_t gs[static restrict 1], - size_t ts[static restrict 1]); - - size_t gva_lcs_graph_distance(GVA_LCS_Graph const self); diff --git a/src/bitset.c b/src/bitset.c deleted file mode 100644 index 94c2867..0000000 --- a/src/bitset.c +++ /dev/null @@ -1,64 +0,0 @@ -// FIXME: __builtin_popcountll -#include // CHAR_BIT -#include // NULL, size_t -#include // memset - -#include "../include/allocator.h" // GVA_Allocator -#include "array.h" // ARRAY_*, array_* -#include "bitset.h" // bitset_* -#include "common.h" // MIN - - -inline size_t* -bitset_init(GVA_Allocator const allocator, size_t const size) -{ - size_t const len = (size + sizeof(size_t) * CHAR_BIT - 1) / (sizeof(size_t) * CHAR_BIT); - size_t* const bitset = array_init(allocator, len, sizeof(*bitset)); - if (bitset == NULL) - { - return NULL; - } // if - array_header(bitset)->length = len; - return memset(bitset, 0, len * sizeof(*bitset)); -} // bitset_init - - -inline void -bitset_add(size_t self[static 1], size_t const start, size_t const end) -{ - size_t const start_idx = start / (sizeof(*self) * CHAR_BIT); - size_t const end_idx = (end - 1) / (sizeof(*self) * CHAR_BIT); - for (size_t i = start_idx; i <= end_idx; ++i) - { - size_t mask = ~0x0ULL; - if (i == start_idx) - { - mask &= ~0x0ULL << (start % (sizeof(*self) * CHAR_BIT)); - } // if - if (i == end_idx) - { - mask &= ~0x0ULL >> (sizeof(*self) * CHAR_BIT - (end % (sizeof(*self) * CHAR_BIT))); - } // if - self[i] |= mask; - } // for -} // bitset_add - - -inline size_t -bitset_intersection_cnt(size_t const lhs[static 1], size_t const rhs[static 1]) -{ - size_t count = 0; - size_t const len = MIN(array_length(lhs), array_length(rhs)); - for (size_t i = 0; i < len; ++i) - { - count += __builtin_popcountll(lhs[i] & rhs[i]); - } // for - return count; -} // bitset_intersection_cnt - - -inline size_t* -bitset_destroy(GVA_Allocator const allocator, size_t const* const self) -{ - return ARRAY_DESTROY(allocator, self); -} // bitset_destroy diff --git a/src/bitset.h b/src/bitset.h deleted file mode 100644 index 3a61c1b..0000000 --- a/src/bitset.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef GVA_BITSET_H -#define GVA_BITSET_H - - -#include // size_t - -#include "../include/allocator.h" // GVA_Allocator - - -size_t* -bitset_init(GVA_Allocator const allocator, size_t const size); - - -void -bitset_add(size_t self[static 1], size_t const start, size_t const end); - - -size_t -bitset_intersection_cnt(size_t const lhs[static 1], size_t const rhs[static 1]); - - -size_t* -bitset_destroy(GVA_Allocator const allocator, size_t const* const self); - - -#endif // GVA_BITSET_H diff --git a/src/dfa.c b/src/dfa.c index 64ec4a3..b8b9559 100644 --- a/src/dfa.c +++ b/src/dfa.c @@ -677,22 +677,6 @@ dfa_dot(FILE* restrict const stream, } // dfa_dot -void -dfa_raw(FILE* restrict const stream, - size_t const height, size_t const width, uint8_t const dfa[static restrict height * width]) -{ - for (size_t i = 0; i < height; ++i) - { - for (size_t j = 0; j < width; ++j) - { - uint8_t const value = get(dfa, i * width + j) & 0x3; - fprintf(stream, "%x ", value); - } // for - fprintf(stream, "\n"); - } // for -} // dfa_raw - - void dfa_svg(FILE* restrict const stream, size_t const len, char const reference[static restrict len], diff --git a/src/dfa.h b/src/dfa.h index 60f1a1e..5e82df0 100644 --- a/src/dfa.h +++ b/src/dfa.h @@ -55,11 +55,6 @@ dfa_dot(FILE* restrict const stream, GVA_Variant const variant, uint8_t const dfa[static restrict 1]); -void -dfa_raw(FILE* restrict const stream, - size_t const height, size_t const width, uint8_t const dfa[static restrict height * width]); - - void dfa_svg(FILE* restrict const stream, size_t const len, char const reference[static restrict len], diff --git a/src/index.c b/src/index.c index 1f24028..52fef50 100644 --- a/src/index.c +++ b/src/index.c @@ -13,7 +13,6 @@ #include "../include/types.h" // GVA_NULL, GVA_Interval, gva_uint #include "../include/variant.h" // GVA_Variant, gva_patch, gva_variant_dup #include "array.h" // ARRAY_*, array_length -#include "bitset.h" // bitset_* #include "common.h" // ABS, MAX, MIN #include "dfa.h" // dfa_* #include "hash_table.h" // HASH_TABLE_*, hash_table_* @@ -68,111 +67,6 @@ dfa_from_index(GVA_Index const self[static 1], size_t const idx) } // dfa_from_index -// FIXME: gva_compare_included -static size_t -variants_included(GVA_Allocator const allocator, - size_t const len_ref, char const reference[static len_ref], - GVA_Variant const lhs, GVA_Variant const rhs, - size_t excluded[static 1]) -{ - size_t const start = MIN(lhs.start, rhs.start); - size_t const end = MAX(lhs.end, rhs.end); - - GVA_String observed_lhs = gva_patch(allocator, end - start, reference + start, - 1, &(GVA_Variant const) {lhs.start - start, lhs.end - start, lhs.sequence}); - GVA_String observed_rhs = gva_patch(allocator, end - start, reference + start, - 1, &(GVA_Variant const) {rhs.start - start, rhs.end - start, rhs.sequence}); - GVA_LCS_Graph lhs_graph = gva_lcs_graph_init(allocator, end - start, reference + start, observed_lhs.len, observed_lhs.str, start); - GVA_LCS_Graph rhs_graph = gva_lcs_graph_init(allocator, end - start, reference + start, observed_rhs.len, observed_rhs.str, start); - - gva_uint const len = end - start + 1; - size_t* lhs_dels = bitset_init(allocator, len); - size_t* lhs_as = bitset_init(allocator, len); - size_t* lhs_cs = bitset_init(allocator, len); - size_t* lhs_gs = bitset_init(allocator, len); - size_t* lhs_ts = bitset_init(allocator, len); - - size_t* rhs_dels = bitset_init(allocator, len); - size_t* rhs_as = bitset_init(allocator, len); - size_t* rhs_cs = bitset_init(allocator, len); - size_t* rhs_gs = bitset_init(allocator, len); - size_t* rhs_ts = bitset_init(allocator, len); - - size_t const start_intersection = MAX(lhs.start, rhs.start); - size_t const end_intersection = MIN(lhs.end, rhs.end); - - gva_lcs_graph_uniq_atomics(lhs_graph, start, start_intersection, end_intersection, lhs_dels, lhs_as, lhs_cs, lhs_gs, lhs_ts); - gva_lcs_graph_destroy(allocator, lhs_graph, false); - - gva_lcs_graph_uniq_atomics(rhs_graph, start, start_intersection, end_intersection, rhs_dels, rhs_as, rhs_cs, rhs_gs, rhs_ts); - gva_lcs_graph_destroy(allocator, rhs_graph, false); - - size_t const included = - bitset_intersection_cnt(lhs_dels, rhs_dels) + - bitset_intersection_cnt(lhs_as, rhs_as) + - bitset_intersection_cnt(lhs_cs, rhs_cs) + - bitset_intersection_cnt(lhs_gs, rhs_gs) + - bitset_intersection_cnt(lhs_ts, rhs_ts); - - *excluded = - bitset_intersection_cnt(lhs_dels, lhs_dels) + - bitset_intersection_cnt(rhs_dels, rhs_dels) + - bitset_intersection_cnt(lhs_as, lhs_as) + - bitset_intersection_cnt(rhs_as, rhs_as) + - bitset_intersection_cnt(lhs_cs, lhs_cs) + - bitset_intersection_cnt(rhs_cs, rhs_cs) + - bitset_intersection_cnt(lhs_gs, lhs_gs) + - bitset_intersection_cnt(rhs_gs, rhs_gs) + - bitset_intersection_cnt(lhs_ts, lhs_ts) + - bitset_intersection_cnt(rhs_ts, rhs_ts); - - rhs_ts = bitset_destroy(allocator, rhs_ts); - rhs_gs = bitset_destroy(allocator, rhs_gs); - rhs_cs = bitset_destroy(allocator, rhs_cs); - rhs_as = bitset_destroy(allocator, rhs_as); - rhs_dels = bitset_destroy(allocator, rhs_dels); - - lhs_ts = bitset_destroy(allocator, lhs_ts); - lhs_gs = bitset_destroy(allocator, lhs_gs); - lhs_cs = bitset_destroy(allocator, lhs_cs); - lhs_as = bitset_destroy(allocator, lhs_as); - lhs_dels = bitset_destroy(allocator, lhs_dels); - - gva_string_destroy(allocator, observed_rhs); - gva_string_destroy(allocator, observed_lhs); - - return included; -} // variants_included - - -// FIXME: gva_compare_included -static inline size_t -variants_with_distance(GVA_Allocator const allocator, - size_t const len, char const reference[static len], - GVA_Variant const lhs, size_t const distance_lhs, - GVA_Variant const rhs, size_t const distance_rhs) -{ - size_t const distance = gva_compare_distance(allocator, len, reference, lhs, rhs); - - if (distance == 0 || distance_rhs - distance_lhs == distance) - { - return distance_lhs; - } // if - if (distance_lhs - distance_rhs == distance) - { - return distance_rhs; - } // if - - size_t excluded = 0; - size_t const included = variants_included(allocator, len, reference, lhs, rhs, &excluded); - if (included == 0) - { - return 0; // disjoint - } // if - return MAX(1, (double) (2 * included - 1) / excluded * MIN(distance_lhs, distance_rhs)); -} // variants_with_distance - - inline GVA_Index* gva_index_init(GVA_Allocator const allocator, size_t const len, char const reference[static len]) @@ -400,9 +294,11 @@ gva_index_query(GVA_Allocator const allocator, ARRAY_APPEND(allocator, result.parts, hits[i].query); } // if i = hits[i].next; + fprintf(stderr, "%u\n", hits[i].query); ARRAY_APPEND(allocator, result.parts, hits[i].query); if (hits[i].query > end) { + fprintf(stderr, "HIER!\n"); GVA_Variant const variant = gva_lcs_graph_local_supremal(graph, start, end); if (distance == 0) { @@ -436,9 +332,28 @@ gva_index_query(GVA_Allocator const allocator, } // else distance += graph.dom_nodes[end].distance - graph.dom_nodes[start].distance; gva_uint const node_idx = self->join[hits[i].join].link ^ entries[idx].gva_key; - size_t const included = variants_with_distance(allocator, self->reference.len, self->reference.str, - variant_from_index(self, node_idx), self->intervals.nodes[node_idx].distance, - supremal, distance); + + fprintf(stderr, "NU2: " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(supremal)); + uint8_t* restrict dfa = dfa_init(allocator, supremal.end - supremal.start + 1, supremal.sequence.len + 1); + size_t offset = 0; + GVA_Variant prev = {0}; + + for (size_t j = start_parts; j < array_length(result.parts); ++j) + { + GVA_Variant const variant = gva_lcs_graph_local_supremal(graph, result.parts[j], result.parts[j] + 1); + if (j > start_parts) + { + offset += prev.sequence.len + variant.start - prev.end; + } // if + dfa = dfa_concat(supremal, dfa, variant, dfas + starts[result.parts[j]], offset); + prev = variant; + } // for + + dfa_dot(stderr, self->reference.len, self->reference.str, supremal, dfa); + + size_t const included = gva_compare_included(allocator, self->reference.len, self->reference.str, + variant_from_index(self, node_idx), self->intervals.nodes[node_idx].distance, dfa_from_index(self, node_idx), + supremal, distance, dfa); gva_string_destroy(allocator, supremal.sequence); size_t excluded = 0; @@ -454,6 +369,8 @@ gva_index_query(GVA_Allocator const allocator, entries[idx].included += included; + dfa = ARRAY_DESTROY(allocator, dfa); + continue; } // if diff --git a/src/lcs_graph.c b/src/lcs_graph.c index 4e45ede..2b6f131 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -11,7 +11,6 @@ #include "../include/variant.h" // GVA_Variant, gva_variant_length #include "align.h" // LCS_Alignment, LCS_Matches, lcs_align* #include "array.h" // ARRAY_*, array_length -#include "bitset.h" // bitset_add #include "common.h" // GVA_NULL, MAX, MIN, gva_uint @@ -527,90 +526,6 @@ gva_lcs_graph_from_variants(GVA_Allocator const allocator, } // gva_lcs_graph_from_variants -static uint8_t const NUC_A = 0x1; -static uint8_t const NUC_C = 0x2; -static uint8_t const NUC_G = 0x4; -static uint8_t const NUC_T = 0x8; - - -inline static uint8_t -nucleotides(size_t const len, char const sequence[static len]) -{ - static uint8_t const MASK[256] = - { - ['A'] = NUC_A, - ['C'] = NUC_C, - ['G'] = NUC_G, - ['T'] = NUC_T, - }; - static uint8_t const UNIVERSE = 0xF; - - uint8_t mask = 0x0; - for (size_t i = 0; mask < UNIVERSE && i < len; ++i) - { - mask |= MASK[(size_t) sequence[i]]; - } // for - return mask; -} // nucleotides - - -void -gva_lcs_graph_uniq_atomics(GVA_LCS_Graph const self, - size_t const offset, - size_t const start, size_t const end, - size_t dels[static restrict 1], - size_t as[static restrict 1], - size_t cs[static restrict 1], - size_t gs[static restrict 1], - size_t ts[static restrict 1]) -{ - for (size_t i = 0; i < array_length(self.nodes); ++i) - { - if (self.nodes[i].match.row > end) - { - continue; - } // if - - for (gva_uint j = self.nodes[i].edges; j != GVA_NULL; j = self.edges[j].next) - { - if (self.nodes[self.edges[j].tail].match.row + self.nodes[self.edges[j].tail].match.length < start) - { - continue; - } // if - - GVA_Variant variant; - gva_uint const count = gva_edges(self.observed.str, - self.nodes[i].match, self.nodes[self.edges[j].tail].match, - i == self.source, self.nodes[self.edges[j].tail].edges == GVA_NULL, - &variant); - - if (variant.end > variant.start) - { - bitset_add(dels, variant.start - offset, variant.end + count - 1 - offset); - } // if - - uint8_t const mask = nucleotides(variant.sequence.len, variant.sequence.str); - if ((mask & NUC_A) == NUC_A) - { - bitset_add(as, variant.start - offset, variant.end + count - offset); - } // if - if ((mask & NUC_C) == NUC_C) - { - bitset_add(cs, variant.start - offset, variant.end + count - offset); - } // if - if ((mask & NUC_G) == NUC_G) - { - bitset_add(gs, variant.start - offset, variant.end + count - offset); - } // if - if ((mask & NUC_T) == NUC_T) - { - bitset_add(ts, variant.start - offset, variant.end + count - offset); - } // if - } // for - } // for -} // gva_lcs_graph_uniq_atomics - - inline size_t gva_lcs_graph_distance(GVA_LCS_Graph const self) { From 6b5021d1476eb034a3fad58ff88a79b155117960 Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 20 May 2026 20:11:08 +0200 Subject: [PATCH 662/704] Removed a lot of DFA debug and some work on HGVS parsing --- include/parser.h | 22 ++++ include/variant.h | 5 - src/compare.c | 2 +- src/dfa.c | 36 ------ src/index.c | 9 -- src/main.c | 3 +- src/parser.c | 322 ++++++++++++++++++++++++++++++++++++++++++++++ src/variant.c | 105 +-------------- 8 files changed, 348 insertions(+), 156 deletions(-) create mode 100644 include/parser.h create mode 100644 src/parser.c diff --git a/include/parser.h b/include/parser.h new file mode 100644 index 0000000..901d035 --- /dev/null +++ b/include/parser.h @@ -0,0 +1,22 @@ +#ifndef GVA_PARSER_H +#define GVA_PARSER_H + + +#include // size + +#include "allocator.h" // GVA_Allocator +#include "variant.h" // GVA_Variant + + +GVA_Variant* +gva_parse_hgvs(GVA_Allocator const allocator, + size_t const len_ref, char const reference[static restrict len_ref], + size_t const len, char const expression[static restrict len]); + + +size_t +gva_parse_spdi(size_t const len, char const expression[static restrict len], + GVA_Variant variants[static restrict 1]); + + +#endif // GVA_PARSER_H diff --git a/include/variant.h b/include/variant.h index 606c9a8..b2a9de9 100644 --- a/include/variant.h +++ b/include/variant.h @@ -28,11 +28,6 @@ typedef struct } GVA_Variant; -size_t -gva_parse_spdi(size_t const len, char const expression[static restrict len], - GVA_Variant variants[static restrict 1]); - - bool gva_variant_eq(GVA_Variant const lhs, GVA_Variant const rhs); diff --git a/src/compare.c b/src/compare.c index 2e28077..85e8a22 100644 --- a/src/compare.c +++ b/src/compare.c @@ -46,7 +46,7 @@ gva_compare_distance(GVA_Allocator const allocator, } // gva_compare_distance -size_t +inline size_t gva_compare_included(GVA_Allocator const allocator, size_t const len, char const reference[static restrict len], GVA_Variant const lhs, size_t const lhs_distance, uint8_t lhs_dfa[static restrict 1], diff --git a/src/dfa.c b/src/dfa.c index b8b9559..a3ef97e 100644 --- a/src/dfa.c +++ b/src/dfa.c @@ -74,7 +74,6 @@ dfa_concat(GVA_Variant const lhs, uint8_t lhs_dfa[static restrict 1], { for (size_t k = 0; k <= rhs.sequence.len; ++k) { - fprintf(stderr, "cpy %zu, %zu -> %zu, %zu\n", j, k, j + rhs.start - lhs.start, k + offset); set(lhs_dfa, (j + rhs.start - lhs.start) * (lhs.sequence.len + 1) + k + offset, get(rhs_dfa, j * (rhs.sequence.len + 1) + k)); } // for @@ -258,8 +257,6 @@ dfa_from_lcs_graph(GVA_Allocator const allocator, uint8_t* dfas, gva_uint tail = head; while (head != GVA_NULL) { - //fprintf(stderr, "POP %u\n", head); - if (head == graph.dom_nodes[end].link) { head = next[head]; @@ -281,7 +278,6 @@ dfa_from_lcs_graph(GVA_Allocator const allocator, uint8_t* dfas, if (next[graph.edges[j].tail] == GVA_NULL && tail != graph.edges[j].tail) { - //fprintf(stderr, " PUSH %u\n", graph.edges[j].tail); next[tail] = graph.edges[j].tail; tail = graph.edges[j].tail; } // if @@ -429,7 +425,6 @@ dfa_overlap(GVA_Allocator const allocator, return 0; // OOM } // if - //size_t count = 0; queue_push_front(&queue, 0, 0); while (!queue_empty(&queue)) { @@ -445,9 +440,6 @@ dfa_overlap(GVA_Allocator const allocator, size_t const rhs_ref = rhs_idx / rhs_width + rhs.start; size_t const included = queue.entries[HASH_TABLE_INDEX(queue.entries, idx)].included; - //count += 1; - // fprintf(stderr, "{%zu, %zu} (%zu): %zu\n", lhs_idx, rhs_idx, idx, included); - if ((lhs_idx == 0 && rhs_ref < lhs_ref) || lhs_idx == lhs_size - 1) { uint8_t const rhs_value = get(rhs_dfa, rhs_idx); @@ -456,8 +448,6 @@ dfa_overlap(GVA_Allocator const allocator, if (rhs_match) { - // .. - // fprintf(stderr, " push (. vs %zu MU) +0 +0 {%zu, %zu} (%zu)\n", rhs_ref, lhs_idx, rhs_idx + rhs_width + 1, lhs_idx * rhs_size + rhs_idx + rhs_width + 1); queue_push_front(&queue, lhs_idx * rhs_size + rhs_idx + rhs_width + 1, included); continue; } // if @@ -467,14 +457,10 @@ dfa_overlap(GVA_Allocator const allocator, if (rhs_deletion) { - // .D - // fprintf(stderr, " push (. vs %zu DELTA) +0 +1 {%zu, %zu} (%zu)\n", rhs_ref, lhs_idx, rhs_idx + rhs_width, lhs_idx * rhs_size + rhs_idx + rhs_width); queue_push_back(&queue, lhs_idx * rhs_size + rhs_idx + rhs_width, included); } // if if (rhs_insertion) { - // .I - // fprintf(stderr, " push (. vs %zu %c) +0 +1 {%zu, %zu} (%zu)\n", rhs_ref, rhs_variant.sequence.str[rhs_idx % rhs_width], lhs_idx, rhs_idx + 1, lhs_idx * rhs_size + rhs_idx + 1); queue_push_back(&queue, lhs_idx * rhs_size + rhs_idx + 1, included); } // if continue; @@ -488,8 +474,6 @@ dfa_overlap(GVA_Allocator const allocator, if (lhs_match) { - // .. - // fprintf(stderr, " push (%zu MU vs .) +0 +0 {%zu, %zu} (%zu)\n", lhs_ref, lhs_idx + lhs_width + 1, rhs_idx, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx); queue_push_front(&queue, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx, included); continue; } // if @@ -499,14 +483,10 @@ dfa_overlap(GVA_Allocator const allocator, if (lhs_deletion) { - // D. - // fprintf(stderr, " push (%zu DELTA vs .) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, lhs_idx + lhs_width, rhs_idx, (lhs_idx + lhs_width) * rhs_size + rhs_idx); queue_push_back(&queue, (lhs_idx + lhs_width) * rhs_size + rhs_idx, included); } // if if (lhs_insertion) { - // I. - // fprintf(stderr, " push (%zu %c vs .) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, lhs_variant.sequence.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx, (lhs_idx + 1) * rhs_size + rhs_idx); queue_push_back(&queue, (lhs_idx + 1) * rhs_size + rhs_idx, included); } // if continue; @@ -521,8 +501,6 @@ dfa_overlap(GVA_Allocator const allocator, if (lhs_match && rhs_match) { - // .. - // fprintf(stderr, " push (%zu MU) {%zu, %zu} +0 +0 (%zu)\n", lhs_ref, lhs_idx + lhs_width + 1, rhs_idx + rhs_width + 1, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx + rhs_width + 1); queue_push_front(&queue, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx + rhs_width + 1, included); continue; } // if @@ -534,50 +512,36 @@ dfa_overlap(GVA_Allocator const allocator, if (lhs_deletion && rhs_deletion) { - // DD - // fprintf(stderr, " push (%zu DELTA) {%zu, %zu} +1 +0 (%zu)\n", lhs_ref, lhs_idx + lhs_width, rhs_idx + rhs_width, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width); queue_push_front(&queue, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width, included + 1); } // if if (lhs_insertion && rhs_insertion && lhs.sequence.str[lhs_idx % lhs_width] == rhs.sequence.str[rhs_idx % rhs_width]) { - // II - // fprintf(stderr, " push (%zu %c) {%zu, %zu} +1 +0 (%zu)\n", lhs_ref, lhs_variant.sequence.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx + 1, (lhs_idx + 1) * rhs_size + rhs_idx + 1); queue_push_front(&queue, (lhs_idx + 1) * rhs_size + rhs_idx + 1, included + 1); } // if if (lhs_deletion && rhs_match) { - // D. - // fprintf(stderr, " push (%zu DELTA vs %zu MU) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, rhs_ref, lhs_idx + lhs_width, rhs_idx + rhs_width + 1, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width + 1); queue_push_back(&queue, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width + 1, included); } // if else if (lhs_match && rhs_deletion) { - // .D - // fprintf(stderr, " push (%zu MU vs %zu DELTA) +0 +1 {%zu, %zu} (%zu)\n", lhs_ref, rhs_ref, lhs_idx + lhs_width + 1, rhs_idx + rhs_width, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx + rhs_width); queue_push_back(&queue, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx + rhs_width, included); } // if if (lhs_insertion && (rhs_deletion || rhs_match || (rhs_insertion && lhs.sequence.str[lhs_idx % lhs_width] != rhs.sequence.str[rhs_idx % rhs_width]))) { - // I. - // fprintf(stderr, " push (%zu %c vs .) {%zu, %zu} +0 +1 (%zu)\n", lhs_ref, lhs_variant.sequence.str[lhs_idx % lhs_width], lhs_idx + 1, rhs_idx, (lhs_idx + 1) * rhs_size + rhs_idx); queue_push_back(&queue, (lhs_idx + 1) * rhs_size + rhs_idx, included); } // if if (rhs_insertion && (lhs_deletion || lhs_match || (lhs_insertion && lhs.sequence.str[lhs_idx % lhs_width] != rhs.sequence.str[rhs_idx % rhs_width]))) { - // .I - // fprintf(stderr, " push (. vs %zu %c) {%zu, %zu} +0 +1 (%zu)\n", rhs_ref, rhs_variant.sequence.str[rhs_idx % rhs_width], lhs_idx, rhs_idx + 1, lhs_idx * rhs_size + rhs_idx + 1); queue_push_back(&queue, lhs_idx * rhs_size + rhs_idx + 1, included); } // if } // while - //fprintf(stderr, "count: %zu\n", count); - size_t included = 0; size_t const idx = HASH_TABLE_INDEX(queue.entries, lhs_size * rhs_size - 1); if (queue.entries[idx].gva_key == lhs_size * rhs_size - 1) diff --git a/src/index.c b/src/index.c index 52fef50..cdc998e 100644 --- a/src/index.c +++ b/src/index.c @@ -294,11 +294,9 @@ gva_index_query(GVA_Allocator const allocator, ARRAY_APPEND(allocator, result.parts, hits[i].query); } // if i = hits[i].next; - fprintf(stderr, "%u\n", hits[i].query); ARRAY_APPEND(allocator, result.parts, hits[i].query); if (hits[i].query > end) { - fprintf(stderr, "HIER!\n"); GVA_Variant const variant = gva_lcs_graph_local_supremal(graph, start, end); if (distance == 0) { @@ -333,11 +331,9 @@ gva_index_query(GVA_Allocator const allocator, distance += graph.dom_nodes[end].distance - graph.dom_nodes[start].distance; gva_uint const node_idx = self->join[hits[i].join].link ^ entries[idx].gva_key; - fprintf(stderr, "NU2: " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(supremal)); uint8_t* restrict dfa = dfa_init(allocator, supremal.end - supremal.start + 1, supremal.sequence.len + 1); size_t offset = 0; GVA_Variant prev = {0}; - for (size_t j = start_parts; j < array_length(result.parts); ++j) { GVA_Variant const variant = gva_lcs_graph_local_supremal(graph, result.parts[j], result.parts[j] + 1); @@ -349,8 +345,6 @@ gva_index_query(GVA_Allocator const allocator, prev = variant; } // for - dfa_dot(stderr, self->reference.len, self->reference.str, supremal, dfa); - size_t const included = gva_compare_included(allocator, self->reference.len, self->reference.str, variant_from_index(self, node_idx), self->intervals.nodes[node_idx].distance, dfa_from_index(self, node_idx), supremal, distance, dfa); @@ -397,7 +391,6 @@ gva_index_query(GVA_Allocator const allocator, } // while if (start_parts < array_length(result.parts)) { - fprintf(stderr, "NU: " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(supremal)); uint8_t* restrict dfa = dfa_init(allocator, supremal.end - supremal.start + 1, supremal.sequence.len + 1); size_t offset = 0; GVA_Variant prev = {0}; @@ -413,8 +406,6 @@ gva_index_query(GVA_Allocator const allocator, prev = variant; } // for - dfa_dot(stderr, self->reference.len, self->reference.str, supremal, dfa); - size_t const included = gva_compare_included(allocator, self->reference.len, self->reference.str, supremal, distance, dfa, gva_lcs_graph_local_supremal(graph, hits[i].query, hits[i].query + 1), graph.dom_nodes[hits[i].query + 1].distance - graph.dom_nodes[hits[i].query].distance, dfas + starts[hits[i].query]); diff --git a/src/main.c b/src/main.c index 8d08a41..be44b5f 100644 --- a/src/main.c +++ b/src/main.c @@ -10,10 +10,11 @@ #include "../include/index.h" // GVA_Index, gva_index_*, GVA_Query_Result #include "../include/lcs_graph.h" // GVA_LCS_Graph, gva_lcs_graph_* #include "../include/relations.h" // GVA_RELATION_LABELS +#include "../include/parser.h" // gva_parse_spdi #include "../include/std_alloc.h" // gva_std_allocator #include "../include/string.h" // GVA_String, gva_string_destroy #include "../include/utils.h" // gva_fasta_sequence* -#include "../include/variant.h" // GVA_VARIANT_*, GVA_Variant, gva_parse_spdi, gva_patch, gva_variant_* +#include "../include/variant.h" // GVA_VARIANT_*, GVA_Variant, gva_patch, gva_variant_* #include "array.h" // ARRAY_*, array_length #include "common.h" // MAX, MIN #include "dfa.h" // dfa_* diff --git a/src/parser.c b/src/parser.c new file mode 100644 index 0000000..8edd2cd --- /dev/null +++ b/src/parser.c @@ -0,0 +1,322 @@ +#include // bool +#include // size_t +#include // memcmp + +#include "../include/allocator.h" // GVA_Allocator +#include "../include/parser.h" // gva_parse_* +#include "../include/string.h" // GVA_String +#include "../include/types.h" // gva_uint +#include "../include/variant.h" // GVA_Variant + + +#include // FIXME: DEBUG + + +static inline bool +is_digit(char const ch) +{ + return ch >= '0' && ch <= '9'; +} // is_digit + + +static inline bool +is_dna_nucleotide(char const ch) +{ + return ch == 'A' || ch == 'C' || ch == 'G' || ch == 'T'; +} // is_dna_nucleotide + + +static inline size_t +match(size_t const len, char const expression[static restrict len], + char const word[static restrict 1]) +{ + size_t idx = 0; + while (idx < len && expression[idx] == word[idx]) + { + idx += 1; + } // while + return word[idx] == '\0' ? idx : 0; +} // match + + +static inline size_t +match_number(size_t const len, char const expression[static restrict len], + gva_uint value[static restrict 1]) +{ + size_t idx = 0; + while (idx < len && is_digit(expression[idx])) + { + *value = *value * 10 + expression[idx] - '0'; // OVERFLOW + idx += 1; + } // while + return idx; +} // match_number + + +static inline size_t +match_location(size_t const len, char const expression[static restrict len], + gva_uint start[static restrict 1], gva_uint end[static restrict 1]) +{ + size_t idx = match_number(len, expression, start); + if (idx == 0) + { + return 0; // expected number + } // if + + *end = *start; + *start -= 1; + if (idx < len && expression[idx] == '_') + { + idx += 1; // '_' + *end = 0; + size_t const tok = match_number(len - idx, expression + idx, end); + if (tok == 0) + { + return 0; // expected number + } // if + idx += tok; + } // if + + return idx; +} // match_location + + +static inline size_t +match_sequence(size_t const len, char const expression[static len]) +{ + size_t idx = 0; + while (idx < len && is_dna_nucleotide(expression[idx])) + { + idx += 1; + } // while + return idx; +} // match_sequence + + +static inline size_t +match_until(size_t const len, char const expression[static len], char const delim) +{ + size_t idx = 0; + while (idx < len && expression[idx] != delim) + { + idx += 1; + } // while + return idx < len && expression[idx] == delim ? idx : 0; +} // match_until + + +static size_t +match_variant(size_t const len_ref, char const reference[static restrict len_ref], + size_t const len, char const expression[static restrict len], + GVA_Variant variant[static restrict 1]) +{ + size_t idx = match_location(len, expression, &variant->start, &variant->end); + if (idx == 0) + { + return 0; // expected location + } // if + + size_t tok = 0; + if ((tok = match(len - idx, expression + idx, "dup"))) + { + idx += tok; // "dup" + if (variant->end <= variant->start) + { + return 0; // invalid range + } // if + + tok = match_sequence(len - idx, expression + idx); + if (tok) + { + if (tok != variant->end - variant->start) + { + return 0; // inconsistent deleted length + } // if + if (memcmp(reference + variant->start, expression + idx, tok) != 0) + { + return 0; // sequence not found in reference + } // if + idx += tok; + } // if + + variant->sequence = (GVA_String) {variant->end - variant->start, reference + variant->start}; + return idx; + } // if + + if ((tok = match(len - idx, expression + idx, "del"))) + { + idx += tok; // "del" + if (variant->end <= variant->start) + { + return 0; // invalid range + } // if + + tok = match_sequence(len - idx, expression + idx); + if (tok) + { + if (tok != variant->end - variant->start) + { + return 0; // inconsistent deleted length + } // if + if (memcmp(reference + variant->start, expression + idx, tok) != 0) + { + return 0; // sequence not found in reference + } // if + idx += tok; + } // if + + if ((tok = match(len - idx, expression + idx, "ins"))) + { + idx += tok; // "ins" + tok = match_sequence(len - idx, expression + idx); + if (tok == 0) + { + return 0; // missing insertion + } // if + variant->sequence = (GVA_String) {tok, expression + idx}; + idx += tok; + } // if + return idx; + } // if + + if ((tok = match(len - idx, expression + idx, "ins"))) + { + idx += tok; // "ins" + tok = match_sequence(len - idx, expression + idx); + if (tok == 0) + { + return 0; // missing insertion + } // if + variant->sequence = (GVA_String) {tok, expression + idx}; + idx += tok; + return idx; + } // if + + if ((tok = match_sequence(len - idx, expression + idx))) + { + if (tok != variant->end - variant->start) + { + return 0; // inconsistent deleted length + } // if + if (memcmp(reference + variant->start, expression + idx, tok) != 0) + { + return 0; // sequence not found in reference + } // if + idx += tok; + } // if + + if (expression[idx] == '>') + { + idx += 1; // '>' + tok = match_sequence(len - idx, expression + idx); + if (tok == 0) + { + return 0; // missing insertion + } // if + variant->sequence = (GVA_String) {tok, expression + idx}; + idx += tok; + return idx; + } // if + + if (expression[idx] == '=') + { + idx += 1; // '=' + return idx; + } // if + + return 0; // unexpected variant type +} // match_variant + + +GVA_Variant* +gva_parse_hgvs(GVA_Allocator const allocator, + size_t const len_ref, char const reference[static restrict len_ref], + size_t const len, char const expression[static restrict len]) +{ + // reference sequence identifier + size_t idx = match_until(len, expression, ':'); + if (idx >= len) + { + return NULL; // expected ':' + } // if + idx += 1; // ':' + + // optional "g." + idx += match(len - idx, expression + idx, "g."); + if (idx >= len) + { + return NULL; // expected variant + } // if + + if (expression[idx] == '=') + { + return NULL; // empty variant + } // if + + if (expression[idx] == '[') + { + // TODO + return NULL; + } // if + + GVA_Variant variant = {0}; + size_t const tok = match_variant(len_ref, reference, len - idx, expression + idx, &variant); + fprintf(stderr, "HIER %zu\n", tok); + + if (tok == 0 || idx + tok != len) + { + return NULL; // expected variant + } // if + + return NULL; +} // gva_parse_hgvs + + +size_t +gva_parse_spdi(size_t const len, char const expression[static restrict len], + GVA_Variant variants[static restrict 1]) +{ + variants[0] = (GVA_Variant) {0}; + // reference sequence identifier + size_t idx = match_until(len, expression, ':'); + if (idx >= len) + { + return 0; // expected ':' + } // if + idx += 1; // ':' + + size_t tok = match_number(len - idx, expression + idx, &variants[0].start); + if (tok == 0) + { + return 0; // expected number (location) + } // if + idx += tok; + + if (idx >= len || expression[idx] != ':') + { + return 0; // expected ':' + } // if + idx += 1; + + tok = match_number(len - idx, expression + idx, &variants[0].end); + if (tok == 0) + { + tok = match_sequence(len - idx, expression + idx); + variants[0].end = tok; // OVERFLOW + } // if + idx += tok; + variants[0].end += variants[0].start; + + if (idx >= len || expression[idx] != ':') + { + return 0; // expected ':' + } // if + idx += 1; + + variants[0].sequence.str = expression + idx; + tok = match_sequence(len - idx, expression + idx); + variants[0].sequence.len = tok; + idx += tok; + + return idx == len; +} // gva_parse_spdi diff --git a/src/variant.c b/src/variant.c index 9c4f98f..cc75f25 100644 --- a/src/variant.c +++ b/src/variant.c @@ -3,114 +3,11 @@ #include // memcmp, memcpy #include "../include/allocator.h" // GVA_Allocator -#include "../include/types.h" // gva_uint #include "../include/string.h" // GVA_String, gva_string_*, gva_prefix_length -#include "../include/variant.h" // gva_parse_spdi, gva_patch +#include "../include/variant.h" // gva_patch, gva_variant_*, #include "common.h" // MIN -static inline bool -is_digit(char const ch) -{ - return ch >= '0' && ch <= '9'; -} // is_digit - - -static inline bool -is_dna_nucleotide(char const ch) -{ - return ch == 'A' || ch == 'C' || ch == 'G' || ch == 'T'; -} // is_dna_nucleotide - - -static size_t -match_number(size_t const len, char const expression[static restrict len], - gva_uint* const restrict num) -{ - size_t idx = 0; - while (idx < len && is_digit(expression[idx])) - { - *num = *num * 10 + expression[idx] - '0'; // OVERFLOW - idx += 1; - } // while - return idx; -} // match_number - - -static size_t -match_sequence(size_t const len, char const expression[static len]) -{ - size_t idx = 0; - while (idx < len && is_dna_nucleotide(expression[idx])) - { - idx += 1; - } // while - return idx; -} // match_sequence - - -static size_t -match_until(size_t const len, char const expression[static len], char const delim) -{ - size_t idx = 0; - while (idx < len && expression[idx] != delim) - { - idx += 1; - } // while - return idx < len && expression[idx] == delim ? idx : 0; -} // match_until - - -size_t -gva_parse_spdi(size_t const len, char const expression[static restrict len], - GVA_Variant variants[static restrict 1]) -{ - variants[0] = (GVA_Variant) {0}; - // sequence - size_t idx = match_until(len, expression, ':'); - if (idx >= len) - { - return 0; // expected ':' - } // if - idx += 1; // ':' - - size_t tok = match_number(len - idx, expression + idx, &variants[0].start); - if (tok == 0) - { - return 0; // expected number (location) - } // if - idx += tok; - - if (idx >= len || expression[idx] != ':') - { - return 0; // expected ':' - } // if - idx += 1; - - tok = match_number(len - idx, expression + idx, &variants[0].end); - if (tok == 0) - { - tok = match_sequence(len - idx, expression + idx); - variants[0].end = tok; // OVERFLOW - } // if - idx += tok; - variants[0].end += variants[0].start; - - if (idx >= len || expression[idx] != ':') - { - return 0; // expected ':' - } // if - idx += 1; - - variants[0].sequence.str = expression + idx; - tok = match_sequence(len - idx, expression + idx); - variants[0].sequence.len = tok; - idx += tok; - - return idx == len; -} // gva_parse_spdi - - inline bool gva_variant_eq(GVA_Variant const lhs, GVA_Variant const rhs) { From 4f1c952866083c6e201334f39797da6d33eb07fc Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 20 May 2026 20:14:20 +0200 Subject: [PATCH 663/704] Added hits for disjoint only --- src/compare.c | 1 + src/index.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/compare.c b/src/compare.c index 85e8a22..0022c65 100644 --- a/src/compare.c +++ b/src/compare.c @@ -63,6 +63,7 @@ gva_compare_included(GVA_Allocator const allocator, return rhs_distance; } // if + //return !dfa_disjoint(lhs, lhs_dfa, rhs, rhs_dfa); return dfa_overlap(allocator, len, reference, lhs, lhs_dfa, rhs, rhs_dfa); } // gva_compare_included diff --git a/src/index.c b/src/index.c index cdc998e..f0c96f1 100644 --- a/src/index.c +++ b/src/index.c @@ -436,6 +436,8 @@ gva_index_query(GVA_Allocator const allocator, // non-distance based if (ABS((intmax_t) self->intervals.nodes[node_idx].distance - (intmax_t) distance) != hits[i].distance) { + //size_t const included = !dfa_disjoint(variant_from_index(self, node_idx), dfa_from_index(self, node_idx), + // gva_lcs_graph_local_supremal(graph, hits[i].query, hits[i].query + 1), dfas + starts[hits[i].query]); size_t const included = dfa_overlap(allocator, self->reference.len, self->reference.str, variant_from_index(self, node_idx), dfa_from_index(self, node_idx), gva_lcs_graph_local_supremal(graph, hits[i].query, hits[i].query + 1), dfas + starts[hits[i].query]); From 4008086c1f20adcad9aa64c94df0f6378ed32214 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 21 May 2026 14:34:30 +0200 Subject: [PATCH 664/704] WIP: HGVS parser --- include/parser.h | 15 +- src/main.c | 54 ++++- src/parser.c | 548 ++++++++++++++++++++++++++++++++++++++--------- 3 files changed, 516 insertions(+), 101 deletions(-) diff --git a/include/parser.h b/include/parser.h index 901d035..74056cc 100644 --- a/include/parser.h +++ b/include/parser.h @@ -2,13 +2,26 @@ #define GVA_PARSER_H +#include // bool #include // size #include "allocator.h" // GVA_Allocator #include "variant.h" // GVA_Variant -GVA_Variant* +typedef struct +{ + GVA_Variant* restrict variants; + char* restrict inserted; + bool interpretable; +} GVA_HGVS_Allele; + + +char +gva_complement(char const ch); + + +GVA_HGVS_Allele gva_parse_hgvs(GVA_Allocator const allocator, size_t const len_ref, char const reference[static restrict len_ref], size_t const len, char const expression[static restrict len]); diff --git a/src/main.c b/src/main.c index be44b5f..b2cdf44 100644 --- a/src/main.c +++ b/src/main.c @@ -779,11 +779,63 @@ all_main(int argc, char* argv[static argc]) } // all_main +int +hgvs_main(int argc, char* argv[static argc]) +{ + if (argc < 2) + { + fprintf(stderr, "usage %s reference.blob\n", argv[0]); + return EXIT_FAILURE; + } // if + + errno = 0; + FILE* stream = fopen(argv[1], "r"); + if (stream == NULL) + { + fprintf(stderr, "error: %s\n", strerror(errno)); + return EXIT_FAILURE; + } // if + + GVA_String reference = {0}; + reference = gva_fasta_sequence_blob(gva_std_allocator, stream); + fclose(stream); + + fprintf(stderr, "reference length: %zu\n", reference.len); + + size_t line_count = 0; + static char line[LINE_SIZE] = {0}; + while (fgets(line, sizeof(line), stdin) != NULL) + { + line_count += 1; + GVA_HGVS_Allele allele = gva_parse_hgvs(gva_std_allocator, reference.len, reference.str, strlen(line) - 1, line); + + if (!allele.interpretable) + { + fprintf(stderr, "%zu: ERROR\n", line_count); + continue; + } // if + + for (size_t i = 0; i < array_length(allele.variants); ++i) + { + fprintf(stdout, "%zu: " GVA_VARIANT_FMT "\n", line_count, GVA_VARIANT_PRINT(allele.variants[i])); + } // for + + ARRAY_DESTROY(gva_std_allocator, allele.variants); + ARRAY_DESTROY(gva_std_allocator, allele.inserted); + } //while + + gva_string_destroy(gva_std_allocator, reference); + + return EXIT_SUCCESS; +} // hgvs_main + + int main(int argc, char* argv[static argc]) { + return hgvs_main(argc, argv); // return allele_main(argc, argv); - return index_main(argc, argv); + // return index_main(argc, argv); // return supremal_main(argc, argv); // return overlap_main(argc, argv); // return all_main(argc, argv); diff --git a/src/parser.c b/src/parser.c index 8edd2cd..aadbdfc 100644 --- a/src/parser.c +++ b/src/parser.c @@ -1,12 +1,13 @@ -#include // bool -#include // size_t -#include // memcmp +#include // bool, true +#include // NULL, size_t +#include // memcmp, mempcy #include "../include/allocator.h" // GVA_Allocator -#include "../include/parser.h" // gva_parse_* +#include "../include/parser.h" // GVA_HGVS_Allele, gva_parse_* #include "../include/string.h" // GVA_String #include "../include/types.h" // gva_uint #include "../include/variant.h" // GVA_Variant +#include "array.h" // ARRAY_*, array_* #include // FIXME: DEBUG @@ -26,16 +27,39 @@ is_dna_nucleotide(char const ch) } // is_dna_nucleotide +inline char +gva_complement(char const ch) +{ + if (ch == 'A') + { + return 'T'; + } // if + if (ch == 'C') + { + return 'G'; + } // if + if (ch == 'G') + { + return 'C'; + } // if + if (ch == 'T') + { + return 'A'; + } // if + return ch; +} // gva_complement + + static inline size_t match(size_t const len, char const expression[static restrict len], - char const word[static restrict 1]) + size_t const len_word, char const word[static restrict len_word]) { size_t idx = 0; - while (idx < len && expression[idx] == word[idx]) + while (idx < len && idx < len_word && expression[idx] == word[idx]) { idx += 1; } // while - return word[idx] == '\0' ? idx : 0; + return idx == len_word ? idx : 0; } // match @@ -53,222 +77,548 @@ match_number(size_t const len, char const expression[static restrict len], } // match_number +static inline size_t +match_sequence(size_t const len, char const expression[static len]) +{ + size_t idx = 0; + while (idx < len && is_dna_nucleotide(expression[idx])) + { + idx += 1; + } // while + return idx; +} // match_sequence + + +static inline size_t +match_until(size_t const len, char const expression[static len], char const delim) +{ + size_t idx = 0; + while (idx < len && expression[idx] != delim) + { + idx += 1; + } // while + return idx < len && expression[idx] == delim ? idx : 0; +} // match_until + + static inline size_t match_location(size_t const len, char const expression[static restrict len], gva_uint start[static restrict 1], gva_uint end[static restrict 1]) { - size_t idx = match_number(len, expression, start); - if (idx == 0) + size_t idx = 0; + size_t tok = 0; + + if (!(tok = match_number(len - idx, expression + idx, start))) { - return 0; // expected number + fprintf(stderr, "expected number\n"); + return 0; } // if + idx += tok; *end = *start; - *start -= 1; + if (*start > 0) + { + *start -= 1; + } // if if (idx < len && expression[idx] == '_') { idx += 1; // '_' *end = 0; - size_t const tok = match_number(len - idx, expression + idx, end); - if (tok == 0) + if (!(tok = match_number(len - idx, expression + idx, end))) { - return 0; // expected number + fprintf(stderr, "expected number\n"); + return 0; + } // if + if (*end < *start) + { + fprintf(stderr, "invalid range\n"); + return 0; } // if idx += tok; } // if - return idx; } // match_location -static inline size_t -match_sequence(size_t const len, char const expression[static len]) +static size_t +match_inserted_part(GVA_Allocator const allocator, + GVA_HGVS_Allele allele[static restrict 1], + size_t const len, char const expression[static restrict len]) { size_t idx = 0; - while (idx < len && is_dna_nucleotide(expression[idx])) + size_t tok = 0; + + if (!(tok = match_sequence(len - idx, expression + idx))) { - idx += 1; - } // while + fprintf(stderr, "expected sequence\n"); + return 0; // expected sequence + } // if + GVA_String const sequence = {tok, expression + idx}; + idx += tok; + + if (idx < len && expression[idx] == '[') + { + idx += 1; // '[' + gva_uint count = 0; + + if (!(tok = match_number(len - idx, expression + idx, &count))) + { + fprintf(stderr, "expected number\n"); + return 0; // expected number + } // if + idx += tok; + + if (idx < len && expression[idx] == ']') + { + idx += 1; // ']' + + if (count > 0) + { + allele->inserted = array_ensure(allocator, allele->inserted, 1, sequence.len * count); // OVERFLOW + for (gva_uint i = 0; i < count; ++i) + { + memcpy(allele->inserted + array_length(allele->inserted) + i * sequence.len, sequence.str, sequence.len); + } // for + array_header(allele->inserted)->length += sequence.len * count; + } // if + return idx; + } // if + + fprintf(stderr, "expected ']'\n"); + return 0; // expected ']' + } // if + + allele->inserted = array_ensure(allocator, allele->inserted, 1, sequence.len); + memcpy(allele->inserted + array_length(allele->inserted), sequence.str, sequence.len); + array_header(allele->inserted)->length += sequence.len; + return idx; -} // match_sequence +} // match_inserted_part -static inline size_t -match_until(size_t const len, char const expression[static len], char const delim) +static size_t +match_insertion(GVA_Allocator const allocator, + GVA_HGVS_Allele allele[static restrict 1], + size_t const len, char const expression[static restrict len]) { size_t idx = 0; - while (idx < len && expression[idx] != delim) + size_t tok = 0; + + if (idx < len && expression[idx] == '[') { - idx += 1; - } // while - return idx < len && expression[idx] == delim ? idx : 0; -} // match_until + idx += 1; // '[' + while (idx < len) + { + if (!(tok = match_inserted_part(allocator, allele, len - idx, expression + idx))) + { + fprintf(stderr, "expected inserted part\n"); + return 0; // expected inserted part + } // if + idx += tok; + + if (idx < len && expression[idx] != ';') + { + break; + } // if + idx += 1; // ';' + } // while + + if (idx < len && expression[idx] == ']') + { + idx += 1; // ']' + return idx; + } // if + + fprintf(stderr, "expected ']'\n"); + return 0; // expected ']' + } // if + + if (!(tok = match_inserted_part(allocator, allele, len - idx, expression + idx))) + { + fprintf(stderr, "expected inserted part\n"); + return 0; // expected inserted part + } // if + idx += tok; + return idx; +} // match_insertion static size_t -match_variant(size_t const len_ref, char const reference[static restrict len_ref], +match_variant(GVA_Allocator const allocator, + GVA_HGVS_Allele allele[static restrict 1], + size_t const len_ref, char const reference[static restrict len_ref], size_t const len, char const expression[static restrict len], GVA_Variant variant[static restrict 1]) { - size_t idx = match_location(len, expression, &variant->start, &variant->end); - if (idx == 0) + size_t idx = 0; + size_t tok = 0; + + if (!(tok = match_location(len - idx, expression + idx, &variant->start, &variant->end))) { + fprintf(stderr, "expected location\n"); return 0; // expected location } // if - size_t tok = 0; - if ((tok = match(len - idx, expression + idx, "dup"))) + if (variant->end >= len_ref) + { + fprintf(stderr, "invalid location in reference\n"); + return 0; // invalid location in reference + } // if + idx += tok; + + // deletion and optionally insertion + if ((tok = match(len - idx, expression + idx, 3, "del"))) { - idx += tok; // "dup" - if (variant->end <= variant->start) + if (variant->start == variant->end) { - return 0; // invalid range + fprintf(stderr, "invalid deleted range\n"); + return 0; // invalid deleted range } // if + idx += tok; - tok = match_sequence(len - idx, expression + idx); - if (tok) + // optional sequence + if ((tok = match_sequence(len - idx, expression + idx))) { - if (tok != variant->end - variant->start) + if (variant->end - variant->start != tok) { + fprintf(stderr, "inconsistent deleted length\n"); return 0; // inconsistent deleted length } // if - if (memcmp(reference + variant->start, expression + idx, tok) != 0) + if (memcmp(reference + variant->start, expression + idx, tok)) { + fprintf(stderr, "sequence not found in reference\n"); return 0; // sequence not found in reference } // if idx += tok; } // if - variant->sequence = (GVA_String) {variant->end - variant->start, reference + variant->start}; + // optional insertion + if ((tok = match(len - idx, expression + idx, 3, "ins"))) + { + idx += tok; + size_t const start = array_length(allele->inserted); + if ((tok = match_insertion(allocator, allele, len - idx, expression + idx))) + { + idx += tok; + variant->sequence = (GVA_String) {array_length(allele->inserted) - start, allele->inserted + start}; + } // if + } // if return idx; } // if - if ((tok = match(len - idx, expression + idx, "del"))) + // duplication + if ((tok = match(len - idx, expression + idx, 3, "dup"))) { - idx += tok; // "del" - if (variant->end <= variant->start) + if (variant->start == variant->end) { - return 0; // invalid range + fprintf(stderr, "invalid duplicated range\n"); + return 0; // invalid duplicated range } // if + idx += tok; - tok = match_sequence(len - idx, expression + idx); - if (tok) + // optional sequence + if ((tok = match_sequence(len - idx, expression + idx))) { - if (tok != variant->end - variant->start) + if (variant->end - variant->start != tok) { - return 0; // inconsistent deleted length + fprintf(stderr, "inconsistent duplicated length\n"); + return 0; // inconsistent duplicated length } // if - if (memcmp(reference + variant->start, expression + idx, tok) != 0) + if (memcmp(reference + variant->start, expression + idx, tok)) { + fprintf(stderr, "sequence not found in reference\n"); return 0; // sequence not found in reference } // if idx += tok; } // if - if ((tok = match(len - idx, expression + idx, "ins"))) + size_t const length = variant->end - variant->start; + size_t const start = array_length(allele->inserted); + allele->inserted = array_ensure(allocator, allele->inserted, 1, length); + memcpy(allele->inserted + start, reference + variant->start, length); + variant->sequence = (GVA_String) {length, allele->inserted + start}; + return idx; + } // if + + // inversion + if ((tok = match(len - idx, expression + idx, 3, "inv"))) + { + if (variant->start == variant->end) + { + fprintf(stderr, "invalid inverted range\n"); + return 0; // invalid inverted range + } // if + idx += tok; + + // optional sequence + if ((tok = match_sequence(len - idx, expression + idx))) { - idx += tok; // "ins" - tok = match_sequence(len - idx, expression + idx); - if (tok == 0) + if (variant->end - variant->start != tok) { - return 0; // missing insertion + fprintf(stderr, "inconsistent inverted length\n"); + return 0; // inconsistent inverted length } // if - variant->sequence = (GVA_String) {tok, expression + idx}; + + for (size_t i = 0; i < tok; ++i) + { + if (reference[variant->end - i - 1] != gva_complement(expression[idx + i])) + { + fprintf(stderr, "complement not found in reference\n"); + return 0; // complement not found in reference + } // if + } // for + idx += tok; } // if + + size_t const length = variant->end - variant->start; + size_t const start = array_length(allele->inserted); + allele->inserted = array_ensure(allocator, allele->inserted, 1, length); + for (size_t i = 0; i < length; ++i) + { + allele->inserted[start + i] = gva_complement(reference[variant->end - i - 1]); + } // for + variant->sequence = (GVA_String) {length, allele->inserted + start}; return idx; } // if - if ((tok = match(len - idx, expression + idx, "ins"))) + // insertion + if ((tok = match(len - idx, expression + idx, 3, "ins"))) { - idx += tok; // "ins" - tok = match_sequence(len - idx, expression + idx); - if (tok == 0) + if (variant->end - variant->start > 2) { - return 0; // missing insertion + fprintf(stderr, "invalid range for insertion\n"); + return 0; // invalid range for insertion } // if - variant->sequence = (GVA_String) {tok, expression + idx}; idx += tok; + variant->end = variant->start; + + size_t const start = array_length(allele->inserted); + if ((tok = match_insertion(allocator, allele, len - idx, expression + idx))) + { + idx += tok; + variant->sequence = (GVA_String) {array_length(allele->inserted) - start, allele->inserted + start}; + } // if return idx; } // if + GVA_String sequence = {0}; + // optional sequence if ((tok = match_sequence(len - idx, expression + idx))) { - if (tok != variant->end - variant->start) - { - return 0; // inconsistent deleted length - } // if - if (memcmp(reference + variant->start, expression + idx, tok) != 0) - { - return 0; // sequence not found in reference - } // if + sequence = (GVA_String) {tok, expression + idx}; idx += tok; } // if - if (expression[idx] == '>') + // substitution + if (idx < len && expression[idx] == '>') { idx += 1; // '>' - tok = match_sequence(len - idx, expression + idx); - if (tok == 0) + + if (sequence.len > 0) { - return 0; // missing insertion + if (sequence.len != variant->end - variant->start) + { + fprintf(stderr, "inconsistent sequence length\n"); + return 0; // inconsistent sequence length + } // if + if (memcmp(reference + variant->start, sequence.str, sequence.len)) + { + fprintf(stderr, "sequence not found in reference\n"); + return 0; // sequence not found in reference + } // if + } // if + + size_t const start = array_length(allele->inserted); + if (!(tok = match_inserted_part(allocator, allele, len - idx, expression + idx))) + { + fprintf(stderr, "expected inserted part\n"); + return 0; // expected inserted part } // if - variant->sequence = (GVA_String) {tok, expression + idx}; idx += tok; + variant->sequence = (GVA_String) {array_length(allele->inserted) - start, allele->inserted + start}; return idx; } // if - if (expression[idx] == '=') + // empty variant + if (idx < len && expression[idx] == '=') { idx += 1; // '=' + size_t const length = variant->end - variant->start; + size_t const start = array_length(allele->inserted); + allele->inserted = array_ensure(allocator, allele->inserted, 1, length); + memcpy(allele->inserted + start, reference + variant->start, length); + variant->sequence = (GVA_String) {length, allele->inserted + start}; return idx; } // if - return 0; // unexpected variant type + // repeats + if (idx < len && expression[idx] == '[') + { + idx += 1; // '[' + + variant->end -= 1; + if (sequence.len == 0) + { + fprintf(stderr, "expected sequence\n"); + return 0; // expected sequence + } // if + + gva_uint count = 0; + if (!(tok = match_number(len - idx, expression + idx, &count))) + { + fprintf(stderr, "expected number\n"); + return 0; // expected number + } // if + idx += tok; + + if (idx < len && expression[idx] == ']') + { + idx += 1; // ']' + // NCBI style repeat + if (variant->end - variant->start == 0) + { + size_t found = 0; + while (match(len_ref - variant->start + found * sequence.len, reference + variant->start + found * sequence.len, sequence.len, sequence.str)) + { + found += 1; + } // while + if (found == 0) + { + fprintf(stderr, "sequence not found in reference\n"); + return 0; // sequence not found in reference + } // if + variant->end = variant->start + found * sequence.len; + + size_t const start = array_length(allele->inserted); + if (count > 0) + { + allele->inserted = array_ensure(allocator, allele->inserted, 1, sequence.len * count); // OVERFLOW + for (gva_uint i = 0; i < count; ++i) + { + memcpy(allele->inserted + array_length(allele->inserted) + i * sequence.len, sequence.str, sequence.len); + } // for + array_header(allele->inserted)->length += sequence.len * count; + } // if + variant->sequence = (GVA_String) {sequence.len * count, allele->inserted + start}; + return idx; + } // if + + size_t const start = array_length(allele->inserted); + if (count > 0) + { + allele->inserted = array_ensure(allocator, allele->inserted, 1, sequence.len * count); // OVERFLOW + for (gva_uint i = 0; i < count; ++i) + { + memcpy(allele->inserted + array_length(allele->inserted) + i * sequence.len, sequence.str, sequence.len); + } // for + array_header(allele->inserted)->length += sequence.len * count; + } // if + variant->sequence = (GVA_String) {sequence.len * count, allele->inserted + start}; + return idx; + } // if + + fprintf(stderr, "expected ']'\n"); + return 0; // expected ']' + } // if + + fprintf(stderr, "unsupported variant\n"); + return 0; // unsupported variant } // match_variant -GVA_Variant* +GVA_HGVS_Allele gva_parse_hgvs(GVA_Allocator const allocator, size_t const len_ref, char const reference[static restrict len_ref], size_t const len, char const expression[static restrict len]) { - // reference sequence identifier - size_t idx = match_until(len, expression, ':'); - if (idx >= len) + size_t idx = 0; + size_t tok = 0; + + // optional reference sequence identifier + if ((tok = match_until(len - idx, expression + idx, ':'))) { - return NULL; // expected ':' + idx += tok + 1; // ':'; } // if - idx += 1; // ':' // optional "g." - idx += match(len - idx, expression + idx, "g."); - if (idx >= len) - { - return NULL; // expected variant - } // if + idx += match(len - idx, expression + idx, 2, "g."); - if (expression[idx] == '=') + // empty variant + if (idx < len && expression[idx] == '=') { - return NULL; // empty variant + idx += 1; // '=' + if (idx == len) + { + return (GVA_HGVS_Allele) {.interpretable = true}; + } // if + + fprintf(stderr, "expected end of expression\n"); + return (GVA_HGVS_Allele) {NULL}; } // if - if (expression[idx] == '[') + GVA_HGVS_Allele allele = {NULL}; + + // allele + if (idx < len && expression[idx] == '[') { - // TODO - return NULL; + idx += 1; // '[' + + while (idx < len) + { + GVA_Variant variant = {0}; + if ((tok = match_variant(allocator, &allele, len_ref, reference, len - idx, expression + idx, &variant))) + { + idx += tok; + ARRAY_APPEND(allocator, allele.variants, variant); + } // if + + if (idx < len && expression[idx] != ';') + { + break; + } // if + idx += 1; // ';' + } // while + + if (idx < len && expression[idx] == ']') + { + idx += 1; // ']' + if (idx == len) + { + allele.interpretable = true; + return allele; + } // if + + allele.variants = ARRAY_DESTROY(allocator, allele.variants); + allele.inserted = ARRAY_DESTROY(allocator, allele.inserted); + fprintf(stderr, "expected end of expression\n"); + return (GVA_HGVS_Allele) {NULL}; // expected end of expression + } // if + + allele.variants = ARRAY_DESTROY(allocator, allele.variants); + allele.inserted = ARRAY_DESTROY(allocator, allele.inserted); + fprintf(stderr, "expected ']'\n"); + return (GVA_HGVS_Allele) {NULL}; // expected ']' } // if + // single variant GVA_Variant variant = {0}; - size_t const tok = match_variant(len_ref, reference, len - idx, expression + idx, &variant); - fprintf(stderr, "HIER %zu\n", tok); - - if (tok == 0 || idx + tok != len) + if ((tok = match_variant(allocator, &allele, len_ref, reference, len - idx, expression + idx, &variant))) { - return NULL; // expected variant + idx += tok; + if (idx == len) + { + ARRAY_APPEND(allocator, allele.variants, variant); + allele.interpretable = true; + return allele; + } // if + + fprintf(stderr, "expected end of expression\n"); + return (GVA_HGVS_Allele) {NULL}; } // if - return NULL; + fprintf(stderr, "expected variant\n"); + return (GVA_HGVS_Allele) {NULL}; // expected variant } // gva_parse_hgvs From 97ed2c0458a696ec62600c1aada4048bb5f6f965 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 21 May 2026 16:04:41 +0200 Subject: [PATCH 665/704] WIP: testing the HGVS parser with dbsnp and clinvar --- src/main.c | 4 +- src/parser.c | 104 ++++++++++++++++++++++++++++++--------------------- 2 files changed, 63 insertions(+), 45 deletions(-) diff --git a/src/main.c b/src/main.c index b2cdf44..330c213 100644 --- a/src/main.c +++ b/src/main.c @@ -811,13 +811,13 @@ hgvs_main(int argc, char* argv[static argc]) if (!allele.interpretable) { - fprintf(stderr, "%zu: ERROR\n", line_count); + fprintf(stdout, "%zu: ERROR: %s", line_count, line); continue; } // if for (size_t i = 0; i < array_length(allele.variants); ++i) { - fprintf(stdout, "%zu: " GVA_VARIANT_FMT "\n", line_count, GVA_VARIANT_PRINT(allele.variants[i])); + // fprintf(stdout, "%zu: " GVA_VARIANT_FMT "\n", line_count, GVA_VARIANT_PRINT(allele.variants[i])); } // for ARRAY_DESTROY(gva_std_allocator, allele.variants); diff --git a/src/parser.c b/src/parser.c index aadbdfc..0e553cd 100644 --- a/src/parser.c +++ b/src/parser.c @@ -110,7 +110,7 @@ match_location(size_t const len, char const expression[static restrict len], if (!(tok = match_number(len - idx, expression + idx, start))) { - fprintf(stderr, "expected number\n"); + //fprintf(stderr, "expected number\n"); return 0; } // if idx += tok; @@ -126,12 +126,12 @@ match_location(size_t const len, char const expression[static restrict len], *end = 0; if (!(tok = match_number(len - idx, expression + idx, end))) { - fprintf(stderr, "expected number\n"); + //fprintf(stderr, "expected number\n"); return 0; } // if if (*end < *start) { - fprintf(stderr, "invalid range\n"); + //fprintf(stderr, "invalid range\n"); return 0; } // if idx += tok; @@ -150,7 +150,7 @@ match_inserted_part(GVA_Allocator const allocator, if (!(tok = match_sequence(len - idx, expression + idx))) { - fprintf(stderr, "expected sequence\n"); + //fprintf(stderr, "expected sequence\n"); return 0; // expected sequence } // if GVA_String const sequence = {tok, expression + idx}; @@ -163,7 +163,7 @@ match_inserted_part(GVA_Allocator const allocator, if (!(tok = match_number(len - idx, expression + idx, &count))) { - fprintf(stderr, "expected number\n"); + //fprintf(stderr, "expected number\n"); return 0; // expected number } // if idx += tok; @@ -184,7 +184,7 @@ match_inserted_part(GVA_Allocator const allocator, return idx; } // if - fprintf(stderr, "expected ']'\n"); + //fprintf(stderr, "expected ']'\n"); return 0; // expected ']' } // if @@ -211,7 +211,7 @@ match_insertion(GVA_Allocator const allocator, { if (!(tok = match_inserted_part(allocator, allele, len - idx, expression + idx))) { - fprintf(stderr, "expected inserted part\n"); + //fprintf(stderr, "expected inserted part\n"); return 0; // expected inserted part } // if idx += tok; @@ -229,13 +229,13 @@ match_insertion(GVA_Allocator const allocator, return idx; } // if - fprintf(stderr, "expected ']'\n"); + //fprintf(stderr, "expected ']'\n"); return 0; // expected ']' } // if if (!(tok = match_inserted_part(allocator, allele, len - idx, expression + idx))) { - fprintf(stderr, "expected inserted part\n"); + //fprintf(stderr, "expected inserted part\n"); return 0; // expected inserted part } // if idx += tok; @@ -255,13 +255,13 @@ match_variant(GVA_Allocator const allocator, if (!(tok = match_location(len - idx, expression + idx, &variant->start, &variant->end))) { - fprintf(stderr, "expected location\n"); + //fprintf(stderr, "expected location\n"); return 0; // expected location } // if if (variant->end >= len_ref) { - fprintf(stderr, "invalid location in reference\n"); + //fprintf(stderr, "invalid location in reference\n"); return 0; // invalid location in reference } // if idx += tok; @@ -271,22 +271,33 @@ match_variant(GVA_Allocator const allocator, { if (variant->start == variant->end) { - fprintf(stderr, "invalid deleted range\n"); + //fprintf(stderr, "invalid deleted range\n"); return 0; // invalid deleted range } // if idx += tok; + // optional number + gva_uint count = 0; + if ((tok = match_number(len - idx, expression + idx, &count))) + { + idx += tok; + if (count != variant->end - variant->start) + { + //fprintf(stderr, "inconsistent deleted length\n"); + return 0; // inconsistent deleted length + } // if + } // if // optional sequence - if ((tok = match_sequence(len - idx, expression + idx))) + else if ((tok = match_sequence(len - idx, expression + idx))) { if (variant->end - variant->start != tok) { - fprintf(stderr, "inconsistent deleted length\n"); + //fprintf(stderr, "inconsistent deleted length\n"); return 0; // inconsistent deleted length } // if if (memcmp(reference + variant->start, expression + idx, tok)) { - fprintf(stderr, "sequence not found in reference\n"); + //fprintf(stderr, "sequence not found in reference\n"); return 0; // sequence not found in reference } // if idx += tok; @@ -300,9 +311,10 @@ match_variant(GVA_Allocator const allocator, if ((tok = match_insertion(allocator, allele, len - idx, expression + idx))) { idx += tok; - variant->sequence = (GVA_String) {array_length(allele->inserted) - start, allele->inserted + start}; + variant->sequence = (GVA_String) {array_length(allele->inserted) - start, (void*) start}; } // if } // if + return idx; } // if @@ -311,7 +323,7 @@ match_variant(GVA_Allocator const allocator, { if (variant->start == variant->end) { - fprintf(stderr, "invalid duplicated range\n"); + //fprintf(stderr, "invalid duplicated range\n"); return 0; // invalid duplicated range } // if idx += tok; @@ -321,12 +333,12 @@ match_variant(GVA_Allocator const allocator, { if (variant->end - variant->start != tok) { - fprintf(stderr, "inconsistent duplicated length\n"); + //fprintf(stderr, "inconsistent duplicated length\n"); return 0; // inconsistent duplicated length } // if if (memcmp(reference + variant->start, expression + idx, tok)) { - fprintf(stderr, "sequence not found in reference\n"); + //fprintf(stderr, "sequence not found in reference\n"); return 0; // sequence not found in reference } // if idx += tok; @@ -336,7 +348,7 @@ match_variant(GVA_Allocator const allocator, size_t const start = array_length(allele->inserted); allele->inserted = array_ensure(allocator, allele->inserted, 1, length); memcpy(allele->inserted + start, reference + variant->start, length); - variant->sequence = (GVA_String) {length, allele->inserted + start}; + variant->sequence = (GVA_String) {length, (void*) start}; return idx; } // if @@ -345,7 +357,7 @@ match_variant(GVA_Allocator const allocator, { if (variant->start == variant->end) { - fprintf(stderr, "invalid inverted range\n"); + //fprintf(stderr, "invalid inverted range\n"); return 0; // invalid inverted range } // if idx += tok; @@ -355,7 +367,7 @@ match_variant(GVA_Allocator const allocator, { if (variant->end - variant->start != tok) { - fprintf(stderr, "inconsistent inverted length\n"); + //fprintf(stderr, "inconsistent inverted length\n"); return 0; // inconsistent inverted length } // if @@ -363,7 +375,7 @@ match_variant(GVA_Allocator const allocator, { if (reference[variant->end - i - 1] != gva_complement(expression[idx + i])) { - fprintf(stderr, "complement not found in reference\n"); + //fprintf(stderr, "complement not found in reference\n"); return 0; // complement not found in reference } // if } // for @@ -378,7 +390,7 @@ match_variant(GVA_Allocator const allocator, { allele->inserted[start + i] = gva_complement(reference[variant->end - i - 1]); } // for - variant->sequence = (GVA_String) {length, allele->inserted + start}; + variant->sequence = (GVA_String) {length, (void*) start}; return idx; } // if @@ -387,7 +399,7 @@ match_variant(GVA_Allocator const allocator, { if (variant->end - variant->start > 2) { - fprintf(stderr, "invalid range for insertion\n"); + //fprintf(stderr, "invalid range for insertion\n"); return 0; // invalid range for insertion } // if idx += tok; @@ -397,7 +409,7 @@ match_variant(GVA_Allocator const allocator, if ((tok = match_insertion(allocator, allele, len - idx, expression + idx))) { idx += tok; - variant->sequence = (GVA_String) {array_length(allele->inserted) - start, allele->inserted + start}; + variant->sequence = (GVA_String) {array_length(allele->inserted) - start, (void*) start}; } // if return idx; } // if @@ -419,12 +431,12 @@ match_variant(GVA_Allocator const allocator, { if (sequence.len != variant->end - variant->start) { - fprintf(stderr, "inconsistent sequence length\n"); + //fprintf(stderr, "inconsistent sequence length\n"); return 0; // inconsistent sequence length } // if if (memcmp(reference + variant->start, sequence.str, sequence.len)) { - fprintf(stderr, "sequence not found in reference\n"); + //fprintf(stderr, "sequence not found in reference\n"); return 0; // sequence not found in reference } // if } // if @@ -432,11 +444,11 @@ match_variant(GVA_Allocator const allocator, size_t const start = array_length(allele->inserted); if (!(tok = match_inserted_part(allocator, allele, len - idx, expression + idx))) { - fprintf(stderr, "expected inserted part\n"); + //fprintf(stderr, "expected inserted part\n"); return 0; // expected inserted part } // if idx += tok; - variant->sequence = (GVA_String) {array_length(allele->inserted) - start, allele->inserted + start}; + variant->sequence = (GVA_String) {array_length(allele->inserted) - start, (void*) start}; return idx; } // if @@ -448,7 +460,7 @@ match_variant(GVA_Allocator const allocator, size_t const start = array_length(allele->inserted); allele->inserted = array_ensure(allocator, allele->inserted, 1, length); memcpy(allele->inserted + start, reference + variant->start, length); - variant->sequence = (GVA_String) {length, allele->inserted + start}; + variant->sequence = (GVA_String) {length, (void*) start}; return idx; } // if @@ -460,14 +472,14 @@ match_variant(GVA_Allocator const allocator, variant->end -= 1; if (sequence.len == 0) { - fprintf(stderr, "expected sequence\n"); + //fprintf(stderr, "expected sequence\n"); return 0; // expected sequence } // if gva_uint count = 0; if (!(tok = match_number(len - idx, expression + idx, &count))) { - fprintf(stderr, "expected number\n"); + //fprintf(stderr, "expected number\n"); return 0; // expected number } // if idx += tok; @@ -485,7 +497,7 @@ match_variant(GVA_Allocator const allocator, } // while if (found == 0) { - fprintf(stderr, "sequence not found in reference\n"); + //fprintf(stderr, "sequence not found in reference\n"); return 0; // sequence not found in reference } // if variant->end = variant->start + found * sequence.len; @@ -500,7 +512,7 @@ match_variant(GVA_Allocator const allocator, } // for array_header(allele->inserted)->length += sequence.len * count; } // if - variant->sequence = (GVA_String) {sequence.len * count, allele->inserted + start}; + variant->sequence = (GVA_String) {sequence.len * count, (void*) start}; return idx; } // if @@ -514,15 +526,15 @@ match_variant(GVA_Allocator const allocator, } // for array_header(allele->inserted)->length += sequence.len * count; } // if - variant->sequence = (GVA_String) {sequence.len * count, allele->inserted + start}; + variant->sequence = (GVA_String) {sequence.len * count, (void*) start}; return idx; } // if - fprintf(stderr, "expected ']'\n"); + //fprintf(stderr, "expected ']'\n"); return 0; // expected ']' } // if - fprintf(stderr, "unsupported variant\n"); + //fprintf(stderr, "unsupported variant\n"); return 0; // unsupported variant } // match_variant @@ -553,7 +565,7 @@ gva_parse_hgvs(GVA_Allocator const allocator, return (GVA_HGVS_Allele) {.interpretable = true}; } // if - fprintf(stderr, "expected end of expression\n"); + //fprintf(stderr, "expected end of expression\n"); return (GVA_HGVS_Allele) {NULL}; } // if @@ -585,19 +597,23 @@ gva_parse_hgvs(GVA_Allocator const allocator, idx += 1; // ']' if (idx == len) { + for (size_t i = 0; i < array_length(allele.variants); ++i) + { + allele.variants[i].sequence.str = allele.inserted + (size_t) allele.variants[i].sequence.str; + } // for allele.interpretable = true; return allele; } // if allele.variants = ARRAY_DESTROY(allocator, allele.variants); allele.inserted = ARRAY_DESTROY(allocator, allele.inserted); - fprintf(stderr, "expected end of expression\n"); + //fprintf(stderr, "expected end of expression\n"); return (GVA_HGVS_Allele) {NULL}; // expected end of expression } // if allele.variants = ARRAY_DESTROY(allocator, allele.variants); allele.inserted = ARRAY_DESTROY(allocator, allele.inserted); - fprintf(stderr, "expected ']'\n"); + //fprintf(stderr, "expected ']'\n"); return (GVA_HGVS_Allele) {NULL}; // expected ']' } // if @@ -608,16 +624,18 @@ gva_parse_hgvs(GVA_Allocator const allocator, idx += tok; if (idx == len) { + variant.sequence.str = allele.inserted + (size_t) variant.sequence.str; ARRAY_APPEND(allocator, allele.variants, variant); allele.interpretable = true; return allele; } // if - fprintf(stderr, "expected end of expression\n"); + allele.inserted = ARRAY_DESTROY(allocator, allele.inserted); + //fprintf(stderr, "expected end of expression\n"); return (GVA_HGVS_Allele) {NULL}; } // if - fprintf(stderr, "expected variant\n"); + //fprintf(stderr, "expected variant\n"); return (GVA_HGVS_Allele) {NULL}; // expected variant } // gva_parse_hgvs From 1fd0c35548af8452f2d7a4ffbbcb7a52848ee435 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 21 May 2026 19:35:00 +0200 Subject: [PATCH 666/704] FIX (questionable) NCBI repeats --- src/parser.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/parser.c b/src/parser.c index 0e553cd..0e7f397 100644 --- a/src/parser.c +++ b/src/parser.c @@ -495,11 +495,6 @@ match_variant(GVA_Allocator const allocator, { found += 1; } // while - if (found == 0) - { - //fprintf(stderr, "sequence not found in reference\n"); - return 0; // sequence not found in reference - } // if variant->end = variant->start + found * sequence.len; size_t const start = array_length(allele->inserted); From c9d15be91f682e138a99d2ea4985b5af40f283b7 Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 22 May 2026 09:48:17 +0200 Subject: [PATCH 667/704] SPDI parsing like HGVS --- include/parser.h | 2 +- src/main.c | 26 ++++++++++++++------ src/parser.c | 63 +++++++++++++++++++++++++++--------------------- 3 files changed, 56 insertions(+), 35 deletions(-) diff --git a/include/parser.h b/include/parser.h index 74056cc..17504ea 100644 --- a/include/parser.h +++ b/include/parser.h @@ -29,7 +29,7 @@ gva_parse_hgvs(GVA_Allocator const allocator, size_t gva_parse_spdi(size_t const len, char const expression[static restrict len], - GVA_Variant variants[static restrict 1]); + GVA_Variant variant[static restrict 1]); #endif // GVA_PARSER_H diff --git a/src/main.c b/src/main.c index 330c213..45984b0 100644 --- a/src/main.c +++ b/src/main.c @@ -807,21 +807,33 @@ hgvs_main(int argc, char* argv[static argc]) while (fgets(line, sizeof(line), stdin) != NULL) { line_count += 1; - GVA_HGVS_Allele allele = gva_parse_hgvs(gva_std_allocator, reference.len, reference.str, strlen(line) - 1, line); - if (!allele.interpretable) + size_t idx = 0; + size_t tok = 0; + + tok = strcspn(line + idx, "\t "); + idx += tok + 1; // ignore identifier + + tok = strcspn(line + idx, "\t "); + GVA_Variant variant = {0}; + if (gva_parse_spdi(tok, line + idx, &variant) == 0) { - fprintf(stdout, "%zu: ERROR: %s", line_count, line); + fprintf(stderr, "%zu: ERROR SPDI: %s", line_count, line); continue; } // if + idx += tok + 1; - for (size_t i = 0; i < array_length(allele.variants); ++i) + tok = strcspn(line + idx, "\n\t "); + GVA_HGVS_Allele allele = gva_parse_hgvs(gva_std_allocator, reference.len, reference.str, tok, line + idx ); + if (!allele.interpretable) { - // fprintf(stdout, "%zu: " GVA_VARIANT_FMT "\n", line_count, GVA_VARIANT_PRINT(allele.variants[i])); - } // for + fprintf(stderr, "%zu: ERROR HGVS: %s", line_count, line); + continue; + } // if + idx += tok + 1; - ARRAY_DESTROY(gva_std_allocator, allele.variants); ARRAY_DESTROY(gva_std_allocator, allele.inserted); + ARRAY_DESTROY(gva_std_allocator, allele.variants); } //while gva_string_destroy(gva_std_allocator, reference); diff --git a/src/parser.c b/src/parser.c index 0e7f397..aa4f014 100644 --- a/src/parser.c +++ b/src/parser.c @@ -111,7 +111,7 @@ match_location(size_t const len, char const expression[static restrict len], if (!(tok = match_number(len - idx, expression + idx, start))) { //fprintf(stderr, "expected number\n"); - return 0; + return 0; // expected number } // if idx += tok; @@ -127,12 +127,12 @@ match_location(size_t const len, char const expression[static restrict len], if (!(tok = match_number(len - idx, expression + idx, end))) { //fprintf(stderr, "expected number\n"); - return 0; + return 0; // expected number } // if if (*end < *start) { //fprintf(stderr, "invalid range\n"); - return 0; + return 0; // invalid range } // if idx += tok; } // if @@ -600,14 +600,14 @@ gva_parse_hgvs(GVA_Allocator const allocator, return allele; } // if - allele.variants = ARRAY_DESTROY(allocator, allele.variants); allele.inserted = ARRAY_DESTROY(allocator, allele.inserted); + allele.variants = ARRAY_DESTROY(allocator, allele.variants); //fprintf(stderr, "expected end of expression\n"); return (GVA_HGVS_Allele) {NULL}; // expected end of expression } // if - allele.variants = ARRAY_DESTROY(allocator, allele.variants); allele.inserted = ARRAY_DESTROY(allocator, allele.inserted); + allele.variants = ARRAY_DESTROY(allocator, allele.variants); //fprintf(stderr, "expected ']'\n"); return (GVA_HGVS_Allele) {NULL}; // expected ']' } // if @@ -637,21 +637,23 @@ gva_parse_hgvs(GVA_Allocator const allocator, size_t gva_parse_spdi(size_t const len, char const expression[static restrict len], - GVA_Variant variants[static restrict 1]) + GVA_Variant variant[static restrict 1]) { - variants[0] = (GVA_Variant) {0}; - // reference sequence identifier - size_t idx = match_until(len, expression, ':'); - if (idx >= len) + size_t idx = 0; + size_t tok = 0; + + // optional reference sequence identifier + if ((tok = match_until(len - idx, expression + idx, ':'))) { - return 0; // expected ':' + idx += tok + 1; // ':'; } // if - idx += 1; // ':' - size_t tok = match_number(len - idx, expression + idx, &variants[0].start); - if (tok == 0) + *variant = (GVA_Variant) {0}; + + // start position + if (!(tok = match_number(len - idx, expression + idx, &variant->start))) { - return 0; // expected number (location) + return 0; // expected number } // if idx += tok; @@ -659,16 +661,20 @@ gva_parse_spdi(size_t const len, char const expression[static restrict len], { return 0; // expected ':' } // if - idx += 1; + idx += 1; // ':' - tok = match_number(len - idx, expression + idx, &variants[0].end); - if (tok == 0) + // optional deleted length + if ((tok = match_number(len - idx, expression + idx, &variant->end))) { - tok = match_sequence(len - idx, expression + idx); - variants[0].end = tok; // OVERFLOW + idx += tok; } // if - idx += tok; - variants[0].end += variants[0].start; + // optional deleted sequence + else if ((tok = match_sequence(len - idx, expression + idx))) + { + idx += tok; + variant->end = tok; // OVERFLOW + } // if + variant->end += variant->start; // OVERFLOW if (idx >= len || expression[idx] != ':') { @@ -676,10 +682,13 @@ gva_parse_spdi(size_t const len, char const expression[static restrict len], } // if idx += 1; - variants[0].sequence.str = expression + idx; - tok = match_sequence(len - idx, expression + idx); - variants[0].sequence.len = tok; - idx += tok; + // optional inserted sequence + if ((tok = match_sequence(len - idx, expression + idx))) + { + variant->sequence.str = expression + idx; + variant->sequence.len = tok; + idx += tok; + } // if - return idx == len; + return idx == len ? idx : 0; } // gva_parse_spdi From ae1feecf4acdf053b16a9d22787c5048b8b9acb3 Mon Sep 17 00:00:00 2001 From: jkvis Date: Sat, 23 May 2026 21:43:07 +0200 Subject: [PATCH 668/704] WIP: more HGVS --- include/extractor.h | 1 + src/main.c | 82 +++++++++++++++++++++++++++++++++++++++++++++ src/parser.c | 41 ++--------------------- 3 files changed, 85 insertions(+), 39 deletions(-) diff --git a/include/extractor.h b/include/extractor.h index 59c1a77..2d9c07b 100644 --- a/include/extractor.h +++ b/include/extractor.h @@ -4,6 +4,7 @@ #include "allocator.h" // GVA_Allocator #include "lcs_graph.h" // GVA_LCS_Graph +#include "variant.h" // GVA_Variant GVA_Variant* diff --git a/src/main.c b/src/main.c index 45984b0..e3b7e38 100644 --- a/src/main.c +++ b/src/main.c @@ -31,6 +31,88 @@ #define REFERENCE_ID "NC_000001.11" +static inline size_t +hgvs_location(size_t const len, char buffer[static len], + size_t const start, size_t const end) +{ + if (end - start == 0) + { + return snprintf(buffer, len, "%zu_%zu", start, start + 1); + } // if + if (end - start == 1) + { + return snprintf(buffer, len, "%zu", start + 1); + } // if + return snprintf(buffer, len, "%zu_%zu", start + 1, end); +} // hgvs_location + + +static size_t +hgvs_variant(size_t const len, char buffer[static len], + size_t const len_ref, char const reference[static restrict len_ref], + GVA_Variant const variant) +{ + size_t idx = hgvs_location(len, buffer, variant.start, variant.end); + + if (variant.end - variant.start == 0) + { + if (variant.sequence.len == 0) + { + return idx + snprintf(buffer + idx, len - idx, "="); + } // if + return idx + snprintf(buffer + idx, len - idx, "ins" GVA_STRING_FMT, GVA_STRING_PRINT(variant.sequence)); + } // if + + if (variant.end - variant.start == 1) + { + if (variant.sequence.len == 0) + { + return idx + snprintf(buffer + idx, len - idx, "del"); + } // if + if (variant.sequence.len == 1) + { + return idx + snprintf(buffer + idx, len - idx, "%c>" GVA_STRING_FMT, reference[variant.start], GVA_STRING_PRINT(variant.sequence)); + } // if + return idx + snprintf(buffer + idx, len - idx, "delins" GVA_STRING_FMT, GVA_STRING_PRINT(variant.sequence)); + } // if + + if (variant.sequence.len == 0) + { + return idx + snprintf(buffer + idx, len - idx, "del"); + } // if + + return idx + snprintf(buffer + idx, len - idx, "delins" GVA_STRING_FMT, GVA_STRING_PRINT(variant.sequence)); +} // hgvs_variant + + +static size_t +to_hgvs(size_t const len, char buffer[static len], + size_t const len_ref, char const reference[static restrict len_ref], + size_t const n, GVA_Variant const variants[static restrict n]) +{ + if (n == 0) + { + return snprintf(buffer, len, "="); + } // if + + if (n == 1) + { + return hgvs_variant(len, buffer, len_ref, reference, variants[0]); + } // if + + size_t idx = snprintf(buffer, len, "["); + for (size_t i = 0; i < n; ++i) + { + idx += hgvs_variant(len - idx, buffer + idx, len_ref, reference, variants[i]); + if (i < n - 1) + { + idx += snprintf(buffer + idx, len - idx, ";"); + } // if + } // for + return idx + snprintf(buffer + idx, len - idx, "]"); +} // to_hgvs + + // line: alphanumeric_id SPDI [distance] static bool parse_line(char const line[static restrict LINE_SIZE], diff --git a/src/parser.c b/src/parser.c index aa4f014..1ad71d7 100644 --- a/src/parser.c +++ b/src/parser.c @@ -10,9 +10,6 @@ #include "array.h" // ARRAY_*, array_* -#include // FIXME: DEBUG - - static inline bool is_digit(char const ch) { @@ -110,7 +107,6 @@ match_location(size_t const len, char const expression[static restrict len], if (!(tok = match_number(len - idx, expression + idx, start))) { - //fprintf(stderr, "expected number\n"); return 0; // expected number } // if idx += tok; @@ -126,12 +122,10 @@ match_location(size_t const len, char const expression[static restrict len], *end = 0; if (!(tok = match_number(len - idx, expression + idx, end))) { - //fprintf(stderr, "expected number\n"); return 0; // expected number } // if if (*end < *start) { - //fprintf(stderr, "invalid range\n"); return 0; // invalid range } // if idx += tok; @@ -150,7 +144,6 @@ match_inserted_part(GVA_Allocator const allocator, if (!(tok = match_sequence(len - idx, expression + idx))) { - //fprintf(stderr, "expected sequence\n"); return 0; // expected sequence } // if GVA_String const sequence = {tok, expression + idx}; @@ -163,7 +156,6 @@ match_inserted_part(GVA_Allocator const allocator, if (!(tok = match_number(len - idx, expression + idx, &count))) { - //fprintf(stderr, "expected number\n"); return 0; // expected number } // if idx += tok; @@ -184,7 +176,6 @@ match_inserted_part(GVA_Allocator const allocator, return idx; } // if - //fprintf(stderr, "expected ']'\n"); return 0; // expected ']' } // if @@ -211,7 +202,6 @@ match_insertion(GVA_Allocator const allocator, { if (!(tok = match_inserted_part(allocator, allele, len - idx, expression + idx))) { - //fprintf(stderr, "expected inserted part\n"); return 0; // expected inserted part } // if idx += tok; @@ -229,13 +219,11 @@ match_insertion(GVA_Allocator const allocator, return idx; } // if - //fprintf(stderr, "expected ']'\n"); return 0; // expected ']' } // if if (!(tok = match_inserted_part(allocator, allele, len - idx, expression + idx))) { - //fprintf(stderr, "expected inserted part\n"); return 0; // expected inserted part } // if idx += tok; @@ -255,13 +243,11 @@ match_variant(GVA_Allocator const allocator, if (!(tok = match_location(len - idx, expression + idx, &variant->start, &variant->end))) { - //fprintf(stderr, "expected location\n"); return 0; // expected location } // if if (variant->end >= len_ref) { - //fprintf(stderr, "invalid location in reference\n"); return 0; // invalid location in reference } // if idx += tok; @@ -271,7 +257,6 @@ match_variant(GVA_Allocator const allocator, { if (variant->start == variant->end) { - //fprintf(stderr, "invalid deleted range\n"); return 0; // invalid deleted range } // if idx += tok; @@ -283,7 +268,6 @@ match_variant(GVA_Allocator const allocator, idx += tok; if (count != variant->end - variant->start) { - //fprintf(stderr, "inconsistent deleted length\n"); return 0; // inconsistent deleted length } // if } // if @@ -292,12 +276,10 @@ match_variant(GVA_Allocator const allocator, { if (variant->end - variant->start != tok) { - //fprintf(stderr, "inconsistent deleted length\n"); return 0; // inconsistent deleted length } // if if (memcmp(reference + variant->start, expression + idx, tok)) { - //fprintf(stderr, "sequence not found in reference\n"); return 0; // sequence not found in reference } // if idx += tok; @@ -323,7 +305,6 @@ match_variant(GVA_Allocator const allocator, { if (variant->start == variant->end) { - //fprintf(stderr, "invalid duplicated range\n"); return 0; // invalid duplicated range } // if idx += tok; @@ -333,12 +314,10 @@ match_variant(GVA_Allocator const allocator, { if (variant->end - variant->start != tok) { - //fprintf(stderr, "inconsistent duplicated length\n"); return 0; // inconsistent duplicated length } // if if (memcmp(reference + variant->start, expression + idx, tok)) { - //fprintf(stderr, "sequence not found in reference\n"); return 0; // sequence not found in reference } // if idx += tok; @@ -357,7 +336,6 @@ match_variant(GVA_Allocator const allocator, { if (variant->start == variant->end) { - //fprintf(stderr, "invalid inverted range\n"); return 0; // invalid inverted range } // if idx += tok; @@ -367,7 +345,6 @@ match_variant(GVA_Allocator const allocator, { if (variant->end - variant->start != tok) { - //fprintf(stderr, "inconsistent inverted length\n"); return 0; // inconsistent inverted length } // if @@ -375,7 +352,6 @@ match_variant(GVA_Allocator const allocator, { if (reference[variant->end - i - 1] != gva_complement(expression[idx + i])) { - //fprintf(stderr, "complement not found in reference\n"); return 0; // complement not found in reference } // if } // for @@ -399,7 +375,6 @@ match_variant(GVA_Allocator const allocator, { if (variant->end - variant->start > 2) { - //fprintf(stderr, "invalid range for insertion\n"); return 0; // invalid range for insertion } // if idx += tok; @@ -431,12 +406,10 @@ match_variant(GVA_Allocator const allocator, { if (sequence.len != variant->end - variant->start) { - //fprintf(stderr, "inconsistent sequence length\n"); return 0; // inconsistent sequence length } // if if (memcmp(reference + variant->start, sequence.str, sequence.len)) { - //fprintf(stderr, "sequence not found in reference\n"); return 0; // sequence not found in reference } // if } // if @@ -444,7 +417,6 @@ match_variant(GVA_Allocator const allocator, size_t const start = array_length(allele->inserted); if (!(tok = match_inserted_part(allocator, allele, len - idx, expression + idx))) { - //fprintf(stderr, "expected inserted part\n"); return 0; // expected inserted part } // if idx += tok; @@ -472,14 +444,12 @@ match_variant(GVA_Allocator const allocator, variant->end -= 1; if (sequence.len == 0) { - //fprintf(stderr, "expected sequence\n"); return 0; // expected sequence } // if gva_uint count = 0; if (!(tok = match_number(len - idx, expression + idx, &count))) { - //fprintf(stderr, "expected number\n"); return 0; // expected number } // if idx += tok; @@ -525,11 +495,9 @@ match_variant(GVA_Allocator const allocator, return idx; } // if - //fprintf(stderr, "expected ']'\n"); return 0; // expected ']' } // if - //fprintf(stderr, "unsupported variant\n"); return 0; // unsupported variant } // match_variant @@ -560,8 +528,7 @@ gva_parse_hgvs(GVA_Allocator const allocator, return (GVA_HGVS_Allele) {.interpretable = true}; } // if - //fprintf(stderr, "expected end of expression\n"); - return (GVA_HGVS_Allele) {NULL}; + return (GVA_HGVS_Allele) {NULL}; // expected end of expression } // if GVA_HGVS_Allele allele = {NULL}; @@ -602,13 +569,11 @@ gva_parse_hgvs(GVA_Allocator const allocator, allele.inserted = ARRAY_DESTROY(allocator, allele.inserted); allele.variants = ARRAY_DESTROY(allocator, allele.variants); - //fprintf(stderr, "expected end of expression\n"); return (GVA_HGVS_Allele) {NULL}; // expected end of expression } // if allele.inserted = ARRAY_DESTROY(allocator, allele.inserted); allele.variants = ARRAY_DESTROY(allocator, allele.variants); - //fprintf(stderr, "expected ']'\n"); return (GVA_HGVS_Allele) {NULL}; // expected ']' } // if @@ -626,11 +591,9 @@ gva_parse_hgvs(GVA_Allocator const allocator, } // if allele.inserted = ARRAY_DESTROY(allocator, allele.inserted); - //fprintf(stderr, "expected end of expression\n"); - return (GVA_HGVS_Allele) {NULL}; + return (GVA_HGVS_Allele) {NULL}; // expected end of expression } // if - //fprintf(stderr, "expected variant\n"); return (GVA_HGVS_Allele) {NULL}; // expected variant } // gva_parse_hgvs From f4982d3143b7bb919fd90cfacdb5075bc8430656 Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 26 May 2026 08:44:00 +0200 Subject: [PATCH 669/704] WIP: HGVS printing and come cleanup --- include/index.h | 7 ++++ include/types.h | 14 +++----- src/extractor.c | 91 +++++++++++++++++++++++++++++++++++++------------ src/main.c | 53 ++++++++++++++++++++++++++++ 4 files changed, 133 insertions(+), 32 deletions(-) diff --git a/include/index.h b/include/index.h index 50783eb..afd7151 100644 --- a/include/index.h +++ b/include/index.h @@ -14,6 +14,13 @@ typedef struct GVA_Index GVA_Index; // opaque +typedef struct +{ + gva_uint start; + gva_uint end; +} GVA_Interval; + + typedef struct { gva_uint idx; diff --git a/include/types.h b/include/types.h index 7d85ce3..7ca6248 100644 --- a/include/types.h +++ b/include/types.h @@ -6,27 +6,21 @@ #include // uint32_t, UINT32_MAX +// Print format specifier for the `gva_uint` type. #define GVA_UINT_FMT "%" PRIu32 // An unsigned integer type to store any position on a reference -// sequence. For human DNA a 32-bit value is enough. +// sequence. For human DNA a 32-bit value is sufficient. // Smaller integer types reduce storage requirements. typedef uint32_t gva_uint; -// The maximum value for the `gva_uint` type. +// The maximum value for the `gva_uint` type. Used as NIL pointer in +// indexed structures as well as for unused/invalid elements. static gva_uint const GVA_NULL = UINT32_MAX; -typedef struct -{ - gva_uint start; - gva_uint end; -} GVA_Interval; - - - typedef struct { gva_uint row; diff --git a/src/extractor.c b/src/extractor.c index 18c5d9b..0931ff5 100644 --- a/src/extractor.c +++ b/src/extractor.c @@ -2,7 +2,7 @@ #include "../include/extractor.h" // gva_canonical #include "../include/lcs_graph.h" // GVA_LCS_Graph, gva_edges -#include "../include/types.h" // GVA_NULL, GVA_Match, gva_uint +#include "../include/types.h" // GVA_NULL, gva_uint #include "array.h" // ARRAY_APPEND, array_length #include "common.h" // MAX, MIN @@ -20,7 +20,7 @@ typedef struct static inline gva_uint -lca(gva_uint* const start, +lca(gva_uint start[static 1], gva_uint lhs, gva_uint rhs, size_t const length, LCA_Table const visited[static length]) { @@ -51,20 +51,30 @@ gva_canonical(GVA_Allocator const allocator, GVA_LCS_Graph const graph) LCA_Table* visited = allocator.allocate(allocator.context, NULL, 0, sizeof(*visited) * length); if (visited == NULL) { - return NULL; + return NULL; // OOM } // if - for (gva_uint i = 0; i < length; ++i) + for (size_t i = 0; i < length; ++i) { visited[i].depth = GVA_NULL; } // for gva_uint sink = GVA_NULL; - visited[graph.source] = (LCA_Table) {GVA_NULL, 0, 0, GVA_NULL, GVA_NULL, GVA_NULL, GVA_NULL}; + visited[graph.source] = (LCA_Table) + { + .lca = GVA_NULL, + .rank = 0, + .depth = 0, + .start = GVA_NULL, + .end = GVA_NULL, + .prev = GVA_NULL, + .next = GVA_NULL, + }; gva_uint rank = 1; // main loop over a queue for (gva_uint head = graph.source, tail = graph.source; head != GVA_NULL; head = visited[head].next) { + // sink if (graph.nodes[head].edges == GVA_NULL) { sink = head; @@ -78,7 +88,16 @@ gva_canonical(GVA_Allocator const allocator, GVA_LCS_Graph const graph) { // add lambda in stack order visited[visited[head].next].prev = lambda; - visited[lambda] = (LCA_Table) {head, rank, visited[head].depth, GVA_NULL, GVA_NULL, head, visited[head].next}; + visited[lambda] = (LCA_Table) + { + .lca = head, + .rank = rank, + .depth = visited[head].depth, + .start = GVA_NULL, + .end = GVA_NULL, + .prev = head, + .next = visited[head].next, + }; rank += 1; visited[head].next = lambda; } // if @@ -88,7 +107,16 @@ gva_canonical(GVA_Allocator const allocator, GVA_LCS_Graph const graph) } // if else if (visited[head].next == lambda) { - visited[lambda] = (LCA_Table) {head, visited[lambda].rank, visited[head].depth, GVA_NULL, GVA_NULL, visited[lambda].prev, visited[lambda].next}; + visited[lambda] = (LCA_Table) + { + .lca = head, + .rank = visited[lambda].rank, + .depth = visited[head].depth, + .start = GVA_NULL, + .end = GVA_NULL, + .prev = visited[lambda].prev, + .next = visited[lambda].next, + }; } // if else { @@ -102,7 +130,16 @@ gva_canonical(GVA_Allocator const allocator, GVA_LCS_Graph const graph) } // else visited[visited[head].next].prev = lambda; visited[visited[lambda].prev].next = visited[lambda].next; - visited[lambda] = (LCA_Table) {head, visited[lambda].rank, visited[head].depth, GVA_NULL, GVA_NULL, head, visited[head].next}; + visited[lambda] = (LCA_Table) + { + .lca = head, + .rank = visited[lambda].rank, + .depth = visited[head].depth, + .start = GVA_NULL, + .end = GVA_NULL, + .prev = head, + .next = visited[head].next, + }; visited[head].next = lambda; } // else } // if @@ -116,9 +153,18 @@ gva_canonical(GVA_Allocator const allocator, GVA_LCS_Graph const graph) GVA_Variant variant; gva_uint const count = gva_edges(graph.observed.str, graph.nodes[head].match, graph.nodes[edge_tail].match, - head == graph.source, edge_tail == 0, + head == graph.source, graph.nodes[edge_tail].edges == GVA_NULL, &variant); - visited[edge_tail] = (LCA_Table) {head, rank, visited[head].depth + 1, variant.start, variant.end + count - 1, tail, GVA_NULL}; + visited[edge_tail] = (LCA_Table) + { + .lca = head, + .rank = rank, + .depth = visited[head].depth + 1, + .start = variant.start, + .end = variant.end + count - 1, + .prev = tail, + .next = GVA_NULL, + }; rank += 1; visited[tail].next = edge_tail; tail = edge_tail; @@ -128,7 +174,7 @@ gva_canonical(GVA_Allocator const allocator, GVA_LCS_Graph const graph) GVA_Variant variant; gva_uint const count = gva_edges(graph.observed.str, graph.nodes[head].match, graph.nodes[edge_tail].match, - head == graph.source, edge_tail == 0, + head == graph.source, graph.nodes[edge_tail].edges == GVA_NULL, &variant); visited[edge_tail].start = MIN(visited[edge_tail].start, variant.start); visited[edge_tail].lca = lca(&visited[edge_tail].start, visited[edge_tail].lca, head, length, visited); @@ -143,23 +189,24 @@ gva_canonical(GVA_Allocator const allocator, GVA_LCS_Graph const graph) gva_uint const head = visited[tail].lca; if (head != GVA_NULL && visited[tail].start != GVA_NULL) { - // we need to skip lambda edges: start && end == -1 + // skip lambda edges: start && end == GVA_NULL gva_uint const start_offset = visited[tail].start - graph.nodes[head].match.row; gva_uint const end_offset = visited[tail].end - graph.nodes[tail].match.row; - GVA_Variant const variant = - { - visited[tail].start, visited[tail].end, - { - (graph.nodes[tail].match.col + end_offset) - (graph.nodes[head].match.col + start_offset), - graph.observed.str + graph.nodes[head].match.col + start_offset, - }, - }; - ARRAY_APPEND(allocator, canonical, variant); + ARRAY_APPEND(allocator, canonical, + ((GVA_Variant) { + .start = visited[tail].start, + .end = visited[tail].end, + .sequence = + { + .len = (graph.nodes[tail].match.col + end_offset) - (graph.nodes[head].match.col + start_offset), + .str = graph.observed.str + graph.nodes[head].match.col + start_offset, + }, + })); } // if } // for if (canonical != NULL) { - for (gva_uint i = 0; i < array_length(canonical) / 2; ++i) + for (size_t i = 0; i < array_length(canonical) / 2; ++i) { GVA_Variant const temp = canonical[i]; canonical[i] = canonical[array_length(canonical) - i - 1]; diff --git a/src/main.c b/src/main.c index e3b7e38..18e8815 100644 --- a/src/main.c +++ b/src/main.c @@ -31,6 +31,43 @@ #define REFERENCE_ID "NC_000001.11" +static inline size_t +repeats(GVA_Allocator const allocator, + size_t const len, char const word[static len]) +{ + size_t* lps = allocator.allocate(allocator.context, NULL, 0, len * sizeof(*lps)); + if (lps == NULL) + { + return 0; // OOM + } // if + + lps[0] = 0; + size_t length = 0; + size_t idx = 1; + while (idx < len) + { + if (word[idx] == word[length]) + { + length += 1; + lps[idx] = length; + idx += 1; + } // if + else if (length > 0) + { + length = lps[length - 1]; + } // if + else + { + lps[idx] = 0; + idx += 1; + } // else + } // while + + lps = allocator.allocate(allocator.context, lps, len * sizeof(*lps), 0); + return len - length; +} // repeats + + static inline size_t hgvs_location(size_t const len, char buffer[static len], size_t const start, size_t const end) @@ -52,6 +89,12 @@ hgvs_variant(size_t const len, char buffer[static len], size_t const len_ref, char const reference[static restrict len_ref], GVA_Variant const variant) { + size_t const inserted = repeats(gva_std_allocator, variant.sequence.len, variant.sequence.str); + size_t const deleted = repeats(gva_std_allocator, variant.end - variant.start, reference + variant.start); + + fprintf(stderr, "%zu vs %zu\n", inserted, deleted); + + size_t idx = hgvs_location(len, buffer, variant.start, variant.end); if (variant.end - variant.start == 0) @@ -864,6 +907,16 @@ all_main(int argc, char* argv[static argc]) int hgvs_main(int argc, char* argv[static argc]) { + static char buffer[1024] = {'\0'}; + GVA_String const ref = {10, "AAATAATATAATAATTTAT"}; + GVA_Variant const variant = {2, 13, {6, "ATAATA"}}; + fprintf(stderr, "%zu\n", to_hgvs(1024, buffer, ref.len, ref.str, 1, &variant)); + + fprintf(stderr, "%s\n", buffer); + + return EXIT_SUCCESS; + + if (argc < 2) { fprintf(stderr, "usage %s reference.blob\n", argv[0]); From ea81d255fb8ff219f25b26d0bd1757fd457d2aaa Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Wed, 27 May 2026 08:14:36 +0200 Subject: [PATCH 670/704] Stats function. --- include/index.h | 3 +++ src/index.c | 25 +++++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/include/index.h b/include/index.h index afd7151..e4bc703 100644 --- a/include/index.h +++ b/include/index.h @@ -87,5 +87,8 @@ size_t gva_index_variant_distance(GVA_Index const* const self, size_t const allele_idx, size_t const variant_idx); +void +gva_index_stats(GVA_Index* const self); + #endif // GVA_INDEX_H diff --git a/src/index.c b/src/index.c index f0c96f1..ae1725b 100644 --- a/src/index.c +++ b/src/index.c @@ -535,3 +535,28 @@ gva_index_variant_distance(GVA_Index const* const self, { return self->intervals.nodes[self->join[variant_idx].link ^ allele_idx].distance; } // gva_index_variant_distance + + +void +gva_index_stats(GVA_Index* const self) +{ + fprintf(stderr, "reference: #%d, %zu\n", 1, self->reference.len); + fprintf(stderr, "interval nodes: #%zu, %zu\n", array_length(self->intervals.nodes), + array_length(self->intervals.nodes) * sizeof(Interval_Tree_Node)); + fprintf(stderr, "inserted nodes: #%zu, %zu\n", array_length(self->inserted.nodes), + array_length(self->inserted.nodes) * sizeof(TrieNode)); + fprintf(stderr, "inserted strings: #%zu, %zu\n", array_length(self->inserted.strings), + array_length(self->inserted.strings) * sizeof(char)); + fprintf(stderr, "dfas nodes: #%zu, %zu\n", array_length(self->dfas.nodes), + array_length(self->dfas.nodes) * sizeof(TrieNode)); + fprintf(stderr, "dfas strings: #%zu, %zu\n", array_length(self->dfas.strings), + array_length(self->dfas.strings) * sizeof(char)); + fprintf(stderr, "ids nodes: #%zu, %zu\n", array_length(self->ids.nodes), + array_length(self->ids.nodes) * sizeof(TrieNode)); + fprintf(stderr, "ids strings: #%zu, %zu\n", array_length(self->ids.strings), + array_length(self->ids.strings) * sizeof(char)); + fprintf(stderr, "alleles: #%zu, %zu\n", array_length(self->alleles), + array_length(self->alleles) * sizeof(Allele)); + fprintf(stderr, "join: #%zu, %zu\n", array_length(self->join), array_length(self->join) * sizeof(Join)); + +} // gva_index_stats From ec34b1d7dbd114b8ccd02b24c4453418c5775765 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Wed, 27 May 2026 08:35:21 +0200 Subject: [PATCH 671/704] Consistency with other *_Node's. --- src/index.c | 6 +++--- src/trie.c | 12 ++++++------ src/trie.h | 4 ++-- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/index.c b/src/index.c index ae1725b..f4a9f19 100644 --- a/src/index.c +++ b/src/index.c @@ -544,15 +544,15 @@ gva_index_stats(GVA_Index* const self) fprintf(stderr, "interval nodes: #%zu, %zu\n", array_length(self->intervals.nodes), array_length(self->intervals.nodes) * sizeof(Interval_Tree_Node)); fprintf(stderr, "inserted nodes: #%zu, %zu\n", array_length(self->inserted.nodes), - array_length(self->inserted.nodes) * sizeof(TrieNode)); + array_length(self->inserted.nodes) * sizeof(Trie_Node)); fprintf(stderr, "inserted strings: #%zu, %zu\n", array_length(self->inserted.strings), array_length(self->inserted.strings) * sizeof(char)); fprintf(stderr, "dfas nodes: #%zu, %zu\n", array_length(self->dfas.nodes), - array_length(self->dfas.nodes) * sizeof(TrieNode)); + array_length(self->dfas.nodes) * sizeof(Trie_Node)); fprintf(stderr, "dfas strings: #%zu, %zu\n", array_length(self->dfas.strings), array_length(self->dfas.strings) * sizeof(char)); fprintf(stderr, "ids nodes: #%zu, %zu\n", array_length(self->ids.nodes), - array_length(self->ids.nodes) * sizeof(TrieNode)); + array_length(self->ids.nodes) * sizeof(Trie_Node)); fprintf(stderr, "ids strings: #%zu, %zu\n", array_length(self->ids.strings), array_length(self->ids.strings) * sizeof(char)); fprintf(stderr, "alleles: #%zu, %zu\n", array_length(self->alleles), diff --git a/src/trie.c b/src/trie.c index 9160efb..b85d1d9 100644 --- a/src/trie.c +++ b/src/trie.c @@ -6,7 +6,7 @@ #include "../include/string.h" // GVA_String, gva_prefix_length #include "../include/types.h" // GVA_NULL, gva_uint #include "array.h" // ARRAY_*, array_* -#include "trie.h" // Trie, TrieNode, trie_* +#include "trie.h" // Trie, Trie_Node, trie_* inline Trie @@ -53,7 +53,7 @@ trie_insert(Trie self[static restrict 1], { gva_uint const start = concat(self, len, key); self->root = ARRAY_APPEND(self->allocator, self->nodes, - ((TrieNode) + ((Trie_Node) { .link = GVA_NULL, .next = GVA_NULL, @@ -83,7 +83,7 @@ trie_insert(Trie self[static restrict 1], { gva_uint const start = concat(self, len, key); gva_uint const next = ARRAY_APPEND(self->allocator, self->nodes, - ((TrieNode) + ((Trie_Node) { .link = GVA_NULL, .next = GVA_NULL, @@ -104,7 +104,7 @@ trie_insert(Trie self[static restrict 1], { gva_uint const start = concat(self, len, key); gva_uint const link = ARRAY_APPEND(self->allocator, self->nodes, - ((TrieNode) + ((Trie_Node) { .link = GVA_NULL, .next = GVA_NULL, @@ -126,7 +126,7 @@ trie_insert(Trie self[static restrict 1], { gva_uint const start = concat(self, len, key); next = ARRAY_APPEND(self->allocator, self->nodes, - ((TrieNode) + ((Trie_Node) { .link = GVA_NULL, .next = GVA_NULL, @@ -136,7 +136,7 @@ trie_insert(Trie self[static restrict 1], })); } // if gva_uint const link = ARRAY_APPEND(self->allocator, self->nodes, - ((TrieNode) + ((Trie_Node) { .link = idx, .next = self->nodes[idx].next, diff --git a/src/trie.h b/src/trie.h index e8392d7..b05f3e7 100644 --- a/src/trie.h +++ b/src/trie.h @@ -16,13 +16,13 @@ typedef struct gva_uint p_start; gva_uint start; gva_uint end; -} TrieNode; +} Trie_Node; typedef struct { char* restrict strings; - TrieNode* restrict nodes; + Trie_Node* restrict nodes; GVA_Allocator allocator; gva_uint root; } Trie; From a0c4675d0b06c1d88ec31f5841d1ac4b8bd88a81 Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 27 May 2026 12:47:24 +0200 Subject: [PATCH 672/704] Cleanup --- include/index.h | 2 +- src/index.c | 28 +++++---- src/main.c | 149 +----------------------------------------------- 3 files changed, 19 insertions(+), 160 deletions(-) diff --git a/include/index.h b/include/index.h index e4bc703..db04039 100644 --- a/include/index.h +++ b/include/index.h @@ -88,7 +88,7 @@ gva_index_variant_distance(GVA_Index const* const self, size_t const allele_idx, size_t const variant_idx); void -gva_index_stats(GVA_Index* const self); +gva_index_stats(GVA_Index const* const self); #endif // GVA_INDEX_H diff --git a/src/index.c b/src/index.c index f4a9f19..91ab625 100644 --- a/src/index.c +++ b/src/index.c @@ -20,6 +20,9 @@ #include "trie.h" // Trie, trie_* +#include // FIXME: DEBUG + + typedef struct { gva_uint link; // X-OR link between interval_idx and allele_idx @@ -537,26 +540,27 @@ gva_index_variant_distance(GVA_Index const* const self, } // gva_index_variant_distance -void -gva_index_stats(GVA_Index* const self) +// FIXME +inline void +gva_index_stats(GVA_Index const* const self) { fprintf(stderr, "reference: #%d, %zu\n", 1, self->reference.len); fprintf(stderr, "interval nodes: #%zu, %zu\n", array_length(self->intervals.nodes), - array_length(self->intervals.nodes) * sizeof(Interval_Tree_Node)); + array_length(self->intervals.nodes) * sizeof(*self->intervals.nodes)); fprintf(stderr, "inserted nodes: #%zu, %zu\n", array_length(self->inserted.nodes), - array_length(self->inserted.nodes) * sizeof(Trie_Node)); + array_length(self->inserted.nodes) * sizeof(*self->inserted.nodes)); fprintf(stderr, "inserted strings: #%zu, %zu\n", array_length(self->inserted.strings), - array_length(self->inserted.strings) * sizeof(char)); + array_length(self->inserted.strings)); fprintf(stderr, "dfas nodes: #%zu, %zu\n", array_length(self->dfas.nodes), - array_length(self->dfas.nodes) * sizeof(Trie_Node)); + array_length(self->dfas.nodes) * sizeof(*self->dfas.nodes)); fprintf(stderr, "dfas strings: #%zu, %zu\n", array_length(self->dfas.strings), - array_length(self->dfas.strings) * sizeof(char)); + array_length(self->dfas.strings)); fprintf(stderr, "ids nodes: #%zu, %zu\n", array_length(self->ids.nodes), - array_length(self->ids.nodes) * sizeof(Trie_Node)); + array_length(self->ids.nodes) * sizeof(*self->ids.nodes)); fprintf(stderr, "ids strings: #%zu, %zu\n", array_length(self->ids.strings), - array_length(self->ids.strings) * sizeof(char)); + array_length(self->ids.strings)); fprintf(stderr, "alleles: #%zu, %zu\n", array_length(self->alleles), - array_length(self->alleles) * sizeof(Allele)); - fprintf(stderr, "join: #%zu, %zu\n", array_length(self->join), array_length(self->join) * sizeof(Join)); - + array_length(self->alleles) * sizeof(*self->alleles)); + fprintf(stderr, "join: #%zu, %zu\n", array_length(self->join), + array_length(self->join) * sizeof(*self->join)); } // gva_index_stats diff --git a/src/main.c b/src/main.c index 18e8815..2a51583 100644 --- a/src/main.c +++ b/src/main.c @@ -560,127 +560,6 @@ allele_main(int argc, char* argv[static argc]) } // allele_main -int -supremal_main(int argc, char* argv[static argc]) -{ - if (argc < 2) - { - fprintf(stderr, "usage %s reference.blob\n", argv[0]); - return EXIT_FAILURE; - } // if - - errno = 0; - FILE* stream = fopen(argv[1], "r"); - if (stream == NULL) - { - fprintf(stderr, "error: %s\n", strerror(errno)); - return EXIT_FAILURE; - } // if - - GVA_String reference = {0}; - reference = gva_fasta_sequence_blob(gva_std_allocator, stream); - fclose(stream); - - fprintf(stderr, "reference length: %zu\n", reference.len); - - Trie dfas = trie_init(gva_std_allocator); - - size_t line_count = 0; - static char line[LINE_SIZE] = {0}; - while (fgets(line, sizeof(line), stdin) != NULL) - { - line_count += 1; - GVA_String id = {0}; - GVA_Variant variant = {0}; - size_t distance = 0; - if (!parse_line(line, &id, &variant, &distance)) - { - fprintf(stderr, "parsing failed at line %zu: %s", line_count, line); - continue; - } // if - - uint8_t* dfa = dfa_from_alignment(gva_std_allocator, NULL, variant.end - variant.start, reference.str + variant.start, variant.sequence.len, variant.sequence.str); - trie_insert(&dfas, array_length(dfa), (char*) dfa); - dfa = ARRAY_DESTROY(gva_std_allocator, dfa); - } // while - fprintf(stderr, "#variants: %zu\n", line_count); - fprintf(stderr, "string len: %zu\n", array_length(dfas.strings)); - fprintf(stderr, "#nodes: %zu\n", array_length(dfas.nodes)); - - trie_destroy(&dfas); - - gva_string_destroy(gva_std_allocator, reference); - - return EXIT_SUCCESS; -} // supremal_main - - -int -overlap_main(int argc, char* argv[static argc]) -{ - (void) argv; - - size_t line_count = 0; - static char line[LINE_SIZE] = {0}; - while (fgets(line, sizeof(line), stdin) != NULL) - { - line_count += 1; - size_t start = 0; - size_t end = 0; - - end = strcspn(line, "\t "); - GVA_String reference = {end, line + start}; - - start += end + 1; - end = strcspn(line + start, "\t "); - - GVA_Variant lhs_variant = {0}; - if (gva_parse_spdi(end, line + start, &lhs_variant) == 0) - { - fprintf(stderr, "Error parsing LHS SPDI at line %zu: %s", line_count, line); - continue; - } // if - - start += end + 1; - end = strcspn(line + start, "\n\t "); - - GVA_Variant rhs_variant = {0}; - if (gva_parse_spdi(end, line + start, &rhs_variant) == 0) - { - fprintf(stderr, "Error parsing RHS SPDI at line %zu: %s", line_count, line); - continue; - } // if - - GVA_LCS_Graph graph = gva_lcs_graph_from_variants(gva_std_allocator, reference.len, reference.str, 1, &rhs_variant); - - gva_lcs_graph_destroy(gva_std_allocator, graph, true); - - //uint8_t* dfa = dfa_concat(gva_std_allocator, 2, variants, dfas); - //dfa_dot(stdout, reference.len, reference.str, rhs_variant, dfa); - //dfa = gva_std_allocator.allocate(gva_std_allocator.context, dfa, 0, 0); - - //uint8_t* lhs_dfa = dfa_from_alignment(gva_std_allocator, NULL, lhs_variant.end - lhs_variant.start, reference.str + lhs_variant.start, lhs_variant.sequence.len, lhs_variant.sequence.str); - //uint8_t* rhs_dfa = dfa_from_alignment(gva_std_allocator, NULL, rhs_variant.end - rhs_variant.start, reference.str + rhs_variant.start, rhs_variant.sequence.len, rhs_variant.sequence.str); - - // dfa_dot(stdout, reference.len, reference.str, lhs_variant, lhs_dfa); - //dfa_dot(stdout, reference.len, reference.str, rhs_variant, rhs_dfa); - // dfa_svg(stdout, reference.len, reference.str, lhs_variant, lhs_dfa); - // dfa_svg(stdout, reference.len, reference.str, rhs_variant, rhs_dfa); - - //fprintf(stderr, "disjoint: %d\n", dfa_disjoint(lhs_variant, lhs_dfa, rhs_variant, rhs_dfa)); - //fprintf(stdout, "%zu\n", dfa_max_overlap(gva_std_allocator, - // reference.len, reference.str, - // lhs_variant, lhs_dfa, - // rhs_variant, rhs_dfa, 0)); - - //rhs_dfa = ARRAY_DESTROY(gva_std_allocator, rhs_dfa); - //lhs_dfa = ARRAY_DESTROY(gva_std_allocator, lhs_dfa); - } // while - - return EXIT_SUCCESS; -} // overlap_main - - typedef struct { gva_uint start; @@ -741,28 +620,6 @@ all_main(int argc, char* argv[static argc]) fprintf(stderr, "reference length: %zu\n", reference.len); -/* - // 1505253:29:AGAGAGGGAGGGAGAGAGAGAGA - // 1505254:3:GGG - GVA_Variant const lhs = {1505253, 1505282, {23, "AGAGAGGGAGGGAGAGAGAGAGA"}}; - GVA_Variant const rhs = {1505254, 1505257, {3, "GGG"}}; - - uint8_t* lhs_dfa = dfa_from_alignment(gva_std_allocator, NULL, lhs.end - lhs.start, reference.str + lhs.start, lhs.sequence.len, lhs.sequence.str); - uint8_t* rhs_dfa = dfa_from_alignment(gva_std_allocator, NULL, rhs.end - rhs.start, reference.str + rhs.start, rhs.sequence.len, rhs.sequence.str); - - dfa_svg(stderr, reference.len, reference.str, lhs, lhs_dfa); - dfa_svg(stderr, reference.len, reference.str, rhs, rhs_dfa); - - fprintf(stderr, "disjoint: %d\n", dfa_disjoint(lhs, lhs_dfa, rhs, rhs_dfa)); - - rhs_dfa = ARRAY_DESTROY(gva_std_allocator, rhs_dfa); - lhs_dfa = ARRAY_DESTROY(gva_std_allocator, lhs_dfa); - - gva_string_destroy(gva_std_allocator, reference); - - return EXIT_SUCCESS; -*/ - errno = 0; stream = fopen(argv[2], "r"); if (stream == NULL) @@ -980,10 +837,8 @@ hgvs_main(int argc, char* argv[static argc]) int main(int argc, char* argv[static argc]) { - return hgvs_main(argc, argv); + // return hgvs_main(argc, argv); // return allele_main(argc, argv); - // return index_main(argc, argv); - // return supremal_main(argc, argv); - // return overlap_main(argc, argv); + return index_main(argc, argv); // return all_main(argc, argv); } // main From e27d29a1f11d5a029d42c72f4fa84b1503f579dc Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 27 May 2026 15:27:43 +0200 Subject: [PATCH 673/704] Layout --- src/trie.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/trie.h b/src/trie.h index b05f3e7..545ef74 100644 --- a/src/trie.h +++ b/src/trie.h @@ -21,10 +21,10 @@ typedef struct typedef struct { - char* restrict strings; + char* restrict strings; Trie_Node* restrict nodes; - GVA_Allocator allocator; - gva_uint root; + GVA_Allocator allocator; + gva_uint root; } Trie; From 2f4d3e764d40feb3f1c9ca45c742154b85c65f6b Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Thu, 28 May 2026 13:47:35 +0200 Subject: [PATCH 674/704] Calculate actual overlap. --- src/main.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main.c b/src/main.c index 2a51583..a3273b8 100644 --- a/src/main.c +++ b/src/main.c @@ -727,11 +727,11 @@ all_main(int argc, char* argv[static argc]) GVA_String lhs_dfa = trie_string(dfas, entries[i].dfa); GVA_String rhs_dfa = trie_string(dfas, entries[j].dfa); - //size_t const overlap = dfa_overlap(gva_std_allocator, reference.len, reference.str, lhs, (uint8_t*) lhs_dfa.str, rhs, (uint8_t*) rhs_dfa.str); - bool const disjoint = dfa_disjoint(lhs, (uint8_t*) lhs_dfa.str, rhs, (uint8_t*) rhs_dfa.str); + size_t const overlap = dfa_overlap(gva_std_allocator, reference.len, reference.str, lhs, (uint8_t*) lhs_dfa.str, rhs, (uint8_t*) rhs_dfa.str); + // bool const disjoint = dfa_disjoint(lhs, (uint8_t*) lhs_dfa.str, rhs, (uint8_t*) rhs_dfa.str); - if (disjoint) - // if (overlap == 0) + // if (disjoint) + if (overlap == 0) { fprintf(stdout, GVA_STRING_FMT " disjoint " GVA_STRING_FMT "\n", GVA_STRING_PRINT(trie_string(labels, entries[i].label)), @@ -739,10 +739,10 @@ all_main(int argc, char* argv[static argc]) } // if else { - fprintf(stdout, GVA_STRING_FMT " overlap " GVA_STRING_FMT " %d\n", + fprintf(stdout, GVA_STRING_FMT " overlap " GVA_STRING_FMT " %zu\n", GVA_STRING_PRINT(trie_string(labels, entries[i].label)), GVA_STRING_PRINT(trie_string(labels, entries[j].label)), - 1); + overlap); } // else } // for } // for From fd96611c6eaeddb23d3f661ba9a6f05eef08d48e Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Thu, 28 May 2026 16:21:04 +0200 Subject: [PATCH 675/704] WIP: mmap backed allocator. --- Makefile | 2 +- src/index.c | 49 ++++++++++++++---- src/main.c | 6 +-- src/mmap.h | 144 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/trie.c | 21 ++++---- src/trie.h | 5 +- 6 files changed, 202 insertions(+), 25 deletions(-) create mode 100644 src/mmap.h diff --git a/Makefile b/Makefile index 7ca3f14..baa8959 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ TEST_COVS = $(TESTS:.c=.c.gcov) TARGET = a.out CC = gcc -CFLAGS = -std=c99 -march=native -Wall -Wextra -Wpedantic -fanalyzer +CFLAGS = -std=c99 -march=native -Wall -Wextra -Wpedantic -fanalyzer -D_GNU_SOURCE MEMCHECK = valgrind -q --leak-check=full --error-exitcode=1 diff --git a/src/index.c b/src/index.c index 91ab625..2f7fdf1 100644 --- a/src/index.c +++ b/src/index.c @@ -19,6 +19,7 @@ #include "interval_tree.h" // Interval_Tree, interval_tree_* #include "trie.h" // Trie, trie_* +#include "mmap.h" #include // FIXME: DEBUG @@ -38,6 +39,20 @@ typedef struct } Allele; +struct allocators +{ + GVA_Allocator intervals; + GVA_Allocator inserted_nodes; + GVA_Allocator inserted_strings; + GVA_Allocator dfas_nodes; + GVA_Allocator dfas_strings; + GVA_Allocator ids_nodes; + GVA_Allocator ids_strings; + GVA_Allocator alleles; + GVA_Allocator join; +}; + + struct GVA_Index { GVA_Allocator allocator; @@ -48,6 +63,7 @@ struct GVA_Index Trie ids; Allele* alleles; Join* join; + struct allocators allocators; }; @@ -83,11 +99,21 @@ gva_index_init(GVA_Allocator const allocator, index->allocator = allocator; index->reference = (GVA_String) {len, reference}; - index->intervals = interval_tree_init(allocator); - index->inserted = trie_init(allocator); - index->dfas = trie_init(allocator); + index->allocators.intervals = mmap_allocator_init("blobs/intervals"); + index->allocators.inserted_nodes = mmap_allocator_init("blobs/inserted_nodes"); + index->allocators.inserted_strings = mmap_allocator_init("blobs/inserted_strings"); + index->allocators.dfas_nodes = mmap_allocator_init("blobs/dfas_nodes"); + index->allocators.dfas_strings = mmap_allocator_init("blobs/dfas_strings"); + index->allocators.ids_nodes = mmap_allocator_init("blobs/ids_nodes"); + index->allocators.ids_strings = mmap_allocator_init("blobs/ids_strings"); + index->allocators.alleles = mmap_allocator_init("blobs/alleles"); + index->allocators.join = mmap_allocator_init("blobs/join"); - index->ids = trie_init(allocator); + index->intervals = interval_tree_init(index->allocators.intervals); + index->inserted = trie_init(index->allocators.inserted_nodes, index->allocators.inserted_strings); + index->dfas = trie_init(index->allocators.dfas_nodes, index->allocators.dfas_strings); + + index->ids = trie_init(index->allocators.ids_nodes, index->allocators.ids_strings); index->alleles = NULL; index->join = NULL; @@ -108,8 +134,13 @@ gva_index_destroy(GVA_Index* const self) trie_destroy(&self->inserted); trie_destroy(&self->dfas); trie_destroy(&self->ids); - self->alleles = ARRAY_DESTROY(self->allocator, self->alleles); - self->join = ARRAY_DESTROY(self->allocator, self->join); + self->alleles = ARRAY_DESTROY(self->allocators.alleles, self->alleles); + self->join = ARRAY_DESTROY(self->allocators.join, self->join); + + mmap_allocator_destroy(self->allocators.alleles); + mmap_allocator_destroy(self->allocators.join); + mmap_allocator_destroy(self->allocators.intervals); + return self->allocator.allocate(self->allocator.context, self, sizeof(*self), 0); } // gva_index_destroy @@ -127,7 +158,7 @@ gva_index_insert(GVA_Index* restrict const self, if (array_length(self->alleles) == 0 || self->alleles[allele_idx].id_idx != id_idx) { - allele_idx = ARRAY_APPEND(self->allocator, self->alleles, + allele_idx = ARRAY_APPEND(self->allocators.alleles, self->alleles, ((Allele) { .id_idx = id_idx, @@ -138,7 +169,7 @@ gva_index_insert(GVA_Index* restrict const self, // add variant gva_uint const inserted_idx = trie_insert(&self->inserted, variant.sequence.len, variant.sequence.str); - gva_uint const tmp_idx = ARRAY_APPEND(self->allocator, self->intervals.nodes, + gva_uint const tmp_idx = ARRAY_APPEND(self->allocators.intervals, self->intervals.nodes, ((Interval_Tree_Node) { .child = {GVA_NULL, GVA_NULL}, @@ -165,7 +196,7 @@ gva_index_insert(GVA_Index* restrict const self, // undo append: interval already in the tree array_header(self->intervals.nodes)->length -= 1; } // else - self->intervals.nodes[node_idx].alleles = ARRAY_APPEND(self->allocator, self->join, + self->intervals.nodes[node_idx].alleles = ARRAY_APPEND(self->allocators.join, self->join, ((Join) { .link = node_idx ^ allele_idx, diff --git a/src/main.c b/src/main.c index a3273b8..42e7256 100644 --- a/src/main.c +++ b/src/main.c @@ -629,9 +629,9 @@ all_main(int argc, char* argv[static argc]) return EXIT_FAILURE; } // if - Trie labels = trie_init(gva_std_allocator); - Trie sequences = trie_init(gva_std_allocator); - Trie dfas = trie_init(gva_std_allocator); + Trie labels = trie_init(gva_std_allocator, gva_std_allocator); + Trie sequences = trie_init(gva_std_allocator, gva_std_allocator); + Trie dfas = trie_init(gva_std_allocator, gva_std_allocator); Entry* entries = NULL; size_t line_count = 0; diff --git a/src/mmap.h b/src/mmap.h new file mode 100644 index 0000000..bbf80ff --- /dev/null +++ b/src/mmap.h @@ -0,0 +1,144 @@ +#include // errno +#include // NULL, size_t +#include // stderr, stdout, fprintf +#include // EXIT_*, free, malloc +#include // strerror + +#include // O_*, S_*, open +#include // MADV_, MAP_*, MREMAP_MAYMOVE, MS_ASYNC, PROT_*, + // madvise, mmap, mremap, msync +#include // stat, fstat +#include // ftruncate, close + +#include "../include/allocator.h" // GVA_Allocator +#include "array.h" // ARRAY*, array_length + + +typedef struct +{ + void* addr; + size_t len; + int fd; +} MMAP_Context; + + +static inline void* +mmap_allocate(void* const restrict context, void* const restrict ptr, size_t const old_size, size_t const new_size) +{ + (void) ptr; // == ctx->addr + + MMAP_Context* const ctx = context; + ctx->len = new_size; + + if (new_size == 0) + { + return NULL; + } // if + + if (ctx->addr == NULL) + { + errno = 0; + ctx->addr = mmap(NULL, ctx->len, PROT_READ | PROT_WRITE, MAP_POPULATE | MAP_SHARED, ctx->fd, 0); + if (ctx->addr == MAP_FAILED) + { + fprintf(stderr, "mmap(): %s\n", strerror(errno)); + return NULL; + } // if + } // if + else + { + errno = 0; + ctx->addr = mremap(ctx->addr, old_size, ctx->len, MREMAP_MAYMOVE); + if (ctx->addr == MAP_FAILED) + { + fprintf(stderr, "mremap(): %s\n", strerror(errno)); + return NULL; + } // if + } // else + + errno = 0; + if (ftruncate(ctx->fd, ctx->len)) + { + fprintf(stderr, "ftruncate(): %s\n", strerror(errno)); + return NULL; + } // if + + return ctx->addr; +} // mmap_allocate + + +static GVA_Allocator +mmap_allocator_init(char const path[static 1]) +{ + MMAP_Context* const ctx = malloc(sizeof(*ctx)); // FIXME + if (ctx == NULL) + { + return (GVA_Allocator) {NULL}; // OOM + } // if + ctx->addr = NULL; + ctx->len = 0; + + errno = 0; + ctx->fd = open(path, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + if (ctx->fd == -1) + { + fprintf(stderr, "open(): %s\n", strerror(errno)); + return (GVA_Allocator) {NULL}; + } // if + + struct stat sb = {0}; + errno = 0; + if (fstat(ctx->fd, &sb) == -1) + { + fprintf(stderr, "fstat(): %s\n", strerror(errno)); + close(ctx->fd); + return (GVA_Allocator) {NULL}; + } // if + + if (sb.st_size > 0) + { + ctx->len = sb.st_size; + + errno = 0; + ctx->addr = mmap(NULL, ctx->len, PROT_READ | PROT_WRITE, MAP_POPULATE | MAP_SHARED, ctx->fd, 0); + if (ctx->addr == MAP_FAILED) + { + fprintf(stderr, "mmap(): %s\n", strerror(errno)); + return (GVA_Allocator) {NULL}; + } // if + + errno = 0; + if (madvise(ctx->addr, ctx->len, MADV_SEQUENTIAL | MADV_WILLNEED)) + { + // not critical + fprintf(stderr, "ERROR: %s\n", strerror(errno)); + } // if + } // if + + return (GVA_Allocator) + { + .allocate = mmap_allocate, + .context = ctx, + }; +} // mmap_allocator_init + + +static inline void +mmap_allocator_destroy(GVA_Allocator const allocator) +{ + MMAP_Context* const ctx = allocator.context; + errno = 0; + if (msync(ctx->addr, ctx->len, MS_ASYNC)) + { + fprintf(stderr, "msync(): %s\n", strerror(errno)); + } // if + close(ctx->fd); + free(allocator.context); // FIXME +} // mmap_allocator_destroy + + +static inline void* +array_load(char* const ptr) +{ + return ptr == NULL ? NULL : ptr + sizeof(Array); +} // array_load diff --git a/src/trie.c b/src/trie.c index b85d1d9..f824b66 100644 --- a/src/trie.c +++ b/src/trie.c @@ -10,11 +10,12 @@ inline Trie -trie_init(GVA_Allocator const allocator) +trie_init(GVA_Allocator const nodes_allocator, GVA_Allocator const strings_allocator) { return (Trie) { - .allocator = allocator, + .nodes_allocator = nodes_allocator, + .strings_allocator = strings_allocator, .root = GVA_NULL, }; } // trie_init @@ -23,8 +24,8 @@ trie_init(GVA_Allocator const allocator) inline void trie_destroy(Trie self[static 1]) { - self->strings = ARRAY_DESTROY(self->allocator, self->strings); - self->nodes = ARRAY_DESTROY(self->allocator, self->nodes); + self->strings = ARRAY_DESTROY(self->strings_allocator, self->strings); + self->nodes = ARRAY_DESTROY(self->nodes_allocator, self->nodes); self->root = GVA_NULL; } // trie_destroy @@ -34,7 +35,7 @@ concat(Trie self[static restrict 1], size_t const len, char const key[static restrict len]) { size_t const start = array_length(self->strings); - self->strings = array_ensure(self->allocator, self->strings, sizeof(*self->strings), len); + self->strings = array_ensure(self->strings_allocator, self->strings, sizeof(*self->strings), len); if (self->strings == NULL) { return start; // OOM @@ -52,7 +53,7 @@ trie_insert(Trie self[static restrict 1], if (self->root == GVA_NULL) { gva_uint const start = concat(self, len, key); - self->root = ARRAY_APPEND(self->allocator, self->nodes, + self->root = ARRAY_APPEND(self->nodes_allocator, self->nodes, ((Trie_Node) { .link = GVA_NULL, @@ -82,7 +83,7 @@ trie_insert(Trie self[static restrict 1], if (self->nodes[idx].next == GVA_NULL) { gva_uint const start = concat(self, len, key); - gva_uint const next = ARRAY_APPEND(self->allocator, self->nodes, + gva_uint const next = ARRAY_APPEND(self->nodes_allocator, self->nodes, ((Trie_Node) { .link = GVA_NULL, @@ -103,7 +104,7 @@ trie_insert(Trie self[static restrict 1], if (self->nodes[idx].link == GVA_NULL) { gva_uint const start = concat(self, len, key); - gva_uint const link = ARRAY_APPEND(self->allocator, self->nodes, + gva_uint const link = ARRAY_APPEND(self->nodes_allocator, self->nodes, ((Trie_Node) { .link = GVA_NULL, @@ -125,7 +126,7 @@ trie_insert(Trie self[static restrict 1], if (prefix < len) { gva_uint const start = concat(self, len, key); - next = ARRAY_APPEND(self->allocator, self->nodes, + next = ARRAY_APPEND(self->nodes_allocator, self->nodes, ((Trie_Node) { .link = GVA_NULL, @@ -135,7 +136,7 @@ trie_insert(Trie self[static restrict 1], .end = array_length(self->strings), })); } // if - gva_uint const link = ARRAY_APPEND(self->allocator, self->nodes, + gva_uint const link = ARRAY_APPEND(self->nodes_allocator, self->nodes, ((Trie_Node) { .link = idx, diff --git a/src/trie.h b/src/trie.h index 545ef74..a7f566f 100644 --- a/src/trie.h +++ b/src/trie.h @@ -23,13 +23,14 @@ typedef struct { char* restrict strings; Trie_Node* restrict nodes; - GVA_Allocator allocator; + GVA_Allocator nodes_allocator; + GVA_Allocator strings_allocator; gva_uint root; } Trie; Trie -trie_init(GVA_Allocator const allocator); +trie_init(GVA_Allocator const nodes_allocator, GVA_Allocator const strings_allocator); void From 921fd6d797a9d687bf58bd035fbb57b4f536bd61 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 28 May 2026 20:47:01 +0200 Subject: [PATCH 676/704] Fixed the leaks --- src/mmap.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/mmap.h b/src/mmap.h index bbf80ff..f350329 100644 --- a/src/mmap.h +++ b/src/mmap.h @@ -1,3 +1,8 @@ +// NOT FREESTANDING +#ifndef GVA_MMAP_H +#define GVA_MMAP_H + + #include // errno #include // NULL, size_t #include // stderr, stdout, fprintf @@ -83,6 +88,7 @@ mmap_allocator_init(char const path[static 1]) if (ctx->fd == -1) { fprintf(stderr, "open(): %s\n", strerror(errno)); + free(ctx); return (GVA_Allocator) {NULL}; } // if @@ -92,6 +98,7 @@ mmap_allocator_init(char const path[static 1]) { fprintf(stderr, "fstat(): %s\n", strerror(errno)); close(ctx->fd); + free(ctx); return (GVA_Allocator) {NULL}; } // if @@ -104,6 +111,8 @@ mmap_allocator_init(char const path[static 1]) if (ctx->addr == MAP_FAILED) { fprintf(stderr, "mmap(): %s\n", strerror(errno)); + close(ctx->fd); + free(ctx); return (GVA_Allocator) {NULL}; } // if @@ -142,3 +151,5 @@ array_load(char* const ptr) { return ptr == NULL ? NULL : ptr + sizeof(Array); } // array_load + +#endif // GVA_MMAP_H From 33d066ccf88655a085be398d344988abf2595c97 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 28 May 2026 21:01:04 +0200 Subject: [PATCH 677/704] WIP: loading from mmap --- src/index.c | 7 ++++--- src/mmap.h | 15 ++++++++++++--- src/trie.c | 4 ++++ 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/index.c b/src/index.c index 2f7fdf1..06cade7 100644 --- a/src/index.c +++ b/src/index.c @@ -110,13 +110,14 @@ gva_index_init(GVA_Allocator const allocator, index->allocators.join = mmap_allocator_init("blobs/join"); index->intervals = interval_tree_init(index->allocators.intervals); + index->intervals.nodes = array_load(index->allocators.intervals.context); + index->inserted = trie_init(index->allocators.inserted_nodes, index->allocators.inserted_strings); index->dfas = trie_init(index->allocators.dfas_nodes, index->allocators.dfas_strings); - index->ids = trie_init(index->allocators.ids_nodes, index->allocators.ids_strings); - index->alleles = NULL; - index->join = NULL; + index->alleles = array_load(index->allocators.alleles.context); + index->join = array_load(index->allocators.join.context); return index; } // gva_index_init diff --git a/src/mmap.h b/src/mmap.h index f350329..5ad226c 100644 --- a/src/mmap.h +++ b/src/mmap.h @@ -3,6 +3,9 @@ #define GVA_MMAP_H +// FIXME: proper header + source + + #include // errno #include // NULL, size_t #include // stderr, stdout, fprintf @@ -120,7 +123,7 @@ mmap_allocator_init(char const path[static 1]) if (madvise(ctx->addr, ctx->len, MADV_SEQUENTIAL | MADV_WILLNEED)) { // not critical - fprintf(stderr, "ERROR: %s\n", strerror(errno)); + fprintf(stderr, "madvise: %s\n", strerror(errno)); } // if } // if @@ -147,9 +150,15 @@ mmap_allocator_destroy(GVA_Allocator const allocator) static inline void* -array_load(char* const ptr) +array_load(void* const ptr) { - return ptr == NULL ? NULL : ptr + sizeof(Array); + if (ptr == NULL) + { + return NULL; + } // if + + MMAP_Context* const ctx = ptr; + return ctx->addr; } // array_load #endif // GVA_MMAP_H diff --git a/src/trie.c b/src/trie.c index f824b66..911c02f 100644 --- a/src/trie.c +++ b/src/trie.c @@ -8,12 +8,16 @@ #include "array.h" // ARRAY_*, array_* #include "trie.h" // Trie, Trie_Node, trie_* +#include "mmap.h" + inline Trie trie_init(GVA_Allocator const nodes_allocator, GVA_Allocator const strings_allocator) { return (Trie) { + .strings = array_load(strings_allocator.context), + .nodes = array_load(nodes_allocator.context), .nodes_allocator = nodes_allocator, .strings_allocator = strings_allocator, .root = GVA_NULL, From b6601bb1e2955f5f63ea1210dd2477c011ff74fc Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 28 May 2026 21:37:05 +0200 Subject: [PATCH 678/704] Oops --- src/mmap.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mmap.h b/src/mmap.h index 5ad226c..13ba0fe 100644 --- a/src/mmap.h +++ b/src/mmap.h @@ -158,7 +158,7 @@ array_load(void* const ptr) } // if MMAP_Context* const ctx = ptr; - return ctx->addr; + return ctx->addr == NULL ? NULL : ctx->addr + sizeof(Array); } // array_load #endif // GVA_MMAP_H From 438d905e6353ec1f44ad0f4194b56b41e3d67127 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 28 May 2026 21:45:49 +0200 Subject: [PATCH 679/704] WIP: more array_load --- src/mmap.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mmap.h b/src/mmap.h index 13ba0fe..b49e9c2 100644 --- a/src/mmap.h +++ b/src/mmap.h @@ -158,7 +158,8 @@ array_load(void* const ptr) } // if MMAP_Context* const ctx = ptr; - return ctx->addr == NULL ? NULL : ctx->addr + sizeof(Array); + return ctx->addr == NULL ? NULL : (char*) ctx->addr + sizeof(Array); } // array_load + #endif // GVA_MMAP_H From b0545d6040c0a702f9d6bc8a926b9b8004a77e38 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 28 May 2026 23:49:31 +0200 Subject: [PATCH 680/704] WIP: prepare for root loading --- src/index.c | 8 ++++---- src/interval_tree.c | 4 ++-- src/interval_tree.h | 2 +- src/main.c | 6 +++--- src/mmap.h | 2 +- src/trie.c | 6 ++++-- src/trie.h | 4 +++- 7 files changed, 18 insertions(+), 14 deletions(-) diff --git a/src/index.c b/src/index.c index 06cade7..56bc931 100644 --- a/src/index.c +++ b/src/index.c @@ -109,12 +109,12 @@ gva_index_init(GVA_Allocator const allocator, index->allocators.alleles = mmap_allocator_init("blobs/alleles"); index->allocators.join = mmap_allocator_init("blobs/join"); - index->intervals = interval_tree_init(index->allocators.intervals); + index->intervals = interval_tree_init(index->allocators.intervals, GVA_NULL); index->intervals.nodes = array_load(index->allocators.intervals.context); - index->inserted = trie_init(index->allocators.inserted_nodes, index->allocators.inserted_strings); - index->dfas = trie_init(index->allocators.dfas_nodes, index->allocators.dfas_strings); - index->ids = trie_init(index->allocators.ids_nodes, index->allocators.ids_strings); + index->inserted = trie_init(index->allocators.inserted_nodes, index->allocators.inserted_strings, GVA_NULL); + index->dfas = trie_init(index->allocators.dfas_nodes, index->allocators.dfas_strings, GVA_NULL); + index->ids = trie_init(index->allocators.ids_nodes, index->allocators.ids_strings, GVA_NULL); index->alleles = array_load(index->allocators.alleles.context); index->join = array_load(index->allocators.join.context); diff --git a/src/interval_tree.c b/src/interval_tree.c index d7e5ca3..8497e0f 100644 --- a/src/interval_tree.c +++ b/src/interval_tree.c @@ -9,12 +9,12 @@ inline Interval_Tree -interval_tree_init(GVA_Allocator const allocator) +interval_tree_init(GVA_Allocator const allocator, gva_uint const root) { return (Interval_Tree) { .allocator = allocator, - .root = GVA_NULL, + .root = root, }; } // interval_tree_init diff --git a/src/interval_tree.h b/src/interval_tree.h index 51c91e5..8fb6937 100644 --- a/src/interval_tree.h +++ b/src/interval_tree.h @@ -36,7 +36,7 @@ typedef struct Interval_Tree -interval_tree_init(GVA_Allocator const allocator); +interval_tree_init(GVA_Allocator const allocator, gva_uint const root); void diff --git a/src/main.c b/src/main.c index 42e7256..4214699 100644 --- a/src/main.c +++ b/src/main.c @@ -629,9 +629,9 @@ all_main(int argc, char* argv[static argc]) return EXIT_FAILURE; } // if - Trie labels = trie_init(gva_std_allocator, gva_std_allocator); - Trie sequences = trie_init(gva_std_allocator, gva_std_allocator); - Trie dfas = trie_init(gva_std_allocator, gva_std_allocator); + Trie labels = trie_init(gva_std_allocator, gva_std_allocator, GVA_NULL); + Trie sequences = trie_init(gva_std_allocator, gva_std_allocator, GVA_NULL); + Trie dfas = trie_init(gva_std_allocator, gva_std_allocator, GVA_NULL); Entry* entries = NULL; size_t line_count = 0; diff --git a/src/mmap.h b/src/mmap.h index b49e9c2..0cbbb39 100644 --- a/src/mmap.h +++ b/src/mmap.h @@ -123,7 +123,7 @@ mmap_allocator_init(char const path[static 1]) if (madvise(ctx->addr, ctx->len, MADV_SEQUENTIAL | MADV_WILLNEED)) { // not critical - fprintf(stderr, "madvise: %s\n", strerror(errno)); + fprintf(stderr, "madvise(): %s\n", strerror(errno)); } // if } // if diff --git a/src/trie.c b/src/trie.c index 911c02f..5cdda0f 100644 --- a/src/trie.c +++ b/src/trie.c @@ -12,7 +12,9 @@ inline Trie -trie_init(GVA_Allocator const nodes_allocator, GVA_Allocator const strings_allocator) +trie_init(GVA_Allocator const nodes_allocator, + GVA_Allocator const strings_allocator, + gva_uint const root) { return (Trie) { @@ -20,7 +22,7 @@ trie_init(GVA_Allocator const nodes_allocator, GVA_Allocator const strings_alloc .nodes = array_load(nodes_allocator.context), .nodes_allocator = nodes_allocator, .strings_allocator = strings_allocator, - .root = GVA_NULL, + .root = root, }; } // trie_init diff --git a/src/trie.h b/src/trie.h index a7f566f..c1a3b0f 100644 --- a/src/trie.h +++ b/src/trie.h @@ -30,7 +30,9 @@ typedef struct Trie -trie_init(GVA_Allocator const nodes_allocator, GVA_Allocator const strings_allocator); +trie_init(GVA_Allocator const nodes_allocator, + GVA_Allocator const strings_allocator, + gva_uint const root); void From 0ed4a58d6e530b2fe624e4f0fd1498474a9beef8 Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 29 May 2026 09:26:49 +0200 Subject: [PATCH 681/704] WIP: meta data --- src/index.c | 56 ++++++++++++++++++++++++++++++++++++++++++++--------- src/main.c | 1 + 2 files changed, 48 insertions(+), 9 deletions(-) diff --git a/src/index.c b/src/index.c index 56bc931..f8bbd0e 100644 --- a/src/index.c +++ b/src/index.c @@ -39,8 +39,9 @@ typedef struct } Allele; -struct allocators +typedef struct { + GVA_Allocator meta; GVA_Allocator intervals; GVA_Allocator inserted_nodes; GVA_Allocator inserted_strings; @@ -50,12 +51,23 @@ struct allocators GVA_Allocator ids_strings; GVA_Allocator alleles; GVA_Allocator join; -}; +} Allocators; + + +typedef struct +{ + gva_uint intervals_root; + gva_uint inserted_root; + gva_uint dfas_root; + gva_uint ids_root; +} Meta; struct GVA_Index { GVA_Allocator allocator; + Allocators allocators; + Meta* meta; GVA_String reference; Interval_Tree intervals; Trie inserted; @@ -63,7 +75,6 @@ struct GVA_Index Trie ids; Allele* alleles; Join* join; - struct allocators allocators; }; @@ -93,12 +104,32 @@ gva_index_init(GVA_Allocator const allocator, GVA_Index* index = allocator.allocate(allocator.context, NULL, 0, sizeof(*index)); if (index == NULL) { - return NULL; + return NULL; // OOM } // if index->allocator = allocator; index->reference = (GVA_String) {len, reference}; + index->allocators.meta = mmap_allocator_init("blobs/meta"); + if (index->allocators.meta.context == NULL || ((MMAP_Context*) index->allocators.meta.context)->addr == NULL) + { + index->meta = index->allocators.meta.allocate(index->allocators.meta.context, NULL, 0, sizeof(*index->meta)); + if (index->meta == NULL) + { + index = allocator.allocate(allocator.context, index, sizeof(*index), 0); + return NULL; // error + } // if + index->meta->intervals_root = GVA_NULL; + index->meta->inserted_root = GVA_NULL; + index->meta->dfas_root = GVA_NULL; + index->meta->ids_root = GVA_NULL; + } // if + else + { + // load meta data + index->meta = ((MMAP_Context*) index->allocators.meta.context)->addr; + } // else + index->allocators.intervals = mmap_allocator_init("blobs/intervals"); index->allocators.inserted_nodes = mmap_allocator_init("blobs/inserted_nodes"); index->allocators.inserted_strings = mmap_allocator_init("blobs/inserted_strings"); @@ -109,12 +140,12 @@ gva_index_init(GVA_Allocator const allocator, index->allocators.alleles = mmap_allocator_init("blobs/alleles"); index->allocators.join = mmap_allocator_init("blobs/join"); - index->intervals = interval_tree_init(index->allocators.intervals, GVA_NULL); + index->intervals = interval_tree_init(index->allocators.intervals, index->meta->intervals_root); index->intervals.nodes = array_load(index->allocators.intervals.context); - index->inserted = trie_init(index->allocators.inserted_nodes, index->allocators.inserted_strings, GVA_NULL); - index->dfas = trie_init(index->allocators.dfas_nodes, index->allocators.dfas_strings, GVA_NULL); - index->ids = trie_init(index->allocators.ids_nodes, index->allocators.ids_strings, GVA_NULL); + index->inserted = trie_init(index->allocators.inserted_nodes, index->allocators.inserted_strings, index->meta->inserted_root); + index->dfas = trie_init(index->allocators.dfas_nodes, index->allocators.dfas_strings, index->meta->dfas_root); + index->ids = trie_init(index->allocators.ids_nodes, index->allocators.ids_strings, index->meta->ids_root); index->alleles = array_load(index->allocators.alleles.context); index->join = array_load(index->allocators.join.context); @@ -131,6 +162,13 @@ gva_index_destroy(GVA_Index* const self) return NULL; } // if + fprintf(stderr, "%u\n", self->intervals.root); + + self->meta->intervals_root = self->intervals.root; + self->meta->inserted_root = self->inserted.root; + self->meta->dfas_root = self->dfas.root; + self->meta->ids_root = self->ids.root; + interval_tree_destroy(&self->intervals); trie_destroy(&self->inserted); trie_destroy(&self->dfas); @@ -141,7 +179,7 @@ gva_index_destroy(GVA_Index* const self) mmap_allocator_destroy(self->allocators.alleles); mmap_allocator_destroy(self->allocators.join); mmap_allocator_destroy(self->allocators.intervals); - + mmap_allocator_destroy(self->allocators.meta); return self->allocator.allocate(self->allocator.context, self, sizeof(*self), 0); } // gva_index_destroy diff --git a/src/main.c b/src/main.c index 4214699..bc9d3f6 100644 --- a/src/main.c +++ b/src/main.c @@ -435,6 +435,7 @@ index_main(int argc, char* argv[static argc]) fclose(stream); fprintf(stderr, "Index populated\n"); + gva_index_stats(index); line_count = 0; while (fgets(line, sizeof(line), stdin) != NULL) From d07f75d4e82795dc3132a80f5c4bc287f73d6bc8 Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 29 May 2026 09:59:11 +0200 Subject: [PATCH 682/704] FIX: deallocate all allocators --- src/index.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/index.c b/src/index.c index f8bbd0e..3bcca55 100644 --- a/src/index.c +++ b/src/index.c @@ -162,8 +162,6 @@ gva_index_destroy(GVA_Index* const self) return NULL; } // if - fprintf(stderr, "%u\n", self->intervals.root); - self->meta->intervals_root = self->intervals.root; self->meta->inserted_root = self->inserted.root; self->meta->dfas_root = self->dfas.root; @@ -176,10 +174,16 @@ gva_index_destroy(GVA_Index* const self) self->alleles = ARRAY_DESTROY(self->allocators.alleles, self->alleles); self->join = ARRAY_DESTROY(self->allocators.join, self->join); + mmap_allocator_destroy(self->allocators.meta); + mmap_allocator_destroy(self->allocators.intervals); + mmap_allocator_destroy(self->allocators.inserted_nodes); + mmap_allocator_destroy(self->allocators.inserted_strings); + mmap_allocator_destroy(self->allocators.dfas_nodes); + mmap_allocator_destroy(self->allocators.dfas_strings); + mmap_allocator_destroy(self->allocators.ids_nodes); + mmap_allocator_destroy(self->allocators.ids_strings); mmap_allocator_destroy(self->allocators.alleles); mmap_allocator_destroy(self->allocators.join); - mmap_allocator_destroy(self->allocators.intervals); - mmap_allocator_destroy(self->allocators.meta); return self->allocator.allocate(self->allocator.context, self, sizeof(*self), 0); } // gva_index_destroy From 43fdea21602d28e71e96aa677f678931790bac36 Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 29 May 2026 10:19:13 +0200 Subject: [PATCH 683/704] Removed duplicate stats --- src/index.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/src/index.c b/src/index.c index 3bcca55..0b9c3a4 100644 --- a/src/index.c +++ b/src/index.c @@ -618,23 +618,20 @@ gva_index_variant_distance(GVA_Index const* const self, inline void gva_index_stats(GVA_Index const* const self) { - fprintf(stderr, "reference: #%d, %zu\n", 1, self->reference.len); - fprintf(stderr, "interval nodes: #%zu, %zu\n", array_length(self->intervals.nodes), + fprintf(stderr, "reference: %zu bytes\n", self->reference.len); + fprintf(stderr, "interval nodes: #%zu, %zu bytes\n", array_length(self->intervals.nodes), array_length(self->intervals.nodes) * sizeof(*self->intervals.nodes)); - fprintf(stderr, "inserted nodes: #%zu, %zu\n", array_length(self->inserted.nodes), + fprintf(stderr, "inserted nodes: #%zu, %zu bytes\n", array_length(self->inserted.nodes), array_length(self->inserted.nodes) * sizeof(*self->inserted.nodes)); - fprintf(stderr, "inserted strings: #%zu, %zu\n", array_length(self->inserted.strings), - array_length(self->inserted.strings)); - fprintf(stderr, "dfas nodes: #%zu, %zu\n", array_length(self->dfas.nodes), + fprintf(stderr, "inserted strings: %zu bytes\n", array_length(self->inserted.strings)); + fprintf(stderr, "dfas nodes: #%zu, %zu bytes\n", array_length(self->dfas.nodes), array_length(self->dfas.nodes) * sizeof(*self->dfas.nodes)); - fprintf(stderr, "dfas strings: #%zu, %zu\n", array_length(self->dfas.strings), - array_length(self->dfas.strings)); - fprintf(stderr, "ids nodes: #%zu, %zu\n", array_length(self->ids.nodes), + fprintf(stderr, "dfas strings: %zu bytes\n", array_length(self->dfas.strings)); + fprintf(stderr, "ids nodes: #%zu, %zu bytes\n", array_length(self->ids.nodes), array_length(self->ids.nodes) * sizeof(*self->ids.nodes)); - fprintf(stderr, "ids strings: #%zu, %zu\n", array_length(self->ids.strings), - array_length(self->ids.strings)); - fprintf(stderr, "alleles: #%zu, %zu\n", array_length(self->alleles), + fprintf(stderr, "ids strings: %zu bytes\n", array_length(self->ids.strings)); + fprintf(stderr, "alleles: #%zu, %zu bytes\n", array_length(self->alleles), array_length(self->alleles) * sizeof(*self->alleles)); - fprintf(stderr, "join: #%zu, %zu\n", array_length(self->join), + fprintf(stderr, "join: #%zu, %zu bytes\n", array_length(self->join), array_length(self->join) * sizeof(*self->join)); } // gva_index_stats From 37ba908839c16af380c6c7cce0129c7d81eddd6b Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 29 May 2026 10:19:37 +0200 Subject: [PATCH 684/704] MMAP minimum size 4096 --- src/mmap.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/mmap.h b/src/mmap.h index 0cbbb39..67c6629 100644 --- a/src/mmap.h +++ b/src/mmap.h @@ -43,6 +43,11 @@ mmap_allocate(void* const restrict context, void* const restrict ptr, size_t con return NULL; } // if + if (ctx->len < 4096) + { + ctx->len = 4096; + } // if + if (ctx->addr == NULL) { errno = 0; From d82c78ff04c83af2983e238960850fd25590294b Mon Sep 17 00:00:00 2001 From: jkvis Date: Sat, 30 May 2026 10:03:19 +0200 Subject: [PATCH 685/704] WIP: refactoring mmap allocators; gva_std_alloc working --- Makefile | 2 +- include/index.h | 18 ++- include/mmap_alloc.h | 30 +++++ include/std_alloc.h | 32 +----- src/array.c | 14 ++- src/array.h | 5 + src/hgvs.c | 216 +++++++++++++++++++++++++++++++++++ src/index.c | 99 +++------------- src/main.c | 263 ++++++------------------------------------- src/mmap.h | 170 ---------------------------- src/mmap_alloc.c | 133 ++++++++++++++++++++++ src/std_alloc.c | 29 +++++ src/trie.c | 2 - 13 files changed, 496 insertions(+), 517 deletions(-) create mode 100644 include/mmap_alloc.h create mode 100644 src/hgvs.c delete mode 100644 src/mmap.h create mode 100644 src/mmap_alloc.c create mode 100644 src/std_alloc.c diff --git a/Makefile b/Makefile index baa8959..7ca3f14 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ TEST_COVS = $(TESTS:.c=.c.gcov) TARGET = a.out CC = gcc -CFLAGS = -std=c99 -march=native -Wall -Wextra -Wpedantic -fanalyzer -D_GNU_SOURCE +CFLAGS = -std=c99 -march=native -Wall -Wextra -Wpedantic -fanalyzer MEMCHECK = valgrind -q --leak-check=full --error-exitcode=1 diff --git a/include/index.h b/include/index.h index db04039..3cb26e8 100644 --- a/include/index.h +++ b/include/index.h @@ -49,8 +49,23 @@ typedef struct } GVA_Query_Result; +typedef struct +{ + GVA_Allocator heap; + GVA_Allocator intervals; + GVA_Allocator inserted_strings; + GVA_Allocator inserted_nodes; + GVA_Allocator dfas_strings; + GVA_Allocator dfas_nodes; + GVA_Allocator ids_strings; + GVA_Allocator ids_nodes; + GVA_Allocator alleles; + GVA_Allocator join; +} GVA_Index_Allocators; + + GVA_Index* -gva_index_init(GVA_Allocator const allocator, +gva_index_init(GVA_Index_Allocators const allocators, size_t const len_ref, char const reference[static len_ref]); @@ -87,6 +102,7 @@ size_t gva_index_variant_distance(GVA_Index const* const self, size_t const allele_idx, size_t const variant_idx); + void gva_index_stats(GVA_Index const* const self); diff --git a/include/mmap_alloc.h b/include/mmap_alloc.h new file mode 100644 index 0000000..4e63b8e --- /dev/null +++ b/include/mmap_alloc.h @@ -0,0 +1,30 @@ +#ifndef GVA_MMAP_ALLOC_H +#define GVA_MMAP_ALLOC_H + + +#include // size_t + + +typedef struct +{ + void* addr; + size_t len; + int fd; +} GVA_Mmap_Context; + + +// Provides a simple file backed memory mapped allocation strategy. +void* +gva_mmap_allocate(void* const restrict context, void* const restrict ptr, + size_t const old_size, size_t const new_size); + + +GVA_Mmap_Context +gva_mmap_context_init(char const path[static 1], size_t const initial_len); + + +void +gva_mmap_context_destroy(GVA_Mmap_Context const ctx[static 1]); + + +#endif // GVA_MMAP_ALLOC_H diff --git a/include/std_alloc.h b/include/std_alloc.h index 3951f6d..e05a248 100644 --- a/include/std_alloc.h +++ b/include/std_alloc.h @@ -1,39 +1,19 @@ -// NOT FREESTANDING #ifndef GVA_STD_ALLOC_H #define GVA_STD_ALLOC_H -#include // NULL, size_t -#include // free, realloc +#include // size_t #include "allocator.h" // GVA_Allocator -// Provides a simple global allocation strategy based on `realloc` from -// libc. -static inline void* -gva_std_allocate(void* const restrict context, void* const restrict ptr, size_t const old_size, size_t const new_size) -{ - (void) context; - (void) old_size; - - if (new_size == 0) - { - free(ptr); - return NULL; - } // if - - void* const new_ptr = realloc(ptr, new_size); - if (new_ptr == NULL) - { - free(ptr); - return NULL; // OOM - } // if - - return new_ptr; -} // gva_std_allocate +// Provides a simple global allocation strategy based on `realloc` from libc. +void* +gva_std_allocate(void* const restrict context, void* const restrict ptr, + size_t const old_size, size_t const new_size); +// Global general purpose allocator. static GVA_Allocator const gva_std_allocator = { .allocate = gva_std_allocate }; diff --git a/src/array.c b/src/array.c index 89a2917..0b5f74f 100644 --- a/src/array.c +++ b/src/array.c @@ -1,7 +1,7 @@ #include // NULL, size_t #include "../include/allocator.h" // GVA_Allocator -#include "array.h" // GVA_Array, gva_array_* +#include "array.h" // Array, array_* inline void* @@ -12,10 +12,7 @@ array_init(GVA_Allocator const allocator, size_t const capacity, { return NULL; // Empty array } // if - Array* const header = allocator.allocate( - allocator.context, - NULL, - 0, + Array* const header = allocator.allocate(allocator.context, NULL, 0, sizeof(*header) + capacity * item_size // OVERFLOW ); if (header == NULL) @@ -80,3 +77,10 @@ array_ensure(GVA_Allocator const allocator, void* const self, new_header->capacity = new_capacity; return new_header + 1; } // array_ensure + + +inline void* +array_load(char* const ptr) +{ + return ptr == NULL ? NULL : ptr + sizeof(Array); +} // array_load diff --git a/src/array.h b/src/array.h index b26c302..3b1df3c 100644 --- a/src/array.h +++ b/src/array.h @@ -48,6 +48,11 @@ array_ensure(GVA_Allocator const allocator, void* const self, size_t const item_size, size_t const extra); +// Internal: Returns an array from raw memory. +void* +array_load(char* const ptr); + + // Destroys an array. Does not destroy the elements of the array. // Returns `NULL`. // Usage: diff --git a/src/hgvs.c b/src/hgvs.c new file mode 100644 index 0000000..b5a6176 --- /dev/null +++ b/src/hgvs.c @@ -0,0 +1,216 @@ +// NOT FREESTANDING +#include // errno +#include // NULL, size_t +#include // ... +#include // ... +#include // ... + +#include "../include/allocator.h" // GVA_Allocator +#include "../include/parser.h" // gva_parse_* +#include "../include/std_alloc.h" // gva_std_allocator +#include "../include/string.h" // GVA_STRING_* +#include "../include/utils.h" // gva_fasta_sequence_blob +#include "../include/variant.h" // GVA_Variant + +#include "array.h" // ARRAY_DESTROY + + +#define LINE_SIZE 4096 + + +static inline size_t +repeats(GVA_Allocator const allocator, + size_t const len, char const word[static len]) +{ + size_t* lps = allocator.allocate(allocator.context, NULL, 0, len * sizeof(*lps)); + if (lps == NULL) + { + return 0; // OOM + } // if + + lps[0] = 0; + size_t length = 0; + size_t idx = 1; + while (idx < len) + { + if (word[idx] == word[length]) + { + length += 1; + lps[idx] = length; + idx += 1; + } // if + else if (length > 0) + { + length = lps[length - 1]; + } // if + else + { + lps[idx] = 0; + idx += 1; + } // else + } // while + + lps = allocator.allocate(allocator.context, lps, len * sizeof(*lps), 0); + return len - length; +} // repeats + + +static inline size_t +hgvs_location(size_t const len, char buffer[static len], + size_t const start, size_t const end) +{ + if (end - start == 0) + { + return snprintf(buffer, len, "%zu_%zu", start, start + 1); + } // if + if (end - start == 1) + { + return snprintf(buffer, len, "%zu", start + 1); + } // if + return snprintf(buffer, len, "%zu_%zu", start + 1, end); +} // hgvs_location + + +static size_t +hgvs_variant(size_t const len, char buffer[static len], + size_t const len_ref, char const reference[static restrict len_ref], + GVA_Variant const variant) +{ + size_t const inserted = repeats(gva_std_allocator, variant.sequence.len, variant.sequence.str); + size_t const deleted = repeats(gva_std_allocator, variant.end - variant.start, reference + variant.start); + + fprintf(stderr, "%zu vs %zu\n", inserted, deleted); + + + size_t idx = hgvs_location(len, buffer, variant.start, variant.end); + + if (variant.end - variant.start == 0) + { + if (variant.sequence.len == 0) + { + return idx + snprintf(buffer + idx, len - idx, "="); + } // if + return idx + snprintf(buffer + idx, len - idx, "ins" GVA_STRING_FMT, GVA_STRING_PRINT(variant.sequence)); + } // if + + if (variant.end - variant.start == 1) + { + if (variant.sequence.len == 0) + { + return idx + snprintf(buffer + idx, len - idx, "del"); + } // if + if (variant.sequence.len == 1) + { + return idx + snprintf(buffer + idx, len - idx, "%c>" GVA_STRING_FMT, reference[variant.start], GVA_STRING_PRINT(variant.sequence)); + } // if + return idx + snprintf(buffer + idx, len - idx, "delins" GVA_STRING_FMT, GVA_STRING_PRINT(variant.sequence)); + } // if + + if (variant.sequence.len == 0) + { + return idx + snprintf(buffer + idx, len - idx, "del"); + } // if + + return idx + snprintf(buffer + idx, len - idx, "delins" GVA_STRING_FMT, GVA_STRING_PRINT(variant.sequence)); +} // hgvs_variant + + +static size_t +to_hgvs(size_t const len, char buffer[static len], + size_t const len_ref, char const reference[static restrict len_ref], + size_t const n, GVA_Variant const variants[static restrict n]) +{ + if (n == 0) + { + return snprintf(buffer, len, "="); + } // if + + if (n == 1) + { + return hgvs_variant(len, buffer, len_ref, reference, variants[0]); + } // if + + size_t idx = snprintf(buffer, len, "["); + for (size_t i = 0; i < n; ++i) + { + idx += hgvs_variant(len - idx, buffer + idx, len_ref, reference, variants[i]); + if (i < n - 1) + { + idx += snprintf(buffer + idx, len - idx, ";"); + } // if + } // for + return idx + snprintf(buffer + idx, len - idx, "]"); +} // to_hgvs + + +int +hgvs_main(int argc, char* argv[static argc]) +{ + static char buffer[1024] = {'\0'}; + GVA_String const ref = {10, "AAATAATATAATAATTTAT"}; + GVA_Variant const variant = {2, 13, {6, "ATAATA"}}; + fprintf(stderr, "%zu\n", to_hgvs(1024, buffer, ref.len, ref.str, 1, &variant)); + + fprintf(stderr, "%s\n", buffer); + + return EXIT_SUCCESS; + + + if (argc < 2) + { + fprintf(stderr, "usage %s reference.blob\n", argv[0]); + return EXIT_FAILURE; + } // if + + errno = 0; + FILE* stream = fopen(argv[1], "r"); + if (stream == NULL) + { + perror("fopen()"); + return EXIT_FAILURE; + } // if + + GVA_String reference = {0}; + reference = gva_fasta_sequence_blob(gva_std_allocator, stream); + fclose(stream); + + fprintf(stderr, "reference length: %zu\n", reference.len); + + size_t line_count = 0; + static char line[LINE_SIZE] = {0}; + while (fgets(line, sizeof(line), stdin) != NULL) + { + line_count += 1; + + size_t idx = 0; + size_t tok = 0; + + tok = strcspn(line + idx, "\t "); + idx += tok + 1; // ignore identifier + + tok = strcspn(line + idx, "\t "); + GVA_Variant variant = {0}; + if (gva_parse_spdi(tok, line + idx, &variant) == 0) + { + fprintf(stderr, "%zu: ERROR SPDI: %s", line_count, line); + continue; + } // if + idx += tok + 1; + + tok = strcspn(line + idx, "\n\t "); + GVA_HGVS_Allele allele = gva_parse_hgvs(gva_std_allocator, reference.len, reference.str, tok, line + idx ); + if (!allele.interpretable) + { + fprintf(stderr, "%zu: ERROR HGVS: %s", line_count, line); + continue; + } // if + idx += tok + 1; + + ARRAY_DESTROY(gva_std_allocator, allele.inserted); + ARRAY_DESTROY(gva_std_allocator, allele.variants); + } //while + + gva_string_destroy(gva_std_allocator, reference); + + return EXIT_SUCCESS; +} // hgvs_main diff --git a/src/index.c b/src/index.c index 0b9c3a4..1a389d5 100644 --- a/src/index.c +++ b/src/index.c @@ -6,21 +6,20 @@ #include "../include/edit.h" // gva_edit_distance #include "../include/index.h" // GVA_Index, GVA_Query_Result, gva_index_* #include "../include/lcs_graph.h" // GVA_LCS_Graph, gva_lcs_graph_* +#include "../include/mmap_alloc.h" // GVA_Mmap_Context, gva_mmap_* #include "../include/relations.h" // GVA_Relation, GVA_CONTAINS, // GVA_DISJOINT, GVA_EQUIVALENT, // GVA_IS_CONTAINED #include "../include/string.h" // GVA_String #include "../include/types.h" // GVA_NULL, GVA_Interval, gva_uint #include "../include/variant.h" // GVA_Variant, gva_patch, gva_variant_dup -#include "array.h" // ARRAY_*, array_length +#include "array.h" // ARRAY_*, array_* #include "common.h" // ABS, MAX, MIN #include "dfa.h" // dfa_* #include "hash_table.h" // HASH_TABLE_*, hash_table_* #include "interval_tree.h" // Interval_Tree, interval_tree_* #include "trie.h" // Trie, trie_* -#include "mmap.h" - #include // FIXME: DEBUG @@ -39,35 +38,9 @@ typedef struct } Allele; -typedef struct -{ - GVA_Allocator meta; - GVA_Allocator intervals; - GVA_Allocator inserted_nodes; - GVA_Allocator inserted_strings; - GVA_Allocator dfas_nodes; - GVA_Allocator dfas_strings; - GVA_Allocator ids_nodes; - GVA_Allocator ids_strings; - GVA_Allocator alleles; - GVA_Allocator join; -} Allocators; - - -typedef struct -{ - gva_uint intervals_root; - gva_uint inserted_root; - gva_uint dfas_root; - gva_uint ids_root; -} Meta; - - struct GVA_Index { - GVA_Allocator allocator; - Allocators allocators; - Meta* meta; + GVA_Index_Allocators allocators; GVA_String reference; Interval_Tree intervals; Trie inserted; @@ -98,54 +71,24 @@ dfa_from_index(GVA_Index const self[static 1], size_t const idx) inline GVA_Index* -gva_index_init(GVA_Allocator const allocator, +gva_index_init(GVA_Index_Allocators const allocators, size_t const len, char const reference[static len]) { - GVA_Index* index = allocator.allocate(allocator.context, NULL, 0, sizeof(*index)); + GVA_Index* index = allocators.heap.allocate(allocators.heap.context, NULL, 0, sizeof(*index)); if (index == NULL) { return NULL; // OOM } // if - index->allocator = allocator; + index->allocators = allocators; index->reference = (GVA_String) {len, reference}; - index->allocators.meta = mmap_allocator_init("blobs/meta"); - if (index->allocators.meta.context == NULL || ((MMAP_Context*) index->allocators.meta.context)->addr == NULL) - { - index->meta = index->allocators.meta.allocate(index->allocators.meta.context, NULL, 0, sizeof(*index->meta)); - if (index->meta == NULL) - { - index = allocator.allocate(allocator.context, index, sizeof(*index), 0); - return NULL; // error - } // if - index->meta->intervals_root = GVA_NULL; - index->meta->inserted_root = GVA_NULL; - index->meta->dfas_root = GVA_NULL; - index->meta->ids_root = GVA_NULL; - } // if - else - { - // load meta data - index->meta = ((MMAP_Context*) index->allocators.meta.context)->addr; - } // else - - index->allocators.intervals = mmap_allocator_init("blobs/intervals"); - index->allocators.inserted_nodes = mmap_allocator_init("blobs/inserted_nodes"); - index->allocators.inserted_strings = mmap_allocator_init("blobs/inserted_strings"); - index->allocators.dfas_nodes = mmap_allocator_init("blobs/dfas_nodes"); - index->allocators.dfas_strings = mmap_allocator_init("blobs/dfas_strings"); - index->allocators.ids_nodes = mmap_allocator_init("blobs/ids_nodes"); - index->allocators.ids_strings = mmap_allocator_init("blobs/ids_strings"); - index->allocators.alleles = mmap_allocator_init("blobs/alleles"); - index->allocators.join = mmap_allocator_init("blobs/join"); - - index->intervals = interval_tree_init(index->allocators.intervals, index->meta->intervals_root); + index->intervals = interval_tree_init(index->allocators.intervals, GVA_NULL); index->intervals.nodes = array_load(index->allocators.intervals.context); - index->inserted = trie_init(index->allocators.inserted_nodes, index->allocators.inserted_strings, index->meta->inserted_root); - index->dfas = trie_init(index->allocators.dfas_nodes, index->allocators.dfas_strings, index->meta->dfas_root); - index->ids = trie_init(index->allocators.ids_nodes, index->allocators.ids_strings, index->meta->ids_root); + index->inserted = trie_init(index->allocators.inserted_nodes, index->allocators.inserted_strings, GVA_NULL); + index->dfas = trie_init(index->allocators.dfas_nodes, index->allocators.dfas_strings, GVA_NULL); + index->ids = trie_init(index->allocators.ids_nodes, index->allocators.ids_strings, GVA_NULL); index->alleles = array_load(index->allocators.alleles.context); index->join = array_load(index->allocators.join.context); @@ -162,11 +105,6 @@ gva_index_destroy(GVA_Index* const self) return NULL; } // if - self->meta->intervals_root = self->intervals.root; - self->meta->inserted_root = self->inserted.root; - self->meta->dfas_root = self->dfas.root; - self->meta->ids_root = self->ids.root; - interval_tree_destroy(&self->intervals); trie_destroy(&self->inserted); trie_destroy(&self->dfas); @@ -174,18 +112,7 @@ gva_index_destroy(GVA_Index* const self) self->alleles = ARRAY_DESTROY(self->allocators.alleles, self->alleles); self->join = ARRAY_DESTROY(self->allocators.join, self->join); - mmap_allocator_destroy(self->allocators.meta); - mmap_allocator_destroy(self->allocators.intervals); - mmap_allocator_destroy(self->allocators.inserted_nodes); - mmap_allocator_destroy(self->allocators.inserted_strings); - mmap_allocator_destroy(self->allocators.dfas_nodes); - mmap_allocator_destroy(self->allocators.dfas_strings); - mmap_allocator_destroy(self->allocators.ids_nodes); - mmap_allocator_destroy(self->allocators.ids_strings); - mmap_allocator_destroy(self->allocators.alleles); - mmap_allocator_destroy(self->allocators.join); - - return self->allocator.allocate(self->allocator.context, self, sizeof(*self), 0); + return self->allocators.heap.allocate(self->allocators.heap.context, self, sizeof(*self), 0); } // gva_index_destroy @@ -226,13 +153,13 @@ gva_index_insert(GVA_Index* restrict const self, gva_uint const node_idx = interval_tree_insert(&self->intervals, tmp_idx); if (node_idx == tmp_idx) { - uint8_t* dfa = dfa_from_alignment(self->allocator, NULL, + uint8_t* dfa = dfa_from_alignment(self->allocators.heap, NULL, variant.end - variant.start, self->reference.str + variant.start, variant.sequence.len, variant.sequence.str); self->intervals.nodes[node_idx].dfa = trie_insert(&self->dfas, array_length(dfa), (char*) dfa); - dfa = ARRAY_DESTROY(self->allocator, dfa); + dfa = ARRAY_DESTROY(self->allocators.heap, dfa); } // if else { diff --git a/src/main.c b/src/main.c index bc9d3f6..98488d6 100644 --- a/src/main.c +++ b/src/main.c @@ -2,9 +2,9 @@ #include // bool, false, true #include // NULL, size_t #include // uint8_t -#include // FILE, stderr, stdout, fclose, fopen, fprintf +#include // FILE, stderr, stdout, fclose, fopen, fprintf, perror #include // EXIT_*, atoll, qsort -#include // strerror, strlen +#include // strlen #include "../include/compare.h" // gva_compare_distance #include "../include/index.h" // GVA_Index, gva_index_*, GVA_Query_Result @@ -21,9 +21,6 @@ #include "trie.h" // Trie, trie_* -#include // DEBUG - - #define LINE_SIZE 4096 // #define REFERENCE_ID "NC_000022.11" @@ -31,131 +28,6 @@ #define REFERENCE_ID "NC_000001.11" -static inline size_t -repeats(GVA_Allocator const allocator, - size_t const len, char const word[static len]) -{ - size_t* lps = allocator.allocate(allocator.context, NULL, 0, len * sizeof(*lps)); - if (lps == NULL) - { - return 0; // OOM - } // if - - lps[0] = 0; - size_t length = 0; - size_t idx = 1; - while (idx < len) - { - if (word[idx] == word[length]) - { - length += 1; - lps[idx] = length; - idx += 1; - } // if - else if (length > 0) - { - length = lps[length - 1]; - } // if - else - { - lps[idx] = 0; - idx += 1; - } // else - } // while - - lps = allocator.allocate(allocator.context, lps, len * sizeof(*lps), 0); - return len - length; -} // repeats - - -static inline size_t -hgvs_location(size_t const len, char buffer[static len], - size_t const start, size_t const end) -{ - if (end - start == 0) - { - return snprintf(buffer, len, "%zu_%zu", start, start + 1); - } // if - if (end - start == 1) - { - return snprintf(buffer, len, "%zu", start + 1); - } // if - return snprintf(buffer, len, "%zu_%zu", start + 1, end); -} // hgvs_location - - -static size_t -hgvs_variant(size_t const len, char buffer[static len], - size_t const len_ref, char const reference[static restrict len_ref], - GVA_Variant const variant) -{ - size_t const inserted = repeats(gva_std_allocator, variant.sequence.len, variant.sequence.str); - size_t const deleted = repeats(gva_std_allocator, variant.end - variant.start, reference + variant.start); - - fprintf(stderr, "%zu vs %zu\n", inserted, deleted); - - - size_t idx = hgvs_location(len, buffer, variant.start, variant.end); - - if (variant.end - variant.start == 0) - { - if (variant.sequence.len == 0) - { - return idx + snprintf(buffer + idx, len - idx, "="); - } // if - return idx + snprintf(buffer + idx, len - idx, "ins" GVA_STRING_FMT, GVA_STRING_PRINT(variant.sequence)); - } // if - - if (variant.end - variant.start == 1) - { - if (variant.sequence.len == 0) - { - return idx + snprintf(buffer + idx, len - idx, "del"); - } // if - if (variant.sequence.len == 1) - { - return idx + snprintf(buffer + idx, len - idx, "%c>" GVA_STRING_FMT, reference[variant.start], GVA_STRING_PRINT(variant.sequence)); - } // if - return idx + snprintf(buffer + idx, len - idx, "delins" GVA_STRING_FMT, GVA_STRING_PRINT(variant.sequence)); - } // if - - if (variant.sequence.len == 0) - { - return idx + snprintf(buffer + idx, len - idx, "del"); - } // if - - return idx + snprintf(buffer + idx, len - idx, "delins" GVA_STRING_FMT, GVA_STRING_PRINT(variant.sequence)); -} // hgvs_variant - - -static size_t -to_hgvs(size_t const len, char buffer[static len], - size_t const len_ref, char const reference[static restrict len_ref], - size_t const n, GVA_Variant const variants[static restrict n]) -{ - if (n == 0) - { - return snprintf(buffer, len, "="); - } // if - - if (n == 1) - { - return hgvs_variant(len, buffer, len_ref, reference, variants[0]); - } // if - - size_t idx = snprintf(buffer, len, "["); - for (size_t i = 0; i < n; ++i) - { - idx += hgvs_variant(len - idx, buffer + idx, len_ref, reference, variants[i]); - if (i < n - 1) - { - idx += snprintf(buffer + idx, len - idx, ";"); - } // if - } // for - return idx + snprintf(buffer + idx, len - idx, "]"); -} // to_hgvs - - // line: alphanumeric_id SPDI [distance] static bool parse_line(char const line[static restrict LINE_SIZE], @@ -390,7 +262,7 @@ index_main(int argc, char* argv[static argc]) FILE* stream = fopen(argv[1], "r"); if (stream == NULL) { - fprintf(stderr, "error: %s\n", strerror(errno)); + perror("fopen()"); return EXIT_FAILURE; } // if @@ -400,7 +272,21 @@ index_main(int argc, char* argv[static argc]) fprintf(stderr, "reference length: %zu\n", reference.len); - GVA_Index* index = gva_index_init(gva_std_allocator, reference.len, reference.str); + GVA_Index_Allocators const allocators = + { + .heap = gva_std_allocator, + .intervals = gva_std_allocator, + .inserted_strings = gva_std_allocator, + .inserted_nodes = gva_std_allocator, + .dfas_strings = gva_std_allocator, + .dfas_nodes = gva_std_allocator, + .ids_strings = gva_std_allocator, + .ids_nodes = gva_std_allocator, + .alleles = gva_std_allocator, + .join = gva_std_allocator, + }; + + GVA_Index* index = gva_index_init(allocators, reference.len, reference.str); if (index == NULL) { fprintf(stderr, "OOM\n"); @@ -412,7 +298,7 @@ index_main(int argc, char* argv[static argc]) stream = fopen(argv[2], "r"); if (stream == NULL) { - fprintf(stderr, "error: %s\n", strerror(errno)); + perror("fopen()"); gva_string_destroy(gva_std_allocator, reference); return EXIT_FAILURE; } // if @@ -434,7 +320,6 @@ index_main(int argc, char* argv[static argc]) } // while fclose(stream); - fprintf(stderr, "Index populated\n"); gva_index_stats(index); line_count = 0; @@ -486,7 +371,7 @@ allele_main(int argc, char* argv[static argc]) FILE* stream = fopen(argv[1], "r"); if (stream == NULL) { - fprintf(stderr, "error: %s\n", strerror(errno)); + perror("fopen()"); return EXIT_FAILURE; } // if @@ -499,7 +384,7 @@ allele_main(int argc, char* argv[static argc]) if (stream == NULL) { gva_string_destroy(gva_std_allocator, reference); - fprintf(stderr, "error: %s\n", strerror(errno)); + perror("fopen()"); return EXIT_FAILURE; } // if @@ -567,7 +452,7 @@ typedef struct gva_uint end; gva_uint inserted; gva_uint distance; - gva_uint label; + gva_uint id; gva_uint dfa; } Entry; @@ -611,7 +496,7 @@ all_main(int argc, char* argv[static argc]) FILE* stream = fopen(argv[1], "r"); if (stream == NULL) { - fprintf(stderr, "error: %s\n", strerror(errno)); + perror("fopen()"); return EXIT_FAILURE; } // if @@ -625,12 +510,12 @@ all_main(int argc, char* argv[static argc]) stream = fopen(argv[2], "r"); if (stream == NULL) { - fprintf(stderr, "error: %s\n", strerror(errno)); + perror("fopen()"); gva_string_destroy(gva_std_allocator, reference); return EXIT_FAILURE; } // if - Trie labels = trie_init(gva_std_allocator, gva_std_allocator, GVA_NULL); + Trie ids = trie_init(gva_std_allocator, gva_std_allocator, GVA_NULL); Trie sequences = trie_init(gva_std_allocator, gva_std_allocator, GVA_NULL); Trie dfas = trie_init(gva_std_allocator, gva_std_allocator, GVA_NULL); Entry* entries = NULL; @@ -664,7 +549,7 @@ all_main(int argc, char* argv[static argc]) .end = variant.end, .inserted = trie_insert(&sequences, variant.sequence.len, variant.sequence.str), .distance = distance, - .label = trie_insert(&labels, id.len, id.str), + .id = trie_insert(&ids, id.len, id.str), .dfa = trie_insert(&dfas, array_length(dfa), (char*) dfa), })); @@ -695,8 +580,8 @@ all_main(int argc, char* argv[static argc]) if (entries[i].start == entries[j].start && entries[i].end == entries[j].end && entries[i].inserted == entries[j].inserted) { fprintf(stdout, GVA_STRING_FMT " equivalent " GVA_STRING_FMT "\n", - GVA_STRING_PRINT(trie_string(labels, entries[i].label)), - GVA_STRING_PRINT(trie_string(labels, entries[j].label))); + GVA_STRING_PRINT(trie_string(ids, entries[i].id)), + GVA_STRING_PRINT(trie_string(ids, entries[j].id))); continue; // equivalent } // if @@ -712,16 +597,16 @@ all_main(int argc, char* argv[static argc]) if (entries[i].distance - entries[j].distance == distance) { fprintf(stdout, GVA_STRING_FMT " contains " GVA_STRING_FMT "\n", - GVA_STRING_PRINT(trie_string(labels, entries[i].label)), - GVA_STRING_PRINT(trie_string(labels, entries[j].label))); + GVA_STRING_PRINT(trie_string(ids, entries[i].id)), + GVA_STRING_PRINT(trie_string(ids, entries[j].id))); continue; // contains } // if if (entries[j].distance - entries[i].distance == distance) { fprintf(stdout, GVA_STRING_FMT " is_contained " GVA_STRING_FMT "\n", - GVA_STRING_PRINT(trie_string(labels, entries[i].label)), - GVA_STRING_PRINT(trie_string(labels, entries[j].label))); + GVA_STRING_PRINT(trie_string(ids, entries[i].id)), + GVA_STRING_PRINT(trie_string(ids, entries[j].id))); continue; // is_contained } // if @@ -735,14 +620,14 @@ all_main(int argc, char* argv[static argc]) if (overlap == 0) { fprintf(stdout, GVA_STRING_FMT " disjoint " GVA_STRING_FMT "\n", - GVA_STRING_PRINT(trie_string(labels, entries[i].label)), - GVA_STRING_PRINT(trie_string(labels, entries[j].label))); + GVA_STRING_PRINT(trie_string(ids, entries[i].id)), + GVA_STRING_PRINT(trie_string(ids, entries[j].id))); } // if else { fprintf(stdout, GVA_STRING_FMT " overlap " GVA_STRING_FMT " %zu\n", - GVA_STRING_PRINT(trie_string(labels, entries[i].label)), - GVA_STRING_PRINT(trie_string(labels, entries[j].label)), + GVA_STRING_PRINT(trie_string(ids, entries[i].id)), + GVA_STRING_PRINT(trie_string(ids, entries[j].id)), overlap); } // else } // for @@ -753,7 +638,7 @@ all_main(int argc, char* argv[static argc]) entries = ARRAY_DESTROY(gva_std_allocator, entries); trie_destroy(&dfas); - trie_destroy(&labels); + trie_destroy(&ids); trie_destroy(&sequences); gva_string_destroy(gva_std_allocator, reference); @@ -762,83 +647,9 @@ all_main(int argc, char* argv[static argc]) } // all_main -int -hgvs_main(int argc, char* argv[static argc]) -{ - static char buffer[1024] = {'\0'}; - GVA_String const ref = {10, "AAATAATATAATAATTTAT"}; - GVA_Variant const variant = {2, 13, {6, "ATAATA"}}; - fprintf(stderr, "%zu\n", to_hgvs(1024, buffer, ref.len, ref.str, 1, &variant)); - - fprintf(stderr, "%s\n", buffer); - - return EXIT_SUCCESS; - - - if (argc < 2) - { - fprintf(stderr, "usage %s reference.blob\n", argv[0]); - return EXIT_FAILURE; - } // if - - errno = 0; - FILE* stream = fopen(argv[1], "r"); - if (stream == NULL) - { - fprintf(stderr, "error: %s\n", strerror(errno)); - return EXIT_FAILURE; - } // if - - GVA_String reference = {0}; - reference = gva_fasta_sequence_blob(gva_std_allocator, stream); - fclose(stream); - - fprintf(stderr, "reference length: %zu\n", reference.len); - - size_t line_count = 0; - static char line[LINE_SIZE] = {0}; - while (fgets(line, sizeof(line), stdin) != NULL) - { - line_count += 1; - - size_t idx = 0; - size_t tok = 0; - - tok = strcspn(line + idx, "\t "); - idx += tok + 1; // ignore identifier - - tok = strcspn(line + idx, "\t "); - GVA_Variant variant = {0}; - if (gva_parse_spdi(tok, line + idx, &variant) == 0) - { - fprintf(stderr, "%zu: ERROR SPDI: %s", line_count, line); - continue; - } // if - idx += tok + 1; - - tok = strcspn(line + idx, "\n\t "); - GVA_HGVS_Allele allele = gva_parse_hgvs(gva_std_allocator, reference.len, reference.str, tok, line + idx ); - if (!allele.interpretable) - { - fprintf(stderr, "%zu: ERROR HGVS: %s", line_count, line); - continue; - } // if - idx += tok + 1; - - ARRAY_DESTROY(gva_std_allocator, allele.inserted); - ARRAY_DESTROY(gva_std_allocator, allele.variants); - } //while - - gva_string_destroy(gva_std_allocator, reference); - - return EXIT_SUCCESS; -} // hgvs_main - - int main(int argc, char* argv[static argc]) { - // return hgvs_main(argc, argv); // return allele_main(argc, argv); return index_main(argc, argv); // return all_main(argc, argv); diff --git a/src/mmap.h b/src/mmap.h deleted file mode 100644 index 67c6629..0000000 --- a/src/mmap.h +++ /dev/null @@ -1,170 +0,0 @@ -// NOT FREESTANDING -#ifndef GVA_MMAP_H -#define GVA_MMAP_H - - -// FIXME: proper header + source - - -#include // errno -#include // NULL, size_t -#include // stderr, stdout, fprintf -#include // EXIT_*, free, malloc -#include // strerror - -#include // O_*, S_*, open -#include // MADV_, MAP_*, MREMAP_MAYMOVE, MS_ASYNC, PROT_*, - // madvise, mmap, mremap, msync -#include // stat, fstat -#include // ftruncate, close - -#include "../include/allocator.h" // GVA_Allocator -#include "array.h" // ARRAY*, array_length - - -typedef struct -{ - void* addr; - size_t len; - int fd; -} MMAP_Context; - - -static inline void* -mmap_allocate(void* const restrict context, void* const restrict ptr, size_t const old_size, size_t const new_size) -{ - (void) ptr; // == ctx->addr - - MMAP_Context* const ctx = context; - ctx->len = new_size; - - if (new_size == 0) - { - return NULL; - } // if - - if (ctx->len < 4096) - { - ctx->len = 4096; - } // if - - if (ctx->addr == NULL) - { - errno = 0; - ctx->addr = mmap(NULL, ctx->len, PROT_READ | PROT_WRITE, MAP_POPULATE | MAP_SHARED, ctx->fd, 0); - if (ctx->addr == MAP_FAILED) - { - fprintf(stderr, "mmap(): %s\n", strerror(errno)); - return NULL; - } // if - } // if - else - { - errno = 0; - ctx->addr = mremap(ctx->addr, old_size, ctx->len, MREMAP_MAYMOVE); - if (ctx->addr == MAP_FAILED) - { - fprintf(stderr, "mremap(): %s\n", strerror(errno)); - return NULL; - } // if - } // else - - errno = 0; - if (ftruncate(ctx->fd, ctx->len)) - { - fprintf(stderr, "ftruncate(): %s\n", strerror(errno)); - return NULL; - } // if - - return ctx->addr; -} // mmap_allocate - - -static GVA_Allocator -mmap_allocator_init(char const path[static 1]) -{ - MMAP_Context* const ctx = malloc(sizeof(*ctx)); // FIXME - if (ctx == NULL) - { - return (GVA_Allocator) {NULL}; // OOM - } // if - ctx->addr = NULL; - ctx->len = 0; - - errno = 0; - ctx->fd = open(path, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); - if (ctx->fd == -1) - { - fprintf(stderr, "open(): %s\n", strerror(errno)); - free(ctx); - return (GVA_Allocator) {NULL}; - } // if - - struct stat sb = {0}; - errno = 0; - if (fstat(ctx->fd, &sb) == -1) - { - fprintf(stderr, "fstat(): %s\n", strerror(errno)); - close(ctx->fd); - free(ctx); - return (GVA_Allocator) {NULL}; - } // if - - if (sb.st_size > 0) - { - ctx->len = sb.st_size; - - errno = 0; - ctx->addr = mmap(NULL, ctx->len, PROT_READ | PROT_WRITE, MAP_POPULATE | MAP_SHARED, ctx->fd, 0); - if (ctx->addr == MAP_FAILED) - { - fprintf(stderr, "mmap(): %s\n", strerror(errno)); - close(ctx->fd); - free(ctx); - return (GVA_Allocator) {NULL}; - } // if - - errno = 0; - if (madvise(ctx->addr, ctx->len, MADV_SEQUENTIAL | MADV_WILLNEED)) - { - // not critical - fprintf(stderr, "madvise(): %s\n", strerror(errno)); - } // if - } // if - - return (GVA_Allocator) - { - .allocate = mmap_allocate, - .context = ctx, - }; -} // mmap_allocator_init - - -static inline void -mmap_allocator_destroy(GVA_Allocator const allocator) -{ - MMAP_Context* const ctx = allocator.context; - errno = 0; - if (msync(ctx->addr, ctx->len, MS_ASYNC)) - { - fprintf(stderr, "msync(): %s\n", strerror(errno)); - } // if - close(ctx->fd); - free(allocator.context); // FIXME -} // mmap_allocator_destroy - - -static inline void* -array_load(void* const ptr) -{ - if (ptr == NULL) - { - return NULL; - } // if - - MMAP_Context* const ctx = ptr; - return ctx->addr == NULL ? NULL : (char*) ctx->addr + sizeof(Array); -} // array_load - - -#endif // GVA_MMAP_H diff --git a/src/mmap_alloc.c b/src/mmap_alloc.c new file mode 100644 index 0000000..b1c3ba5 --- /dev/null +++ b/src/mmap_alloc.c @@ -0,0 +1,133 @@ +// NOT FREESTANDING +// LINUX ONLY! +#define _GNU_SOURCE + + +#include // DEBUG: errno +#include // NULL, size_t +#include // DEBUG: perror + +#include // O_*, S_*, open +#include // MADV_, MAP_*, MREMAP_MAYMOVE, PROT_*, + // madvise, mmap, mremap, munmap +#include // stat, fstat +#include // ftruncate, close + +#include "../include/mmap_alloc.h" // GVA_Mmap_Context, gva_mmap_* +#include "common.h" // MAX + + +inline void* +gva_mmap_allocate(void* const restrict context, void* const restrict ptr, + size_t const old_size, size_t const new_size) +{ + (void) ptr; // ignored (== ctx->addr) + + GVA_Mmap_Context* const restrict ctx = context; + + // free: NOP + if (new_size == 0) + { + return NULL; + } // if + + // deallocate or sufficient available: NOP + if (new_size < old_size || new_size < ctx->len) + { + return ctx->addr; + } // if + + // allocate more + + errno = 0; // DEBUG + if (ftruncate(ctx->fd, new_size) == -1) + { + perror("ftruncate()"); // DEBUG + return NULL; // error + } // if + + errno = 0; // DEBUG + void* const restrict addr = mremap(ctx->addr, ctx->len, new_size, MREMAP_MAYMOVE); + if (addr == MAP_FAILED) + { + perror("mremap()"); // DEBUG + return NULL; // error + } // if + ctx->addr = addr; + ctx->len = new_size; + + return ctx->addr; +} // gva_mmap_allocate + + +GVA_Mmap_Context +gva_mmap_context_init(char const path[static 1], size_t const initial_len) +{ + static size_t const MINIMUM_LEN = 4096; + + GVA_Mmap_Context ctx = {NULL}; + + errno = 0; // DEBUG + ctx.fd = open(path, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + if (ctx.fd == -1) + { + perror("open()"); // DEBUG + return (GVA_Mmap_Context) {NULL}; // error + } // if + + struct stat sb = {0}; + errno = 0; // DEBUG + if (fstat(ctx.fd, &sb) == -1) + { + perror("fstat()"); // DEBUG + close(ctx.fd); // unchecked + return (GVA_Mmap_Context) {NULL}; // error + } // if + size_t const file_len = sb.st_size; + + ctx.len = MAX(MAX(MINIMUM_LEN, initial_len), file_len); + + if (file_len < ctx.len) + { + errno = 0; // DEBUG + if (ftruncate(ctx.fd, ctx.len) == -1) + { + perror("ftruncate()"); // DEBUG + close(ctx.fd); // unchecked + return (GVA_Mmap_Context) {NULL}; // error + } // if + } // if + + errno = 0; // DEBUG + ctx.addr = mmap(NULL, ctx.len, PROT_READ | PROT_WRITE, MAP_POPULATE | MAP_SHARED, ctx.fd, 0); + if (ctx.addr == MAP_FAILED) + { + perror("mmap()"); // DEBUG + close(ctx.fd); // unchecked + return (GVA_Mmap_Context) {NULL}; // error + } // if + + errno = 0; // DEBUG + if (madvise(ctx.addr, ctx.len, MADV_SEQUENTIAL | MADV_WILLNEED) == -1) + { + perror("madvise()"); // DEBUG + } // if + + return ctx; +} // gva_mmap_context_init + + +inline void +gva_mmap_context_destroy(GVA_Mmap_Context const ctx[static 1]) +{ + errno = 0; // DEBUG + if (munmap(ctx->addr, ctx->len) == -1) + { + perror("munmap()"); // DEBUG + } // if + errno = 0; // DEBUG + if (close(ctx->fd) == -1) + { + perror("close()"); // DEBUG + } // if +} // gva_mmap_context_destroy diff --git a/src/std_alloc.c b/src/std_alloc.c new file mode 100644 index 0000000..81d5c9b --- /dev/null +++ b/src/std_alloc.c @@ -0,0 +1,29 @@ +// NOT FREESTANDING +#include // NULL, size_t +#include // free, realloc + +#include "../include/std_alloc.h" // gva_std_allocate + + +inline void* +gva_std_allocate(void* const restrict context, void* const restrict ptr, + size_t const old_size, size_t const new_size) +{ + (void) context; // ignored + (void) old_size; // ignored + + if (new_size == 0) + { + free(ptr); + return NULL; + } // if + + void* const new_ptr = realloc(ptr, new_size); + if (new_ptr == NULL) + { + free(ptr); + return NULL; // OOM + } // if + + return new_ptr; +} // gva_std_allocate diff --git a/src/trie.c b/src/trie.c index 5cdda0f..3849bae 100644 --- a/src/trie.c +++ b/src/trie.c @@ -8,8 +8,6 @@ #include "array.h" // ARRAY_*, array_* #include "trie.h" // Trie, Trie_Node, trie_* -#include "mmap.h" - inline Trie trie_init(GVA_Allocator const nodes_allocator, From 31786880b0f7cf50d52434233de1ad5a2bd55da0 Mon Sep 17 00:00:00 2001 From: jkvis Date: Sat, 30 May 2026 12:14:52 +0200 Subject: [PATCH 686/704] WIP: meta data in index --- include/index.h | 1 + src/array.c | 7 +++--- src/array.h | 2 +- src/index.c | 39 ++++++++++++++++++++++++++++------ src/interval_tree.c | 10 +++++++-- src/main.c | 52 +++++++++++++++++++++++++++++++++++++-------- src/trie.c | 13 ++++++++---- src/trie.h | 6 +++--- 8 files changed, 101 insertions(+), 29 deletions(-) diff --git a/include/index.h b/include/index.h index 3cb26e8..54e8914 100644 --- a/include/index.h +++ b/include/index.h @@ -52,6 +52,7 @@ typedef struct typedef struct { GVA_Allocator heap; + GVA_Allocator meta; GVA_Allocator intervals; GVA_Allocator inserted_strings; GVA_Allocator inserted_nodes; diff --git a/src/array.c b/src/array.c index 0b5f74f..1e4f34b 100644 --- a/src/array.c +++ b/src/array.c @@ -44,7 +44,7 @@ array_ensure(GVA_Allocator const allocator, void* const self, size_t const item_size, size_t const extra) { // Initial allocation - if (self == NULL) + if (self == NULL || array_header(self)->capacity == 0) { return array_init(allocator, extra, item_size); } // if @@ -80,7 +80,8 @@ array_ensure(GVA_Allocator const allocator, void* const self, inline void* -array_load(char* const ptr) +array_load(void* const ptr) { - return ptr == NULL ? NULL : ptr + sizeof(Array); + // This assumes that addr is the first field in an allocator context. + return ptr == NULL ? NULL : *(char**) ptr + sizeof(Array); } // array_load diff --git a/src/array.h b/src/array.h index 3b1df3c..36456e5 100644 --- a/src/array.h +++ b/src/array.h @@ -50,7 +50,7 @@ array_ensure(GVA_Allocator const allocator, void* const self, // Internal: Returns an array from raw memory. void* -array_load(char* const ptr); +array_load(void* const ptr); // Destroys an array. Does not destroy the elements of the array. diff --git a/src/index.c b/src/index.c index 1a389d5..20bcecf 100644 --- a/src/index.c +++ b/src/index.c @@ -6,7 +6,6 @@ #include "../include/edit.h" // gva_edit_distance #include "../include/index.h" // GVA_Index, GVA_Query_Result, gva_index_* #include "../include/lcs_graph.h" // GVA_LCS_Graph, gva_lcs_graph_* -#include "../include/mmap_alloc.h" // GVA_Mmap_Context, gva_mmap_* #include "../include/relations.h" // GVA_Relation, GVA_CONTAINS, // GVA_DISJOINT, GVA_EQUIVALENT, // GVA_IS_CONTAINED @@ -38,10 +37,19 @@ typedef struct } Allele; +typedef struct +{ + gva_uint intervals_root; + gva_uint inserted_root; + gva_uint dfas_root; + gva_uint ids_root; +} Meta; + struct GVA_Index { GVA_Index_Allocators allocators; GVA_String reference; + Meta* meta; Interval_Tree intervals; Trie inserted; Trie dfas; @@ -83,13 +91,24 @@ gva_index_init(GVA_Index_Allocators const allocators, index->allocators = allocators; index->reference = (GVA_String) {len, reference}; - index->intervals = interval_tree_init(index->allocators.intervals, GVA_NULL); - index->intervals.nodes = array_load(index->allocators.intervals.context); - - index->inserted = trie_init(index->allocators.inserted_nodes, index->allocators.inserted_strings, GVA_NULL); - index->dfas = trie_init(index->allocators.dfas_nodes, index->allocators.dfas_strings, GVA_NULL); - index->ids = trie_init(index->allocators.ids_nodes, index->allocators.ids_strings, GVA_NULL); + if (allocators.meta.context == NULL) + { + index->meta = allocators.meta.allocate(allocators.meta.context, NULL, 0, sizeof(*index->meta)); + if (index->meta == NULL) + { + return allocators.heap.allocate(allocators.heap.context, index, sizeof(*index), 0); // OOM + } // if + } // if + else + { + // load meta data + index->meta = (Meta*) *(char**) allocators.meta.context; + } // else + index->intervals = interval_tree_init(index->allocators.intervals, index->meta->intervals_root); + index->inserted = trie_init(index->allocators.inserted_strings, index->allocators.inserted_nodes, index->meta->inserted_root); + index->dfas = trie_init(index->allocators.dfas_strings, index->allocators.dfas_nodes, index->meta->dfas_root); + index->ids = trie_init(index->allocators.ids_strings, index->allocators.ids_nodes, index->meta->ids_root); index->alleles = array_load(index->allocators.alleles.context); index->join = array_load(index->allocators.join.context); @@ -105,6 +124,12 @@ gva_index_destroy(GVA_Index* const self) return NULL; } // if + self->meta->intervals_root = self->intervals.root; + self->meta->inserted_root = self->inserted.root; + self->meta->dfas_root = self->dfas.root; + self->meta->ids_root = self->ids.root; + + self->meta = self->allocators.meta.allocate(self->allocators.meta.context, self->meta, sizeof(*self->meta), 0); interval_tree_destroy(&self->intervals); trie_destroy(&self->inserted); trie_destroy(&self->dfas); diff --git a/src/interval_tree.c b/src/interval_tree.c index 8497e0f..4127b59 100644 --- a/src/interval_tree.c +++ b/src/interval_tree.c @@ -3,7 +3,7 @@ #include "../include/allocator.h" // GVA_Allocator #include "../include/types.h" // GVA_NULL -#include "array.h" // ARRAY_DESTROY +#include "array.h" // ARRAY_DESTROY, array_* #include "common.h" // MAX #include "interval_tree.h" // Interval_Tree, interval_tree_* @@ -11,11 +11,17 @@ inline Interval_Tree interval_tree_init(GVA_Allocator const allocator, gva_uint const root) { - return (Interval_Tree) + Interval_Tree tree = { + .nodes = array_load(allocator.context), .allocator = allocator, .root = root, }; + if (array_length(tree.nodes) == 0) + { + tree.root = GVA_NULL; + } // if + return tree; } // interval_tree_init diff --git a/src/main.c b/src/main.c index 98488d6..42d9257 100644 --- a/src/main.c +++ b/src/main.c @@ -9,6 +9,7 @@ #include "../include/compare.h" // gva_compare_distance #include "../include/index.h" // GVA_Index, gva_index_*, GVA_Query_Result #include "../include/lcs_graph.h" // GVA_LCS_Graph, gva_lcs_graph_* +#include "../include/mmap_alloc.h" // GVA_Mmap_Context, gva_mmap_* #include "../include/relations.h" // GVA_RELATION_LABELS #include "../include/parser.h" // gva_parse_spdi #include "../include/std_alloc.h" // gva_std_allocator @@ -272,18 +273,40 @@ index_main(int argc, char* argv[static argc]) fprintf(stderr, "reference length: %zu\n", reference.len); + GVA_Mmap_Context meta_ctx = gva_mmap_context_init("blobs/meta.bin", 0); + GVA_Mmap_Context intervals_ctx = gva_mmap_context_init("blobs/intervals.bin", 0); + GVA_Mmap_Context inserted_strings_ctx = gva_mmap_context_init("blobs/inserted_strings.bin", 0); + GVA_Mmap_Context inserted_nodes_ctx = gva_mmap_context_init("blobs/inserted_nodes.bin", 0); + GVA_Mmap_Context dfas_strings_ctx = gva_mmap_context_init("blobs/dfas_strings.bin", 0); + GVA_Mmap_Context dfas_nodes_ctx = gva_mmap_context_init("blobs/dfas_nodes.bin", 0); + GVA_Mmap_Context ids_strings_ctx = gva_mmap_context_init("blobs/ids_strings.bin", 0); + GVA_Mmap_Context ids_nodes_ctx = gva_mmap_context_init("blobs/ids_nodes.bin", 0); + GVA_Mmap_Context alleles_ctx = gva_mmap_context_init("blobs/alleles.bin", 0); + GVA_Mmap_Context join_ctx = gva_mmap_context_init("blobs/join.bin", 0); + GVA_Index_Allocators const allocators = { .heap = gva_std_allocator, - .intervals = gva_std_allocator, - .inserted_strings = gva_std_allocator, - .inserted_nodes = gva_std_allocator, - .dfas_strings = gva_std_allocator, - .dfas_nodes = gva_std_allocator, - .ids_strings = gva_std_allocator, - .ids_nodes = gva_std_allocator, - .alleles = gva_std_allocator, - .join = gva_std_allocator, + //.meta = gva_std_allocator, + .meta = { .allocate = gva_mmap_allocate, .context = &meta_ctx }, + //.intervals = gva_std_allocator, + .intervals = { .allocate = gva_mmap_allocate, .context = &intervals_ctx }, + //.inserted_strings = gva_std_allocator, + .inserted_strings = { .allocate = gva_mmap_allocate, .context = &inserted_strings_ctx }, + //.inserted_nodes = gva_std_allocator, + .inserted_nodes = { .allocate = gva_mmap_allocate, .context = &inserted_nodes_ctx }, + //.dfas_strings = gva_std_allocator, + .dfas_strings = { .allocate = gva_mmap_allocate, .context = &dfas_strings_ctx }, + //.dfas_nodes = gva_std_allocator, + .dfas_nodes = { .allocate = gva_mmap_allocate, .context = &dfas_nodes_ctx }, + //.ids_strings = gva_std_allocator, + .ids_strings = { .allocate = gva_mmap_allocate, .context = &ids_strings_ctx }, + //.ids_nodes = gva_std_allocator, + .ids_nodes = { .allocate = gva_mmap_allocate, .context = &ids_nodes_ctx }, + //.alleles = gva_std_allocator, + .alleles = { .allocate = gva_mmap_allocate, .context = &alleles_ctx }, + //.join = gva_std_allocator, + .join = { .allocate = gva_mmap_allocate, .context = &join_ctx }, }; GVA_Index* index = gva_index_init(allocators, reference.len, reference.str); @@ -352,6 +375,17 @@ index_main(int argc, char* argv[static argc]) } // while index = gva_index_destroy(index); + gva_mmap_context_destroy(&meta_ctx); + gva_mmap_context_destroy(&intervals_ctx); + gva_mmap_context_destroy(&inserted_strings_ctx); + gva_mmap_context_destroy(&inserted_nodes_ctx); + gva_mmap_context_destroy(&dfas_strings_ctx); + gva_mmap_context_destroy(&dfas_nodes_ctx); + gva_mmap_context_destroy(&ids_strings_ctx); + gva_mmap_context_destroy(&ids_nodes_ctx); + gva_mmap_context_destroy(&alleles_ctx); + gva_mmap_context_destroy(&join_ctx); + gva_string_destroy(gva_std_allocator, reference); return EXIT_SUCCESS; diff --git a/src/trie.c b/src/trie.c index 3849bae..45d3dea 100644 --- a/src/trie.c +++ b/src/trie.c @@ -10,18 +10,23 @@ inline Trie -trie_init(GVA_Allocator const nodes_allocator, - GVA_Allocator const strings_allocator, +trie_init(GVA_Allocator const strings_allocator, + GVA_Allocator const nodes_allocator, gva_uint const root) { - return (Trie) + Trie trie = { .strings = array_load(strings_allocator.context), .nodes = array_load(nodes_allocator.context), - .nodes_allocator = nodes_allocator, .strings_allocator = strings_allocator, + .nodes_allocator = nodes_allocator, .root = root, }; + if (array_length(trie.nodes) == 0) + { + trie.root = GVA_NULL; + } // if + return trie; } // trie_init diff --git a/src/trie.h b/src/trie.h index c1a3b0f..7b583f3 100644 --- a/src/trie.h +++ b/src/trie.h @@ -23,15 +23,15 @@ typedef struct { char* restrict strings; Trie_Node* restrict nodes; - GVA_Allocator nodes_allocator; GVA_Allocator strings_allocator; + GVA_Allocator nodes_allocator; gva_uint root; } Trie; Trie -trie_init(GVA_Allocator const nodes_allocator, - GVA_Allocator const strings_allocator, +trie_init(GVA_Allocator const strings_allocator, + GVA_Allocator const nodes_allocator, gva_uint const root); From 4bcdcc398a5d943287bacc75bcc2f9ba3df2328f Mon Sep 17 00:00:00 2001 From: jkvis Date: Sat, 30 May 2026 15:06:57 +0200 Subject: [PATCH 687/704] WIP: debugging --- src/index.c | 20 ++++++++++++++++++++ src/main.c | 22 ++++++++++++---------- 2 files changed, 32 insertions(+), 10 deletions(-) diff --git a/src/index.c b/src/index.c index 20bcecf..77fe0c1 100644 --- a/src/index.c +++ b/src/index.c @@ -98,6 +98,10 @@ gva_index_init(GVA_Index_Allocators const allocators, { return allocators.heap.allocate(allocators.heap.context, index, sizeof(*index), 0); // OOM } // if + index->meta->intervals_root = GVA_NULL; + index->meta->inserted_root = GVA_NULL; + index->meta->dfas_root = GVA_NULL; + index->meta->ids_root = GVA_NULL; } // if else { @@ -112,6 +116,13 @@ gva_index_init(GVA_Index_Allocators const allocators, index->alleles = array_load(index->allocators.alleles.context); index->join = array_load(index->allocators.join.context); + fprintf(stderr, "intervals root: %d\n", index->intervals.root); + fprintf(stderr, "inserted root: %d\n", index->inserted.root); + fprintf(stderr, "dfas root: %d\n", index->dfas.root); + fprintf(stderr, "ids root: %d\n", index->ids.root); + + gva_index_stats(index); + return index; } // gva_index_init @@ -129,6 +140,11 @@ gva_index_destroy(GVA_Index* const self) self->meta->dfas_root = self->dfas.root; self->meta->ids_root = self->ids.root; + fprintf(stderr, "intervals root: %d\n", self->intervals.root); + fprintf(stderr, "inserted root: %d\n", self->inserted.root); + fprintf(stderr, "dfas root: %d\n", self->dfas.root); + fprintf(stderr, "ids root: %d\n", self->ids.root); + self->meta = self->allocators.meta.allocate(self->allocators.meta.context, self->meta, sizeof(*self->meta), 0); interval_tree_destroy(&self->intervals); trie_destroy(&self->inserted); @@ -160,6 +176,10 @@ gva_index_insert(GVA_Index* restrict const self, .join.start = array_length(self->join), })); } // if + else if (self->alleles[allele_idx].id_idx > id_idx) + { + return; // allele id is already in the index + } // if // add variant gva_uint const inserted_idx = trie_insert(&self->inserted, diff --git a/src/main.c b/src/main.c index 42d9257..1e39c6e 100644 --- a/src/main.c +++ b/src/main.c @@ -287,25 +287,27 @@ index_main(int argc, char* argv[static argc]) GVA_Index_Allocators const allocators = { .heap = gva_std_allocator, - //.meta = gva_std_allocator, + /* + .meta = gva_std_allocator, + .intervals = gva_std_allocator, + .inserted_strings = gva_std_allocator, + .inserted_nodes = gva_std_allocator, + .dfas_strings = gva_std_allocator, + .dfas_nodes = gva_std_allocator, + .ids_strings = gva_std_allocator, + .ids_nodes = gva_std_allocator, + .alleles = gva_std_allocator, + .join = gva_std_allocator, + */ .meta = { .allocate = gva_mmap_allocate, .context = &meta_ctx }, - //.intervals = gva_std_allocator, .intervals = { .allocate = gva_mmap_allocate, .context = &intervals_ctx }, - //.inserted_strings = gva_std_allocator, .inserted_strings = { .allocate = gva_mmap_allocate, .context = &inserted_strings_ctx }, - //.inserted_nodes = gva_std_allocator, .inserted_nodes = { .allocate = gva_mmap_allocate, .context = &inserted_nodes_ctx }, - //.dfas_strings = gva_std_allocator, .dfas_strings = { .allocate = gva_mmap_allocate, .context = &dfas_strings_ctx }, - //.dfas_nodes = gva_std_allocator, .dfas_nodes = { .allocate = gva_mmap_allocate, .context = &dfas_nodes_ctx }, - //.ids_strings = gva_std_allocator, .ids_strings = { .allocate = gva_mmap_allocate, .context = &ids_strings_ctx }, - //.ids_nodes = gva_std_allocator, .ids_nodes = { .allocate = gva_mmap_allocate, .context = &ids_nodes_ctx }, - //.alleles = gva_std_allocator, .alleles = { .allocate = gva_mmap_allocate, .context = &alleles_ctx }, - //.join = gva_std_allocator, .join = { .allocate = gva_mmap_allocate, .context = &join_ctx }, }; From 4da177b618d3f2e9bc4b2a8b091e932c5f8f86f6 Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 3 Jun 2026 15:51:14 +0200 Subject: [PATCH 688/704] FIX: always 1 --- src/trie.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/trie.c b/src/trie.c index 45d3dea..5b86508 100644 --- a/src/trie.c +++ b/src/trie.c @@ -44,7 +44,7 @@ concat(Trie self[static restrict 1], size_t const len, char const key[static restrict len]) { size_t const start = array_length(self->strings); - self->strings = array_ensure(self->strings_allocator, self->strings, sizeof(*self->strings), len); + self->strings = array_ensure(self->strings_allocator, self->strings, 1, len); if (self->strings == NULL) { return start; // OOM From 177f672ad4b37b2f8418a7094f4807ba3d7e5205 Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 3 Jun 2026 15:51:59 +0200 Subject: [PATCH 689/704] Bring back overlap_main --- src/main.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/src/main.c b/src/main.c index 1e39c6e..1c9dd1f 100644 --- a/src/main.c +++ b/src/main.c @@ -482,6 +482,61 @@ allele_main(int argc, char* argv[static argc]) } // allele_main +int +overlap_main(int argc, char* argv[static argc]) +{ + (void) argv; + + size_t line_count = 0; + static char line[LINE_SIZE] = {0}; + while (fgets(line, sizeof(line), stdin) != NULL) + { + line_count += 1; + size_t start = 0; + size_t end = 0; + + end = strcspn(line, "\t "); + GVA_String reference = {end, line + start}; + + start += end + 1; + end = strcspn(line + start, "\t "); + + GVA_Variant lhs_variant = {0}; + if (gva_parse_spdi(end, line + start, &lhs_variant) == 0) + { + fprintf(stderr, "Error parsing LHS SPDI at line %zu: %s", line_count, line); + continue; + } // if + + start += end + 1; + end = strcspn(line + start, "\n\t "); + + GVA_Variant rhs_variant = {0}; + if (gva_parse_spdi(end, line + start, &rhs_variant) == 0) + { + fprintf(stderr, "Error parsing RHS SPDI at line %zu: %s", line_count, line); + continue; + } // if + + uint8_t* lhs_dfa = dfa_from_alignment(gva_std_allocator, NULL, lhs_variant.end - lhs_variant.start, reference.str + lhs_variant.start, lhs_variant.sequence.len, lhs_variant.sequence.str); + uint8_t* rhs_dfa = dfa_from_alignment(gva_std_allocator, NULL, rhs_variant.end - rhs_variant.start, reference.str + rhs_variant.start, rhs_variant.sequence.len, rhs_variant.sequence.str); + + ///dfa_dot(stdout, reference.len, reference.str, lhs_variant, lhs_dfa); + ///dfa_dot(stdout, reference.len, reference.str, rhs_variant, rhs_dfa); + + fprintf(stdout, "%zu\n", dfa_overlap(gva_std_allocator, + reference.len, reference.str, + lhs_variant, lhs_dfa, + rhs_variant, rhs_dfa)); + + rhs_dfa = ARRAY_DESTROY(gva_std_allocator, rhs_dfa); + lhs_dfa = ARRAY_DESTROY(gva_std_allocator, lhs_dfa); + } // while + + return EXIT_SUCCESS; +} // overlap_main + + typedef struct { gva_uint start; From 3645efce2645b4b376f4f946a40c507fc85c53ef Mon Sep 17 00:00:00 2001 From: jkvis Date: Wed, 3 Jun 2026 15:52:33 +0200 Subject: [PATCH 690/704] WIP: improvements on dfa_overlap --- src/dfa.c | 48 ++++++++++++++++++++---------------------------- 1 file changed, 20 insertions(+), 28 deletions(-) diff --git a/src/dfa.c b/src/dfa.c index a3ef97e..eb3164e 100644 --- a/src/dfa.c +++ b/src/dfa.c @@ -434,32 +434,28 @@ dfa_overlap(GVA_Allocator const allocator, break; } // if + size_t const included = queue.entries[HASH_TABLE_INDEX(queue.entries, idx)].included; + size_t const lhs_idx = idx / rhs_size; size_t const rhs_idx = idx % rhs_size; size_t const lhs_ref = lhs_idx / lhs_width + lhs.start; size_t const rhs_ref = rhs_idx / rhs_width + rhs.start; - size_t const included = queue.entries[HASH_TABLE_INDEX(queue.entries, idx)].included; if ((lhs_idx == 0 && rhs_ref < lhs_ref) || lhs_idx == lhs_size - 1) { - uint8_t const rhs_value = get(rhs_dfa, rhs_idx); - bool const rhs_match = rhs_idx % rhs_width < rhs_width - 1 && - reference[rhs.start + rhs_idx / rhs_width] == rhs.sequence.str[rhs_idx % rhs_width]; - - if (rhs_match) + if (rhs_idx % rhs_width < rhs_width - 1 && + reference[rhs.start + rhs_idx / rhs_width] == rhs.sequence.str[rhs_idx % rhs_width]) { queue_push_front(&queue, lhs_idx * rhs_size + rhs_idx + rhs_width + 1, included); continue; } // if - bool const rhs_deletion = rhs_value & DFA_DELETION; - bool const rhs_insertion = rhs_value & DFA_INSERTION; - - if (rhs_deletion) + uint8_t const rhs_value = get(rhs_dfa, rhs_idx); + if (rhs_value & DFA_DELETION) { queue_push_back(&queue, lhs_idx * rhs_size + rhs_idx + rhs_width, included); } // if - if (rhs_insertion) + if (rhs_value & DFA_INSERTION) { queue_push_back(&queue, lhs_idx * rhs_size + rhs_idx + 1, included); } // if @@ -468,34 +464,27 @@ dfa_overlap(GVA_Allocator const allocator, if ((rhs_idx == 0 && lhs_ref < rhs_ref) || rhs_idx == rhs_size - 1) { - uint8_t const lhs_value = get(lhs_dfa, lhs_idx); - bool const lhs_match = lhs_idx % lhs_width < lhs_width - 1 && - reference[lhs.start + lhs_idx / lhs_width] == lhs.sequence.str[lhs_idx % lhs_width]; - - if (lhs_match) + if (lhs_idx % lhs_width < lhs_width - 1 && + reference[lhs.start + lhs_idx / lhs_width] == lhs.sequence.str[lhs_idx % lhs_width]) { queue_push_front(&queue, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx, included); continue; } // if - bool const lhs_deletion = lhs_value & DFA_DELETION; - bool const lhs_insertion = lhs_value & DFA_INSERTION; - - if (lhs_deletion) + uint8_t const lhs_value = get(lhs_dfa, lhs_idx); + if (lhs_value & DFA_DELETION) { queue_push_back(&queue, (lhs_idx + lhs_width) * rhs_size + rhs_idx, included); } // if - if (lhs_insertion) + if (lhs_value & DFA_INSERTION) { queue_push_back(&queue, (lhs_idx + 1) * rhs_size + rhs_idx, included); } // if continue; } // if - uint8_t const lhs_value = get(lhs_dfa, lhs_idx); bool const lhs_match = lhs_idx % lhs_width < lhs_width - 1 && reference[lhs.start + lhs_idx / lhs_width] == lhs.sequence.str[lhs_idx % lhs_width]; - uint8_t const rhs_value = get(rhs_dfa, rhs_idx); bool const rhs_match = rhs_idx % rhs_width < rhs_width - 1 && reference[rhs.start + rhs_idx / rhs_width] == rhs.sequence.str[rhs_idx % rhs_width]; @@ -505,8 +494,11 @@ dfa_overlap(GVA_Allocator const allocator, continue; } // if + uint8_t const lhs_value = get(lhs_dfa, lhs_idx); bool const lhs_deletion = lhs_value & DFA_DELETION; bool const lhs_insertion = lhs_value & DFA_INSERTION; + + uint8_t const rhs_value = get(rhs_dfa, rhs_idx); bool const rhs_deletion = rhs_value & DFA_DELETION; bool const rhs_insertion = rhs_value & DFA_INSERTION; @@ -515,11 +507,6 @@ dfa_overlap(GVA_Allocator const allocator, queue_push_front(&queue, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width, included + 1); } // if - if (lhs_insertion && rhs_insertion && lhs.sequence.str[lhs_idx % lhs_width] == rhs.sequence.str[rhs_idx % rhs_width]) - { - queue_push_front(&queue, (lhs_idx + 1) * rhs_size + rhs_idx + 1, included + 1); - } // if - if (lhs_deletion && rhs_match) { queue_push_back(&queue, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width + 1, included); @@ -528,6 +515,11 @@ dfa_overlap(GVA_Allocator const allocator, { queue_push_back(&queue, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx + rhs_width, included); } // if + else if (lhs_insertion && rhs_insertion && + lhs.sequence.str[lhs_idx % lhs_width] == rhs.sequence.str[rhs_idx % rhs_width]) + { + queue_push_front(&queue, (lhs_idx + 1) * rhs_size + rhs_idx + 1, included + 1); + } // if if (lhs_insertion && (rhs_deletion || rhs_match || (rhs_insertion && lhs.sequence.str[lhs_idx % lhs_width] != rhs.sequence.str[rhs_idx % rhs_width]))) From 06c3a6ae6b3f49be59865ab17d375578840cb88c Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 4 Jun 2026 11:22:37 +0200 Subject: [PATCH 691/704] Debug info for dfa_overlap --- include/mmap_alloc.h | 2 +- src/dfa.c | 28 ++++++++++++++++++++++++---- src/main.c | 3 ++- 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/include/mmap_alloc.h b/include/mmap_alloc.h index 4e63b8e..f4b2aca 100644 --- a/include/mmap_alloc.h +++ b/include/mmap_alloc.h @@ -7,7 +7,7 @@ typedef struct { - void* addr; + void* addr; // this *must* be the first field size_t len; int fd; } GVA_Mmap_Context; diff --git a/src/dfa.c b/src/dfa.c index eb3164e..cbfc322 100644 --- a/src/dfa.c +++ b/src/dfa.c @@ -419,6 +419,8 @@ dfa_overlap(GVA_Allocator const allocator, size_t const lhs_size = (lhs.end - lhs.start + 1) * lhs_width; size_t const rhs_size = (rhs.end - rhs.start + 1) * rhs_width; + fprintf(stderr, "strict digraph{\nrankdir=LR\nnode[shape=none]\n"); + Queue queue = queue_init(allocator, INITIAL_SIZE); if (queue.entries == NULL) { @@ -429,10 +431,6 @@ dfa_overlap(GVA_Allocator const allocator, while (!queue_empty(&queue)) { size_t const idx = queue_pop(&queue); - if (idx == lhs_size * rhs_size - 1) // OVERFLOW - { - break; - } // if size_t const included = queue.entries[HASH_TABLE_INDEX(queue.entries, idx)].included; @@ -441,11 +439,19 @@ dfa_overlap(GVA_Allocator const allocator, size_t const lhs_ref = lhs_idx / lhs_width + lhs.start; size_t const rhs_ref = rhs_idx / rhs_width + rhs.start; + fprintf(stderr, "%zu[fixedsize=true,label=\"(%zu, %zu)\\n%zu\",shape=circle,width=1]\n", idx, lhs_idx, rhs_idx, included); + + if (idx == lhs_size * rhs_size - 1) // OVERFLOW + { + break; + } // if + if ((lhs_idx == 0 && rhs_ref < lhs_ref) || lhs_idx == lhs_size - 1) { if (rhs_idx % rhs_width < rhs_width - 1 && reference[rhs.start + rhs_idx / rhs_width] == rhs.sequence.str[rhs_idx % rhs_width]) { + fprintf(stderr, "%zu->%zu\n", idx, lhs_idx * rhs_size + rhs_idx + rhs_width + 1); queue_push_front(&queue, lhs_idx * rhs_size + rhs_idx + rhs_width + 1, included); continue; } // if @@ -453,10 +459,12 @@ dfa_overlap(GVA_Allocator const allocator, uint8_t const rhs_value = get(rhs_dfa, rhs_idx); if (rhs_value & DFA_DELETION) { + fprintf(stderr, "%zu->%zu\n", idx, lhs_idx * rhs_size + rhs_idx + rhs_width); queue_push_back(&queue, lhs_idx * rhs_size + rhs_idx + rhs_width, included); } // if if (rhs_value & DFA_INSERTION) { + fprintf(stderr, "%zu->%zu\n", idx, lhs_idx * rhs_size + rhs_idx + 1); queue_push_back(&queue, lhs_idx * rhs_size + rhs_idx + 1, included); } // if continue; @@ -467,6 +475,7 @@ dfa_overlap(GVA_Allocator const allocator, if (lhs_idx % lhs_width < lhs_width - 1 && reference[lhs.start + lhs_idx / lhs_width] == lhs.sequence.str[lhs_idx % lhs_width]) { + fprintf(stderr, "%zu->%zu\n", idx, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx); queue_push_front(&queue, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx, included); continue; } // if @@ -474,10 +483,12 @@ dfa_overlap(GVA_Allocator const allocator, uint8_t const lhs_value = get(lhs_dfa, lhs_idx); if (lhs_value & DFA_DELETION) { + fprintf(stderr, "%zu->%zu\n", idx, (lhs_idx + lhs_width) * rhs_size + rhs_idx); queue_push_back(&queue, (lhs_idx + lhs_width) * rhs_size + rhs_idx, included); } // if if (lhs_value & DFA_INSERTION) { + fprintf(stderr, "%zu->%zu\n", idx, (lhs_idx + 1) * rhs_size + rhs_idx); queue_push_back(&queue, (lhs_idx + 1) * rhs_size + rhs_idx, included); } // if continue; @@ -490,6 +501,7 @@ dfa_overlap(GVA_Allocator const allocator, if (lhs_match && rhs_match) { + fprintf(stderr, "%zu->%zu\n", idx, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx + rhs_width + 1); queue_push_front(&queue, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx + rhs_width + 1, included); continue; } // if @@ -504,36 +516,44 @@ dfa_overlap(GVA_Allocator const allocator, if (lhs_deletion && rhs_deletion) { + fprintf(stderr, "%zu->%zu[label=\"Δ +1\"]\n", idx, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width); queue_push_front(&queue, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width, included + 1); } // if if (lhs_deletion && rhs_match) { + fprintf(stderr, "%zu->%zu\n", idx, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width + 1); queue_push_back(&queue, (lhs_idx + lhs_width) * rhs_size + rhs_idx + rhs_width + 1, included); } // if else if (lhs_match && rhs_deletion) { + fprintf(stderr, "%zu->%zu\n", idx, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx + rhs_width); queue_push_back(&queue, (lhs_idx + lhs_width + 1) * rhs_size + rhs_idx + rhs_width, included); } // if else if (lhs_insertion && rhs_insertion && lhs.sequence.str[lhs_idx % lhs_width] == rhs.sequence.str[rhs_idx % rhs_width]) { + fprintf(stderr, "%zu->%zu[label=\"%c +1\"]\n", idx, (lhs_idx + 1) * rhs_size + rhs_idx + 1, lhs.sequence.str[lhs_idx % lhs_width]); queue_push_front(&queue, (lhs_idx + 1) * rhs_size + rhs_idx + 1, included + 1); } // if if (lhs_insertion && (rhs_deletion || rhs_match || (rhs_insertion && lhs.sequence.str[lhs_idx % lhs_width] != rhs.sequence.str[rhs_idx % rhs_width]))) { + fprintf(stderr, "%zu->%zu\n", idx, (lhs_idx + 1) * rhs_size + rhs_idx); queue_push_back(&queue, (lhs_idx + 1) * rhs_size + rhs_idx, included); } // if if (rhs_insertion && (lhs_deletion || lhs_match || (lhs_insertion && lhs.sequence.str[lhs_idx % lhs_width] != rhs.sequence.str[rhs_idx % rhs_width]))) { + fprintf(stderr, "%zu->%zu\n", idx, lhs_idx * rhs_size + rhs_idx + 1); queue_push_back(&queue, lhs_idx * rhs_size + rhs_idx + 1, included); } // if } // while + fprintf(stderr, "}\n"); + size_t included = 0; size_t const idx = HASH_TABLE_INDEX(queue.entries, lhs_size * rhs_size - 1); if (queue.entries[idx].gva_key == lhs_size * rhs_size - 1) diff --git a/src/main.c b/src/main.c index 1c9dd1f..f94d67c 100644 --- a/src/main.c +++ b/src/main.c @@ -742,6 +742,7 @@ int main(int argc, char* argv[static argc]) { // return allele_main(argc, argv); - return index_main(argc, argv); + return overlap_main(argc, argv); + // return index_main(argc, argv); // return all_main(argc, argv); } // main From ca861a0b9aceaee5229defe5c203082c73e6be9e Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 8 Jun 2026 18:50:00 +0200 Subject: [PATCH 692/704] WIP: allele extractor --- src/lcs_graph.c | 40 +++++++++++++++++++++++++++---- src/main.c | 63 +++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 95 insertions(+), 8 deletions(-) diff --git a/src/lcs_graph.c b/src/lcs_graph.c index 2b6f131..c2e47af 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -14,6 +14,9 @@ #include "common.h" // GVA_NULL, MAX, MIN, gva_uint +#include // FIXME: DEBUG + + static void concat(GVA_Allocator const allocator, GVA_LCS_Graph lhs[static 1], GVA_LCS_Graph const rhs, @@ -86,9 +89,12 @@ local_supremal(GVA_Allocator const allocator, size_t const offset_row, size_t const offset_col, GVA_LCS_Graph graph[static restrict 1]) { + fprintf(stderr, GVA_STRING_FMT " vs " GVA_STRING_FMT "\n", GVA_STRING_PRINT(((GVA_String) {len_ref, reference})), GVA_STRING_PRINT(((GVA_String) {len_obs, observed}))); + if (len_ref == 0 || len_obs == 0) { GVA_LCS_Graph local = gva_lcs_graph_init(allocator, len_ref, reference, len_obs, observed, offset_row); + fprintf(stderr, "BASE: " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(gva_lcs_graph_supremal(local))); concat(allocator, graph, local, offset_col); gva_lcs_graph_destroy(allocator, local, false); return; @@ -108,6 +114,11 @@ local_supremal(GVA_Allocator const allocator, for (size_t i = 0; i < forward.max_lcs_pos; ++i) { size_t const j = forward.max_lcs_pos - i - 1; + + fprintf(stderr, "%zu: (%zu, %zu) %d (%zu, %zu) %d\n", i, + forward.match[i].row + offset_row, forward.match[i].col + offset_col, forward.uniq[i], + len_ref - backward.match[j].row - 1, len_obs - backward.match[j].col - 1, backward.uniq[j]); + if (forward.match[i].row == len_ref - backward.match[j].row - 1 && forward.match[i].col == len_obs - backward.match[j].col - 1 && (forward.uniq[i] == 1 || backward.uniq[j] == 1)) @@ -121,6 +132,7 @@ local_supremal(GVA_Allocator const allocator, forward.match[i].col - prev_col - 1, observed + prev_col + 1, offset_row + prev_row + 1, offset_col + prev_col + 1, graph); + fprintf(stderr, "RECURSE %u %u %d %d\n", forward.match[i].row, forward.match[i].col, forward.uniq[i], backward.uniq[j]); } // if prev_row = forward.match[i].row; @@ -130,10 +142,30 @@ local_supremal(GVA_Allocator const allocator, size_t const distance = len_ref + len_obs - 2 * forward.max_lcs_pos - sum; if (distance > 0) { - sum += distance; - GVA_LCS_Graph local = gva_lcs_graph_init(allocator, len_ref - prev_row - 1, reference + prev_row + 1, len_obs - prev_col - 1, observed + prev_col + 1, offset_row + prev_row + 1); - concat(allocator, graph, local, offset_col + prev_col + 1); - gva_lcs_graph_destroy(allocator, local, false); + if (prev_row != (size_t) -1) + { + local_supremal(allocator, + len_ref - prev_row - 1, reference + prev_row + 1, + len_obs - prev_col - 1, observed + prev_col + 1, + offset_row + prev_row + 1, offset_col + prev_col + 1, + graph); + fprintf(stderr, "RECURSE last\n"); + } // if + else + { + GVA_LCS_Graph local = gva_lcs_graph_init(allocator, len_ref - prev_row - 1, reference + prev_row + 1, len_obs - prev_col - 1, observed + prev_col + 1, offset_row + prev_row + 1); + fprintf(stderr, GVA_VARIANT_FMT " %zu\n", GVA_VARIANT_PRINT(gva_lcs_graph_supremal(local)), gva_variant_length(gva_lcs_graph_supremal(local))); + if (array_length(local.dom_nodes) > 2) + { + fprintf(stderr, "MULTI\n"); + for (size_t i = 0; i < array_length(local.dom_nodes) - 1; ++i) + { + fprintf(stderr, " " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(gva_lcs_graph_local_supremal(local, i, i + 1))); + } // for + } // if + concat(allocator, graph, local, offset_col + prev_col + 1); + gva_lcs_graph_destroy(allocator, local, false); + } // else } // if backward.match = allocator.allocate(allocator.context, backward.match, MIN(len_ref, len_obs), 0); diff --git a/src/main.c b/src/main.c index 1c9dd1f..e170319 100644 --- a/src/main.c +++ b/src/main.c @@ -16,6 +16,7 @@ #include "../include/string.h" // GVA_String, gva_string_destroy #include "../include/utils.h" // gva_fasta_sequence* #include "../include/variant.h" // GVA_VARIANT_*, GVA_Variant, gva_patch, gva_variant_* +#include "align.h" #include "array.h" // ARRAY_*, array_length #include "common.h" // MAX, MIN #include "dfa.h" // dfa_* @@ -24,9 +25,9 @@ #define LINE_SIZE 4096 -// #define REFERENCE_ID "NC_000022.11" +#define REFERENCE_ID "NC_000022.11" // #define REFERENCE_ID "NC_000006.12" -#define REFERENCE_ID "NC_000001.11" +// #define REFERENCE_ID "NC_000001.11" // line: alphanumeric_id SPDI [distance] @@ -394,9 +395,62 @@ index_main(int argc, char* argv[static argc]) } // index_main +void +random_string(size_t const len, char str[static len]) +{ + for (size_t i = 0; i < len; ++i) + { + str[i] = "ACGT"[rand() % 4]; + } // for +} // random_string + + int allele_main(int argc, char* argv[static argc]) { + if (argc < 2) + { + fprintf(stderr, "usage: %s seed\n", argv[0]); + return EXIT_FAILURE; + } // if + + srand(atoi(argv[1])); + + GVA_String ref = gva_string_dup(gva_std_allocator, (GVA_String) {10, "GGCTGAATAC"}); + GVA_Variant var = {0, 10, {10, "TAGAACAGCA"}}; + + LCS_Alignment lcs = lcs_align(gva_std_allocator, ref.len, ref.str, var.sequence.len, var.sequence.str, 0); + + fprintf(stderr, "%zu\n", lcs.length); + for (size_t i = 0; i < lcs.length; ++i) + { + fprintf(stderr, "%zu: ", i); + for (gva_uint j = lcs.index[i].head; j != GVA_NULL; j = lcs.nodes[j].next) + { + fprintf(stderr, "(%u, %u, %u) ", lcs.nodes[j].match.row, lcs.nodes[j].match.col, lcs.nodes[j].match.length); + } // for + fprintf(stderr, "\n"); + } // for + + lcs.index = gva_std_allocator.allocate(gva_std_allocator.context, lcs.index, lcs.length * sizeof(*lcs.index), 0); + lcs.nodes = ARRAY_DESTROY(gva_std_allocator, lcs.nodes); + + GVA_LCS_Graph g = gva_lcs_graph_from_allele(gva_std_allocator, ref.len, ref.str, 1, &var); + + fprintf(stderr, GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(gva_lcs_graph_supremal(g))); + for (size_t i = 0; i < array_length(g.dom_nodes) - 1; ++i) + { + fprintf(stderr, " " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(gva_lcs_graph_local_supremal(g, i, i + 1))); + } // for + fprintf(stderr, "\n"); + + gva_lcs_graph_destroy(gva_std_allocator, g, true); + + gva_string_destroy(gva_std_allocator, ref); + + return EXIT_SUCCESS; + + if (argc < 3) { fprintf(stderr, "usage: %s reference observed\n", argv[0]); @@ -741,7 +795,8 @@ all_main(int argc, char* argv[static argc]) int main(int argc, char* argv[static argc]) { - // return allele_main(argc, argv); - return index_main(argc, argv); + return allele_main(argc, argv); + // return index_main(argc, argv); + // return overlap_main(argc, argv); // return all_main(argc, argv); } // main From b28cff5cd7d3852b016127de01d91465ad8fa64c Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 8 Jun 2026 22:51:09 +0200 Subject: [PATCH 693/704] WIP: random variants for allele extractor --- src/lcs_graph.c | 10 ++++++---- src/main.c | 31 +++++++++++++++++++++---------- 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/src/lcs_graph.c b/src/lcs_graph.c index c2e47af..50ecbce 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -115,8 +115,8 @@ local_supremal(GVA_Allocator const allocator, { size_t const j = forward.max_lcs_pos - i - 1; - fprintf(stderr, "%zu: (%zu, %zu) %d (%zu, %zu) %d\n", i, - forward.match[i].row + offset_row, forward.match[i].col + offset_col, forward.uniq[i], + fprintf(stderr, "%zu: (%u, %u) %d (%zu, %zu) %d\n", i, + forward.match[i].row, forward.match[i].col, forward.uniq[i], len_ref - backward.match[j].row - 1, len_obs - backward.match[j].col - 1, backward.uniq[j]); if (forward.match[i].row == len_ref - backward.match[j].row - 1 && @@ -127,12 +127,13 @@ local_supremal(GVA_Allocator const allocator, if (distance > 0) { sum += distance; + fprintf(stderr, "RECURSE %u %u %d %d {\n", forward.match[i].row, forward.match[i].col, forward.uniq[i], backward.uniq[j]); local_supremal(allocator, forward.match[i].row - prev_row - 1, reference + prev_row + 1, forward.match[i].col - prev_col - 1, observed + prev_col + 1, offset_row + prev_row + 1, offset_col + prev_col + 1, graph); - fprintf(stderr, "RECURSE %u %u %d %d\n", forward.match[i].row, forward.match[i].col, forward.uniq[i], backward.uniq[j]); + fprintf(stderr, "}\n"); } // if prev_row = forward.match[i].row; @@ -144,12 +145,13 @@ local_supremal(GVA_Allocator const allocator, { if (prev_row != (size_t) -1) { + fprintf(stderr, "RECURSE {\n"); local_supremal(allocator, len_ref - prev_row - 1, reference + prev_row + 1, len_obs - prev_col - 1, observed + prev_col + 1, offset_row + prev_row + 1, offset_col + prev_col + 1, graph); - fprintf(stderr, "RECURSE last\n"); + fprintf(stderr, "}\n"); } // if else { diff --git a/src/main.c b/src/main.c index e170319..9c028bd 100644 --- a/src/main.c +++ b/src/main.c @@ -416,9 +416,13 @@ allele_main(int argc, char* argv[static argc]) srand(atoi(argv[1])); - GVA_String ref = gva_string_dup(gva_std_allocator, (GVA_String) {10, "GGCTGAATAC"}); - GVA_Variant var = {0, 10, {10, "TAGAACAGCA"}}; + GVA_String ref = gva_string_init(gva_std_allocator, 10); + GVA_Variant var = {0, ref.len, gva_string_init(gva_std_allocator, 10)}; + //GVA_String ref = gva_string_dup(gva_std_allocator, (GVA_String) {10, "GGCTGAATAC"}); + //GVA_Variant var = {0, ref.len, {10, "TAGAACAGCA"}}; + +/* LCS_Alignment lcs = lcs_align(gva_std_allocator, ref.len, ref.str, var.sequence.len, var.sequence.str, 0); fprintf(stderr, "%zu\n", lcs.length); @@ -434,18 +438,25 @@ allele_main(int argc, char* argv[static argc]) lcs.index = gva_std_allocator.allocate(gva_std_allocator.context, lcs.index, lcs.length * sizeof(*lcs.index), 0); lcs.nodes = ARRAY_DESTROY(gva_std_allocator, lcs.nodes); +*/ + for (size_t i = 0; i < 20; ++i) + { + random_string(ref.len, (char*) ref.str); + random_string(var.sequence.len, (char*) var.sequence.str); - GVA_LCS_Graph g = gva_lcs_graph_from_allele(gva_std_allocator, ref.len, ref.str, 1, &var); + GVA_LCS_Graph g = gva_lcs_graph_from_allele(gva_std_allocator, ref.len, ref.str, 1, &var); - fprintf(stderr, GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(gva_lcs_graph_supremal(g))); - for (size_t i = 0; i < array_length(g.dom_nodes) - 1; ++i) - { - fprintf(stderr, " " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(gva_lcs_graph_local_supremal(g, i, i + 1))); - } // for - fprintf(stderr, "\n"); + fprintf(stderr, GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(gva_lcs_graph_supremal(g))); + for (size_t i = 0; i < array_length(g.dom_nodes) - 1; ++i) + { + fprintf(stderr, " " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(gva_lcs_graph_local_supremal(g, i, i + 1))); + } // for + fprintf(stderr, "\n"); - gva_lcs_graph_destroy(gva_std_allocator, g, true); + gva_lcs_graph_destroy(gva_std_allocator, g, true); + } // for + gva_string_destroy(gva_std_allocator, var.sequence); gva_string_destroy(gva_std_allocator, ref); return EXIT_SUCCESS; From 4917ea3de429c3f2e162ba3f2111564544920dfa Mon Sep 17 00:00:00 2001 From: jkvis Date: Tue, 9 Jun 2026 10:30:00 +0200 Subject: [PATCH 694/704] WIP: checking allele extractor with 1kg --- src/lcs_graph.c | 28 +++++++++++++++++++++------- src/main.c | 41 ++++++++++++++++++++++++++--------------- 2 files changed, 47 insertions(+), 22 deletions(-) diff --git a/src/lcs_graph.c b/src/lcs_graph.c index 50ecbce..d6c9e8f 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -81,6 +81,12 @@ concat(GVA_Allocator const allocator, } // concat +/* +int multi; +int recurse; +int base; +*/ + // FIXME: recursion! static void local_supremal(GVA_Allocator const allocator, @@ -89,12 +95,13 @@ local_supremal(GVA_Allocator const allocator, size_t const offset_row, size_t const offset_col, GVA_LCS_Graph graph[static restrict 1]) { - fprintf(stderr, GVA_STRING_FMT " vs " GVA_STRING_FMT "\n", GVA_STRING_PRINT(((GVA_String) {len_ref, reference})), GVA_STRING_PRINT(((GVA_String) {len_obs, observed}))); + //fprintf(stderr, GVA_STRING_FMT " vs " GVA_STRING_FMT "\n", GVA_STRING_PRINT(((GVA_String) {len_ref, reference})), GVA_STRING_PRINT(((GVA_String) {len_obs, observed}))); if (len_ref == 0 || len_obs == 0) { + //base += 1; GVA_LCS_Graph local = gva_lcs_graph_init(allocator, len_ref, reference, len_obs, observed, offset_row); - fprintf(stderr, "BASE: " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(gva_lcs_graph_supremal(local))); + //fprintf(stderr, "BASE: " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(gva_lcs_graph_supremal(local))); concat(allocator, graph, local, offset_col); gva_lcs_graph_destroy(allocator, local, false); return; @@ -115,9 +122,11 @@ local_supremal(GVA_Allocator const allocator, { size_t const j = forward.max_lcs_pos - i - 1; + /* fprintf(stderr, "%zu: (%u, %u) %d (%zu, %zu) %d\n", i, forward.match[i].row, forward.match[i].col, forward.uniq[i], len_ref - backward.match[j].row - 1, len_obs - backward.match[j].col - 1, backward.uniq[j]); + */ if (forward.match[i].row == len_ref - backward.match[j].row - 1 && forward.match[i].col == len_obs - backward.match[j].col - 1 && @@ -126,14 +135,15 @@ local_supremal(GVA_Allocator const allocator, size_t const distance = forward.match[i].row + forward.match[i].col - 2 * i - sum; if (distance > 0) { + //recurse += 1; sum += distance; - fprintf(stderr, "RECURSE %u %u %d %d {\n", forward.match[i].row, forward.match[i].col, forward.uniq[i], backward.uniq[j]); + //fprintf(stderr, "RECURSE %u %u %d %d {\n", forward.match[i].row, forward.match[i].col, forward.uniq[i], backward.uniq[j]); local_supremal(allocator, forward.match[i].row - prev_row - 1, reference + prev_row + 1, forward.match[i].col - prev_col - 1, observed + prev_col + 1, offset_row + prev_row + 1, offset_col + prev_col + 1, graph); - fprintf(stderr, "}\n"); + //fprintf(stderr, "}\n"); } // if prev_row = forward.match[i].row; @@ -145,26 +155,30 @@ local_supremal(GVA_Allocator const allocator, { if (prev_row != (size_t) -1) { - fprintf(stderr, "RECURSE {\n"); + //recurse += 1; + //fprintf(stderr, "RECURSE {\n"); local_supremal(allocator, len_ref - prev_row - 1, reference + prev_row + 1, len_obs - prev_col - 1, observed + prev_col + 1, offset_row + prev_row + 1, offset_col + prev_col + 1, graph); - fprintf(stderr, "}\n"); + //fprintf(stderr, "}\n"); } // if else { GVA_LCS_Graph local = gva_lcs_graph_init(allocator, len_ref - prev_row - 1, reference + prev_row + 1, len_obs - prev_col - 1, observed + prev_col + 1, offset_row + prev_row + 1); + /* fprintf(stderr, GVA_VARIANT_FMT " %zu\n", GVA_VARIANT_PRINT(gva_lcs_graph_supremal(local)), gva_variant_length(gva_lcs_graph_supremal(local))); - if (array_length(local.dom_nodes) > 2) + if (array_length(local.dom_nodes) == 3) { + multi = 1; fprintf(stderr, "MULTI\n"); for (size_t i = 0; i < array_length(local.dom_nodes) - 1; ++i) { fprintf(stderr, " " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(gva_lcs_graph_local_supremal(local, i, i + 1))); } // for } // if + */ concat(allocator, graph, local, offset_col + prev_col + 1); gva_lcs_graph_destroy(allocator, local, false); } // else diff --git a/src/main.c b/src/main.c index 9c028bd..3b1caef 100644 --- a/src/main.c +++ b/src/main.c @@ -404,10 +404,15 @@ random_string(size_t const len, char str[static len]) } // for } // random_string +extern int base; +extern int recurse; +extern int multi; + int allele_main(int argc, char* argv[static argc]) { +/* if (argc < 2) { fprintf(stderr, "usage: %s seed\n", argv[0]); @@ -416,13 +421,12 @@ allele_main(int argc, char* argv[static argc]) srand(atoi(argv[1])); - GVA_String ref = gva_string_init(gva_std_allocator, 10); - GVA_Variant var = {0, ref.len, gva_string_init(gva_std_allocator, 10)}; + //GVA_String ref = gva_string_init(gva_std_allocator, 10); + //GVA_Variant var = {0, ref.len, gva_string_init(gva_std_allocator, 10)}; - //GVA_String ref = gva_string_dup(gva_std_allocator, (GVA_String) {10, "GGCTGAATAC"}); - //GVA_Variant var = {0, ref.len, {10, "TAGAACAGCA"}}; + GVA_String ref = gva_string_dup(gva_std_allocator, (GVA_String) {10, "CTACCCGGGA"}); + GVA_Variant var = {0, ref.len, {10, "CATAAGAGTG"}}; -/* LCS_Alignment lcs = lcs_align(gva_std_allocator, ref.len, ref.str, var.sequence.len, var.sequence.str, 0); fprintf(stderr, "%zu\n", lcs.length); @@ -438,20 +442,27 @@ allele_main(int argc, char* argv[static argc]) lcs.index = gva_std_allocator.allocate(gva_std_allocator.context, lcs.index, lcs.length * sizeof(*lcs.index), 0); lcs.nodes = ARRAY_DESTROY(gva_std_allocator, lcs.nodes); -*/ - for (size_t i = 0; i < 20; ++i) + + //while (true) { - random_string(ref.len, (char*) ref.str); - random_string(var.sequence.len, (char*) var.sequence.str); + //random_string(ref.len, (char*) ref.str); + //random_string(var.sequence.len, (char*) var.sequence.str); + base = 0; + recurse = 0; + multi = 0; GVA_LCS_Graph g = gva_lcs_graph_from_allele(gva_std_allocator, ref.len, ref.str, 1, &var); - fprintf(stderr, GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(gva_lcs_graph_supremal(g))); - for (size_t i = 0; i < array_length(g.dom_nodes) - 1; ++i) + if (base > 1 && recurse > 2 && multi) { - fprintf(stderr, " " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(gva_lcs_graph_local_supremal(g, i, i + 1))); - } // for - fprintf(stderr, "\n"); + fprintf(stderr, GVA_STRING_FMT " vs " GVA_STRING_FMT "\n", GVA_STRING_PRINT(ref), GVA_STRING_PRINT(var.sequence)); + //fprintf(stderr, GVA_STRING_FMT ":" GVA_VARIANT_FMT "\n", GVA_STRING_PRINT(ref), GVA_VARIANT_PRINT(gva_lcs_graph_supremal(g))); + for (size_t i = 0; i < array_length(g.dom_nodes) - 1; ++i) + { + fprintf(stderr, " " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(gva_lcs_graph_local_supremal(g, i, i + 1))); + } // for + fprintf(stderr, "\n"); + } // if gva_lcs_graph_destroy(gva_std_allocator, g, true); } // for @@ -460,7 +471,7 @@ allele_main(int argc, char* argv[static argc]) gva_string_destroy(gva_std_allocator, ref); return EXIT_SUCCESS; - +*/ if (argc < 3) { From 4013c0a05ab4b3414274b53d75696b7e31dee200 Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Mon, 15 Jun 2026 12:56:49 +0200 Subject: [PATCH 695/704] WIP: sync on last instead of first. --- src/align.c | 9 +++++++-- src/lcs_graph.c | 23 ++++++++++++----------- src/main.c | 14 ++++++-------- 3 files changed, 25 insertions(+), 21 deletions(-) diff --git a/src/align.c b/src/align.c index c772ed7..9b5128d 100644 --- a/src/align.c +++ b/src/align.c @@ -10,6 +10,9 @@ #include "common.h" // ABS, MAX, MIN +#include + + typedef struct { GVA_Allocator const allocator; @@ -236,11 +239,13 @@ onp_snake(size_t const m, char const a[static restrict m], row += 1; col += 1; size_t const lcs_pos = (row + col - ABS(delta) - 2 * p + ABS(d_row - d_col)) / 2; + fprintf(stderr, "M: (%zu, %zu): %zu\n", row - 1, col - 1, lcs_pos); result->uniq[lcs_pos - 1] = 0; if (lcs_pos > result->max_lcs_pos) { result->max_lcs_pos = lcs_pos; - result->uniq[lcs_pos - 1] = 1; + } + // result->uniq[lcs_pos - 1] = 1; if (swapped) { result->match[lcs_pos - 1].row = col - 1; @@ -251,7 +256,7 @@ onp_snake(size_t const m, char const a[static restrict m], result->match[lcs_pos - 1].row = row - 1; result->match[lcs_pos - 1].col = col - 1; } // else - } // if + // } // if } // while return col; diff --git a/src/lcs_graph.c b/src/lcs_graph.c index d6c9e8f..6922c7a 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -95,22 +95,24 @@ local_supremal(GVA_Allocator const allocator, size_t const offset_row, size_t const offset_col, GVA_LCS_Graph graph[static restrict 1]) { - //fprintf(stderr, GVA_STRING_FMT " vs " GVA_STRING_FMT "\n", GVA_STRING_PRINT(((GVA_String) {len_ref, reference})), GVA_STRING_PRINT(((GVA_String) {len_obs, observed}))); + fprintf(stderr, GVA_STRING_FMT " vs " GVA_STRING_FMT "\n", GVA_STRING_PRINT(((GVA_String) {len_ref, reference})), GVA_STRING_PRINT(((GVA_String) {len_obs, observed}))); if (len_ref == 0 || len_obs == 0) { //base += 1; GVA_LCS_Graph local = gva_lcs_graph_init(allocator, len_ref, reference, len_obs, observed, offset_row); - //fprintf(stderr, "BASE: " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(gva_lcs_graph_supremal(local))); + fprintf(stderr, "BASE: " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(gva_lcs_graph_supremal(local))); concat(allocator, graph, local, offset_col); gva_lcs_graph_destroy(allocator, local, false); return; } // if + fprintf(stderr, "F\n"); LCS_Matches forward = lcs_align_one(allocator, len_ref, reference, len_obs, observed); gva_string_reverse(len_ref, (char*) reference); gva_string_reverse(len_obs, (char*) observed); + fprintf(stderr, "B\n"); LCS_Matches backward = lcs_align_one(allocator, len_ref, reference, len_obs, observed); gva_string_reverse(len_ref, (char*) reference); gva_string_reverse(len_obs, (char*) observed); @@ -122,28 +124,27 @@ local_supremal(GVA_Allocator const allocator, { size_t const j = forward.max_lcs_pos - i - 1; - /* fprintf(stderr, "%zu: (%u, %u) %d (%zu, %zu) %d\n", i, forward.match[i].row, forward.match[i].col, forward.uniq[i], len_ref - backward.match[j].row - 1, len_obs - backward.match[j].col - 1, backward.uniq[j]); - */ if (forward.match[i].row == len_ref - backward.match[j].row - 1 && - forward.match[i].col == len_obs - backward.match[j].col - 1 && - (forward.uniq[i] == 1 || backward.uniq[j] == 1)) + forward.match[i].col == len_obs - backward.match[j].col - 1 // && + // (forward.uniq[i] == 1 || backward.uniq[j] == 1) + ) { size_t const distance = forward.match[i].row + forward.match[i].col - 2 * i - sum; if (distance > 0) { //recurse += 1; sum += distance; - //fprintf(stderr, "RECURSE %u %u %d %d {\n", forward.match[i].row, forward.match[i].col, forward.uniq[i], backward.uniq[j]); + fprintf(stderr, "RECURSE %u %u %d %d {\n", forward.match[i].row, forward.match[i].col, forward.uniq[i], backward.uniq[j]); local_supremal(allocator, forward.match[i].row - prev_row - 1, reference + prev_row + 1, forward.match[i].col - prev_col - 1, observed + prev_col + 1, offset_row + prev_row + 1, offset_col + prev_col + 1, graph); - //fprintf(stderr, "}\n"); + fprintf(stderr, "}\n"); } // if prev_row = forward.match[i].row; @@ -156,19 +157,19 @@ local_supremal(GVA_Allocator const allocator, if (prev_row != (size_t) -1) { //recurse += 1; - //fprintf(stderr, "RECURSE {\n"); + fprintf(stderr, "RECURSE {\n"); local_supremal(allocator, len_ref - prev_row - 1, reference + prev_row + 1, len_obs - prev_col - 1, observed + prev_col + 1, offset_row + prev_row + 1, offset_col + prev_col + 1, graph); - //fprintf(stderr, "}\n"); + fprintf(stderr, "}\n"); } // if else { GVA_LCS_Graph local = gva_lcs_graph_init(allocator, len_ref - prev_row - 1, reference + prev_row + 1, len_obs - prev_col - 1, observed + prev_col + 1, offset_row + prev_row + 1); - /* fprintf(stderr, GVA_VARIANT_FMT " %zu\n", GVA_VARIANT_PRINT(gva_lcs_graph_supremal(local)), gva_variant_length(gva_lcs_graph_supremal(local))); + /* if (array_length(local.dom_nodes) == 3) { multi = 1; diff --git a/src/main.c b/src/main.c index 3b1caef..f55b27b 100644 --- a/src/main.c +++ b/src/main.c @@ -412,7 +412,6 @@ extern int multi; int allele_main(int argc, char* argv[static argc]) { -/* if (argc < 2) { fprintf(stderr, "usage: %s seed\n", argv[0]); @@ -424,8 +423,8 @@ allele_main(int argc, char* argv[static argc]) //GVA_String ref = gva_string_init(gva_std_allocator, 10); //GVA_Variant var = {0, ref.len, gva_string_init(gva_std_allocator, 10)}; - GVA_String ref = gva_string_dup(gva_std_allocator, (GVA_String) {10, "CTACCCGGGA"}); - GVA_Variant var = {0, ref.len, {10, "CATAAGAGTG"}}; + GVA_String ref = gva_string_dup(gva_std_allocator, (GVA_String) {10, "AGGCGTCGAA"}); + GVA_Variant var = {0, ref.len, {10, "GTGTGTGCGG"}}; LCS_Alignment lcs = lcs_align(gva_std_allocator, ref.len, ref.str, var.sequence.len, var.sequence.str, 0); @@ -448,12 +447,12 @@ allele_main(int argc, char* argv[static argc]) //random_string(ref.len, (char*) ref.str); //random_string(var.sequence.len, (char*) var.sequence.str); - base = 0; - recurse = 0; - multi = 0; + // base = 0; + // recurse = 0; + // multi = 0; GVA_LCS_Graph g = gva_lcs_graph_from_allele(gva_std_allocator, ref.len, ref.str, 1, &var); - if (base > 1 && recurse > 2 && multi) + // if (base > 1 && recurse > 2 && multi) { fprintf(stderr, GVA_STRING_FMT " vs " GVA_STRING_FMT "\n", GVA_STRING_PRINT(ref), GVA_STRING_PRINT(var.sequence)); //fprintf(stderr, GVA_STRING_FMT ":" GVA_VARIANT_FMT "\n", GVA_STRING_PRINT(ref), GVA_VARIANT_PRINT(gva_lcs_graph_supremal(g))); @@ -471,7 +470,6 @@ allele_main(int argc, char* argv[static argc]) gva_string_destroy(gva_std_allocator, ref); return EXIT_SUCCESS; -*/ if (argc < 3) { From 05132f10452023cbb75aa5c1d1f6ff7496c5fe7b Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 18 Jun 2026 14:12:12 +0200 Subject: [PATCH 696/704] WIP: furthest match per LCS pos --- src/align.c | 25 ++++++++++++++++++++++--- src/edit.c | 3 +-- src/lcs_graph.c | 32 ++++++++++++++++++++------------ src/main.c | 28 +++++++++++++++++----------- 4 files changed, 60 insertions(+), 28 deletions(-) diff --git a/src/align.c b/src/align.c index 9b5128d..19cd2c6 100644 --- a/src/align.c +++ b/src/align.c @@ -239,13 +239,11 @@ onp_snake(size_t const m, char const a[static restrict m], row += 1; col += 1; size_t const lcs_pos = (row + col - ABS(delta) - 2 * p + ABS(d_row - d_col)) / 2; - fprintf(stderr, "M: (%zu, %zu): %zu\n", row - 1, col - 1, lcs_pos); + //fprintf(stderr, "M: (%zu, %zu): %zu\n", row - 1, col - 1, lcs_pos); result->uniq[lcs_pos - 1] = 0; if (lcs_pos > result->max_lcs_pos) { result->max_lcs_pos = lcs_pos; - } - // result->uniq[lcs_pos - 1] = 1; if (swapped) { result->match[lcs_pos - 1].row = col - 1; @@ -256,6 +254,27 @@ onp_snake(size_t const m, char const a[static restrict m], result->match[lcs_pos - 1].row = row - 1; result->match[lcs_pos - 1].col = col - 1; } // else + } // if + else + { + // result->uniq[lcs_pos - 1] = 1; + if (swapped) + { + if (result->match[lcs_pos - 1].col < row - 1 || + (result->match[lcs_pos - 1].col == row - 1 && result->match[lcs_pos - 1].row > col - 1)) + result->match[lcs_pos - 1].row = col - 1; + result->match[lcs_pos - 1].col = row - 1; + } // if + else + { + if (result->match[lcs_pos - 1].row < row - 1 || + (result->match[lcs_pos - 1].row == row - 1 && result->match[lcs_pos - 1].col > col - 1)) + { + result->match[lcs_pos - 1].row = row - 1; + result->match[lcs_pos - 1].col = col - 1; + } // if + } // else + } // else // } // if } // while diff --git a/src/edit.c b/src/edit.c index 8da31c8..0aca2d6 100644 --- a/src/edit.c +++ b/src/edit.c @@ -1,10 +1,9 @@ #include // intmax_t -#include // bool, false, true #include // NULL, size_t #include "../include/allocator.h" // GVA_Allocator #include "../include/edit.h" // gva_edit_distance -#include "common.h" // ABS, MAX +#include "common.h" // MAX static inline size_t diff --git a/src/lcs_graph.c b/src/lcs_graph.c index 6922c7a..2383336 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -95,27 +95,27 @@ local_supremal(GVA_Allocator const allocator, size_t const offset_row, size_t const offset_col, GVA_LCS_Graph graph[static restrict 1]) { - fprintf(stderr, GVA_STRING_FMT " vs " GVA_STRING_FMT "\n", GVA_STRING_PRINT(((GVA_String) {len_ref, reference})), GVA_STRING_PRINT(((GVA_String) {len_obs, observed}))); + // fprintf(stderr, GVA_STRING_FMT " vs " GVA_STRING_FMT "\n", GVA_STRING_PRINT(((GVA_String) {len_ref, reference})), GVA_STRING_PRINT(((GVA_String) {len_obs, observed}))); if (len_ref == 0 || len_obs == 0) { //base += 1; GVA_LCS_Graph local = gva_lcs_graph_init(allocator, len_ref, reference, len_obs, observed, offset_row); - fprintf(stderr, "BASE: " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(gva_lcs_graph_supremal(local))); + //fprintf(stderr, "BASE: " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(gva_lcs_graph_supremal(local))); concat(allocator, graph, local, offset_col); gva_lcs_graph_destroy(allocator, local, false); return; } // if - fprintf(stderr, "F\n"); LCS_Matches forward = lcs_align_one(allocator, len_ref, reference, len_obs, observed); gva_string_reverse(len_ref, (char*) reference); gva_string_reverse(len_obs, (char*) observed); + fprintf(stderr, "F\n"); - fprintf(stderr, "B\n"); LCS_Matches backward = lcs_align_one(allocator, len_ref, reference, len_obs, observed); gva_string_reverse(len_ref, (char*) reference); gva_string_reverse(len_obs, (char*) observed); + fprintf(stderr, "B\n"); size_t sum = 0; size_t prev_row = -1; @@ -124,9 +124,11 @@ local_supremal(GVA_Allocator const allocator, { size_t const j = forward.max_lcs_pos - i - 1; + /* fprintf(stderr, "%zu: (%u, %u) %d (%zu, %zu) %d\n", i, forward.match[i].row, forward.match[i].col, forward.uniq[i], len_ref - backward.match[j].row - 1, len_obs - backward.match[j].col - 1, backward.uniq[j]); + */ if (forward.match[i].row == len_ref - backward.match[j].row - 1 && forward.match[i].col == len_obs - backward.match[j].col - 1 // && @@ -134,21 +136,27 @@ local_supremal(GVA_Allocator const allocator, ) { size_t const distance = forward.match[i].row + forward.match[i].col - 2 * i - sum; - if (distance > 0) + if (distance > 0 && (prev_row == (size_t) -1 || (prev_row < forward.match[i].row && prev_col < forward.match[i].col))) { //recurse += 1; sum += distance; +/* + fprintf(stderr, "prev: %zd %zd\n", prev_row, prev_col); fprintf(stderr, "RECURSE %u %u %d %d {\n", forward.match[i].row, forward.match[i].col, forward.uniq[i], backward.uniq[j]); +*/ local_supremal(allocator, forward.match[i].row - prev_row - 1, reference + prev_row + 1, forward.match[i].col - prev_col - 1, observed + prev_col + 1, offset_row + prev_row + 1, offset_col + prev_col + 1, graph); - fprintf(stderr, "}\n"); + //fprintf(stderr, "}\n"); } // if - prev_row = forward.match[i].row; - prev_col = forward.match[i].col; + if (prev_row == (size_t) -1 || (prev_row < forward.match[i].row && prev_col < forward.match[i].col)) + { + prev_row = forward.match[i].row; + prev_col = forward.match[i].col; + } } // if } // for size_t const distance = len_ref + len_obs - 2 * forward.max_lcs_pos - sum; @@ -157,20 +165,20 @@ local_supremal(GVA_Allocator const allocator, if (prev_row != (size_t) -1) { //recurse += 1; - fprintf(stderr, "RECURSE {\n"); + //fprintf(stderr, "RECURSE {\n"); local_supremal(allocator, len_ref - prev_row - 1, reference + prev_row + 1, len_obs - prev_col - 1, observed + prev_col + 1, offset_row + prev_row + 1, offset_col + prev_col + 1, graph); - fprintf(stderr, "}\n"); + //fprintf(stderr, "}\n"); } // if else { GVA_LCS_Graph local = gva_lcs_graph_init(allocator, len_ref - prev_row - 1, reference + prev_row + 1, len_obs - prev_col - 1, observed + prev_col + 1, offset_row + prev_row + 1); - fprintf(stderr, GVA_VARIANT_FMT " %zu\n", GVA_VARIANT_PRINT(gva_lcs_graph_supremal(local)), gva_variant_length(gva_lcs_graph_supremal(local))); + //fprintf(stderr, GVA_VARIANT_FMT " %zu\n", GVA_VARIANT_PRINT(gva_lcs_graph_supremal(local)), gva_variant_length(gva_lcs_graph_supremal(local))); /* - if (array_length(local.dom_nodes) == 3) + if (array_length(local.dom_nodes) > 2) { multi = 1; fprintf(stderr, "MULTI\n"); diff --git a/src/main.c b/src/main.c index f55b27b..0909f4d 100644 --- a/src/main.c +++ b/src/main.c @@ -412,6 +412,7 @@ extern int multi; int allele_main(int argc, char* argv[static argc]) { +/* if (argc < 2) { fprintf(stderr, "usage: %s seed\n", argv[0]); @@ -420,11 +421,12 @@ allele_main(int argc, char* argv[static argc]) srand(atoi(argv[1])); - //GVA_String ref = gva_string_init(gva_std_allocator, 10); - //GVA_Variant var = {0, ref.len, gva_string_init(gva_std_allocator, 10)}; + GVA_String ref = gva_string_init(gva_std_allocator, 10); + GVA_Variant var = {0, ref.len, gva_string_init(gva_std_allocator, 10)}; + + //GVA_String ref = gva_string_dup(gva_std_allocator, (GVA_String) {10, "AGGCGTCGAA"}); + //GVA_Variant var = {0, ref.len, {10, "GTGTGTGCGG"}}; - GVA_String ref = gva_string_dup(gva_std_allocator, (GVA_String) {10, "AGGCGTCGAA"}); - GVA_Variant var = {0, ref.len, {10, "GTGTGTGCGG"}}; LCS_Alignment lcs = lcs_align(gva_std_allocator, ref.len, ref.str, var.sequence.len, var.sequence.str, 0); @@ -442,17 +444,17 @@ allele_main(int argc, char* argv[static argc]) lcs.index = gva_std_allocator.allocate(gva_std_allocator.context, lcs.index, lcs.length * sizeof(*lcs.index), 0); lcs.nodes = ARRAY_DESTROY(gva_std_allocator, lcs.nodes); - //while (true) + while (true) { - //random_string(ref.len, (char*) ref.str); - //random_string(var.sequence.len, (char*) var.sequence.str); + random_string(ref.len, (char*) ref.str); + random_string(var.sequence.len, (char*) var.sequence.str); - // base = 0; - // recurse = 0; - // multi = 0; + //base = 0; + //recurse = 0; + //multi = 0; GVA_LCS_Graph g = gva_lcs_graph_from_allele(gva_std_allocator, ref.len, ref.str, 1, &var); - // if (base > 1 && recurse > 2 && multi) + //if (base > 1 && recurse > 2 && multi) { fprintf(stderr, GVA_STRING_FMT " vs " GVA_STRING_FMT "\n", GVA_STRING_PRINT(ref), GVA_STRING_PRINT(var.sequence)); //fprintf(stderr, GVA_STRING_FMT ":" GVA_VARIANT_FMT "\n", GVA_STRING_PRINT(ref), GVA_VARIANT_PRINT(gva_lcs_graph_supremal(g))); @@ -463,13 +465,17 @@ allele_main(int argc, char* argv[static argc]) fprintf(stderr, "\n"); } // if + fprintf(stderr, "\n"); + gva_lcs_graph_destroy(gva_std_allocator, g, true); + break; } // for gva_string_destroy(gva_std_allocator, var.sequence); gva_string_destroy(gva_std_allocator, ref); return EXIT_SUCCESS; +*/ if (argc < 3) { From 39374661cc4dc3fd18774baa1964072643a18505 Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 18 Jun 2026 15:23:50 +0200 Subject: [PATCH 697/704] WIP: furthest match --- src/lcs_graph.c | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/src/lcs_graph.c b/src/lcs_graph.c index 2383336..e44ff3a 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -87,16 +87,22 @@ int recurse; int base; */ +size_t max_depth; + // FIXME: recursion! static void local_supremal(GVA_Allocator const allocator, size_t const len_ref, char const reference[static restrict len_ref], size_t const len_obs, char const observed[static restrict len_obs], size_t const offset_row, size_t const offset_col, - GVA_LCS_Graph graph[static restrict 1]) + GVA_LCS_Graph graph[static restrict 1], + size_t const depth) { // fprintf(stderr, GVA_STRING_FMT " vs " GVA_STRING_FMT "\n", GVA_STRING_PRINT(((GVA_String) {len_ref, reference})), GVA_STRING_PRINT(((GVA_String) {len_obs, observed}))); + max_depth = MAX(max_depth, depth); + + if (len_ref == 0 || len_obs == 0) { //base += 1; @@ -110,12 +116,14 @@ local_supremal(GVA_Allocator const allocator, LCS_Matches forward = lcs_align_one(allocator, len_ref, reference, len_obs, observed); gva_string_reverse(len_ref, (char*) reference); gva_string_reverse(len_obs, (char*) observed); - fprintf(stderr, "F\n"); + //fprintf(stderr, "F\n"); LCS_Matches backward = lcs_align_one(allocator, len_ref, reference, len_obs, observed); gva_string_reverse(len_ref, (char*) reference); gva_string_reverse(len_obs, (char*) observed); - fprintf(stderr, "B\n"); + //fprintf(stderr, "B\n"); + + size_t count = 0; size_t sum = 0; size_t prev_row = -1; @@ -144,11 +152,13 @@ local_supremal(GVA_Allocator const allocator, fprintf(stderr, "prev: %zd %zd\n", prev_row, prev_col); fprintf(stderr, "RECURSE %u %u %d %d {\n", forward.match[i].row, forward.match[i].col, forward.uniq[i], backward.uniq[j]); */ + + count += 1; local_supremal(allocator, forward.match[i].row - prev_row - 1, reference + prev_row + 1, forward.match[i].col - prev_col - 1, observed + prev_col + 1, offset_row + prev_row + 1, offset_col + prev_col + 1, - graph); + graph, depth + 1); //fprintf(stderr, "}\n"); } // if @@ -164,13 +174,14 @@ local_supremal(GVA_Allocator const allocator, { if (prev_row != (size_t) -1) { + count += 1; //recurse += 1; //fprintf(stderr, "RECURSE {\n"); local_supremal(allocator, len_ref - prev_row - 1, reference + prev_row + 1, len_obs - prev_col - 1, observed + prev_col + 1, offset_row + prev_row + 1, offset_col + prev_col + 1, - graph); + graph, depth + 1); //fprintf(stderr, "}\n"); } // if else @@ -193,6 +204,12 @@ local_supremal(GVA_Allocator const allocator, } // else } // if + if (depth == 0) + { + fprintf(stderr, "count: %zu\n", count); + fprintf(stderr, "max_depth: %zu\n", max_depth); + } // if + backward.match = allocator.allocate(allocator.context, backward.match, MIN(len_ref, len_obs), 0); backward.uniq = allocator.allocate(allocator.context, backward.uniq, MIN(len_ref, len_obs), 0); forward.match = allocator.allocate(allocator.context, forward.match, MIN(len_ref, len_obs), 0); @@ -521,7 +538,7 @@ gva_lcs_graph_from_allele(GVA_Allocator const allocator, size_t const n, GVA_Variant const variants[static restrict n]) { GVA_LCS_Graph graph = {.observed = gva_patch(allocator, len_ref, reference, n, variants)}; - local_supremal(allocator, len_ref, reference, graph.observed.len, graph.observed.str, 0, 0, &graph); + local_supremal(allocator, len_ref, reference, graph.observed.len, graph.observed.str, 0, 0, &graph, 0); if (graph.nodes == NULL) { graph = gva_lcs_graph_init(allocator, len_ref, reference, graph.observed.len, graph.observed.str, 0); From a3bceed6daf70b51dc913978cbfaf0da8959781f Mon Sep 17 00:00:00 2001 From: jkvis Date: Thu, 25 Jun 2026 14:52:00 +0200 Subject: [PATCH 698/704] WIP: bidirectional alignment --- src/align.c | 26 +----- src/lcs_graph.c | 56 ++++--------- src/main.c | 214 +++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 217 insertions(+), 79 deletions(-) diff --git a/src/align.c b/src/align.c index 19cd2c6..c772ed7 100644 --- a/src/align.c +++ b/src/align.c @@ -10,9 +10,6 @@ #include "common.h" // ABS, MAX, MIN -#include - - typedef struct { GVA_Allocator const allocator; @@ -239,11 +236,11 @@ onp_snake(size_t const m, char const a[static restrict m], row += 1; col += 1; size_t const lcs_pos = (row + col - ABS(delta) - 2 * p + ABS(d_row - d_col)) / 2; - //fprintf(stderr, "M: (%zu, %zu): %zu\n", row - 1, col - 1, lcs_pos); result->uniq[lcs_pos - 1] = 0; if (lcs_pos > result->max_lcs_pos) { result->max_lcs_pos = lcs_pos; + result->uniq[lcs_pos - 1] = 1; if (swapped) { result->match[lcs_pos - 1].row = col - 1; @@ -255,27 +252,6 @@ onp_snake(size_t const m, char const a[static restrict m], result->match[lcs_pos - 1].col = col - 1; } // else } // if - else - { - // result->uniq[lcs_pos - 1] = 1; - if (swapped) - { - if (result->match[lcs_pos - 1].col < row - 1 || - (result->match[lcs_pos - 1].col == row - 1 && result->match[lcs_pos - 1].row > col - 1)) - result->match[lcs_pos - 1].row = col - 1; - result->match[lcs_pos - 1].col = row - 1; - } // if - else - { - if (result->match[lcs_pos - 1].row < row - 1 || - (result->match[lcs_pos - 1].row == row - 1 && result->match[lcs_pos - 1].col > col - 1)) - { - result->match[lcs_pos - 1].row = row - 1; - result->match[lcs_pos - 1].col = col - 1; - } // if - } // else - } // else - // } // if } // while return col; diff --git a/src/lcs_graph.c b/src/lcs_graph.c index e44ff3a..d6c9e8f 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -87,21 +87,15 @@ int recurse; int base; */ -size_t max_depth; - // FIXME: recursion! static void local_supremal(GVA_Allocator const allocator, size_t const len_ref, char const reference[static restrict len_ref], size_t const len_obs, char const observed[static restrict len_obs], size_t const offset_row, size_t const offset_col, - GVA_LCS_Graph graph[static restrict 1], - size_t const depth) + GVA_LCS_Graph graph[static restrict 1]) { - // fprintf(stderr, GVA_STRING_FMT " vs " GVA_STRING_FMT "\n", GVA_STRING_PRINT(((GVA_String) {len_ref, reference})), GVA_STRING_PRINT(((GVA_String) {len_obs, observed}))); - - max_depth = MAX(max_depth, depth); - + //fprintf(stderr, GVA_STRING_FMT " vs " GVA_STRING_FMT "\n", GVA_STRING_PRINT(((GVA_String) {len_ref, reference})), GVA_STRING_PRINT(((GVA_String) {len_obs, observed}))); if (len_ref == 0 || len_obs == 0) { @@ -116,14 +110,10 @@ local_supremal(GVA_Allocator const allocator, LCS_Matches forward = lcs_align_one(allocator, len_ref, reference, len_obs, observed); gva_string_reverse(len_ref, (char*) reference); gva_string_reverse(len_obs, (char*) observed); - //fprintf(stderr, "F\n"); LCS_Matches backward = lcs_align_one(allocator, len_ref, reference, len_obs, observed); gva_string_reverse(len_ref, (char*) reference); gva_string_reverse(len_obs, (char*) observed); - //fprintf(stderr, "B\n"); - - size_t count = 0; size_t sum = 0; size_t prev_row = -1; @@ -132,41 +122,32 @@ local_supremal(GVA_Allocator const allocator, { size_t const j = forward.max_lcs_pos - i - 1; - /* + /* fprintf(stderr, "%zu: (%u, %u) %d (%zu, %zu) %d\n", i, forward.match[i].row, forward.match[i].col, forward.uniq[i], len_ref - backward.match[j].row - 1, len_obs - backward.match[j].col - 1, backward.uniq[j]); - */ + */ if (forward.match[i].row == len_ref - backward.match[j].row - 1 && - forward.match[i].col == len_obs - backward.match[j].col - 1 // && - // (forward.uniq[i] == 1 || backward.uniq[j] == 1) - ) + forward.match[i].col == len_obs - backward.match[j].col - 1 && + (forward.uniq[i] == 1 || backward.uniq[j] == 1)) { size_t const distance = forward.match[i].row + forward.match[i].col - 2 * i - sum; - if (distance > 0 && (prev_row == (size_t) -1 || (prev_row < forward.match[i].row && prev_col < forward.match[i].col))) + if (distance > 0) { //recurse += 1; sum += distance; -/* - fprintf(stderr, "prev: %zd %zd\n", prev_row, prev_col); - fprintf(stderr, "RECURSE %u %u %d %d {\n", forward.match[i].row, forward.match[i].col, forward.uniq[i], backward.uniq[j]); -*/ - - count += 1; + //fprintf(stderr, "RECURSE %u %u %d %d {\n", forward.match[i].row, forward.match[i].col, forward.uniq[i], backward.uniq[j]); local_supremal(allocator, forward.match[i].row - prev_row - 1, reference + prev_row + 1, forward.match[i].col - prev_col - 1, observed + prev_col + 1, offset_row + prev_row + 1, offset_col + prev_col + 1, - graph, depth + 1); + graph); //fprintf(stderr, "}\n"); } // if - if (prev_row == (size_t) -1 || (prev_row < forward.match[i].row && prev_col < forward.match[i].col)) - { - prev_row = forward.match[i].row; - prev_col = forward.match[i].col; - } + prev_row = forward.match[i].row; + prev_col = forward.match[i].col; } // if } // for size_t const distance = len_ref + len_obs - 2 * forward.max_lcs_pos - sum; @@ -174,22 +155,21 @@ local_supremal(GVA_Allocator const allocator, { if (prev_row != (size_t) -1) { - count += 1; //recurse += 1; //fprintf(stderr, "RECURSE {\n"); local_supremal(allocator, len_ref - prev_row - 1, reference + prev_row + 1, len_obs - prev_col - 1, observed + prev_col + 1, offset_row + prev_row + 1, offset_col + prev_col + 1, - graph, depth + 1); + graph); //fprintf(stderr, "}\n"); } // if else { GVA_LCS_Graph local = gva_lcs_graph_init(allocator, len_ref - prev_row - 1, reference + prev_row + 1, len_obs - prev_col - 1, observed + prev_col + 1, offset_row + prev_row + 1); - //fprintf(stderr, GVA_VARIANT_FMT " %zu\n", GVA_VARIANT_PRINT(gva_lcs_graph_supremal(local)), gva_variant_length(gva_lcs_graph_supremal(local))); /* - if (array_length(local.dom_nodes) > 2) + fprintf(stderr, GVA_VARIANT_FMT " %zu\n", GVA_VARIANT_PRINT(gva_lcs_graph_supremal(local)), gva_variant_length(gva_lcs_graph_supremal(local))); + if (array_length(local.dom_nodes) == 3) { multi = 1; fprintf(stderr, "MULTI\n"); @@ -204,12 +184,6 @@ local_supremal(GVA_Allocator const allocator, } // else } // if - if (depth == 0) - { - fprintf(stderr, "count: %zu\n", count); - fprintf(stderr, "max_depth: %zu\n", max_depth); - } // if - backward.match = allocator.allocate(allocator.context, backward.match, MIN(len_ref, len_obs), 0); backward.uniq = allocator.allocate(allocator.context, backward.uniq, MIN(len_ref, len_obs), 0); forward.match = allocator.allocate(allocator.context, forward.match, MIN(len_ref, len_obs), 0); @@ -538,7 +512,7 @@ gva_lcs_graph_from_allele(GVA_Allocator const allocator, size_t const n, GVA_Variant const variants[static restrict n]) { GVA_LCS_Graph graph = {.observed = gva_patch(allocator, len_ref, reference, n, variants)}; - local_supremal(allocator, len_ref, reference, graph.observed.len, graph.observed.str, 0, 0, &graph, 0); + local_supremal(allocator, len_ref, reference, graph.observed.len, graph.observed.str, 0, 0, &graph); if (graph.nodes == NULL) { graph = gva_lcs_graph_init(allocator, len_ref, reference, graph.observed.len, graph.observed.str, 0); diff --git a/src/main.c b/src/main.c index 0909f4d..a91f9e1 100644 --- a/src/main.c +++ b/src/main.c @@ -7,6 +7,8 @@ #include // strlen #include "../include/compare.h" // gva_compare_distance +#include "../include/edit.h" // gva_edit_distance +#include "../include/extractor.h" // gva_canonical #include "../include/index.h" // GVA_Index, gva_index_*, GVA_Query_Result #include "../include/lcs_graph.h" // GVA_LCS_Graph, gva_lcs_graph_* #include "../include/mmap_alloc.h" // GVA_Mmap_Context, gva_mmap_* @@ -25,9 +27,9 @@ #define LINE_SIZE 4096 -#define REFERENCE_ID "NC_000022.11" +// #define REFERENCE_ID "NC_000022.11" // #define REFERENCE_ID "NC_000006.12" -// #define REFERENCE_ID "NC_000001.11" +#define REFERENCE_ID "NC_000001.11" // line: alphanumeric_id SPDI [distance] @@ -404,9 +406,156 @@ random_string(size_t const len, char str[static len]) } // for } // random_string +/* extern int base; extern int recurse; extern int multi; +*/ + +static inline size_t +onp_snake(size_t const m, char const a[static restrict m], + size_t const n, char const b[static restrict n], + intmax_t const k, intmax_t const lower, intmax_t const upper, + size_t const p, size_t len_lcs[static restrict 1]) +{ + size_t col = MAX(lower, upper); + size_t row = col - k; + + size_t lcs_pos = (row + col - (n - m) - 2 * p + ABS((intmax_t) (m - row) - (intmax_t) (n - col))) / 2; + + while (row < m && col < n && a[row] == b[col]) + { + //fprintf(stderr, " M (%zu, %zu) @ %zu\n", row, col, lcs_pos); + row += 1; + col += 1; + lcs_pos += 1; + } // while + *len_lcs = MAX(*len_lcs, lcs_pos); + return col; +} // onp_snake + + +static inline size_t +onp_snake_p(size_t const m, char const a[static restrict m], + size_t const n, char const b[static restrict n], + intmax_t const k, intmax_t const lower, intmax_t const upper, + size_t const p, size_t len_lcs[static restrict 1]) +{ + size_t col = MAX(lower, upper); + size_t row = col - k; + + size_t lcs_pos = (row + col - (n - m) - 2 * p + ABS((intmax_t) (m - row) - (intmax_t) (n - col))) / 2; + + while (row < m && col < n && a[m - row - 1] == b[n - col - 1]) + { + //fprintf(stderr, " MP (%zu, %zu) @ %zu\n", m - row - 1, n - col - 1, lcs_pos); + row += 1; + col += 1; + lcs_pos += 1; + } // while + *len_lcs = MAX(*len_lcs, lcs_pos); + return col; +} // onp_snake_p + + +static size_t +onp_compare(size_t const m, char const a[static restrict m], + size_t const n, char const b[static restrict n]) +{ + intmax_t const delta = n - m; + size_t const offset = m + 1; + size_t const size = m + n + 3; + intmax_t* const restrict fp = malloc(size * sizeof(*fp)); + intmax_t* const restrict fpp = malloc(size * sizeof(*fpp)); + if (fp == NULL || fpp == NULL) + { + free(fpp); + free(fp); + return -1; + } // if + + //fprintf(stderr, "%s vs %s\n", a, b); + + for (intmax_t i = -1; i <= delta; ++i) + { + fp[i + offset] = -1; + fpp[i + offset] = -1; + } // for + + size_t len_lcs = 0; + size_t len_lcs_p = 0; + + size_t p = 0; + while (fp[delta + offset] <= (intmax_t) n - fpp[delta + offset] - 1) + { + //fprintf(stderr, "p: %zu\n", p); + fp[-p - 1 + offset] = -1; + for (intmax_t k = -p; k <= delta - 1; ++k) + { + fp[k + offset] = onp_snake(m, a, n, b, k, fp[k - 1 + offset] + 1, fp[k + 1 + offset], p, &len_lcs); + } // for + fp[delta + p + 1 + offset] = -1; + for (intmax_t k = delta + p; k >= delta + 1; --k) + { + fp[k + offset] = onp_snake(m, a, n, b, k, fp[k - 1 + offset] + 1, fp[k + 1 + offset], p, &len_lcs); + } // for + fp[delta + offset] = onp_snake(m, a, n, b, delta, fp[delta - 1 + offset] + 1, fp[delta + 1 + offset], p, &len_lcs); + + + fpp[-p - 1 + offset] = -1; + for (intmax_t k = -p; k <= delta - 1; ++k) + { + fpp[k + offset] = onp_snake_p(m, a, n, b, k, fpp[k - 1 + offset] + 1, fpp[k + 1 + offset], p, &len_lcs_p); + } // for + fpp[delta + p + 1 + offset] = - 1; + for (intmax_t k = delta + p; k >= delta + 1; --k) + { + fpp[k + offset] = onp_snake_p(m, a, n, b, k, fpp[k - 1 + offset] + 1, fpp[k + 1 + offset], p, &len_lcs_p); + } // for + fpp[delta + offset] = onp_snake_p(m, a, n, b, delta, fpp[delta - 1 + offset] + 1, fpp[delta + 1 + offset], p, &len_lcs_p); + +/* + for (intmax_t k = -p; k <= delta - 1; ++k) + { + fprintf(stderr, "%ld ", fp[k + offset]); + } // for + fprintf(stderr, "[%ld] ", fp[delta + offset]); + for (intmax_t k = delta + p; k >= delta + 1; --k) + { + fprintf(stderr, "%ld ", fp[k + offset]); + } // for + fprintf(stderr, ": %zu\n", len_lcs); + + for (intmax_t k = -p; k <= delta - 1; ++k) + { + fprintf(stderr, "%ld ", fpp[k + offset]); + } // for + fprintf(stderr, "[%ld] ", fpp[delta + offset]); + for (intmax_t k = delta + p; k >= delta + 1; --k) + { + fprintf(stderr, "%ld ", fpp[k + offset]); + } // for + fprintf(stderr, ": %zu\n", len_lcs_p); +*/ + p += 1; + } // while + + //fprintf(stderr, "%ld vs %ld\n", fp[delta + offset], (intmax_t) n - fpp[delta + offset] - 1); + + free(fpp); + free(fp); + return p; +} // onp_compare + + +static inline size_t +edit_distance(size_t const len_ref, char const reference[static restrict len_ref], + size_t const len_obs, char const observed[static restrict len_obs]) +{ + return len_ref > len_obs ? + onp_compare(len_obs, observed, len_ref, reference) : + onp_compare(len_ref, reference, len_obs, observed); +} // edit_distance int @@ -421,12 +570,12 @@ allele_main(int argc, char* argv[static argc]) srand(atoi(argv[1])); - GVA_String ref = gva_string_init(gva_std_allocator, 10); - GVA_Variant var = {0, ref.len, gva_string_init(gva_std_allocator, 10)}; + //GVA_String ref = gva_string_init(gva_std_allocator, 10); + //GVA_Variant var = {0, ref.len, gva_string_init(gva_std_allocator, 10)}; - //GVA_String ref = gva_string_dup(gva_std_allocator, (GVA_String) {10, "AGGCGTCGAA"}); - //GVA_Variant var = {0, ref.len, {10, "GTGTGTGCGG"}}; + GVA_String ref = gva_string_dup(gva_std_allocator, (GVA_String) {11, "AGGCGTCGAAA"}); + GVA_Variant var = {0, ref.len, {10, "GTGTGTGCGG"}}; LCS_Alignment lcs = lcs_align(gva_std_allocator, ref.len, ref.str, var.sequence.len, var.sequence.str, 0); @@ -444,17 +593,17 @@ allele_main(int argc, char* argv[static argc]) lcs.index = gva_std_allocator.allocate(gva_std_allocator.context, lcs.index, lcs.length * sizeof(*lcs.index), 0); lcs.nodes = ARRAY_DESTROY(gva_std_allocator, lcs.nodes); - while (true) +// while (true) { - random_string(ref.len, (char*) ref.str); - random_string(var.sequence.len, (char*) var.sequence.str); + //random_string(ref.len, (char*) ref.str); + //random_string(var.sequence.len, (char*) var.sequence.str); //base = 0; //recurse = 0; //multi = 0; GVA_LCS_Graph g = gva_lcs_graph_from_allele(gva_std_allocator, ref.len, ref.str, 1, &var); - //if (base > 1 && recurse > 2 && multi) + if (base > 1 && recurse > 2 && multi) { fprintf(stderr, GVA_STRING_FMT " vs " GVA_STRING_FMT "\n", GVA_STRING_PRINT(ref), GVA_STRING_PRINT(var.sequence)); //fprintf(stderr, GVA_STRING_FMT ":" GVA_VARIANT_FMT "\n", GVA_STRING_PRINT(ref), GVA_VARIANT_PRINT(gva_lcs_graph_supremal(g))); @@ -465,10 +614,7 @@ allele_main(int argc, char* argv[static argc]) fprintf(stderr, "\n"); } // if - fprintf(stderr, "\n"); - gva_lcs_graph_destroy(gva_std_allocator, g, true); - break; } // for gva_string_destroy(gva_std_allocator, var.sequence); @@ -532,9 +678,22 @@ allele_main(int argc, char* argv[static argc]) ARRAY_APPEND(gva_std_allocator, variants, gva_variant_dup(gva_std_allocator, trimmed)); } // while fclose(stream); + + GVA_String observed = gva_patch(gva_std_allocator, reference.len, reference.str, array_length(variants), variants); + fprintf(stderr, "#variants: %zu\n", array_length(variants)); fprintf(stderr, "#dropped: %zu\n", dropped); + size_t const distance = gva_edit_distance(gva_std_allocator, reference.len, reference.str, observed.len, observed.str); + + fprintf(stderr, "distance: %zu\n", distance); + + gva_string_destroy(gva_std_allocator, observed); + + + + +/* GVA_LCS_Graph graph = gva_lcs_graph_from_allele(gva_std_allocator, reference.len, reference.str, array_length(variants), variants); for (size_t i = 0; i < array_length(graph.dom_nodes) - 1; ++i) { @@ -546,6 +705,7 @@ allele_main(int argc, char* argv[static argc]) fprintf(stderr, "#edges: %zu\n", array_length(graph.edges)); gva_lcs_graph_destroy(gva_std_allocator, graph, true); +*/ if (variants != NULL) { @@ -817,6 +977,33 @@ all_main(int argc, char* argv[static argc]) return EXIT_SUCCESS; } // all_main +/* +int +hgvs_main(int argc, char* argv[static argc]) +{ + if (argc < 4) + { + fprintf(stderr, "usage: %s reference observed hgvs\n", argv[0]); + return EXIT_FAILURE; + } // if + + GVA_LCS_Graph graph = gva_lcs_graph_init(gva_std_allocator, strlen(argv[1]), argv[1], strlen(argv[2]), argv[2], 0); + GVA_Variant* variants = gva_canonical(gva_std_allocator, graph); + + static char buffer[LINE_SIZE] = {'\0'}; + gva_to_hgvs(LINE_SIZE, buffer, strlen(argv[1]), argv[1], array_length(variants), variants); + + if (memcmp(buffer, argv[3], strlen(argv[3])) != 0) + { + fprintf(stderr, "DIFF: %s vs %s\n", buffer, argv[3]); + } // if + + ARRAY_DESTROY(gva_std_allocator, variants); + gva_lcs_graph_destroy(gva_std_allocator, graph, false); + + return EXIT_SUCCESS; +} // hgvs_main +*/ int main(int argc, char* argv[static argc]) @@ -825,4 +1012,5 @@ main(int argc, char* argv[static argc]) // return index_main(argc, argv); // return overlap_main(argc, argv); // return all_main(argc, argv); + // return hgvs_main(argc, argv); } // main From 11e04e8b9170e45363f9a7a3a8bae19f6167fb0a Mon Sep 17 00:00:00 2001 From: Mark Santcroos Date: Thu, 25 Jun 2026 16:04:39 +0200 Subject: [PATCH 699/704] WIP: Baseline to work on bi-directional. --- src/main.c | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/src/main.c b/src/main.c index a91f9e1..ca0d654 100644 --- a/src/main.c +++ b/src/main.c @@ -425,7 +425,7 @@ onp_snake(size_t const m, char const a[static restrict m], while (row < m && col < n && a[row] == b[col]) { - //fprintf(stderr, " M (%zu, %zu) @ %zu\n", row, col, lcs_pos); + fprintf(stderr, " M (%zu, %zu) @ %zu\n", row, col, lcs_pos); row += 1; col += 1; lcs_pos += 1; @@ -448,7 +448,7 @@ onp_snake_p(size_t const m, char const a[static restrict m], while (row < m && col < n && a[m - row - 1] == b[n - col - 1]) { - //fprintf(stderr, " MP (%zu, %zu) @ %zu\n", m - row - 1, n - col - 1, lcs_pos); + fprintf(stderr, " MP (%zu, %zu) @ %zu\n", m - row - 1, n - col - 1, lcs_pos); row += 1; col += 1; lcs_pos += 1; @@ -474,7 +474,7 @@ onp_compare(size_t const m, char const a[static restrict m], return -1; } // if - //fprintf(stderr, "%s vs %s\n", a, b); + // fprintf(stderr, "%s vs %s\n", a, b); for (intmax_t i = -1; i <= delta; ++i) { @@ -488,7 +488,7 @@ onp_compare(size_t const m, char const a[static restrict m], size_t p = 0; while (fp[delta + offset] <= (intmax_t) n - fpp[delta + offset] - 1) { - //fprintf(stderr, "p: %zu\n", p); + fprintf(stderr, "p: %zu\n", p); fp[-p - 1 + offset] = -1; for (intmax_t k = -p; k <= delta - 1; ++k) { @@ -514,7 +514,6 @@ onp_compare(size_t const m, char const a[static restrict m], } // for fpp[delta + offset] = onp_snake_p(m, a, n, b, delta, fpp[delta - 1 + offset] + 1, fpp[delta + 1 + offset], p, &len_lcs_p); -/* for (intmax_t k = -p; k <= delta - 1; ++k) { fprintf(stderr, "%ld ", fp[k + offset]); @@ -536,11 +535,10 @@ onp_compare(size_t const m, char const a[static restrict m], fprintf(stderr, "%ld ", fpp[k + offset]); } // for fprintf(stderr, ": %zu\n", len_lcs_p); -*/ p += 1; } // while - //fprintf(stderr, "%ld vs %ld\n", fp[delta + offset], (intmax_t) n - fpp[delta + offset] - 1); + fprintf(stderr, "%ld vs %ld\n", fp[delta + offset], (intmax_t) n - fpp[delta + offset] - 1); free(fpp); free(fp); @@ -561,7 +559,6 @@ edit_distance(size_t const len_ref, char const reference[static restrict len_ref int allele_main(int argc, char* argv[static argc]) { -/* if (argc < 2) { fprintf(stderr, "usage: %s seed\n", argv[0]); @@ -574,7 +571,7 @@ allele_main(int argc, char* argv[static argc]) //GVA_Variant var = {0, ref.len, gva_string_init(gva_std_allocator, 10)}; - GVA_String ref = gva_string_dup(gva_std_allocator, (GVA_String) {11, "AGGCGTCGAAA"}); + GVA_String ref = gva_string_dup(gva_std_allocator, (GVA_String) {10, "AGGCGTCGAA"}); GVA_Variant var = {0, ref.len, {10, "GTGTGTGCGG"}}; LCS_Alignment lcs = lcs_align(gva_std_allocator, ref.len, ref.str, var.sequence.len, var.sequence.str, 0); @@ -593,6 +590,9 @@ allele_main(int argc, char* argv[static argc]) lcs.index = gva_std_allocator.allocate(gva_std_allocator.context, lcs.index, lcs.length * sizeof(*lcs.index), 0); lcs.nodes = ARRAY_DESTROY(gva_std_allocator, lcs.nodes); + size_t const distance = edit_distance(ref.len, ref.str, var.sequence.len, var.sequence.str); + + /* // while (true) { //random_string(ref.len, (char*) ref.str); @@ -601,6 +601,7 @@ allele_main(int argc, char* argv[static argc]) //base = 0; //recurse = 0; //multi = 0; + GVA_LCS_Graph g = gva_lcs_graph_from_allele(gva_std_allocator, ref.len, ref.str, 1, &var); if (base > 1 && recurse > 2 && multi) @@ -615,14 +616,15 @@ allele_main(int argc, char* argv[static argc]) } // if gva_lcs_graph_destroy(gva_std_allocator, g, true); - } // for + } // while + */ - gva_string_destroy(gva_std_allocator, var.sequence); + // gva_string_destroy(gva_std_allocator, var.sequence); gva_string_destroy(gva_std_allocator, ref); return EXIT_SUCCESS; -*/ + /* if (argc < 3) { fprintf(stderr, "usage: %s reference observed\n", argv[0]); @@ -689,6 +691,7 @@ allele_main(int argc, char* argv[static argc]) fprintf(stderr, "distance: %zu\n", distance); gva_string_destroy(gva_std_allocator, observed); + */ @@ -707,6 +710,7 @@ allele_main(int argc, char* argv[static argc]) gva_lcs_graph_destroy(gva_std_allocator, graph, true); */ + /* if (variants != NULL) { for (size_t i = 0; i < array_length(variants); ++i) @@ -719,6 +723,7 @@ allele_main(int argc, char* argv[static argc]) gva_string_destroy(gva_std_allocator, reference); return EXIT_SUCCESS; + */ } // allele_main From 37fb858565384c342947641c103aed024dc04fd2 Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 29 Jun 2026 15:33:14 +0200 Subject: [PATCH 700/704] WIP: HGVS printing --- include/hgvs.h | 16 +++++ src/hgvs.c | 184 +++++++++++++++++++++---------------------------- 2 files changed, 93 insertions(+), 107 deletions(-) create mode 100644 include/hgvs.h diff --git a/include/hgvs.h b/include/hgvs.h new file mode 100644 index 0000000..c909a24 --- /dev/null +++ b/include/hgvs.h @@ -0,0 +1,16 @@ +#ifndef GVA_HGVS_H +#define GVA_HGVS_H + + +#include // size_t + +#include "variant.h" // GVA_Variant + + +size_t +gva_to_hgvs(size_t const len, char buffer[static restrict len], + size_t const len_ref, char const reference[static restrict len_ref], + size_t const n, GVA_Variant const variants[static restrict n]); + + +#endif // GVA_HGVS_H diff --git a/src/hgvs.c b/src/hgvs.c index b5a6176..5e80d9c 100644 --- a/src/hgvs.c +++ b/src/hgvs.c @@ -1,22 +1,14 @@ // NOT FREESTANDING -#include // errno #include // NULL, size_t -#include // ... -#include // ... -#include // ... +#include // snprintf +#include // memcmp #include "../include/allocator.h" // GVA_Allocator -#include "../include/parser.h" // gva_parse_* #include "../include/std_alloc.h" // gva_std_allocator #include "../include/string.h" // GVA_STRING_* -#include "../include/utils.h" // gva_fasta_sequence_blob +#include "../include/types.h" // GVA_UINT_FMT #include "../include/variant.h" // GVA_Variant -#include "array.h" // ARRAY_DESTROY - - -#define LINE_SIZE 4096 - static inline size_t repeats(GVA_Allocator const allocator, @@ -55,37 +47,86 @@ repeats(GVA_Allocator const allocator, } // repeats -static inline size_t -hgvs_location(size_t const len, char buffer[static len], - size_t const start, size_t const end) -{ - if (end - start == 0) - { - return snprintf(buffer, len, "%zu_%zu", start, start + 1); - } // if - if (end - start == 1) - { - return snprintf(buffer, len, "%zu", start + 1); - } // if - return snprintf(buffer, len, "%zu_%zu", start + 1, end); -} // hgvs_location - - static size_t hgvs_variant(size_t const len, char buffer[static len], size_t const len_ref, char const reference[static restrict len_ref], GVA_Variant const variant) { - size_t const inserted = repeats(gva_std_allocator, variant.sequence.len, variant.sequence.str); - size_t const deleted = repeats(gva_std_allocator, variant.end - variant.start, reference + variant.start); + fprintf(stderr, GVA_STRING_FMT "\n", GVA_STRING_PRINT(((GVA_String) {variant.end - variant.start, reference + variant.start}))); + fprintf(stderr, GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(variant)); + + size_t len_inserted = repeats(gva_std_allocator, variant.sequence.len, variant.sequence.str); + if (len_inserted > 0) + { + size_t cnt_inserted = variant.sequence.len / len_inserted; + size_t rem_inserted = variant.sequence.len % len_inserted; + + size_t len_deleted = repeats(gva_std_allocator, variant.end - variant.start, reference + variant.start); + if (len_deleted > 0) + { + size_t cnt_deleted = (variant.end - variant.start) / len_deleted; + size_t rem_deleted = (variant.end - variant.start) % len_deleted; + + char const* inserted = variant.sequence.str; + char const* deleted = reference + variant.start; + + fprintf(stderr, "%zu: " GVA_STRING_FMT " %zu %zu\n", len_inserted, + GVA_STRING_PRINT(((GVA_String) {len_inserted, inserted})), + cnt_inserted, rem_inserted); + fprintf(stderr, "%zu: " GVA_STRING_FMT " %zu %zu\n", len_deleted, + GVA_STRING_PRINT(((GVA_String) {len_deleted, deleted})), + cnt_deleted, rem_deleted); + + if (len_inserted < len_deleted && + memcmp(deleted, inserted, len_inserted) == 0) + { + fprintf(stderr, "if\n"); + len_inserted = len_deleted; + cnt_inserted = 1; + rem_inserted = rem_deleted; + } // if + else if (len_deleted < len_inserted && + memcmp(deleted, inserted, len_deleted) == 0) + { + fprintf(stderr, "else if\n"); + len_deleted = len_inserted; + cnt_deleted = 1; + rem_deleted = rem_inserted; + } // if + + if (memcmp(deleted, inserted, len_deleted) == 0) + { + // duplictation + if (cnt_deleted == 1 && cnt_inserted == 2) + { + if (variant.end - variant.start == 0) + { + return snprintf(buffer, len, "%zudup", + variant.start + rem_deleted + 1); + } // if + return snprintf(buffer, len, "%zu_" GVA_UINT_FMT "dup", + variant.start + rem_deleted + 1, variant.end); + } // if + + // repeat + return snprintf(buffer, len, "%zu_" GVA_UINT_FMT GVA_STRING_FMT "[%zu]", + variant.start + rem_deleted + 1, variant.end, + GVA_STRING_PRINT(((GVA_String) {len_inserted, inserted + rem_inserted})), + cnt_inserted); + } // if + } // if + } // if + + + + - fprintf(stderr, "%zu vs %zu\n", inserted, deleted); - size_t idx = hgvs_location(len, buffer, variant.start, variant.end); if (variant.end - variant.start == 0) { + size_t const idx = snprintf(buffer, len, GVA_UINT_FMT "_" GVA_UINT_FMT, variant.start, variant.start + 1); if (variant.sequence.len == 0) { return idx + snprintf(buffer + idx, len - idx, "="); @@ -95,6 +136,7 @@ hgvs_variant(size_t const len, char buffer[static len], if (variant.end - variant.start == 1) { + size_t const idx = snprintf(buffer, len, GVA_UINT_FMT, variant.start + 1); if (variant.sequence.len == 0) { return idx + snprintf(buffer + idx, len - idx, "del"); @@ -106,6 +148,7 @@ hgvs_variant(size_t const len, char buffer[static len], return idx + snprintf(buffer + idx, len - idx, "delins" GVA_STRING_FMT, GVA_STRING_PRINT(variant.sequence)); } // if + size_t const idx = snprintf(buffer, len, GVA_UINT_FMT "_" GVA_UINT_FMT, variant.start + 1, variant.end); if (variant.sequence.len == 0) { return idx + snprintf(buffer + idx, len - idx, "del"); @@ -115,8 +158,8 @@ hgvs_variant(size_t const len, char buffer[static len], } // hgvs_variant -static size_t -to_hgvs(size_t const len, char buffer[static len], +size_t +gva_to_hgvs(size_t const len, char buffer[static restrict len], size_t const len_ref, char const reference[static restrict len_ref], size_t const n, GVA_Variant const variants[static restrict n]) { @@ -140,77 +183,4 @@ to_hgvs(size_t const len, char buffer[static len], } // if } // for return idx + snprintf(buffer + idx, len - idx, "]"); -} // to_hgvs - - -int -hgvs_main(int argc, char* argv[static argc]) -{ - static char buffer[1024] = {'\0'}; - GVA_String const ref = {10, "AAATAATATAATAATTTAT"}; - GVA_Variant const variant = {2, 13, {6, "ATAATA"}}; - fprintf(stderr, "%zu\n", to_hgvs(1024, buffer, ref.len, ref.str, 1, &variant)); - - fprintf(stderr, "%s\n", buffer); - - return EXIT_SUCCESS; - - - if (argc < 2) - { - fprintf(stderr, "usage %s reference.blob\n", argv[0]); - return EXIT_FAILURE; - } // if - - errno = 0; - FILE* stream = fopen(argv[1], "r"); - if (stream == NULL) - { - perror("fopen()"); - return EXIT_FAILURE; - } // if - - GVA_String reference = {0}; - reference = gva_fasta_sequence_blob(gva_std_allocator, stream); - fclose(stream); - - fprintf(stderr, "reference length: %zu\n", reference.len); - - size_t line_count = 0; - static char line[LINE_SIZE] = {0}; - while (fgets(line, sizeof(line), stdin) != NULL) - { - line_count += 1; - - size_t idx = 0; - size_t tok = 0; - - tok = strcspn(line + idx, "\t "); - idx += tok + 1; // ignore identifier - - tok = strcspn(line + idx, "\t "); - GVA_Variant variant = {0}; - if (gva_parse_spdi(tok, line + idx, &variant) == 0) - { - fprintf(stderr, "%zu: ERROR SPDI: %s", line_count, line); - continue; - } // if - idx += tok + 1; - - tok = strcspn(line + idx, "\n\t "); - GVA_HGVS_Allele allele = gva_parse_hgvs(gva_std_allocator, reference.len, reference.str, tok, line + idx ); - if (!allele.interpretable) - { - fprintf(stderr, "%zu: ERROR HGVS: %s", line_count, line); - continue; - } // if - idx += tok + 1; - - ARRAY_DESTROY(gva_std_allocator, allele.inserted); - ARRAY_DESTROY(gva_std_allocator, allele.variants); - } //while - - gva_string_destroy(gva_std_allocator, reference); - - return EXIT_SUCCESS; -} // hgvs_main +} // gva_to_hgvs From 728fec629fef8b4699da7e56034844656d21b090 Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 29 Jun 2026 15:33:55 +0200 Subject: [PATCH 701/704] WIP: bidirectional alignment --- src/main.c | 211 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 203 insertions(+), 8 deletions(-) diff --git a/src/main.c b/src/main.c index f55b27b..d5bfb81 100644 --- a/src/main.c +++ b/src/main.c @@ -7,6 +7,9 @@ #include // strlen #include "../include/compare.h" // gva_compare_distance +#include "../include/edit.h" // gva_edit_distance +#include "../include/extractor.h" // gva_canonical +#include "../include/hgvs.h" // gva_to_hgvs #include "../include/index.h" // GVA_Index, gva_index_*, GVA_Query_Result #include "../include/lcs_graph.h" // GVA_LCS_Graph, gva_lcs_graph_* #include "../include/mmap_alloc.h" // GVA_Mmap_Context, gva_mmap_* @@ -25,9 +28,9 @@ #define LINE_SIZE 4096 -#define REFERENCE_ID "NC_000022.11" +// #define REFERENCE_ID "NC_000022.11" // #define REFERENCE_ID "NC_000006.12" -// #define REFERENCE_ID "NC_000001.11" +#define REFERENCE_ID "NC_000001.11" // line: alphanumeric_id SPDI [distance] @@ -404,14 +407,162 @@ random_string(size_t const len, char str[static len]) } // for } // random_string +/* extern int base; extern int recurse; extern int multi; +*/ + +static inline size_t +onp_snake(size_t const m, char const a[static restrict m], + size_t const n, char const b[static restrict n], + intmax_t const k, intmax_t const lower, intmax_t const upper, + size_t const p, size_t len_lcs[static restrict 1]) +{ + size_t col = MAX(lower, upper); + size_t row = col - k; + + size_t lcs_pos = (row + col - (n - m) - 2 * p + ABS((intmax_t) (m - row) - (intmax_t) (n - col))) / 2; + + while (row < m && col < n && a[row] == b[col]) + { + //fprintf(stderr, " M (%zu, %zu) @ %zu\n", row, col, lcs_pos); + row += 1; + col += 1; + lcs_pos += 1; + } // while + *len_lcs = MAX(*len_lcs, lcs_pos); + return col; +} // onp_snake + + +static inline size_t +onp_snake_p(size_t const m, char const a[static restrict m], + size_t const n, char const b[static restrict n], + intmax_t const k, intmax_t const lower, intmax_t const upper, + size_t const p, size_t len_lcs[static restrict 1]) +{ + size_t col = MAX(lower, upper); + size_t row = col - k; + + size_t lcs_pos = (row + col - (n - m) - 2 * p + ABS((intmax_t) (m - row) - (intmax_t) (n - col))) / 2; + + while (row < m && col < n && a[m - row - 1] == b[n - col - 1]) + { + //fprintf(stderr, " MP (%zu, %zu) @ %zu\n", m - row - 1, n - col - 1, lcs_pos); + row += 1; + col += 1; + lcs_pos += 1; + } // while + *len_lcs = MAX(*len_lcs, lcs_pos); + return col; +} // onp_snake_p + + +static size_t +onp_compare(size_t const m, char const a[static restrict m], + size_t const n, char const b[static restrict n]) +{ + intmax_t const delta = n - m; + size_t const offset = m + 1; + size_t const size = m + n + 3; + intmax_t* const restrict fp = malloc(size * sizeof(*fp)); + intmax_t* const restrict fpp = malloc(size * sizeof(*fpp)); + if (fp == NULL || fpp == NULL) + { + free(fpp); + free(fp); + return -1; + } // if + + //fprintf(stderr, "%s vs %s\n", a, b); + + for (intmax_t i = -1; i <= delta; ++i) + { + fp[i + offset] = -1; + fpp[i + offset] = -1; + } // for + + size_t len_lcs = 0; + size_t len_lcs_p = 0; + + size_t p = 0; + while (fp[delta + offset] <= (intmax_t) n - fpp[delta + offset] - 1) + { + //fprintf(stderr, "p: %zu\n", p); + fp[-p - 1 + offset] = -1; + for (intmax_t k = -p; k <= delta - 1; ++k) + { + fp[k + offset] = onp_snake(m, a, n, b, k, fp[k - 1 + offset] + 1, fp[k + 1 + offset], p, &len_lcs); + } // for + fp[delta + p + 1 + offset] = -1; + for (intmax_t k = delta + p; k >= delta + 1; --k) + { + fp[k + offset] = onp_snake(m, a, n, b, k, fp[k - 1 + offset] + 1, fp[k + 1 + offset], p, &len_lcs); + } // for + fp[delta + offset] = onp_snake(m, a, n, b, delta, fp[delta - 1 + offset] + 1, fp[delta + 1 + offset], p, &len_lcs); + + + fpp[-p - 1 + offset] = -1; + for (intmax_t k = -p; k <= delta - 1; ++k) + { + fpp[k + offset] = onp_snake_p(m, a, n, b, k, fpp[k - 1 + offset] + 1, fpp[k + 1 + offset], p, &len_lcs_p); + } // for + fpp[delta + p + 1 + offset] = - 1; + for (intmax_t k = delta + p; k >= delta + 1; --k) + { + fpp[k + offset] = onp_snake_p(m, a, n, b, k, fpp[k - 1 + offset] + 1, fpp[k + 1 + offset], p, &len_lcs_p); + } // for + fpp[delta + offset] = onp_snake_p(m, a, n, b, delta, fpp[delta - 1 + offset] + 1, fpp[delta + 1 + offset], p, &len_lcs_p); + +/* + for (intmax_t k = -p; k <= delta - 1; ++k) + { + fprintf(stderr, "%ld ", fp[k + offset]); + } // for + fprintf(stderr, "[%ld] ", fp[delta + offset]); + for (intmax_t k = delta + p; k >= delta + 1; --k) + { + fprintf(stderr, "%ld ", fp[k + offset]); + } // for + fprintf(stderr, ": %zu\n", len_lcs); + + for (intmax_t k = -p; k <= delta - 1; ++k) + { + fprintf(stderr, "%ld ", fpp[k + offset]); + } // for + fprintf(stderr, "[%ld] ", fpp[delta + offset]); + for (intmax_t k = delta + p; k >= delta + 1; --k) + { + fprintf(stderr, "%ld ", fpp[k + offset]); + } // for + fprintf(stderr, ": %zu\n", len_lcs_p); +*/ + p += 1; + } // while + + //fprintf(stderr, "%ld vs %ld\n", fp[delta + offset], (intmax_t) n - fpp[delta + offset] - 1); + + free(fpp); + free(fp); + return p; +} // onp_compare + + +static inline size_t +edit_distance(size_t const len_ref, char const reference[static restrict len_ref], + size_t const len_obs, char const observed[static restrict len_obs]) +{ + return len_ref > len_obs ? + onp_compare(len_obs, observed, len_ref, reference) : + onp_compare(len_ref, reference, len_obs, observed); +} // edit_distance int allele_main(int argc, char* argv[static argc]) { +/* if (argc < 2) { fprintf(stderr, "usage: %s seed\n", argv[0]); @@ -423,7 +574,8 @@ allele_main(int argc, char* argv[static argc]) //GVA_String ref = gva_string_init(gva_std_allocator, 10); //GVA_Variant var = {0, ref.len, gva_string_init(gva_std_allocator, 10)}; - GVA_String ref = gva_string_dup(gva_std_allocator, (GVA_String) {10, "AGGCGTCGAA"}); + + GVA_String ref = gva_string_dup(gva_std_allocator, (GVA_String) {11, "AGGCGTCGAAA"}); GVA_Variant var = {0, ref.len, {10, "GTGTGTGCGG"}}; LCS_Alignment lcs = lcs_align(gva_std_allocator, ref.len, ref.str, var.sequence.len, var.sequence.str, 0); @@ -442,17 +594,17 @@ allele_main(int argc, char* argv[static argc]) lcs.index = gva_std_allocator.allocate(gva_std_allocator.context, lcs.index, lcs.length * sizeof(*lcs.index), 0); lcs.nodes = ARRAY_DESTROY(gva_std_allocator, lcs.nodes); - //while (true) +// while (true) { //random_string(ref.len, (char*) ref.str); //random_string(var.sequence.len, (char*) var.sequence.str); - // base = 0; - // recurse = 0; - // multi = 0; + //base = 0; + //recurse = 0; + //multi = 0; GVA_LCS_Graph g = gva_lcs_graph_from_allele(gva_std_allocator, ref.len, ref.str, 1, &var); - // if (base > 1 && recurse > 2 && multi) + if (base > 1 && recurse > 2 && multi) { fprintf(stderr, GVA_STRING_FMT " vs " GVA_STRING_FMT "\n", GVA_STRING_PRINT(ref), GVA_STRING_PRINT(var.sequence)); //fprintf(stderr, GVA_STRING_FMT ":" GVA_VARIANT_FMT "\n", GVA_STRING_PRINT(ref), GVA_VARIANT_PRINT(gva_lcs_graph_supremal(g))); @@ -470,6 +622,7 @@ allele_main(int argc, char* argv[static argc]) gva_string_destroy(gva_std_allocator, ref); return EXIT_SUCCESS; +*/ if (argc < 3) { @@ -526,9 +679,22 @@ allele_main(int argc, char* argv[static argc]) ARRAY_APPEND(gva_std_allocator, variants, gva_variant_dup(gva_std_allocator, trimmed)); } // while fclose(stream); + + GVA_String observed = gva_patch(gva_std_allocator, reference.len, reference.str, array_length(variants), variants); + fprintf(stderr, "#variants: %zu\n", array_length(variants)); fprintf(stderr, "#dropped: %zu\n", dropped); + size_t const distance = edit_distance(reference.len, reference.str, observed.len, observed.str); + + fprintf(stderr, "distance: %zu\n", distance); + + gva_string_destroy(gva_std_allocator, observed); + + + + +/* GVA_LCS_Graph graph = gva_lcs_graph_from_allele(gva_std_allocator, reference.len, reference.str, array_length(variants), variants); for (size_t i = 0; i < array_length(graph.dom_nodes) - 1; ++i) { @@ -540,6 +706,7 @@ allele_main(int argc, char* argv[static argc]) fprintf(stderr, "#edges: %zu\n", array_length(graph.edges)); gva_lcs_graph_destroy(gva_std_allocator, graph, true); +*/ if (variants != NULL) { @@ -812,6 +979,33 @@ all_main(int argc, char* argv[static argc]) } // all_main +int +hgvs_main(int argc, char* argv[static argc]) +{ + if (argc < 4) + { + fprintf(stderr, "usage: %s reference observed hgvs\n", argv[0]); + return EXIT_FAILURE; + } // if + + GVA_LCS_Graph graph = gva_lcs_graph_init(gva_std_allocator, strlen(argv[1]), argv[1], strlen(argv[2]), argv[2], 0); + GVA_Variant* variants = gva_canonical(gva_std_allocator, graph); + + static char buffer[LINE_SIZE] = {'\0'}; + gva_to_hgvs(LINE_SIZE, buffer, strlen(argv[1]), argv[1], array_length(variants), variants); + + if (memcmp(buffer, argv[3], strlen(argv[3])) != 0) + { + fprintf(stderr, "DIFF: %s vs %s\n", buffer, argv[3]); + } // if + + ARRAY_DESTROY(gva_std_allocator, variants); + gva_lcs_graph_destroy(gva_std_allocator, graph, false); + + return EXIT_SUCCESS; +} // hgvs_main + + int main(int argc, char* argv[static argc]) { @@ -819,4 +1013,5 @@ main(int argc, char* argv[static argc]) // return index_main(argc, argv); // return overlap_main(argc, argv); // return all_main(argc, argv); + // return hgvs_main(argc, argv); } // main From 8143f366b2eff82ef526c965fbd8a3cf606f9fa5 Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 6 Jul 2026 17:24:26 +0200 Subject: [PATCH 702/704] Debugging bidirectional --- src/main.c | 80 +++++++++++++++++++++++++++++------------------------- 1 file changed, 43 insertions(+), 37 deletions(-) diff --git a/src/main.c b/src/main.c index dd9da9f..8f9952e 100644 --- a/src/main.c +++ b/src/main.c @@ -417,6 +417,7 @@ static inline size_t onp_snake(size_t const m, char const a[static restrict m], size_t const n, char const b[static restrict n], intmax_t const k, intmax_t const lower, intmax_t const upper, + size_t const max_col, size_t const p, size_t len_lcs[static restrict 1]) { size_t col = MAX(lower, upper); @@ -424,9 +425,9 @@ onp_snake(size_t const m, char const a[static restrict m], size_t lcs_pos = (row + col - (n - m) - 2 * p + ABS((intmax_t) (m - row) - (intmax_t) (n - col))) / 2; - while (row < m && col < n && a[row] == b[col]) + while (row < m && col < max_col && a[row] == b[col]) { - //fprintf(stderr, " M (%zu, %zu) @ %zu\n", row, col, lcs_pos); + fprintf(stderr, " M (%zu, %zu) @ %zu\n", row, col, lcs_pos); row += 1; col += 1; lcs_pos += 1; @@ -440,6 +441,7 @@ static inline size_t onp_snake_p(size_t const m, char const a[static restrict m], size_t const n, char const b[static restrict n], intmax_t const k, intmax_t const lower, intmax_t const upper, + size_t const max_col, size_t const p, size_t len_lcs[static restrict 1]) { size_t col = MAX(lower, upper); @@ -447,9 +449,9 @@ onp_snake_p(size_t const m, char const a[static restrict m], size_t lcs_pos = (row + col - (n - m) - 2 * p + ABS((intmax_t) (m - row) - (intmax_t) (n - col))) / 2; - while (row < m && col < n && a[m - row - 1] == b[n - col - 1]) + while (row < m && col < max_col && a[m - row - 1] == b[n - col - 1]) { - //fprintf(stderr, " MP (%zu, %zu) @ %zu\n", m - row - 1, n - col - 1, lcs_pos); + fprintf(stderr, " MP (%zu, %zu) @ %zu\n", m - row - 1, n - col - 1, lcs_pos); row += 1; col += 1; lcs_pos += 1; @@ -484,36 +486,40 @@ onp_compare(size_t const m, char const a[static restrict m], size_t len_lcs = 0; size_t len_lcs_p = 0; + size_t forward = 0; + size_t backward = 0; + size_t p = 0; while (fp[delta + offset] <= (intmax_t) n - fpp[delta + offset] - 1) { - //fprintf(stderr, "p: %zu\n", p); + fprintf(stderr, "p: %zu\n", p); + fp[-p - 1 + offset] = -1; for (intmax_t k = -p; k <= delta - 1; ++k) { - fp[k + offset] = onp_snake(m, a, n, b, k, fp[k - 1 + offset] + 1, fp[k + 1 + offset], p, &len_lcs); + fp[k + offset] = onp_snake(m, a, n, b, k, fp[k - 1 + offset] + 1, fp[k + 1 + offset], n - backward, p, &len_lcs); } // for fp[delta + p + 1 + offset] = -1; for (intmax_t k = delta + p; k >= delta + 1; --k) { - fp[k + offset] = onp_snake(m, a, n, b, k, fp[k - 1 + offset] + 1, fp[k + 1 + offset], p, &len_lcs); + fp[k + offset] = onp_snake(m, a, n, b, k, fp[k - 1 + offset] + 1, fp[k + 1 + offset], n - backward, p, &len_lcs); } // for - fp[delta + offset] = onp_snake(m, a, n, b, delta, fp[delta - 1 + offset] + 1, fp[delta + 1 + offset], p, &len_lcs); + forward = fp[delta + offset] = onp_snake(m, a, n, b, delta, fp[delta - 1 + offset] + 1, fp[delta + 1 + offset], n - backward, p, &len_lcs); fpp[-p - 1 + offset] = -1; for (intmax_t k = -p; k <= delta - 1; ++k) { - fpp[k + offset] = onp_snake_p(m, a, n, b, k, fpp[k - 1 + offset] + 1, fpp[k + 1 + offset], p, &len_lcs_p); + fpp[k + offset] = onp_snake_p(m, a, n, b, k, fpp[k - 1 + offset] + 1, fpp[k + 1 + offset], n - forward, p, &len_lcs_p); } // for fpp[delta + p + 1 + offset] = - 1; for (intmax_t k = delta + p; k >= delta + 1; --k) { - fpp[k + offset] = onp_snake_p(m, a, n, b, k, fpp[k - 1 + offset] + 1, fpp[k + 1 + offset], p, &len_lcs_p); + fpp[k + offset] = onp_snake_p(m, a, n, b, k, fpp[k - 1 + offset] + 1, fpp[k + 1 + offset], n - forward, p, &len_lcs_p); } // for - fpp[delta + offset] = onp_snake_p(m, a, n, b, delta, fpp[delta - 1 + offset] + 1, fpp[delta + 1 + offset], p, &len_lcs_p); + backward = fpp[delta + offset] = onp_snake_p(m, a, n, b, delta, fpp[delta - 1 + offset] + 1, fpp[delta + 1 + offset], n - forward, p, &len_lcs_p); + -/* for (intmax_t k = -p; k <= delta - 1; ++k) { fprintf(stderr, "%ld ", fp[k + offset]); @@ -535,15 +541,13 @@ onp_compare(size_t const m, char const a[static restrict m], fprintf(stderr, "%ld ", fpp[k + offset]); } // for fprintf(stderr, ": %zu\n", len_lcs_p); -*/ + p += 1; } // while - //fprintf(stderr, "%ld vs %ld\n", fp[delta + offset], (intmax_t) n - fpp[delta + offset] - 1); - free(fpp); free(fp); - return p; + return len_lcs + len_lcs_p; } // onp_compare @@ -560,7 +564,7 @@ edit_distance(size_t const len_ref, char const reference[static restrict len_ref int allele_main(int argc, char* argv[static argc]) { -/* + if (argc < 2) { fprintf(stderr, "usage: %s seed\n", argv[0]); @@ -573,9 +577,14 @@ allele_main(int argc, char* argv[static argc]) //GVA_Variant var = {0, ref.len, gva_string_init(gva_std_allocator, 10)}; - GVA_String ref = gva_string_dup(gva_std_allocator, (GVA_String) {10, "AGGCGTCGAA"}); - GVA_Variant var = {0, ref.len, {10, "GTGTGTGCGG"}}; + //GVA_String ref = gva_string_dup(gva_std_allocator, (GVA_String) {10, "AGGCGTCGAA"}); + //GVA_Variant var = {0, ref.len, {10, "GTGTGTGCGG"}}; + + GVA_String ref = gva_string_dup(gva_std_allocator, (GVA_String) {10, "CTATATGGAT"}); + GVA_Variant var = {0, ref.len, {10, "TCTTCAGTGG"}}; + +/* LCS_Alignment lcs = lcs_align(gva_std_allocator, ref.len, ref.str, var.sequence.len, var.sequence.str, 0); fprintf(stderr, "%zu\n", lcs.length); @@ -593,37 +602,34 @@ allele_main(int argc, char* argv[static argc]) lcs.nodes = ARRAY_DESTROY(gva_std_allocator, lcs.nodes); size_t const distance = edit_distance(ref.len, ref.str, var.sequence.len, var.sequence.str); + fprintf(stderr, "lcs = %zu\n", distance); -// while (true) + return EXIT_SUCCESS; +*/ + //while (true) { //random_string(ref.len, (char*) ref.str); //random_string(var.sequence.len, (char*) var.sequence.str); - //base = 0; - //recurse = 0; - //multi = 0; - GVA_LCS_Graph g = gva_lcs_graph_from_allele(gva_std_allocator, ref.len, ref.str, 1, &var); + size_t const len_lcs = edit_distance(ref.len, ref.str, var.sequence.len, var.sequence.str); + size_t const distance = gva_edit_distance(gva_std_allocator, ref.len, ref.str, var.sequence.len, var.sequence.str); - if (base > 1 && recurse > 2 && multi) + if (ref.len + var.sequence.len - 2 * len_lcs != distance) { + fprintf(stderr, "len_lcs: %zu\n", len_lcs); + fprintf(stderr, "distance: %zu\n", distance); + fprintf(stderr, "true lcs: %zu\n", (ref.len + var.sequence.len - distance) / 2); fprintf(stderr, GVA_STRING_FMT " vs " GVA_STRING_FMT "\n", GVA_STRING_PRINT(ref), GVA_STRING_PRINT(var.sequence)); - //fprintf(stderr, GVA_STRING_FMT ":" GVA_VARIANT_FMT "\n", GVA_STRING_PRINT(ref), GVA_VARIANT_PRINT(gva_lcs_graph_supremal(g))); - for (size_t i = 0; i < array_length(g.dom_nodes) - 1; ++i) - { - fprintf(stderr, " " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(gva_lcs_graph_local_supremal(g, i, i + 1))); - } // for - fprintf(stderr, "\n"); + //break; } // if - gva_lcs_graph_destroy(gva_std_allocator, g, true); } // while - - // gva_string_destroy(gva_std_allocator, var.sequence); + gva_string_destroy(gva_std_allocator, var.sequence); gva_string_destroy(gva_std_allocator, ref); return EXIT_SUCCESS; -*/ +/* if (argc < 3) { @@ -691,7 +697,7 @@ allele_main(int argc, char* argv[static argc]) fprintf(stderr, "distance: %zu\n", distance); gva_string_destroy(gva_std_allocator, observed); - +*/ /* GVA_LCS_Graph graph = gva_lcs_graph_from_allele(gva_std_allocator, reference.len, reference.str, array_length(variants), variants); for (size_t i = 0; i < array_length(graph.dom_nodes) - 1; ++i) @@ -715,7 +721,7 @@ allele_main(int argc, char* argv[static argc]) } // if */ - gva_string_destroy(gva_std_allocator, reference); + //gva_string_destroy(gva_std_allocator, reference); return EXIT_SUCCESS; From 64ad6e99db841dbc0caf08db2e800be192af5636 Mon Sep 17 00:00:00 2001 From: jkvis Date: Mon, 24 Aug 2026 16:09:33 +0200 Subject: [PATCH 703/704] Clean up --- src/lcs_graph.c | 37 -------- src/main.c | 243 +----------------------------------------------- 2 files changed, 1 insertion(+), 279 deletions(-) diff --git a/src/lcs_graph.c b/src/lcs_graph.c index d6c9e8f..9838b89 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -14,9 +14,6 @@ #include "common.h" // GVA_NULL, MAX, MIN, gva_uint -#include // FIXME: DEBUG - - static void concat(GVA_Allocator const allocator, GVA_LCS_Graph lhs[static 1], GVA_LCS_Graph const rhs, @@ -81,12 +78,6 @@ concat(GVA_Allocator const allocator, } // concat -/* -int multi; -int recurse; -int base; -*/ - // FIXME: recursion! static void local_supremal(GVA_Allocator const allocator, @@ -95,13 +86,9 @@ local_supremal(GVA_Allocator const allocator, size_t const offset_row, size_t const offset_col, GVA_LCS_Graph graph[static restrict 1]) { - //fprintf(stderr, GVA_STRING_FMT " vs " GVA_STRING_FMT "\n", GVA_STRING_PRINT(((GVA_String) {len_ref, reference})), GVA_STRING_PRINT(((GVA_String) {len_obs, observed}))); - if (len_ref == 0 || len_obs == 0) { - //base += 1; GVA_LCS_Graph local = gva_lcs_graph_init(allocator, len_ref, reference, len_obs, observed, offset_row); - //fprintf(stderr, "BASE: " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(gva_lcs_graph_supremal(local))); concat(allocator, graph, local, offset_col); gva_lcs_graph_destroy(allocator, local, false); return; @@ -122,12 +109,6 @@ local_supremal(GVA_Allocator const allocator, { size_t const j = forward.max_lcs_pos - i - 1; - /* - fprintf(stderr, "%zu: (%u, %u) %d (%zu, %zu) %d\n", i, - forward.match[i].row, forward.match[i].col, forward.uniq[i], - len_ref - backward.match[j].row - 1, len_obs - backward.match[j].col - 1, backward.uniq[j]); - */ - if (forward.match[i].row == len_ref - backward.match[j].row - 1 && forward.match[i].col == len_obs - backward.match[j].col - 1 && (forward.uniq[i] == 1 || backward.uniq[j] == 1)) @@ -135,15 +116,12 @@ local_supremal(GVA_Allocator const allocator, size_t const distance = forward.match[i].row + forward.match[i].col - 2 * i - sum; if (distance > 0) { - //recurse += 1; sum += distance; - //fprintf(stderr, "RECURSE %u %u %d %d {\n", forward.match[i].row, forward.match[i].col, forward.uniq[i], backward.uniq[j]); local_supremal(allocator, forward.match[i].row - prev_row - 1, reference + prev_row + 1, forward.match[i].col - prev_col - 1, observed + prev_col + 1, offset_row + prev_row + 1, offset_col + prev_col + 1, graph); - //fprintf(stderr, "}\n"); } // if prev_row = forward.match[i].row; @@ -155,30 +133,15 @@ local_supremal(GVA_Allocator const allocator, { if (prev_row != (size_t) -1) { - //recurse += 1; - //fprintf(stderr, "RECURSE {\n"); local_supremal(allocator, len_ref - prev_row - 1, reference + prev_row + 1, len_obs - prev_col - 1, observed + prev_col + 1, offset_row + prev_row + 1, offset_col + prev_col + 1, graph); - //fprintf(stderr, "}\n"); } // if else { GVA_LCS_Graph local = gva_lcs_graph_init(allocator, len_ref - prev_row - 1, reference + prev_row + 1, len_obs - prev_col - 1, observed + prev_col + 1, offset_row + prev_row + 1); - /* - fprintf(stderr, GVA_VARIANT_FMT " %zu\n", GVA_VARIANT_PRINT(gva_lcs_graph_supremal(local)), gva_variant_length(gva_lcs_graph_supremal(local))); - if (array_length(local.dom_nodes) == 3) - { - multi = 1; - fprintf(stderr, "MULTI\n"); - for (size_t i = 0; i < array_length(local.dom_nodes) - 1; ++i) - { - fprintf(stderr, " " GVA_VARIANT_FMT "\n", GVA_VARIANT_PRINT(gva_lcs_graph_local_supremal(local, i, i + 1))); - } // for - } // if - */ concat(allocator, graph, local, offset_col + prev_col + 1); gva_lcs_graph_destroy(allocator, local, false); } // else diff --git a/src/main.c b/src/main.c index 8f9952e..1658a43 100644 --- a/src/main.c +++ b/src/main.c @@ -398,239 +398,9 @@ index_main(int argc, char* argv[static argc]) } // index_main -void -random_string(size_t const len, char str[static len]) -{ - for (size_t i = 0; i < len; ++i) - { - str[i] = "ACGT"[rand() % 4]; - } // for -} // random_string - -/* -extern int base; -extern int recurse; -extern int multi; -*/ - -static inline size_t -onp_snake(size_t const m, char const a[static restrict m], - size_t const n, char const b[static restrict n], - intmax_t const k, intmax_t const lower, intmax_t const upper, - size_t const max_col, - size_t const p, size_t len_lcs[static restrict 1]) -{ - size_t col = MAX(lower, upper); - size_t row = col - k; - - size_t lcs_pos = (row + col - (n - m) - 2 * p + ABS((intmax_t) (m - row) - (intmax_t) (n - col))) / 2; - - while (row < m && col < max_col && a[row] == b[col]) - { - fprintf(stderr, " M (%zu, %zu) @ %zu\n", row, col, lcs_pos); - row += 1; - col += 1; - lcs_pos += 1; - } // while - *len_lcs = MAX(*len_lcs, lcs_pos); - return col; -} // onp_snake - - -static inline size_t -onp_snake_p(size_t const m, char const a[static restrict m], - size_t const n, char const b[static restrict n], - intmax_t const k, intmax_t const lower, intmax_t const upper, - size_t const max_col, - size_t const p, size_t len_lcs[static restrict 1]) -{ - size_t col = MAX(lower, upper); - size_t row = col - k; - - size_t lcs_pos = (row + col - (n - m) - 2 * p + ABS((intmax_t) (m - row) - (intmax_t) (n - col))) / 2; - - while (row < m && col < max_col && a[m - row - 1] == b[n - col - 1]) - { - fprintf(stderr, " MP (%zu, %zu) @ %zu\n", m - row - 1, n - col - 1, lcs_pos); - row += 1; - col += 1; - lcs_pos += 1; - } // while - *len_lcs = MAX(*len_lcs, lcs_pos); - return col; -} // onp_snake_p - - -static size_t -onp_compare(size_t const m, char const a[static restrict m], - size_t const n, char const b[static restrict n]) -{ - intmax_t const delta = n - m; - size_t const offset = m + 1; - size_t const size = m + n + 3; - intmax_t* const restrict fp = malloc(size * sizeof(*fp)); - intmax_t* const restrict fpp = malloc(size * sizeof(*fpp)); - if (fp == NULL || fpp == NULL) - { - free(fpp); - free(fp); - return -1; - } // if - - for (intmax_t i = -1; i <= delta; ++i) - { - fp[i + offset] = -1; - fpp[i + offset] = -1; - } // for - - size_t len_lcs = 0; - size_t len_lcs_p = 0; - - size_t forward = 0; - size_t backward = 0; - - size_t p = 0; - while (fp[delta + offset] <= (intmax_t) n - fpp[delta + offset] - 1) - { - fprintf(stderr, "p: %zu\n", p); - - fp[-p - 1 + offset] = -1; - for (intmax_t k = -p; k <= delta - 1; ++k) - { - fp[k + offset] = onp_snake(m, a, n, b, k, fp[k - 1 + offset] + 1, fp[k + 1 + offset], n - backward, p, &len_lcs); - } // for - fp[delta + p + 1 + offset] = -1; - for (intmax_t k = delta + p; k >= delta + 1; --k) - { - fp[k + offset] = onp_snake(m, a, n, b, k, fp[k - 1 + offset] + 1, fp[k + 1 + offset], n - backward, p, &len_lcs); - } // for - forward = fp[delta + offset] = onp_snake(m, a, n, b, delta, fp[delta - 1 + offset] + 1, fp[delta + 1 + offset], n - backward, p, &len_lcs); - - - fpp[-p - 1 + offset] = -1; - for (intmax_t k = -p; k <= delta - 1; ++k) - { - fpp[k + offset] = onp_snake_p(m, a, n, b, k, fpp[k - 1 + offset] + 1, fpp[k + 1 + offset], n - forward, p, &len_lcs_p); - } // for - fpp[delta + p + 1 + offset] = - 1; - for (intmax_t k = delta + p; k >= delta + 1; --k) - { - fpp[k + offset] = onp_snake_p(m, a, n, b, k, fpp[k - 1 + offset] + 1, fpp[k + 1 + offset], n - forward, p, &len_lcs_p); - } // for - backward = fpp[delta + offset] = onp_snake_p(m, a, n, b, delta, fpp[delta - 1 + offset] + 1, fpp[delta + 1 + offset], n - forward, p, &len_lcs_p); - - - for (intmax_t k = -p; k <= delta - 1; ++k) - { - fprintf(stderr, "%ld ", fp[k + offset]); - } // for - fprintf(stderr, "[%ld] ", fp[delta + offset]); - for (intmax_t k = delta + p; k >= delta + 1; --k) - { - fprintf(stderr, "%ld ", fp[k + offset]); - } // for - fprintf(stderr, ": %zu\n", len_lcs); - - for (intmax_t k = -p; k <= delta - 1; ++k) - { - fprintf(stderr, "%ld ", fpp[k + offset]); - } // for - fprintf(stderr, "[%ld] ", fpp[delta + offset]); - for (intmax_t k = delta + p; k >= delta + 1; --k) - { - fprintf(stderr, "%ld ", fpp[k + offset]); - } // for - fprintf(stderr, ": %zu\n", len_lcs_p); - - p += 1; - } // while - - free(fpp); - free(fp); - return len_lcs + len_lcs_p; -} // onp_compare - - -static inline size_t -edit_distance(size_t const len_ref, char const reference[static restrict len_ref], - size_t const len_obs, char const observed[static restrict len_obs]) -{ - return len_ref > len_obs ? - onp_compare(len_obs, observed, len_ref, reference) : - onp_compare(len_ref, reference, len_obs, observed); -} // edit_distance - - int allele_main(int argc, char* argv[static argc]) { - - if (argc < 2) - { - fprintf(stderr, "usage: %s seed\n", argv[0]); - return EXIT_FAILURE; - } // if - - srand(atoi(argv[1])); - - //GVA_String ref = gva_string_init(gva_std_allocator, 10); - //GVA_Variant var = {0, ref.len, gva_string_init(gva_std_allocator, 10)}; - - - //GVA_String ref = gva_string_dup(gva_std_allocator, (GVA_String) {10, "AGGCGTCGAA"}); - //GVA_Variant var = {0, ref.len, {10, "GTGTGTGCGG"}}; - - GVA_String ref = gva_string_dup(gva_std_allocator, (GVA_String) {10, "CTATATGGAT"}); - GVA_Variant var = {0, ref.len, {10, "TCTTCAGTGG"}}; - - -/* - LCS_Alignment lcs = lcs_align(gva_std_allocator, ref.len, ref.str, var.sequence.len, var.sequence.str, 0); - - fprintf(stderr, "%zu\n", lcs.length); - for (size_t i = 0; i < lcs.length; ++i) - { - fprintf(stderr, "%zu: ", i); - for (gva_uint j = lcs.index[i].head; j != GVA_NULL; j = lcs.nodes[j].next) - { - fprintf(stderr, "(%u, %u, %u) ", lcs.nodes[j].match.row, lcs.nodes[j].match.col, lcs.nodes[j].match.length); - } // for - fprintf(stderr, "\n"); - } // for - - lcs.index = gva_std_allocator.allocate(gva_std_allocator.context, lcs.index, lcs.length * sizeof(*lcs.index), 0); - lcs.nodes = ARRAY_DESTROY(gva_std_allocator, lcs.nodes); - - size_t const distance = edit_distance(ref.len, ref.str, var.sequence.len, var.sequence.str); - fprintf(stderr, "lcs = %zu\n", distance); - - return EXIT_SUCCESS; -*/ - //while (true) - { - //random_string(ref.len, (char*) ref.str); - //random_string(var.sequence.len, (char*) var.sequence.str); - - size_t const len_lcs = edit_distance(ref.len, ref.str, var.sequence.len, var.sequence.str); - size_t const distance = gva_edit_distance(gva_std_allocator, ref.len, ref.str, var.sequence.len, var.sequence.str); - - if (ref.len + var.sequence.len - 2 * len_lcs != distance) - { - fprintf(stderr, "len_lcs: %zu\n", len_lcs); - fprintf(stderr, "distance: %zu\n", distance); - fprintf(stderr, "true lcs: %zu\n", (ref.len + var.sequence.len - distance) / 2); - fprintf(stderr, GVA_STRING_FMT " vs " GVA_STRING_FMT "\n", GVA_STRING_PRINT(ref), GVA_STRING_PRINT(var.sequence)); - //break; - } // if - - } // while - - gva_string_destroy(gva_std_allocator, var.sequence); - gva_string_destroy(gva_std_allocator, ref); - - return EXIT_SUCCESS; -/* - if (argc < 3) { fprintf(stderr, "usage: %s reference observed\n", argv[0]); @@ -687,18 +457,9 @@ allele_main(int argc, char* argv[static argc]) } // while fclose(stream); - GVA_String observed = gva_patch(gva_std_allocator, reference.len, reference.str, array_length(variants), variants); - fprintf(stderr, "#variants: %zu\n", array_length(variants)); fprintf(stderr, "#dropped: %zu\n", dropped); - size_t const distance = edit_distance(reference.len, reference.str, observed.len, observed.str); - - fprintf(stderr, "distance: %zu\n", distance); - - gva_string_destroy(gva_std_allocator, observed); -*/ -/* GVA_LCS_Graph graph = gva_lcs_graph_from_allele(gva_std_allocator, reference.len, reference.str, array_length(variants), variants); for (size_t i = 0; i < array_length(graph.dom_nodes) - 1; ++i) { @@ -719,12 +480,10 @@ allele_main(int argc, char* argv[static argc]) } // for variants = ARRAY_DESTROY(gva_std_allocator, variants); } // if -*/ - //gva_string_destroy(gva_std_allocator, reference); + gva_string_destroy(gva_std_allocator, reference); return EXIT_SUCCESS; - } // allele_main From 65f0e9391dfe0c2fb2089600754942c41fe8e7d8 Mon Sep 17 00:00:00 2001 From: jkvis Date: Fri, 4 Sep 2026 14:58:04 +0200 Subject: [PATCH 704/704] Two string main with LCS nodes --- src/lcs_graph.c | 13 +++++++++++++ src/main.c | 23 ++++++++++++++++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/lcs_graph.c b/src/lcs_graph.c index 9838b89..a0e8dc6 100644 --- a/src/lcs_graph.c +++ b/src/lcs_graph.c @@ -14,6 +14,9 @@ #include "common.h" // GVA_NULL, MAX, MIN, gva_uint +#include // FIXME: DEBUG + + static void concat(GVA_Allocator const allocator, GVA_LCS_Graph lhs[static 1], GVA_LCS_Graph const rhs, @@ -163,6 +166,16 @@ gva_lcs_graph_init(GVA_Allocator const allocator, LCS_Alignment lcs = lcs_align(allocator, len_ref, reference, len_obs, observed, offset); size_t const distance = len_ref + len_obs - 2 * lcs.length; + for (size_t i = 0; i < lcs.length; ++i) + { + fprintf(stderr, "%zu: ", i); + for (gva_uint j = lcs.index[i].head; j != GVA_NULL; j = lcs.nodes[j].next) + { + fprintf(stderr, "(%u, %u, %u), ", lcs.nodes[j].match.row, lcs.nodes[j].match.col, lcs.nodes[j].match.length); + } // for + fprintf(stderr, "\n"); + } // for + GVA_LCS_Graph graph = { .observed = {len_obs, observed}, diff --git a/src/main.c b/src/main.c index 1658a43..047edc3 100644 --- a/src/main.c +++ b/src/main.c @@ -770,10 +770,31 @@ hgvs_main(int argc, char* argv[static argc]) } // hgvs_main +int +pair_main(int argc, char* argv[static argc]) +{ + if (argc < 3) + { + fprintf(stderr, "usage: %s reference observed\n", argv[0]); + return EXIT_FAILURE; + } // if + + GVA_LCS_Graph graph = gva_lcs_graph_init(gva_std_allocator, strlen(argv[1]), argv[1], strlen(argv[2]), argv[2], 0); + + gva_lcs_graph_dot(stdout, graph); + + gva_lcs_graph_destroy(gva_std_allocator, graph, false); + + return EXIT_SUCCESS; +} // hgvs_main + + + int main(int argc, char* argv[static argc]) { - return allele_main(argc, argv); + return pair_main(argc, argv); + // return allele_main(argc, argv); // return index_main(argc, argv); // return overlap_main(argc, argv); // return all_main(argc, argv);