/// <summary> /// Retrieve the IDs from the XML results from ELink /// </summary> /// <param name="xml">XML results from ELink</param> /// <param name="relatedRanks">Ouput - dictionary that maps PMIDs to map for looking up rank in related results</param> /// <returns>Dictionary that maps source PMIds to a list of IDs extracted from the XML (or an empty list of none)</returns> private static Dictionary <int, List <int> > GetIdsFromXml(string xml, out Dictionary <int, Dictionary <int, RankAndScore> > relatedRanks) { Dictionary <int, List <int> > result = new Dictionary <int, List <int> >(); relatedRanks = new Dictionary <int, Dictionary <int, RankAndScore> >(); List <int> ids = new List <int>(); XmlDocument xmlDoc = new XmlDocument(); xmlDoc.LoadXml(xml); XmlNodeList linkSets = xmlDoc["eLinkResult"].ChildNodes; foreach (XmlNode linkSet in linkSets) { // There's one <LinkSet> for each PMID from the search int pmid; if (int.TryParse(linkSet["IdList"]["Id"].InnerText, out pmid)) { Dictionary <int, RankAndScore> relatedRank = null; if (relatedRanks.ContainsKey(pmid)) { relatedRank = relatedRanks[pmid]; } else { relatedRank = new Dictionary <int, RankAndScore>(); relatedRanks.Add(pmid, relatedRank); } XmlNodeList linkSetDbs = linkSet.SelectNodes("LinkSetDb"); // Find the "pubmed_pubmed" link set foreach (XmlNode linkSetDb in linkSetDbs) { if (linkSetDb["LinkName"].InnerText == "pubmed_pubmed") { // We've found the link set of related PubMed publications. Add it to the results. List <int> linkList; if (result.ContainsKey(pmid)) { linkList = result[pmid] as List <int>; } else { linkList = new List <int>(); result[pmid] = linkList; } int rank = 0; foreach (XmlNode link in linkSetDb.SelectNodes("Link")) { int score; if (!int.TryParse(link["Score"].InnerText, out score)) { score = -1; } int relatedPmid; if (int.TryParse(link["Id"].InnerText, out relatedPmid)) { linkList.Add(relatedPmid); RankAndScore rankAndScore = new RankAndScore() { Rank = ++rank, Score = score }; relatedRank.Add(relatedPmid, rankAndScore); } } } } } } return(result); }
/// <summary> /// Go through all of the ranks and scores retrieved from the server for each PMID and write them to the output file and the database. /// </summary> /// <param name="db">Database to write to</param> /// <param name="relatedTableName">Name of the related table</param> /// <param name="relatedSearchResults">NCBI search results parsed into a dictionary that maps queried PMIDs to a list of related PMIDs</param> /// <param name="relatedRanks">Dictionary parsed from NCBI search results that maps each queried PMID to a dictionary of related PMIDs and their ranks and scores</param> /// <param name="outputFilename">Output file to append to</param> /// <param name="inputQueue">Input queue for marking success or error</param> /// <returns>True if a lines were successfully added to the file and table, false if an error occurred</returns> private bool WriteRelatedRanksToOutputFileAndDatabase(Database db, string relatedTableName, Dictionary <int, List <int> > relatedSearchResults, Dictionary <int, Dictionary <int, RankAndScore> > relatedRanks, string outputFilename, InputQueue inputQueue) { if (BackgroundWorker != null && BackgroundWorker.CancellationPending) { Trace.WriteLine(DateTime.Now + " - stopped"); return(false); } foreach (int pmid in relatedSearchResults.Keys) { List <int> relatedPmids = relatedSearchResults[pmid]; if (relatedPmids == null) { Trace.WriteLine($"{DateTime.Now} - found empty related PMID list for PMID {pmid} ({++_pmidsProcessed} of {inputQueue.TotalPmidsAdded})"); } else if (!relatedRanks.ContainsKey(pmid)) { Trace.WriteLine($"{DateTime.Now} - no ranks or scores found for PMID {pmid} ({++_pmidsProcessed} of {inputQueue.TotalPmidsAdded})"); } else { Trace.WriteLine($"{DateTime.Now} - found {relatedPmids.Count} results for PMID {pmid} ({++_pmidsProcessed} of {inputQueue.TotalPmidsAdded})"); Dictionary <int, RankAndScore> ranksAndScores = relatedRanks[pmid]; foreach (int relatedPmid in relatedPmids) { if (!ranksAndScores.ContainsKey(relatedPmid)) { Trace.WriteLine(DateTime.Now + " - unable to find related ranks and scores for PMID " + pmid + ", related PMID " + relatedPmid); } else { RankAndScore rankAndScore = ranksAndScores[relatedPmid]; string line = String.Format("{0},{1},{2},{3}", pmid, relatedPmid, rankAndScore.Rank, rankAndScore.Score); string output = line + Environment.NewLine; try { File.AppendAllText(outputFilename, output); } catch (Exception ex) { Trace.WriteLine(DateTime.Now + " - unable to append '" + line + "' to the output file: " + ex.Message); Trace.WriteLine(ex.StackTrace); Trace.WriteLine(DateTime.Now + " - stopping the run, use the Resume button to resume"); inputQueue.MarkError(pmid); return(false); } bool written = WriteRelatedRankToDatabase(db, relatedTableName, pmid, relatedPmid, rankAndScore.Rank, rankAndScore.Score); if (!written) { return(false); } } } } // Mark the PMID processed in the queue inputQueue.MarkProcessed(pmid); } return(true); }