public static ProcessingStatus GetMovieProcessingStatus(Movie movie, ProcessingOptionsMovieCTF optionsCTF, ProcessingOptionsMovieMovement optionsMovement, ProcessingOptionsBoxNet optionsBoxNet, ProcessingOptionsMovieExport optionsExport, Warp.Options options, bool considerFilter = true) { bool DoCTF = options.ProcessCTF; bool DoMovement = options.ProcessMovement; bool DoBoxNet = options.ProcessPicking; bool DoExport = optionsExport.DoAverage || optionsExport.DoStack || optionsExport.DoDeconv; ProcessingStatus Status = ProcessingStatus.Processed; if (movie.UnselectManual != null && (bool)movie.UnselectManual) { Status = ProcessingStatus.LeaveOut; } else if (movie.OptionsCTF == null && movie.OptionsMovement == null && movie.OptionsMovieExport == null) { Status = ProcessingStatus.Unprocessed; } else { if (DoCTF && (movie.OptionsCTF == null || movie.OptionsCTF != optionsCTF)) { Status = ProcessingStatus.Outdated; } else if (DoMovement && (movie.OptionsMovement == null || movie.OptionsMovement != optionsMovement)) { Status = ProcessingStatus.Outdated; } else if (DoBoxNet && (movie.OptionsBoxNet == null || movie.OptionsBoxNet != optionsBoxNet)) { Status = ProcessingStatus.Outdated; } else if (DoExport && (movie.OptionsMovieExport == null || movie.OptionsMovieExport != optionsExport)) { Status = ProcessingStatus.Outdated; } } if (Status == ProcessingStatus.Processed && movie.UnselectFilter && movie.UnselectManual == null && considerFilter) { Status = ProcessingStatus.FilteredOut; } return(Status); }
private async void ButtonAddLocal_OnClick(object sender, RoutedEventArgs e) { System.Windows.Forms.OpenFileDialog OpenDialog = new System.Windows.Forms.OpenFileDialog(); OpenDialog.Filter = "Warp Folder Settings|*.settings|Warp Data Source|*.source"; System.Windows.Forms.DialogResult OpenResult = OpenDialog.ShowDialog(); if (OpenResult.ToString() == "OK") { FileInfo Info = new FileInfo(OpenDialog.FileName); #region Check if user wants to use an existing source file instead //if (Info.Extension.ToLower() == ".settings" && // File.Exists(OpenDialog.FileName.Substring(0, OpenDialog.FileName.LastIndexOf(".")) + ".source")) //{ // var Result = await ((MainWindow)Application.Current.MainWindow).ShowMessageAsync("Similar source file found", // $"Would you like to use {Helper.PathToName(Info.Name) + ".source"} instead?", // MessageDialogStyle.AffirmativeAndNegativeAndSingleAuxiliary, // new MetroDialogSettings // { // AffirmativeButtonText = "Use existing source", // NegativeButtonText = "Replace with new source from settings", // FirstAuxiliaryButtonText = "Cancel" // }); // if (Result == MessageDialogResult.FirstAuxiliary) // Cancel // { // return; // } // else if (Result == MessageDialogResult.Affirmative) // Use existing .source // { // OpenDialog.FileName = OpenDialog.FileName.Substring(0, OpenDialog.FileName.LastIndexOf(".")) + ".source"; // Info = new FileInfo(OpenDialog.FileName); // } //} #endregion if (Info.Extension.ToLower() == ".settings") { #region Load preprocessing options Warp.Options Options = new Warp.Options(); try { Options.Load(OpenDialog.FileName); } catch { await((MainWindow)Application.Current.MainWindow).ShowMessageAsync("Oopsie", $"An error was encountered when reading {Info.Name}.", MessageDialogStyle.Affirmative); return; } #endregion #region Load items with metadata string FileExtension = Options.Import.Extension; var AvailableFiles = Directory.EnumerateFiles(Info.DirectoryName, FileExtension).ToArray(); Movie[] Items = new Movie[AvailableFiles.Length]; string[] MatchingStarNames = null; if (FileExtension != "*.tomostar" && AvailableFiles.Length > 0) { Movie First = new Movie(AvailableFiles[0]); MatchingStarNames = Directory.EnumerateFiles(First.MatchingDir, "*.star").ToArray(); } { var ProgressDialog = await((MainWindow)Application.Current.MainWindow).ShowProgressAsync("Loading metadata...", ""); ProgressDialog.Maximum = AvailableFiles.Count(); await Task.Run(() => { int Done = 0; Parallel.For(0, AvailableFiles.Length, i => { string file = AvailableFiles[i]; string XmlPath = file.Substring(0, file.LastIndexOf(".")) + ".xml"; if (File.Exists(XmlPath)) { Items[i] = (FileExtension == "*.tomostar" ? new TiltSeries(file) : new Movie(file, MatchingStarNames)); } lock (Items) ProgressDialog.SetProgress(++Done); }); }); await ProgressDialog.CloseAsync(); } if (Items.Length == 0) { await((MainWindow)Application.Current.MainWindow).ShowMessageAsync("Oopsie", $"No micrographs or tilt series found to match these settings.", MessageDialogStyle.Affirmative); return; } #endregion #region Figure out filtering status #region Astigmatism statistics Movie[] ItemsWithCTF = Items.Where(v => v.OptionsCTF != null && v.CTF != null).ToArray(); List <float2> AstigmatismPoints = new List <float2>(ItemsWithCTF.Length); foreach (var item in ItemsWithCTF) { AstigmatismPoints.Add(new float2((float)Math.Cos((float)item.CTF.DefocusAngle * 2 * Helper.ToRad) * (float)item.CTF.DefocusDelta, (float)Math.Sin((float)item.CTF.DefocusAngle * 2 * Helper.ToRad) * (float)item.CTF.DefocusDelta)); } float2 AstigmatismMean = new float2(); float AstigmatismStd = 0.1f; if (AstigmatismPoints.Count > 0) { AstigmatismMean = new float2(); foreach (var point in AstigmatismPoints) { AstigmatismMean += point; } AstigmatismMean /= AstigmatismPoints.Count; AstigmatismStd = 0; foreach (var point in AstigmatismPoints) { AstigmatismStd += (point - AstigmatismMean).LengthSq(); } AstigmatismStd = (float)Math.Max(1e-4, Math.Sqrt(AstigmatismStd / AstigmatismPoints.Count)); } #endregion int[] ParticleCounts = Items.Select(item => item.GetParticleCount(Options.Filter.ParticlesSuffix)).ToArray(); bool HaveParticles = ParticleCounts.Any(v => v > 0); foreach (var item in Items) { bool FilterStatus = true; if (item.OptionsCTF != null) { FilterStatus &= item.CTF.Defocus >= Options.Filter.DefocusMin && item.CTF.Defocus <= Options.Filter.DefocusMax; float AstigmatismDeviation = (new float2((float)Math.Cos((float)item.CTF.DefocusAngle * 2 * Helper.ToRad) * (float)item.CTF.DefocusDelta, (float)Math.Sin((float)item.CTF.DefocusAngle * 2 * Helper.ToRad) * (float)item.CTF.DefocusDelta) - AstigmatismMean).Length() / AstigmatismStd; FilterStatus &= AstigmatismDeviation <= (float)Options.Filter.AstigmatismMax; FilterStatus &= item.CTFResolutionEstimate <= Options.Filter.ResolutionMax; FilterStatus &= item.CTF.PhaseShift >= Options.Filter.PhaseMin && item.CTF.PhaseShift <= Options.Filter.PhaseMax; FilterStatus &= item.GetParticleCount(Options.Filter.ParticlesSuffix) >= Options.Filter.ParticlesMin; } if (item.OptionsMovement != null) { FilterStatus &= item.MeanFrameMovement <= Options.Filter.MotionMax; } item.UnselectFilter = !FilterStatus; } ProcessingOptionsMovieCTF OptionsCTF = Options.GetProcessingMovieCTF(); ProcessingOptionsMovieMovement OptionsMovement = Options.GetProcessingMovieMovement(); ProcessingOptionsBoxNet OptionsBoxNet = Options.GetProcessingBoxNet(); ProcessingOptionsMovieExport OptionsExport = Options.GetProcessingMovieExport(); List <Movie> ItemsProcessed = new List <Movie>(); List <Movie> ItemsFilteredOut = new List <Movie>(); List <Movie> ItemsUnselected = new List <Movie>(); foreach (Movie item in Items) { ProcessingStatus Status = GetMovieProcessingStatus(item, OptionsCTF, OptionsMovement, OptionsBoxNet, OptionsExport, Options); if (Status == ProcessingStatus.Processed || (Status == ProcessingStatus.Outdated && !item.UnselectFilter)) { ItemsProcessed.Add(item); } else if (Status == ProcessingStatus.FilteredOut || (Status == ProcessingStatus.Outdated && item.UnselectFilter)) { ItemsFilteredOut.Add(item); } else if (Status == ProcessingStatus.LeaveOut) { ItemsUnselected.Add(item); } } #endregion #region Figure out how many frames/tilts there are to use int UsableFrames = 1; if (Items[0].GetType() == typeof(Movie)) { UsableFrames = MapHeader.ReadFromFile(Items[0].Path).Dimensions.Z; } else { UsableFrames = ((TiltSeries)Items[0]).NTilts; } #endregion #region Show dialog CustomDialog Dialog = new CustomDialog(); Dialog.HorizontalContentAlignment = HorizontalAlignment.Center; DialogCreateSourceFromSettings DialogContent = new DialogCreateSourceFromSettings(); DialogContent.TextTitle.Text = $"Create data source from\n{Info.Name}"; DialogContent.StatsSeriesStatusProcessed.Values = new ChartValues <ObservableValue> { new ObservableValue(ItemsProcessed.Count) }; DialogContent.StatsSeriesStatusUnfiltered.Values = new ChartValues <ObservableValue> { new ObservableValue(ItemsFilteredOut.Count) }; DialogContent.StatsSeriesStatusUnselected.Values = new ChartValues <ObservableValue> { new ObservableValue(ItemsUnselected.Count) }; DialogContent.SliderFrames.Value = UsableFrames; DialogContent.SliderFrames.MaxValue = UsableFrames; DialogContent.Close += () => { ((MainWindow)Application.Current.MainWindow).HideMetroDialogAsync(Dialog); }; DialogContent.Create += async() => { #region Create source metadata and check if one with the same path already exists DataSource NewSource = new DataSource { PixelSizeX = Options.PixelSizeX, PixelSizeY = Options.PixelSizeY, PixelSizeAngle = Options.PixelSizeAngle, DimensionsX = Options.Tomo.DimensionsX, DimensionsY = Options.Tomo.DimensionsY, DimensionsZ = Options.Tomo.DimensionsZ, FrameLimit = (int)DialogContent.SliderFrames.Value, GainPath = Options.Import.CorrectGain ? Options.Import.GainPath : "", GainFlipX = Options.Import.GainFlipX, GainFlipY = Options.Import.GainFlipY, GainTranspose = Options.Import.GainTranspose, DosePerAngstromFrame = Options.Import.DosePerAngstromFrame, Name = DialogContent.TextSourceName.Text, Path = Info.DirectoryName + "\\" + Helper.RemoveInvalidChars(DialogContent.TextSourceName.Text) + ".source" }; if (Population.Sources.Any(s => s.Path == NewSource.Path)) { await((MainWindow)Application.Current.MainWindow).ShowMessageAsync("Oopsie", $"{Helper.PathToNameWithExtension(NewSource.Path)} already exists in this population. Please choose a different name.", MessageDialogStyle.Affirmative); return; } await((MainWindow)Application.Current.MainWindow).HideMetroDialogAsync(Dialog); #endregion #region Add all items and their data hashes List <Movie> AllItems = new List <Movie>(ItemsProcessed); if ((bool)DialogContent.CheckFilter.IsChecked) { AllItems.AddRange(ItemsFilteredOut); } if ((bool)DialogContent.CheckManual.IsChecked) { AllItems.AddRange(ItemsUnselected); } if (AllItems.Count == 0) { await((MainWindow)Application.Current.MainWindow).ShowMessageAsync("Oopsie", $"No micrographs or tilt series found to match these settings.", MessageDialogStyle.Affirmative); return; } { var ProgressDialog = await((MainWindow)Application.Current.MainWindow).ShowProgressAsync("Calculating data hashes...", ""); ProgressDialog.Maximum = AllItems.Count; await Task.Run(() => { int Done = 0; foreach (var item in AllItems) { NewSource.Files.Add(item.GetDataHash(), item.Name); ProgressDialog.SetProgress(++Done); } }); await ProgressDialog.CloseAsync(); } #endregion #region Check for overlapping hashes string[] Overlapping = Helper.Combine(Population.Sources.Select(s => s.Files.Where(f => NewSource.Files.ContainsKey(f.Key)).Select(f => f.Value).ToArray())); if (Overlapping.Length > 0) { string Offenders = ""; for (int o = 0; o < Math.Min(5, Overlapping.Length); o++) { Offenders += "\n" + Overlapping[o]; } if (Overlapping.Length > 5) { Offenders += $"\n... and {Overlapping.Length - 5} more."; } await((MainWindow)Application.Current.MainWindow).ShowMessageAsync("Oopsie", "The new source contains files that are already used in this population:" + Offenders, MessageDialogStyle.Affirmative); return; } #endregion { var ProgressDialog = await((MainWindow)Application.Current.MainWindow).ShowProgressAsync("Committing initial version...", ""); ProgressDialog.Maximum = AllItems.Count; await Task.Run(() => { NewSource.Commit(); }); await ProgressDialog.CloseAsync(); } Population.Sources.Add(NewSource); UpdateGridItems(); }; Dialog.Content = DialogContent; await((MainWindow)Application.Current.MainWindow).ShowMetroDialogAsync(Dialog, new MetroDialogSettings() { }); #endregion } else { try { if (Population.Sources.Any(s => s.Path == OpenDialog.FileName)) { await((MainWindow)Application.Current.MainWindow).ShowMessageAsync("Oopsie", "This data source is already part of this population.", MessageDialogStyle.Affirmative); return; } DataSource NewSource = DataSource.FromFile(OpenDialog.FileName); Population.Sources.Add(NewSource); UpdateGridItems(); } catch { await((MainWindow)Application.Current.MainWindow).ShowMessageAsync("Oopsie", $"An error was encountered when reading {Info.Name}.", MessageDialogStyle.Affirmative); return; } } } }