/// <summary> /// The <see cref="ITracker.GazeDataChanged"/> event handler. /// Calculates the new sampling data from the trackers format. /// Updates the live viewers cursors and send a /// <see cref="NewRawDataAvailable"/> message to write the /// data into the database. /// </summary> /// <param name="sender"> /// Source of the event. /// </param> /// <param name="e"> /// A <see cref="GazeDataChangedEventArgs"/> with the event data. /// </param> public void TrackerGazeDataChanged(object sender, GazeDataChangedEventArgs e) { // Save current timestamp lock (this.timeLock) { this.lastTimeStamp = e.Gazedata.Time; } if (this.currentTrial == null) { return; } // Create a new RawData object var newRawData = new RawData { SubjectName = this.currentTracker.Subject.SubjectName, GazePosX = e.Gazedata.GazePosX, GazePosY = e.Gazedata.GazePosY }; newRawData = ModifyGazeDataWhenBetweenZeroAndOne(newRawData); newRawData.PupilDiaX = e.Gazedata.PupilDiaX; newRawData.PupilDiaY = e.Gazedata.PupilDiaY; long gazeTime = e.Gazedata.Time - this.recordingStarttime; newRawData.Time = gazeTime; newRawData.TrialSequence = this.trialSequenceCounter; // Retrieve mouse position, this is already in SCREEN COORDINATES PointF? newMousePos = this.GetMousePosition(); if (this.currentSlide.MouseCursorVisible && newMousePos != null) { newRawData.MousePosX = newMousePos.Value.X + this.xScrollOffset; newRawData.MousePosY = newMousePos.Value.Y + this.yScrollOffset; } // Update gaze cursor with reduced update rate // if (_counter % REDUCING_COUNT == 0) if (newRawData.GazePosX != null && newRawData.GazePosY != null) { var newCursorPos = new PointF(newRawData.GazePosX.Value, newRawData.GazePosY.Value); if (this.smoothing) { if (this.PointsArNear(newCursorPos, this.currentGazeCursorCenter)) { this.numberOfSamplesInRegion++; this.sumOfSamplesInRegion.X += newCursorPos.X; this.sumOfSamplesInRegion.Y += newCursorPos.Y; this.currentGazeCursorCenter.X = this.sumOfSamplesInRegion.X / this.numberOfSamplesInRegion; this.currentGazeCursorCenter.Y = this.sumOfSamplesInRegion.Y / this.numberOfSamplesInRegion; } else { this.numberOfSamplesInRegion = 0; this.sumOfSamplesInRegion = PointF.Empty; this.currentGazeCursorCenter = newCursorPos; } } else { this.currentGazeCursorCenter = newCursorPos; } } // Update mouse cursor with reduced update rate // if (_counter % REDUCING_COUNT == 0) { if (this.systemHasSecondaryScreen || this.forcePanelViewerUpdate) { if (newRawData.MousePosX.HasValue && newRawData.MousePosY.HasValue) { this.currentMouseCursorCenter = new PointF(newRawData.MousePosX.Value, newRawData.MousePosY.Value); } } } if (!this.currentSlide.IsDisabled) { this.OnNewRawDataAvailable(new NewRawDataAvailableEventArgs(newRawData)); } }
/// <summary> /// /// /// </summary> /// <param name="newRawData"></param> /// <returns></returns> public RawData ModifyGazeDataWhenBetweenZeroAndOne(RawData newRawData) { // The GazePos data is in values from 0 to 1 // so scale it to SCREEN COORDINATES // and add optional scroll offset if (newRawData.GazePosX != null) { if (newRawData.GazePosX >= 0 && newRawData.GazePosX <= 1) { newRawData.GazePosX = newRawData.GazePosX * this.xResolution + this.xScrollOffset; } } if (newRawData.GazePosY != null) { if (newRawData.GazePosY >= 0 && newRawData.GazePosY <= 1) { newRawData.GazePosY = newRawData.GazePosY * this.yResolution + this.yScrollOffset; } } return newRawData; }
/// <summary> /// This method creates a new <see cref="RawData"/> with the /// event id and sends it to be recorded into the dataset /// by a call of <see cref="NewRawDataAvailable"/>. /// </summary> /// <param name="inputEvent"> /// A <see cref="TrialEvent"/> with the /// event data. /// </param> private void WriteTrialEventToRawData(TrialEvent inputEvent) { // Create a new RawData object // Fill its members with current values. var newRawData = new RawData { SubjectName = this.currentTracker.Subject.SubjectName, TrialSequence = this.trialSequenceCounter, Time = inputEvent.Time + this.currentTrialStarttime, EventID = inputEvent.EventID }; // Raise the NewRawDataAvailable event with the new data // to submit its contents to the database. this.OnNewRawDataAvailable(new NewRawDataAvailableEventArgs(newRawData)); }
/// <summary> /// Initializes a new instance of the NewRawDataAvailableEventArgs class. /// </summary> /// <param name="newRawData"> /// The raw data row as a /// <see cref="SQLiteOgamaDataSet.RawdataRow"/> value. /// </param> public NewRawDataAvailableEventArgs(RawData newRawData) { this.RawData = newRawData; }
/////////////////////////////////////////////////////////////////////////////// // Eventhandler // /////////////////////////////////////////////////////////////////////////////// #region EVENTS /////////////////////////////////////////////////////////////////////////////// // Eventhandler for UI, Menu, Buttons, Toolbars etc. // /////////////////////////////////////////////////////////////////////////////// #region WINDOWSEVENTHANDLER #endregion //WINDOWSEVENTHANDLER /////////////////////////////////////////////////////////////////////////////// // Eventhandler for Custom Defined Events // /////////////////////////////////////////////////////////////////////////////// #region CUSTOMEVENTHANDLER #endregion //CUSTOMEVENTHANDLER #endregion //EVENTS /////////////////////////////////////////////////////////////////////////////// // Methods and Eventhandling for Background tasks // /////////////////////////////////////////////////////////////////////////////// #region BACKGROUNDWORKER #endregion //BACKGROUNDWORKER /////////////////////////////////////////////////////////////////////////////// // Inherited methods // /////////////////////////////////////////////////////////////////////////////// #region OVERRIDES #endregion //OVERRIDES /////////////////////////////////////////////////////////////////////////////// // Methods for doing main class job // /////////////////////////////////////////////////////////////////////////////// #region METHODS /// <summary> /// Generate all the lists of subject, trial and raw data. /// </summary> /// <remarks>This is the heart of the class. If something does not work as expected, /// first have a look here.</remarks> private static void GenerateSubjectTrialRawdataList() { rawDataList.Clear(); trialList.Clear(); subjectList.Clear(); trialEventsList.Clear(); // Use the decimal separator specified. NumberFormatInfo nfi = CultureInfo.GetCultureInfo("en-US").NumberFormat; if (asciiSettings.DecimalSeparatorCharacter == ',') { nfi = CultureInfo.GetCultureInfo("de-DE").NumberFormat; } // Begin reading File string lastSubject = string.Empty; int lastTrialID = -5; string line = string.Empty; int counter = 0; try { // Open file using (StreamReader importReader = new StreamReader(asciiSettings.Filename)) { string[] columns; Dictionary<string, int> columnNames = new Dictionary<string, int>(); // Read every line of ImportFile while ((line = importReader.ReadLine()) != null) { // ignore empty lines if (line.Trim() == string.Empty) { continue; } // Ignore Quotes if (line.StartsWith("#")) { continue; } // Skip first line filled with column titles if (counter == 0) { columns = line.Split('\t'); for (int i = 0; i < columns.Length; i++) { columnNames.Add(columns[i], i); } counter++; continue; } // Split line in columns string[] items = line.Split('\t'); // read subjects data string subjectName = items[columnNames["SubjectName"]]; if (subjectName != lastSubject) { SubjectsData newSubjectData = new SubjectsData(); newSubjectData.SubjectName = subjectName; newSubjectData.Category = items[columnNames["SubjectCategory"]]; int result; if (int.TryParse(items[columnNames["Age"]], out result)) { newSubjectData.Age = result; } newSubjectData.Sex = items[columnNames["Sex"]]; newSubjectData.Handedness = items[columnNames["Handedness"]]; newSubjectData.Comments = items[columnNames["Comments"]]; if (!subjectList.Contains(newSubjectData)) { subjectList.Add(newSubjectData); } lastSubject = subjectName; } // read trials data int trialID = Convert.ToInt32(items[columnNames["TrialID"]]); if (trialID != lastTrialID) { TrialsData newTrialsData = new TrialsData(); newTrialsData.SubjectName = subjectName; newTrialsData.TrialID = trialID; newTrialsData.TrialName = items[columnNames["TrialName"]]; newTrialsData.TrialSequence = Convert.ToInt32(items[columnNames["TrialSequence"]]); newTrialsData.Category = items[columnNames["TrialCategory"]]; newTrialsData.TrialStartTime = Convert.ToInt64(items[columnNames["TrialStartTime"]]); int result; if (int.TryParse(items[columnNames["Duration"]], out result)) { newTrialsData.Duration = result; } if (items[columnNames["EliminateData"]] != string.Empty) { newTrialsData.EliminateData = true; } if (!trialList.Contains(newTrialsData)) { trialList.Add(newTrialsData); } lastTrialID = trialID; } // read trials data string eventeventID = items[columnNames["EventEventID"]]; if (eventeventID != string.Empty) { TrialEventsData newTrialEventsData = new TrialEventsData(); newTrialEventsData.EventID = Convert.ToInt32(items[columnNames["EventEventID"]]); newTrialEventsData.EventParam = items[columnNames["EventParam"]]; newTrialEventsData.EventTask = items[columnNames["EventTask"]]; newTrialEventsData.EventTime = Convert.ToInt64(items[columnNames["EventTime"]]); newTrialEventsData.EventType = items[columnNames["EventType"]]; newTrialEventsData.SubjectName = subjectName; newTrialEventsData.TrialSequence = Convert.ToInt32(items[columnNames["TrialSequence"]]); if (!trialEventsList.Contains(newTrialEventsData)) { trialEventsList.Add(newTrialEventsData); } } // Create Ogama columns placeholder RawData newRawData = new RawData(); // Save time value newRawData.Time = Convert.ToInt64(items[columnNames["Time"]]); newRawData.SubjectName = subjectName; newRawData.TrialSequence = Convert.ToInt32(items[columnNames["TrialSequence"]]); newRawData.Category = items[columnNames["TrialCategory"]]; if (items[columnNames["PupilDiaX"]] != string.Empty) { newRawData.PupilDiaX = Convert.ToSingle(items[columnNames["PupilDiaX"]], nfi); } if (items[columnNames["PupilDiaY"]] != string.Empty) { newRawData.PupilDiaY = Convert.ToSingle(items[columnNames["PupilDiaY"]], nfi); } if (items[columnNames["GazePosX"]] != string.Empty) { newRawData.GazePosX = Convert.ToSingle(items[columnNames["GazePosX"]], nfi); } if (items[columnNames["GazePosY"]] != string.Empty) { newRawData.GazePosY = Convert.ToSingle(items[columnNames["GazePosY"]], nfi); } if (items[columnNames["MousePosX"]] != string.Empty) { newRawData.MousePosX = Convert.ToSingle(items[columnNames["MousePosX"]], nfi); } if (items[columnNames["MousePosY"]] != string.Empty) { newRawData.MousePosY = Convert.ToSingle(items[columnNames["MousePosY"]], nfi); } if (items[columnNames["EventID"]] != string.Empty) { newRawData.EventID = Convert.ToInt32(items[columnNames["EventID"]]); } // Add the parsed raw data row to the list. rawDataList.Add(newRawData); } } } catch (Exception ex) { ExceptionMethods.HandleException(ex); } }
/// <summary> /// This method saves the given collection of <see cref="RawData"/> into the /// given <see cref="SQLiteOgamaDataSet.RawdataDataTable"/> /// </summary> /// <param name="lstRawData">A <see cref="RawData"/> with the new samples.</param> /// <param name="subjectRawDataTable">The <see cref="SQLiteOgamaDataSet.RawdataDataTable"/> to be filled.</param> /// <returns><strong>True</strong> if successful otherwise <strong>false</strong>.</returns> public static bool SaveDataToTable(RawData[] lstRawData, SQLiteOgamaDataSet.RawdataDataTable subjectRawDataTable) { try { // Notify the beginning of adding rows to subjectRawDataTable subjectRawDataTable.BeginLoadData(); foreach (RawData data in lstRawData) { // Save data into datarow. SQLiteOgamaDataSet.RawdataRow workRowRawData = subjectRawDataTable.NewRawdataRow(); workRowRawData.SubjectName = data.SubjectName; workRowRawData.TrialSequence = data.TrialSequence; workRowRawData.Time = data.Time; if (!data.PupilDiaX.HasValue) { workRowRawData.SetPupilDiaXNull(); } else { workRowRawData.PupilDiaX = data.PupilDiaX.Value; } if (!data.PupilDiaY.HasValue) { workRowRawData.SetPupilDiaYNull(); } else { workRowRawData.PupilDiaY = data.PupilDiaY.Value; } if (!data.GazePosX.HasValue) { workRowRawData.SetGazePosXNull(); } else { workRowRawData.GazePosX = data.GazePosX.Value; } if (!data.GazePosY.HasValue) { workRowRawData.SetGazePosYNull(); } else { workRowRawData.GazePosY = data.GazePosY.Value; } if (!data.MousePosX.HasValue) { workRowRawData.SetMousePosXNull(); } else { workRowRawData.MousePosX = data.MousePosX.Value; } if (!data.MousePosY.HasValue) { workRowRawData.SetMousePosYNull(); } else { workRowRawData.MousePosY = data.MousePosY.Value; } if (!data.EventID.HasValue) { workRowRawData.SetEventIDNull(); } else { workRowRawData.EventID = data.EventID.Value; } subjectRawDataTable.AddRawdataRow(workRowRawData); } subjectRawDataTable.EndLoadData(); } catch (Exception ex) { ExceptionMethods.HandleException(ex); return false; } return true; }
/// <summary> /// Generate the list of raw data under the current /// parsing conditions. /// </summary> /// <param name="numberOfImportLines"> /// An <see cref="int"/> /// with the max number of lines to import. /// Set it to -1 to use all lines. /// </param> /// <remarks> /// This is the heart of the class. If something does not work as expected, /// first have a look here. /// </remarks> private static void GenerateOgamaRawDataList(int numberOfImportLines) { // Clear existing values RawDataList.Clear(); double lastTimeInFileTime = -1; // Retrieve existing slideshow trials (to check matching filenames for // correct trial ID numbering List<Trial> trials = Document.ActiveDocument.ExperimentSettings.SlideShow.Trials; List<string> trialNames = Document.ActiveDocument.ExperimentSettings.SlideShow.GetTrialNames(); // Use the decimal separator specified. NumberFormatInfo nfi = CultureInfo.GetCultureInfo("en-US").NumberFormat; if (asciiSetting.DecimalSeparatorCharacter == ',') { nfi = CultureInfo.GetCultureInfo("de-DE").NumberFormat; } // Enumerate the columns in the import file and assign their title. var columnsImportNum = new Dictionary<string, int>(); for (int i = 0; i < asciiSetting.ColumnHeaders.Count; i++) { if (!columnsImportNum.ContainsKey(asciiSetting.ColumnHeaders[i])) { columnsImportNum.Add(asciiSetting.ColumnHeaders[i], i); } else { return; } } // Get the assigned titles of the import columns for Ogamas columns string strSubjectNameImportColumn = asciiSetting.ColumnAssignments["SubjectName"]; string strTrialSequenceImportColumn = asciiSetting.ColumnAssignments["TrialSequence"]; string strTrialIDImportColumn = asciiSetting.ColumnAssignments["TrialID"]; string strTrialImageImportColumn = asciiSetting.ColumnAssignments["TrialImage"]; string strCategoryImportColumn = asciiSetting.ColumnAssignments["TrialCategory"]; string strTimeImportColumn = asciiSetting.ColumnAssignments["Time"]; string strPupilDiaXImportColumn = asciiSetting.ColumnAssignments["PupilDiaX"]; string strPupilDiaYImportColumn = asciiSetting.ColumnAssignments["PupilDiaY"]; string strGazePosXImportColumn = asciiSetting.ColumnAssignments["GazePosX"]; string strGazePosYImportColumn = asciiSetting.ColumnAssignments["GazePosY"]; string strMousePosXImportColumn = asciiSetting.ColumnAssignments["MousePosX"]; string strMousePosYImportColumn = asciiSetting.ColumnAssignments["MousePosY"]; // Convert the names into column counters. int numSubjectImportColumn = strSubjectNameImportColumn == string.Empty ? -1 : columnsImportNum[strSubjectNameImportColumn]; int numTrialSequenceImportColumn = strTrialSequenceImportColumn == string.Empty ? -1 : columnsImportNum[strTrialSequenceImportColumn]; int numTrialIDImportColumn = strTrialIDImportColumn == string.Empty ? -1 : columnsImportNum[strTrialIDImportColumn]; int numTrialImageImportColumn = strTrialImageImportColumn == string.Empty ? -1 : columnsImportNum[strTrialImageImportColumn]; int numCategoryImportColumn = strCategoryImportColumn == string.Empty ? -1 : columnsImportNum[strCategoryImportColumn]; int numTimeImportColumn = strTimeImportColumn == string.Empty ? -1 : columnsImportNum[strTimeImportColumn]; int numPupilDiaXImportColumn = strPupilDiaXImportColumn == string.Empty ? -1 : columnsImportNum[strPupilDiaXImportColumn]; int numPupilDiaYImportColumn = strPupilDiaYImportColumn == string.Empty ? -1 : columnsImportNum[strPupilDiaYImportColumn]; int numGazePosXImportColumn = strGazePosXImportColumn == string.Empty ? -1 : columnsImportNum[strGazePosXImportColumn]; int numGazePosYImportColumn = strGazePosYImportColumn == string.Empty ? -1 : columnsImportNum[strGazePosYImportColumn]; int numMousePosXImportColumn = strMousePosXImportColumn == string.Empty ? -1 : columnsImportNum[strMousePosXImportColumn]; int numMousePosYImportColumn = strMousePosYImportColumn == string.Empty ? -1 : columnsImportNum[strMousePosYImportColumn]; // Create a list of starting times from the list of the trial dialog // if this mode is selected. if (detectionSetting.TrialImportMode == TrialSequenceImportModes.UseAssignmentTable) { // If first given trial start time does not start with zero, // add a "zero trial" for the very first samples if (detectionSetting.TrialSequenceToStarttimeAssignments.Count > 0) { ////if (!detectionSetting.TrialSequenceToStarttimeAssignments.ContainsValue(0)) ////{ //// int zeroTrialSequence = 0; //// if (detectionSetting.TrialSequenceToStarttimeAssignments.ContainsKey(0)) //// { //// zeroTrialSequence = -1; //// } //// detectionSetting.TrialSequenceToStarttimeAssignments.Add(zeroTrialSequence, 0); ////} } else { // In this trial import modes an empty TrialSequenceToStarttimeAssignments // List is not allowed. return; } } else { detectionSetting.TrialSequenceToTrialIDAssignments.Clear(); detectionSetting.TrialSequenceToStarttimeAssignments.Clear(); } string line; int counter = 0; int columncount = 0; int trialCounter = 0; int currentTrialSequence = 0; bool isLastTrial = false; string lastSubjectName = "#"; string currentSubjectName = "#"; SortedList<int, long> trial2Time = detectionSetting.TrialSequenceToStarttimeAssignments; if (trial2Time.Count > 0) { currentTrialSequence = trial2Time.Keys[0]; } // Begin reading File try { // Open file using (var importReader = new StreamReader(asciiSetting.Filename)) { // Clear old entries except parses from table if (detectionSetting.StimuliImportMode != StimuliImportModes.UseAssignmentTable) { detectionSetting.ImageDictionary.Clear(); detectionSetting.TrialIDToImageAssignments.Clear(); } // Read every line of ImportFile while ((line = importReader.ReadLine()) != null) { // ignore empty lines if (line.Trim() == string.Empty) { continue; } // Ignore Quotes if applicable if (asciiSetting.IgnoreQuotes && line.Trim().Substring(0, asciiSetting.IgnoreQuotationString.Length) == asciiSetting.IgnoreQuotationString) { continue; } // Check for trial detection specifications switch (detectionSetting.TrialImportMode) { case TrialSequenceImportModes.UseMSGLines: // Check for MSG lines containing the trigger string if applicable if (line.Contains(detectionSetting.TrialTriggerString)) { currentTrialSequence = trialCounter; trialCounter++; } break; case TrialSequenceImportModes.UseAssignmentTable: case TrialSequenceImportModes.UseImportColumn: // No trial counting needed break; } // Check for image detection specifications switch (detectionSetting.StimuliImportMode) { // Read iViewX Scene Image Lines if applicable case StimuliImportModes.UseiViewXMSG: // Two cases: Lines with "scene image: bitmap.bmp" or // lines with "# Message: bitmap.bmp" possible. ExtractImageNameFromiViewXmsg(line, "Scene Image: ", currentTrialSequence); ExtractImageNameFromiViewXmsg(line, "# Message", currentTrialSequence); break; // Search for Image filenames if applicable case StimuliImportModes.SearchForImageEnding: if (line.Contains("." + detectionSetting.StimuliFileExtension)) { string[] itemsImageLine = line.Trim().Split(asciiSetting.ColumnSeparatorCharacter); string fileName = string.Empty; foreach (string str in itemsImageLine) { string[] subItemsImageLine = str.Trim().Split(' '); foreach (string str2 in subItemsImageLine) { if (str2.Contains("." + detectionSetting.StimuliFileExtension)) { fileName = str2; fileName = fileName.Trim(); fileName = fileName.Replace("'", string.Empty); fileName = Path.GetFileName(fileName); } } } // Only save the first image for each trial... if (!detectionSetting.ImageDictionary.ContainsKey(currentTrialSequence)) { detectionSetting.ImageDictionary.Add(currentTrialSequence, fileName); } string stimulusName = Path.GetFileNameWithoutExtension(fileName); int trialID = currentTrialSequence; if (trialNames.Contains(stimulusName)) { Trial trialFound = trials.Find(delegate(Trial t) { return t.Name == stimulusName; }); if (trialFound == null) { // This trial picture was seen before in import process foreach (KeyValuePair<int, string> kvp in detectionSetting.TrialIDToImageAssignments) { if (Path.GetFileNameWithoutExtension(kvp.Value) == stimulusName) { trialID = kvp.Key; break; } } } else { // This trial is in the slideshow already trialID = trialFound.ID; } } else { trialNames.Add(stimulusName); } if (!detectionSetting.TrialIDToImageAssignments.ContainsKey(trialID)) { detectionSetting.TrialIDToImageAssignments.Add(trialID, fileName); } if (!detectionSetting.TrialSequenceToTrialIDAssignments.ContainsKey(currentTrialSequence)) { detectionSetting.TrialSequenceToTrialIDAssignments.Add(currentTrialSequence, trialID); } } break; case StimuliImportModes.UseAssignmentTable: case StimuliImportModes.UseImportColumn: // No image extraction needed. break; } // Ignore lines that do not have the "use only" quotation // string if (asciiSetting.UseQuotes && !line.Contains(asciiSetting.UseQuotationString)) { continue; } // ignore lines with ignore trigger if (asciiSetting.IgnoreTriggerStringLines && line.Contains(asciiSetting.IgnoreTriggerString)) { continue; } // Split Tab separated line items string[] items = line.Split(asciiSetting.ColumnSeparatorCharacter); // Skip first line if filled with column titles if (asciiSetting.ColumnTitlesAtFirstRow && counter == 0) { counter++; columncount = items.Length; continue; } // Use only numeric starting lines if applicable if (asciiSetting.IgnoreNotNumeralLines && !IOHelpers.IsNumeric(line[0])) { continue; } // Set columncount in first valid line if (counter == 0) { columncount = items.Length; } // Skip small lines if applicable if (asciiSetting.IgnoreSmallLines && columncount > items.Length) { continue; } // Create Ogama columns placeholder var newRawData = new RawData(); bool subjectChanged = false; // Write subject name value if (numSubjectImportColumn != -1) { currentSubjectName = items[numSubjectImportColumn]; newRawData.SubjectName = currentSubjectName; if (currentSubjectName != lastSubjectName) { lastSubjectName = currentSubjectName; currentTrialSequence = 0; trialCounter = 0; subjectChanged = true; } } else { newRawData.SubjectName = detectionSetting.SubjectName; } // Calculate time value double timeInFileTime = Convert.ToDouble(items[numTimeImportColumn], nfi); long timeInMs = Convert.ToInt64(timeInFileTime * detectionSetting.TimeFactor); // If there is a data < starttime, skip them if (detectionSetting.TrialSequenceToStarttimeAssignments.Count > 0) { if (timeInMs < detectionSetting.TrialSequenceToStarttimeAssignments.Values[0]) { continue; } } // Save starttime if (counter == 0 || (asciiSetting.ColumnTitlesAtFirstRow && counter == 1) || subjectChanged) { asciiSetting.StartTime = timeInMs; trial2Time[currentTrialSequence] = timeInMs; detectionSetting.TrialSequenceToStarttimeAssignments[currentTrialSequence] = timeInMs; } // Check for duplicate time entries if (timeInFileTime == lastTimeInFileTime) { string message = string.Format( "Two consecutive raw data samples had the same sampling time {0}." + Environment.NewLine + "Time in FileTime is {1}" + Environment.NewLine + "PrevTime in FileTime is {2}" + Environment.NewLine + "This indicates an logfile error or wrong timescale." + Environment.NewLine + "Please try to change the timescale to milliseconds.", timeInMs, timeInFileTime, lastTimeInFileTime); ExceptionMethods.ProcessErrorMessage(message); return; } // Set time check value lastTimeInFileTime = timeInFileTime; // Save time value newRawData.Time = timeInMs - asciiSetting.StartTime; // Write Trial Sequence switch (detectionSetting.TrialImportMode) { case TrialSequenceImportModes.UseMSGLines: newRawData.TrialSequence = currentTrialSequence; break; case TrialSequenceImportModes.UseAssignmentTable: if (!isLastTrial && newRawData.Time + asciiSetting.StartTime >= trial2Time.Values[trialCounter]) { trialCounter++; if (trialCounter >= trial2Time.Count) { isLastTrial = true; } } currentTrialSequence = trial2Time.Keys[trialCounter - 1]; newRawData.TrialSequence = currentTrialSequence; break; case TrialSequenceImportModes.UseImportColumn: if (numTrialSequenceImportColumn != -1) { currentTrialSequence = Convert.ToInt32(items[numTrialSequenceImportColumn]); newRawData.TrialSequence = currentTrialSequence; } break; } int? columnTrialID = null; // Write trialID to detection settings. if (numTrialIDImportColumn != -1 && items.Length > numTrialIDImportColumn) { columnTrialID = Convert.ToInt32(items[numTrialIDImportColumn]); if (!detectionSetting.TrialSequenceToTrialIDAssignments.ContainsKey(currentTrialSequence)) { detectionSetting.TrialSequenceToTrialIDAssignments.Add(currentTrialSequence, columnTrialID.Value); } } // Write Stimulus file to detection settings. if (numTrialImageImportColumn != -1 && items.Length > numTrialImageImportColumn) { int usedTrialID = currentTrialSequence; if (columnTrialID.HasValue) { usedTrialID = columnTrialID.Value; } if (!detectionSetting.TrialIDToImageAssignments.ContainsKey(usedTrialID)) { detectionSetting.TrialIDToImageAssignments.Add(usedTrialID, items[numTrialImageImportColumn]); } if (!detectionSetting.TrialSequenceToTrialIDAssignments.ContainsKey(currentTrialSequence)) { detectionSetting.TrialSequenceToTrialIDAssignments.Add(currentTrialSequence, usedTrialID); } } // Write trial category if (numCategoryImportColumn != -1 && items.Length > numCategoryImportColumn) { newRawData.Category = items[numCategoryImportColumn]; } // Write PupilDiameters if (numPupilDiaXImportColumn != -1 && items.Length > numPupilDiaXImportColumn) { if (IOHelpers.IsNumeric(items[numPupilDiaXImportColumn])) { newRawData.PupilDiaX = Convert.ToSingle(items[numPupilDiaXImportColumn], nfi); } } if (numPupilDiaYImportColumn != -1 && items.Length > numPupilDiaYImportColumn) { if (IOHelpers.IsNumeric(items[numPupilDiaYImportColumn])) { newRawData.PupilDiaY = Convert.ToSingle(items[numPupilDiaYImportColumn], nfi); } } // Write gaze positions if (numGazePosXImportColumn != -1 && items.Length > numGazePosXImportColumn) { if (IOHelpers.IsNumeric(items[numGazePosXImportColumn])) { newRawData.GazePosX = Convert.ToSingle(items[numGazePosXImportColumn], nfi); } } if (numGazePosYImportColumn != -1 && items.Length > numGazePosYImportColumn) { if (IOHelpers.IsNumeric(items[numGazePosYImportColumn])) { newRawData.GazePosY = Convert.ToSingle(items[numGazePosYImportColumn], nfi); } } // Write mouse positions if (numMousePosXImportColumn != -1 && items.Length > numMousePosXImportColumn) { if (IOHelpers.IsNumeric(items[numMousePosXImportColumn])) { newRawData.MousePosX = Convert.ToSingle(items[numMousePosXImportColumn], nfi); } } if (numMousePosYImportColumn != -1 && items.Length > numMousePosYImportColumn) { if (IOHelpers.IsNumeric(items[numMousePosYImportColumn])) { newRawData.MousePosY = Convert.ToSingle(items[numMousePosYImportColumn], nfi); } } // Add the parsed raw data row to the list. RawDataList.Add(newRawData); // Increase counter counter++; // Cancel import, if only a part for preview should be imported. if (counter > numberOfImportLines && numberOfImportLines >= 0) { break; } } // reached end of file of number of import lines } } catch (Exception ex) { ExceptionMethods.HandleException(ex); } }