Пример #1
0
 /// <summary>
 /// Adds a range of <see cref="VGElement"/>s to the collection.
 /// </summary>
 /// <param name="elementCollection">The <see cref="VGElementCollection"/> to be
 /// added to the end of the collection.</param>
 public void AddRange(VGElementCollection elementCollection)
 {
     foreach (VGElement element in elementCollection)
     {
         this.List.Add(element);
     }
 }
Пример #2
0
 /// <summary>
 /// Initializes a new instance of the Slide class.
 /// </summary>
 public Slide()
 {
     this.stimuli                   = new VGElementCollection();
     this.activeXElements           = new VGElementCollection();
     this.targets                   = new VGElementCollection();
     this.correctResponses          = new StopConditionCollection();
     this.links                     = new StopConditionCollection();
     this.stopConditions            = new StopConditionCollection();
     this.category                  = string.Empty;
     this.TriggerSignal             = new Trigger(TriggerSignaling.None, TriggerOutputDevices.LPT, 40, 255, 0x0378);
     this.IdOfPreSlideFixationTrial = -1;
 }
Пример #3
0
 /// <summary>
 /// Removes the first occurrence of a specific
 /// <see cref="VGElement"/> from the collection.
 /// </summary>
 /// <param name="list">The <see cref="VGElement"/>
 /// to remove from the collection.</param>
 public void RemoveAll(VGElementCollection list)
 {
     if (list != null && list.Count > 0)
     {
         foreach (VGElement element in list)
         {
             if (this.List.Contains(element))
             {
                 this.List.Remove(element);
             }
         }
     }
 }
Пример #4
0
        /// <summary>
        /// Searches the collection list for all members with
        /// the given group and returns this items in a new
        /// <see cref="VGElementCollection"/>
        /// </summary>
        /// <param name="searchGroup">The <see cref="VGStyleGroup"/>
        /// that the elements should match.</param>
        /// <returns>A <see cref="VGElementCollection"/> with the
        /// members of the list that are in the given search group.</returns>
        public VGElementCollection FindAllGroupMembers(VGStyleGroup searchGroup)
        {
            VGElementCollection subList = new VGElementCollection();

            foreach (VGElement element in this.List)
            {
                if ((element.StyleGroup & searchGroup) == searchGroup)
                {
                    subList.Add(element);
                }
            }

            return(subList);
        }
Пример #5
0
        /// <summary>
        /// Removes all occurrences of <see cref="VGElement"/>s
        /// with the given name from the collection.
        /// </summary>
        /// <param name="name">The <see cref="string"/> with the name of the elements
        /// to remove from the collection.</param>
        public void Remove(string name)
        {
            if (name != string.Empty)
            {
                VGElementCollection removeList = new VGElementCollection();
                foreach (VGElement element in this.List)
                {
                    if (element.Name == name)
                    {
                        removeList.Add(element);
                    }
                }

                foreach (VGElement element in removeList)
                {
                    this.List.Remove(element);
                }
            }
        }
Пример #6
0
 /// <summary>
 /// Initializes a new instance of the Slide class.
 /// </summary>
 /// <param name="newName">A <see cref="string"/> with the unique name of this Slide</param>
 /// <param name="newBackgroundColor">A <see cref="Color"/> with the background color for this slide</param>
 /// <param name="newBackgroundImage">A <see cref="Image"/> with the background image for this slide</param>
 /// <param name="newStopConditions">A <see cref="StopConditionCollection"/> list
 /// of responses for which the slide presentation should stop.</param>
 /// <param name="newResponses">An optional <see cref="StopConditionCollection"/> with responses
 /// that indicate correct answers.</param>
 /// <param name="newCategory">A <see cref="string"/> with an optional category
 /// that gives an additional slide distinction.</param>
 /// <param name="newPresentationSize">A <see cref="Size"/> with the original
 /// presentation size of this slide.</param>
 public Slide(
     string newName,
     Color newBackgroundColor,
     Image newBackgroundImage,
     StopConditionCollection newStopConditions,
     StopConditionCollection newResponses,
     string newCategory,
     Size newPresentationSize)
 {
     this.stimuli                   = new VGElementCollection();
     this.activeXElements           = new VGElementCollection();
     this.targets                   = new VGElementCollection();
     this.links                     = new StopConditionCollection();
     this.stopConditions            = newStopConditions;
     this.BackgroundColor           = newBackgroundColor;
     this.BackgroundImage           = newBackgroundImage;
     this.name                      = newName;
     this.correctResponses          = newResponses;
     this.category                  = newCategory;
     this.PresentationSize          = newPresentationSize;
     this.IdOfPreSlideFixationTrial = -1;
 }
Пример #7
0
    /// <summary>
    /// Removes all occurrences of <see cref="VGElement"/>s
    /// with the given name from the collection. 
    /// </summary>
    /// <param name="name">The <see cref="string"/> with the name of the elements
    /// to remove from the collection.</param>
    public void Remove(string name)
    {
      if (name != string.Empty)
      {
        VGElementCollection removeList = new VGElementCollection();
        foreach (VGElement element in this.List)
        {
          if (element.Name == name)
          {
            removeList.Add(element);
          }
        }

        foreach (VGElement element in removeList)
        {
          this.List.Remove(element);
        }
      }
    }
Пример #8
0
    /// <summary>
    /// This static method calculates the number of regressions in the given AOI 
    /// using the given table of fixations and line height.
    /// </summary>
    /// <param name="fixationView">A <see cref="DataView"/> with the list of fixations</param>
    /// <param name="aois">A <see cref="VGElementCollection"/> with the AOIs.</param>
    /// <param name="lineHeight">The line height of the textual area.</param>
    /// <returns>An <see cref="Int32"/> with the number of regressions.</returns>
    private static int CalcRegressions(
      DataView fixationView,
      VGElementCollection aois,
      int lineHeight)
    {
      int regressionCount = 0;

      // Check if we are using AOIs and we did not found any.
      if (aois != null && aois.Count == 0)
      {
        // -2 = this AOIs was not definded in this trial
        regressionCount = -2;
        return regressionCount;
      }

      PointF lastLocation = PointF.Empty;
      VGElement lastHittedAOI = null;
      foreach (DataRowView fixRow in fixationView)
      {
        // Calculate overall regressions
        if (aois != null)
        {
          // Calculate regressions in single AOI
          if (aois.Count == 1)
          {
            if (IsFixAtTarget(aois, fixRow) == null)
            {
              // Reset last location if fixation was outside AOI
              // so first refixation in AOI will restart the count
              lastLocation = PointF.Empty;
              continue;
            }
          }
          else
          {
            // Calculate regressions in AOI groups
            VGElement hittedAOI = IsFixAtTarget(aois, fixRow);
            if (hittedAOI == null)
            {
              // Reset last location if fixation was outside AOI
              // so first refixation in AOI will restart the count
              lastLocation = PointF.Empty;
              lastHittedAOI = null;
              continue;
            }
            else if (hittedAOI != lastHittedAOI)
            {
              // Reset last location if fixation was outside last AOI
              // but inside other AOI of same group
              // so first refixation in AOI will restart the count
              lastLocation = PointF.Empty;
              lastHittedAOI = hittedAOI;
              continue;
            }
          }
        }

        // Get Fixation location
        PointF currentLocation = new PointF(
          Convert.ToSingle(fixRow["PosX"]),
          Convert.ToSingle(fixRow["PosY"]));

        if (currentLocation.X > lastLocation.X)
        {
          // Default forward, no regression
          lastLocation = currentLocation;
          continue;
        }

        if (currentLocation.Y > lastLocation.Y + lineHeight)
        {
          // Default line change, no regression
          lastLocation = currentLocation;
          continue;
        }

        if (currentLocation.Y < lastLocation.Y - 2 * lineHeight)
        {
          // Big Line skipping upwards, no regression
          lastLocation = currentLocation;
          continue;
        }

        // Either go back in the line or go back vertical,
        // both is a regression
        lastLocation = currentLocation;
        regressionCount++;
      }

      return regressionCount;
    }
Пример #9
0
 /// <summary>
 /// Initializes a new instance of the Slide class.
 /// </summary>
 /// <param name="newName">A <see cref="string"/> with the unique name of this Slide</param>
 /// <param name="newBackgroundColor">A <see cref="Color"/> with the background color for this slide</param>
 /// <param name="newBackgroundImage">A <see cref="Image"/> with the background image for this slide</param>
 /// <param name="newStopConditions">A <see cref="StopConditionCollection"/> list
 /// of responses for which the slide presentation should stop.</param>
 /// <param name="newResponses">An optional <see cref="StopConditionCollection"/> with responses
 /// that indicate correct answers.</param>
 /// <param name="newCategory">A <see cref="string"/> with an optional category 
 /// that gives an additional slide distinction.</param>
 /// <param name="newPresentationSize">A <see cref="Size"/> with the original 
 /// presentation size of this slide.</param>
 public Slide(
   string newName,
   Color newBackgroundColor,
   Image newBackgroundImage,
   StopConditionCollection newStopConditions,
   StopConditionCollection newResponses,
   string newCategory,
   Size newPresentationSize)
 {
   this.stimuli = new VGElementCollection();
   this.activeXElements = new VGElementCollection();
   this.targets = new VGElementCollection();
   this.links = new StopConditionCollection();
   this.stopConditions = newStopConditions;
   this.BackgroundColor = newBackgroundColor;
   this.BackgroundImage = newBackgroundImage;
   this.name = newName;
   this.correctResponses = newResponses;
   this.category = newCategory;
   this.PresentationSize = newPresentationSize;
   this.IdOfPreSlideFixationTrial = -1;
 }
