X-Git-Url: http://git.euphorik.ch/?a=blobdiff_plain;f=Parasitemia%2FParasitemiaUI%2FAnalysis.fs;h=2ff0b1e31c1612430a6e7d2485639c3f1208ef9b;hb=85adb74195fe7145535d3d36263aec2f7879cd60;hp=24f9adbcaa743661dbebb0243cb2f5f80f1c13b0;hpb=3990946e49fe34e9adcf0e04b0418cd16676e6fe;p=master-thesis.git diff --git a/Parasitemia/ParasitemiaUI/Analysis.fs b/Parasitemia/ParasitemiaUI/Analysis.fs index 24f9adb..2ff0b1e 100644 --- a/Parasitemia/ParasitemiaUI/Analysis.fs +++ b/Parasitemia/ParasitemiaUI/Analysis.fs @@ -19,38 +19,27 @@ open ParasitemiaCore.Config open Types let showWindow (parent: Window) (state: State.State) : bool = - let window = Views.AnalysisWindow() - window.Root.Owner <- parent - window.Root.Left <- parent.Left + parent.ActualWidth / 2. - window.Root.Width / 2. - window.Root.Top <- parent.Top + parent.ActualHeight / 2. - window.Root.Height / 2. - - let ctrl (name: string): 'a = window.Root.FindName(name) :?> 'a - - let butClose: Button = ctrl "butClose" - let butStart: Button = ctrl "butStart" - - let stackSourceImagesSelection: StackPanel = ctrl "stackSourceImagesSelection" - let progressBar: ProgressBar = ctrl "progress" - let textLog: TextBlock = ctrl "textLog" - let scrollLog: ScrollViewer = ctrl "scrollLog" + let win = Views.AnalysisWindow() + win.Root.Owner <- parent + win.Root.Left <- parent.Left + parent.ActualWidth / 2. - win.Root.Width / 2. + win.Root.Top <- parent.Top + parent.ActualHeight / 2. - win.Root.Height / 2. let logListener = { new Logger.IListener with member this.NewEntry severity mess = - window.Root.Dispatcher.Invoke(fun () -> - textLog.Inlines.Add(Documents.Run(mess)) - textLog.Inlines.Add(Documents.LineBreak()) - scrollLog.ScrollToBottom()) } + win.Root.Dispatcher.Invoke(fun () -> + win.textLog.Inlines.Add(Documents.Run(mess)) + win.textLog.Inlines.Add(Documents.LineBreak()) + win.scrollLog.ScrollToBottom()) } Logger.Log.AddListener(logListener) let minPPI = 1. let maxPPI = 10e6 let parseAndValidatePPI (input: string) : float option = - let res = ref 0. - if Double.TryParse(input, res) && !res >= minPPI && !res <= maxPPI - then Some !res - else None + match Double.TryParse(input) with + | true, value when value >= minPPI && value <= maxPPI -> Some value + | _ -> None let monitor = Object() let mutable atLeastOneAnalysisPerformed = false @@ -58,8 +47,8 @@ let showWindow (parent: Window) (state: State.State) : bool = let mutable analysisCancelled = false let updateSourceImages () = - stackSourceImagesSelection.Children.Clear() - let width = int stackSourceImagesSelection.ActualWidth + win.stackSourceImagesSelection.Children.Clear() + let width = int win.stackSourceImagesSelection.ActualWidth for srcImg in state.SourceImages do let imageSourceSelection = Views.ImageSourceSelection(Tag = srcImg, Margin = Thickness(3.)) imageSourceSelection.Tag <- srcImg @@ -74,6 +63,11 @@ let showWindow (parent: Window) (state: State.State) : bool = imageSourceSelection.menuZoom50X.Click.AddHandler(fun obj args -> imageSourceSelection.txtResolution.Text <- "230000") imageSourceSelection.menuZoom100X.Click.AddHandler(fun obj args -> imageSourceSelection.txtResolution.Text <- "460000") + imageSourceSelection.butPPICalculator.Click.AddHandler(fun obj args -> + match PPICalculator.showWindow win.Root with + | Some resolution -> imageSourceSelection.txtResolution.Text <- resolution.ToString() + | None -> ()) + imageSourceSelection.txtResolution.PreviewTextInput.AddHandler(fun obj args -> let text = imageSourceSelection.txtResolution.Text + args.Text args.Handled <- match parseAndValidatePPI text with Some _ -> false | None -> true) @@ -82,12 +76,12 @@ let showWindow (parent: Window) (state: State.State) : bool = let checkbox = imageSourceSelection.chkSelection checkbox.IsChecked <- Nullable(not (checkbox.IsChecked.HasValue && checkbox.IsChecked.Value))) - stackSourceImagesSelection.Children.Add(imageSourceSelection) |> ignore + win.stackSourceImagesSelection.Children.Add(imageSourceSelection) |> ignore // Get the new parameters for each image. If an error occurs then 'None' is returned and a message box is displayed. // The boolean is 'true' if the image is selected (checked). let getInputImagesParameters () : (SourceImage * bool * Parameters) list option = - let sourceImagesControls = stackSourceImagesSelection.Children |> Seq.cast + let sourceImagesControls = win.stackSourceImagesSelection.Children |> Seq.cast let parameters = seq { for srcImgCtrl in sourceImagesControls do let srcImg = srcImgCtrl.Tag :?> SourceImage @@ -102,9 +96,9 @@ let showWindow (parent: Window) (state: State.State) : bool = then None else Some parameters - butClose.Click.AddHandler(fun obj args -> window.Root.Close()) + win.butClose.Click.AddHandler(fun obj args -> win.Root.Close()) - butStart.Click.AddHandler(fun obj args -> + win.butStart.Click.AddHandler(fun obj args -> match getInputImagesParameters () with | Some imagesParameters -> let imagesToProcess = [ @@ -117,41 +111,47 @@ let showWindow (parent: Window) (state: State.State) : bool = then MessageBox.Show("No image selected", "Cannot start analysis", MessageBoxButton.OK, MessageBoxImage.Information) |> ignore else + win.stackSourceImagesSelection.IsEnabled <- false analysisPerformed <- false - butStart.IsEnabled <- false - butClose.Content <- "Abort" + win.butStart.IsEnabled <- false + win.butClose.Content <- "Abort" + async { - let results = + let maybeResults = ParasitemiaCore.Analysis.doMultipleAnalysis imagesToProcess - (Some (fun progress -> window.Root.Dispatcher.Invoke(fun () -> progressBar.Value <- float progress))) + (Some (fun progress -> win.Root.Dispatcher.Invoke(fun () -> win.progress.Value <- float progress); not analysisCancelled)) lock monitor ( fun() -> - if not analysisCancelled - then + match maybeResults with + | Some results -> for id, cells in results do state.SetResult (int id) cells - - window.Root.Dispatcher.Invoke(fun () -> - butStart.IsEnabled <- true - butClose.Content <- "Close" - updateSourceImages ()) - Logger.Log.User("All analyses terminated successfully") atLeastOneAnalysisPerformed <- true - analysisPerformed <- true) + analysisPerformed <- true + | None -> + Logger.Log.User("Analysis aborted") + + win.Root.Dispatcher.Invoke(fun () -> + win.progress.Value <- if maybeResults.IsSome then 100. else 0. + win.stackSourceImagesSelection.IsEnabled <- true + win.butStart.IsEnabled <- true + win.butClose.Content <- "Close" + updateSourceImages ())) } |> Async.Start | _ -> ()) - window.Root.Loaded.AddHandler(fun obj args -> updateSourceImages ()) + win.Root.Loaded.AddHandler(fun obj args -> updateSourceImages ()) - window.Root.ShowDialog() |> ignore + win.Root.ShowDialog() |> ignore Logger.Log.RmListener(logListener) lock monitor (fun () -> if not analysisPerformed then + // To cancel the current analysis if one is running on the next call to the progress function. analysisCancelled <- true atLeastOneAnalysisPerformed)