Пример #1
0
    def runTest(self):
        choice = {0: 1, 1: -1, 2: 1}
        RT = {0: 100, 1: 200, 2: 300}
        valueLeft = {0: 0, 1: 1, 2: 2}
        valueRight = {0: 3, 1: 2, 2: 1}
        fixItem = {0: [2, 1], 1: [1, 2], 2: [1, 2]}
        fixTime = {0: [50, 50], 1: [150, 50], 2: [150, 150]}
        fixRDV = {0: [0.1, 0.2], 1: [0.5, 0.8], 2: [0.3, 0.6]}
        numTrials = 3
        util.save_simulations_to_csv(
            choice, RT, valueLeft, valueRight, fixItem, fixTime, fixRDV,
            numTrials)

        choiceFile = open('choice.csv', 'r')
        RTFile = open('rt.csv', 'r')
        valueLeftFile = open('value_left.csv', 'r')
        valueRightFile = open('value_right.csv', 'r')
        fixItemFile = open('fix_item.csv', 'r')
        fixTimeFile = open('fix_time.csv', 'r')
        fixRDVFile = open('fix_rdv.csv', 'r')

        self.assertEqual("0,1,-1,1\n", choiceFile.read())
        self.assertEqual("0,100,200,300\n", RTFile.read())
        self.assertEqual("0,0,1,2\n", valueLeftFile.read())
        self.assertEqual("0,3,2,1\n", valueRightFile.read())
        self.assertEqual("0,2,1,1\n1,1,2,2\n", fixItemFile.read())
        self.assertEqual("0,50,150,150\n1,50,50,150\n", fixTimeFile.read())
        self.assertEqual("0,0.1,0.5,0.3\n1,0.2,0.8,0.6\n", fixRDVFile.read())

        os.remove('choice.csv')
        os.remove('rt.csv')
        os.remove('value_left.csv')
        os.remove('value_right.csv')
        os.remove('fix_item.csv')
        os.remove('fix_time.csv')
        os.remove('fix_rdv.csv')
