DataTable GraphSurveys_QOL(int patientId, DateTime baseDate) { MSKProstateQOLSurvey helper = new MSKProstateQOLSurvey(); // we could make GetSurveyTable a property that returns a DataView DataTable _surveyTable = helper.GetSurveys(patientId); //DataView surveyScores = helper.GetScores(_surveyTable); DataView surveyScores = helper.GetScores_Adjusted_ActiveSurvelliance(_surveyTable); DataTable efChartTable = InitChartTable(); DataTable ufChartTable = InitChartTable(); int count = surveyScores.Count; SurveyDa.BaselineScores baseline = SurveyDa.GetPhysicianBaselineScores(patientId, baseDate); for (int i = 0; i < count; i++) { DataRowView row = surveyScores[i]; DateTime surveyDate = (DateTime)row["SurveyDate"]; double yearsSinceBaseDate = (surveyDate - baseDate).Days / DAYS_PER_YEAR; Func <string, int?> getScore = s => row[s] == DBNull.Value ? null : (int?)row[s]; int?efScore = getScore("EF_Score"); int?ufScore = getScore("UF_Score"); if (efScore.HasValue) { AddDataPoint(efChartTable, yearsSinceBaseDate, efScore.Value); } if (ufScore.HasValue) { AddDataPoint(ufChartTable, yearsSinceBaseDate, ufScore.Value); } EFChart.Series["QOL_Scores"].Points.DataBind(efChartTable.DefaultView, "Years", "Score", "Tooltip=Score, Label=Score"); UFChart.Series["QOL_Scores"].Points.DataBind(ufChartTable.DefaultView, "Years", "Score", "Tooltip=Score, Label=Score"); } return(_surveyTable); }
// analyze post-rp survey data, return raw survey data DataTable AnalyzeSurveys(int patientId, DateTime rpDate) { MSKProstateQOLSurvey helper = new MSKProstateQOLSurvey(); // we could make GetSurveyTable a property that returns a DataView DataTable _surveyTable = helper.GetSurveys(patientId); DataView surveyScores = helper.GetScores(_surveyTable); DataTable efChartTable = InitChartTable(); DataTable ufChartTable = InitChartTable(); int count = surveyScores.Count; SurveyDa.BaselineScores baseline = SurveyDa.GetPhysicianBaselineScores(patientId, rpDate); BaselinePhysicianEFScore.Text = baseline.ErectileFunction.HasValue ? baseline.ErectileFunction.ToString() : "N/A"; BaselinePhysicianUFScore.Text = baseline.UrinaryFunction.HasValue ? baseline.UrinaryFunction.ToString() : "N/A"; bool foundPatientBaseline_EF = false; bool addedPatientBaseline_EF = false; bool foundPatientBaseline_UF = false; bool addedPatientBaseline_UF = false; int patientBaseline_efScore = 0; int patientBaseline_ufScore = 0; int?prevMinUrinaryScore = null; int?prevUrinaryScore = null; for (int i = 0; i < count; i++) { DataRowView row = surveyScores[i]; DateTime surveyDate = (DateTime)row["SurveyDate"]; double monthsSinceRP = (surveyDate - rpDate).Days / DAYS_PER_MONTH; //int roundedMonths = (int) Math.Round(monthsSinceRP, 0); double roundedMonths = monthsSinceRP; bool physicianReported = (bool)row["PhysicianReported"]; // display scores as a fraction Func <int, string, string> frac = (x, f) => x + " / " + row[f]; Func <string, int?> getScore = s => row[s] == DBNull.Value ? null : (int?)row[s]; int?efScore = getScore("EF_Score"); int?ufScore = getScore("UF_Score"); int?qolScore = getScore("GH_Score"); int?bowelScore = getScore("BF_Score"); // add only the most recent pre-rp survey to the chart datasources if (surveyDate <= rpDate) { if (efScore.HasValue) { patientBaseline_efScore = efScore.Value; foundPatientBaseline_EF = true; if (count == 1) { BaselinePatientEFScore.Text = frac(patientBaseline_efScore, "EF_Possible") + " " + GetErectileStatus(patientBaseline_efScore); AddDataPoint(efChartTable, 0, patientBaseline_efScore); } } if (ufScore.HasValue) { patientBaseline_ufScore = ufScore.Value; foundPatientBaseline_UF = true; if (count == 1) { BaselinePatientUFScore.Text = frac(patientBaseline_ufScore, "UF_Possible") + " " + GetUrinaryStatus(patientBaseline_ufScore); AddDataPoint(ufChartTable, 0, patientBaseline_ufScore); } } continue; } else { if (foundPatientBaseline_EF && !addedPatientBaseline_EF) { BaselinePatientEFScore.Text = frac(patientBaseline_efScore, "EF_Possible") + " " + GetErectileStatus(patientBaseline_efScore); AddDataPoint(efChartTable, 0, patientBaseline_efScore); addedPatientBaseline_EF = true; } if (foundPatientBaseline_UF && !addedPatientBaseline_UF) { BaselinePatientUFScore.Text = frac(patientBaseline_ufScore, "UF_Possible") + " " + GetUrinaryStatus(patientBaseline_ufScore); AddDataPoint(ufChartTable, 0, patientBaseline_ufScore); addedPatientBaseline_UF = true; } } if (efScore.HasValue) { AddDataPoint(efChartTable, roundedMonths, efScore.Value); } if (ufScore.HasValue) { AddDataPoint(ufChartTable, roundedMonths, ufScore.Value); } // conditionally build status messages Action <Label, string, Func <int, string>, HtmlContainerControl> status = (l, s, f, bullet) => { object obj = row[s]; if (obj != DBNull.Value) { l.Text = "Current: " + f((int)obj); } else if (bullet != null) { bullet.Visible = false; } }; if (i == count - 1) { // handle current if (efScore.HasValue) { CurrentEFScore.Text = frac(efScore.Value, "EF_Possible") + " " + GetErectileStatus(efScore.Value); } if (ufScore.HasValue) { CurrentUFScore.Text = frac(ufScore.Value, "UF_Possible") + " " + GetUrinaryStatus(ufScore.Value); } if (bowelScore.HasValue) { CurrentBFScore.Text = GetBowelSymptoms(bowelScore.Value); } if (qolScore.HasValue) { CurrentGeneralScore.Text = frac(qolScore.Value, "GH_Possible"); } status(CurrentPenetrationStatus, "PenetrationResponse", GetPenetrationMessage, CurrentPenetrationBullet); status(CurrentPadStatus, "PadResponse", GetPadMessage, PadStatusBullet); } // clear alerts if conditions improve // erectile alerts if (efScore.HasValue) { if (efScore < 22) { erectileAlerts.Add(surveyDate); } else { erectileAlerts.Clear(); } } // urinary alerts // handle max urinary score if (ufScore.HasValue) { if (i > 0 && prevMinUrinaryScore.HasValue) { if ((monthsSinceRP > 12 && ufScore <= prevMinUrinaryScore.Value - 3) || (monthsSinceRP <= 12 && ufScore < prevMinUrinaryScore.Value)) { urinaryDeclineAlerts.Add(surveyDate); } else if (prevUrinaryScore.HasValue && ufScore > prevUrinaryScore) { urinaryDeclineAlerts.Clear(); } } if (!prevMinUrinaryScore.HasValue || ufScore < prevMinUrinaryScore.Value) { prevMinUrinaryScore = ufScore; } prevUrinaryScore = ufScore; } // qol alerts if (qolScore.HasValue) { if (qolScore < 6) { qolAlerts.Add(surveyDate); } else { qolAlerts.Clear(); } } // pad alerts object padObj = row["PadResponse"]; if (padObj != DBNull.Value && surveyDate > rpDate.AddYears(1)) { if (3 <= (int)padObj) { padAlerts.Add(surveyDate); } else { padAlerts.Clear(); } } // bowel alerts object bowelHabitObj = row["HabitResponse"]; object bowelEnjoymentObj = row["EnjoymentResponse"]; if ((bowelHabitObj != DBNull.Value && 3 <= (int)bowelHabitObj) || (bowelEnjoymentObj != DBNull.Value && 3 <= (int)bowelEnjoymentObj)) { bowelAlerts.Add(surveyDate); } else if (bowelHabitObj != DBNull.Value && bowelEnjoymentObj != DBNull.Value && 2 >= (int)bowelHabitObj && 2 >= (int)bowelEnjoymentObj) { bowelAlerts.Clear(); } } UFChart.DataSource = ufChartTable; EFChart.DataSource = efChartTable; /* * List<int> months = new List<int>() { 0, 3, 6, 9, 12, 15, 18, 21, 24, 36, 48 }; * var ranges = GenerateRanges(months); * * DataTable ufTableFiltered = FilterChartDataPoints(ufChartTable, ranges); * DataTable efTableFiltered = FilterChartDataPoints(efChartTable, ranges); * * UFChart.DataSource = ufTableFiltered; * EFChart.DataSource = efTableFiltered; * * showUrinaryChart = ufTableFiltered.Rows.Count > 1; * showErectileChart = efTableFiltered.Rows.Count > 1; */ showUrinaryChart = ufChartTable.Rows.Count > 1; showErectileChart = efChartTable.Rows.Count > 1; return(_surveyTable); }
// a cut-down version of ProstateQOLResults.AnalyzeSurveys(...), // which is tightly-coupled with the display for the associated report private void AnalyzeSurveys(int patientId, DateTime rpDate) { MSKProstateQOLSurvey helper = new MSKProstateQOLSurvey(); DataTable surveyTable = helper.GetSurveys(patientId); DataView surveyScores = helper.GetScores(surveyTable); int count = surveyScores.Count; int patientBaseline_efScore = 0; int patientBaseline_ufScore = 0; bool foundPatientBaseline_EF = false; bool addedPatientBaseline_EF = false; bool foundPatientBaseline_UF = false; bool addedPatientBaseline_UF = false; int?prevMinUrinaryScore = null; int?prevUrinaryScore = null; for (int i = 0; i < count; i++) { DataRowView row = surveyScores[i]; DateTime surveyDate = (DateTime)row["SurveyDate"]; double monthsSinceRP = (surveyDate - rpDate).Days / DAYS_PER_MONTH; //int roundedMonths = (int) Math.Round(monthsSinceRP, 0); double roundedMonths = monthsSinceRP; Func <string, int?> getScore = s => row[s] == DBNull.Value ? null : (int?)row[s]; int?efScore = getScore("EF_Score"); int?ufScore = getScore("UF_Score"); int?qolScore = getScore("GH_Score"); int?bowelScore = getScore("BF_Score"); // add only the most recent pre-rp survey to the chart datasources if (surveyDate <= rpDate) { if (efScore.HasValue) { patientBaseline_efScore = efScore.Value; foundPatientBaseline_EF = true; if (count == 1) { AddDataPoint(efChartTable, 0, patientBaseline_efScore); } } if (ufScore.HasValue) { patientBaseline_ufScore = ufScore.Value; foundPatientBaseline_UF = true; if (count == 1) { AddDataPoint(ufChartTable, 0, patientBaseline_ufScore); } } continue; } else { if (foundPatientBaseline_EF && !addedPatientBaseline_EF) { AddDataPoint(efChartTable, 0, patientBaseline_efScore); addedPatientBaseline_EF = true; } if (foundPatientBaseline_UF && !addedPatientBaseline_UF) { AddDataPoint(ufChartTable, 0, patientBaseline_ufScore); addedPatientBaseline_UF = true; } } if (efScore.HasValue) { AddDataPoint(efChartTable, roundedMonths, efScore.Value); } if (ufScore.HasValue) { AddDataPoint(ufChartTable, roundedMonths, ufScore.Value); } // clear alerts if conditions improve // erectile alerts if (efScore.HasValue) { if (efScore < 22) { erectileAlerts.Add(surveyDate); } else { erectileAlerts.Clear(); } } // urinary alerts // handle max urinary score if (ufScore.HasValue) { if (i > 0 && prevMinUrinaryScore.HasValue) { if ((monthsSinceRP > 12 && ufScore <= prevMinUrinaryScore.Value - 3) || (monthsSinceRP <= 12 && ufScore < prevMinUrinaryScore.Value)) { urinaryDeclineAlerts.Add(surveyDate); } else if (prevUrinaryScore.HasValue && ufScore > prevUrinaryScore) { urinaryDeclineAlerts.Clear(); } } if (!prevMinUrinaryScore.HasValue || ufScore < prevMinUrinaryScore.Value) { prevMinUrinaryScore = ufScore; } prevUrinaryScore = ufScore; } // qol alerts if (qolScore.HasValue) { if (qolScore < 6) { qolAlerts.Add(surveyDate); } else { qolAlerts.Clear(); } } // pad alerts object padObj = row["PadResponse"]; if (padObj != DBNull.Value && surveyDate > rpDate.AddYears(1)) { if (3 <= (int)padObj) { padAlerts.Add(surveyDate); } else { padAlerts.Clear(); } } // bowel alerts object bowelHabitObj = row["HabitResponse"]; object bowelEnjoymentObj = row["EnjoymentResponse"]; if ((bowelHabitObj != DBNull.Value && 3 <= (int)bowelHabitObj) || (bowelEnjoymentObj != DBNull.Value && 3 <= (int)bowelEnjoymentObj)) { bowelAlerts.Add(surveyDate); } else if (bowelHabitObj != DBNull.Value && bowelEnjoymentObj != DBNull.Value && 2 >= (int)bowelHabitObj && 2 >= (int)bowelEnjoymentObj) { bowelAlerts.Clear(); } } /* * List<int> months = new List<int>() { 0, 3, 6, 9, 12, 15, 18, 21, 24, 36, 48 }; * var ranges = GenerateRanges(months); * * ufChartTable = FilterChartDataPoints(ufChartTable, ranges); * efChartTable = FilterChartDataPoints(efChartTable, ranges); */ }