Esempio n. 1
0
    /// <summary>
    /// This static method calculates the average fixation duration
    /// at the AOIs given in the table.
    /// </summary>
    /// <param name="fixationTable">A <see cref="DataTable"/> with the fixations
    /// to use.</param>
    /// <param name="aois">An <see cref="VGElementCollection"/> with the AOIs to calculate the parameter for.</param>
    /// <returns>An <see cref="int"/> with the average fixation duration at the AOIs in ms.</returns>
    public static AOIStatistic CalcAOIStatistic(DataView fixationTable, VGElementCollection aois)
    {
      AOIStatistic aoiStatistic = new AOIStatistic();

      // NO Target AOI defined
      aoiStatistic.FixationDurationMean = -2;
      aoiStatistic.FixationDurationMedian = -2;
      aoiStatistic.FixationCount = -2;
      aoiStatistic.SumOfTimeOfAllFixations = -2;
      aoiStatistic.FirstHitTimeAfterBeeingOutside = -2;
      aoiStatistic.SaccadeDuration = -2;
      aoiStatistic.SaccadeLength = -2;
      aoiStatistic.SaccadeVelocity = -2;

      if (aois.Count == 0)
      {
        return aoiStatistic;
      }

      DataTable fixationsInAOIs = (DataTable)fixationTable.Table.Clone();
      fixationsInAOIs.Clear();

      int hitCount = 0;

      bool wasOutside = false;
      aoiStatistic.FirstHitTimeAfterBeeingOutside = -1;
      foreach (DataRowView fixRow in fixationTable)
      {
        if (IsFixAtTarget(aois, fixRow) != null)
        {
          hitCount++;
          aoiStatistic.HitTimes.Add(hitCount, (long)fixRow["StartTime"]);
          fixationsInAOIs.Rows.Add(fixRow.Row.ItemArray);

          if (wasOutside && aoiStatistic.FirstHitTimeAfterBeeingOutside == -1)
          {
            aoiStatistic.FirstHitTimeAfterBeeingOutside = (long)fixRow["StartTime"];
          }
        }
        else
        {
          wasOutside = true;
        }
      }

      // Fixation Durations
      double[] fixationsDurations = GetFixationDurationsArray(fixationsInAOIs);
      Descriptive descriptives = new Descriptive(fixationsDurations);

      // -1 : no fixations in AOI
      if (fixationsDurations.Length > 0)
      {
        descriptives.Analyze(); // analyze the data
      }

      aoiStatistic.FixationDurationMean = fixationsDurations.Length == 0 ? -1 : descriptives.Result.Mean;
      aoiStatistic.FixationDurationMedian = fixationsDurations.Length == 0 ? -1 : descriptives.Result.Median;
      aoiStatistic.FixationCount = fixationsDurations.Length == 0 ? -1 : (int)descriptives.Result.Count;
      aoiStatistic.SumOfTimeOfAllFixations = fixationsDurations.Length == 0 ? -1 : descriptives.Result.Sum;

      // Saccade Durations
      double saccadeDuration;
      double saccadeLength;
      double saccadeVelocity;

      GetSaccadeArrays(fixationsInAOIs, out saccadeDuration, out saccadeLength, out saccadeVelocity);

      aoiStatistic.SaccadeDuration = saccadeDuration;
      aoiStatistic.SaccadeLength = saccadeLength;
      aoiStatistic.SaccadeVelocity = saccadeVelocity;

      return aoiStatistic;
    }