Пример #2
0
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("--num-threads", type=int, default=9,
                        help="Size of the thread pool.")
    parser.add_argument("--trials-per-subject", type=int, default=100,
                        help="Number of trials from each subject to be used in "
                        "the analysis; if smaller than 1, all trials are used.")
    parser.add_argument("--num-simulations", type=int, default=400,
                        help="Number of simulations to be generated per trial "
                        "condition.")
    parser.add_argument("--range-d", nargs="+", type=float,
                        default=[0.003, 0.006, 0.009],
                        help="Search range for parameter d.")
    parser.add_argument("--range-sigma", nargs="+", type=float,
                        default=[0.03, 0.06, 0.09],
                        help="Search range for parameter sigma.")
    parser.add_argument("--range-theta", nargs="+", type=float,
                        default=[0.3, 0.5, 0.7],
                        help="Search range for parameter theta.")
    parser.add_argument("--expdata-file-name", type=str, default="expdata.csv",
                        help="Name of experimental data file.")
    parser.add_argument("--fixations-file-name", type=str,
                        default="fixations.csv", help="Name of fixations file.")
    parser.add_argument("--use-cis-trials", default=False, action="store_true",
                        help="Use CIS trials in the analysis.")
    parser.add_argument("--use-trans-trials", default=False,
                        action="store_true", help="Use TRANS trials in the "
                        "analysis.")
    parser.add_argument("--save-simulations", default=False,
                        action="store_true", help="Save simulations to CSV.")
    parser.add_argument("--verbose", default=False, action="store_true",
                        help="Increase output verbosity.")
    args = parser.parse_args()

    pool = Pool(args.num_threads)

    # Load experimental data from CSV file.
    try:
        data = load_data_from_csv(
            args.expdata_file_name, args.fixations_file_name,
            useAngularDists=True)
    except Exception as e:
        print("An exception occurred while loading the data: " + str(e))
        return
    choice = data.choice
    valueLeft = data.valueLeft
    valueRight = data.valueRight
    fixItem = data.fixItem
    fixTime = data.fixTime
    isCisTrial = data.isCisTrial
    isTransTrial = data.isTransTrial

    # Maximum likelihood estimation.
    # Grid search on the parameters of the model using odd trials only.
    if args.verbose:
        print("Starting grid search...")
    models = list()
    listParams = list()
    for d in args.range_d:
        for theta in args.range_theta:
            for sigma in args.range_sigma:
                models.append((d, theta, sigma))
                params = (choice, valueLeft, valueRight, fixItem, fixTime, d,
                          theta, sigma, args.trials_per_subject, True, False,
                          isCisTrial, isTransTrial, args.use_cis_trials,
                          args.use_trans_trials, args.verbose)
                listParams.append(params)
    results = pool.map(get_model_nll_wrapper, listParams)

    # Get optimal parameters.
    minNegLogLikeIdx = results.index(min(results))
    optimD = models[minNegLogLikeIdx][0]
    optimTheta = models[minNegLogLikeIdx][1]
    optimSigma = models[minNegLogLikeIdx][2]
    if args.verbose:
        print("Finished grid search!")
        print("Optimal d: " + str(optimD))
        print("Optimal theta: " + str(optimTheta))
        print("Optimal sigma: " + str(optimSigma))
        print("Min NLL: " + str(min(results)))

    # Get empirical distributions from even trials only.
    try:
        dists = get_empirical_distributions(
            valueLeft, valueRight, fixItem, fixTime, useOddTrials=False,
            useEvenTrials=True, isCisTrial=isCisTrial,
            isTransTrial=isTransTrial, useCisTrials=args.use_cis_trials,
            useTransTrials=args.use_trans_trials)
    except Exception as e:
        print("An exception occurred while getting empirical distributions: " +
              str(e))
        return
    probLeftFixFirst = dists.probLeftFixFirst
    distLatencies = dists.distLatencies
    distTransitions = dists.distTransitions
    distFixations = dists.distFixations

    # Parameters for generating simulations.
    orientations = range(-15,20,5)
    trialConditions = list()
    for oLeft in orientations:
        for oRight in orientations:
            vLeft = np.absolute((np.absolute(oLeft) - 15) / 5)
            vRight = np.absolute((np.absolute(oRight) - 15) / 5)
            if oLeft != oRight and args.use_cis_trials and oLeft * oRight >= 0:
                trialConditions.append((vLeft, vRight))
            elif (oLeft != oRight and args.use_trans_trials and
                  oLeft * oRight <= 0):
                trialConditions.append((vLeft, vRight))

    # Generate simulations using the empirical distributions and the
    # estimated parameters.
    try:
        simul = run_simulations(
            probLeftFixFirst, distLatencies, distTransitions, distFixations,
            args.num_simulations, trialConditions, optimD, optimTheta,
            sigma=optimSigma)
    except Exception as e:
        print("An exception occurred while running simulations: " + str(e))
        return
    simulRT = simul.RT
    simulChoice = simul.choice
    simulValueLeft = simul.valueLeft
    simulValueRight = simul.valueRight
    simulFixItem = simul.fixItem
    simulFixTime = simul.fixTime
    simulFixRDV = simul.fixRDV

    if args.save_simulations:
        totalTrials = args.num_simulations * len(trialConditions)
        save_simulations_to_csv(
            simulChoice, simulRT, simulValueLeft, simulValueRight, simulFixItem,
            simulFixTime, simulFixRDV, totalTrials)
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("subject", type=str, help="Subject name.")
    parser.add_argument("--num-threads", type=int, default=9,
                        help="Size of the thread pool.")
    parser.add_argument("--num-trials", type=int, default=100,
                        help="Number of trials to be used in the analysis; if "
                        "smaller than 1, all trials are used.")
    parser.add_argument("--num-samples", type=int, default=32,
                        help="Number of samples to be drawn from the posterior "
                        "distribution when generating simulations.")
    parser.add_argument("--num-simulations-per-sample", type=int, default=1,
                        help="Number of simulations to be genearated for each "
                        "sample drawn from the posterior distribution.")
    parser.add_argument("--range-d", nargs="+", type=float,
                        default=[0.003, 0.006, 0.009],
                        help="Search range for parameter d.")
    parser.add_argument("--range-sigma", nargs="+", type=float,
                        default=[0.03, 0.06, 0.09],
                        help="Search range for parameter sigma.")
    parser.add_argument("--range-theta", nargs="+", type=float,
                        default=[0.3, 0.5, 0.7],
                        help="Search range for parameter theta.")
    parser.add_argument("--expdata-file-name", type=str, default="expdata.csv",
                        help="Name of experimental data file.")
    parser.add_argument("--fixations-file-name", type=str,
                        default="fixations.csv", help="Name of fixations file.")
    parser.add_argument("--save-simulations", default=False,
                        action="store_true", help="Save simulations to CSV.")
    parser.add_argument("--verbose", default=False, action="store_true",
                        help="Increase output verbosity.")
    args = parser.parse_args()

    pool = Pool(args.num_threads)

    choice = dict()
    valueLeft = dict()
    valueRight = dict()
    fixItem = dict()
    fixTime = dict()

    # Load experimental data from CSV file.
    try:
        data = load_data_from_csv(
            args.expdata_file_name, args.fixations_file_name,
            useAngularDists=True)
    except Exception as e:
        print("An exception occurred while loading the data: " + str(e))
        return
    choice[args.subject] = data.choice[args.subject]
    valueLeft[args.subject] = data.valueLeft[args.subject]
    valueRight[args.subject] = data.valueRight[args.subject]
    fixItem[args.subject] = data.fixItem[args.subject]
    fixTime[args.subject] = data.fixTime[args.subject]

    # Posteriors estimation for the parameters of the model, using odd trials.
    if args.verbose:
        print("Starting grid search for subject " + args.subject + "...")
    numModels = (len(args.range_d) * len(args.range_theta) *
                 len(args.range_sigma))
    models = list()
    posteriors = dict()
    for d in args.range_d:
        for theta in args.range_theta:
            for sigma in args.range_sigma:
                model = (d, theta, sigma)
                models.append(model)
                posteriors[model] = 1. / numModels

    subjects = choice.keys()
    for subject in subjects:
        trials = choice[subject].keys()
        if args.num_trials < 1:
            args.num_trials = len(trials)
        trialSet = np.random.choice(
            [trial for trial in trials if trial % 2],
            args.num_trials, replace=False)
        for trial in trialSet:
            if not trial % 2:
                continue
            listParams = list()
            for model in models:
                listParams.append(
                    (choice[subject][trial], valueLeft[subject][trial],
                    valueRight[subject][trial], fixItem[subject][trial],
                    fixTime[subject][trial], model[0], model[1], model[2]))
            try:
                likelihoods = pool.map(get_trial_likelihood_wrapper, listParams)
            except Exception as e:
                print("An exception occurred during the likelihood computation "
                      "for trial " + str(trial) + ": " + str(e))
                return

            # Get the denominator for normalizing the posteriors.
            i = 0
            denominator = 0
            for model in models:
                denominator += posteriors[model] * likelihoods[i]
                i += 1
            if denominator == 0:
                continue

            # Calculate the posteriors after this trial.
            i = 0
            for model in models:
                prior = posteriors[model]
                posteriors[model] = likelihoods[i] * prior / denominator
                i += 1
        if args.verbose:
            for model in posteriors:
                print("P" + str(model) + " = " + str(posteriors[model]))
            print("Sum: " + str(sum(posteriors.values())))

    if args.verbose:
        print("Finished grid search!")

    # Get empirical distributions from even trials.
    try:
        dists = get_empirical_distributions(
            valueLeft, valueRight, fixItem, fixTime, useOddTrials=False,
            useEvenTrials=True)
    except Exception as e:
        print("An exception occurred while getting empirical distributions: " +
              str(e))
        return
    probLeftFixFirst = dists.probLeftFixFirst
    distLatencies = dists.distLatencies
    distTransitions = dists.distTransitions
    distFixations = dists.distFixations

    # Trial conditions for generating simulations.
    orientations = range(-15,20,5)
    trialConditions = list()
    for oLeft in orientations:
        for oRight in orientations:
            if oLeft != oRight:
                vLeft = np.absolute((np.absolute(oLeft) - 15) / 5)
                vRight = np.absolute((np.absolute(oRight) - 15) / 5)
                trialConditions.append((vLeft, vRight))

    # Generate probabilistic simulations using the posteriors distribution.
    try:
        simul = generate_probabilistic_simulations(
            probLeftFixFirst, distLatencies, distTransitions, distFixations,
            trialConditions, posteriors, args.num_samples,
            args.num_simulations_per_sample)
    except Exception as e:
        print("An exception occurred while running simulations: " + str(e))
        return
    simulRT = simul.RT
    simulChoice = simul.choice
    simulValueLeft = simul.valueLeft
    simulValueRight = simul.valueRight
    simulFixItem = simul.fixItem
    simulFixTime = simul.fixTime
    simulFixRDV = simul.fixRDV

    if args.save_simulations:
        totalTrials = len(simulRT.keys())
        save_simulations_to_csv(
            simulChoice, simulRT, simulValueLeft, simulValueRight, simulFixItem,
            simulFixTime, simulFixRDV, totalTrials)
