/// <summary> /// The <see cref="PresenterModule.TrialChanged"/> event handler. /// Stores the trial information into the database /// and updates the live viewer with the new slide. /// </summary> /// <param name="sender"> /// Source of the event. /// </param> /// <param name="e"> /// A <see cref="TrialChangedEventArgs"/> with the event data. /// </param> private void ObjPresenterTrialChanged(object sender, TrialChangedEventArgs e) { // Set time critical values long currentTime = this.counterChangedTime; this.xScrollOffset = 0; this.yScrollOffset = 0; // If the last trial was a disabled trial (PreFixationSlide) // Only update start times if (e.FinishedTrial[e.FinishedTrial.Count - 1].IsDisabled) { // Update new trial this.currentTrialStarttime = currentTime - this.recordingStarttime; if (this.chbRecordAudio.Checked || this.chbRecordVideo.Checked) { this.currentTrialVideoStartTime = e.WebcamTime; } this.Invoke(this.delegateNewSlideAvailable); return; } if (e.FinishedTrial.Name != "DummyTrial") { // Update current trial this.precedingTrial = e.FinishedTrial; // When rawData list exceeds sample limit or this was the last trial // write the samples into the database if (this.rawDataLists[this.listCounter].Count > MINSAMPLESFORWRITINGTODATABASE || e.NextTrial == null) { // Stop recording if this was the last trial or cancelled if (e.NextTrial == null) { // Stop tracking this.currentTracker.Stop(); // Give the presentation thread time to close. Application.DoEvents(); } // switch to next raw data list for writing lock (this) { // Save copy to dataset table in new thread AsyncHelper.FireAndForget( new WaitCallback(StoreRecordsInDataSetTable), new DataToTable(this.rawDataLists[this.listCounter], this.subjectRawDataTable)); // Clear list, cause its content was copied during creation of DataToTable this.rawDataLists[this.listCounter].Clear(); this.listCounter++; if (this.listCounter == NUMWRITINGTHREADS) { this.listCounter = 0; } } } // Write new trial information var trialData = new TrialsData { SubjectName = this.currentTracker.Subject.SubjectName, TrialName = this.precedingTrial.Name, TrialSequence = this.trialSequenceCounter - 1, TrialID = this.precedingTrial.ID, Category = this.precedingTrial[0].Category, TrialStartTime = this.currentTrialStarttime, Duration = (int)(currentTime - this.recordingStarttime - this.currentTrialStarttime) }; if (this.trialSequenceCounter > 0) { this.trialDataList.Add(trialData); } // Store usercam start event if applicable if (this.chbRecordAudio.Checked || this.chbRecordVideo.Checked) { var usercamVideoEvent = new MediaEvent { EventID = this.trialEventList.Count, Param = this.currentTrialVideoStartTime.ToString(CultureInfo.InvariantCulture), Task = MediaEventTask.Start, Time = 0, Type = EventType.Usercam, SubjectName = this.currentTracker.Subject.SubjectName, TrialSequence = this.trialSequenceCounter - 1 }; if (this.trialSequenceCounter > 0) { this.trialEventList.Add(usercamVideoEvent); } } // Store subjects response event var inputEvent = new InputEvent { EventID = this.trialEventList.Count, SubjectName = this.currentTracker.Subject.SubjectName, Task = InputEventTask.SlideChange, Time = trialData.Duration, TrialSequence = this.trialSequenceCounter - 1, Type = EventType.Response }; if (e.Response != null) { inputEvent.Param = e.Response.ToString(); } if (this.trialSequenceCounter >= 0) { this.trialEventList.Add(inputEvent); } } // Update new trial this.currentTrialStarttime = currentTime - this.recordingStarttime; if (this.chbRecordAudio.Checked || this.chbRecordVideo.Checked) { this.currentTrialVideoStartTime = e.WebcamTime; } // Update recorder modules viewer var updateLiveViewerThread = new Thread(this.NewSlideAvailable); updateLiveViewerThread.SetApartmentState(ApartmentState.STA); updateLiveViewerThread.Start(); }
/////////////////////////////////////////////////////////////////////////////// // 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 iterates the imported fixation rows to /// catch the trial changes that are detected during the call /// of <see cref="GenerateOgamaFixationDataList(int)" />. /// The trials are then written into the trial list. /// </summary> private static void GenerateOgamaSubjectAndTrialList() { // Clear foregoing imports. TrialList.Clear(); SubjectList.Clear(); if (FixationDataList.Count == 0) { return; } // Initializes variables var lastSequence = -5; var lastSubject = "#"; // Iterate raw data list for (int i = 0; i < FixationDataList.Count; i++) { var importRow = FixationDataList[i]; int currentSequence = importRow.TrialSequence; string currentSubject = importRow.SubjectName; FixationDataList[i] = importRow; // If subject has changed write new subject table entry. if (currentSubject != lastSubject) { var newSubjectsData = new SubjectsData { SubjectName = currentSubject }; SubjectList.Add(newSubjectsData); lastSubject = currentSubject; } // If trial has changed parse the trial information to // create a trial entry in the trialList. if (currentSequence != lastSequence) { string subject = importRow.SubjectName ?? "Subject1"; // Create trial row var newTrialData = new TrialsData { SubjectName = subject, TrialSequence = importRow.TrialSequence, TrialID = importRow.TrialID, TrialName = importRow.TrialID.ToString(CultureInfo.InvariantCulture) }; TrialList.Add(newTrialData); lastSequence = currentSequence; } } }
/// <summary> /// This method iterates the imported raw data rows to /// catch the trial changes that are detected during the call /// of <see cref="GenerateOgamaRawDataList(int)" />. /// The trials are then written into the trial list. /// </summary> private static void GenerateOgamaSubjectAndTrialList() { // Clear foregoing imports. TrialList.Clear(); SubjectList.Clear(); if (RawDataList.Count == 0) { // string message = "The parsing of the log file into OGAMAs " + // "Raw data columns failed. No lines have been successfully read. " + // Environment.NewLine + // "So the trial generation could not be started." + // Environment.NewLine + "Please change the import settings and try again"; // ExceptionMethods.ProcessErrorMessage(message); return; } // Initializes variables int currentSequence = 0; int lastSequence = -5; string currentSubject = "#"; string lastSubject = "#"; int overallTrialCounter = 0; int trialCounter = 0; int subjectCounter = 0; // Iterate raw data list for (int i = 0; i < RawDataList.Count; i++) { RawData importRow = RawDataList[i]; currentSequence = importRow.TrialSequence; currentSubject = importRow.SubjectName; // If subject has changed write new subject table entry. if (currentSubject != lastSubject) { var newSubjectsData = new SubjectsData(); newSubjectsData.SubjectName = currentSubject; SubjectList.Add(newSubjectsData); if (subjectCounter > 0) { TrialsData tempSubjetData = TrialList[overallTrialCounter - 1]; tempSubjetData.Duration = (int)(RawDataList[i - 1].Time - tempSubjetData.TrialStartTime); TrialList[overallTrialCounter - 1] = tempSubjetData; } lastSubject = currentSubject; lastSequence = -5; trialCounter = 0; subjectCounter++; } // If trial has changed parse the trial information to // create a trial entry in the trialList. if (currentSequence != lastSequence) { string subject = importRow.SubjectName != null ? importRow.SubjectName : "Subject1"; string categorie = importRow.Category != null ? importRow.Category : string.Empty; int trialID = currentSequence; if (detectionSetting.TrialSequenceToTrialIDAssignments.ContainsKey(currentSequence)) { trialID = detectionSetting.TrialSequenceToTrialIDAssignments[currentSequence]; } string image = "No image file specified"; switch (detectionSetting.StimuliImportMode) { case StimuliImportModes.UseiViewXMSG: if (detectionSetting.ImageDictionary.ContainsKey(currentSequence)) { image = detectionSetting.ImageDictionary[currentSequence]; } break; case StimuliImportModes.UseImportColumn: case StimuliImportModes.UseAssignmentTable: if (detectionSetting.TrialSequenceToTrialIDAssignments.ContainsKey(currentSequence)) { trialID = detectionSetting.TrialSequenceToTrialIDAssignments[currentSequence]; if (detectionSetting.TrialIDToImageAssignments.ContainsKey(trialID)) { image = detectionSetting.TrialIDToImageAssignments[trialID]; } } break; case StimuliImportModes.SearchForImageEnding: if (detectionSetting.ImageDictionary.ContainsKey(currentSequence)) { image = detectionSetting.ImageDictionary[currentSequence]; } break; } // Add empty trial to sequence numbering. if (detectionSetting.StimuliImportMode != StimuliImportModes.UseImportColumn && image == "No image file specified") { if (!detectionSetting.TrialSequenceToTrialIDAssignments.ContainsKey(currentSequence)) { detectionSetting.TrialSequenceToTrialIDAssignments.Add(currentSequence, 0); } } long time = 0; switch (detectionSetting.TrialImportMode) { ////// Use the table timing ////if (detectionSetting.TrialSequenceToStarttimeAssignments.ContainsKey(currentSequence)) ////{ //// time = detectionSetting.TrialSequenceToStarttimeAssignments[currentSequence]; ////} //// break; case TrialSequenceImportModes.UseAssignmentTable: case TrialSequenceImportModes.UseMSGLines: case TrialSequenceImportModes.UseImportColumn: // Use the raw data timing time = importRow.Time; break; } // Create trial row var newTrialData = new TrialsData(); newTrialData.SubjectName = subject; newTrialData.TrialSequence = currentSequence; newTrialData.TrialID = trialID; newTrialData.TrialName = image; newTrialData.Category = categorie; newTrialData.TrialStartTime = time; newTrialData.Duration = -1; TrialList.Add(newTrialData); lastSequence = currentSequence; trialCounter++; overallTrialCounter++; // Calculate trial duration for foregoing trial. if (trialCounter > 1) { TrialsData tempSubjetData = TrialList[overallTrialCounter - 2]; int duration = 0; switch (detectionSetting.TrialImportMode) { case TrialSequenceImportModes.UseAssignmentTable: // Use the table timing duration = (int)(time - tempSubjetData.TrialStartTime); break; case TrialSequenceImportModes.UseMSGLines: case TrialSequenceImportModes.UseImportColumn: // Use the raw data timing duration = (int)(RawDataList[i].Time - tempSubjetData.TrialStartTime); break; } //// If there is lot of time (>200ms) left between last and current trial //// don´t use the space in between for the duration value. ////if (rawDataList[i].Time - rawDataList[i - 1].Time > 200) ////{ //// duration = (int)(rawDataList[i - 1].Time - tempSubjetData.TrialStartTime); ////} tempSubjetData.Duration = duration; TrialList[overallTrialCounter - 2] = tempSubjetData; } } } // Reached end of rawdatalist, so add last trial duration value from last entry if (trialCounter >= 1) { TrialsData tempSubjetData = TrialList[overallTrialCounter - 1]; tempSubjetData.Duration = (int)(RawDataList[RawDataList.Count - 1].Time - tempSubjetData.TrialStartTime); TrialList[overallTrialCounter - 1] = tempSubjetData; } }