Exemple #1
0
        private List <SMParameterValue> changeBoundaries(int exptID, int defID, RatControlDataContext db)
        {
            int?FirstRCEID = null;
            int?LastRCEID  = null;

            db.GetFirstRCE(exptID, defID, ref FirstRCEID);
            db.GetLastRCE(exptID, defID, ref LastRCEID);

            if (FirstRCEID == null || LastRCEID == null)
            {
                Trace.WriteLine("RCEIDs are null");
            }
            else
            {
                var Features  = db.ExecuteQuery <double?>(@"SELECT Details.value('(//SetRewardPluginDetails/@Feature)[1]', 'float') AS A1 FROM RatControlEvents WHERE ExptID = {0} AND RatEventsID >= {1} AND RatEventsID <= {2} AND Details.value('(//SetRewardPluginDetails/@RandOn)[1]', 'bit') = 0 AND EventType = 9 ORDER BY A1 DESC", exptID.ToString(), FirstRCEID.ToString(), LastRCEID.ToString()).ToArray();
                var Completed = db.ExecuteQuery <int?>(@"SELECT Details.value('(//SetRewardPluginDetails/@Completed)[1]', 'int') AS A1 FROM RatControlEvents WHERE ExptID = {0} AND RatEventsID >= {1} AND RatEventsID <= {2} AND Details.value('(//SetRewardPluginDetails/@RandOn)[1]', 'bit') = 0 AND EventType = 9 ORDER BY A1 DESC", exptID.ToString(), FirstRCEID.ToString(), LastRCEID.ToString()).ToArray();

                int nevents = Features.Count();

                int n = 0;
                for (int i = 0; i < nevents; i++)
                {
                    if ((Features[i] != null) & (Completed[i] == 1))
                    {
                        n++;
                    }
                }

                // Convert angles into distance from target angle
                Double[] Dists = new double[n];

                n = 0;
                for (int i = 0; i < nevents; i++)
                {
                    if ((Features[i] != null) & (Completed[i] == 1))
                    {
                        Dists[n] = Math.Abs(T - (double)Features[i]);
                        n++;
                    }
                }

                // Sort the distances from closest to farthest
                Array.Sort(Dists);

                // Find the distance of the 35% farthest one
                int psampnum = (int)Math.Round(n * pTarget / 100);
                var w        = Dists[psampnum];

                LB = T - w;
                UB = T + w;
            }

            List <SMParameterValue> newParams = updateSMParams();

            return(newParams);
        }
Exemple #2
0
        private void jumpTarget(int exptID, int defID, RatControlDataContext db)
        {
            int?FirstRCEID = null;
            int?LastRCEID  = null;

            db.GetFirstRCE(exptID, defID, ref FirstRCEID);
            db.GetLastRCE(exptID, defID, ref LastRCEID);

            if (FirstRCEID == null || LastRCEID == null)
            {
                Trace.WriteLine("RCEIDs are null");
            }
            else
            {
                double upperEdge = TargetEdgeDist;
                double lowerEdge = -TargetEdgeDist;
                double prevT     = T;        // Record previous target location before updating it.

                double bound1   = lowerEdge; // Bounds of available intervals
                double bound2   = prevT - MinJumpDist;
                double bound3   = prevT + MinJumpDist;
                double bound4   = upperEdge;
                double intvLen1 = 0; // Length of lower available interval made up by bound1 to bound2
                double intvLen2 = 0; // Length of upper available interval made up by bound3 to bound4

                // Keep interval length as zero if target is too close to the edge
                if (bound2 > bound1)
                {
                    // previous target is very close to the upper edge
                    intvLen1 = bound2 - bound1;
                }
                if (bound4 > bound3)
                {
                    // previous target is very close to the lower edge
                    intvLen2 = bound4 - bound3;
                }

                // Pick a random location within the two intervals
                Random random          = new Random();
                double randomTargetLoc = random.NextDouble() * (intvLen1 + intvLen2);
                if (randomTargetLoc > intvLen1)
                {
                    // previous target is very close to the upper edge
                    T = bound3 + randomTargetLoc - intvLen1;
                }
                else
                {
                    // previous target is very close to the lower edge
                    T = bound1 + randomTargetLoc;
                }
            }
        }
