Example #1
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);
                }
            }
        }
Example #2
0
        /// <summary>
        /// Overridden. Does the same as the base method,
        /// but renames all AOIs with an increasing number.
        /// </summary>
        /// <param name="aoiTable">The <see cref="DataTable"/> with the AOIs.</param>
        /// <returns>A <see cref="List{VGElement}"/> with the renamed shapes.</returns>
        protected override VGElementCollection GetAOIElements(DataTable aoiTable)
        {
            VGElementCollection aoiElements = base.GetAOIElements(aoiTable);

            for (int i = 0; i < aoiElements.Count; i++)
            {
                VGElement element = aoiElements[i];

                // Modify shape names to fit Levenshtein settings.
                string shapeName = currentIdentifierList[i];
                element.Name   = shapeName;
                aoiElements[i] = element;
            }

            return(aoiElements);
        }
Example #3
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);
        }
Example #4
0
        /// <summary>
        /// This method calculates a string representation of the fixational scanpath
        /// of the given subject under the current settings.
        /// </summary>
        /// <param name="name">A <see cref="string"/> with the subject name.</param>
        /// <returns>The calculated scanpath string representation.</returns>
        public string CalcPathString(string name)
        {
            string returnScanpathString = string.Empty;

            if (!this.CheckForValidFixations())
            {
                return(returnScanpathString);
            }

            this.SetSubjectFilter(name, null, null);

            switch (this.gridBase)
            {
            case GridBase.None:
                // Do nothing returns empty string and zero distance
                break;

            case GridBase.Rectangular:
                // Get grid segments
                VGElementCollection segments =
                    this.Elements.FindAllGroupMembers(VGStyleGroup.SCA_GRID_RECTANGLE);

                // Iterate fixations and add name of grid segment to levensthein string,
                // if fixation center is in bounds of current segment.
                for (int i = 0; i < this.GazeFixationsView.Count; i++)
                {
                    DataRow row = this.GazeFixationsView[i].Row;

                    // Skip samples that are out of timing section bounds
                    long fixationStartTime =
                        row.IsNull("StartTime") ? 0 : Convert.ToInt64(row["StartTime"]);

                    if (fixationStartTime < this.SectionStartTime)
                    {
                        continue;
                    }

                    if (fixationStartTime > this.SectionEndTime)
                    {
                        break;
                    }

                    foreach (VGRectangle rect in segments)
                    {
                        PointF fixationCenter = new PointF(Convert.ToSingle(row["PosX"]), Convert.ToSingle(row["PosY"]));
                        if (rect.Contains(fixationCenter))
                        {
                            if (this.ignoreSubsequentHits && returnScanpathString.EndsWith(rect.Name))
                            {
                                continue;
                            }

                            returnScanpathString += rect.Name;
                            break;
                        }
                    }
                }

                break;

            case GridBase.AOIs:

                if (this.AOITable != null)
                {
                    VGElementCollection aoiList = this.GetAOIElements(this.AOITable);

                    // Iterate fixations and add name of grid segment to levensthein string,
                    // if fixation center is in bounds of current segment.
                    for (int i = 0; i < this.GazeFixationsView.Count; i++)
                    {
                        DataRow row = this.GazeFixationsView[i].Row;

                        // Skip samples that are out of timing section bounds
                        long fixationStartTime = row.IsNull("StartTime") ? 0 :
                                                 Convert.ToInt64(row["StartTime"]);
                        if (fixationStartTime < this.SectionStartTime)
                        {
                            continue;
                        }

                        if (fixationStartTime > this.SectionEndTime)
                        {
                            break;
                        }

                        bool outOfAOI = true;

                        foreach (VGElement aoi in aoiList)
                        {
                            PointF fixationCenter = new PointF(Convert.ToSingle(row["PosX"]), Convert.ToSingle(row["PosY"]));
                            if (aoi.Contains(fixationCenter))
                            {
                                outOfAOI = false;
                                if (this.ignoreSubsequentHits && returnScanpathString.EndsWith(aoi.Name))
                                {
                                    continue;
                                }

                                returnScanpathString += aoi.Name;
                                break;
                            }
                        }

                        if (outOfAOI)
                        {
                            if (!this.ignoreSubsequentHits || !returnScanpathString.EndsWith("#"))
                            {
                                returnScanpathString += "#";
                            }
                        }
                    }
                }

                break;
            }

            return(returnScanpathString);
        }
Example #5
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;
 }