public static bool Export2Bitmap(this UISettings ui, Bitmap bmp1, Bitmap bmp2, string filename, Boolean separate) { try { // compare bmp1 bmp2 dimension may be neccessary if (separate) //export in 2 files { int lastdot = filename.LastIndexOf('.'); string file2 = filename.Substring(0, lastdot) + "_bw" + filename.Substring(lastdot); using (Bitmap finalBitmap = new Bitmap(bmp1.Width / ui.ExportDetailRatio, bmp1.Height / ui.ExportDetailRatio)) { using (Graphics gm = Graphics.FromImage(finalBitmap)) { gm.Clear(Color.Black); //set background color gm.DrawImage(bmp1, new Rectangle(0, 0, bmp1.Width / ui.ExportDetailRatio, bmp1.Height / ui.ExportDetailRatio)); } finalBitmap.Save(filename, System.Drawing.Imaging.ImageFormat.Jpeg.getEncoder(), 85L.jpgEncoderCQ()); } using (Bitmap finalBitmap = new Bitmap(bmp2.Width / ui.ExportDetailRatio, bmp2.Height / ui.ExportDetailRatio)) { using (Graphics gm = Graphics.FromImage(finalBitmap)) { gm.Clear(Color.Black); //set background color gm.DrawImage(bmp2, new Rectangle(0, 0, bmp2.Width / ui.ExportDetailRatio, bmp2.Height / ui.ExportDetailRatio)); } finalBitmap.Save(file2, System.Drawing.Imaging.ImageFormat.Jpeg.getEncoder(), 85L.jpgEncoderCQ()); } return(true); } else //export in 1 file, horizontal merge { using (Bitmap finalBitmap = new Bitmap(bmp1.Width * 2 / ui.ExportDetailRatio, bmp1.Height / ui.ExportDetailRatio)) { using (Graphics gm = Graphics.FromImage(finalBitmap)) { gm.Clear(Color.Black); //set background color gm.DrawImage(bmp1, new Rectangle(0, 0, bmp1.Width / ui.ExportDetailRatio, bmp1.Height / ui.ExportDetailRatio)); gm.DrawImage(bmp2, new Rectangle(bmp1.Width / ui.ExportDetailRatio, 0, bmp1.Width / ui.ExportDetailRatio, bmp1.Height / ui.ExportDetailRatio)); } finalBitmap.Save(filename, System.Drawing.Imaging.ImageFormat.Jpeg.getEncoder(), 85L.jpgEncoderCQ()); return(true); } } } catch { return(false); } }
public CalPAP(UISettings ui, FileData file, ref ConcurrentBag <double> AreaBag) : base(ui, file) { try { MulticolorComponentsLabeling mclabel = new MulticolorComponentsLabeling() { Low = (int)Math.Round(Low_Threshold / ui.um2px2), High = (int)Math.Round(Math.Min(int.MaxValue, High_Threshold / ui.um2px2)) }; Invert AFinvert = new Invert(); UnmanagedResult = mclabel.Apply(AFinvert.Apply(UnmanagedBlackWhite)); foreach (Blobx blob in mclabel.BlobCounter.blobs) { //if (blob.Area<mclabel.Low) { // Low_count++; Low_sumArea+=blob.Area; //} else if (blob.Area<=mclabel.High) { Normal_count++; Normal_SumArea += ui.um2px2 * blob.Area; AreaBag.Add(ui.um2px2 * blob.Area); //} else { // High_count++; High_sumArea+=blob.Area; //} } Total_SumArea = ui.um2px2 * (UnmanagedMarkup.Width * UnmanagedMarkup.Height); // total area Lung_SumArea = Total_SumArea - Low_SumArea - High_SumArea; // lung area Paren_SumArea = Lung_SumArea - NonParen_SumArea; // parenchymal area Tis_SumArea = Paren_SumArea - Normal_SumArea; // septum tissue Normal_Count = 1000.0d * 1000.0d * Normal_count / Paren_SumArea; // counts per reference area StringBuilder header = new StringBuilder(); header.Append($"{FileName} ps: {ui.PixelScale:G2}/{ui.ResizeValue:G2} px/um" + $"\nlung: {Lung_SumArea:G2}µm\xB2, {Lung_SumArea/Total_SumArea:0%} image (blw: {Low_SumArea/Total_SumArea:0%} ovr: {High_SumArea/Total_SumArea:0%})" + $"\nparenchyma: {Paren_SumArea:G2}µm\xB2, {Paren_SumArea/Lung_SumArea:0%} lung (exc: {NonParen_SumArea/Total_SumArea:0%})" + $"\nseptum: {Tis_SumArea:G2}µm\xB2, {Tis_SumArea/Paren_SumArea:0%} paren (airspace: {Normal_SumArea/Total_SumArea:0%})"); StringBuilder footer = new StringBuilder(); footer.Append($"Total #: {mclabel.BlobCounter.blobs.Count}"); UnmanagedMarkup = UnmanagedImage.FromManagedImage(AddBlobText(UnmanagedMarkup.ToManagedImage(false), Color.Black, $"{header}", $"{footer}", null, null, (int)Math.Round(0.02d * UnmanagedMarkup.Width * Math.Sqrt(ui.ExportDetailRatio)))); UnmanagedResult = UnmanagedImage.FromManagedImage(AddBlobText(UnmanagedResult.ToManagedImage(false), Color.PaleGreen, $"{header}", $"{footer}", null, null, (int)Math.Round(0.02d * UnmanagedMarkup.Width * Math.Sqrt(ui.ExportDetailRatio)))); } catch { throw new Exception("Error Occured During Airspace Profiling"); } }
//public static T DeepCopy<T>(T other) //{ // using (var ms = new MemoryStream()) { // var formatter = new BinaryFormatter(); // formatter.Serialize(ms, other); // ms.Position=0; // return (T)formatter.Deserialize(ms); // } //} //public static async Task<bool> Save(this UISettings ui, string filename = "LastSaved.xsetting") //{ // ui.ShowBusySign("Saving Settings..."); // bool result = await Task<bool>.Factory.StartNew(() => { // try { // using (FileStream fsUserSetting = File.Create(filename)) { // var formatter = new XmlSerializer(ui.GetType()); // formatter.Serialize(fsUserSetting, ui); // } // return true; // } catch { MessageBox.Show("Failed to save the current settings!", "Error", MessageBoxButton.OK, MessageBoxImage.Error); return false; } // }); // ui.StopBusySign(); return result; //} public static async Task <bool> SaveCrypt(this UISettings ui, string filename = "LastSaved.xsetting") { ui.ShowBusySign("Saving Settings..."); try { await Task.Factory.StartNew(() => { var aUE = new UnicodeEncoding(); byte[] key = aUE.GetBytes("password"); var RMCrypto = new RijndaelManaged(); using (var fs = File.Open(filename, FileMode.Create)) { using (var cs = new CryptoStream(fs, RMCrypto.CreateEncryptor(key, key), CryptoStreamMode.Write)) { var xml = new XmlSerializer(ui.GetType()); xml.Serialize(cs, ui); } } }); return(true); } catch { MessageBox.Show("Failed to save the current settings!", "Error", MessageBoxButton.OK, MessageBoxImage.Error); return(false); } finally { ui.StopBusySign(); } }
public static async Task BatchAQ2(this UISettings ui, List <FileData> listfiles) { try { Directory.CreateDirectory($"{ui.WorkDirectory}\\{ui.ProjectName}\\LMAQ2"); // quantify with 2-dist using (var file = File.AppendText($"{ui.WorkDirectory}\\{ui.ProjectName}\\_{ui.ProjectName}_LMAQ2.csv")) { file.Write("\n" + CalBlobAQ2.getEntryNote + "\n" + CalBlobAQ2.getDescription + "\n" + CalBlobAQ2.getHeader); } var progress = new Progress($"Analyzing {listfiles.Count} files ...", listfiles.Count); using (ui.cts = new CancellationTokenSource()) { if (!ui.MultiThreadingSwitch) // false - single thread { foreach (FileData imgfile in listfiles) { using (var img = await Task <CalBlobAQ2> .Factory.StartNew(() => { return(new CalBlobAQ2(ui, imgfile)); })) { ui.UpdateImageSource(img.BitmapOriginal, img.BitmapMarkup, img.BitmapExclude, img.BitmapGray, img.BitmapBlackWhite, img.BitmapResult); ui.Export2Bitmap(img.BitmapMarkup, img.BitmapResult, $"{ui.WorkDirectory}\\{ui.ProjectName}\\LMAQ2\\{img.OutName}.png", ui.ExportDetailSwitch); progress.Increment(ui, $"{ui.WorkDirectory}\\{ui.ProjectName}\\_{ui.ProjectName}_LMAQ2.csv", img.getResult); } ui.cts.Token.ThrowIfCancellationRequested(); } } else // true - open multi thread pool { await Task.Factory.StartNew(() => { Parallel.ForEach(listfiles, new ParallelOptions() { CancellationToken = ui.cts.Token, MaxDegreeOfParallelism = Environment.ProcessorCount }, (FileData imgfile) => { using (var img = new CalBlobAQ2(ui, imgfile)) { ui.Export2Bitmap(img.BitmapMarkup, img.BitmapResult, $"{ui.WorkDirectory}\\{ui.ProjectName}\\LMAQ2\\{img.OutName}.jpe", ui.ExportDetailSwitch); progress.Increment(ui, $"{ui.WorkDirectory}\\{ui.ProjectName}\\_{ui.ProjectName}_LMAQ2.csv", img.getResult); } }); }); } } } catch { throw new Exception("Error encountered during batch airspace quantification."); } }
//public static async Task<bool> Load(this DockingManager dockingManager, UISettings ui, string filename = "LastSaved.xlayout") //{ // ui.ShowBusySign("Saving Settings..."); // try { // var serializer = new XmlLayoutSerializer(dockingManager); // using (var stream = new StreamReader(filename)) { serializer.Deserialize(stream); } // ui.StopBusySign(); return true; // } catch { ui.StopBusySign(); MessageBox.Show("Failed to load the selected layout!", "Error", MessageBoxButton.OK, MessageBoxImage.Error); return false; } //} public static async Task <bool> LoadCrypt(this DockingManager dockingManager, UISettings ui, string filename = "LastSaved.xlayout") { ui.ShowBusySign("Saving Settings..."); try { var deserializer = new XmlLayoutSerializer(dockingManager); using (var fs = new FileStream(filename, FileMode.Open)) { using (var sr = new StreamReader(fs)) { var aUE = new UnicodeEncoding(); byte[] key = aUE.GetBytes("password"); using (var RMCrypto = new RijndaelManaged()) { using (var cs = new CryptoStream(fs, RMCrypto.CreateDecryptor(key, key), CryptoStreamMode.Read)) { deserializer.Deserialize(cs); } } } } return(true); } catch { MessageBox.Show("Failed to load the selected layout!", "Error", MessageBoxButton.OK, MessageBoxImage.Error); return(false); } finally { ui.StopBusySign(); } }
public Binarize(UISettings ui, FileData file) : base(ui, file) { try { Invert AFinvert = new Invert(); switch (ui.ThresholdIndex) // threshold method selection "Global mean" / "Local adaptive" { case 0: // Global if (ui.ThreshGlobalIsAbsolute) // use absolute { Threshold AFglobalbinary = new Threshold(ui.ThreshGlobalAbsolute); UnmanagedBlackWhite = AFglobalbinary.Apply(UnmanagedGray); } else // use relative { ImageStatistics stats = new ImageStatistics(UnmanagedGray, AFinvert.Apply(UnmanagedExclude)); Threshold AFglobalbinary = new Threshold(stats.Gray.Center2QuantileValue(1.0d * ui.ThreshGlobalRelative / 255.0d)); UnmanagedBlackWhite = AFglobalbinary.Apply(UnmanagedGray); } break; case 1: // Local BradleyLocalThresholdingX AFlocalbinary = new BradleyLocalThresholdingX() { PixelBrightnessDifferenceLimit = ui.ThreshLocalBrightnessDifference, WindowSize = ui.ThreshLocalWindowSize, UpperLimit = 250 }; UnmanagedBlackWhite = AFlocalbinary.Apply(UnmanagedGray); break; } if (ui.FillHoleAirspaceSwitch && ui.FillHoleAirspace != 0) // fill holes of airspaces { FillHoles AFfillinair = new FillHoles() { CoupledSizeFiltering = true, MaxHoleHeight = ui.FillHoleAirspace, MaxHoleWidth = ui.FillHoleAirspace }; //FillHolesArea AFfillinair=new FillHolesArea() { MaxHoleArea=ui.FillHoleAirspace }; AFfillinair.ApplyInPlace(UnmanagedBlackWhite); } UnmanagedBlackWhite = AFinvert.Apply(UnmanagedBlackWhite); if (ui.FillHoleTissueSwitch && ui.FillHoleTissue != 0) // fill holes of tissue { FillHoles AFfillintissue = new FillHoles() { CoupledSizeFiltering = true, MaxHoleHeight = ui.FillHoleTissue, MaxHoleWidth = ui.FillHoleTissue }; //FillHolesArea AFfillintissue=new FillHolesArea() { MaxHoleArea=ui.FillHoleTissue }; AFfillintissue.ApplyInPlace(UnmanagedBlackWhite); } if (ui.MorphoDilateSwitch && ui.MorphoDilate != 0) // Morphological Dilate { int n = (Math.Max(ui.MorphoDilate, 0) * 2 + 1); short[,] morphmatrix = new short[n, n]; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { morphmatrix[i, j] = 1; } } Dilatation AFdilate = new Dilatation(morphmatrix); AFdilate.ApplyInPlace(UnmanagedBlackWhite); } if (ui.MorphoErodeSwitch && ui.MorphoErode != 0) // Morphological Erode { int n = (Math.Max(ui.MorphoErode, 0) * 2 + 1); short[,] morphmatrix = new short[n, n]; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { morphmatrix[i, j] = 1; } } Erosion AFerode = new Erosion(morphmatrix); AFerode.ApplyInPlace(UnmanagedBlackWhite); } if (ui.ExcludeColorSwitch) { NonParen_SumArea = ui.um2px2 * UnmanagedExclude.NonBlackArea(); } if (ui.BlobMinSwitch) { Low_Threshold = Math.Pow(10.0d, ui.BlobMin) - 1; } else { Low_Threshold = 0.0d; } if (ui.BlobMaxSwitch) { High_Threshold = Math.Pow(10.0d, ui.BlobMax) - 1; } else { High_Threshold = int.MaxValue; } if (ui.BlobMinSwitch || ui.BlobMaxSwitch) { Merge AFmerge1 = new Merge(UnmanagedExclude); ExcludeSize AFexcsize = new ExcludeSize() { Low = (int)Math.Round(Low_Threshold / ui.um2px2), High = (int)Math.Round(Math.Min(int.MaxValue, High_Threshold / ui.um2px2)) }; Merge AFmerge2 = new Merge(AFexcsize.Apply(AFinvert.Apply(AFmerge1.Apply(UnmanagedBlackWhite)))); AFmerge2.ApplyInPlace(UnmanagedExclude); Low_SumArea = ui.um2px2 * AFexcsize.LowCount; High_SumArea = ui.um2px2 * AFexcsize.HighCount; } } catch { throw new Exception("Error Occured During Binarization"); } }
public CalPAQ1(UISettings ui, FileData f, CalPAC categ = null) : base(ui, f) { try { // low-alv-des-high cut if (categ != null) // use alv des cutoffs from categorize class { Alv_Log_Size = categ.p1Mean; //Sac_Log_Size=categ.p2Mean; //Des_Log_Size=categ.p3Mean; Alv_Size = Math.Pow(10.0d, categ.p1Mean) - 1; //Sac_size=Math.Pow(10.0d, categ.p2Mean)-1; //Des_size=Math.Pow(10.0d, categ.p3Mean)-1; //Alv_Cut=Math.Pow(10.0d, categ.Alv_Log_Cut)-1; DucDes_Threshold = Math.Pow(10.0d, categ.c1_DucDes_CI95_1tail) - 1; //Alv_cut=Alv_Cut/px2um2; } else // alv des cutoffs from ui { DucDes_Threshold = Math.Pow(10.0d, ui.BlobDes) - 1; } DucDes_Log_Threshold = Math.Log10(DucDes_Threshold + 1); AreaComponentsLabeling aclabel = new AreaComponentsLabeling() { Low = (int)Math.Round(Low_Threshold / ui.um2px2), High = (int)Math.Round(Math.Min(int.MaxValue, High_Threshold / ui.um2px2)), Alv = (int)Math.Round(DucDes_Threshold / ui.um2px2), // use Des_cut to elliminate Sac color Des = (int)Math.Round(DucDes_Threshold / ui.um2px2) }; Invert AFinvert = new Invert(); UnmanagedResult = aclabel.Apply(AFinvert.Apply(UnmanagedBlackWhite)); //Low_count = Low_sumArea = High_count = High_sumArea = 0; foreach (Blobx blob in aclabel.BlobCounter.blobs) { if (blob.Area <= aclabel.Des) // alv/sac { AlvSac_count++; AlvSac_SumArea += ui.um2px2 * blob.Area; AlvSac_SumBoundary += ui.umpx * blob.Perimeter; } else // duct/des { DucDes_count++; DucDes_SumArea += ui.um2px2 * blob.Area; DucDes_SumBoundary += ui.umpx * blob.Perimeter; } } Total_SumArea = ui.um2px2 * (UnmanagedMarkup.Width * UnmanagedMarkup.Height); // total area Lung_SumArea = Total_SumArea - Low_SumArea - High_SumArea; // lung area Paren_SumArea = Lung_SumArea - NonParen_SumArea; // parenchymal area Tis_SumArea = Paren_SumArea - AlvSac_SumArea - DucDes_SumArea; // septum tissue AlvSac_Count = 1000.0d * 1000.0d * AlvSac_count / Paren_SumArea; DucDes_Count = 1000.0d * 1000.0d * DucDes_count / Paren_SumArea; AlvSac_Boundary = 1.0d * AlvSac_SumBoundary / Paren_SumArea; DucDes_Boundary = 1.0d * DucDes_SumBoundary / Paren_SumArea; AlvSac_Fraction = 1.0d * AlvSac_SumArea / Paren_SumArea; DucDes_Fraction = 1.0d * DucDes_SumArea / Paren_SumArea; // is still better to divide by paren area Tis_Fraction = 1.0d - AlvSac_Fraction - DucDes_Fraction; DucDes_Alv_Ratio = DucDes_Fraction / AlvSac_Fraction; StringBuilder header = new StringBuilder(); header.Append($"{FileName} ps: {ui.PixelScale:G2}/{ui.ResizeValue:G2} px/um" + $"\nduc/des thres:{DucDes_Log_Threshold:0.00} log\x2081\x2080µm\xB2"); header.Append($"\nlung: {Lung_SumArea:G2}µm\xB2, {(1.0d*Lung_SumArea/Total_SumArea):0%} image (blw: {Low_SumArea/Total_SumArea:0%} ovr: {1.0d*High_SumArea/Total_SumArea:0%})"); header.Append($"\nparenchyma: {Paren_SumArea:G2}µm\xB2, {(Paren_SumArea/Lung_SumArea):0%} lung (exc: {1.0d*NonParen_SumArea/Total_SumArea:0%})"); header.Append($"\nseptum: {Tis_SumArea:G2}µm\xB2, {Tis_SumArea/Paren_SumArea:0%} paren (airspace: {(AlvSac_SumArea+DucDes_SumArea)/Total_SumArea:0%})"); StringBuilder footer = new StringBuilder(); if (Math.Abs(Alv_Size) > 0.01d) { footer.Append($" AS:{Alv_Size:G2} (Size, µm\xB2)"); } footer.Append($"\nASC:{AlvSac_Count:G2} DC:{DucDes_Count:G2} (Count\x2090: 1/mm\xB2)" + $"\nASB:{AlvSac_Boundary:G2} DB:{DucDes_Boundary:G2} (Boundary\x2090, 1/µm)" + $"\nASF:{AlvSac_Fraction:0%} DF:{DucDes_Fraction:0%} (Area\x2090 Fraction, %)" + $"\nTF:{Tis_Fraction:0.0%} D2A:{DucDes_Alv_Ratio:F2} (Fraction, Ratio)"); UnmanagedMarkup = UnmanagedImage.FromManagedImage(AddBlobText(UnmanagedMarkup.ToManagedImage(false), Color.Black, $"{header}", $"{footer}", null, null, // ,blobs, blobDes.ToArray() (int)Math.Round(0.02d * UnmanagedMarkup.Width * Math.Sqrt(ui.ExportDetailRatio)))); UnmanagedResult = UnmanagedImage.FromManagedImage(AddBlobText(UnmanagedResult.ToManagedImage(false), Color.PaleGreen, $"{header}", $"{footer}", null, null, // ,blobs, blobDes.ToArray() (int)Math.Round(0.02d * UnmanagedMarkup.Width * Math.Sqrt(ui.ExportDetailRatio)))); } catch { throw new Exception("Error Occured During Airspace Quantification"); } }
public CalParen(UISettings ui, FileData file) : base(ui, file) { Merge AFmerge = new Merge(UnmanagedExclude); AFmerge.ApplyInPlace(UnmanagedBlackWhite); }
public CalPAC(UISettings ui, string grouping, int n, List <double> AreaPool) { try { //Stopwatch sw = new Stopwatch(); //sw.Start(); Grouping = grouping; N = n; AreaPool.Sort(); // for weight sampling //double px2um2=ui.PixelScale*ui.PixelScale/ui.ResizeRatio/ui.ResizeRatio; var CountDis = new List <double[]>(); double AreaSum = 0.0d; for (int i = 0; i < AreaPool.Count; i++) { double[] data = new double[1]; data[0] = Math.Log10(AreaPool[i] + 1); //data[1] = (double)(mFull[i]/100.0d); CountDis.Add(data); AreaSum += AreaPool[i]; } ///1-Dist fitted with 1-Population GaussianMixtureModel gmm1 = new GaussianMixtureModel(1); gmm1Fit = gmm1.Compute(CountDis.ToArray()); p1Mean = gmm1.Gaussians[0].Mean[0]; p1Covariance = gmm1.Gaussians[0].Covariance[0, 0]; p1Proportion = gmm1.Gaussians[0].Proportion; ///1-Dist fitted with 2-Populations / take the larger proportion //GaussianMixtureModel gmm1=new GaussianMixtureModel(2); //gmm1Fit=gmm1.Compute(countDis.ToArray()); //int m=(gmm1.Gaussians[0].Proportion>gmm1.Gaussians[1].Proportion) ? 0 : 1; //p1Mean=gmm1.Gaussians[m].Mean[0]; //p1Covariance=gmm1.Gaussians[m].Covariance[0, 0]; //p1Proportion=gmm1.Gaussians[m].Proportion; ///List<double[]> areaDis = WeightExpansion(AreaPool, divider=10.0d); //var AreaDis = new List<double[]>(); //double divider = 10.0d; //for (int i = 0; i<AreaPool.Count; i++) { // double[] data = new double[1]; // data[0]=Math.Log10(AreaPool[i]+1); // for (int r = 0; r<Math.Round(AreaPool[i]/divider); r++) { AreaDis.Add(data); } //} ///List<double[]> areaDis = WeightSampling(AreaPool, AreaSum, Math.Max((int)Math.Round(AreaSum/5000.0d), 1)); // sample every divided by 5000 evenly or every one if not too large var AreaDis = new List <double[]>(); int askip = (int)Math.Round(Math.Max(AreaSum / 5000.0d, 1)); for (int sn = 0; sn < (int)Math.Floor(AreaSum); sn += askip) // sample number { double s = 0.0d; for (int bi = 0; bi < AreaPool.Count; bi++) { s += AreaPool[bi]; if (s > sn) { double[] data = new double[1]; data[0] = Math.Log10(AreaPool[bi] + 1); AreaDis.Add(data); break; } } } ///2-Dist fitted with 2-Populations / GaussianMixtureModel gmm2 = new GaussianMixtureModel(2); gmm2Fit = gmm2.Compute(AreaDis.ToArray()); int a = (gmm2.Gaussians[0].Mean[0] < gmm2.Gaussians[1].Mean[0]) ? 0 : 1; p2Mean = gmm2.Gaussians[a].Mean[0]; p2Covariance = gmm2.Gaussians[a].Covariance[0, 0]; p2Proportion = gmm2.Gaussians[a].Proportion; p3Mean = gmm2.Gaussians[1 - a].Mean[0]; p3Covariance = gmm2.Gaussians[1 - a].Covariance[0, 0]; p3Proportion = gmm2.Gaussians[1 - a].Proportion; DistCount = Bucketize(CountDis); DistArea = Bucketize(AreaDis); //sw.Stop(); //Debug.Write(sw.Elapsed); } catch { throw new Exception("Error Occured During Airspace Categorization"); } }
public static async Task BatchAP2(this UISettings ui, List <FileData> listfiles) { try { Directory.CreateDirectory($"{ui.WorkDirectory}\\{ui.ProjectName}\\LMAP"); // profile using (var file = File.AppendText($"{ui.WorkDirectory}\\{ui.ProjectName}\\_{ui.ProjectName}_LMAP.csv")) { file.Write("\n" + CalPAC.getEntryNote + "\n" + CalPAC.getDescription + "\n" + CalPAC.getHeader); } Directory.CreateDirectory($"{ui.WorkDirectory}\\{ui.ProjectName}\\LMAQ2"); // quantify with 2-dist using (var file = File.AppendText($"{ui.WorkDirectory}\\{ui.ProjectName}\\_{ui.ProjectName}_LMAQ2.csv")) { file.Write("\n" + CalBlobAQ2.getEntryNote + "\n" + CalBlobAQ2.getDescription + "\n" + CalBlobAQ2.getHeader); } switch (ui.ProfilingIndex) { case 0: foreach (FileData f in listfiles) { f.Grouping = "All"; } break; case 1: foreach (FileData f in listfiles) { f.Grouping = f.Group; } break; case 2: foreach (FileData f in listfiles) { f.Grouping = f.Group + "-" + f.Individual; } break; case 3: foreach (FileData f in listfiles) { f.Grouping = f.OutName; } break; } var filegroups = listfiles.GroupBy(g => g.Grouping).Select(l => l.ToList()).ToList(); var progress = new Progress($"Analyzing {listfiles.Count} files in {filegroups.Count} groups ...", listfiles.Count * 2 + filegroups.Count); // 2X the work + additional categorization using (ui.cts = new CancellationTokenSource()) { foreach (List <FileData> filegroup in filegroups) // Process each group { if (!ui.MultiThreadingSwitch) // false - single thread { var areaPool = new ConcurrentBag <double>(); foreach (FileData imgfile in filegroup) { using (var img = await Task <CalPAP> .Factory.StartNew(() => { return(new CalPAP(ui, imgfile, ref areaPool)); })) { ui.UpdateImageSource(img.BitmapOriginal, img.BitmapMarkup, img.BitmapExclude, img.BitmapGray, img.BitmapBlackWhite, img.BitmapResult); ui.Export2Bitmap(img.BitmapMarkup, img.BitmapResult, $"{ui.WorkDirectory}\\{ui.ProjectName}\\LMAP\\{img.OutName}.jpe", ui.ExportDetailSwitch); progress.Increment(ui); //incremenet without writing result } ui.cts.Token.ThrowIfCancellationRequested(); } var categ = await Task <CalPAC> .Factory.StartNew(() => { return(new CalPAC(ui, filegroup[0].Grouping, filegroup.Count, areaPool.ToList())); }); ui.Graph1 = categ.ToOxyPlot(1); ui.Graph1.ExportPng($"{ui.WorkDirectory}\\{ui.ProjectName}\\{filegroup[0].Grouping}_1-Count.png"); ui.Graph2 = categ.ToOxyPlot(2); ui.Graph2.ExportPng($"{ui.WorkDirectory}\\{ui.ProjectName}\\{filegroup[0].Grouping}_2-Area.png"); ui.Graph3 = categ.ToOxyPlot(3); ui.Graph3.ExportPng($"{ui.WorkDirectory}\\{ui.ProjectName}\\{filegroup[0].Grouping}_3-Count&Area.png"); progress.Increment(ui, $"{ui.WorkDirectory}\\{ui.ProjectName}\\_{ui.ProjectName}_LMAP.csv", categ.getResult); ui.cts.Token.ThrowIfCancellationRequested(); foreach (FileData imgfile in filegroup) { using (var img = await Task <CalBlobAQ2> .Factory.StartNew(() => { return(new CalBlobAQ2(ui, imgfile, categ)); })) { ui.UpdateImageSource(img.BitmapOriginal, img.BitmapMarkup, img.BitmapExclude, img.BitmapGray, img.BitmapBlackWhite, img.BitmapResult); ui.Export2Bitmap(img.BitmapMarkup, img.BitmapResult, $"{ui.WorkDirectory}\\{ui.ProjectName}\\LMAQ2\\{img.OutName}.png", ui.ExportDetailSwitch); progress.Increment(ui, $"{ui.WorkDirectory}\\{ui.ProjectName}\\_{ui.ProjectName}_LMAQ2.csv", img.getResult); } ui.cts.Token.ThrowIfCancellationRequested(); } } else // true - open multi thread pool { var categ = await Task <CalPAC> .Factory.StartNew(() => { var areaPool = new ConcurrentBag <double>(); Parallel.ForEach(filegroup, new ParallelOptions() { CancellationToken = ui.cts.Token, MaxDegreeOfParallelism = Environment.ProcessorCount }, (FileData imgfile) => { using (var img = new CalPAP(ui, imgfile, ref areaPool)) { ui.Export2Bitmap(img.BitmapMarkup, img.BitmapResult, $"{ui.WorkDirectory}\\{ui.ProjectName}\\LMAP\\{img.OutName}.jpe", ui.ExportDetailSwitch); progress.Increment(ui); //incremenet without writing result } }); return(new CalPAC(ui, filegroup[0].Grouping, filegroup.Count, areaPool.ToList())); }); ui.cts.Token.ThrowIfCancellationRequested(); ui.Graph1 = categ.ToOxyPlot(1); ui.Graph1.ExportPng($"{ui.WorkDirectory}\\{ui.ProjectName}\\{filegroup[0].Grouping}_1-Count.png"); ui.Graph2 = categ.ToOxyPlot(2); ui.Graph2.ExportPng($"{ui.WorkDirectory}\\{ui.ProjectName}\\{filegroup[0].Grouping}_2-Area.png"); ui.Graph3 = categ.ToOxyPlot(3); ui.Graph3.ExportPng($"{ui.WorkDirectory}\\{ui.ProjectName}\\{filegroup[0].Grouping}_3-Count&Area.png"); progress.Increment(ui, $"{ui.WorkDirectory}\\{ui.ProjectName}\\_{ui.ProjectName}_LMAP.csv", categ.getResult); ui.cts.Token.ThrowIfCancellationRequested(); await Task.Factory.StartNew(() => { Parallel.ForEach(filegroup, new ParallelOptions() { CancellationToken = ui.cts.Token, MaxDegreeOfParallelism = Environment.ProcessorCount }, (FileData imgfile) => { using (var img = new CalBlobAQ2(ui, imgfile, categ)) { ui.Export2Bitmap(img.BitmapMarkup, img.BitmapResult, $"{ui.WorkDirectory}\\{ui.ProjectName}\\LMAQ2\\{img.OutName}.jpe", ui.ExportDetailSwitch); progress.Increment(ui, $"{ui.WorkDirectory}\\{ui.ProjectName}\\_{ui.ProjectName}_LMAQ2.csv", img.getResult); } }); }); ui.cts.Token.ThrowIfCancellationRequested(); } } } } catch { throw new Exception("Error encountered during batch airspace profiling."); } }