Example #1
0
    ///////////////////////////////////////////////////////////////////////////////
    // Methods for doing main class job                                          //
    ///////////////////////////////////////////////////////////////////////////////
    #region METHODS

    /// <summary>
    /// Initializes fields if applicable;
    /// </summary>
    private void InitializeFields()
    {
      // For Designer support check for empty Application settings
      if (Properties.Settings.Default != null)
      {
        this.currentLoopState = new LoopState();
        this.currentLoopState.ProcessBeginningTime = DateTime.Now;

        this.showBlinks = Properties.Settings.Default.GazeModeBlinks;
        this.isGazeDiscreteLength = Properties.Settings.Default.GazeModeCutPath;
        this.isMouseDiscreteLength = Properties.Settings.Default.MouseModeCutPath;

        var speedValue = Properties.Settings.Default.ReplaySpeed;
        switch (speedValue)
        {
          case "10x": this.speed = 10f;
            break;
          case "5x": this.speed = 5f;
            break;
          case "3x": this.speed = 3f;
            break;
          case "2x": this.speed = 2f;
            break;
          case "1x": this.speed = 1f;
            break;
          case "0.5x": this.speed = 0.5f;
            break;
          case "0.3x": this.speed = 0.33f;
            break;
          case "0.2x": this.speed = 0.2f;
            break;
          case "0.1x": this.speed = 0.1f;
            break;
          default: this.speed = 1f;
            break;
        }

        this.objFixGazeDetection = new FixationDetection();
        this.objFixMouseDetection = new FixationDetection();

        this.gazeFixations = new VGElementCollection();
        this.mouseFixations = new VGElementCollection();

        if (Properties.Settings.Default.GazeModeCursor)
        {
          this.gazeDrawingMode |= ReplayDrawingModes.Cursor;
        }

        if (Properties.Settings.Default.GazeModePath)
        {
          this.gazeDrawingMode |= ReplayDrawingModes.Path;
        }

        if (Properties.Settings.Default.GazeModeFixations)
        {
          this.gazeDrawingMode |= ReplayDrawingModes.Fixations;
        }

        if (Properties.Settings.Default.GazeModeFixCon)
        {
          this.gazeDrawingMode |= ReplayDrawingModes.FixationConnections;
        }

        if (Properties.Settings.Default.GazeModeSpotlight)
        {
          this.gazeDrawingMode |= ReplayDrawingModes.Spotlight;
        }

        if (Properties.Settings.Default.MouseModeCursor)
        {
          this.mouseDrawingMode |= ReplayDrawingModes.Cursor;
        }

        if (Properties.Settings.Default.MouseModePath)
        {
          this.mouseDrawingMode |= ReplayDrawingModes.Path;
        }

        if (Properties.Settings.Default.MouseModeFixations)
        {
          this.mouseDrawingMode |= ReplayDrawingModes.Fixations;
        }

        if (Properties.Settings.Default.MouseModeFixCon)
        {
          this.mouseDrawingMode |= ReplayDrawingModes.FixationConnections;
        }

        if (Properties.Settings.Default.MouseModeSpotlight)
        {
          this.mouseDrawingMode |= ReplayDrawingModes.Spotlight;
        }

        this.maxLengthPath = (int)Properties.Settings.Default.MaxPointsPolyline;
        this.numFixToShow = (int)Properties.Settings.Default.MaxNumberFixations;

        // Initialize and load sounds for the replay of mouse clicks.
        this.sndLeftClick = new SoundPlayer();
        this.sndLeftClick.Stream = Properties.Resources.clickLeft;
        this.sndLeftClick.LoadAsync();

        this.sndRightClick = new SoundPlayer();
        this.sndRightClick.Stream = Properties.Resources.clickRight;
        this.sndRightClick.LoadAsync();
      }
    }