Пример #4
0
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("--num-threads",
                        type=int,
                        default=9,
                        help="Size of the thread pool.")
    parser.add_argument(
        "--trials-per-subject",
        type=int,
        default=100,
        help="Number of trials from each subject to be used in "
        "the analysis; if smaller than 1, all trials are used.")
    parser.add_argument(
        "--num-samples",
        type=int,
        default=100,
        help="Number of samples to be drawn from the posterior "
        "distribution when generating simulations.")
    parser.add_argument("--num-simulations-per-sample",
                        type=int,
                        default=10,
                        help="Number of simulations to be genearated for each "
                        "sample drawn from the posterior distribution.")
    parser.add_argument("--range-d",
                        nargs="+",
                        type=float,
                        default=[0.003, 0.006, 0.009],
                        help="Search range for parameter d.")
    parser.add_argument("--range-sigma",
                        nargs="+",
                        type=float,
                        default=[0.03, 0.06, 0.09],
                        help="Search range for parameter sigma.")
    parser.add_argument("--range-theta",
                        nargs="+",
                        type=float,
                        default=[0.3, 0.5, 0.7],
                        help="Search range for parameter theta.")
    parser.add_argument("--expdata-file-name",
                        type=str,
                        default="expdata.csv",
                        help="Name of experimental data file.")
    parser.add_argument("--fixations-file-name",
                        type=str,
                        default="fixations.csv",
                        help="Name of fixations file.")
    parser.add_argument("--save-simulations",
                        default=False,
                        action="store_true",
                        help="Save simulations to CSV.")
    parser.add_argument("--verbose",
                        default=False,
                        action="store_true",
                        help="Increase output verbosity.")
    args = parser.parse_args()

    pool = Pool(args.num_threads)

    # Load experimental data from CSV file.
    try:
        data = load_data_from_csv(args.expdata_file_name,
                                  args.fixations_file_name,
                                  useAngularDists=True)
    except Exception as e:
        print("An exception occurred while loading the data: " + str(e))
        return
    choice = data.choice
    valueLeft = data.valueLeft
    valueRight = data.valueRight
    fixItem = data.fixItem
    fixTime = data.fixTime

    # Posteriors estimation for the parameters of the model, using odd trials.
    if args.verbose:
        print("Starting grid search...")
    numModels = (len(args.range_d) * len(args.range_theta) *
                 len(args.range_sigma))
    models = list()
    posteriors = dict()
    for d in args.range_d:
        for theta in args.range_theta:
            for sigma in args.range_sigma:
                model = (d, theta, sigma)
                models.append(model)
                posteriors[model] = 1. / numModels

    subjects = choice.keys()
    for subject in subjects:
        if args.verbose:
            print("Running subject " + subject + "...")
        trials = choice[subject].keys()
        if args.trials_per_subject < 1:
            args.trials_per_subject = len(trials)
        trialSet = np.random.choice([trial for trial in trials if trial % 2],
                                    args.trials_per_subject,
                                    replace=False)
        for trial in trialSet:
            listParams = list()
            for model in models:
                listParams.append(
                    (choice[subject][trial], valueLeft[subject][trial],
                     valueRight[subject][trial], fixItem[subject][trial],
                     fixTime[subject][trial], model[0], model[1], model[2]))
            try:
                likelihoods = pool.map(get_trial_likelihood_wrapper,
                                       listParams)
            except Exception as e:
                print(
                    "An exception occurred during the likelihood computation "
                    "for subject " + subject + ", trial " + str(trial) + ": " +
                    str(e))
                return

            # Get the denominator for normalizing the posteriors.
            i = 0
            denominator = 0
            for model in models:
                denominator += posteriors[model] * likelihoods[i]
                i += 1
            if denominator == 0:
                continue

            # Calculate the posteriors after this trial.
            i = 0
            for model in models:
                prior = posteriors[model]
                posteriors[model] = likelihoods[i] * prior / denominator
                i += 1

        if args.verbose:
            for model in posteriors:
                print("P" + str(model) + " = " + str(posteriors[model]))
            print("Sum: " + str(sum(posteriors.values())))

    if args.verbose:
        print("Finished grid search!")

    # Get empirical distributions from even trials.
    try:
        dists = get_empirical_distributions(valueLeft,
                                            valueRight,
                                            fixItem,
                                            fixTime,
                                            useOddTrials=False,
                                            useEvenTrials=True)
    except Exception as e:
        print("An exception occurred while getting empirical distributions: " +
              str(e))
        return
    probLeftFixFirst = dists.probLeftFixFirst
    distLatencies = dists.distLatencies
    distTransitions = dists.distTransitions
    distFixations = dists.distFixations

    # Trial conditions for generating simulations.
    orientations = range(-15, 20, 5)
    trialConditions = list()
    for oLeft in orientations:
        for oRight in orientations:
            if oLeft != oRight:
                vLeft = np.absolute((np.absolute(oLeft) - 15) / 5)
                vRight = np.absolute((np.absolute(oRight) - 15) / 5)
                trialConditions.append((vLeft, vRight))

    # Generate probabilistic simulations using the posteriors distribution.
    try:
        simul = generate_probabilistic_simulations(
            probLeftFixFirst, distLatencies, distTransitions, distFixations,
            trialConditions, posteriors, args.num_samples,
            args.num_simulations_per_sample)
    except Exception as e:
        print("An exception occurred while running simulations: " + str(e))
        return
    simulRT = simul.RT
    simulChoice = simul.choice
    simulValueLeft = simul.valueLeft
    simulValueRight = simul.valueRight
    simulFixItem = simul.fixItem
    simulFixTime = simul.fixTime
    simulFixRDV = simul.fixRDV

    if args.save_simulations:
        totalTrials = len(simulRT.keys())
        save_simulations_to_csv(simulChoice, simulRT, simulValueLeft,
                                simulValueRight, simulFixItem, simulFixTime,
                                simulFixRDV, totalTrials)