Esempio n. 2
0
    /// <summary>
    /// Submethod for calculating gaze statistics variables
    /// Calls the static methods used for calculating the variables.
    /// </summary>
    /// <param name="newRow">current row of statistic data grid view to fill with variables</param>
    /// <param name="trialRow">Trial table row for current subject.</param>
    /// <param name="subjectName">current calculated subjects name</param>
    /// <param name="targetAOIs">A <see cref="VGElementCollection"/> with the group of target AOIs.</param>
    /// <param name="searchRectAOIs">A <see cref="VGElementCollection"/> with the group of search rect AOIs.</param>
    public void FillGazeColumns(
      DataGridViewRow newRow,
      DataRowView trialRow,
      string subjectName,
      VGElementCollection targetAOIs,
      VGElementCollection searchRectAOIs)
    {
      // Calculate or read Fixation Columns 
      float duration = Convert.ToSingle(trialRow["Duration"]);
      int trialID = (int)trialRow["TrialID"];
      int trialSequence = (int)trialRow["TrialSequence"];

      DataTable fixationTable =
        Document.ActiveDocument.DocDataSet.GazeFixationsAdapter.GetDataBySubjectAndSequence(subjectName, trialSequence);
      DataView fixationView = new DataView(fixationTable);

      SortedList<long, InputEvent> mouseEvents = Queries.GetTrialMouseEvents(subjectName, trialSequence);

      // Fixation Counts
      if (this.gazeParams == (this.gazeParams | GazeParams.Fixations))
      {
        newRow.Cells["GFIXCOUN"].Value = fixationTable.Rows.Count;
      }

      if (this.gazeParams == (this.gazeParams | GazeParams.FixationsPS))
      {
        newRow.Cells["GFIXCOpS"].Value = fixationTable.Rows.Count / duration * 1000;
      }

      if (this.gazeParams == (this.gazeParams | GazeParams.FixationsUntilFirstMouseClick))
      {
        newRow.Cells["GFIXCO1C"].Value = CalcNumberOfFixationsUntilFirstMouseClick(mouseEvents, fixationTable);
      }

      // Fixation Duration
      double[] fixationsDurations = GetFixationDurationsArray(fixationTable);
      Descriptive descriptives = new Descriptive(fixationsDurations);

      if (fixationsDurations.Length > 0)
      {
        descriptives.Analyze(); // analyze the data
      }

      if (this.gazeParams == (this.gazeParams | GazeParams.FixationDurationMean))
      {
        newRow.Cells["GFIXDURA"].Value = fixationsDurations.Length == 0 ? -1 : descriptives.Result.Mean;
      }

      if (this.gazeParams == (this.gazeParams | GazeParams.FixationDurationMedian))
      {
        newRow.Cells["GFIXDUME"].Value = fixationsDurations.Length == 0 ? -1 : descriptives.Result.Median;
      }

      if (this.gazeParams == (this.gazeParams | GazeParams.FixationSaccadeRatio))
      {
        newRow.Cells["GFIXDUpS"].Value = fixationsDurations.Length == 0 ? -1 : descriptives.Result.Sum / duration * 1000;
      }

      if (this.gazeParams == (this.gazeParams | GazeParams.TimeToFirstFixInSearchRect))
      {
        if (searchRectAOIs.Count > 0)
        {
          AOIStatistic aoiStatistic = CalcAOIStatistic(fixationView, searchRectAOIs);
          newRow.Cells["GFIXRECT"].Value = aoiStatistic.HitTimes.Count > 0 ? aoiStatistic.HitTimes[1] : -1;
        }
        else
        {
          newRow.Cells["GFIXRECT"].Value = -2;
        }
      }

      if (targetAOIs.Count > 0)
      {
        AOIStatistic aoiStatistic = CalcAOIStatistic(fixationView, targetAOIs);

        // Target Fixations
        if (this.gazeParams == (this.gazeParams | GazeParams.TimeAtTarget))
        {
          newRow.Cells["GFIXTAFT"].Value = aoiStatistic.SumOfTimeOfAllFixations;
        }

        if (this.gazeParams == (this.gazeParams | GazeParams.TimeToFirstFixAtTarget))
        {
          newRow.Cells["GFIXTARG"].Value = aoiStatistic.HitTimes.Count > 0 ? aoiStatistic.HitTimes[1] : -1;
        }

        if (this.gazeParams == (this.gazeParams | GazeParams.TimeToSecondFixAtTarget))
        {
          newRow.Cells["GFIX2TAR"].Value = aoiStatistic.HitTimes.Count > 1 ? aoiStatistic.HitTimes[2] : -1;
        }
      }
      else
      {
        if (this.gazeParams == (this.gazeParams | GazeParams.TimeAtTarget))
        {
          newRow.Cells["GFIXTAFT"].Value = -1;
        }

        if (this.gazeParams == (this.gazeParams | GazeParams.TimeToFirstFixAtTarget))
        {
          newRow.Cells["GFIXTARG"].Value = -1;
        }

        if (this.gazeParams == (this.gazeParams | GazeParams.TimeToSecondFixAtTarget))
        {
          newRow.Cells["GFIX2TAR"].Value = -1;
        }
      }

      // Fixation connections path length
      float pathLengthGaze = CalcPathLengthOfFixationConnections(fixationTable);
      if (this.gazeParams == (this.gazeParams | GazeParams.Pathlength))
      {
        newRow.Cells["GFIXPATH"].Value = pathLengthGaze;
      }

      if (this.gazeParams == (this.gazeParams | GazeParams.PathlengthPS))
      {
        newRow.Cells["GFIXPApS"].Value = pathLengthGaze > 0 ? pathLengthGaze / duration * 1000 : -1;
      }

      if (this.gazeParams == (this.gazeParams | GazeParams.AverageSaccadeLength))
      {
        newRow.Cells["GFIXSALE"].Value = pathLengthGaze > 0 ? pathLengthGaze / (fixationTable.Rows.Count - 1) : -1;
      }

      if (this.gazeParams == (this.gazeParams | GazeParams.AverageSaccadeVelocity))
      {
        newRow.Cells["GFIXSAVE"].Value = CalcAverageSaccadeVelocity(fixationTable);
      }

      // Custom fixation variables
      if (this.gazeParams == (this.gazeParams | GazeParams.Custom))
      {
        foreach (CustomVariable var in this.gazeCustomParams)
        {
          if (var.IsAOIGroup)
          {
            // AOI specifies AOI group
            DataTable aoiTable
              = Document.ActiveDocument.DocDataSet.AOIsAdapter.GetDataByTrialIDAndGroup(trialID, var.AOIName);

            VGElementCollection aois = new VGElementCollection();
            foreach (DataRow row in aoiTable.Rows)
            {
              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);
              aois.Add(aoi);
            }

            AOIStatistic aoiStatistic = CalcAOIStatistic(fixationView, aois);

            switch (var.ParamType)
            {
              case ParamTypes.CompleteTime:
                newRow.Cells[var.ColumnName].Value = aoiStatistic.SumOfTimeOfAllFixations;
                break;
              case ParamTypes.TimeUntil:
                newRow.Cells[var.ColumnName].Value = aoiStatistic.HitTimes.Count > var.Number - 1 ? aoiStatistic.HitTimes[var.Number] : -1;
                break;
              case ParamTypes.NumberOf:
                newRow.Cells[var.ColumnName].Value = aoiStatistic.FixationCount;
                break;
              case ParamTypes.FixationDurationMean:
                newRow.Cells[var.ColumnName].Value = aoiStatistic.FixationDurationMean;
                break;
              case ParamTypes.FixationDurationMedian:
                newRow.Cells[var.ColumnName].Value = aoiStatistic.FixationDurationMedian;
                break;
              case ParamTypes.Regressions:
                newRow.Cells[var.ColumnName].Value = CalcRegressions(fixationView, aois, var.Number);
                break;
              case ParamTypes.SaccadeDuration:
                newRow.Cells[var.ColumnName].Value = aoiStatistic.SaccadeDuration;
                break;
              case ParamTypes.SaccadeLength:
                newRow.Cells[var.ColumnName].Value = aoiStatistic.SaccadeLength;
                break;
              case ParamTypes.SaccadeVelocity:
                newRow.Cells[var.ColumnName].Value = aoiStatistic.SaccadeVelocity;
                break;
            }
          }
          else if (var.AOIName != string.Empty)
          {
            // AOI specifies a single AOI
            DataTable aoiTable
              = Document.ActiveDocument.DocDataSet.AOIsAdapter.GetDataByTrialIDAndShapeName(trialID, var.AOIName);

            if (aoiTable.Rows.Count == 1)
            {
              string strPtList = aoiTable.Rows[0]["ShapePts"].ToString();
              string aoiType = aoiTable.Rows[0]["ShapeType"].ToString();
              string aoiName = aoiTable.Rows[0]["ShapeName"].ToString();
              string shapeGroup = aoiTable.Rows[0]["ShapeGroup"].ToString();

              VGElement aoi = Queries.GetVGElementFromDatabase(aoiType, aoiName, shapeGroup, strPtList);
              VGElementCollection aoiContainer = new VGElementCollection();
              aoiContainer.Add(aoi);
              AOIStatistic aoiStatistic = CalcAOIStatistic(fixationView, aoiContainer);

              switch (var.ParamType)
              {
                case ParamTypes.CompleteTime:
                  newRow.Cells[var.ColumnName].Value = aoiStatistic.SumOfTimeOfAllFixations;
                  break;
                case ParamTypes.TimeUntil:
                  newRow.Cells[var.ColumnName].Value = aoiStatistic.HitTimes.Count > var.Number - 1 ? aoiStatistic.HitTimes[var.Number] : -1;
                  break;
                case ParamTypes.NumberOf:
                  newRow.Cells[var.ColumnName].Value = aoiStatistic.FixationCount;
                  break;
                case ParamTypes.FixationDurationMean:
                  newRow.Cells[var.ColumnName].Value = aoiStatistic.FixationDurationMean;
                  break;
                case ParamTypes.FixationDurationMedian:
                  newRow.Cells[var.ColumnName].Value = aoiStatistic.FixationDurationMedian;
                  break;
                case ParamTypes.Regressions:
                  newRow.Cells[var.ColumnName].Value = CalcRegressions(fixationView, aoiContainer, var.Number);
                  break;
                case ParamTypes.SaccadeDuration:
                  newRow.Cells[var.ColumnName].Value = aoiStatistic.SaccadeDuration;
                  break;
                case ParamTypes.SaccadeLength:
                  newRow.Cells[var.ColumnName].Value = aoiStatistic.SaccadeLength;
                  break;
                case ParamTypes.SaccadeVelocity:
                  newRow.Cells[var.ColumnName].Value = aoiStatistic.SaccadeVelocity;
                  break;
              }
            }
            else
            {
              newRow.Cells[var.ColumnName].Value = -2;
            }
          }
          else if (var.ParamType == ParamTypes.Regressions)
          {
            newRow.Cells[var.ColumnName].Value = CalcRegressions(fixationView, null, var.Number);
          }
          else
          {
            newRow.Cells[var.ColumnName].Value = -2;
          }
        }
      }

      fixationTable.Dispose();
    }
