Update coding style.
[master-thesis.git] / Parasitemia / ParasitemiaUI / PiaZ.fs
index d4ea46f..92ebbe0 100644 (file)
@@ -18,26 +18,36 @@ let extension = ".piaz"
 let filter = "PIA|*.piaz"
 
 // Information associated to a document.
-type JSONInformation = {
-    patientID: string
-}
+type JSONInformation =
+    {
+        patientID : string
+        fileVersion : int
+    }
 
 // Information associated to each images.
-type JSONSourceImage = {
-    num: int
-    RBCRadius: float32 // The RBC Radius found by granulometry.
-    parameters: ParasitemiaCore.Config.Parameters
-    dateLastAnalysis: DateTime
-    rbcs: RBC List
-}
-
-type DocumentData = {
-    patientID: string
-    images: SourceImage list
-}
+type JSONSourceImage =
+    {
+        num : int
+        name : string
+
+        RBCRadius : float32 // The RBC Radius found by granulometry.
+        parameters : ParasitemiaCore.Config.Parameters
+        dateLastAnalysis : DateTime
+        rbcs : RBC List
+
+        healthyRBCBrightness : float32 // 0 to 1.
+        infectedRBCBrightness : float32 // 0 to 1.
+    }
+
+type DocumentData =
+    {
+        patientID : string
+        images : SourceImage list
+    }
 
 let mainEntryName = "info.json"
 let imageExtension = ".tiff"
+let currentFileVersion = 2
 
 /// <summary>
 /// Save a document in a give file path. The file may already exist.
@@ -45,53 +55,93 @@ let imageExtension = ".tiff"
 /// <param name="filePath"></param>
 /// <param name="data"></param>
 /// <exception cref="System.IOException">If the file cannot be written</exception>
-let save (filePath: string) (data: DocumentData) =
-    use file = ZipFile.Open(filePath, ZipArchiveMode.Update)
+let save (filePath : string) (data : DocumentData) =
+    use file = ZipFile.Open (filePath, ZipArchiveMode.Update)
 
     for e in List.ofSeq file.Entries do // 'ofSeq' to not iterate a collection currently modified.
-        e.Delete()
+        e.Delete ()
 
     // Main JSON file.
-    let mainEntry = file.CreateEntry(mainEntryName, CompressionLevel.Fastest)
-    use mainEntryWriter = new StreamWriter(mainEntry.Open())
-    mainEntryWriter.Write(JsonConvert.SerializeObject({ JSONInformation.patientID = data.patientID }))
+    let mainEntry = file.CreateEntry (mainEntryName, CompressionLevel.Fastest)
+    use mainEntryWriter = new StreamWriter (mainEntry.Open ())
+    mainEntryWriter.Write (JsonConvert.SerializeObject ({ patientID = data.patientID; fileVersion = currentFileVersion }))
 
     // Write each images and the associated information.
     for srcImg in data.images do
         let imgFilename = (string srcImg.num) + imageExtension
-        let imgEntry = file.CreateEntry(imgFilename, CompressionLevel.NoCompression) // FIXME: It seems a compression is applied to this file despite of the 'NoCompression' flag.
-        srcImg.img.ToBitmap().Save(imgEntry.Open(), System.Drawing.Imaging.ImageFormat.Tiff)
-
-        let imgJSONEntry = file.CreateEntry(imgFilename + ".json", CompressionLevel.Fastest)
-        use imgJSONFileWriter = new StreamWriter(imgJSONEntry.Open())
-        imgJSONFileWriter.Write(JsonConvert.SerializeObject({ num = srcImg.num; RBCRadius = srcImg.config.RBCRadius.Pixel; parameters = srcImg.config.Parameters; dateLastAnalysis = srcImg.dateLastAnalysis; rbcs = srcImg.rbcs }))
+        let imgEntry = file.CreateEntry (imgFilename, CompressionLevel.NoCompression) // FIXME: It seems a compression is applied to this file despite of the 'NoCompression' flag.
+        srcImg.img.ToBitmap().Save (imgEntry.Open (), System.Drawing.Imaging.ImageFormat.Tiff)
+
+        let imgJSONEntry = file.CreateEntry (imgFilename + ".json", CompressionLevel.Fastest)
+        use imgJSONFileWriter = new StreamWriter (imgJSONEntry.Open ())
+        imgJSONFileWriter.Write (
+            JsonConvert.SerializeObject (
+                {
+                    num = srcImg.num
+                    name = srcImg.name
+                    RBCRadius = srcImg.config.RBCRadius.Pixel
+                    parameters = srcImg.config.Parameters
+                    dateLastAnalysis = srcImg.dateLastAnalysis
+                    rbcs = srcImg.rbcs
+                    healthyRBCBrightness = srcImg.healthyRBCBrightness
+                    infectedRBCBrightness = srcImg.infectedRBCBrightness
+                }
+            )
+        )
+
+let updateDocumentData (fromVersion : int) (toVersion : int) (data : DocumentData) : DocumentData =
+    for v in fromVersion + 1 .. toVersion do
+        match v with
+        | 1 -> // Version 0 -> 1 : set initial brightness for rbc.
+            data.images |> List.iter (fun i -> i.healthyRBCBrightness <- 1.f; i.infectedRBCBrightness <- 1.f)
+        | _ -> ()
+    data
 
 /// <summary>
 /// Load document from a give file path.
 /// </summary>
 /// <param name="filePath"></param>
 /// <exception cref="System.IOException">If the file cannot be read</exception>
