/*public void UpdateProgress (object sender, IterationEventArgs e) { if (ProgressUpdate == null) return; int iteration = e.IterationIndex + 1; if (iteration == 1) stopwatch = System.Diagnostics.Stopwatch.StartNew(); var progressUpdate = new ProgressUpdateEventArgs(); if (e.IterationCount > 0) { progressUpdate.Total = 1000; progressUpdate.Current = e.IterationCount == 0 ? 0 : Math.Min(progressUpdate.Total, (int) Math.Round((double) iteration / e.IterationCount * 1000.0)); double progressRate = stopwatch.Elapsed.TotalSeconds > 0 ? iteration / stopwatch.Elapsed.TotalSeconds : 0; long iterationsRemaining = e.IterationCount - iteration; TimeSpan timeRemaining = progressRate == 0 ? TimeSpan.Zero : TimeSpan.FromSeconds(iterationsRemaining / progressRate); progressUpdate.Message = String.Format("{0} ({1}/{2}) - {3} per second, {4}h{5}m{6}s remaining", e.Message, iteration, e.IterationCount, (long) progressRate, timeRemaining.Hours, timeRemaining.Minutes, timeRemaining.Seconds); } else { progressUpdate.Total = 0; progressUpdate.Current = iteration; progressUpdate.Message = String.Format("{0} ({1})", e.Message, iteration); } ProgressUpdate(this, progressUpdate); e.Cancel = progressUpdate.Cancel; }*/ public void UpdateProgress (object sender, MergerWrapper.MergingProgressEventArgs e) { if (e.MergingException != null) Program.HandleException(e.MergingException); if (ProgressUpdate == null) return; if (e.MergedFiles == 0) stopwatch = Stopwatch.StartNew(); var progressUpdate = new ProgressUpdateEventArgs(); progressUpdate.Total = e.TotalFiles; progressUpdate.Current = e.MergedFiles; double progressRate = stopwatch.Elapsed.TotalSeconds > 0 ? e.MergedFiles / stopwatch.Elapsed.TotalSeconds : 0; long bytesRemaining = e.TotalFiles - e.MergedFiles; TimeSpan timeRemaining = progressRate == 0 ? TimeSpan.Zero : TimeSpan.FromSeconds(bytesRemaining / progressRate); progressUpdate.Message = String.Format("Merging results... ({0}/{1}) - {2} per second, {3}h{4}m{5}s remaining", e.MergedFiles, e.TotalFiles, Math.Round(progressRate, 1), timeRemaining.Hours, timeRemaining.Minutes, timeRemaining.Seconds); ProgressUpdate(this, progressUpdate); e.Cancel = progressUpdate.Cancel; }
void OpenFiles (IList<string> filepaths, TreeNode rootNode = null) { try { var xml_filepaths = filepaths.Where(filepath => !filepath.EndsWith(".idpDB")); var idpDB_filepaths = filepaths.Where(filepath => filepath.EndsWith(".idpDB")); bool openSingleFile = xml_filepaths.Count() + idpDB_filepaths.Count() == 1; if (xml_filepaths.Count() + idpDB_filepaths.Count() == 0) { if (Program.IsHeadless) { Console.Error.WriteLine("Headless mode must be passed some idpDB files to merge."); Close(); return; } else throw new Exception("no filepaths to open"); } if (Program.IsHeadless && xml_filepaths.Any()) Program.HandleUserError(new Exception("headless mode only supports merging and filtering idpDB files")); // warn if idpDBs already exist bool warnOnce = false, skipReconvert = false; var skipFiles = new List<string>(); foreach (string filepath in xml_filepaths) { string idpDB_filepath = Path.ChangeExtension(filepath.Replace(".pep.xml", ".pepXML"), ".idpDB"); if (File.Exists(idpDB_filepath)) { if (!warnOnce && MessageBox.Show("Some of these files have already been converted. Do you want to reconvert them?", "Result already converted", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button2) != DialogResult.Yes) skipReconvert = true; warnOnce = true; if (skipReconvert) skipFiles.Add(filepath); else File.Delete(idpDB_filepath); } } xml_filepaths = xml_filepaths.Where(o => !skipFiles.Contains(o)); idpDB_filepaths = idpDB_filepaths.Union(skipFiles.Select(o => Path.ChangeExtension(o.Replace(".pep.xml", ".pepXML"), ".idpDB"))); // determine if merged filepath exists and that it's a valid idpDB var potentialPaths = filepaths.Select(item => Path.Combine(Path.GetDirectoryName(item) ?? string.Empty, Path.GetFileNameWithoutExtension(item) ?? string.Empty) + ".idpDB").ToList(); // for Mascot files (*.dat), use parseSource() to get the real filename, else save time by just using filename without extension var sourceNames = filepaths.Select(o => Path.Combine(Path.GetDirectoryName(o), o.ToLower().EndsWith(".dat") ? Parser.ParseSource(o) : Path.GetFileNameWithoutExtension(o.Replace(".pep.xml", ".pepXML")) + Path.GetExtension(o))); string commonFilepath = Util.GetCommonFilename(sourceNames); if (!openSingleFile && potentialPaths.Contains(commonFilepath)) commonFilepath = commonFilepath.Replace(".idpDB", " (merged).idpDB"); string mergeTargetFilepath = defaultMergedOutputFilepath ?? commonFilepath; if (!openSingleFile && File.Exists(mergeTargetFilepath) && Program.IsHeadless) File.Delete(mergeTargetFilepath); else { // check that the single idpDB is writable; if not, it needs to be copied if (openSingleFile) { // sanity check that file exists after the path manipulation above if (idpDB_filepaths.Count() == 1 && !File.Exists(mergeTargetFilepath)) throw new Exception(String.Format("error in internal path manipulation for opening single idpDB: {0} transformed to {1} which does not exist", sourceNames.First(), mergeTargetFilepath)); string oldFilename = mergeTargetFilepath; while (true) { if (canReadWriteInDirectory(Path.GetDirectoryName(mergeTargetFilepath))) break; MessageBox.Show("IDPicker files cannot be opened from a read-only location, pick a writable path to copy it to."); if (!saveFileDialog(ref mergeTargetFilepath)) return; } // if location was changed, copy to the new location if (oldFilename != mergeTargetFilepath) { toolStripStatusLabel.Text = "Copying idpDB..."; File.Copy(oldFilename, mergeTargetFilepath, true); } } else { // if not headless and MergedOutputFilepath is unset, // then give the user a chance to override the merge target location if (!Program.IsHeadless && defaultMergedOutputFilepath == null && !saveFileDialog(ref mergeTargetFilepath, "Choose where to create the merged idpDB")) return; while (true) { if (!canReadWriteInDirectory(Path.GetDirectoryName(mergeTargetFilepath))) { MessageBox.Show("IDPicker files cannot be merged to a read-only location, pick a writable path."); if (Program.IsHeadless || !saveFileDialog(ref mergeTargetFilepath, "Pick a writable path in which to create the merged idpDB")) return; continue; } // the SaveFileDialog already asked the user to confirm overwriting an existing file if (File.Exists(mergeTargetFilepath)) File.Delete(mergeTargetFilepath); break; } } } // set main window title BeginInvoke(new MethodInvoker(() => Text = mergeTargetFilepath)); //set up delayed messages so non-fatal errors that occur at the end arent lost var delayedMessages = new List<string[]>(); if (xml_filepaths.Count() > 0) { importCancelled = false; // loop until the import settings don't result in any fatal errors, or user cancels while (!importCancelled) { Parser parser = new Parser(); Invoke(new MethodInvoker(() => parser.ImportSettings += importSettingsHandler)); var ilr = new IterationListenerRegistry(); var progressForm = new ProgressForm(xml_filepaths, ilr) { Text = "Import Progress", StartPosition = FormStartPosition.CenterParent, }; Invoke(new MethodInvoker(() => progressForm.Show(this))); try { parser.Parse(xml_filepaths, ilr); // read log for non-fatal errors //string log = Logger.Reader.ReadToEnd().Trim(); //if (log.Length > 0) // Invoke(new MethodInvoker(() => UserDialog.Show(this, "Log Messages", new TextBox {Multiline = true, Text = log.Replace("\n", "\r\n"), ReadOnly = true, Size = new Size(800, 600), ScrollBars = ScrollBars.Both}, MessageBoxButtons.OK))); break; // no fatal errors, break the loop } catch (Exception ex) { if (ex.Message.Contains("no peptides found mapping to a decoy protein") || ex.Message.Contains("peptides did not map to the database") || ex.Message.Contains("duplicate protein id")) Program.HandleUserError(ex); else throw; } finally { importCancelled |= progressForm.Cancelled; Invoke(new MethodInvoker(() => progressForm.Close())); } } if (importCancelled) return; idpDB_filepaths = idpDB_filepaths.Union(xml_filepaths.Select(o => Path.ChangeExtension(o.Replace(".pep.xml", ".pepXML"), ".idpDB"))); } if (idpDB_filepaths.Count() > 1) { var merger = new MergerWrapper(mergeTargetFilepath, idpDB_filepaths); toolStripStatusLabel.Text = "Merging results..."; merger.MergingProgress += progressMonitor.UpdateProgress; merger.Start(); idpDB_filepaths = new List<string>() {mergeTargetFilepath}; } // HACK: this needs to be handled more gracefully if (!IsHandleCreated) return; if (Properties.GUI.Settings.Default.WarnAboutNonFixedDrive && !Util.IsPathOnFixedDrive(mergeTargetFilepath)) { string oldFilename = mergeTargetFilepath; bool copyLocal = true; Invoke(new MethodInvoker(() => { var form = new NonFixedDriveWarningForm(); if (form.ShowDialog(this) == DialogResult.Ignore) copyLocal = false; })); if (copyLocal) { string newFilename = Path.GetFileName(mergeTargetFilepath); if (!saveFileDialog(ref newFilename, "Pick a local path to copy the idpDB to")) return; toolStripStatusLabel.Text = "Copying idpDB..."; File.Copy(oldFilename, newFilename, true); mergeTargetFilepath = newFilename; // set main window title BeginInvoke(new MethodInvoker(() => Text = mergeTargetFilepath)); } } if (!IsHandleCreated) return; Util.PrecacheFile(mergeTargetFilepath, progressMonitor.UpdateProgress); if (!IsHandleCreated) return; BeginInvoke(new MethodInvoker(() => { clearProgress(); toolStripStatusLabel.Text = "Upgrading schema and creating session factory..."; statusStrip.Refresh(); })); var sessionFactory = DataModel.SessionFactoryFactory.CreateSessionFactory(mergeTargetFilepath, new SessionFactoryConfig { WriteSqlToConsoleOut = true }); if (logForm != null) logForm.SetSessionFactory(sessionFactory); BeginInvoke(new MethodInvoker(() => { // reload qonverter settings because the ids may change after merging toolStripStatusLabel.Text = "Loading qonverter settings..."; statusStrip.Refresh(); session = sessionFactory.OpenSession(); session.DefaultReadOnly = true; session.CreateSQLQuery("PRAGMA temp_store=MEMORY; PRAGMA mmap_size=70368744177664; -- 2^46").ExecuteUpdate(); toolStripStatusLabel.Text = "Refreshing group structure..."; statusStrip.Refresh(); var usedGroups = GroupingControlForm.SetInitialStructure(rootNode, session, defaultApplySourceGroupHierarchy); if (usedGroups != null && usedGroups.Any()) { var allGroupsByName = session.Query<SpectrumSourceGroup>().ToDictionary(o => o.Name); var usedGroupsByName = usedGroups.ToDictionary(o => o.Name); // if usedGroupsByName does not contain a key from allGroupsByName, delete the group foreach (var unusedGroup in allGroupsByName.Where(o => !usedGroupsByName.ContainsKey(o.Key))) session.Delete(unusedGroup); } session.Flush(); // check for embedded gene metadata; // if it isn't there, ask the user if they want to embed it; // if not, disable gene-related features if (!Program.IsHeadless && !Embedder.HasGeneMetadata(mergeTargetFilepath) && Properties.GUI.Settings.Default.WarnAboutNoGeneMetadata) { bool embedGeneMetadata = true; Invoke(new MethodInvoker(() => { var form = new EmbedGeneMetadataWarningForm(); if (form.ShowDialog(this) == DialogResult.Ignore) embedGeneMetadata = false; })); if (embedGeneMetadata) { loadRefSeqGeneMetadata(); // will call OpenFiles() after embedding, so return immediately return; } } else { // disable gene-related features } qonverterSettingsByAnalysis = session.Query<QonverterSettings>().ToDictionary(o => session.Get<Analysis>(o.Id)); _layoutManager.SetSession(session); //set or save default layout dockPanel.Visible = true; _layoutManager.CurrentLayout = _layoutManager.GetCurrentDefault(); //breadCrumbControl.BreadCrumbs.Clear(); // pick a default RoundToNearest based on number of distinct modifications decimal roundToNearest = 1m; var distinctModificationFormat = new DistinctMatchFormat(); var modMasses = session.CreateQuery("SELECT DISTINCT mod.MonoMassDelta FROM Modification mod").List<double>(); for (int i = 4; i > 0; --i) { distinctModificationFormat.ModificationMassRoundToNearest = (decimal) (1.0 / Math.Pow(10, i)); if (modMasses.Select(o => distinctModificationFormat.Round(o)).Distinct().Count() < 30) { roundToNearest = distinctModificationFormat.ModificationMassRoundToNearest.Value; break; } } modificationTableForm.RoundToNearest = roundToNearest; basicFilter = DataFilter.LoadFilter(session); // if user has overridden filters from the command-line, make sure to reapply the filter if (!defaultDataFilter.PersistentDataFilter.Equals(defaultDataFilter.OriginalPersistentDataFilter)) basicFilter = null; if (basicFilter == null) { basicFilter = new DataFilter(defaultDataFilter); basicFilterControl.DataFilter = basicFilter; viewFilter = basicFilter; ApplyBasicFilter(); } else { basicFilterControl.DataFilter = basicFilter; viewFilter = basicFilter; try { // check that the unfiltered tables exist session.CreateSQLQuery("SELECT COUNT(*) FROM UnfilteredProtein").UniqueResult(); setData(); } catch { ApplyBasicFilter(); } } if (TestUILayout) { int i = 0; foreach(var form in dockPanel.Contents) { ++i; form.DockingHandler.DockAreas = (form.DockingHandler.DockAreas | DockAreas.Float); var rect = dockPanel.ClientRectangle; rect.Offset(i * 15, i * 15); rect.Size = new System.Drawing.Size(960, 600); form.DockingHandler.Show(dockPanel, rect); } } toolStripStatusLabel.Text = "Ready"; Activate(); })); //show list of delayed non-fatal errors if (delayedMessages.Any()) { var sb = new StringBuilder(); foreach (var message in delayedMessages) sb.AppendLine(string.Format("{0}:{1}{2}{1}", message[0], Environment.NewLine, message[1])); var messageString = sb.ToString(); ShowExpandedMessageBox(messageString); } } catch (Exception ex) { Program.HandleException(ex); } }