public static SolveResults ComputeSOM(KMap _som) { SolveResults result = new SolveResults(); _som.trainNodes(); _som.outputNodeWeights(); _som.iter++; result.Value = _som; return(result); }
/// <summary> /// This is the method that actually does the work. /// </summary> /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param> protected override void SolveInstance(IGH_DataAccess DA) { colors = new List <System.Drawing.Color>(); pNames = new List <string>(); pAreas = new List <double>(); List <Rectangle3d> rects = new List <Rectangle3d>(); GH_Structure <GH_Number> pData; GH_Structure <GH_Number> pWeights; List <Point3d> points = new List <Point3d>(); DataTree <double> mod_pData; DataTree <double> mod_pWeights; string message = "nothing"; bool optimized = false; int numMetrics = -1; DA.GetData(IN_numMetrics, ref numMetrics); DA.GetData(IN_reset, ref reset); DA.GetData(IN_run, ref run); DA.GetData(IN_mode, ref optimized); DA.GetDataList(IN_programNames, pNames); DA.GetDataList(IN_programAreas, pAreas); DA.GetDataTree(IN_programData, out pData); DA.GetDataList(IN_programColors, colors); DA.GetDataList(IN_pRects, rects); DA.GetDataTree(IN_pWeights, out pWeights); DA.GetData(IN_resolution, ref _resolution); DA.GetData(IN_radMultiplier, ref radiusMultiplier); DA.GetData(IN_showSOM, ref showSOM); DA.GetData(IN_SOMDisplay, ref display); DA.GetData(IN_DisplayLabels, ref displayText); if (run) { isRunning = true; } else { isRunning = false; } if (isRunning) { ExpireSolution(true); } var simpleNameTree = new DataTree <string>(); try { if (reset || SOM == null) { circles = new List <Polyline>(); points = new List <Point3d>(); radii = new List <double>(); gradientList = new List <System.Drawing.Color>(); for (int i = 0; i < rects.Count; i++) { points.Add(rects[i].Center); } for (int i = 0; i < pAreas.Count; i++) { var rad = Math.Sqrt(pAreas[i] / Math.PI); radii.Add(rad * radiusMultiplier); } mod_pData = new DataTree <double>(); mod_pWeights = new DataTree <double>(); for (int i = 0; i < pData.Paths.Count; i++) { var path = pData.get_Branch(i); for (int j = 0; j < path.Count; j++) { var p = new GH_Path(i); var prog = pData.get_DataItem(p, j).Value; mod_pData.Add(prog, new GH_Path(i)); } } for (int i = 0; i < pWeights.Paths.Count; i++) { var path = pWeights.get_Branch(i); for (int j = 0; j < path.Count; j++) { var p = new GH_Path(i); var weight = pWeights.get_DataItem(p, j).Value; mod_pWeights.Add(weight, new GH_Path(i)); } } //DA.SetDataTree(OUT_nodeWeights,mod_pWeights); SOM = new KMap(mod_pData, points, _resolution, mod_pWeights, numMetrics, 0.12, radii, 1.0, maximumIterations); SOM.applyProgramInputs(pNames.Count); SOM.outputNodesXY(); reset = false; } if (SOM.iter < maximumIterations) { if (InPreSolve) { Task <SolveResults> task = Task.Run(() => ComputeSOM(SOM), CancelToken); TaskList.Add(task); return; } if (!GetSolveResults(DA, out SolveResults result)) { result = ComputeSOM(SOM); SOM = result.Value; } message = string.Format("Runnning...{0}/{1} iterations", SOM.iter, maximumIterations); } else { message = "Done."; isRunning = false; run = false; ClearData(); } if (showSOM) { var nL = new List <double>(); SOM.nodeWeights.Clear(); for (int i = 0; i < SOM.nodeW.BranchCount; i++) { GH_Path path = SOM.nodeW.Path(i); int elementCount = SOM.nodeW.Branch(i).Count; double average = 0; for (int j = 0; j < elementCount; j++) { average += SOM.nodeW[path, j]; } average /= elementCount; nL.Add(average); //average value of all dims of a node } SOM.nodeWeights = nL; Remapper re = new Remapper(SOM.nodeWeights, SOM.nodePoints, pNames, pAreas, _resolution, optimized); var n = re.nodes; var _tree = re.programTree; ///silly name tree output as requested.. for (int i = 0; i < _tree.BranchCount; i++) { simpleNameTree.Add(_tree.Branch(i)[0].name.Split('_')[0], new GH_Path(i)); } //'tree' below is the sorted nodes corresponding to each program based on their BMU var tempTree = new DataTree <sNode>(); for (int i = 0; i < _tree.BranchCount; i++) { int localBCount = _tree.Branch(i).Count; var orderedBranch = _tree.Branch(i).OrderBy(c => c.multiplierStrength).ToList(); tempTree.AddRange(orderedBranch, new GH_Path(i)); } SOM.tree.Clear(); for (int i = 0; i < tempTree.BranchCount; i++) { var fPath = tempTree.Path(i); int localBCount = tempTree.Branch(i).Count; for (int j = 0; j < localBCount; j++) { Plane plane = new Plane(tempTree.Branch(i)[j].pos, Vector3d.ZAxis); Interval inter = new Interval(-_resolution * 0.5, _resolution * 0.5); var rect = new Rectangle3d(plane, inter, inter); var poly = rect.ToPolyline(); //circles.Add(poly); SOM.tree.Add(poly, new GH_Path(fPath)); } } //data for visualization var _points = new List <Point3d>(); SOM.m_pNames = new List <string>(); for (int i = 0; i < n.Count; i++) { var p = n[i].pos; var name = n[i].name; var multiplier = n[i].multiplierStrength; _points.Add(p); SOM.m_pNames.Add(name); } //color by gradient colors // for (int i = 0; i < nodeWeights.Count; i++) if (display == 1) { gradientList = new List <System.Drawing.Color>(); for (int i = 0; i < n.Count; i++) { var multiplier = n[i].multiplierStrength; var gColor = new ColorHSL(multiplier, 0, multiplier); var rgb = gColor.ToArgbColor(); gradientList.Add(rgb); } } else if (display == 2) { gradientList = new List <System.Drawing.Color>(); for (int i = 0; i < n.Count; i++) { var gColor = new ColorHSL(SOM.nodeWeights[i], SOM.nodeWeights[i], SOM.nodeWeights[i], SOM.nodeWeights[i]); var rgb = gColor.ToArgbColor(); gradientList.Add(rgb); } } for (int i = 0; i < SOM.m_pNames.Count; i++) { for (int j = 0; j < pNames.Count; j++) { var strippedName = SOM.RemoveNumbersSymbols(SOM.m_pNames[i]); if (strippedName == pNames[j]) { SOM.discreteCol.Add(colors[j]); } } } SOM.drawingPolys.Clear(); SOM.drawCircles(); circles = SOM.drawingPolys; } } catch (Exception e) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, e.ToString()); } DA.SetData(OUT_RunFeedback, message); DA.SetDataList(OUT_nodeWeights, SOM.nodeWeights); DA.SetDataTree(OUT_programTree, SOM.tree); DA.SetDataTree(OUT_programNames, simpleNameTree); }