Пример #5
0
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("subject", type=str, help="Subject name")
    parser.add_argument("--num-threads", type=int, default=9,
                        help="Size of the thread pool.")
    parser.add_argument("--num-trials", type=int, default=100,
                        help="Number of trials to be used in the analysis; if "
                        "smaller than 1, all trials are used.")
    parser.add_argument("--num-simulations", type=int, default=32,
                        help="Number of simulations to be generated per trial "
                        "condition.")
    parser.add_argument("--range-d", nargs="+", type=float,
                        default=[0.003, 0.006, 0.009],
                        help="Search range for parameter d.")
    parser.add_argument("--range-sigma", nargs="+", type=float,
                        default=[0.03, 0.06, 0.09],
                        help="Search range for parameter sigma.")
    parser.add_argument("--range-theta", nargs="+", type=float,
                        default=[0.3, 0.5, 0.7],
                        help="Search range for parameter theta.")
    parser.add_argument("--expdata-file-name", type=str, default="expdata.csv",
                        help="Name of experimental data file.")
    parser.add_argument("--fixations-file-name", type=str,
                        default="fixations.csv", help="Name of fixations file.")
    parser.add_argument("--save-simulations", default=False,
                        action="store_true", help="Save simulations to CSV.")
    parser.add_argument("--save-figures", default=False,
                        action="store_true", help="Save figures comparing "
                        "choice and RT curves for data and simulations.")
    parser.add_argument("--verbose", default=False, action="store_true",
                        help="Increase output verbosity.")
    args = parser.parse_args()

    pool = Pool(args.num_threads)

    choice = dict()
    valueLeft = dict()
    valueRight = dict()
    fixItem = dict()
    fixTime = dict()

    # Load experimental data from CSV file.
    try:
        data = load_data_from_csv(
            args.expdata_file_name, args.fixations_file_name,
            useAngularDists=True)
    except Exception as e:
        print("An exception occurred while loading the data: " + str(e))
        return
    choice[args.subject] = data.choice[args.subject]
    valueLeft[args.subject] = data.valueLeft[args.subject]
    valueRight[args.subject] = data.valueRight[args.subject]
    fixItem[args.subject] = data.fixItem[args.subject]
    fixTime[args.subject] = data.fixTime[args.subject]

    # Maximum likelihood estimation using odd trials only.
    # Grid search on the parameters of the model.
    if args.verbose:
        print("Starting grid search for subject " + args.subject + "...")
    models = list()
    listParams = list()
    for d in args.range_d:
        for theta in args.range_theta:
            for sigma in args.range_sigma:
                models.append((d, theta, sigma))
                params = (choice, valueLeft, valueRight, fixItem, fixTime, d,
                          theta, sigma, args.num_trials, True, False,
                          args.verbose)
                listParams.append(params)
    results = pool.map(get_model_nll_wrapper, listParams)

    # Get optimal parameters.
    minNegLogLikeIdx = results.index(min(results))
    optimD = models[minNegLogLikeIdx][0]
    optimTheta = models[minNegLogLikeIdx][1]
    optimSigma = models[minNegLogLikeIdx][2]
    if args.verbose:
        print("Finished grid search!")
        print("Optimal d: " + str(optimD))
        print("Optimal theta: " + str(optimTheta))
        print("Optimal sigma: " + str(optimSigma))
        print("Min NLL: " + str(min(results)))

    # Get empirical distributions from even trials.
    try:
        dists = get_empirical_distributions(
            valueLeft, valueRight, fixItem, fixTime, useOddTrials=False,
            useEvenTrials=True)
    except Exception as e:
        print("An exception occurred while getting empirical distributions: " +
              str(e))
        return
    probLeftFixFirst = dists.probLeftFixFirst
    distLatencies = dists.distLatencies
    distTransitions = dists.distTransitions
    distFixations = dists.distFixations

    # Trial conditions for generating simulations.
    orientations = range(-15,20,5)
    trialConditions = list()
    for oLeft in orientations:
        for oRight in orientations:
            if oLeft != oRight:
                vLeft = np.absolute((np.absolute(oLeft) - 15) / 5)
                vRight = np.absolute((np.absolute(oRight) - 15) / 5)
                trialConditions.append((vLeft, vRight))

    # Generate simulations using the even trials distributions and the
    # estimated parameters.
    try:
        simul = run_simulations(
            probLeftFixFirst, distLatencies, distTransitions, distFixations,
            args.num_simulations, trialConditions, optimD, optimTheta,
            sigma=optimSigma)
    except Exception as e:
        print("An exception occurred while running simulations: " + str(e))
        return
    simulRT = simul.RT
    simulChoice = simul.choice
    simulValueLeft = simul.valueLeft
    simulValueRight = simul.valueRight
    simulFixItem = simul.fixItem
    simulFixTime = simul.fixTime
    simulFixRDV = simul.fixRDV

    totalTrials = args.num_simulations * len(trialConditions)

    if args.save_simulations:
        save_simulations_to_csv(
            simulChoice, simulRT, simulValueLeft, simulValueRight, simulFixItem,
            simulFixTime, simulFixRDV, totalTrials)

    if args.save_figures:
        # Create pdf file to save figures.
        pp = PdfPages(
            "figures_" + str(optimD) + "_" + str(optimTheta) + "_" +
            str(optimSigma) + "_" + str(args.num_simulations) + ".pdf")

        # Generate choice and RT curves for real data (odd trials) and
        # simulations (generated from even trials).
        fig1 = generate_choice_curves(
            choice, valueLeft, valueRight, simulChoice, simulValueLeft,
            simulValueRight, totalTrials)
        pp.savefig(fig1)
        fig2 = generate_rt_curves(
            RT, valueLeft, valueRight, simulRT, simulValueLeft, simulValueRight,
            totalTrials)
        pp.savefig(fig2)
        pp.close()
