module ParasitemiaUI.Utils open System.IO open Newtonsoft.Json open Types let inline listAsStr (s : 'a seq) = s |> Seq.fold (fun acc obj -> acc + (if acc = "" then "" else ", ") + string obj) "" let percentText (nbTotal : int, nb : int) : string = if nbTotal = 0 then "" else let percent = 100. * (float nb) / (float nbTotal) sprintf "%.1f %% (%d / %d)" percent nb nbTotal let predefinedPPIFilename = "predefined-ppi.json" let predefinedPPIFilepath = Path.Combine (Constants.USER_DIRECTORY, predefinedPPIFilename) let sensorSizesFilename = "sensor-sizes.json" let sensorSizesFilepath = Path.Combine (Constants.USER_DIRECTORY, sensorSizesFilename) let private savePredefinedPPIToFile (predefinedPPI : PredefinedPPI list) = try Directory.CreateDirectory Constants.USER_DIRECTORY |> ignore use file = new StreamWriter (predefinedPPIFilepath) file.Write (JsonConvert.SerializeObject (predefinedPPI, JsonSerializerSettings (Formatting = Formatting.Indented))) with ex -> Logger.Log.Error "Unable to save predefined PPI to file \"%s\": %O" predefinedPPIFilepath ex let private saveSensorSizesToFile (sensorSizes : SensorSize list) = try Directory.CreateDirectory Constants.USER_DIRECTORY |> ignore use file = new StreamWriter (sensorSizesFilepath) file.Write (JsonConvert.SerializeObject (sensorSizes, JsonSerializerSettings (Formatting = Formatting.Indented))) with ex -> Logger.Log.Error "Unable to save sensor sizes to file \"%s\": %O" sensorSizesFilepath ex let predefinedPPI : PredefinedPPI list = try use file = new StreamReader (predefinedPPIFilepath) JsonConvert.DeserializeObject (file.ReadToEnd ()) with | _ex -> savePredefinedPPIToFile defaultPredefinedPPI defaultPredefinedPPI let sensorSizes : SensorSize list = try use file = new StreamReader (sensorSizesFilepath) JsonConvert.DeserializeObject (file.ReadToEnd ()) with | _ex -> saveSensorSizesToFile defaultSensorSizes defaultSensorSizes let toRomanNumber (v : int) : string = let rec decompose (v : int) : string = if v >= 1000 then "M" + decompose (v - 1000) elif v >= 900 then "CM" + decompose (v - 900) elif v >= 500 then "D" + decompose (v - 500) elif v >= 400 then "CD" + decompose (v - 400) elif v >= 100 then "C" + decompose (v - 100) elif v >= 90 then "XC" + decompose (v - 90) elif v >= 50 then "L" + decompose (v - 50) elif v >= 40 then "XL" + decompose (v - 40) elif v >= 10 then "X" + decompose (v - 10) elif v >= 9 then "IX" + decompose (v - 9) elif v >= 5 then "V" + decompose (v - 5) elif v >= 4 then "IV" + decompose (v - 4) elif v >= 1 then "I" + decompose (v - 1) else "" decompose v let argsHelp = let programName = System.AppDomain.CurrentDomain.FriendlyName "Usage of Parasitemia:\n" + "Non-interactive mode:\n" + (sprintf " %s (--folder |--file ) --output [--debug]\n" programName) + " --folder : an input folder containing images to analyze\n" + " --file : an image file to be analyzed\n" + " --output : a folder to put the results\n" + " --debug : output more information like intermediate images (it takes more CPU and memory) and write debug information to the log files\n" + "Interactive mode:\n" + (sprintf " %s [] [--debug]\n" programName) + " : a PIAZ file to automatically open at startup\n" + " --debug : output information like intermediate images in the current directory (it takes more CPU and memory)" open System open System.Windows // Inspired by https://github.com/fsprojects/FSharp.ViewModule/blob/master/src/FSharp.ViewModule/FunCommand.fs type FunCommand (execute : obj -> unit, canExecute : obj -> bool) = let canExecuteChanged = Event () interface Input.ICommand with [] member this.CanExecuteChanged = canExecuteChanged.Publish member this.CanExecute (param : obj) = canExecute param member this.Execute (param : obj) = execute param