Пример #10
0
    /// <summary>
    /// Calculates whether the fixation given in datarow hits one of the 
    /// areas of interest given in the AOI Table and returns the 
    /// name of the AOI and its category.
    /// </summary>
    /// <param name="aoiCollection"><see cref="VGElementCollection"/> of areas of interest for current trial</param>
    /// <param name="fixationRow">fixational row</param>
    /// <returns>List of AOI name/group pairs that are hitted from fixation.</returns>
    public static List<string[]> FixationHitsAOI(
      VGElementCollection aoiCollection,
      DataRowView fixationRow)
    {
      List<string[]> hittedAOIs = new List<string[]>();
      string aoiName = "nowhere";
      string aoiGroup = "nowhere";

      foreach (VGElement aoiElement in aoiCollection)
      {
        // Check for intersection between newPath and Clicklist or Fixationlist
        PointF searchPoint = new PointF(
          Convert.ToSingle(fixationRow["PosX"]),
          Convert.ToSingle(fixationRow["PosY"]));

        if (aoiElement.Contains(searchPoint, tolerance))
        {
          aoiGroup = aoiElement.ElementGroup == null ? string.Empty : aoiElement.ElementGroup.Trim();
          aoiName = aoiElement.Name.Trim();
          if (aoiGroup == string.Empty || aoiGroup == " ")
          {
            aoiGroup = "nowhere";
          }

          string[] hittedAOI = { aoiName, aoiGroup };
          hittedAOIs.Add(hittedAOI);
        }
      }

      return hittedAOIs;
    }
Пример #11
0
    /// <summary>
    /// Calculates whether the fixation given in datarow hits one of the 
    /// areas of interest given in the AOI Table
    /// </summary>
    /// <param name="aois">A <see cref="VGElementCollection"/> with the areas of interest for current trial.</param>
    /// <param name="fixationRow">fixational row</param>
    /// <returns>Row number of aoi that is hitted from fixation.</returns>
    private static VGElement IsFixAtTarget(VGElementCollection aois, DataRowView fixationRow)
    {
      foreach (VGElement aoi in aois)
      {
        // Check for intersection
        PointF searchPoint = new PointF(
          Convert.ToSingle(fixationRow["PosX"]),
          Convert.ToSingle(fixationRow["PosY"]));

        if (aoi.Contains(searchPoint, tolerance))
        {
          return aoi;
        }
      }

      return null;
    }
Пример #12
0
    /// <summary>
    /// This method converts the AOI table with areas of interest from the database
    /// into a list of <see cref="VGElement"/>s.
    /// </summary>
    /// <param name="aoiTable">The <see cref="DataTable"/> with the AOIs.</param>
    /// <returns>A <see cref="List{VGElement}"/> with the shapes.</returns>
    protected virtual VGElementCollection GetAOIElements(DataTable aoiTable)
    {
      Pen defaultPen = new Pen(Properties.Settings.Default.AOIStandardColor, Properties.Settings.Default.AOIStandardWidth);
      Pen targetPen = new Pen(Properties.Settings.Default.AOITargetColor, Properties.Settings.Default.AOITargetWidth);
      Pen searchRectPen = new Pen(Properties.Settings.Default.AOISearchRectColor, Properties.Settings.Default.AOISearchRectWidth);
      Font defaultFont = (Font)Properties.Settings.Default.AOIStandardFont.Clone();
      Font targetFont = (Font)Properties.Settings.Default.AOITargetFont.Clone();
      Font searchRectFont = (Font)Properties.Settings.Default.AOISearchRectFont.Clone();
      Color defaultFontColor = Properties.Settings.Default.AOIStandardFontColor;
      Color targetFontColor = Properties.Settings.Default.AOITargetFontColor;
      Color searchRectFontColor = Properties.Settings.Default.AOISearchRectFontColor;

      VGElementCollection aoiList = new VGElementCollection();
      int counter = 0;

      try
      {
        foreach (DataRow row in aoiTable.Rows)
        {
          string strPtList = row["ShapePts"].ToString();
          string shapeName = row["ShapeName"].ToString();
          Pen usedPen = defaultPen;
          Font usedFont = defaultFont;
          Color usedFontColor = defaultFontColor;
          VGStyleGroup usedStyleGroup = VGStyleGroup.AOI_NORMAL;
          List<PointF> pointList = ObjectStringConverter.StringToPointFList(strPtList);
          string usedElementGroup = row["ShapeGroup"].ToString();
          switch (usedElementGroup)
          {
            case "Target":
              usedPen = targetPen;
              usedFont = targetFont;
              usedFontColor = targetFontColor;
              usedStyleGroup = VGStyleGroup.SCA_GRID_AOI;
              break;
            case "SearchRect":
              usedPen = searchRectPen;
              usedFont = searchRectFont;
              usedFontColor = searchRectFontColor;
              usedStyleGroup = VGStyleGroup.SCA_GRID_AOI;
              break;
            default:
              usedPen = defaultPen;
              usedFont = defaultFont;
              usedFontColor = defaultFontColor;
              usedStyleGroup = VGStyleGroup.SCA_GRID_AOI;
              break;
          }

          // Create the shape depending on ShapeType
          RectangleF boundingRect = new RectangleF();
          switch (row["ShapeType"].ToString())
          {
            case "Rectangle":
              boundingRect.Location = pointList[0];
              boundingRect.Width = pointList[2].X - pointList[0].X;
              boundingRect.Height = pointList[2].Y - pointList[0].Y;

              // Create Rect with defined stroke
              VGRectangle newRect = new VGRectangle(
                ShapeDrawAction.NameAndEdge,
                usedPen,
                usedFont,
                usedFontColor,
                boundingRect,
                usedStyleGroup,
                shapeName,
                usedElementGroup);

              aoiList.Add(newRect);
              break;
            case "Ellipse":
              boundingRect.Location = pointList[0];
              boundingRect.Width = pointList[2].X - pointList[0].X;
              boundingRect.Height = pointList[2].Y - pointList[0].Y;

              // Create Rect with defined stroke
              VGEllipse newEllipse = new VGEllipse(
                ShapeDrawAction.NameAndEdge,
                usedPen,
                usedFont,
                usedFontColor,
                boundingRect,
                usedStyleGroup,
                shapeName,
                usedElementGroup);

              aoiList.Add(newEllipse);
              break;
            case "Polyline":
              // Create Polyline with defined stroke
              VGPolyline newPolyline = new VGPolyline(
                ShapeDrawAction.NameAndEdge,
                usedPen,
                usedFont,
                usedFontColor,
                usedStyleGroup,
                shapeName,
                usedElementGroup);

              foreach (PointF point in pointList)
              {
                newPolyline.AddPt(point);
              }

              newPolyline.ClosePolyline();
              aoiList.Add(newPolyline);
              boundingRect = newPolyline.Bounds;
              break;
          }

          counter++;
        }
      }
      catch (Exception ex)
      {
        ExceptionMethods.HandleException(ex);
      }

      return aoiList;
    }
Пример #13
0
    /// <summary>
    /// Calculates whether the mouse click position given in datarow hits one of the 
    /// areas of interest given in the AOI Table
    /// </summary>
    /// <param name="aois">A <see cref="VGElementCollection"/> with the areas of interest for current trial.</param>
    /// <param name="clickLocation">A <see cref="Point"/> with the location of the click in screen coordinates.</param>
    /// <returns>Row number of AOI that is hitted from the mouse click.</returns>
    private static int IsClickAtTarget(VGElementCollection aois, Point clickLocation)
    {
      // Never over AOI
      int hitIndex = -1;

      if (aois.Count == 0)
      {
        // NO AOIs definded
        hitIndex = -2;
        return hitIndex;
      }

      int rowCounter = 0;
      foreach (VGElement target in aois)
      {
        // Check for intersection between newPath and Clicklist or Fixationlist
        if (target.Contains(clickLocation, tolerance))
        {
          hitIndex = rowCounter;
          break;
        }

        rowCounter++;
      }

      return hitIndex;
    }
