private void DrawGraph() { if (!(propertyGrid.SelectedObject is SpectralData)) { return; } SpectralData data = (SpectralData)propertyGrid.SelectedObject; EfficiencyMeasurement[] effpts = data.EfficiencyPoints.ToArray(); int numPoints = 500; int ticks = 10; canvas.BackColor = Color.LightGray; //get the max an min of the efficieny points double maxOrd = effpts.Max(e => e.Efficiency); double minOrd = effpts.Min(e => e.Efficiency); //get ordinate graph bounds that look nice double ordTickRange = GetTickRange(maxOrd - minOrd, ticks); double ordTickMag = Math.Log10(ordTickRange) > 0 ? Math.Ceiling(Math.Log10(ordTickRange)): Math.Floor(Math.Log10(ordTickRange)); maxOrd = ordTickRange * Math.Round(1 + maxOrd / ordTickRange); minOrd = ordTickRange * (Math.Round(minOrd / ordTickRange - 1)); double minAbsc = 0;// Properties.Settings.Default.LOWERELIMT * 0.75; double maxAbsc = Properties.Settings.Default.UPPERELIMIT; //get abscissa graph bounds that look nice double abscTickRange = GetTickRange(maxAbsc - minAbsc, ticks); double abscTickMag = Math.Log10(abscTickRange) > 0 ? Math.Ceiling(Math.Log10(abscTickRange)) : Math.Floor(Math.Log10(abscTickRange)); maxAbsc = abscTickRange * Math.Round(maxAbsc / abscTickRange); minAbsc = abscTickRange * (Math.Round(minAbsc / abscTickRange)); Graphics graph = canvas.CreateGraphics(); graph.Clear(canvas.BackColor); Pen pen = new Pen(Color.DarkSlateGray); int seperation = (canvas.Location.Y - (propertyGrid.Location.Y + propertyGrid.Height)) * 2; Rectangle chart = new Rectangle(7 * seperation, seperation, (int)(0.8F * canvas.Width), (int)(0.8F * canvas.Height)); //graph.DrawRectangle(pen, chart); //get the energy limit double lowE = minAbsc;// Properties.Settings.Default.LOWERELIMT * 0.75; double highE = maxAbsc; //get the position converstion factors. double xconv = (chart.Left - chart.Right) / (lowE - highE); double xoff = chart.Right - (xconv * highE); double yconv = (chart.Bottom - chart.Top) / (minOrd - maxOrd); double yoff = chart.Bottom - (yconv * minOrd); //build a formatting string StringBuilder format = new StringBuilder("0"); format.Append(ordTickMag >= 0 ? "" : "."); for (int j = 0; j < Math.Abs(ordTickMag); j++) { format.Append(0); } //loop throuhg and add lables int tickLength = seperation; double ord = minOrd, absc = minAbsc; while (Math.Round(ord, (int)Math.Abs(ordTickMag)) <= maxOrd) { //draw the y-axis int y = (int)(yconv * (ord) + yoff); graph.DrawLine(pen, chart.Left - tickLength, y, chart.Right, y); string label = (ord).ToString(format.ToString()); SizeF labelSize = graph.MeasureString(label, propertyGrid.Font); graph.DrawString(label, propertyGrid.Font, pen.Brush, new PointF(chart.Left - tickLength - labelSize.Width, y - labelSize.Height / 2)); ord += ordTickRange; } while (Math.Round(absc, (int)Math.Abs(abscTickMag)) <= maxAbsc) { //draw the x-axis int x = (int)(xconv * (absc) + xoff); graph.DrawLine(pen, x, chart.Bottom + tickLength, x, chart.Top); string label = (absc).ToString(); SizeF labelSize = graph.MeasureString(label, propertyGrid.Font); graph.DrawString(label, propertyGrid.Font, pen.Brush, new PointF(x - labelSize.Width / 2, chart.Bottom + labelSize.Height)); absc += abscTickRange; } //fill the an array of points that represents the curve double eJump = (highE - lowE) / numPoints; Point[] curvePoints = new Point[numPoints]; double ene = lowE; for (int i = 0; i < numPoints; i++) { ene += eJump; double eff = data.GetEfficiency(ene); int x = Convert.ToInt32(ene * xconv + xoff); double y = yoff + eff * yconv; if (y > chart.Bottom || double.IsNaN(y)) { y = chart.Bottom; } else if (y < chart.Top || double.IsInfinity(y)) { y = chart.Top; } curvePoints[i] = new Point(x, (int)y); } //make the graph thick Pen graphPen = pen; graphPen.Width *= 3; graph.DrawCurve(graphPen, curvePoints); //put the efficiency points on the chart for (int i = 0; i < effpts.Length; i++) { int x = Convert.ToInt32(effpts[i].Energy * xconv + xoff); int y = Convert.ToInt32(yoff + effpts[i].Efficiency * yconv); int ptSize = Convert.ToInt32(graphPen.Width); graph.DrawRectangle(graphPen, new Rectangle(x - ptSize, y - ptSize, 2 * ptSize, 2 * ptSize)); } }
/// <summary> /// Sets the lines with an assoicated nuclide /// </summary> /// <param name="nuc">the nuclide</param> /// <param name="Peak">the peak </param> public void SetLines(DataRow nuc, DataRow peak) { if (lib == null) { throw new NullReferenceException("Library is not defined"); } if (specData == null) { throw new NullReferenceException("Spectal Data is not defined"); } double area = double.TryParse(peak["AREA"].ToString(), out area) ? area : 0.0; double mda = double.TryParse(peak["CRITLEVEL"].ToString(), out mda) ? 2.71 + 2 * mda : 0.0; matches.Tables["MATCHEDLINES"].Clear(); //get the daughters line and its daughters. Dictionary <string, double> daughters = lib.GetDaughters((string)nuc["NAME"]); //generate a string for the nuclides incuding the daughters StringBuilder nucList = new StringBuilder(); nucList.Append("'" + nuc["NAME"] + "',"); foreach (string key in daughters.Keys) { nucList.Append("'" + key + "',"); } nucList.Remove(nucList.Length - 1, 1); //get the lines for the nucs DataTable lines = lib.Select("PHOTONS", "NAME IN (" + nucList.ToString() + ") AND YIELD > '" + yeildLimit + "'"); foreach (DataRow line in lines.Rows) { double eff = specData.GetEfficiency((double)line["ENERGY"]); //get the yelds of the daughters. double yieldMult = (daughters.TryGetValue((string)line["NAME"], out double branchRatio)) ? branchRatio : 1; //double yieldMult = isParent ? (double)nuc["BRANCHING"] : 1; //get the basis line if (Math.Abs((double)line["ENERGY"] - (double)nuc["ENERGY"]) < 1e-6) { matches.Tables["MATCHEDLINES"].Rows.Add(line["NAME"], line["LINENUMBER"], line["ENERGY"], yieldMult * (double)line["YIELD"], line["TYPE"], eff, area, mda, true, (int)peak["ID"], nuc["DIFFERENCE"]); } else { //reject anything that falls below the yield limit double y2 = (double)line["YIELD"] * yieldMult; if (y2 < yeildLimit) { continue; } //DataRow basis = temp.FirstOrDefault(c => c["NAME"].Equals(line["NAME"])); double e2 = specData.GetEfficiency((double)nuc["ENERGY"]); //set the MDA's it is possible this fails so throw it in a try catch double m2 = 2.71; try { m2 = 2.71 + 3.29 * Math.Sqrt(specData.GetRegion(double.Parse(line["ENERGY"].ToString()))); } catch (Exception ex) { Console.WriteLine(ex.Message + ":\n" + ex.StackTrace); } //double e1 = CAMData.Efficiency(float.Parse(nuc["ENERGY"].ToString()), calParameters); double y1 = (double)nuc["YIELD"]; matches.Tables["MATCHEDLINES"].Rows.Add(line["NAME"], line["LINENUMBER"], line["ENERGY"], y2, line["TYPE"], eff, area * e2 * y2 / (eff * y1), m2); } } }