Example #2
0
    /// <summary>
    /// Calculates fixations from raw data and writes them into 
    /// the database in the fixations tables.
    /// </summary>
    /// <param name="sampleType">The <see cref="SampleType"/> of the data, gaze or mouse</param>
    /// <param name="subject">A <see cref="String"/> with the subject name</param>
    /// <param name="trialsTable">The database trials <see cref="DataTable"/></param>
    /// <param name="worker">The <see cref="BackgroundWorker"/> of the calculation</param>
    /// <param name="e">The <see cref="DoWorkEventArgs"/> of the <see cref="BackgroundWorker"/></param>
    public void CalcFixations(
      SampleType sampleType,
      string subject,
      System.Data.DataTable trialsTable,
      BackgroundWorker worker,
      DoWorkEventArgs e)
    {
      // Fixation  Calculating Objects //////////////////////////////////////////
      FixationDetection objFixationDetection = new FixationDetection();

      // Instantiate the delegate using the method as a parameter
      GetDataDelegate getDataMethod = null;
      int minSamples = 0;
      int maxDistance = 0;

      if (sampleType == (sampleType | SampleType.Gaze))
      {
        getDataMethod = Queries.GetGazeData;
        minSamples = this.gazeMinSamples;
        maxDistance = this.gazeMaxDistance;
      }
      else if (sampleType == (sampleType | SampleType.Mouse))
      {
        getDataMethod = Queries.GetMouseData;
        minSamples = this.mouseMinSamples;
        maxDistance = this.mouseMaxDistance;
      }

      bool point_found_delayed;
      /* sample gazepoint-found flag,      */
      /*   min_fix_samples ago             */
      float x_delayed;      /* sample gazepoint coordinates,     */
      float y_delayed;      /*   min_fix_samples ago             */
      float deviation_delayed;
      /* deviation of the gaze from the    */
      /*   present fixation,               */
      /*   min_fix_samples ago             */
      /* Fixation data - delayed:          */
      float x_fix_delayed = new float();       /* fixation point as estimated       */
      float y_fix_delayed = new float();       /*   min_fix_samples ago             */
      int saccade_duration_delayed;
      /* duration of the saccade           */
      /*   preceeding the preset fixation  */
      /*   (samples)                       */
      long fix_start_time = new long();
      int fix_duration_delayed_samples = new int(); /* duration of the present fixation  */
      long fix_duration_delayed_milliseconds = new long(); /* duration of the present fixation  */

      EyeMotionState currentState = new EyeMotionState();

      // OtherVars
      int counterTrial = 0;
      PointF trialLastFixCenter = new PointF(0, 0);

      // Loop Rows=Trials
      foreach (DataRow trialRow in trialsTable.Rows)
      {
        List<Fixation> fixations = new List<Fixation>();

        // Reinitialize Fixation detection object
        // to ensure no overlay between fixations of 
        // trials that follow each other.
        objFixationDetection.InitFixation(minSamples);

        int trialID = (int)trialRow["TrialID"];
        int trialSequence = (int)trialRow["TrialSequence"];

        // Holds RawData corresponding to selected trial and subject
        DataTable rawDataTable = Queries.GetRawDataBySubjectAndTrialSequence(subject, trialSequence);
        long trialStartTime = rawDataTable.Rows.Count > 0 ? (long)rawDataTable.Rows[0]["Time"] : 0;

        int counterRows = 0;
        int counterFix = 0;
        bool isFixation = false;

        // Loop RawData
        foreach (DataRow rowRaw in rawDataTable.Rows)
        {
          PointF? newPt;
          SampleValidity isValidData = getDataMethod(
            rowRaw,
            Document.ActiveDocument.PresentationSize,
            out newPt);

          bool useSample = false;
          switch (isValidData)
          {
            case SampleValidity.Valid:
              useSample = true;
              break;
            case SampleValidity.Empty:
              useSample = true;
              break;
            case SampleValidity.Null:
              break;
            case SampleValidity.OutOfStimulus:
              useSample = true;
              break;
          }

          if (useSample)
          {
            PointF dataPoint = newPt.Value;

            currentState = objFixationDetection.DetectFixation(
              dataPoint.IsEmpty ? false : true,
              Convert.ToInt64(rowRaw[3]),
              dataPoint.X,
              dataPoint.Y,
              maxDistance,
              minSamples,
              out point_found_delayed,
              out x_delayed,
              out y_delayed,
              out deviation_delayed,
              out x_fix_delayed,
              out y_fix_delayed,
              out saccade_duration_delayed,
              out fix_start_time,
              out fix_duration_delayed_milliseconds,
              out fix_duration_delayed_samples);

            switch (currentState)
            {
              case EyeMotionState.FIXATING:
                if (!isFixation)
                {
                  isFixation = true;
                }

                break;
              case EyeMotionState.FIXATION_COMPLETED:
                PointF fixationCenter = new PointF(x_fix_delayed, y_fix_delayed);

                // if (!Queries.OutOfScreen(fixationCenter)) TODO
                {
                  Fixation completedFixation = new Fixation();
                  completedFixation.CountInTrial = counterFix + 1;
                  completedFixation.Length = fix_duration_delayed_milliseconds;
                  completedFixation.PosX = x_fix_delayed;
                  completedFixation.PosY = y_fix_delayed;
                  completedFixation.SampleType = sampleType;
                  completedFixation.StartTime = fix_start_time - trialStartTime;
                  completedFixation.SubjectName = (string)trialRow["SubjectName"];
                  completedFixation.TrialID = (int)trialRow["TrialID"];
                  completedFixation.TrialSequence = (int)trialRow["TrialSequence"];

                  if (this.eliminateFirstFixation && this.eliminateFirstFixationSimple == false && counterFix == 0 && VGPolyline.Distance(fixationCenter, trialLastFixCenter) < maxDistance && fix_duration_delayed_milliseconds < this.limitForFirstFixation)
                  {
                    // Eliminate if applicable
                  }
                  else if (this.eliminateFirstFixationSimple && counterFix == 0)
                  {
                    // do nothing, just go on with the next fixation eliminating this one
                    counterFix++;
                  }
                  else
                  {
                    fixations.Add(completedFixation);
                    counterFix++;
                  }
                }

                isFixation = false;
                break;
              case EyeMotionState.ERROR:
                break;
              default:
                break;
            }
          }

          counterRows++;

          // End RawData Loop
        }

        // Save last Fix if it has not been saved by a following saccade
        if (isFixation && fix_duration_delayed_milliseconds > 0)
        {
          Fixation lastFixation = new Fixation();
          lastFixation.CountInTrial = counterFix + 1;
          lastFixation.Length = fix_duration_delayed_milliseconds;
          lastFixation.PosX = x_fix_delayed;
          lastFixation.PosY = y_fix_delayed;
          lastFixation.SampleType = sampleType;
          lastFixation.StartTime = fix_start_time - trialStartTime;
          lastFixation.SubjectName = (string)trialRow["SubjectName"];
          lastFixation.TrialID = (int)trialRow["TrialID"];
          lastFixation.TrialSequence = (int)trialRow["TrialSequence"];
          fixations.Add(lastFixation);
        }

        // Save last FixCenter for Eliminating first Fix of new trial if choosen in UI
        trialLastFixCenter.X = x_fix_delayed;
        trialLastFixCenter.Y = y_fix_delayed;

        if (this.mergeConsecutiveFixations)
        {
          // Look for consecutive fixations that are beneath each other
          // (within GazeMaxDistance) because of
          // miscalculation due to blinks or missing data.
          List<Fixation> mergedFixations = new List<Fixation>();
          if (fixations.Count > 1)
          {
            Fixation foregoingFixation = fixations[0];
            bool merged = false;
            int mergedCounter = 0;
            int consecutiveMerges = 0;
            int trialFixCounter = 1;
            PointF foregoingFixationCenter = new PointF(foregoingFixation.PosX, foregoingFixation.PosY);
            for (int i = 1; i < fixations.Count; i++)
            {
              // Test if consecutive calculated fixations lie in GazeMaxDistanceRange
              PointF fixationCenter = new PointF(fixations[i].PosX, fixations[i].PosY);
              int distance = (int)VGPolyline.Distance(foregoingFixationCenter, fixationCenter);
              if (distance < maxDistance)
              {
                long sumOfDuration = foregoingFixation.Length + fixations[i].Length;
                foregoingFixation.PosX = (foregoingFixation.PosX * foregoingFixation.Length +
                  fixations[i].PosX * fixations[i].Length) / sumOfDuration;
                foregoingFixation.PosY = (foregoingFixation.PosY * foregoingFixation.Length +
                  fixations[i].PosY * fixations[i].Length) / sumOfDuration;
                foregoingFixation.Length = fixations[i].StartTime - foregoingFixation.StartTime + fixations[i].Length;
                merged = true;
                mergedCounter++;
                consecutiveMerges++;
              }
              else
              {
                if (!merged)
                {
                  foregoingFixation.CountInTrial = trialFixCounter;
                  mergedFixations.Add(foregoingFixation);
                  trialFixCounter++;
                }
                else
                {
                  merged = false;
                  foregoingFixation.CountInTrial -= mergedCounter - 1;
                  foregoingFixation.CountInTrial = trialFixCounter;
                  mergedFixations.Add(foregoingFixation);
                  consecutiveMerges = 0;
                  trialFixCounter++;
                }

                foregoingFixation = fixations[i];
                foregoingFixationCenter = fixationCenter;
              }
            }

            if (!merged)
            {
              foregoingFixation.CountInTrial = trialFixCounter;
              mergedFixations.Add(foregoingFixation);
              trialFixCounter++;
            }
          }
          else
          {
            mergedFixations = fixations;
          }

          foreach (Fixation fixationToSave in mergedFixations)
          {
            this.SaveFixationToTable(fixationToSave);
          }
        }
        else
        {
          // Don not merge fixations, use the originals.
          foreach (Fixation fixationToSave in fixations)
          {
            this.SaveFixationToTable(fixationToSave);
          }
        }

        // increase TrialCounter
        counterTrial++;

        if (worker != null)
        {
          if (worker.CancellationPending)
          {
            e.Cancel = true;
            break;
          }
          else
          {
            // Report progress as a percentage of the total task.
            int percentComplete = Convert.ToInt32(Convert.ToSingle(counterTrial) / trialsTable.Rows.Count * 100);
            worker.ReportProgress(percentComplete);
          }
        }

        // End Trial Loop
      }

      // Save Data to MDF File
      this.WriteToMDF(sampleType);
    }