/// <summary> /// Gets the nuclides similar to the provided name /// </summary> /// <param name="name"></param> /// <param name="id"></param> /// <param name="exactName"></param> public void SetNuclides(string name, int id = 0, bool exactName = false) { //convert the nuclide name to ensure it is good. name = exactName? name : lib.GetNuclideName(name); if (String.IsNullOrEmpty(name)) { throw new ArgumentException("A nuclide must be entered"); } DataTable nucs; if (!exactName) { nucs = lib.Select("NUCLIDES", "NAME LIKE '%" + name + "%' OR PARENT LIKE '%" + name + "%'"); } else { nucs = lib.Select("NUCLIDES", "NAME = '" + name.Trim() + "'"); } foreach (DataRow nuc in nucs.Rows) { double score = 1; //DataRow key = lib.Select("MAX(YIELD) FROM PHOTONS WHERE NAME = '" + nuc["NAME"] +"'").Rows[0]; //whene there is no parent if (nuc["PARENT"].Equals("NONE")) { //include the yeild weight matches.Tables["MATCHEDNUCLIDES"].Rows.Add(id, nuc["NAME"], 1 * score, nuc["NAME"], nuc["HALF_LIFE"], nuc["HALF_LIFE_UNIT"]); //key["ENERGY"], key["YIELD"], key["TYPE"], key["DIFFERENCE"], nuc["BRANCHING"]); id++; } //add the parent if there is one else { //check for repeats bool repeatNuc = matches.Tables["MATCHEDNUCLIDES"].AsEnumerable().Any(row => (string)nuc["NAME"] == row.Field <string>("NUCLIDE")); bool repeat = matches.Tables["MATCHEDNUCLIDES"].AsEnumerable().Any(row => (string)nuc["NAME"] == row.Field <string>("NUCLIDE") && (double)nuc["HALF_LIFE"] == row.Field <double>("HALF_LIFE") && (string)nuc["HALF_LIFE_UNIT"] == row.Field <string>("HALF_LIFE_UNIT")); //only add parents who's daughters have shorter half lives double parentHalfLife = ICRPData.ConvertHalfLifeToDays((string)nuc["PARENT_HALF_LIFE_UNIT"], (double)nuc["PARENT_HALF_LIFE"]); double daughterHalfLife = ICRPData.ConvertHalfLifeToDays((string)nuc["HALF_LIFE_UNIT"], (double)nuc["HALF_LIFE"]); if (PDhalfLifeLimit * parentHalfLife > daughterHalfLife) { string nucName = nuc["NAME"].ToString(); //check for repeats if (!repeat) { matches.Tables["MATCHEDNUCLIDES"].Rows.Add(id, nucName, 1 * score, nuc["NAME"], nuc["HALF_LIFE"], nuc["HALF_LIFE_UNIT"]); id++; } matches.Tables["MATCHEDNUCLIDES"].Rows.Add(id, nuc["PARENT"], 1 * score, nuc["NAME"], nuc["PARENT_HALF_LIFE"], nuc["PARENT_HALF_LIFE_UNIT"]); id++; } //add the others else if (!repeatNuc) { //also add the daughter matches.Tables["MATCHEDNUCLIDES"].Rows.Add(id, nuc["NAME"], 1 * score, nuc["NAME"], nuc["HALF_LIFE"], nuc["HALF_LIFE_UNIT"]); id++; } } } }
/// <summary> /// Set the Nuclide matches where the energy in the libary is +/- the tolerance /// </summary> /// <param name="energy">Energy of the line in keV</param> /// <param name="elapsed">elapsed time in days</param> /// <param name="tol">Energy tolerance</param> public void SetNuclides(double energy, TimeSpan elapsedWait, double tol = 1, PeakType type = PeakType.Photopeak) { if (lib == null) { throw new NullReferenceException("Library is not defined"); } double tolerance = tol; //convert the time span to days double elapsed = elapsedWait.TotalDays; //cut down on redundant calls by only doing this the first time this method is called. if (type == PeakType.Photopeak) { //get escape peaks DataRow[] SE = MatchSE(energy, tolerance); //check if this is a single escape peak if (SE.Length > 0) { foreach (DataRow SEPeak in SE) { SetNuclides((double)SEPeak["ENERGY"], elapsedWait, (double)SEPeak["FWHM"], PeakType.SingleEscape); } } //check if this is a double escape peak DataRow[] DE = MatchDE(energy, tolerance); if (DE.Length > 0) { foreach (DataRow DEPeak in DE) { SetNuclides((double)DEPeak["ENERGY"], elapsedWait, (double)DEPeak["FWHM"], PeakType.DoubleEscape); } } } //check for sum peaks MatchRandom(energy, tolerance); //get the matched nuclides string expression = "ENERGY > " + (energy - tolerance).ToString() + " AND ENERGY < " + (energy + tolerance).ToString() + " AND YIELD > " + yeildLimit; DataTable tmatches = lib.Select("PHOTONS", expression); //DataTable tmatches = lib.Tables["PHOTONS"].Select(expression).CopyToDataTable(); tmatches.Columns.Add("DIFFERENCE", typeof(double), energy + "- ENERGY"); //generate a string to fill the MATCHEDNUCLIDES table StringBuilder nucList = new StringBuilder(); foreach (DataRow row in tmatches.Rows) { nucList.Append("'" + row["NAME"] + "',"); } nucList.Remove(nucList.Length - 1, 1); //get the data and fill the table DataTable nucs = lib.Select("NUCLIDES", "NAME IN (" + nucList.ToString() + ")"); int id = matches.Tables["MATCHEDNUCLIDES"].Rows.Count; foreach (DataRow nuc in nucs.Rows) { double score = 1; //Get the basis line DataRow basis = tmatches.Select("NAME = '" + nuc["NAME"] + "'")[0]; //if it is a single escape peak if (type == PeakType.SingleEscape) { score *= (double)basis["YIELD"] / 100; score *= ScoreHalfLife((double)nuc["HALF_LIFE"], (string)nuc["HALF_LIFE_UNIT"], elapsed); score *= ScoreDeviation(basis, tolerance); if (score < scoreLimit) { continue; } matches.Tables["MATCHEDNUCLIDES"].Rows.Add(id, "S.E.", 1 * score, nuc["NAME"], nuc["HALF_LIFE"], nuc["HALF_LIFE_UNIT"], basis["ENERGY"], basis["YIELD"], type.ToString(), basis["DIFFERENCE"], nuc["BRANCHING"]); id++; } //if it is a double escape peak else if (type == PeakType.DoubleEscape) { score *= (double)basis["YIELD"] / 100; score *= ScoreHalfLife((double)nuc["HALF_LIFE"], (string)nuc["HALF_LIFE_UNIT"], elapsed); score *= ScoreDeviation(basis, tolerance); if (score < scoreLimit) { continue; } matches.Tables["MATCHEDNUCLIDES"].Rows.Add(id, "D.E.", 1 * score, nuc["NAME"], nuc["HALF_LIFE"], nuc["HALF_LIFE_UNIT"], basis["ENERGY"], basis["YIELD"], type.ToString(), basis["DIFFERENCE"], nuc["BRANCHING"]); id++; } //if it is a sum peak else if (type == PeakType.Sum) { matches.Tables["MATCHEDNUCLIDES"].Rows.Add(id, "S.E.", 1 * score, nuc["NAME"], nuc["HALF_LIFE"], nuc["HALF_LIFE_UNIT"], basis["ENERGY"], basis["YIELD"], basis["TYPE"], basis["DIFFERENCE"], nuc["BRANCHING"]); } //when there is no parent else if (nuc["PARENT"].Equals("NONE")) { //include the yeild weight score *= (double)basis["YIELD"] / 100; score *= ScoreHalfLife((double)nuc["HALF_LIFE"], (string)nuc["HALF_LIFE_UNIT"], elapsed); score *= ScoreDeviation(basis, tolerance); if (score < scoreLimit) { continue; } matches.Tables["MATCHEDNUCLIDES"].Rows.Add(id, nuc["NAME"], 1 * score, nuc["NAME"], nuc["HALF_LIFE"], nuc["HALF_LIFE_UNIT"], basis["ENERGY"], basis["YIELD"], basis["TYPE"], basis["DIFFERENCE"], nuc["BRANCHING"]); id++; } //add a decay chain if there is one else if (nuc["PARENT"].ToString().Contains('+')) { //get the first nuclide DataTable topNucs = lib.Select("NUCLIDES", "NAME = '" + nuc["PARENT"].ToString().Trim('+') + "' AND PARENT = '" + nuc["PARENT"].ToString() + "'"); if (topNucs == null || topNucs.Rows.Count < 1) { continue; } //it's alwasys the first row DataRow topNuc = topNucs.Rows[0]; score *= ScoreHalfLife((double)topNuc["HALF_LIFE"], (string)topNuc["HALF_LIFE_UNIT"], elapsed); score *= ScoreDeviation(basis, tolerance); basis["YIELD"] = (double)basis["YIELD"] * (double)nuc["BRANCHING"]; score *= (double)basis["YIELD"] / 100; if (score < scoreLimit) { continue; } matches.Tables["MATCHEDNUCLIDES"].Rows.Add(id, topNuc["PARENT"], 1 * score, nuc["NAME"], topNuc["HALF_LIFE"], topNuc["HALF_LIFE_UNIT"], basis["ENERGY"], basis["YIELD"], basis["TYPE"], basis["DIFFERENCE"], nuc["BRANCHING"]); id++; } //add the parent if there is one else { //only add parents who's daughters have shorter half lives double parentHalfLife = ICRPData.ConvertHalfLifeToDays((string)nuc["PARENT_HALF_LIFE_UNIT"], (double)nuc["PARENT_HALF_LIFE"]); double daughterHalfLife = ICRPData.ConvertHalfLifeToDays((string)nuc["HALF_LIFE_UNIT"], (double)nuc["HALF_LIFE"]); //skip parents with shorter half lives and already existing rows if (PDhalfLifeLimit * parentHalfLife > daughterHalfLife) { //include the yeild weight score *= (double)basis["YIELD"] / 100; score *= ScoreHalfLife((double)nuc["PARENT_HALF_LIFE"], (string)nuc["PARENT_HALF_LIFE_UNIT"], elapsed); score *= ScoreDeviation(basis, tolerance); if (score < scoreLimit) { continue; } //serarch for repeats if (!matches.Tables["MATCHEDNUCLIDES"].AsEnumerable().Any(row => (string)nuc["NAME"] == row.Field <string>("NUCLIDE") && (double)nuc["HALF_LIFE"] == row.Field <double>("HALF_LIFE") && (string)nuc["HALF_LIFE_UNIT"] == row.Field <string>("HALF_LIFE_UNIT"))) { matches.Tables["MATCHEDNUCLIDES"].Rows.Add(id, nuc["NAME"], 1 * score, nuc["NAME"], nuc["HALF_LIFE"], nuc["HALF_LIFE_UNIT"], basis["ENERGY"], basis["YIELD"], basis["TYPE"], basis["DIFFERENCE"], nuc["BRANCHING"]); id++; } matches.Tables["MATCHEDNUCLIDES"].Rows.Add(id, nuc["PARENT"], 1 * score, nuc["NAME"], nuc["PARENT_HALF_LIFE"], nuc["PARENT_HALF_LIFE_UNIT"], basis["ENERGY"], (double)basis["YIELD"] * (double)nuc["BRANCHING"], basis["TYPE"], basis["DIFFERENCE"], nuc["BRANCHING"]); id++; } //add just the match avoiding repeats else if (!matches.Tables["MATCHEDNUCLIDES"].AsEnumerable().Any(row => (string)nuc["NAME"] == row.Field <string>("NAME"))) { score *= (double)basis["YIELD"] / 100; score *= ScoreHalfLife((double)nuc["HALF_LIFE"], (string)nuc["HALF_LIFE_UNIT"], elapsed); score *= ScoreDeviation(basis, tolerance); if (score < scoreLimit) { continue; } matches.Tables["MATCHEDNUCLIDES"].Rows.Add(id, nuc["NAME"], 1 * score, nuc["NAME"], nuc["HALF_LIFE"], nuc["HALF_LIFE_UNIT"], basis["ENERGY"], basis["YIELD"], basis["TYPE"], basis["DIFFERENCE"], nuc["BRANCHING"]); id++; } } } }