Пример #14
0
 /// <summary>
 ///   Custom initializations.
 /// </summary>
 private void InitializeOther()
 {
   this.elements = new VGElementCollection();
   this.grayBrush = new SolidBrush(Color.FromArgb(200, Color.Black));
   this.presentationSize = Screen.PrimaryScreen.Bounds.Size;
 }
Пример #15
0
    /// <summary>
    /// Overridden <see cref="Control.MouseDown"/> event handler.
    /// Starts requested shape creation when left mouse button is pressed.
    /// Otherwise looks for elements under mouse cursor and selects them.
    /// If there is already a selected element and the mouse is over a grab
    /// handle it is selected.
    /// </summary>
    /// <remarks>Pressing the ALT key during selection iterates
    /// through the elementsUnderMouseCursor collection.</remarks>
    /// <param name="e">The <see cref="MouseEventArgs"/> with the event data (click point).</param>
    protected override void OnMouseDown(MouseEventArgs e)
    {
      // base.OnMouseDown(e);

      // Achieve focus to the picture, because otherwise it will not
      // receive input keys which are interesting as modifiers.
      this.Focus();

      if (Control.ModifierKeys != Keys.ShiftKey)
      {
        // Transform mouse down point to stimulus coordinates
        PointF mouseLocationF = this.GetTransformedMouseLocation(e.Location);
        Point mouseLocation = Point.Round(mouseLocationF);

        if (this.state != BuildState.None)
        {
          // Is creating a new shape
          // Left Mouse Button pressed, so start Logging
          if (e.Button == MouseButtons.Left)
          {
            this.state = BuildState.FirstPointSet;

            // Add the new shape to the list.
            if (!this.Elements.Contains(this.newShape))
            {
              this.Elements.Add(this.newShape);
            }

            // Select it
            this.SelectedElement = this.newShape;

            // save click point for later bounding rectangle creation
            this.firstClickPoint = mouseLocationF;

            // Special handling for polyline construction
            // every click is a polyline point
            // up to the moment the polyline is closed
            if (this.newShape is VGPolyline)
            {
              this.currentLine.FirstPoint = this.firstClickPoint;

              // Add the _CurrentLine element during polyline
              // creation
              if (!Elements.Contains(this.currentLine))
              {
                Elements.Add(this.currentLine);
              }

              // Cast newShape to polyline
              VGPolyline poly = (VGPolyline)this.newShape;

              // Check for closing polyline conditions
              if (this.PointsAreNear(poly.FirstPt, mouseLocationF) &&
                poly.GetPointCount() > 2)
              {
                // If the mouse click point is near the first point
                // close polyline.
                poly.ClosePolyline();

                this.state = BuildState.None;

                // New Graphic element created, so notify listeners.
                this.OnShapeAdded(new ShapeEventArgs(this.newShape));

                // CleanUp creation mode
                this.Elements.Remove(this.currentLine);
                this.newShape = null;
              }
              else
              {
                // Point is anywhere else, but not near the first
                // polyline point.
                // Add new polyline point and update CurrentLine.
                this.currentLine.FirstPoint = mouseLocationF;
                poly.AddPt(mouseLocationF);
              }
            }
            else if (this.newShape is VGLine)
            {
              // Cast newShape to VGLine
              VGLine line = (VGLine)this.newShape;
              line.FirstPoint = this.firstClickPoint;
            }
            else if (this.newShape is VGFlash)
            {
              // Cast newShape to VGFlash
              VGFlash flash = (VGFlash)this.newShape;
              flash.InitializeOnControl(this.Parent, false, this.StimulusToScreen);
            }
          }
        }
        else
        {
          // We are not in new shape creation mode
          if (e.Button == MouseButtons.Left)
          {
            this.mouseDownPoint = e.Location;

            // Store elements under mouse cursor.
            VGElementCollection elementsUnderMouseCursor = new VGElementCollection();
            int numberOfElements = this.Elements.Count;
            for (int i = 0; i < numberOfElements; i++)
            {
              VGElement currentElement = this.Elements[numberOfElements - i - 1];
              if (currentElement.Contains(mouseLocation))
              {
                elementsUnderMouseCursor.Add(currentElement);
                if (currentElement == this.SelectedElement)
                {
                  this.counterUnderCursor = elementsUnderMouseCursor.Count - 1;
                }
              }
            }

            if (this.selectedElement == null)
            {
              // Check whether an element lies under
              // mouse cursor. Select the next item.
              if (elementsUnderMouseCursor.Count > 0)
              {
                this.SelectedElement = elementsUnderMouseCursor[0];
                this.selectedElement.IsInEditMode = true;
              }
              else
              {
                this.SelectedElement = null;
              }
            }
            else if (this.selectedElement.Contains(mouseLocation))
            {
              // Click in selected element 
              // could be more than one, so iterate if Modifier alt is pressed.
              if (Control.ModifierKeys == Keys.Alt)
              {
                this.Cursor = Cursors.Default;
                this.counterUnderCursor++;

                // Reset counter if larger than element list size.
                if (this.counterUnderCursor >= elementsUnderMouseCursor.Count)
                {
                  this.counterUnderCursor = 0;
                }

                // Select next item if there is any
                if (elementsUnderMouseCursor.Count > 1)
                {
                  this.ResetSelectedElement();

                  // Use property to invoke Shape Selected event.
                  this.SelectedElement = elementsUnderMouseCursor[this.counterUnderCursor];
                  this.selectedElement.IsInEditMode = true;
                }
              }
              else
              {
                // No alt is pressed
                // Select grab handle, if mouse is over it
                foreach (GrabHandle handle in this.selectedElement.GrabHandles)
                {
                  if (handle.Contains(mouseLocation))
                  {
                    this.activeGrabHandle = handle;
                    break;
                  }

                  // Select center handle
                  this.activeGrabHandle = this.selectedElement.GrabHandles[0];
                }
              }
            }
            else
            {
              // Click in region outside current selected element
              // Reset selected element. And look for other element
              // under mouse cursor.
              this.ResetSelectedElement();

              // Select the first element that lies under mouse cursor.
              if (elementsUnderMouseCursor.Count > 0)
              {
                this.SelectedElement = elementsUnderMouseCursor[0];
                this.selectedElement.IsInEditMode = true;
              }
              else
              {
                this.SelectedElement = null;
              }
            }

            this.DrawForeground(false);
          }
        }
      }
    }
Пример #16
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();
    }
Пример #17
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;
    }
Пример #18
0
    /// <summary>
    /// This method calculates the transition matrix
    /// of the given trial between the AOIs of this trial.
    /// </summary>
    /// <param name="fixations">The fixations of the current trial</param>
    /// <param name="trialsAOIs">A <see cref="VGElementCollection"/> with the AOIs.</param>
    /// <returns>An two dimensional <see cref="Array"/> with 
    /// integers indicating the number of transitions between AOI in row and column.</returns>
    public static Array CreateTransitionMatrixForSingleAOIs(
      DataView fixations,
      VGElementCollection trialsAOIs)
    {
      int aoiCount = trialsAOIs.Count;

      // Create transition matrix
      Array transitionMatrix = Array.CreateInstance(typeof(int), aoiCount + 1, aoiCount + 1);

      // Assign names and indices of AOI.
      Dictionary<string, int> groupIndexAssignment = new Dictionary<string, int>();
      groupIndexAssignment.Add("nowhere", 0);
      for (int i = 0; i < aoiCount; i++)
      {
        string aoiGroupEntry = trialsAOIs[i].Name;
        if (!groupIndexAssignment.ContainsKey(aoiGroupEntry))
        {
          groupIndexAssignment.Add(aoiGroupEntry, i + 1);
        }
      }

      // Iterate selected subjects
      string foregoingHittedAOIName = string.Empty;
      string foregoingSubjectName = string.Empty;
      foreach (DataRowView fixationRow in fixations)
      {
        string subjectName = fixationRow["SubjectName"].ToString();
        if (subjectName != foregoingSubjectName)
        {
          foregoingHittedAOIName = string.Empty;
          foregoingSubjectName = subjectName;
        }

        string hittedAOIName = "nowhere";
        string hittedAOIGroup = "nowhere";
        List<string[]> hittedAOIs = Statistic.FixationHitsAOI(trialsAOIs, fixationRow);
        if (hittedAOIs.Count > 0)
        {
          // Take only first hitted AOI
          hittedAOIName = hittedAOIs[0][0];
          hittedAOIGroup = hittedAOIs[0][1];
        }

        if (foregoingHittedAOIName != string.Empty)
        {
          int indexOfHittedGroup = groupIndexAssignment[hittedAOIName];
          int indexOfForegoingGroup = groupIndexAssignment[foregoingHittedAOIName];
          int oldEntry = (int)transitionMatrix.GetValue(indexOfForegoingGroup, indexOfHittedGroup);
          int newEntry = oldEntry + 1;
          transitionMatrix.SetValue(newEntry, indexOfForegoingGroup, indexOfHittedGroup);
        }

        foregoingHittedAOIName = hittedAOIName;
      }

      return transitionMatrix;
    }