Exemple #3
0
        private Status evaluatePerformance(int exptID, int defID, RatControlDataContext db)
        {
            int?FirstRCEID = null;
            int?LastRCEID  = null;

            db.GetFirstRCE(exptID, defID, ref FirstRCEID);
            db.GetLastRCE(exptID, defID, ref LastRCEID);

            int    numOfRewardedTrials;
            double percentRewarded;

            // number of trials in previous session
            int[] query1      = db.ExecuteQuery <int>(@"SELECT RatEventsID AS param6 FROM RatControlEvents WHERE ExptID = {0} AND RatEventsID >= {1} AND RatEventsID <= {2} AND Details.value('(//SetRewardPluginDetails/@RandOn)[1]', 'bit') = 0", ExptID.ToString(), FirstRCEID.ToString(), LastRCEID.ToString()).ToArray();
            int   numOfTrials = query1.Count();

            // int numOfTrials = ScriptHelper.CountNumEntries(exptID, JSPressState, defID, JSPressSubFSM, db);

            Trace.WriteLine("Number of Trials: " + numOfTrials);

            // Evaluate number of trials and percentage
            if (numOfTrials < MinNumOfTrials)
            {
                return(Status.Good);

                Trace.WriteLine("Too Few Trials");
            }
            else
            {
                int[] query2 = db.ExecuteQuery <int>(@"SELECT RatEventsID AS param6 FROM RatControlEvents WHERE ExptID = {0} AND RatEventsID >= {1} AND RatEventsID <= {2} AND Details.value('(//SetRewardPluginDetails/@RandOn)[1]', 'bit') = 0 AND Details.value('(//SetRewardPluginDetails/@Reward)[1]', 'int') > 0", ExptID.ToString(), FirstRCEID.ToString(), LastRCEID.ToString()).ToArray();
                numOfRewardedTrials = query2.Count();

                // numOfRewardedTrials = ScriptHelper.CountNumEntries(exptID, RewardState, defID, RewardSubFSM, db);
                percentRewarded = (double)numOfRewardedTrials / (double)numOfTrials * 100;
                Trace.WriteLine("Percentage Rewarded: " + percentRewarded + "%");

                if (percentRewarded < MinRewarded)
                {
                    return(Status.Hard);
                }
                else if (percentRewarded > MaxRewarded)
                {
                    return(Status.Easy);
                }
                else
                {
                    return(Status.Good);
                }
            }
        }