-let load (filePath: string) : DocumentData =
-    use file = ZipFile.Open(filePath, ZipArchiveMode.Read)
-
-    let mainEntry = file.GetEntry(mainEntryName)
-    use mainEntryReader = new StreamReader(mainEntry.Open())
-    let info = JsonConvert.DeserializeObject<JSONInformation>(mainEntryReader.ReadToEnd())
-
-    { patientID = info.patientID
-      images = [ let mutable imgNum = 0
-                 for imgEntry in file.Entries do
-                    if imgEntry.Name.EndsWith(imageExtension)
-                    then
-                        let img = new Image<Bgr, byte>(new System.Drawing.Bitmap(imgEntry.Open(), false)) // FIXME: Should we dispose the bitmap?
-                        imgNum <- imgNum + 1
-                        let imgEntry = file.GetEntry(imgEntry.Name + ".json")
-                        use imgEntryFileReader = new StreamReader(imgEntry.Open())
-                        let imgInfo = JsonConvert.DeserializeObject<JSONSourceImage>(imgEntryFileReader.ReadToEnd())
-                        let config = ParasitemiaCore.Config.Config(imgInfo.parameters)
-                        config.SetRBCRadius imgInfo.RBCRadius
-                        yield { num = imgNum
-                                config = config
-                                dateLastAnalysis = imgInfo.dateLastAnalysis
-                                img = img
-                                rbcs = imgInfo.rbcs } ] }
\ No newline at end of file
+let load (filePath : string) (defaultConfig : ParasitemiaCore.Config.Config) : DocumentData =
+    use file = ZipFile.Open (filePath, ZipArchiveMode.Read)
+
+    let mainEntry = file.GetEntry (mainEntryName)
+    use mainEntryReader = new StreamReader (mainEntry.Open ())
+    let info = JsonConvert.DeserializeObject<JSONInformation> (mainEntryReader.ReadToEnd ())
+
+    updateDocumentData info.fileVersion currentFileVersion
+        {
+            patientID = info.patientID
+            images =
+                [
+                    let mutable imgNum = 0
+                    for imgEntry in file.Entries do
+                        if imgEntry.Name.EndsWith (imageExtension) then
+                            use bitmap = new System.Drawing.Bitmap (imgEntry.Open (), false)
+                            let img = new Image<Bgr, byte> (bitmap)
+                            imgNum <- imgNum + 1
+                            let imgJSONEntry = file.GetEntry (imgEntry.Name + ".json")
+                            use imgJSONFileReader = new StreamReader (imgJSONEntry.Open ())
+                            let imgInfo = JsonConvert.DeserializeObject<JSONSourceImage> (imgJSONFileReader.ReadToEnd ())
+
+                            let config = defaultConfig.Copy ()
+                            config.Parameters <-
+                                {
+                                    ParasitemiaCore.Config.defaultParameters with
+                                        resolution = imgInfo.parameters.resolution
+                                }
+
+                            config.SetRBCRadius imgInfo.RBCRadius
+                            yield
+                                {
+                                    num = imgNum
+                                    name = imgInfo.name
+                                    config = config
+                                    dateLastAnalysis = imgInfo.dateLastAnalysis
+                                    img = img
+                                    rbcs = imgInfo.rbcs
+                                    healthyRBCBrightness = imgInfo.healthyRBCBrightness
+                                    infectedRBCBrightness = imgInfo.infectedRBCBrightness
+                                }
+                ]
+        }
\ No newline at end of file