Пример #19
0
 /// <summary>
 /// Removes the first occurrence of a specific
 /// <see cref="VGElement"/> from the collection. 
 /// </summary>
 /// <param name="list">The <see cref="VGElement"/>
 /// to remove from the collection.</param>
 public void RemoveAll(VGElementCollection list)
 {
   if (list != null && list.Count > 0)
   {
     foreach (VGElement element in list)
     {
       if (this.List.Contains(element))
       {
         this.List.Remove(element);
       }
     }
   }
 }
Пример #20
0
    /// <summary>
    /// Searches the collection list for all members with
    /// the given group and returns this items in a new
    /// <see cref="VGElementCollection"/>
    /// </summary>
    /// <param name="searchGroup">The <see cref="VGStyleGroup"/>
    /// that the elements should match.</param>
    /// <returns>A <see cref="VGElementCollection"/> with the 
    /// members of the list that are in the given search group.</returns>
    public VGElementCollection FindAllGroupMembers(VGStyleGroup searchGroup)
    {
      VGElementCollection subList = new VGElementCollection();
      foreach (VGElement element in this.List)
      {
        if ((element.StyleGroup & searchGroup) == searchGroup)
        {
          subList.Add(element);
        }
      }

      return subList;
    }
Пример #21
0
    /// <summary>
    /// This method removes the elements for which the onset time
    /// is greater than the time of the given
    /// first valid sample.
    /// </summary>
    /// <param name="firstValidSample">
    /// A <see cref="TimedPoint"/>
    /// with the sample that is the first one not to be removed
    /// </param>
    private void RemoveFixations(TimedPoint firstValidSample)
    {
      var elementsToRemove = new VGElementCollection();
      var removedGazeFixationsCount = 0;
      var removedMouseFixationsCount = 0;
      foreach (VGElement element in this.Elements)
      {
        if (element.ElementGroup != "Default")
        {
          if (element.OnsetTime > firstValidSample.Time)
          {
            if (element.StyleGroup == VGStyleGroup.RPL_PEN_GAZE_FIX)
            {
              removedGazeFixationsCount++;
            }
            else if (element.StyleGroup == VGStyleGroup.RPL_PEN_MOUSE_FIX)
            {
              removedMouseFixationsCount++;
            }

            elementsToRemove.Add(element);
          }
          else if (element.EndTime > firstValidSample.Time)
          {
            // Scale ellipse
          }
        }
      }

      this.gazeFixations.RemoveRange(this.gazeFixations.Count - removedGazeFixationsCount, removedGazeFixationsCount);
      this.mouseFixations.RemoveRange(this.mouseFixations.Count - removedMouseFixationsCount, removedMouseFixationsCount);

      this.gazeFixConPolyline.RemoveLastPts(removedGazeFixationsCount);
      this.mouseFixConPolyline.RemoveLastPts(removedMouseFixationsCount);

      this.Elements.RemoveAll(elementsToRemove);
    }
        ///////////////////////////////////////////////////////////////////////////////
        // Construction and Initializing methods                                     //
        ///////////////////////////////////////////////////////////////////////////////
        #region CONSTRUCTION

        /// <summary>
        /// Initializes a new instance of the VGElementCollectionPropertyDescriptor class.
        /// </summary>
        /// <param name="collection">The <see cref="VGElementCollection"/>
        /// for this <see cref="PropertyDescriptor"/></param>
        /// <param name="index">The index to use.</param>
        public VGElementCollectionPropertyDescriptor(VGElementCollection collection, int index)
            : base("#" + index.ToString(), null)
        {
            this.collection = collection;
            this.index      = index;
        }
Пример #23
0
    /// <summary>
    /// This method draws the statistic bubbles and transisiton arrows
    ///   of given <see cref="SampleType"/> in given <see cref="VisualizationModes"/>.
    /// </summary>
    /// <param name="mode">
    /// The <see cref="VisualizationModes"/> to be used.
    /// </param>
    /// <param name="sampleType">
    /// The <see cref="SampleType"/> of the data.
    /// </param>
    public void DrawAOIStatistics(VisualizationModes mode, SampleType sampleType)
    {
      // Skip if no data available
      if (this.aoiStatistics == null)
      {
        return;
      }

      // Get all statistical elements
      var statisticalElements = this.Elements.FindAllGroupMembers(VGStyleGroup.AOI_STATISTICS_ARROW);
      statisticalElements.AddRange(this.Elements.FindAllGroupMembers(VGStyleGroup.AOI_STATISTICS_BUBBLE));

      this.Elements.RemoveAll(statisticalElements);

      var distances = new List<int>();

      var aoisWithoutSearchRects = new VGElementCollection();
      foreach (VGElement aoi in this.AoiCollection)
      {
        if (aoi.StyleGroup != VGStyleGroup.AOI_SEARCHRECT)
        {
          aoisWithoutSearchRects.Add(aoi);
        }
      }

      foreach (VGElement aoi in aoisWithoutSearchRects)
      {
        if (!this.aoiStatistics.ContainsKey(aoi.Name))
        {
          continue;
        }

        var aoiStatistic = this.aoiStatistics[aoi.Name];
        if ((mode & VisualizationModes.FixationTime) == VisualizationModes.FixationTime)
        {
          if (aoiStatistic.SumOfTimeOfAllFixations > 0)
          {
            var bounds = this.GetCircleBounds(aoi.Center, aoiStatistic.SumOfTimeOfAllFixations, mode);
            var ellipse = new VGEllipse(
              this.BubbleDrawAction, 
              this.BubblePen, 
              this.BubbleBrush, 
              this.BubbleFont, 
              this.BubbleFontColor, 
              bounds, 
              VGStyleGroup.AOI_STATISTICS_BUBBLE, 
              aoiStatistic.SumOfTimeOfAllFixations + " ms", 
              string.Empty);

            ellipse.TextAlignment = this.BubbleTextAlignment;
            distances.Add((int)(bounds.Width / 2));
            this.Elements.Add(ellipse);
          }
        }

        if ((mode & VisualizationModes.NumberOfFixations) == VisualizationModes.NumberOfFixations)
        {
          if (aoiStatistic.FixationCount > 0)
          {
            var bounds = this.GetCircleBounds(aoi.Center, aoiStatistic.FixationCount, mode);
            var ellipse = new VGEllipse(
              this.BubbleDrawAction, 
              this.BubblePen, 
              this.BubbleBrush, 
              this.BubbleFont, 
              this.BubbleFontColor, 
              bounds, 
              VGStyleGroup.AOI_STATISTICS_BUBBLE, 
              aoiStatistic.FixationCount.ToString(CultureInfo.InvariantCulture), 
              string.Empty);

            ellipse.TextAlignment = this.BubbleTextAlignment;
            distances.Add((int)(bounds.Width / 2));
            this.Elements.Add(ellipse);
          }
        }

        if ((mode & VisualizationModes.AverageFixationDuration) == VisualizationModes.AverageFixationDuration)
        {
          if (aoiStatistic.FixationDurationMean > 0)
          {
            var bounds = this.GetCircleBounds(aoi.Center, aoiStatistic.FixationDurationMean, mode);
            var ellipse = new VGEllipse(
              this.BubbleDrawAction, 
              this.BubblePen, 
              this.BubbleBrush, 
              this.BubbleFont, 
              this.BubbleFontColor, 
              bounds, 
              VGStyleGroup.AOI_STATISTICS_BUBBLE, 
              aoiStatistic.FixationDurationMean.ToString("N0") + " ms", 
              string.Empty);
            ellipse.TextAlignment = this.BubbleTextAlignment;
            distances.Add((int)(bounds.Width / 2));
            this.Elements.Add(ellipse);
          }
        }
      }

      // Check for absolute or relative transition values
      var absolute = (mode & VisualizationModes.AbsoluteTransitions) == VisualizationModes.AbsoluteTransitions;

      if ((mode & VisualizationModes.RelativeTransitions) == VisualizationModes.RelativeTransitions
          || (mode & VisualizationModes.AbsoluteTransitions) == VisualizationModes.AbsoluteTransitions)
      {
        DataView trialsFixations = null;

        // Get filtered fixations data view
        switch (sampleType)
        {
          case SampleType.Gaze:
            trialsFixations = this.GazeFixationsView;
            break;
          case SampleType.Mouse:
            trialsFixations = this.MouseFixationsView;
            break;
        }

        var transitions = Statistics.Statistic.CreateTransitionMatrixForSingleAOIs(
          trialsFixations, 
          aoisWithoutSearchRects);

        float transitionSum = 0;

        // Calculate transition total sum only if relative values are requested.
        if (!absolute)
        {
          for (var i = 0; i <= transitions.GetUpperBound(0); i++)
          {
            // Skip nowhere transitions
            if (i == 0)
            {
              continue;
            }

            for (var j = 0; j <= transitions.GetUpperBound(1); j++)
            {
              // Only take values outside the diagonal
              if (i == j || j == 0)
              {
                continue;
              }

              transitionSum += (int)transitions.GetValue(i, j);
            }
          }
        }

        // Write transitionMatrix to dgv
        for (var i = transitions.GetLowerBound(0); i <= transitions.GetUpperBound(0); i++)
        {
          // Skip nowhere transitions
          if (i == 0)
          {
            continue;
          }

          for (var j = transitions.GetLowerBound(1); j <= transitions.GetUpperBound(1); j++)
          {
            // Only take values above the diagonal
            if (i >= j)
            {
              continue;
            }

            float transAtoB;
            float transBtoA;
            if (absolute)
            {
              transAtoB = (int)transitions.GetValue(i, j);
              transBtoA = (int)transitions.GetValue(j, i);
            }
            else
            {
              transAtoB = (float)Math.Round((int)transitions.GetValue(i, j) / transitionSum * 100, 1);
              transBtoA = (float)Math.Round((int)transitions.GetValue(j, i) / transitionSum * 100, 1);
            }

            if (transAtoB > 0 || transBtoA > 0)
            {
              var showNumbers = false;
              if ((this.ArrowDrawAction & ShapeDrawAction.Name) == ShapeDrawAction.Name)
              {
                this.ArrowDrawAction |= ~ShapeDrawAction.Name;
                showNumbers = true;
              }

              var arrow = new VGArrow(this.ArrowDrawAction, this.ArrowPen);
              arrow.Brush = this.ArrowBrush;
              if (!showNumbers)
              {
                arrow.HideWeights = true;
              }

              var location1 = aoisWithoutSearchRects[i - 1].Center;
              var location2 = aoisWithoutSearchRects[j - 1].Center;
              var distanceFirst = distances.Count >= i ? distances[i - 1] : 15;
              var distanceSecond = distances.Count >= j ? distances[j - 1] : 15;
              if (location1.X <= location2.X)
              {
                arrow.FirstPoint = location1;
                arrow.SecondPoint = location2;
                arrow.FirstPointDistance = distanceFirst;
                arrow.SecondPointDistance = distanceSecond;
                arrow.FirstPointWeight = transBtoA;
                arrow.SecondPointWeight = transAtoB;
              }
              else
              {
                arrow.FirstPoint = location2;
                arrow.SecondPoint = location1;
                arrow.FirstPointDistance = distanceSecond;
                arrow.SecondPointDistance = distanceFirst;
                arrow.FirstPointWeight = transAtoB;
                arrow.SecondPointWeight = transBtoA;
              }

              arrow.FormatString = "N0";
              if (!absolute)
              {
                if (arrow.FirstPointWeight < 1 && arrow.SecondPointWeight < 1)
                {
                  arrow.FormatString = "N1";
                }

                arrow.AddOnString = "%";
              }

              arrow.WeightFont = this.ArrowFont;
              arrow.WeightFontColor = this.ArrowFontColor;
              arrow.ScaleFactor = this.ArrowFactor;
              arrow.StyleGroup = VGStyleGroup.AOI_STATISTICS_ARROW;
              arrow.TextAlignment = this.ArrowTextAlignment;
              this.Elements.Add(arrow);
            }
          }
        }
      }

      this.DrawForeground(true);
    }
