/////////////////////////////////////////////////////////////////////////////// // Methods for doing main class job // /////////////////////////////////////////////////////////////////////////////// #region METHODS /// <summary> /// This method exports the fixations of the given <see cref="SampleType"/> /// to the given File including AOI information. /// </summary> /// <param name="options">An <see cref="ExportOptions"/> with options for the file export.</param> /// <param name="type">The <see cref="SampleType"/> to be exported.</param> private void Export(ExportOptions options, SampleType type) { string tableName = string.Empty; string fileName = string.Empty; DataTable dataTable = new DataTable(); switch (type) { case SampleType.Gaze: tableName = "GazeFixations"; dataTable = Document.ActiveDocument.DocDataSet.GazeFixations; fileName = options.GazeFileName; break; case SampleType.Mouse: tableName = "MouseFixations"; dataTable = Document.ActiveDocument.DocDataSet.MouseFixations; fileName = options.MouseFileName; break; } bool unknownSubjectFound = false; string missingSubjectName = string.Empty; using (StreamWriter exportFileWriter = new StreamWriter(fileName)) { // Write Documentation exportFileWriter.WriteLine("# File: " + Path.GetFileName(fileName)); exportFileWriter.WriteLine("# Created: " + DateTime.Today.Date.ToLongDateString() + "," + DateTime.Now.ToLongTimeString()); exportFileWriter.WriteLine("# with: " + Application.ProductName + " Version: " + Document.ActiveDocument.ExperimentSettings.OgamaVersion.ToString(3)); exportFileWriter.WriteLine("# Contents: " + tableName + " table."); exportFileWriter.WriteLine("# Applies to Projekt:" + Document.ActiveDocument.ExperimentSettings.Name); exportFileWriter.WriteLine("#"); if (options.ExportFixations) { // Write Column Names foreach (DataColumn dataColumn in dataTable.Columns) { exportFileWriter.Write(dataColumn.Caption); exportFileWriter.Write("\t"); } } else { // We should export saccades which need some other column descriptions exportFileWriter.Write("SubjectName"); exportFileWriter.Write("\t"); exportFileWriter.Write("TrialID"); exportFileWriter.Write("\t"); exportFileWriter.Write("TrialSequence"); exportFileWriter.Write("\t"); exportFileWriter.Write("CountInTrial"); exportFileWriter.Write("\t"); exportFileWriter.Write("StartTime"); exportFileWriter.Write("\t"); exportFileWriter.Write("Duration"); exportFileWriter.Write("\t"); exportFileWriter.Write("Distance"); exportFileWriter.Write("\t"); exportFileWriter.Write("Velocity"); exportFileWriter.Write("\t"); exportFileWriter.Write("Validity"); exportFileWriter.Write("\t"); } if (options.ExportSubjectDetails) { exportFileWriter.Write("SubjectCategory"); exportFileWriter.Write("\t"); exportFileWriter.Write("Age"); exportFileWriter.Write("\t"); exportFileWriter.Write("Sex"); exportFileWriter.Write("\t"); exportFileWriter.Write("Handedness"); exportFileWriter.Write("\t"); exportFileWriter.Write("Comments"); exportFileWriter.Write("\t"); DataTable customParams = Document.ActiveDocument.DocDataSet.ParamsAdapter.GetData(); foreach (DataRow paramRow in customParams.Rows) { exportFileWriter.Write(paramRow["Param"]); exportFileWriter.Write("\t"); } } if (options.ExportTrialDetails) { exportFileWriter.Write("Trial Name"); exportFileWriter.Write("\t"); exportFileWriter.Write("Trial Category"); exportFileWriter.Write("\t"); exportFileWriter.Write("SlideNr"); exportFileWriter.Write("\t"); } if (options.ExportAOIDetails) { if (options.ExportFixations) { exportFileWriter.Write("AOI"); exportFileWriter.Write("\t"); exportFileWriter.Write("AOI group"); exportFileWriter.Write("\t"); } else { exportFileWriter.Write("Saccade Target AOI"); exportFileWriter.Write("\t"); exportFileWriter.Write("Saccade Target AOI group"); exportFileWriter.Write("\t"); } } exportFileWriter.WriteLine(); int trialID = -1; int lastTrialID = -1; string subjectName = string.Empty; string lastsubjectName = "LastSubjectKLSMA"; DataView trialsAOIsView = new DataView(Document.ActiveDocument.DocDataSet.AOIs); SubjectsData subjectData = new SubjectsData(); Dictionary<string, string> subjectParams = new Dictionary<string, string>(); // Sort fixation data DataView fixationsView = new DataView(dataTable); fixationsView.Sort = "SubjectName, TrialSequence, CountInTrial ASC"; VGElementCollection trialAOIs = new VGElementCollection(); string category = string.Empty; string trialName = string.Empty; PointF lastFixationCenter = PointF.Empty; long lastFixationEndTime = 0; int lastFixationDuration = 0; int countInTrial = 0; int slideNr = 0; List<long> slideStartTimes = new List<long>(); foreach (DataRowView dataRow in fixationsView) { trialID = (int)dataRow["TrialID"]; // Skip trials that are not selected. if (!options.CheckedTrialIDs.Contains(trialID)) { continue; } int trialSequence = (int)dataRow["TrialSequence"]; long startTime = (long)dataRow["StartTime"]; int length = (int)dataRow["Length"]; float posX = Convert.ToSingle(dataRow["PosX"]); float posY = Convert.ToSingle(dataRow["PosY"]); PointF fixationCenter = new PointF(posX, posY); subjectName = dataRow["SubjectName"].ToString(); if (!options.CheckedSubjects.Contains(subjectName)) { continue; } if (options.ExportSubjectDetails) { if (subjectName != lastsubjectName) { subjectData = new SubjectsData(); DataTable subjectsTable = Document.ActiveDocument.DocDataSet.SubjectsAdapter.GetDataBySubject(subjectName); if (subjectsTable.Rows.Count == 0) { unknownSubjectFound = true; missingSubjectName = subjectName; continue; } // Parse subject information if (!subjectsTable.Rows[0].IsNull("Age")) { subjectData.Age = (int)subjectsTable.Rows[0]["Age"]; } subjectData.Category = subjectsTable.Rows[0]["Category"].ToString(); subjectData.Comments = subjectsTable.Rows[0]["Comments"].ToString(); subjectData.Handedness = subjectsTable.Rows[0]["Handedness"].ToString(); subjectData.Sex = subjectsTable.Rows[0]["Sex"].ToString(); // Parse custom subject information subjectParams.Clear(); DataTable subjectParamsTable = Document.ActiveDocument.DocDataSet.SubjectParametersAdapter.GetDataBySubject(subjectName); foreach (DataRow paramRow in subjectParamsTable.Rows) { subjectParams.Add(paramRow["Param"].ToString(), paramRow["ParamValue"].ToString()); } lastsubjectName = subjectName; } } if (trialID != lastTrialID) { slideStartTimes.Clear(); DataTable trialEvents = Document.ActiveDocument.DocDataSet.TrialEventsAdapter.GetDataBySubjectNameTrialSequenceButOnlySlideChangeResponses(subjectName, trialSequence); foreach (DataRow slideEventRow in trialEvents.Rows) { slideStartTimes.Add((long)slideEventRow["EventTime"]); } countInTrial = 0; slideNr = 0; if (options.ExportTrialDetails || options.ExportAOIDetails) { DataTable trialTable = Document.ActiveDocument.DocDataSet.TrialsAdapter.GetDataBySubjectAndTrialID(subjectName, trialID); if (trialTable.Rows.Count > 0) { category = trialTable.Rows[0]["Category"].ToString(); trialName = trialTable.Rows[0]["TrialName"].ToString(); } string filter = "TrialID=" + trialID + string.Empty; trialsAOIsView.RowFilter = filter; lastTrialID = trialID; trialAOIs.Clear(); foreach (DataRowView row in trialsAOIsView) { string strPtList = row["ShapePts"].ToString(); string aoiType = row["ShapeType"].ToString(); string aoiName = row["ShapeName"].ToString(); string shapeGroup = row["ShapeGroup"].ToString(); VGElement aoi = Queries.GetVGElementFromDatabase(aoiType, aoiName, shapeGroup, strPtList); trialAOIs.Add(aoi); } } } if (slideStartTimes.Count > (slideNr + 1) && startTime > slideStartTimes[slideNr]) { slideNr++; } if (options.ExportFixations) { // Write fixation table content foreach (object cellValue in dataRow.Row.ItemArray) { exportFileWriter.Write(cellValue.ToString()); exportFileWriter.Write("\t"); } } else { if (countInTrial != 0) { // we should export saccades exportFileWriter.Write(subjectName); exportFileWriter.Write("\t"); exportFileWriter.Write(trialID); exportFileWriter.Write("\t"); exportFileWriter.Write(trialSequence); exportFileWriter.Write("\t"); exportFileWriter.Write(countInTrial); exportFileWriter.Write("\t"); exportFileWriter.Write(lastFixationEndTime); exportFileWriter.Write("\t"); int duration = (int)(startTime - lastFixationEndTime); exportFileWriter.Write(duration); exportFileWriter.Write("\t"); float distance = VGPolyline.Distance(lastFixationCenter, fixationCenter); exportFileWriter.Write(distance); exportFileWriter.Write("\t"); exportFileWriter.Write(distance / duration); exportFileWriter.Write("\t"); int validity = 0; if (duration > lastFixationDuration) { validity = -1; } exportFileWriter.Write(validity); exportFileWriter.Write("\t"); } } if (options.ExportSubjectDetails) { if (options.ExportFixations || countInTrial != 0) { // Write subject information exportFileWriter.Write(subjectData.Category); exportFileWriter.Write("\t"); exportFileWriter.Write(subjectData.Age); exportFileWriter.Write("\t"); exportFileWriter.Write(subjectData.Sex); exportFileWriter.Write("\t"); exportFileWriter.Write(subjectData.Handedness); exportFileWriter.Write("\t"); exportFileWriter.Write(subjectData.Comments); exportFileWriter.Write("\t"); foreach (string paramValue in subjectParams.Values) { exportFileWriter.Write(paramValue); exportFileWriter.Write("\t"); } } } if (options.ExportTrialDetails) { if (options.ExportFixations || countInTrial != 0) { // Write trial information exportFileWriter.Write(trialName != string.Empty ? trialName : "NamelessTrial"); exportFileWriter.Write("\t"); exportFileWriter.Write(category); exportFileWriter.Write("\t"); exportFileWriter.Write(slideNr); exportFileWriter.Write("\t"); } } if (options.ExportAOIDetails) { if (options.ExportFixations || countInTrial != 0) { // Retrieve AOI position string hittedAOIName = string.Empty; string hittedAOIGroup = string.Empty; List<string[]> hittedAOIs = Statistics.Statistic.FixationHitsAOI(trialAOIs, dataRow); if (hittedAOIs.Count == 0) { hittedAOIName = "nowhere"; hittedAOIGroup = "nowhere"; } foreach (string[] aoi in hittedAOIs) { // Concatenate hitted AOIs hittedAOIName += aoi[0] + "#"; hittedAOIGroup += aoi[1] + "#"; } if (hittedAOIs.Count > 0) { hittedAOIName = hittedAOIName.Substring(0, hittedAOIName.Length - 1); hittedAOIGroup = hittedAOIGroup.Substring(0, hittedAOIGroup.Length - 1); } exportFileWriter.Write(hittedAOIName); exportFileWriter.Write("\t"); exportFileWriter.Write(hittedAOIGroup); exportFileWriter.Write("\t"); } } if (options.ExportFixations || countInTrial != 0) { // Write new line for next row. exportFileWriter.WriteLine(); } countInTrial++; lastFixationCenter = fixationCenter; lastFixationEndTime = startTime + length; lastFixationDuration = length; } } if (unknownSubjectFound) { string message = "At least one fixation of an subject that is not in the database anymore " + "was found. Subject: '" + missingSubjectName + "'" + Environment.NewLine + "Please re-run a complete fixation calculation for all subjects."; ExceptionMethods.ProcessMessage("Old subject fixations found", message); } ExceptionMethods.ProcessMessage("Export successful.", "Fixations were successfully exported to file"); }
/// <summary> /// Iterates selected trials and calculates the transition table. /// </summary> /// <param name="worker"> /// The <see cref="BackgroundWorker"/> /// </param> /// <param name="e"> /// A <see cref="DoWorkEventArgs"/> with the event data. /// </param> private void FillTransitionsWithData(BackgroundWorker worker, DoWorkEventArgs e) { DataTable aoiTable = Document.ActiveDocument.DocDataSet.AOIs; var trialsAOIs = new DataView(aoiTable); DataTable subjectsTable = Document.ActiveDocument.DocDataSet.SubjectsAdapter.GetData(); var trialAOIs = new VGElementCollection(); List<string> checkedSubjects = GetCheckedSubjects(this.trvTransitionsSubjects); if (this.rdbTransitionUseAOIGroups.Checked) { int aoiGroupCount = this.aoiGroups.Count; Array transitionMatrix = Array.CreateInstance(typeof(int), aoiGroupCount + 1, aoiGroupCount + 1); var groupIndexAssignment = new Dictionary<string, int>(); groupIndexAssignment.Add("nowhere", 0); for (int i = 0; i < aoiGroupCount; i++) { string aoiGroupEntry = this.aoiGroups[i]; groupIndexAssignment.Add(aoiGroupEntry, i + 1); } // Get selected trials var trialIDs = new List<int>(); foreach (TreeNode categoryNode in this.trvTrialsAOI.Nodes) { foreach (TreeNode trialNode in categoryNode.Nodes) { if (trialNode.Checked) { trialIDs.Add(Convert.ToInt32(trialNode.Name)); } } } // Iterate selected subjects foreach (DataRow subjectRow in subjectsTable.Rows) { string subjectName = subjectRow["SubjectName"].ToString(); if (checkedSubjects.Contains(subjectName)) { DataView fixations = null; if (this.btnEye.Checked) { fixations = new DataView(Document.ActiveDocument.DocDataSet.GazeFixationsAdapter.GetDataBySubject(subjectName)); } else if (this.btnMouse.Checked) { fixations = new DataView(Document.ActiveDocument.DocDataSet.MouseFixationsAdapter.GetDataBySubject(subjectName)); } string foregoingHittedAOIGroup = string.Empty; int foregoingTrialID = -1; foreach (DataRowView fixationRow in fixations) { var trialID = (int)fixationRow["TrialID"]; if (!trialIDs.Contains(trialID)) { continue; } if (trialID != foregoingTrialID) { trialsAOIs.RowFilter = "TrialID=" + trialID.ToString(); foregoingTrialID = trialID; trialAOIs.Clear(); foreach (DataRowView row in trialsAOIs) { string strPtList = row["ShapePts"].ToString(); string aoiType = row["ShapeType"].ToString(); string aoiName = row["ShapeName"].ToString(); string shapeGroup = row["ShapeGroup"].ToString(); VGElement aoi = Queries.GetVGElementFromDatabase(aoiType, aoiName, shapeGroup, strPtList); trialAOIs.Add(aoi); } } string hittedAOIName = string.Empty; string hittedAOIGroup = string.Empty; List<string[]> hittedAOIs = Statistic.FixationHitsAOI(trialAOIs, fixationRow); if (hittedAOIs.Count > 0) { // Take only first hitted AOI hittedAOIName = hittedAOIs[0][0]; hittedAOIGroup = hittedAOIs[0][1]; } if (foregoingHittedAOIGroup != string.Empty) { if (hittedAOIGroup == string.Empty) { hittedAOIGroup = "nowhere"; } int indexOfHittedGroup = groupIndexAssignment[hittedAOIGroup]; int indexOfForegoingGroup = groupIndexAssignment[foregoingHittedAOIGroup]; var oldEntry = (int)transitionMatrix.GetValue(indexOfForegoingGroup, indexOfHittedGroup); int newEntry = oldEntry + 1; transitionMatrix.SetValue(newEntry, indexOfForegoingGroup, indexOfHittedGroup); } foregoingHittedAOIGroup = hittedAOIGroup; } } } // Write transitionMatrix to dgv for (int i = transitionMatrix.GetLowerBound(0); i <= transitionMatrix.GetUpperBound(0); i++) { // Get a datagridview via asynchronous call. DataGridViewRow newRow = this.GetTransitionsDataGridViewRow(); if (i > 0) { newRow.Cells[0].Value = this.aoiGroups[i - 1]; } else { newRow.Cells[0].Value = "nowhere"; } for (int j = transitionMatrix.GetLowerBound(1); j <= transitionMatrix.GetUpperBound(1); j++) { newRow.Cells[j + 1].Value = transitionMatrix.GetValue(i, j); } } } else if (this.rdbTransitionsUseTrial.Checked) { trialAOIs.Clear(); trialsAOIs.RowFilter = "TrialID=" + e.Argument; foreach (DataRowView row in trialsAOIs) { string strPtList = row["ShapePts"].ToString(); string aoiType = row["ShapeType"].ToString(); string aoiName = row["ShapeName"].ToString(); string shapeGroup = row["ShapeGroup"].ToString(); VGElement aoi = Queries.GetVGElementFromDatabase(aoiType, aoiName, shapeGroup, strPtList); trialAOIs.Add(aoi); } var gazeFixations = new DataView(Document.ActiveDocument.DocDataSet.GazeFixationsAdapter.GetDataByTrialID((int)e.Argument)); var mouseFixations = new DataView(Document.ActiveDocument.DocDataSet.MouseFixationsAdapter.GetDataByTrialID((int)e.Argument)); string filterString = string.Empty; foreach (string subject in checkedSubjects) { filterString += "(SubjectName='" + subject + "') OR "; } filterString = filterString.Substring(0, filterString.Length - 4); gazeFixations.RowFilter = filterString; mouseFixations.RowFilter = filterString; Array transitionMatrix = null; if (this.btnEye.Checked) { transitionMatrix = Statistic.CreateTransitionMatrixForSingleAOIs(gazeFixations, trialAOIs); } else if (this.btnMouse.Checked) { transitionMatrix = Statistic.CreateTransitionMatrixForSingleAOIs(mouseFixations, trialAOIs); } // Write transitionMatrix to dgv for (int i = transitionMatrix.GetLowerBound(0); i <= transitionMatrix.GetUpperBound(0); i++) { // Get a datagridview via asynchronous call. DataGridViewRow newRow = this.GetTransitionsDataGridViewRow(); if (i > 0) { newRow.Cells[0].Value = trialAOIs[i - 1].Name; } else { newRow.Cells[0].Value = "nowhere"; } for (int j = transitionMatrix.GetLowerBound(1); j <= transitionMatrix.GetUpperBound(1); j++) { newRow.Cells[j + 1].Value = transitionMatrix.GetValue(i, j); } } } }