private void AddNode(TreeNode tn, Explanation e) { TreeNode node = new TreeNode(e.GetValue().ToString("G4") + " " + e.GetDescription()); if (null == tn) { treeExplain.Nodes.Add(node); } else { tn.Nodes.Add(node); } Explanation[] kids = e.GetDetails(); if (kids != null && kids.Length > 0) { for (int i = 0; i < kids.Length; i++) { AddNode(node, kids[i]); } } }
/// <summary> Assert that an explanation has the expected score, and optionally that its /// sub-details max/sum/factor match to that score. /// /// </summary> /// <param name="q">String representation of the query for assertion messages /// </param> /// <param name="doc">Document ID for assertion messages /// </param> /// <param name="score">Real score value of doc with query q /// </param> /// <param name="deep">indicates whether a deep comparison of sub-Explanation details should be executed /// </param> /// <param name="expl">The Explanation to match against score /// </param> public static void VerifyExplanation(System.String q, int doc, float score, bool deep, Explanation expl) { float value_Renamed = expl.GetValue(); Assert.AreEqual(score, value_Renamed, EXPLAIN_SCORE_TOLERANCE_DELTA, q + ": score(doc=" + doc + ")=" + score + " != explanationScore=" + value_Renamed + " Explanation: " + expl); if (!deep) return ; Explanation[] detail = expl.GetDetails(); if (detail != null) { if (detail.Length == 1) { // simple containment, no matter what the description says, // just verify contained expl has same score VerifyExplanation(q, doc, score, deep, detail[0]); } else { // explanation must either: // - end with one of: "product of:", "sum of:", "max of:", or // - have "max plus <x> times others" (where <x> is float). float x = 0; System.String descr = expl.GetDescription().ToLower(); bool productOf = descr.EndsWith("product of:"); bool sumOf = descr.EndsWith("sum of:"); bool maxOf = descr.EndsWith("max of:"); bool maxTimesOthers = false; if (!(productOf || sumOf || maxOf)) { // maybe 'max plus x times others' int k1 = descr.IndexOf("max plus "); if (k1 >= 0) { k1 += "max plus ".Length; int k2 = descr.IndexOf(" ", k1); try { x = SupportClass.Single.Parse(descr.Substring(k1, (k2) - (k1)).Trim()); if (descr.Substring(k2).Trim().Equals("times others of:")) { maxTimesOthers = true; } } catch (System.FormatException) { } } } Assert.IsTrue(productOf || sumOf || maxOf || maxTimesOthers, q + ": multi valued explanation description=\"" + descr + "\" must be 'max of plus x times others' or end with 'product of'" + " or 'sum of:' or 'max of:' - " + expl); float sum = 0; float product = 1; float max = 0; for (int i = 0; i < detail.Length; i++) { float dval = detail[i].GetValue(); VerifyExplanation(q, doc, dval, deep, detail[i]); product *= dval; sum += dval; max = System.Math.Max(max, dval); } float combined = 0; if (productOf) { combined = product; } else if (sumOf) { combined = sum; } else if (maxOf) { combined = max; } else if (maxTimesOthers) { combined = max + x * (sum - max); } else { Assert.IsTrue(false, "should never get here!"); } Assert.AreEqual(combined, value_Renamed, EXPLAIN_SCORE_TOLERANCE_DELTA, q + ": actual subDetails combined==" + combined + " != value=" + value_Renamed + " Explanation: " + expl); } } }