Пример #24
0
        /// <summary>
        /// Initializes a new instance of the Slide class as a clone of
        /// the given slide.
        /// </summary>
        /// <param name="slide">The <see cref="Slide"/> to clone.</param>
        public Slide(Slide slide)
        {
            // Clone stimuli
            this.stimuli = new VGElementCollection();
            foreach (VGElement element in slide.VGStimuli)
            {
                this.stimuli.Add((VGElement)element.Clone());
            }

            // Clone activeXElements
            this.activeXElements = new VGElementCollection();
            foreach (VGElement element in slide.ActiveXStimuli)
            {
                this.activeXElements.Add((VGElement)element.Clone());
            }

            // Clone stop conditions
            this.stopConditions = new StopConditionCollection();
            foreach (StopCondition condition in slide.StopConditions)
            {
                this.stopConditions.Add((StopCondition)condition.Clone());
            }

            // Clone background properties
            this.BackgroundColor = slide.BackgroundColor;
            if (slide.BackgroundImage != null)
            {
                this.BackgroundImage = (Image)slide.BackgroundImage.Clone();
            }

            if (slide.BackgroundSound != null)
            {
                this.BackgroundSound = (AudioFile)slide.BackgroundSound.Clone();
            }

            // Clone trigger
            this.TriggerSignal = slide.TriggerSignal;

            this.IsDesktopSlide            = slide.IsDesktopSlide;
            this.IdOfPreSlideFixationTrial = slide.IdOfPreSlideFixationTrial;
            this.IsDisabled = slide.IsDisabled;

            // Clone correct responses
            this.correctResponses = new StopConditionCollection();
            foreach (StopCondition condition in slide.CorrectResponses)
            {
                this.correctResponses.Add((StopCondition)condition.Clone());
            }

            // Clone links
            this.links = new StopConditionCollection();
            foreach (StopCondition condition in slide.Links)
            {
                this.links.Add((StopCondition)condition.Clone());
            }

            // Clone description
            this.name     = slide.Name;
            this.category = slide.Category;

            // Clone target areas
            this.targets = new VGElementCollection();
            foreach (VGElement target in slide.TargetShapes)
            {
                this.targets.Add((VGElement)target.Clone());
            }

            // Clone mouse properties
            this.MouseInitialPosition     = slide.MouseInitialPosition;
            this.MouseCursorVisible       = slide.MouseCursorVisible;
            this.ForceMousePositionChange = slide.ForceMousePositionChange;

            this.PresentationSize = slide.PresentationSize;
            this.Modified         = slide.Modified;
        }
Пример #25
0
 /// <summary>
 /// Initializes a new instance of the Slide class.
 /// </summary>
 public Slide()
 {
   this.stimuli = new VGElementCollection();
   this.activeXElements = new VGElementCollection();
   this.targets = new VGElementCollection();
   this.correctResponses = new StopConditionCollection();
   this.links = new StopConditionCollection();
   this.stopConditions = new StopConditionCollection();
   this.category = string.Empty;
   this.TriggerSignal = new Trigger(TriggerSignaling.None, TriggerOutputDevices.LPT, 40, 255, 0x0378);
   this.IdOfPreSlideFixationTrial = -1;
 }
Пример #26
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();
      }
    }
Пример #27
0
    /// <summary>
    /// Calculates the time to the first fixation in given area of interest.
    /// AOI table has normally only one row.
    /// </summary>
    /// <param name="aois">A <see cref="VGElementCollection"/> with the areas of interest for current trial.</param>
    /// <param name="inputTable">Table with fixation list.</param>
    /// <param name="numberOfFixation">Set to number of fixation that should be
    /// detected (first, second, third)</param>
    /// <returns>Number of fixation that is the "numberOfFixation" (first, second, third) in given AOI</returns>
    private static int GetNumberOfFixationInGivenAOIList(
      VGElementCollection aois,
      DataTable inputTable,
      int numberOfFixation)
    {
      // Never over AOI
      int hitIndex = -1;

      if (aois.Count == 0)
      {
        // NO AOIs definded
        hitIndex = -2;
        return hitIndex;
      }

      int rowCounter = 0;
      int hitCount = 0;

      // Check for intersection between pathIncludingAllAOIs and Clicklist or Fixationlist
      foreach (DataRow inputRow in inputTable.Rows)
      {
        PointF searchPoint = new PointF(
          Convert.ToSingle(inputRow["PosX"]),
          Convert.ToSingle(inputRow["PosY"]));

        foreach (VGElement aoi in aois)
        {
          if (aoi.Contains(searchPoint, tolerance))
          {
            // That means given point lies in current AOI.
            hitCount++;
            if (hitCount == numberOfFixation)
            {
              hitIndex = rowCounter;
              break;
            }
          }
        }

        rowCounter++;
      }

      return hitIndex;
    }
Пример #28
0
    /// <summary>
    /// Calculates the statistical parameters for the current trial and <see cref="SampleType"/>
    /// </summary>
    /// <param name="sampleType">
    /// The <see cref="SampleType"/> of which the data should be used.
    /// </param>
    public void CalculateAOIStatistics(SampleType sampleType)
    {
      this.aoiStatistics = new Dictionary<string, AOIStatistic>();
      foreach (VGElement aoi in this.AoiCollection)
      {
        var aoiStatistic = new AOIStatistic();
        var aoiContainer = new VGElementCollection();
        aoiContainer.Add(aoi);

        switch (sampleType)
        {
          case SampleType.Gaze:
            aoiStatistic = Statistics.Statistic.CalcAOIStatistic(this.GazeFixationsView, aoiContainer);
            break;
          case SampleType.Mouse:
            aoiStatistic = Statistics.Statistic.CalcAOIStatistic(this.MouseFixationsView, aoiContainer);
            break;
        }

        if (!this.aoiStatistics.ContainsKey(aoi.Name))
        {
          this.aoiStatistics.Add(aoi.Name, aoiStatistic);
        }
      }
    }