Esempio n. 3
0
    /// <summary>
    /// This static methods calculates the mean saccade duration, length and velocity from the given table of fixations
    /// from the database
    /// </summary>
    /// <param name="fixationsInAOIs">A <see cref="DataTable"/> with the fixations.</param>
    /// <param name="saccadeDuration">The mean saccade duration</param>
    /// <param name="saccadeLength">The mean saccade length</param>
    /// <param name="saccadeVelocity">The mean saccade velocity</param>
    private static void GetSaccadeArrays(
      DataTable fixationsInAOIs,
      out double saccadeDuration,
      out double saccadeLength,
      out double saccadeVelocity)
    {
      List<double> saccadeDurations = new List<double>();
      List<double> saccadeLengths = new List<double>();
      List<double> saccadeVelocitys = new List<double>();

      PointF lastFixationCenter = PointF.Empty;
      double lastFixationEndTime = 0;
      int lastCountInTrial = 0;

      for (int i = 0; i < fixationsInAOIs.Rows.Count; i++)
      {
        DataRow row = fixationsInAOIs.Rows[i];
        double posX = Convert.ToDouble(row["PosX"]);
        double posY = Convert.ToDouble(row["PosY"]);
        PointF fixationCenter = new PointF((float)posX, (float)posY);
        double fixationDuration = Convert.ToDouble(row["Length"]);
        double fixationStartTime = Convert.ToDouble(row["StartTime"]);
        int countInTrial = Convert.ToInt32(row["CountInTrial"]);

        if (i > 0 && (countInTrial == lastCountInTrial + 1))
        {
          double currentSaccadeDuration = fixationStartTime - lastFixationEndTime;
          double currentSaccadeLength = VGPolyline.Distance(fixationCenter, lastFixationCenter);
          saccadeDurations.Add(currentSaccadeDuration);
          saccadeLengths.Add(currentSaccadeLength);
          saccadeVelocitys.Add(currentSaccadeLength / currentSaccadeDuration);
        }

        lastFixationEndTime = fixationStartTime + fixationDuration;
        lastFixationCenter = fixationCenter;
        lastCountInTrial = countInTrial;
      }

      // -1 : no saccades in AOI
      // Calculate saccade duration mean
      Descriptive descriptives = new Descriptive(saccadeDurations.ToArray());
      if (saccadeDurations.Count > 0)
      {
        descriptives.Analyze(); // analyze the data
      }

      saccadeDuration = saccadeDurations.Count == 0 ? -1 : descriptives.Result.Mean;

      // Calculate saccade length mean
      descriptives = new Descriptive(saccadeLengths.ToArray());

      if (saccadeLengths.Count > 0)
      {
        descriptives.Analyze(); // analyze the data
      }

      saccadeLength = saccadeLengths.Count == 0 ? -1 : descriptives.Result.Mean;

      // Calculate saccade velocitys mean
      descriptives = new Descriptive(saccadeVelocitys.ToArray());

      if (saccadeVelocitys.Count > 0)
      {
        descriptives.Analyze(); // analyze the data
      }

      // -1 : no fixations in AOI
      saccadeVelocity = saccadeVelocitys.Count == 0 ? -1 : descriptives.Result.Mean;
    }