private void DoBLAST(string filename) { // Update progress bar, set content of user control to initial state // Load protein sequences FastaParser parser = new FastaParser(); IList<ISequence> queryList = parser.Parse(filename).ToList(); // Initialize and populate queue of query sequences Queue<QueueSequence> queryQueue = new Queue<QueueSequence>(); int j = 0; // For debuging int progValue = 0; int currentProgress = 0; foreach (ISequence protein in queryList) { QueueSequence qp = new QueueSequence(); qp.Sequence = protein; qp.Position = j; string name = j.ToString(); j++; if (File.Exists(Up.ProjectDir + "\\xml\\" + name + ".xml")) { IList<BlastResult> blastResults; BlastXmlParser parser2 = new BlastXmlParser(); try { blastResults = parser2.Parse(Up.ProjectDir + "\\xml\\" + name + ".xml"); progValue = Convert.ToInt32(Math.Round((double)currentProgress / queryList.Count() * 100, 0)); UpdateProgressBar(progValue, "Validating BLAST results."); currentProgress++; } catch { queryQueue.Enqueue(qp); } } else { queryQueue.Enqueue(qp); } } // Initialize BLAST queue positions to having no jobs (EMPTY) BlastQueue blastQueue = new BlastQueue(); // While there are proteins left to submit to BLAST, or there are // busy jobs still on the queue UpdateProgressBar(progValue, "Starting up BLAST service, please wait."); while (queryQueue.Count > 0 || blastQueue.isBlastQueueBusy()) { // Iterate over blastQueue for (int i = 0; i < BlastQueue.Length; i++) { // Get blastJob from array and update status BlastJob blastJob = blastQueue[i]; QueueSequence qp = new QueueSequence(); qp.Sequence = blastJob.Query; qp.Position = blastJob.Position; // if queue position is AVAILABLE if (blastJob.JobStatus == BlastJob.AVAILABLE) { if (queryQueue.Count > 0) { QueueSequence qp2 = queryQueue.Dequeue(); // try to submit job, enqueue back the protein if submission failed. try { blastQueue[i] = submit(qp2); if (blastQueue[i].JobStatus == BlastJob.FAILED) { blastQueue[i].JobStatus = BlastJob.AVAILABLE; queryQueue.Enqueue(qp2); } else { UpdateProgressBar(progValue, "Submitting sequences to NCBI BLAST"); } } catch (Exception eee) { MessageBox.Show(eee.Message); } } } else { string jobId = blastJob.JobId; NCBIBlastHandler blastService = blastJob.BlastService; ServiceRequestInformation info = blastService.GetRequestStatus(jobId); Thread.Sleep(BlastQueue.RequestDelay); switch (info.Status) { case ServiceRequestStatus.Error: blastQueue[i].JobStatus = BlastJob.AVAILABLE; queryQueue.Enqueue(qp); break; case ServiceRequestStatus.Canceled: blastQueue[i].JobStatus = BlastJob.AVAILABLE; queryQueue.Enqueue(qp); break; case ServiceRequestStatus.Ready: string result = blastService.GetResult(jobId, blastJob.SearchParams); string name = blastJob.Position.ToString(); TextWriter tw = new StreamWriter(Up.ProjectDir + "\\xml\\" + name + ".xml"); tw.Write(result); tw.Close(); Debug.WriteLine("BLAST JOB: " + jobId + " , " + name + " , " + info.StatusInformation); // Added by VF on Jan, 22, 2013. Catches invalid BLAST records IList<BlastResult> blastResults; BlastXmlParser parser2 = new BlastXmlParser(); bool parsePassed = false; int fetchAttempts = 0; while (!parsePassed && fetchAttempts < 3) { try { blastResults = parser2.Parse(Up.ProjectDir + "\\xml\\" + name + ".xml"); parsePassed = true; Debug.WriteLine("FETCH OK JobId: " + jobId + " InputOrder: " + name + ". This is attempt:" + fetchAttempts.ToString()); } catch (Exception eee) { Debug.WriteLine("Trying to fetch JobId: " + jobId + " InputOrder: " + name + ". This is attempt: " + fetchAttempts.ToString()); parsePassed = false; result = blastService.GetResult(jobId, blastJob.SearchParams); TextWriter tw2 = new StreamWriter(Up.ProjectDir + "\\xml\\" + name + ".xml"); tw2.Write(result); tw2.Close(); fetchAttempts += 1; } Thread.Sleep(1000); } try { blastResults = parser2.Parse(Up.ProjectDir + "\\xml\\" + name + ".xml"); } catch (Exception eee) { blastQueue[i].JobStatus = BlastJob.AVAILABLE; queryQueue.Enqueue(qp); Debug.WriteLine("REQUEUE of JobId: " + " " + jobId + " InputOrder: " + name + " because max fetch is " + fetchAttempts.ToString()); break; } currentProgress += 1; progValue = Convert.ToInt32(Math.Round((double)currentProgress / queryList.Count() * 100, 0)); UpdateProgressBar(progValue, "Saving"); blastQueue[i].JobStatus = BlastJob.AVAILABLE; if (queryQueue.Count > 0) { QueueSequence qp3 = queryQueue.Dequeue(); try { blastQueue[i] = submit(qp3); if (blastQueue[i].JobStatus == BlastJob.FAILED) { blastQueue[i].JobStatus = BlastJob.AVAILABLE; queryQueue.Enqueue(qp3); } else { UpdateProgressBar(progValue, "Submitting sequences to NCBI BLAST"); } } catch (Exception eee) { MessageBox.Show(eee.Message); MessageBox.Show("Error creating a jobId for sequence " + qp3.Position); throw new Exception("Error creating a jobId for sequence" + qp3.Position); } } break; case ServiceRequestStatus.Queued: break; case ServiceRequestStatus.Waiting: break; default: MessageBox.Show("BLAST error " + info.Status + " " + blastJob.JobStatus + " for " + qp.Position); break; } } } } }
/// <summary> /// A helper method for the BLAST task. Submits a job to BLAST. /// </summary> /// <param name="qp"></param> /// <returns></returns> private BlastJob submit(QueueSequence qp) { // Configure BLAST service ConfigParameters configParams = new ConfigParameters(); configParams.UseBrowserProxy = Up.BlastUseBrowserProxy; BlastParameters searchParams = new BlastParameters(); string query = ">" + qp.Sequence.DisplayID + "\n" + qp.Sequence.ToString(); searchParams.Add("Program", Up.BlastProgram); searchParams.Add("Database", Up.BlastDatabase); searchParams.Add("GeneticCode", Up.BlastGeneticCode); searchParams.Add("Expect", "10"); searchParams.Add("Query", query); // Create BLAST service NCBIBlastHandler blastService = new NCBIBlastHandler(); blastService.Configuration = configParams; // Submit BLAST Job string jobId; try { jobId = blastService.SubmitRequest(qp.Sequence, searchParams); } catch(Exception eee) { if (eee.Message.Contains("WebException")) { ToggleProxy(); } BlastJob blastJob2 = new BlastJob(); blastJob2.JobStatus = BlastJob.FAILED; blastJob2.Query = qp.Sequence; blastJob2.Position = qp.Position; return blastJob2; } // Make sure job was submitted successfully ServiceRequestInformation info = blastService.GetRequestStatus(jobId); if (info.Status != ServiceRequestStatus.Waiting && info.Status != ServiceRequestStatus.Ready && info.Status != ServiceRequestStatus.Queued) { //Console.WriteLine("\tError Submitting Job: " + info.Status); BlastJob blastJob2 = new BlastJob(); blastJob2.JobStatus = BlastJob.FAILED; blastJob2.Query = qp.Sequence; blastJob2.Position = qp.Position; return blastJob2; } Thread.Sleep(BlastQueue.SubmitDelay); //Console.WriteLine("\tSuccessfully submitted jobId: " + jobId); // Return a BlastJob, set jobStatus to BUSY BlastJob blastJob = new BlastJob() { JobId = jobId, SearchParams = searchParams, ConfigParams = configParams, BlastService = blastService, JobStatus = BlastJob.BUSY, Query = qp.Sequence, Position = qp.Position }; return blastJob; }