Пример #29
0
    /// <summary>
    /// Iterates selected trials and calculates the transition table.
    /// </summary>
    /// <param name="worker">
    /// The <see cref="BackgroundWorker"/>
    /// </param>
    /// <param name="e">
    /// A <see cref="DoWorkEventArgs"/> with the event data.
    /// </param>
    private void FillTransitionsWithData(BackgroundWorker worker, DoWorkEventArgs e)
    {
      DataTable aoiTable = Document.ActiveDocument.DocDataSet.AOIs;
      var trialsAOIs = new DataView(aoiTable);
      DataTable subjectsTable = Document.ActiveDocument.DocDataSet.SubjectsAdapter.GetData();
      var trialAOIs = new VGElementCollection();
      List<string> checkedSubjects = GetCheckedSubjects(this.trvTransitionsSubjects);

      if (this.rdbTransitionUseAOIGroups.Checked)
      {
        int aoiGroupCount = this.aoiGroups.Count;
        Array transitionMatrix = Array.CreateInstance(typeof(int), aoiGroupCount + 1, aoiGroupCount + 1);
        var groupIndexAssignment = new Dictionary<string, int>();
        groupIndexAssignment.Add("nowhere", 0);
        for (int i = 0; i < aoiGroupCount; i++)
        {
          string aoiGroupEntry = this.aoiGroups[i];
          groupIndexAssignment.Add(aoiGroupEntry, i + 1);
        }

        // Get selected trials
        var trialIDs = new List<int>();

        foreach (TreeNode categoryNode in this.trvTrialsAOI.Nodes)
        {
          foreach (TreeNode trialNode in categoryNode.Nodes)
          {
            if (trialNode.Checked)
            {
              trialIDs.Add(Convert.ToInt32(trialNode.Name));
            }
          }
        }

        // Iterate selected subjects
        foreach (DataRow subjectRow in subjectsTable.Rows)
        {
          string subjectName = subjectRow["SubjectName"].ToString();

          if (checkedSubjects.Contains(subjectName))
          {
            DataView fixations = null;
            if (this.btnEye.Checked)
            {
              fixations =
                new DataView(Document.ActiveDocument.DocDataSet.GazeFixationsAdapter.GetDataBySubject(subjectName));
            }
            else if (this.btnMouse.Checked)
            {
              fixations =
                new DataView(Document.ActiveDocument.DocDataSet.MouseFixationsAdapter.GetDataBySubject(subjectName));
            }

            string foregoingHittedAOIGroup = string.Empty;
            int foregoingTrialID = -1;

            foreach (DataRowView fixationRow in fixations)
            {
              var trialID = (int)fixationRow["TrialID"];
              if (!trialIDs.Contains(trialID))
              {
                continue;
              }

              if (trialID != foregoingTrialID)
              {
                trialsAOIs.RowFilter = "TrialID=" + trialID.ToString();
                foregoingTrialID = trialID;

                trialAOIs.Clear();
                foreach (DataRowView row in trialsAOIs)
                {
                  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);
                  trialAOIs.Add(aoi);
                }
              }

              string hittedAOIName = string.Empty;
              string hittedAOIGroup = string.Empty;
              List<string[]> hittedAOIs = Statistic.FixationHitsAOI(trialAOIs, fixationRow);
              if (hittedAOIs.Count > 0)
              {
                // Take only first hitted AOI
                hittedAOIName = hittedAOIs[0][0];
                hittedAOIGroup = hittedAOIs[0][1];
              }

              if (foregoingHittedAOIGroup != string.Empty)
              {
                if (hittedAOIGroup == string.Empty)
                {
                  hittedAOIGroup = "nowhere";
                }

                int indexOfHittedGroup = groupIndexAssignment[hittedAOIGroup];
                int indexOfForegoingGroup = groupIndexAssignment[foregoingHittedAOIGroup];
                var oldEntry = (int)transitionMatrix.GetValue(indexOfForegoingGroup, indexOfHittedGroup);
                int newEntry = oldEntry + 1;
                transitionMatrix.SetValue(newEntry, indexOfForegoingGroup, indexOfHittedGroup);
              }

              foregoingHittedAOIGroup = hittedAOIGroup;
            }
          }
        }

        // Write transitionMatrix to dgv
        for (int i = transitionMatrix.GetLowerBound(0); i <= transitionMatrix.GetUpperBound(0); i++)
        {
          // Get a datagridview via asynchronous call.
          DataGridViewRow newRow = this.GetTransitionsDataGridViewRow();
          if (i > 0)
          {
            newRow.Cells[0].Value = this.aoiGroups[i - 1];
          }
          else
          {
            newRow.Cells[0].Value = "nowhere";
          }

          for (int j = transitionMatrix.GetLowerBound(1); j <= transitionMatrix.GetUpperBound(1); j++)
          {
            newRow.Cells[j + 1].Value = transitionMatrix.GetValue(i, j);
          }
        }
      }
      else if (this.rdbTransitionsUseTrial.Checked)
      {
        trialAOIs.Clear();
        trialsAOIs.RowFilter = "TrialID=" + e.Argument;
        foreach (DataRowView row in trialsAOIs)
        {
          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);
          trialAOIs.Add(aoi);
        }

        var gazeFixations =
          new DataView(Document.ActiveDocument.DocDataSet.GazeFixationsAdapter.GetDataByTrialID((int)e.Argument));
        var mouseFixations =
          new DataView(Document.ActiveDocument.DocDataSet.MouseFixationsAdapter.GetDataByTrialID((int)e.Argument));

        string filterString = string.Empty;
        foreach (string subject in checkedSubjects)
        {
          filterString += "(SubjectName='" + subject + "') OR ";
        }

        filterString = filterString.Substring(0, filterString.Length - 4);

        gazeFixations.RowFilter = filterString;
        mouseFixations.RowFilter = filterString;

        Array transitionMatrix = null;
        if (this.btnEye.Checked)
        {
          transitionMatrix = Statistic.CreateTransitionMatrixForSingleAOIs(gazeFixations, trialAOIs);
        }
        else if (this.btnMouse.Checked)
        {
          transitionMatrix = Statistic.CreateTransitionMatrixForSingleAOIs(mouseFixations, trialAOIs);
        }

        // Write transitionMatrix to dgv
        for (int i = transitionMatrix.GetLowerBound(0); i <= transitionMatrix.GetUpperBound(0); i++)
        {
          // Get a datagridview via asynchronous call.
          DataGridViewRow newRow = this.GetTransitionsDataGridViewRow();
          if (i > 0)
          {
            newRow.Cells[0].Value = trialAOIs[i - 1].Name;
          }
          else
          {
            newRow.Cells[0].Value = "nowhere";
          }

          for (int j = transitionMatrix.GetLowerBound(1); j <= transitionMatrix.GetUpperBound(1); j++)
          {
            newRow.Cells[j + 1].Value = transitionMatrix.GetValue(i, j);
          }
        }
      }
    }
