예제 #1
0
 public object Clone()
 {
     return(new Session()
     {
         InitialData = (SessionData)InitialData?.Clone(),
         DifferenceData = (SessionData)DifferenceData?.Clone(),
         CurrentData = (SessionData)CurrentData?.Clone(),
         SessionDate = SessionDate,
         Username = Username,
         GainedPlays = new List <OsuApiHelper.OsuPlay>(GainedPlays)
     });
 }
        /// <summary>
        /// Sets the data for the statistics object. The statistic values
        /// are calculated in this method. The results and truth dictionaries
        /// must contain at least a key for every frame between minimal and
        /// maximal frame number.
        /// </summary>
        /// <param name="truth">The ground truth dictionary.</param>
        /// <param name="results">The result dictionary.</param>
        /// <param name="truth_id">The id of the user to compare to as truth in
        /// the truth data ids.</param>
        /// <param name="results_id">The id of the result user to compare with
        /// in the result data ids.</param>
        /// <param name="converter">A function to convert 3d data to 2d data
        /// if necessary.</param>
        /// <exception cref="Exception">Thrown if the frames are not continuous
        /// from first to last.</exception>
        internal void SetData(ImageDictionary truth,
                              ImageDictionary results, int truth_id, int results_id,
                              To2DConverter converter)
        {
            // Reset.
            GlobalMean     = 0.0;
            FrameMean      = 0.0;
            FrameValue     = 0.0;
            NumberOfPoints = 0;
            first_frame    = int.MaxValue;
            last_frame     = -1;

            isInBatchMode = false;
            errors        = new Dictionary <SkeletonJoint, List <DifferenceData> >();
            foreach (JointTranslationTuple translation in JointDictionary.JointTranslationList)
            {
                errors.Add(translation.joint_type, new List <DifferenceData>());
            }
            resultDict = results;
            truthDict  = truth;
            work_in_3D = results.Is3DData;
            if (work_in_3D && !truth.Is3DData)
            {
                throw new ArgumentException("Trying to compare data with insufficient information.");
            }

            // Check converter availability if necessary
            if (!resultDict.Is3DData && truth.Is3DData && converter == null)
            {
                throw new ArgumentException("Must convert data to 2D, but no converter was specified.");
            }

            // Start calculating data.
            foreach (int frame in results.Keys)
            {
                if (frame < first_frame)
                {
                    first_frame = frame;
                }
                if (frame > last_frame)
                {
                    last_frame = frame;
                }

                // Convert the data if necessary
                JointDictionary frame_data_truth   = new JointDictionary(work_in_3D);
                JointDictionary frame_data_results = new JointDictionary(work_in_3D);
                bool            user_in_truth      = false;
                bool            user_in_results    = false;

                if (results[frame].ContainsKey(results_id))
                {
                    user_in_results = true;
                    if (results.Is3DData && !work_in_3D)
                    {
                        frame_data_results = converter(results[frame][results_id]);
                    }
                    else
                    {
                        frame_data_results = results[frame][results_id];
                    }
                }
                if (truth[frame].ContainsKey(truth_id))
                {
                    user_in_truth = true;
                    if (truth.Is3DData && !work_in_3D)
                    {
                        frame_data_truth = converter(truth[frame][truth_id]);
                    }
                    else
                    {
                        frame_data_truth = truth[frame][truth_id];
                    }
                }

                foreach (SkeletonJoint joint in errors.Keys)
                {
                    DifferenceData data = new DifferenceData();
                    data.frame      = frame;
                    data.Difference = double.NaN;
                    Point3D resultsPoint = new Point3D(), truthPoint = new Point3D();

                    if (user_in_results && frame_data_results.ContainsKey(joint))
                    {
                        data.inResultData = true;
                        resultsPoint      = frame_data_results[joint].Position;
                    }
                    if (user_in_truth && frame_data_truth.ContainsKey(joint))
                    {
                        data.inTruthData = true;
                        data.Confidence  = frame_data_truth[joint].Confidence;
                        truthPoint       = frame_data_truth[joint].Position;
                    }

                    if (data.inTruthData && data.inResultData)
                    {
                        if (work_in_3D)
                        {
                            data.Difference = Math.Sqrt(
                                Math.Pow(truthPoint.X - resultsPoint.X, 2.0) +
                                Math.Pow(truthPoint.Y - resultsPoint.Y, 2.0) +
                                Math.Pow(truthPoint.Z - resultsPoint.Z, 2.0));
                        }
                        else
                        {
                            data.Difference = Math.Sqrt(
                                Math.Pow(truthPoint.X - resultsPoint.X, 2.0) +
                                Math.Pow(truthPoint.Y - resultsPoint.Y, 2.0));
                        }
                    }

                    int position = 0;
                    List <DifferenceData> to_insert_in = errors[joint];
                    for (int i = 0; i < to_insert_in.Count; i++)
                    {
                        if (frame > to_insert_in[i].frame)
                        {
                            break;
                        }
                        else
                        {
                            position++;
                        }
                    }

                    errors[joint].Add(data);
                }
            }


            // Check that list is complete!!!
            int  range  = last_frame - first_frame + 1;
            bool failed = false;

            foreach (SkeletonJoint joint in errors.Keys)
            {
                if (errors[joint].Count != range)
                {
                    failed = true;
                    break;
                }
            }
            if (failed)
            {
                errors.Clear();
                throw new Exception("The algorithm results did not contain every " +
                                    "frame from the first to the last.");
            }
        }