bingo/sqlserver/Source/MangoFastIndexFetch.cs (127 lines of code) (raw):

using System; using System.IO; using System.Collections.Generic; using System.Collections; using System.Text; using System.Data; using System.Data.SqlClient; using System.Data.SqlTypes; using System.Runtime.Serialization.Formatters.Binary; using System.Runtime.InteropServices; namespace indigo { public class MangoFastIndexFetch { MangoIndexData _index_data; enum SearchType { UNDEF, SUB, SIM } ; SearchType search_type = SearchType.UNDEF; bool highlighting = false; public MangoFastIndexFetch (MangoIndexData index_data) { _index_data = index_data; } public int? nextAfterStorageId { get; set; } public void prepareSub (string query, string options, bool highlighting, bool smarts) { int res = BingoCore.lib.mangoSetupMatch(smarts ? "SMARTS" : "SUB", query, options); if (res < 0) throw new Exception(BingoCore.lib.bingoGetError()); search_type = SearchType.SUB; BingoCore.lib.mangoSetHightlightingMode(highlighting ? 1 : 0); this.highlighting = highlighting; } public void prepareSimilarity (string query, string options, float min, float max) { int res = BingoCore.lib.mangoSetupMatch("SIM", query, options); if (res < 0) throw new Exception(BingoCore.lib.bingoGetError()); BingoCore.lib.mangoSimilaritySetMinMaxBounds(min, max); search_type = SearchType.SIM; } private void simGetMinMaxBounds (IList<int> storage_ids, ref int[] min_common_ones, ref int[] max_common_ones, SqlConnection conn) { BingoTimer timer2 = new BingoTimer("fingerprints.screening_bounds_ones"); int cache_index = 0; int[] targets_ones = new int[storage_ids.Count]; for (int i = 0; i < storage_ids.Count; i++) { int storage_id = storage_ids[i]; targets_ones[i] = _index_data.storage.getShort(storage_id, 4, conn, ref cache_index); } timer2.end(); BingoTimer timer3 = new BingoTimer("fingerprints.screening_bounds_get"); IntPtr min_common_ones_ptr, max_common_ones_ptr; BingoCore.lib.mangoSimilarityGetBitMinMaxBoundsArray(targets_ones.Length, targets_ones, out min_common_ones_ptr, out max_common_ones_ptr); if (min_common_ones.Length != storage_ids.Count || max_common_ones.Length != storage_ids.Count) throw new Exception("Internal error in simGetMinMaxBounds: array lengths mismatch"); Marshal.Copy(min_common_ones_ptr, min_common_ones, 0, targets_ones.Length); Marshal.Copy(max_common_ones_ptr, max_common_ones, 0, targets_ones.Length); timer3.end(); } public IEnumerable<FetchedData> fetch (SqlConnection conn) { byte[] fp; BingoCore.mangoGetQueryFingerprint(out fp); // Search using fast index _index_data.fingerprints.init(conn); _index_data.storage.validate(conn); int need_coords = BingoCore.lib.mangoNeedCoords(); byte[] xyz = new byte[0]; IEnumerable<int> screened; if (search_type == SearchType.SUB) { if (!_index_data.fingerprints.ableToScreen(fp)) screened = _index_data.storage.enumerateStorageIds(nextAfterStorageId); else screened = _index_data.fingerprints.screenSub(conn, fp, nextAfterStorageId); } else { screened = _index_data.fingerprints.screenSim(conn, fp, nextAfterStorageId, new BingoFingerprints.getBoundsDelegate(simGetMinMaxBounds)); } int cache_index = 0; foreach (int storage_id in screened) { if (_index_data.storage.isDeleted(storage_id, conn, ref cache_index)) continue; // TODO: add match with xyz test for binary molecules byte[] data_with_cmf = _index_data.storage.get(storage_id, 6, -1, conn, ref cache_index); if (need_coords != 0) { xyz = _index_data.getXyz(storage_id, conn); } int ret = BingoCore.lib.mangoMatchTargetBinary(data_with_cmf, data_with_cmf.Length, xyz, xyz.Length); if (ret < 0) { // Exception has happend // Extract id int id = _index_data.storage.getInt(storage_id, 0, conn, ref cache_index); string msg = "Undef"; if (ret == -2) msg = BingoCore.lib.bingoGetError(); if (ret == -1) msg = BingoCore.lib.bingoGetWarning(); throw new Exception(String.Format("Id = {0}: {1}", id, msg)); } if (ret == 1) { // Extract id int id = _index_data.storage.getInt(storage_id, 0, conn, ref cache_index); FetchedData mol = new FetchedData(id); if (highlighting) { if (need_coords == 0) { // Load xyz byte[] xyz_found = _index_data.getXyz(storage_id, conn); BingoCore.lib.mangoLoadTargetBinaryXyz(xyz_found, xyz_found.Length); } mol.str = BingoCore.mangoGetHightlightedMolecule(); } if (search_type == SearchType.SIM) BingoCore.lib.mangoSimilarityGetScore(out mol.value); yield return mol; } } } } }