Пример #30
0
    ///////////////////////////////////////////////////////////////////////////////
    // Methods for doing main class job                                          //
    ///////////////////////////////////////////////////////////////////////////////
    #region METHODS

    /// <summary>
    /// This method exports the fixations of the given <see cref="SampleType"/>
    /// to the given File including AOI information.
    /// </summary>
    /// <param name="options">An <see cref="ExportOptions"/> with options for the file export.</param>
    /// <param name="type">The <see cref="SampleType"/> to be exported.</param>
    private void Export(ExportOptions options, SampleType type)
    {
      string tableName = string.Empty;
      string fileName = string.Empty;

      DataTable dataTable = new DataTable();
      switch (type)
      {
        case SampleType.Gaze:
          tableName = "GazeFixations";
          dataTable = Document.ActiveDocument.DocDataSet.GazeFixations;
          fileName = options.GazeFileName;
          break;
        case SampleType.Mouse:
          tableName = "MouseFixations";
          dataTable = Document.ActiveDocument.DocDataSet.MouseFixations;
          fileName = options.MouseFileName;
          break;
      }

      bool unknownSubjectFound = false;
      string missingSubjectName = string.Empty;

      using (StreamWriter exportFileWriter = new StreamWriter(fileName))
      {
        // Write Documentation
        exportFileWriter.WriteLine("# File: " + Path.GetFileName(fileName));
        exportFileWriter.WriteLine("# Created: " + DateTime.Today.Date.ToLongDateString() + "," + DateTime.Now.ToLongTimeString());
        exportFileWriter.WriteLine("# with: " + Application.ProductName + " Version: " + Document.ActiveDocument.ExperimentSettings.OgamaVersion.ToString(3));

        exportFileWriter.WriteLine("# Contents: " + tableName + " table.");
        exportFileWriter.WriteLine("# Applies to Projekt:" + Document.ActiveDocument.ExperimentSettings.Name);
        exportFileWriter.WriteLine("#");

        if (options.ExportFixations)
        {
          // Write Column Names
          foreach (DataColumn dataColumn in dataTable.Columns)
          {
            exportFileWriter.Write(dataColumn.Caption);
            exportFileWriter.Write("\t");
          }
        }
        else
        {
          // We should export saccades which need some other column descriptions
          exportFileWriter.Write("SubjectName");
          exportFileWriter.Write("\t");
          exportFileWriter.Write("TrialID");
          exportFileWriter.Write("\t");
          exportFileWriter.Write("TrialSequence");
          exportFileWriter.Write("\t");
          exportFileWriter.Write("CountInTrial");
          exportFileWriter.Write("\t");
          exportFileWriter.Write("StartTime");
          exportFileWriter.Write("\t");
          exportFileWriter.Write("Duration");
          exportFileWriter.Write("\t");
          exportFileWriter.Write("Distance");
          exportFileWriter.Write("\t");
          exportFileWriter.Write("Velocity");
          exportFileWriter.Write("\t");
          exportFileWriter.Write("Validity");
          exportFileWriter.Write("\t");
        }

        if (options.ExportSubjectDetails)
        {
          exportFileWriter.Write("SubjectCategory");
          exportFileWriter.Write("\t");
          exportFileWriter.Write("Age");
          exportFileWriter.Write("\t");
          exportFileWriter.Write("Sex");
          exportFileWriter.Write("\t");
          exportFileWriter.Write("Handedness");
          exportFileWriter.Write("\t");
          exportFileWriter.Write("Comments");
          exportFileWriter.Write("\t");

          DataTable customParams =
            Document.ActiveDocument.DocDataSet.ParamsAdapter.GetData();
          foreach (DataRow paramRow in customParams.Rows)
          {
            exportFileWriter.Write(paramRow["Param"]);
            exportFileWriter.Write("\t");
          }
        }

        if (options.ExportTrialDetails)
        {
          exportFileWriter.Write("Trial Name");
          exportFileWriter.Write("\t");
          exportFileWriter.Write("Trial Category");
          exportFileWriter.Write("\t");
          exportFileWriter.Write("SlideNr");
          exportFileWriter.Write("\t");
        }

        if (options.ExportAOIDetails)
        {
          if (options.ExportFixations)
          {
            exportFileWriter.Write("AOI");
            exportFileWriter.Write("\t");
            exportFileWriter.Write("AOI group");
            exportFileWriter.Write("\t");
          }
          else
          {
            exportFileWriter.Write("Saccade Target AOI");
            exportFileWriter.Write("\t");
            exportFileWriter.Write("Saccade Target AOI group");
            exportFileWriter.Write("\t");
          }
        }

        exportFileWriter.WriteLine();

        int trialID = -1;
        int lastTrialID = -1;

        string subjectName = string.Empty;
        string lastsubjectName = "LastSubjectKLSMA";

        DataView trialsAOIsView = new DataView(Document.ActiveDocument.DocDataSet.AOIs);
        SubjectsData subjectData = new SubjectsData();
        Dictionary<string, string> subjectParams = new Dictionary<string, string>();

        // Sort fixation data
        DataView fixationsView = new DataView(dataTable);
        fixationsView.Sort = "SubjectName, TrialSequence, CountInTrial ASC";

        VGElementCollection trialAOIs = new VGElementCollection();
        string category = string.Empty;
        string trialName = string.Empty;
        PointF lastFixationCenter = PointF.Empty;
        long lastFixationEndTime = 0;
        int lastFixationDuration = 0;
        int countInTrial = 0;
        int slideNr = 0;
        List<long> slideStartTimes = new List<long>();
        foreach (DataRowView dataRow in fixationsView)
        {
          trialID = (int)dataRow["TrialID"];

          // Skip trials that are not selected.
          if (!options.CheckedTrialIDs.Contains(trialID))
          {
            continue;
          }

          int trialSequence = (int)dataRow["TrialSequence"];
          long startTime = (long)dataRow["StartTime"];
          int length = (int)dataRow["Length"];
          float posX = Convert.ToSingle(dataRow["PosX"]);
          float posY = Convert.ToSingle(dataRow["PosY"]);
          PointF fixationCenter = new PointF(posX, posY);

          subjectName = dataRow["SubjectName"].ToString();
          if (!options.CheckedSubjects.Contains(subjectName))
          {
            continue;
          }

          if (options.ExportSubjectDetails)
          {
            if (subjectName != lastsubjectName)
            {
              subjectData = new SubjectsData();

              DataTable subjectsTable = Document.ActiveDocument.DocDataSet.SubjectsAdapter.GetDataBySubject(subjectName);
              if (subjectsTable.Rows.Count == 0)
              {
                unknownSubjectFound = true;
                missingSubjectName = subjectName;
                continue;
              }

              // Parse subject information
              if (!subjectsTable.Rows[0].IsNull("Age"))
              {
                subjectData.Age = (int)subjectsTable.Rows[0]["Age"];
              }

              subjectData.Category = subjectsTable.Rows[0]["Category"].ToString();
              subjectData.Comments = subjectsTable.Rows[0]["Comments"].ToString();
              subjectData.Handedness = subjectsTable.Rows[0]["Handedness"].ToString();
              subjectData.Sex = subjectsTable.Rows[0]["Sex"].ToString();

              // Parse custom subject information
              subjectParams.Clear();
              DataTable subjectParamsTable = Document.ActiveDocument.DocDataSet.SubjectParametersAdapter.GetDataBySubject(subjectName);
              foreach (DataRow paramRow in subjectParamsTable.Rows)
              {
                subjectParams.Add(paramRow["Param"].ToString(), paramRow["ParamValue"].ToString());
              }

              lastsubjectName = subjectName;
            }
          }

          if (trialID != lastTrialID)
          {
            slideStartTimes.Clear();
            DataTable trialEvents = Document.ActiveDocument.DocDataSet.TrialEventsAdapter.GetDataBySubjectNameTrialSequenceButOnlySlideChangeResponses(subjectName, trialSequence);
            foreach (DataRow slideEventRow in trialEvents.Rows)
            {
              slideStartTimes.Add((long)slideEventRow["EventTime"]);
            }

            countInTrial = 0;
            slideNr = 0;

            if (options.ExportTrialDetails || options.ExportAOIDetails)
            {
              DataTable trialTable = Document.ActiveDocument.DocDataSet.TrialsAdapter.GetDataBySubjectAndTrialID(subjectName, trialID);
              if (trialTable.Rows.Count > 0)
              {
                category = trialTable.Rows[0]["Category"].ToString();
                trialName = trialTable.Rows[0]["TrialName"].ToString();
              }

              string filter = "TrialID=" + trialID + string.Empty;
              trialsAOIsView.RowFilter = filter;
              lastTrialID = trialID;
              trialAOIs.Clear();

              foreach (DataRowView row in trialsAOIsView)
              {
                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);
                trialAOIs.Add(aoi);
              }
            }
          }

          if (slideStartTimes.Count > (slideNr + 1) && startTime > slideStartTimes[slideNr])
          {
            slideNr++;
          }

          if (options.ExportFixations)
          {
            // Write fixation table content
            foreach (object cellValue in dataRow.Row.ItemArray)
            {
              exportFileWriter.Write(cellValue.ToString());
              exportFileWriter.Write("\t");
            }
          }
          else
          {
            if (countInTrial != 0)
            {
              // we should export saccades
              exportFileWriter.Write(subjectName);
              exportFileWriter.Write("\t");
              exportFileWriter.Write(trialID);
              exportFileWriter.Write("\t");
              exportFileWriter.Write(trialSequence);
              exportFileWriter.Write("\t");
              exportFileWriter.Write(countInTrial);
              exportFileWriter.Write("\t");
              exportFileWriter.Write(lastFixationEndTime);
              exportFileWriter.Write("\t");
              int duration = (int)(startTime - lastFixationEndTime);
              exportFileWriter.Write(duration);
              exportFileWriter.Write("\t");
              float distance = VGPolyline.Distance(lastFixationCenter, fixationCenter);
              exportFileWriter.Write(distance);
              exportFileWriter.Write("\t");
              exportFileWriter.Write(distance / duration);
              exportFileWriter.Write("\t");

              int validity = 0;
              if (duration > lastFixationDuration)
              {
                validity = -1;
              }

              exportFileWriter.Write(validity);
              exportFileWriter.Write("\t");
            }
          }

          if (options.ExportSubjectDetails)
          {
            if (options.ExportFixations || countInTrial != 0)
            {
              // Write subject information
              exportFileWriter.Write(subjectData.Category);
              exportFileWriter.Write("\t");
              exportFileWriter.Write(subjectData.Age);
              exportFileWriter.Write("\t");
              exportFileWriter.Write(subjectData.Sex);
              exportFileWriter.Write("\t");
              exportFileWriter.Write(subjectData.Handedness);
              exportFileWriter.Write("\t");
              exportFileWriter.Write(subjectData.Comments);
              exportFileWriter.Write("\t");

              foreach (string paramValue in subjectParams.Values)
              {
                exportFileWriter.Write(paramValue);
                exportFileWriter.Write("\t");
              }
            }
          }

          if (options.ExportTrialDetails)
          {
            if (options.ExportFixations || countInTrial != 0)
            {
              // Write trial information
              exportFileWriter.Write(trialName != string.Empty ? trialName : "NamelessTrial");
              exportFileWriter.Write("\t");
              exportFileWriter.Write(category);
              exportFileWriter.Write("\t");
              exportFileWriter.Write(slideNr);
              exportFileWriter.Write("\t");
            }
          }

          if (options.ExportAOIDetails)
          {
            if (options.ExportFixations || countInTrial != 0)
            {
              // Retrieve AOI position
              string hittedAOIName = string.Empty;
              string hittedAOIGroup = string.Empty;
              List<string[]> hittedAOIs = Statistics.Statistic.FixationHitsAOI(trialAOIs, dataRow);

              if (hittedAOIs.Count == 0)
              {
                hittedAOIName = "nowhere";
                hittedAOIGroup = "nowhere";
              }

              foreach (string[] aoi in hittedAOIs)
              {
                // Concatenate hitted AOIs
                hittedAOIName += aoi[0] + "#";
                hittedAOIGroup += aoi[1] + "#";
              }

              if (hittedAOIs.Count > 0)
              {
                hittedAOIName = hittedAOIName.Substring(0, hittedAOIName.Length - 1);
                hittedAOIGroup = hittedAOIGroup.Substring(0, hittedAOIGroup.Length - 1);
              }

              exportFileWriter.Write(hittedAOIName);
              exportFileWriter.Write("\t");
              exportFileWriter.Write(hittedAOIGroup);
              exportFileWriter.Write("\t");
            }
          }

          if (options.ExportFixations || countInTrial != 0)
          {
            // Write new line for next row.
            exportFileWriter.WriteLine();
          }

          countInTrial++;
          lastFixationCenter = fixationCenter;
          lastFixationEndTime = startTime + length;
          lastFixationDuration = length;
        }
      }

      if (unknownSubjectFound)
      {
        string message = "At least one fixation of an subject that is not in the database anymore " +
          "was found. Subject: '" + missingSubjectName + "'" + Environment.NewLine +
          "Please re-run a complete fixation calculation for all subjects.";
        ExceptionMethods.ProcessMessage("Old subject fixations found", message);
      }

      ExceptionMethods.ProcessMessage("Export successful.", "Fixations were successfully exported to file");
    }
