/// <summary> /// Determine if match passes the current filter settings /// </summary> /// <param name="ssm"></param> /// <param name="dbId"></param> /// <param name="searchType"></param> /// <param name="searchTypeCount"></param> /// <param name="include"></param> /// <returns></returns> bool FilterMatch( StructSearchMatch ssm, int dbId, StructureSearchType searchType, CheckEdit searchTypeCtl, ref int searchTypeCount, ref bool include) { bool dbChecked = false; if (dbId == CorpDbId) { dbChecked = CorpDB.Checked; } else if (dbId == ChemblDbId) { dbChecked = ChemblDB.Checked; } if (!dbChecked || ssm.SrcDbId != dbId || ssm.SearchType != searchType) { return(false); } if (searchTypeCtl.Checked) { include = true; } searchTypeCount++; return(true); }
StructSearchMatch ReadFingerprintRec_To_StructSearchMatch( ReadFingerprintRecArgs a) { StructSearchMatch sm = new StructSearchMatch(); sm.SearchType = StructureSearchType.MolSim; sm.SrcDbId = a.src; sm.SrcCid = AsciiEncodingInstance.GetString(a.cidBytes, 0, a.cidLength); if (sm.SrcDbId == 0) { sm.SrcCid = CompoundId.NormalizeForDatabase(sm.SrcCid); // be sure CorpIds are proper length } return(sm); }
/// <summary> /// Find Cid for debug purposes /// </summary> /// <param name="a"></param> /// <returns></returns> bool IsSrcCidMatch( string cid, ReadFingerprintRecArgs a) { StructSearchMatch sm = ReadFingerprintRec_To_StructSearchMatch(a); if (Lex.Eq(sm.SrcCid, cid)) { return(true); } else { return(false); } }
/// <summary> /// Build the set of results rows based on the current key set /// </summary> /// <param name="eqp"></param> void BuildRelatedStructureSearchQueryEngineRows( ExecuteQueryParms eqp) { HashSet <string> keySet = new HashSet <string>(); if (eqp.SearchKeySubset != null) // subsetting { foreach (string cid0 in eqp.SearchKeySubset) { keySet.Add(cid0); } } List <StructSearchMatch> recs = RSS.AllMatches; // start with full match list Results = new List <object[]>(); // destination results list (may or may not be subsetted) for (int ri = 0; ri < recs.Count; ri++) { StructSearchMatch m = recs[ri]; if (keySet != null && keySet.Count > 0 && Lex.IsDefined(m.SrcCid)) { if (!keySet.Contains(m.SrcCid)) { continue; } } if (RestrictedDatabaseView.KeyIsRetricted(m.SrcCid)) { continue; } object[] voa = new object[2]; voa[0] = m.SrcCid; voa[1] = m; Results.Add(voa); } CursorPos = -1; return; }
/// <summary> /// Build the set of results rows based on the current key set /// </summary> /// <returns></returns> void BuildECFP4QueryEngineRows( ExecuteQueryParms eqp) { HashSet <string> keySet = new HashSet <string>(); if (eqp.SearchKeySubset != null) // subsetting { foreach (string cid0 in eqp.SearchKeySubset) { keySet.Add(cid0); } } List <StructSearchMatch> recs = Ecfp4Dao.MatchList; // start with full match list Results = new List <object[]>(); // destination results list (may or may not be subsetted) for (int ri = 0; ri < recs.Count; ri++) { StructSearchMatch m = recs[ri]; if (keySet != null && keySet.Count > 0 && Lex.IsDefined(m.SrcCid)) { if (!keySet.Contains(m.SrcCid)) { continue; } } object[] voa = new object[VoLength]; voa[0] = m.SrcCid; if (VoLength > 1) { voa[1] = m.MatchScore; } Results.Add(voa); } CursorPos = -1; return; }
/// <summary> /// Merge MatchLists for each file that was searched taking best sim score for each compound /// and then sort by decreasing sim score /// </summary> List <StructSearchMatch> MergeIndividualFileMatchLists() { Dictionary <string, StructSearchMatch> matchDict = new Dictionary <string, StructSearchMatch>(); for (int smlIdx = 0; smlIdx < FileMatchLists.Length; smlIdx++) { List <StructSearchMatch> sml = FileMatchLists[smlIdx]; if (sml == null) { continue; } for (int smIdx = 0; smIdx < sml.Count; smIdx++) { StructSearchMatch sm = sml[smIdx]; if (sm == null) { continue; } string key = sm.SrcDbId.ToString() + "." + sm.SrcCid; if (matchDict.ContainsKey(key)) { if (sm.MatchScore > matchDict[key].MatchScore) // take largest similarity value { matchDict[key] = sm; } } else { matchDict[key] = sm; } } } List <StructSearchMatch> matchList = new List <StructSearchMatch>(matchDict.Values); return(matchList); }
/// <summary> /// Search a single file /// </summary> void SearchSingleFile(int fi) { StructSearchMatch sm = null; AssertMx.IsNotNull(FpDao, "FpDao"); List <StructSearchMatch> matchList = FileMatchLists[fi]; AssertMx.IsNotNull(matchList, "matchList"); OpenBitSet queryObs = new OpenBitSet(QueryFpLongArray, QueryFpLongArray.Length); AssertMx.IsNotNull(queryObs, "queryObs"); OpenBitSet dbObs = new OpenBitSet(QueryFpLongArray, QueryFpLongArray.Length); // gets set to DB fp for intersect AssertMx.IsNotNull(dbObs, "dbObs"); FileStream fs = FileStreamReaders[fi]; AssertMx.IsNotNull(fs, "fs"); ReadFingerprintRecArgs a = new ReadFingerprintRecArgs(); a.Initialize(fs, QueryFpLongArray.Length); try { while (true) { bool readOk = FpDao.ReadRawFingerprintRec(a); if (!readOk) { break; } //if (IsSrcCidMatch("03435269", a)) a = a; // debug dbObs.Bits = a.fingerprint; dbObs.Intersect(queryObs); int commonCnt = (int)dbObs.Cardinality(); float simScore = commonCnt / (float)(a.cardinality + QueryFpCardinality - commonCnt); if (simScore >= MinimumSimilarity) { sm = ReadFingerprintRec_To_StructSearchMatch(a); sm.SearchType = StructureSearchType.MolSim; sm.MatchScore = simScore; matchList.Add(sm); } } } catch (Exception ex) { string msg = ex.Message; msg += string.Format("\r\nfi: {0}, fs.Name: {1}, sm: {2}", fi, fs.Name, sm != null ? sm.Serialize() : ""); DebugLog.Message(DebugLog.FormatExceptionMessage(ex, msg)); throw new Exception(msg, ex); } return; }
/// <summary> /// ExecuteSearch /// </summary> /// <param name="queryMol"></param> public List <StructSearchMatch> ExecuteSearch( IAtomContainer queryMol) { AssertMx.IsTrue(FingerprintType == FingerprintType.MACCS || FingerprintType == FingerprintType.Circular, "Invalid FingerprintType: " + FingerprintType); QueryMol = queryMol; BitSetFingerprint fp = // generate a fingerprint CdkMol.BuildBitSetFingerprintForLargestFragment(queryMol, FingerprintType); QueryFpCardinality = fp.cardinality(); QueryFpLongArray = fp.asBitSet().toLongArray(); MatchList = new List <StructSearchMatch>(); ThreadException = null; foreach (string databaseName in FingerprintDbMx.Databases) // loop on all databases { int srcId = -1; if (Lex.Contains(databaseName, "corp")) { if (!GetCorpSim) { continue; } srcId = StructSearchMatch.CorpDbId; } else if (Lex.Contains(databaseName, "chembl")) { if (!GetChemblSim) { continue; } srcId = StructSearchMatch.ChemblDbId; } if (Debug) { DebugLog.Message("Starting sim search on " + databaseName + " database"); } FpDao = new FingerprintDao(databaseName, FingerprintType); if (!FpDao.DataFilesExist()) { continue; // no files for this database } FileStreamReaders = FpDao.OpenReaders(); FileMatchLists = new List <StructSearchMatch> [FileStreamReaders.Length]; for (int i1 = 0; i1 < FileMatchLists.Length; i1++) { FileMatchLists[i1] = new List <StructSearchMatch>(); } DateTime t0 = DateTime.Now; if (UseMultipleThreads) { ExecuteMultiThreadSearch(); } else { ExecuteSingleThreadSearch(); } double et = TimeOfDay.Delta(ref t0); FpDao.CloseReaders(); List <StructSearchMatch> matchList = MergeIndividualFileMatchLists(); if (KeysToExclude != null || SearchKeySubset != null) // filter by any allowed/disallowed keys { List <StructSearchMatch> matchList2 = new List <StructSearchMatch>(); foreach (StructSearchMatch m0 in matchList) { if (KeysToExclude != null && KeysToExclude.Contains(m0.SrcCid)) { continue; } if (SearchKeySubset != null && !SearchKeySubset.Contains(m0.SrcCid)) { continue; } matchList2.Add(m0); } matchList = matchList2; } matchList.Sort(StructSearchMatch.CompareByMatchQuality); //int removeCount = matchList.Count - MaxHits; // limit to maxhits per database //if (removeCount > 0) // matchList.RemoveRange(MaxHits, removeCount); //foreach (StructSearchMatch ssm0 in matchList) // if (ssm0.SrcId != srcId) ssm0.SrcId = srcId; // debug MatchList.AddRange(matchList); double et2 = TimeOfDay.Delta(ref t0); string msg = string.Format("Search complete (" + databaseName + ").Time : {0:0.00} ", et) + string.Format("{0} Hits: ", FileMatchLists[0].Count); if (Debug) { DebugLog.Message(msg); } for (int hi = 0; hi < 5 && hi < FileMatchLists[0].Count; hi++) { StructSearchMatch sm = FileMatchLists[0][hi]; msg += sm.SrcCid + string.Format(" = {0:0.00}, ", sm.MatchScore); } } // database loop if (ThreadException != null) { throw new Exception(ThreadException.Message, ThreadException); } MatchList.Sort( // sort by decreasing sim value delegate(StructSearchMatch p1, StructSearchMatch p2) { return(p2.MatchScore.CompareTo(p1.MatchScore)); }); if (MaxHits > 0 && MatchList.Count > MaxHits) // remove hits beyond maximum if defined { MatchList.RemoveRange(MaxHits, MatchList.Count - MaxHits); } //ShowProgress(msg); //Thread.Sleep(10000000); return(MatchList); }
/// <summary> /// Update the match counts panel and structure view based on a set of structures and filter values /// </summary> /// <param name="excludeCurrentHitList"></param> /// <param name="rssrs"></param> public void DisplayRelatedStructures( List <StructSearchMatch> fml) { MoleculeMx cs; if (fml == null || fml.Count == 0) { DisplayEmptyStructureGrid(); return; } if (StructureDisplayQuery == null) { BuildStructureDisplayQuery(); // initial setup } Query q = StructureDisplayQuery; QueryTable qt = q.Tables[0]; DataTableMx dt = Qm.DataTable; MoleculeGridControl grid = Qm.MoleculeGrid; grid.BeginUpdate(); dt.Clear(); // filter table HashSet <string> cidSet = new HashSet <string>(); for (int mi = 0; mi < fml.Count; mi++) // build and add the rows to the datatable of structures { StructSearchMatch ssm = fml[mi]; DataRowMx dr = dt.NewRow(); dr[qt.Alias + ".CompoundId"] = ssm.SrcCid; cs = new MoleculeMx(ssm.MolStringFormat, ssm.MolString); if (Lex.IsDefined(ssm.SrcCid)) { cs.SetMolComments("CorpId=" + ssm.SrcCid); // Attach CorpId to Molfile so it will be rendered correctly } if (ssm.SearchType == StructureSearchType.SmallWorld && Lex.IsDefined(ssm.GraphicsString)) { cs.SvgString = ssm.GraphicsString; } dr[qt.Alias + ".Structure"] = cs; dr[qt.Alias + ".MatchType"] = ssm.SearchTypeName; dr[qt.Alias + ".MatchScore"] = ssm.MatchScore; dr[qt.Alias + ".Database"] = ssm.SrcName; dt.Rows.Add(dr); cidSet.Add(ssm.SrcCid); } Qm.DataTableManager.InitializeRowAttributes(); string title = "Related Structures - Matches: " + fml.Count + ", Compound Ids: " + cidSet.Count; Qm.MoleculeGrid.SetTableHeaderCaption(0, title); if (!RSC.MoleculeGridPageControl.Visible) { RSC.MoleculeGridPageControl.Visible = true; } grid.EndUpdate(); ToolHelper.RefreshDataDisplay(Qm); return; }
/// <summary> /// Get related structures of the specified types using the supplied compound id for the query structure /// </summary> /// <param name="queryCid"></param> /// <param name="mtName"></param> /// <returns></returns> public static List <StructSearchMatch> GetRelatedMatchRows( string queryCid, string mtName) { List <StructSearchMatch> ssmList; string serializedResult = ""; if (queryCid == null || queryCid == "") { return(null); } if (ServiceFacade.UseRemoteServices) { Mobius.Services.Native.INativeSession nativeClient = ServiceFacade.CreateNativeSessionProxy(); Services.Native.NativeMethodTransportObject resultObject = ServiceFacade.InvokeNativeMethod(nativeClient, (int)Services.Native.ServiceCodes.MobiusCompoundUtilService, (int)Services.Native.ServiceOpCodes.MobiusCompoundUtilService.GetRelatedStructures, new Services.Native.NativeMethodTransportObject(new object[] { queryCid, mtName })); ((System.ServiceModel.IClientChannel)nativeClient).Close(); serializedResult = (resultObject != null) ? (string)resultObject.Value : null; } else { serializedResult = QEL.MoleculeUtil.GetRelatedMatchRowsSerialized(queryCid, mtName); } if (Lex.IsUndefined(serializedResult)) { return(new List <StructSearchMatch>()); } try { ssmList = new List <StructSearchMatch>(); string[] sa = serializedResult.Split('\n'); foreach (string s in sa) { if (Lex.IsUndefined(s)) { continue; } StructSearchMatch ssm = StructSearchMatch.Deserialize(s); ssmList.Add(ssm); } return(ssmList); } catch (Exception ex) { string msg = DebugLog.FormatExceptionMessage(ex); ServicesLogFile.Message(msg, CommonConfigInfo.ServicesLogFileName); // try to log on server return(new List <StructSearchMatch>()); // return empty result } }