Пример #6
0
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("subject", type=str, help="Subject name")
    parser.add_argument("--num-threads",
                        type=int,
                        default=9,
                        help="Size of the thread pool.")
    parser.add_argument("--num-trials",
                        type=int,
                        default=100,
                        help="Number of trials to be used in the analysis; if "
                        "smaller than 1, all trials are used.")
    parser.add_argument("--num-simulations",
                        type=int,
                        default=32,
                        help="Number of simulations to be generated per trial "
                        "condition.")
    parser.add_argument("--range-d",
                        nargs="+",
                        type=float,
                        default=[0.003, 0.006, 0.009],
                        help="Search range for parameter d.")
    parser.add_argument("--range-sigma",
                        nargs="+",
                        type=float,
                        default=[0.03, 0.06, 0.09],
                        help="Search range for parameter sigma.")
    parser.add_argument("--range-theta",
                        nargs="+",
                        type=float,
                        default=[0.3, 0.5, 0.7],
                        help="Search range for parameter theta.")
    parser.add_argument("--expdata-file-name",
                        type=str,
                        default="expdata.csv",
                        help="Name of experimental data file.")
    parser.add_argument("--fixations-file-name",
                        type=str,
                        default="fixations.csv",
                        help="Name of fixations file.")
    parser.add_argument("--save-simulations",
                        default=False,
                        action="store_true",
                        help="Save simulations to CSV.")
    parser.add_argument("--save-figures",
                        default=False,
                        action="store_true",
                        help="Save figures comparing "
                        "choice and RT curves for data and simulations.")
    parser.add_argument("--verbose",
                        default=False,
                        action="store_true",
                        help="Increase output verbosity.")
    args = parser.parse_args()

    pool = Pool(args.num_threads)

    choice = dict()
    valueLeft = dict()
    valueRight = dict()
    fixItem = dict()
    fixTime = dict()

    # Load experimental data from CSV file.
    try:
        data = load_data_from_csv(args.expdata_file_name,
                                  args.fixations_file_name,
                                  useAngularDists=True)
    except Exception as e:
        print("An exception occurred while loading the data: " + str(e))
        return
    choice[args.subject] = data.choice[args.subject]
    valueLeft[args.subject] = data.valueLeft[args.subject]
    valueRight[args.subject] = data.valueRight[args.subject]
    fixItem[args.subject] = data.fixItem[args.subject]
    fixTime[args.subject] = data.fixTime[args.subject]

    # Maximum likelihood estimation using odd trials only.
    # Grid search on the parameters of the model.
    if args.verbose:
        print("Starting grid search for subject " + args.subject + "...")
    models = list()
    listParams = list()
    for d in args.range_d:
        for theta in args.range_theta:
            for sigma in args.range_sigma:
                models.append((d, theta, sigma))
                params = (choice, valueLeft, valueRight, fixItem, fixTime, d,
                          theta, sigma, args.num_trials, True, False,
                          args.verbose)
                listParams.append(params)
    results = pool.map(get_model_nll_wrapper, listParams)

    # Get optimal parameters.
    minNegLogLikeIdx = results.index(min(results))
    optimD = models[minNegLogLikeIdx][0]
    optimTheta = models[minNegLogLikeIdx][1]
    optimSigma = models[minNegLogLikeIdx][2]
    if args.verbose:
        print("Finished grid search!")
        print("Optimal d: " + str(optimD))
        print("Optimal theta: " + str(optimTheta))
        print("Optimal sigma: " + str(optimSigma))
        print("Min NLL: " + str(min(results)))

    # Get empirical distributions from even trials.
    try:
        dists = get_empirical_distributions(valueLeft,
                                            valueRight,
                                            fixItem,
                                            fixTime,
                                            useOddTrials=False,
                                            useEvenTrials=True)
    except Exception as e:
        print("An exception occurred while getting empirical distributions: " +
              str(e))
        return
    probLeftFixFirst = dists.probLeftFixFirst
    distLatencies = dists.distLatencies
    distTransitions = dists.distTransitions
    distFixations = dists.distFixations

    # Trial conditions for generating simulations.
    orientations = range(-15, 20, 5)
    trialConditions = list()
    for oLeft in orientations:
        for oRight in orientations:
            if oLeft != oRight:
                vLeft = np.absolute((np.absolute(oLeft) - 15) / 5)
                vRight = np.absolute((np.absolute(oRight) - 15) / 5)
                trialConditions.append((vLeft, vRight))

    # Generate simulations using the even trials distributions and the
    # estimated parameters.
    try:
        simul = run_simulations(probLeftFixFirst,
                                distLatencies,
                                distTransitions,
                                distFixations,
                                args.num_simulations,
                                trialConditions,
                                optimD,
                                optimTheta,
                                sigma=optimSigma)
    except Exception as e:
        print("An exception occurred while running simulations: " + str(e))
        return
    simulRT = simul.RT
    simulChoice = simul.choice
    simulValueLeft = simul.valueLeft
    simulValueRight = simul.valueRight
    simulFixItem = simul.fixItem
    simulFixTime = simul.fixTime
    simulFixRDV = simul.fixRDV

    totalTrials = args.num_simulations * len(trialConditions)

    if args.save_simulations:
        save_simulations_to_csv(simulChoice, simulRT, simulValueLeft,
                                simulValueRight, simulFixItem, simulFixTime,
                                simulFixRDV, totalTrials)

    if args.save_figures:
        # Create pdf file to save figures.
        pp = PdfPages("figures_" + str(optimD) + "_" + str(optimTheta) + "_" +
                      str(optimSigma) + "_" + str(args.num_simulations) +
                      ".pdf")

        # Generate choice and RT curves for real data (odd trials) and
        # simulations (generated from even trials).
        fig1 = generate_choice_curves(choice, valueLeft, valueRight,
                                      simulChoice, simulValueLeft,
                                      simulValueRight, totalTrials)
        pp.savefig(fig1)
        fig2 = generate_rt_curves(RT, valueLeft, valueRight, simulRT,
                                  simulValueLeft, simulValueRight, totalTrials)
        pp.savefig(fig2)
        pp.close()
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("--bin-step", type=int, default=10,
                        help="Size of the bin step to be used in the fixation "
                        "distributions.")
    parser.add_argument("--max-fix-bin", type=int, default=3000,
                        help="Maximum fixation length to be used in the "
                        "fixation distributions.")
    parser.add_argument("--num-fix-dists", type=int, default=3,
                        help="Number of fixation distributions.")
    parser.add_argument("--num-iterations", type=int, default=3,
                        help="Number of iterations used to approximate the"
                        "true distributions.")
    parser.add_argument("--num-simulations", type=int, default=400,
                        help="Number of simulations to be generated per trial "
                        "condition.")
    parser.add_argument("--d", type=float, default=0.004,
                        help="aDDM parameter for generating simulations.")
    parser.add_argument("--sigma", type=float, default=0.07,
                        help="aDDM parameter for generating simulations.")
    parser.add_argument("--theta", type=float, default=0.25,
                        help="aDDM parameter for generating simulations.")
    parser.add_argument("--expdata-file-name", type=str, default="expdata.csv",
                        help="Name of experimental data file.")
    parser.add_argument("--fixations-file-name", type=str,
                        default="fixations.csv", help="Name of fixations file.")
    parser.add_argument("--save-simulations", default=False,
                        action="store_true", help="Save simulations to CSV.")
    parser.add_argument("--verbose", default=False, action="store_true",
                        help="Increase output verbosity.")
    args = parser.parse_args()

    # Time bins to be used in the fixation distributions.
    bins = range(args.bin_step, args.max_fix_bin + args.bin_step, args.bin_step)

    # Load experimental data from CSV file.
    try:
        data = load_data_from_csv(
            args.expdata_file_name, args.fixations_file_name,
            useAngularDists=True)
    except Exception as e:
        print("An exception occurred while loading the data: " + str(e))
        return
    RT = data.RT
    choice = data.choice
    valueLeft = data.valueLeft
    valueRight = data.valueRight
    fixItem = data.fixItem
    fixTime = data.fixTime

    # Get empirical distributions from even trials.
    try:
        dists = get_empirical_distributions(
            valueLeft, valueRight, fixItem, fixTime, useOddTrials=False,
            useEvenTrials=True)
    except Exception as e:
        print("An exception occurred while getting empirical distributions: " +
              str(e))
        return
    probLeftFixFirst = dists.probLeftFixFirst
    distLatencies = dists.distLatencies
    distTransitions = dists.distTransitions
    distFixations = dists.distFixations

    # Trial conditions for generating simulations.
    orientations = range(-15,20,5)
    trialConditions = list()
    for oLeft in orientations:
        for oRight in orientations:
            if oLeft != oRight:
                vLeft = np.absolute((np.absolute(oLeft) - 15) / 5)
                vRight = np.absolute((np.absolute(oRight) - 15) / 5)
                trialConditions.append((vLeft, vRight))

    # Create original empirical distributions of fixations.
    empiricalFixDist = dict()
    for numFix in xrange(1, args.num_fix_dists + 1):
        empiricalFixDist[numFix] = dict()
        for valueDiff in xrange(-3,4):
            empiricalFixDist[numFix][valueDiff] = dict()
            for bin in bins:
                empiricalFixDist[numFix][valueDiff][bin] = 0
            for fixTime in distFixations[numFix][valueDiff]:
                bin = args.bin_step * min((fixTime // args.bin_step) + 1,
                                          len(bins))
                empiricalFixDist[numFix][valueDiff][bin] += 1

    # Normalize the distributions.
    for numFix in xrange(1, args.num_fix_dists + 1):
        for valueDiff in xrange(-3,4):
            sumBins = sum(empiricalFixDist[numFix][valueDiff].values())
            for bin in bins:
                empiricalFixDist[numFix][valueDiff][bin] = (
                    float(empiricalFixDist[numFix][valueDiff][bin]) /
                    float(sumBins))

    for it in xrange(args.num_iterations):
        if args.verbose:
            print("Iteration " + str(it + 1) + "/" + str(args.num_iterations))
        # Generate simulations using the current empirical distributions and the
        # model parameters.
        try:
            simul = run_simulations(
                probLeftFixFirst, distLatencies, distTransitions,
                empiricalFixDist, args.num_simulations, trialConditions, args.d,
                args.theta, args.sigma, bins, args.num_fix_dists)
        except Exception as e:
            print("An exception occurred while running simulations in " +
                  "iteration " + str(it) + ": " + str(e))
            return
        simulRT = simul.RT
        simulChoice = simul.choice
        simulValueLeft = simul.valueLeft
        simulValueRight = simul.valueRight
        simulFixItem = simul.fixItem
        simulFixTime = simul.fixTime
        simulFixRDV = simul.fixRDV
        simulUninterruptedLastFixTime = simul.uninterruptedLastFixTime

        countLastFix = dict()
        countTotal = dict()
        for numFix in xrange(1, args.num_fix_dists + 1):
            countLastFix[numFix] = dict()
            countTotal[numFix] = dict()
            for valueDiff in xrange(-3,4):
                countLastFix[numFix][valueDiff] = dict()
                countTotal[numFix][valueDiff] = dict()
                for bin in bins:
                    countLastFix[numFix][valueDiff][bin] = 0
                    countTotal[numFix][valueDiff][bin] = 0

        for trial in simulRT.keys():
            # Count all item fixations, except last.
            fixUnfixValueDiffs = {
                1: simulValueLeft[trial] - simulValueRight[trial],
                2: simulValueRight[trial] - simulValueLeft[trial]}
            lastItemFixSkipped = False
            lastFixItem = -1
            numFix = 1
            for item, time in zip(
                    simulFixItem[trial][::-1], simulFixTime[trial][::-1]):
                if not lastItemFixSkipped and (item == 1 or item == 2):
                    lastFixItem = item
                    lastItemFixSkipped = True
                    continue
                if item == 1 or item == 2:
                    bin = args.bin_step * min((time // args.bin_step) + 1,
                                              len(bins))
                    vDiff = fixUnfixValueDiffs[item]
                    countTotal[numFix][vDiff][bin] += 1
                    if numFix < args.num_fix_dists:
                        numFix += 1
            # Count last fixation.
            vDiff = fixUnfixValueDiffs[lastFixItem]
            bin = args.bin_step * min(
                (simulUninterruptedLastFixTime[trial] // args.bin_step) + 1,
                len(bins))
            countLastFix[numFix][vDiff][bin] += 1
            countTotal[numFix][vDiff][bin] += 1

        # Obtain true distributions of fixations.
        trueFixDist = dict()
        for numFix in xrange(1, args.num_fix_dists + 1):
            trueFixDist[numFix] = dict()
            for valueDiff in xrange(-3,4):
                trueFixDist[numFix][valueDiff] = dict()
                for bin in bins:
                    probNotLastFix = 1
                    if countTotal[numFix][valueDiff][bin] > 0:
                        probNotLastFix = 1 - (
                            float(countLastFix[numFix][valueDiff][bin]) /
                            float(countTotal[numFix][valueDiff][bin]))
                    if probNotLastFix == 0:
                        trueFixDist[numFix][valueDiff][bin] = (
                            empiricalFixDist[numFix][valueDiff][bin])
                    else:
                        trueFixDist[numFix][valueDiff][bin] = (
                            float(empiricalFixDist[numFix][valueDiff][bin]) /
                            float(probNotLastFix))
        # Normalize the distributions.
        for numFix in xrange(1, args.num_fix_dists + 1):
            for valueDiff in xrange(-3,4):
                sumBins = sum(trueFixDist[numFix][valueDiff].values())
                if sumBins > 0:
                    for bin in bins:
                        trueFixDist[numFix][valueDiff][bin] = (
                            float(trueFixDist[numFix][valueDiff][bin]) /
                            float(sumBins))

        # Update empirical distributions using the current true distributions.
        empiricalFixDist = trueFixDist

    # Generate final simulations.
    try:
        simul = run_simulations(
            probLeftFixFirst, distLatencies, distTransitions, empiricalFixDist,
            args.num_simulations, trialConditions, args.d, args.theta,
            args.sigma, bins, args.num_fix_dists)
    except Exception as e:
            print("An exception occurred while running the final " +
                  "simulations: " + str(e))
            return
    simulRT = simul.RT
    simulChoice = simul.choice
    simulValueLeft = simul.valueLeft
    simulValueRight = simul.valueRight
    simulFixItem = simul.fixItem
    simulFixTime = simul.fixTime
    simulFixRDV = simul.fixRDV
    simulUninterruptedLastFixTime = simul.uninterruptedLastFixTime

    if args.save_simulations:
        totalTrials = args.num_simulations * len(trialConditions)
        save_simulations_to_csv(
            simulChoice, simulRT, simulValueLeft, simulValueRight, simulFixItem,
            simulFixTime, simulFixRDV, totalTrials)
Пример #8
0
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("--bin-step",
                        type=int,
                        default=10,
                        help="Size of the bin step to be used in the fixation "
                        "distributions.")
    parser.add_argument("--max-fix-bin",
                        type=int,
                        default=3000,
                        help="Maximum fixation length to be used in the "
                        "fixation distributions.")
    parser.add_argument("--num-fix-dists",
                        type=int,
                        default=3,
                        help="Number of fixation distributions.")
    parser.add_argument("--num-iterations",
                        type=int,
                        default=3,
                        help="Number of iterations used to approximate the"
                        "true distributions.")
    parser.add_argument("--num-simulations",
                        type=int,
                        default=400,
                        help="Number of simulations to be generated per trial "
                        "condition.")
    parser.add_argument("--d",
                        type=float,
                        default=0.004,
                        help="aDDM parameter for generating simulations.")
    parser.add_argument("--sigma",
                        type=float,
                        default=0.07,
                        help="aDDM parameter for generating simulations.")
    parser.add_argument("--theta",
                        type=float,
                        default=0.25,
                        help="aDDM parameter for generating simulations.")
    parser.add_argument("--expdata-file-name",
                        type=str,
                        default="expdata.csv",
                        help="Name of experimental data file.")
    parser.add_argument("--fixations-file-name",
                        type=str,
                        default="fixations.csv",
                        help="Name of fixations file.")
    parser.add_argument("--save-simulations",
                        default=False,
                        action="store_true",
                        help="Save simulations to CSV.")
    parser.add_argument("--verbose",
                        default=False,
                        action="store_true",
                        help="Increase output verbosity.")
    args = parser.parse_args()

    # Time bins to be used in the fixation distributions.
    bins = range(args.bin_step, args.max_fix_bin + args.bin_step,
                 args.bin_step)

    # Load experimental data from CSV file.
    try:
        data = load_data_from_csv(args.expdata_file_name,
                                  args.fixations_file_name,
                                  useAngularDists=True)
    except Exception as e:
        print("An exception occurred while loading the data: " + str(e))
        return
    RT = data.RT
    choice = data.choice
    valueLeft = data.valueLeft
    valueRight = data.valueRight
    fixItem = data.fixItem
    fixTime = data.fixTime

    # Get empirical distributions from even trials.
    try:
        dists = get_empirical_distributions(valueLeft,
                                            valueRight,
                                            fixItem,
                                            fixTime,
                                            useOddTrials=False,
                                            useEvenTrials=True)
    except Exception as e:
        print("An exception occurred while getting empirical distributions: " +
              str(e))
        return
    probLeftFixFirst = dists.probLeftFixFirst
    distLatencies = dists.distLatencies
    distTransitions = dists.distTransitions
    distFixations = dists.distFixations

    # Trial conditions for generating simulations.
    orientations = range(-15, 20, 5)
    trialConditions = list()
    for oLeft in orientations:
        for oRight in orientations:
            if oLeft != oRight:
                vLeft = np.absolute((np.absolute(oLeft) - 15) / 5)
                vRight = np.absolute((np.absolute(oRight) - 15) / 5)
                trialConditions.append((vLeft, vRight))

    # Create original empirical distributions of fixations.
    empiricalFixDist = dict()
    for numFix in xrange(1, args.num_fix_dists + 1):
        empiricalFixDist[numFix] = dict()
        for valueDiff in xrange(-3, 4):
            empiricalFixDist[numFix][valueDiff] = dict()
            for bin in bins:
                empiricalFixDist[numFix][valueDiff][bin] = 0
            for fixTime in distFixations[numFix][valueDiff]:
                bin = args.bin_step * min(
                    (fixTime // args.bin_step) + 1, len(bins))
                empiricalFixDist[numFix][valueDiff][bin] += 1

    # Normalize the distributions.
    for numFix in xrange(1, args.num_fix_dists + 1):
        for valueDiff in xrange(-3, 4):
            sumBins = sum(empiricalFixDist[numFix][valueDiff].values())
            for bin in bins:
                empiricalFixDist[numFix][valueDiff][bin] = (
                    float(empiricalFixDist[numFix][valueDiff][bin]) /
                    float(sumBins))

    for it in xrange(args.num_iterations):
        if args.verbose:
            print("Iteration " + str(it + 1) + "/" + str(args.num_iterations))
        # Generate simulations using the current empirical distributions and the
        # model parameters.
        try:
            simul = run_simulations(probLeftFixFirst, distLatencies,
                                    distTransitions, empiricalFixDist,
                                    args.num_simulations, trialConditions,
                                    args.d, args.theta, args.sigma, bins,
                                    args.num_fix_dists)
        except Exception as e:
            print("An exception occurred while running simulations in " +
                  "iteration " + str(it) + ": " + str(e))
            return
        simulRT = simul.RT
        simulChoice = simul.choice
        simulValueLeft = simul.valueLeft
        simulValueRight = simul.valueRight
        simulFixItem = simul.fixItem
        simulFixTime = simul.fixTime
        simulFixRDV = simul.fixRDV
        simulUninterruptedLastFixTime = simul.uninterruptedLastFixTime

        countLastFix = dict()
        countTotal = dict()
        for numFix in xrange(1, args.num_fix_dists + 1):
            countLastFix[numFix] = dict()
            countTotal[numFix] = dict()
            for valueDiff in xrange(-3, 4):
                countLastFix[numFix][valueDiff] = dict()
                countTotal[numFix][valueDiff] = dict()
                for bin in bins:
                    countLastFix[numFix][valueDiff][bin] = 0
                    countTotal[numFix][valueDiff][bin] = 0

        for trial in simulRT.keys():
            # Count all item fixations, except last.
            fixUnfixValueDiffs = {
                1: simulValueLeft[trial] - simulValueRight[trial],
                2: simulValueRight[trial] - simulValueLeft[trial]
            }
            lastItemFixSkipped = False
            lastFixItem = -1
            numFix = 1
            for item, time in zip(simulFixItem[trial][::-1],
                                  simulFixTime[trial][::-1]):
                if not lastItemFixSkipped and (item == 1 or item == 2):
                    lastFixItem = item
                    lastItemFixSkipped = True
                    continue
                if item == 1 or item == 2:
                    bin = args.bin_step * min(
                        (time // args.bin_step) + 1, len(bins))
                    vDiff = fixUnfixValueDiffs[item]
                    countTotal[numFix][vDiff][bin] += 1
                    if numFix < args.num_fix_dists:
                        numFix += 1
            # Count last fixation.
            vDiff = fixUnfixValueDiffs[lastFixItem]
            bin = args.bin_step * min(
                (simulUninterruptedLastFixTime[trial] // args.bin_step) + 1,
                len(bins))
            countLastFix[numFix][vDiff][bin] += 1
            countTotal[numFix][vDiff][bin] += 1

        # Obtain true distributions of fixations.
        trueFixDist = dict()
        for numFix in xrange(1, args.num_fix_dists + 1):
            trueFixDist[numFix] = dict()
            for valueDiff in xrange(-3, 4):
                trueFixDist[numFix][valueDiff] = dict()
                for bin in bins:
                    probNotLastFix = 1
                    if countTotal[numFix][valueDiff][bin] > 0:
                        probNotLastFix = 1 - (
                            float(countLastFix[numFix][valueDiff][bin]) /
                            float(countTotal[numFix][valueDiff][bin]))
                    if probNotLastFix == 0:
                        trueFixDist[numFix][valueDiff][bin] = (
                            empiricalFixDist[numFix][valueDiff][bin])
                    else:
                        trueFixDist[numFix][valueDiff][bin] = (
                            float(empiricalFixDist[numFix][valueDiff][bin]) /
                            float(probNotLastFix))
        # Normalize the distributions.
        for numFix in xrange(1, args.num_fix_dists + 1):
            for valueDiff in xrange(-3, 4):
                sumBins = sum(trueFixDist[numFix][valueDiff].values())
                if sumBins > 0:
                    for bin in bins:
                        trueFixDist[numFix][valueDiff][bin] = (
                            float(trueFixDist[numFix][valueDiff][bin]) /
                            float(sumBins))

        # Update empirical distributions using the current true distributions.
        empiricalFixDist = trueFixDist

    # Generate final simulations.
    try:
        simul = run_simulations(probLeftFixFirst, distLatencies,
                                distTransitions, empiricalFixDist,
                                args.num_simulations, trialConditions, args.d,
                                args.theta, args.sigma, bins,
                                args.num_fix_dists)
    except Exception as e:
        print("An exception occurred while running the final " +
              "simulations: " + str(e))
        return
    simulRT = simul.RT
    simulChoice = simul.choice
    simulValueLeft = simul.valueLeft
    simulValueRight = simul.valueRight
    simulFixItem = simul.fixItem
    simulFixTime = simul.fixTime
    simulFixRDV = simul.fixRDV
    simulUninterruptedLastFixTime = simul.uninterruptedLastFixTime

    if args.save_simulations:
        totalTrials = args.num_simulations * len(trialConditions)
        save_simulations_to_csv(simulChoice, simulRT, simulValueLeft,
                                simulValueRight, simulFixItem, simulFixTime,
                                simulFixRDV, totalTrials)