Пример #31
0
    /// <summary>
    /// This static method parses the aoi table filtered by the given trialID
    ///   for AOIs within the given group and returns them in a <see cref="VGElementCollection"/>
    /// </summary>
    /// <param name="trialID">
    /// An <see cref="Int32"/> with the trial ID
    /// </param>
    /// <param name="groupName">
    /// A <see cref="string"/> with the group name.
    /// </param>
    /// <returns>
    /// A <see cref="VGElementCollection"/> with the AOIs of the given group.
    /// </returns>
    private VGElementCollection GetGroupAOIs(int trialID, string groupName)
    {
      var groupAOIs = new VGElementCollection();
      DataTable targetTable = Document.ActiveDocument.DocDataSet.AOIsAdapter.GetDataByTrialIDAndGroup(
        trialID, groupName);
      var targetAois = new VGElementCollection();
      foreach (DataRow row in targetTable.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);
        groupAOIs.Add(aoi);
      }

      return groupAOIs;
    }
Пример #32
0
    /// <summary>
    /// Initializes a new instance of the Slide class as a clone of 
    /// the given slide.
    /// </summary>
    /// <param name="slide">The <see cref="Slide"/> to clone.</param>
    public Slide(Slide slide)
    {
      // Clone stimuli
      this.stimuli = new VGElementCollection();
      foreach (VGElement element in slide.VGStimuli)
      {
        this.stimuli.Add((VGElement)element.Clone());
      }

      // Clone activeXElements
      this.activeXElements = new VGElementCollection();
      foreach (VGElement element in slide.ActiveXStimuli)
      {
        this.activeXElements.Add((VGElement)element.Clone());
      }

      // Clone stop conditions
      this.stopConditions = new StopConditionCollection();
      foreach (StopCondition condition in slide.StopConditions)
      {
        this.stopConditions.Add((StopCondition)condition.Clone());
      }

      // Clone background properties
      this.BackgroundColor = slide.BackgroundColor;
      if (slide.BackgroundImage != null)
      {
        this.BackgroundImage = (Image)slide.BackgroundImage.Clone();
      }

      if (slide.BackgroundSound != null)
      {
        this.BackgroundSound = (AudioFile)slide.BackgroundSound.Clone();
      }

      // Clone trigger
      this.TriggerSignal = slide.TriggerSignal;

      this.IsDesktopSlide = slide.IsDesktopSlide;
      this.IdOfPreSlideFixationTrial = slide.IdOfPreSlideFixationTrial;
      this.IsDisabled = slide.IsDisabled;

      // Clone correct responses
      this.correctResponses = new StopConditionCollection();
      foreach (StopCondition condition in slide.CorrectResponses)
      {
        this.correctResponses.Add((StopCondition)condition.Clone());
      }

      // Clone links
      this.links = new StopConditionCollection();
      foreach (StopCondition condition in slide.Links)
      {
        this.links.Add((StopCondition)condition.Clone());
      }

      // Clone description
      this.name = slide.Name;
      this.category = slide.Category;

      // Clone target areas
      this.targets = new VGElementCollection();
      foreach (VGElement target in slide.TargetShapes)
      {
        this.targets.Add((VGElement)target.Clone());
      }

      // Clone mouse properties
      this.MouseInitialPosition = slide.MouseInitialPosition;
      this.MouseCursorVisible = slide.MouseCursorVisible;
      this.ForceMousePositionChange = slide.ForceMousePositionChange;

      this.PresentationSize = slide.PresentationSize;
      this.Modified = slide.Modified;
    }
Пример #33
0
 /// <summary>
 /// Adds a range of <see cref="VGElement"/>s to the collection.
 /// </summary>
 /// <param name="elementCollection">The <see cref="VGElementCollection"/> to be 
 /// added to the end of the collection.</param>
 public void AddRange(VGElementCollection elementCollection)
 {
   foreach (VGElement element in elementCollection)
   {
     this.List.Add(element);
   }
 }
    ///////////////////////////////////////////////////////////////////////////////
    // Construction and Initializing methods                                     //
    ///////////////////////////////////////////////////////////////////////////////
    #region CONSTRUCTION

    /// <summary>
    /// Initializes a new instance of the VGElementCollectionPropertyDescriptor class.
    /// </summary>
    /// <param name="collection">The <see cref="VGElementCollection"/>
    /// for this <see cref="PropertyDescriptor"/></param>
    /// <param name="index">The index to use.</param>
    public VGElementCollectionPropertyDescriptor(VGElementCollection collection, int index)
      : base("#" + index.ToString(), null)
    {
      this.collection = collection;
      this.index = index;
    }
Пример #35
0
    /// <summary>
    /// This static method calculates the number of clicks at the given AOI or AOI group.
    /// </summary>
    /// <param name="mouseStopConditions">A <see cref="List{MouseStopCondition}"/> with the clicks.</param>
    /// <param name="aoiTable">A <see cref="DataTable"/> with the aoi or aois.</param>
    /// <param name="button">A <see cref="MouseButtons"/> with the button to count for.</param>
    /// <returns>An <see cref="Int32"/> with the number of clicks of the given 
    /// mouse button at the given AOI(s).</returns>
    private static int CalcNumberOfClicksAtAOIs(
      List<MouseStopCondition> mouseStopConditions,
      DataTable aoiTable,
      MouseButtons button)
    {
      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);
      }

      // Never over AOI
      int numberOfClicksAtAOI = -1;

      List<Point> clickLocations = ParseConditionsForLocations(mouseStopConditions, button);

      if (aois.Count == 0)
      {
        // no AOIs definded
        return -2;
      }

      if (clickLocations.Count == 0)
      {
        // no clicks of given type at all
        return -3;
      }

      int count = 0;
      foreach (Point clickLocation in clickLocations)
      {
        int hitIndex = IsClickAtTarget(aois, clickLocation);
        if (hitIndex >= 0)
        {
          count++;
        }
      }

      numberOfClicksAtAOI = count == 0 ? -1 : count;

      // -1: Never over AOI
      // -2; no AOIs definded
      // -3; no clicks of given type at all
      return numberOfClicksAtAOI;
    }