Exemple #4
0
        public override SMCompletionStatus IsComplete(out List <SMParameterValue> newParams)
        {
            Status status = Status.Good;

            newParams = null;

            if (!SMStarted)
            {
                using (RatControlDataContext db = new RatControlDataContext())
                {
                    int exptIDEval = ExptID; // exptID used for evaluating performance
                    int defIDEval  = 0;      // defID used for evaluating performance

                    // First check to see if there was a previous session in this experiment
                    var defIDs = ScriptHelper.GetStageDefIDs(ExptID, null, false, db);
                    if ((defIDs.Count() > 0) & Shaping)
                    {
                        int DefID = defIDs.Max();
                        exptIDEval = ExptID;
                        defIDEval  = DefID;
                        status     = evaluatePerformance(exptIDEval, defIDEval, db);
                    }
                    else
                    {
                        newParams = useScriptParameters(); // use script parameters
                    }

                    //////////// Random Reward Code ////////////
                    int[] defidcount = db.ExecuteQuery <int>(@"SELECT COUNT(Definition.value('(//@TrialBlock)[1]', 'int')) AS param6 FROM StateMachines WHERE ExptID = {0} AND Type = 4 AND Definition.value('(//@NormalTrials)[1]', 'int') > 0", ExptID.ToString()).ToArray();

                    // Retrieve old script parameters
                    if (defidcount[0] > 0)
                    {
                        // Recover block parameters passed from previous session
                        var sql    = db.ExecuteQuery <Parameter>(@"SELECT Definition.value('(//@TrialBlock)[1]', 'int') AS param6, Definition.value('(//@Order0)[1]', 'int') AS param7, Definition.value('(//@Order1)[1]', 'int') AS param8, Definition.value('(//@Order2)[1]', 'int') AS param9 FROM StateMachines WHERE ExptID = {0} AND Type = 4 AND Definition.value('(//@NormalTrials)[1]', 'int') > 0", ExptID.ToString()).ToArray();
                        int lindex = sql.Length - 1;

                        // Current block number
                        trblock = sql[lindex].param6;

                        // These are the block numbers of the blocks that will have random reward
                        blockorder[0] = sql[lindex].param7;
                        blockorder[1] = sql[lindex].param8;
                        blockorder[2] = sql[lindex].param9;
                    }

                    Random rnd = new Random();

                    // Initialize block numbers
                    if (trblock == 0)
                    {
                        // initialize block order
                        double[] tmpOrder = new double[numBlocks];
                        int[]    tmpVals  = new int[numBlocks];

                        // initialize block order
                        for (int i = 0; i < numBlocks; i++)
                        {
                            tmpOrder[i] = rnd.NextDouble();
                            tmpVals[i]  = i;
                        }
                        // Find the indices of the lowest 3. These will be the random reward blocks
                        Array.Sort(tmpOrder, tmpVals);
                        blockorder[0] = tmpVals[0];
                        blockorder[1] = tmpVals[1];
                        blockorder[2] = tmpVals[2];

                        string tmpString = "Block Sequence: ";
                        for (int i = 0; i < 3; i++)
                        {
                            tmpString = tmpString + blockorder[i];
                            if (i < numBlocks - 1)
                            {
                                tmpString = tmpString + " ";
                            }
                        }
                        Trace.WriteLine(tmpString);
                    }

                    // Add some randomness to the number of normal and prob trials: +- 10
                    NormTrials = defNormTrials + (int)Math.Round(2 * BlockJitter * rnd.NextDouble()) - BlockJitter;
                    ProbTrials = defProbTrials + (int)Math.Round(2 * BlockJitter * rnd.NextDouble()) - BlockJitter;

                    // Set reward probability, if the current block is one of the 3 reward blocks
                    if (blockorder[0] == trblock)
                    {
                        RandomReward = true;
                        RewardProb   = RewardProb1 / 100;
                    }
                    else if (blockorder[1] == trblock)
                    {
                        RandomReward = true;
                        RewardProb   = RewardProb2 / 100;
                    }
                    else if (blockorder[2] == trblock)
                    {
                        RandomReward = true;
                        RewardProb   = RewardProb3 / 100;
                    }
                    else
                    {
                        RandomReward = false;
                        RewardProb   = -1;
                    }
                    Trace.WriteLine("Reward Probability = " + RewardProb);

                    // Update trblock
                    if (trblock == (numBlocks - 1))
                    {
                        trblock = 0;
                    }
                    else
                    {
                        trblock++;
                    }


                    //////////////////////////////////

                    switch (status)
                    {
                    case Status.Good:
                        Trace.WriteLine("Good");
                        if ((LB == 0) || (UB == 0))
                        {
                            newParams = useScriptParameters();
                        }
                        else
                        {
                            newParams = updateSMParams();
                        }
                        break;

                    case Status.Easy:
                        if ((LB == 0) || (UB == 0))
                        {
                            newParams = useScriptParameters();
                        }
                        else
                        {
                            newParams = changeBoundaries(exptIDEval, defIDEval, db);
                            if ((UB - LB) / 2 < BoundThreshJump)     // check for jump
                            {
                                Trace.WriteLine("Jumping Target");
                                jumpTarget(exptIDEval, defIDEval, db);
                                newParams = changeBoundaries(exptIDEval, defIDEval, db);
                            }
                            else     // just easy
                            {
                                Trace.WriteLine("Too Easy");
                            }
                        }
                        break;

                    case Status.Hard:
                        Trace.WriteLine("Too Hard");
                        if ((LB == 0) || (UB == 0))
                        {
                            newParams = useScriptParameters();
                        }
                        else
                        {
                            newParams = changeBoundaries(exptIDEval, defIDEval, db);
                        }
                        break;

                    default:
                        newParams = updateSMParams();
                        break;
                    }

                    Trace.WriteLine("New Upper Bound = " + UB + ", New Lower Bound = " + LB + ", Target = " + T);
                    SMStarted = true;
                    return(SMCompletionStatus.SubStageComplete);
                }
            }
            else
            {
                return(SMCompletionStatus.Incomplete);
            }
        }