Exemplo n.º 1
0
        /// <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);
        }
Exemplo n.º 2
0
        /// <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);
        }