private List<string> GenerateArtifactMessage(cPlate PlateToProcess, int CurrentDescSel) { int NumWell = PlateToProcess.GetNumberOfActiveWells(); List<string> Messages = new List<string>(); // Normality Test List<double> CurrentDesc = new List<double>(); for (int IdxValue = 0; IdxValue < CompleteScreening.Columns; IdxValue++) for (int IdxValue0 = 0; IdxValue0 < CompleteScreening.Rows; IdxValue0++) { cWell TmpWell = PlateToProcess.GetWell(IdxValue, IdxValue0, true); if (TmpWell != null) CurrentDesc.Add(TmpWell.ListDescriptors[CurrentDescSel].GetValue()); } CurrentDesc.Sort(); if ((std(CurrentDesc.ToArray()) == 0)) { //Messages.Add(/*PlateToProcess.Name + "\n \n*/"No systematic error detected !"); return null; } double Anderson_DarlingValue = Anderson_Darling(CurrentDesc.ToArray()); Messages.Add(string.Format("{0:0.###}", Anderson_DarlingValue)); // now clustering if (!KMeans((int)GlobalInfo.OptionsWindow.numericUpDownSystErrorIdentKMeansClasses.Value, PlateToProcess, CurrentDescSel)) { List<string> ListMessageError = new List<string>(); ListMessageError.Add("K-Means Error"); return ListMessageError; } // and finally classification int MinObjectsNumber = (NumWell * (int)GlobalInfo.OptionsWindow.numericUpDownSystemMinWellRatio.Value) / 100; List<string> ListMessage = ComputePlateBasedClassification((int)GlobalInfo.OptionsWindow.numericUpDownSystErrorIdentKMeansClasses.Value, MinObjectsNumber, PlateToProcess); for (int i = 0; i < ListMessage.Count; i++) Messages.Add(ListMessage[i]); return Messages; }
/// <summary> /// K-Mean for Systematic error Identification /// </summary> /// <param name="Classes"></param> /// <param name="PlateToProcess"></param> /// <param name="Desc"></param> /// <returns></returns> private bool KMeans(int Classes, cPlate PlateToProcess, int Desc) { int NumWell = PlateToProcess.GetNumberOfActiveWells(); int Numdesc = cGlobalInfo.CurrentScreening.GetNumberOfActiveDescriptor(); double[,] DataForKMeans = new double[NumWell, Numdesc]; List<double> CurrentDesc = new List<double>(); double[] NormDesc = null; for (int IdxValue = 0; IdxValue < cGlobalInfo.CurrentScreening.Columns; IdxValue++) for (int IdxValue0 = 0; IdxValue0 < cGlobalInfo.CurrentScreening.Rows; IdxValue0++) { cWell TmpWell = PlateToProcess.GetWell(IdxValue, IdxValue0, true); if (TmpWell != null) CurrentDesc.Add(TmpWell.ListSignatures[Desc].GetValue()); } if (CurrentDesc.Count == 0) return false; NormDesc = MeanCenteringStdStandarization(CurrentDesc.ToArray()); for (int row = 0; row < NumWell; row++) DataForKMeans[row, 0] = NormDesc[row]; int Info; double[,] CenterPos; int[] ClusterIndx; try { alglib.kmeansgenerate(DataForKMeans, NumWell, Numdesc, Classes, 10, out Info, out CenterPos, out ClusterIndx); int Idx = 0; for (int IdxValue = 0; IdxValue < cGlobalInfo.CurrentScreening.Columns; IdxValue++) for (int IdxValue0 = 0; IdxValue0 < cGlobalInfo.CurrentScreening.Rows; IdxValue0++) { cWell TmpWell = PlateToProcess.GetWell(IdxValue, IdxValue0, true); if (TmpWell != null) { if (ClusterIndx[Idx] == -1) TmpWell.SetAsNoneSelected(); else TmpWell.SetClass(ClusterIndx[Idx]); Idx++; } } } catch { MessageBox.Show("Check the data validity", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return false; } return true; }
/// <summary> /// K - Mean clustering procedure /// </summary> /// <param name="Classes"></param> /// <param name="PlateToProcess"></param> /// <returns></returns> private bool KMeans(int Classes, cPlate PlateToProcess) { int NumWell = PlateToProcess.GetNumberOfActiveWells(); int Numdesc = CompleteScreening.GetNumberOfActiveDescriptor(); double[,] DataForKMeans = new double[NumWell, Numdesc]; int IdxDesc = 0; for (int desc = 0; desc < CompleteScreening.ListDescriptors.Count; desc++) { if (CompleteScreening.ListDescriptors[desc].IsActive() == false) continue; List<double> CurrentDesc = new List<double>(); double[] NormDesc = null; for (int IdxValue = 0; IdxValue < CompleteScreening.Columns; IdxValue++) for (int IdxValue0 = 0; IdxValue0 < CompleteScreening.Rows; IdxValue0++) { cWell TmpWell = PlateToProcess.GetWell(IdxValue, IdxValue0, true); if (TmpWell != null) CurrentDesc.Add(TmpWell.ListDescriptors[desc].GetValue()); } if (CurrentDesc.Count == 0) continue; NormDesc = MeanCenteringStdStandarization(CurrentDesc.ToArray()); for (int row = 0; row < NumWell; row++) DataForKMeans[row, IdxDesc] = NormDesc[row]; IdxDesc++; } int Info; double[,] CenterPos; int[] ClusterIndx; try { alglib.kmeansgenerate(DataForKMeans, NumWell, Numdesc, Classes, 10, out Info, out CenterPos, out ClusterIndx); int Idx = 0; for (int IdxValue = 0; IdxValue < CompleteScreening.Columns; IdxValue++) for (int IdxValue0 = 0; IdxValue0 < CompleteScreening.Rows; IdxValue0++) { cWell TmpWell = PlateToProcess.GetWell(IdxValue, IdxValue0, true); if (TmpWell != null) { if (ClusterIndx[Idx] == -1) TmpWell.SetAsNoneSelected(); else TmpWell.SetClass(ClusterIndx[Idx]); Idx++; } } } catch { richTextBoxInfoClustering.AppendText("\nPlate: " + PlateToProcess.Name + " skipped: data corrupted (check your descriptor data validity)."); //MessageBox.Show("Check the data validity", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return false; } return true; }