示例#1
0
        ///////////////////////////////////////////////////////////////////////////////
        // Methods for doing main class job                                          //
        ///////////////////////////////////////////////////////////////////////////////
        #region PRIVATEMETHODS

        /// <summary>
        /// Writes given fixation data into the data sets fixation tables.
        /// </summary>
        /// <param name="fixationToSave">Fixation to be written to database</param>
        private void SaveFixationToTable(Fixation fixationToSave)
        {
            DataTable fixTable = null;

            if (fixationToSave.SampleType == (fixationToSave.SampleType | SampleType.Gaze))
            {
                fixTable = Document.ActiveDocument.DocDataSet.GazeFixations;
            }
            else if (fixationToSave.SampleType == (fixationToSave.SampleType | SampleType.Mouse))
            {
                fixTable = Document.ActiveDocument.DocDataSet.MouseFixations;
            }

            // Create New Fixation DataRow
            DataRow workRowFixationData;

            workRowFixationData = fixTable.NewRow();

            // Fill with Data
            workRowFixationData["SubjectName"]   = fixationToSave.SubjectName;
            workRowFixationData["TrialID"]       = fixationToSave.TrialID;
            workRowFixationData["TrialSequence"] = fixationToSave.TrialSequence;
            workRowFixationData["CountInTrial"]  = fixationToSave.CountInTrial;
            workRowFixationData["StartTime"]     = fixationToSave.StartTime;
            workRowFixationData["Length"]        = fixationToSave.Length;
            workRowFixationData["PosX"]          = fixationToSave.PosX;
            workRowFixationData["PosY"]          = fixationToSave.PosY;

            // Write into DB
            try
            {
                fixTable.Rows.Add(workRowFixationData);
            }
            catch (Exception ex)
            {
                ExceptionMethods.HandleException(ex);
            }
        }
示例#2
0
    ///////////////////////////////////////////////////////////////////////////////
    // Methods for doing main class job                                          //
    ///////////////////////////////////////////////////////////////////////////////
    #region PRIVATEMETHODS

    /// <summary>
    /// Writes given fixation data into the data sets fixation tables.
    /// </summary>
    /// <param name="fixationToSave">Fixation to be written to database</param>
    private void SaveFixationToTable(Fixation fixationToSave)
    {
      DataTable fixTable = null;
      if (fixationToSave.SampleType == (fixationToSave.SampleType | SampleType.Gaze))
      {
        fixTable = Document.ActiveDocument.DocDataSet.GazeFixations;
      }
      else if (fixationToSave.SampleType == (fixationToSave.SampleType | SampleType.Mouse))
      {
        fixTable = Document.ActiveDocument.DocDataSet.MouseFixations;
      }

      // Create New Fixation DataRow
      DataRow workRowFixationData;
      workRowFixationData = fixTable.NewRow();

      // Fill with Data
      workRowFixationData["SubjectName"] = fixationToSave.SubjectName;
      workRowFixationData["TrialID"] = fixationToSave.TrialID;
      workRowFixationData["TrialSequence"] = fixationToSave.TrialSequence;
      workRowFixationData["CountInTrial"] = fixationToSave.CountInTrial;
      workRowFixationData["StartTime"] = fixationToSave.StartTime;
      workRowFixationData["Length"] = fixationToSave.Length;
      workRowFixationData["PosX"] = fixationToSave.PosX;
      workRowFixationData["PosY"] = fixationToSave.PosY;

      // Write into DB
      try
      {
        fixTable.Rows.Add(workRowFixationData);
      }
      catch (Exception ex)
      {
        ExceptionMethods.HandleException(ex);
      }
    }
示例#3
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);
    }
示例#4
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);
        }