def rest(trial_dur=10): """ creates target file for the rest task Args: trial_dur (float) - duration of the trial in seconds(for rest it is set at 10 seconds as default) target file fields: There are no trials really. Just one start_time and end_time """ # path to save the target files path2task_target = consts.target_dir / study_name / 'rest' consts.dircheck(path2task_target) T = {} # will be converted to a dataframe and saved as the target file T['hand'] = 'None' T['iti_dur'] = 0 T['star_time'] = 0 T['stim'] = 'fixation' T['trial_dur'] = trial_dur T['display_trial_feedback'] = False df_tmp = pd.DataFrame(T) target_filename = path2task_target / f"rest_{trial_dur}sec_{run+1:02d}.csv" df_tmp.to_csv(target_filename)
def visual_search(nrun=5, study_name='behavioral', hand='right', iti_dur=0.5, trial_dur=2, display_trial_feedback=True, TR=1, task_dur=30): """ creates target file for the visual_search task target file fields: trial_num (a column with no name - just the trial number starting from 0) stim () condition_name (easy - medium - hard) trial_type (True/False) display_trial_feedback (True/False) hand (left/right) iti_dur (duration of iti) start_time (time when the trial starts) end_time (time when the trial ends) trial_dur (trial duration) For this task, another file is needed to determine position of the display display_pos file: trial (trial number) stim (?) xpos (x coordinate) ypos (y_coordinate) orientation (orientation of the stimuli) """ # path to save the target files path2task_target = consts.target_dir / study_name / 'visual_search2' consts.dircheck(path2task_target) # loop over runs and create target files for run in range(nrun): T = {} # dictionary that will be converted to a dataframe later n_trials = int(task_dur / (trial_dur + iti_dur)) # total number of trials
def visuospatial_order(nrun=5, study_name='behavioral', dot_dur=0.75, delay_dur=0.5, prob_dur=1, iti_dur=0.5, trial_dur=6, task_dur=30, hand='right', TR=1, display_trial_feedback=True, num_trials=1, circle_radius=8, load=6, min_distance=1): """ creates target file for the visuospatial_order task target file fields: trial_num (a column with no name - just the trial number starting from 0) load (number of dots) dot_dur (time duration when the dot remains on the screen and then disapears) delay_dur (duration of the delay) trial_type (True/False) prob_dots (the dots that are chosen for the prob number or coordinates?) prob_dur (duration when prob stayes on the screen) trial_dur (duration of the trial) display_trial_feedback (True/False) hand (left/right) iti_dur (duration of iti) start_time (time when the trial starts) end_time (time when the trial ends) """ # path to save the target files path2task_target = consts.target_dir / study_name / 'visuospatial_order' consts.dircheck(path2task_target) # Version 1. Simple: Considers a circle with a certain radius and draws random dots from the circle # loop over runs and create target for run in range(nrun): T = {} # dictionary that will be converted to a dataframe later n_trials = int(task_dur / (trial_dur + iti_dur)) # total number of trials # assign trial_types n_trials_T = int(n_trials / 2) n_trials_F = n_trials - n_trials_T trials_True = np.tile(True, n_trials_T) trials_False = np.tile(False, n_trials_F) trials_types = np.concatenate((trials_True, trials_False), axis=0) # randomly shuffle trials np.random.shuffle(trials_types) # fill in fields T['trial_type'] = trials_types T['trial_dur'] = [trial_dur for i in range(n_trials)] T['iti_dur'] = [iti_dur for i in range(n_trials)] T['delay_dur'] = [delay_dur for i in range(n_trials)] T['dot_dur'] = [dot_dur for i in range(n_trials)] T['prob_dur'] = [prob_dur for i in range(n_trials)] T['hand'] = [hand for i in range(n_trials)] T['display_trial_feedback'] = [ display_trial_feedback for i in range(n_trials) ] T['start_time'] = [(trial_dur + iti_dur) * i for i in range(n_trials)] T['end_time'] = [(i + 1) * trial_dur + i * iti_dur for i in range(n_trials)] T['circle_radius'] = [circle_radius for i in range(n_trials)] T['xys_stim'] = [] T['xys_prob'] = [] # T['angle_prob'] = [] for t in range(n_trials): # ?????????????????????? Points on a circle ???????????????????????????? ## Create the circle with a certain radius # tt = np.linspace(0, 10000, num = 6, endpoint=True) ## Using the equations for the circle to create x and y # x = circle_radius*np.cos(tt) # y = circle_radius*np.sin(tt) # x = np.linspace(0, circle_radius+1, num = 1000, endpoint = True) # y = np.linspace(0, circle_radius+1, num = 1000, endpoint = True) # ??????????????????????????????????????????????????????????????????????? # ?????????????????????? Points within a square (OLD) ???????????????????????????? # x = np.random.randint(-circle_radius/2, circle_radius/2, size=1000) # y = np.random.randint(-circle_radius/2, circle_radius/2, size=1000) # circle_xys = [[x[i], y[i]] for i in range(len(x))] # randomly select from circle_xys # dot_idx = np.random.choice(len(circle_xys), size = load, replace=False) # dot_xys = [circle_xys[i] for i in dot_idx] # ???????????????????????????????????????????????????????????????????????????????? # ------------------ Generate random numbers iteratively ------------------------ # generate random points iteratively, x = np.random.uniform(-circle_radius / 2, circle_radius / 2) y = np.random.uniform(-circle_radius / 2, circle_radius / 2) # checks the distance between all the points to make sure they are at a minimum distance counter = 2 # counter for the point dot_xys = [] dot_xys.append([x, y]) while counter < load + 1: # start generating the other points ## generate another random point next_point = False xi = np.random.uniform(-circle_radius / 2, circle_radius / 2) yi = np.random.uniform(-circle_radius / 2, circle_radius / 2) # check the distance between this point and all the other points already in the list dot_xys for point in dot_xys: # calculate the distance distance = np.sqrt(((point[0] - xi)**2) + ((point[1] - yi)**2)) # print(distance) # if the distance is lower than a threshold, break the loop and generate another point if distance < min_distance: next_point = True break else: continue # append the point to the list of dots only if its distance from # all the other points is larger than min_distance if not next_point: counter += 1 dot_xys.append([xi, yi]) # ------------------------------------------------------------------------------- T['xys_stim'].append(dot_xys) # randomly pick two of the dots for probe based on the trial type # get the trial_type for the current trial current_tt = T['trial_type'][t] # pick two dots rand_probs = np.random.choice(len(dot_xys), size=2, replace=False) if ~current_tt: # False trial # the trial is false so two wrong digits with wrong order can be generated # sort the indices in descending order to make sure that their order is flipped probs_idx = np.sort(rand_probs)[::-1] else: # True trial # sort the indices in ascending order to make sure that their order is conserved probs_idx = np.sort(rand_probs) probs_xys = [dot_xys[i] for i in probs_idx] ## get the angle between the prob_dots abs_y = np.abs(probs_xys[0][1] - probs_xys[1][1]) abs_x = np.abs(probs_xys[0][0] - probs_xys[1][0]) # prob_angle = math.degrees(math.atan(abs_y/abs_x)) T['xys_prob'].append(probs_xys) # T['angle_prob'].append(prob_angle) df_tmp = pd.DataFrame(T) target_filename = path2task_target / f"visuospatial_order_{task_dur}sec_{run+1:02d}.csv" df_tmp.to_csv(target_filename) return
def flexion_extension(nrun=5, study_name='behavioral', trial_dur=14, iti_dur=1, stim_dur=1, task_dur=30, display_trial_feedback=False, TR=1): """ creates target file for the toe flexion extension task Args: nrun (int) - number of runs study_name (str) - behavioral or fmri iti_dur (float) - iti duration in seconds stim_dur (float) - duration when the action (either flexion or extension) stays on the screen TR (float) - TR in seconds task_dur (float) - task duration in seconds display_trial_feedback (bool) - True: display feedback after trial, False: don't display feedback after trial target file fields: trial_num (a column with no name - just the trial number starting from 0) stim (either flex or extend toes) trial_type (None - no true of false response) display_trial_feedback (True/False - always false because there are no real responses ) foot (left/right) iti_dur (duration of iti) start_time (time when the trial starts) end_time (time when the trial ends) trial_dur (trial duration) """ # path to save the target files path2task_target = consts.target_dir / study_name / 'flexion_extension' consts.dircheck(path2task_target) # loop over runs and create target files for run in range(nrun): T = { } # this will be converted to a dataframe and saved as target file n_trials = int(task_dur / (trial_dur + iti_dur)) # total number of trials n_trials_left = int(n_trials / 2) # trials for left foot n_trials_right = n_trials - n_trials_left # trials for right foot # fill in fields T['stim'] = ["flexion extension" for i in range(n_trials)] T['stim_dur'] = [stim_dur for i in range(n_trials)] T['trial_dur'] = [trial_dur for i in range(n_trials)] T['iti_dur'] = [iti_dur for i in range(n_trials)] T['start_time'] = [(trial_dur + iti_dur) * i for i in range(n_trials)] T['end_time'] = [(i + 1) * trial_dur + i * iti_dur for i in range(n_trials)] T['trial_type'] = ['None' for i in range(n_trials)] T['hand'] = ['None' for i in range(n_trials)] T['display_trial_feedback'] = [ display_trial_feedback for i in range(n_trials) ] ## determine the foot # trials_left = list(np.tile("left", n_trials_left).T.flatten()) # trials_right = list(np.tile("right", n_trials_right).T.flatten()) ### foot assignment #### random makes it difficult! # np.random.shuffle(trials_foot) #### maybe make it so that every other trial is right foot? # trials_foot = trials_left + trials_right # trials_foot[::2] = trials_left # trials_foot[1::2] = trials_right #### do nothing fancy and just concatenate them? # trials_foot = np.concatenate((trials_left, trials_right), axis = 0) # T['foot'] = trials_foot df_tmp = pd.DataFrame(T) target_filename = path2task_target / f"flexion_extension_{task_dur}sec_{run+1:02d}.csv" df_tmp.to_csv(target_filename) return
def finger_sequence(nrun=5, study_name='behavioral', seq_length=6, num_trials=1, announce_time=0, iti_dur=0.5, trial_dur=3.25, TR=1, task_dur=30, display_trial_feedback=True): """ creates target file for the finger sequence task Args: nrun (int) - number of runs study_name (str) - behavioral or fmri seq_length (int) - length of sequence or number of digits num_trials (int) - number of repetitions per trial type announce_time(float) - time for announcing the trial iti_dur (float) - iti duration in seconds trial_dur_list (list) - trial duration in seconds (first element: slow , second element: fast) TR (float) - TR in seconds task_dur (float) - task duration in seconds display_trial_feedback (bool) - True: display feedback after trial, False: don't display feedback after trial target file fields: trial_num (a column with no name - just the trial number starting from 0) sequence (a sequence of digits) condition_type (simple - complex) trial_type (None - no true of false response) display_trial_feedback (True/False) hand (left/right) iti_dur (duration of iti) start_time (time when the trial starts) end_time (time when the trial ends) trial_dur (trial duration) """ # the sequences seq = {} ## EXperimental: seq['complex'] = [ '1 3 2 4 3 2', '2 1 3 4 3 1', '3 2 4 1 4 2', '4 1 2 3 4 1' ] ## Control seq['simple'] = [ '1 1 1 1 1 1', '2 2 2 2 2 2', '3 3 3 3 3 3', '4 4 4 4 4 4' ] # path to save the target files path2task_target = consts.target_dir / study_name / 'finger_sequence' consts.dircheck(path2task_target) # loop over runs and create target files for run in range(nrun): T = {} # dictionary that will be converted to dataframe n_trials = int(task_dur / (trial_dur + iti_dur)) # total number of trials n_trials_comp = int(n_trials / 2) n_trials_simp = n_trials - n_trials_comp # hand assignment for complex trials ## left: 0, right: 1 ## hands are assigned equally (half of trials are with left and half are with right hand) # n_trials_left_comp = int(n_trials_comp/2) # n_trials_right_comp = n_trials_comp - n_trials_left_comp # left_trials_comp = np.tile('left', (n_trials_left_comp, 1)) # right_trials_comp = np.tile('right', (n_trials_right_comp, 1)) # trials_hands_comp = np.vstack((left_trials_comp, right_trials_comp)) # hand assignment for simple trials ## left: 0, right: 1 ## hands are assigned equally (half of trials are with left and half are with right hand) # n_trials_left_simp = int(n_trials_simp/2) # n_trials_right_simp = n_trials_simp - n_trials_left_simp # left_trials_simp = np.tile('left', (n_trials_left_simp, 1)) # right_trials_simp = np.tile('right', (n_trials_right_simp, 1)) # trials_hands_simp = np.vstack((left_trials_simp, right_trials_simp)) # shuffle hand assignments for complex and simple trials # np.random.shuffle(trials_hands_comp) # np.random.shuffle(trials_hands_simp) # shuffle sequences for complex and simple np.random.shuffle(seq['complex']) np.random.shuffle(seq['simple']) # fill in fields ## randomize order of complex and simple conditions across runs if run % 2 == 0: # in even runs complex sequences come first T['condition_type'] = np.concatenate((np.tile( 'complex', n_trials_comp), np.tile('simple', n_trials_simp)), axis=0) T['sequence'] = np.concatenate((seq['complex'], seq['simple']), axis=0).T.flatten() # T['hand'] = np.concatenate((trials_hands_comp, trials_hands_simp), axis=0).T.flatten() T['hand'] = np.tile('right', n_trials).T.flatten() else: # in odd runs simple sequences come first T['condition_type'] = np.concatenate((np.tile( 'simple', n_trials_simp), np.tile('complex', n_trials_comp)), axis=0) T['sequence'] = np.concatenate((seq['simple'], seq['complex']), axis=0).T.flatten() # T['hand'] = np.concatenate((trials_hands_simp, trials_hands_comp), axis=0).T.flatten() T['hand'] = np.tile('left', n_trials).T.flatten() T['trial_dur'] = [trial_dur for i in range(n_trials)] T['iti_dur'] = [iti_dur for i in range(n_trials)] T['start_time'] = [(trial_dur + iti_dur) * i for i in range(n_trials)] T['end_time'] = [(i + 1) * trial_dur + i * iti_dur for i in range(n_trials)] T['trial_type'] = ['None' for i in range(n_trials)] T['announce_time'] = [announce_time for i in range(n_trials)] T['display_trial_feedback'] = [ display_trial_feedback for i in range(n_trials) ] df_tmp = pd.DataFrame(T) target_filename = path2task_target / f"finger_sequence_{task_dur}sec_{run+1:02d}.csv" df_tmp.to_csv(target_filename) return
def sternberg_order(nrun=5, study_name='behavioral', digit_dur=0.75, delay_dur=0.5, prob_dur=1, load_list=[4, 6], iti_dur=0.5, trial_dur=6, task_dur=30, hand='right', display_trial_feedback=True, num_trials=1, TR=1): """ creates target file for the sternberg_order task Args: nrun (int) - number of runs study_name (str) - behavioral or fmri load? (int) - number of digits to show during encoding num_trials (int) - number of repetitions per trial type iti_dur (float) - iti duration in seconds delay_dur (float) - duration of delay between encoding and prob in seconds digit_dur (float) - duration when a digit stays on the screen in seconds prob_dur (float) - duration when prob stays on the screen in seconds hand (str) - hand with which response needs to be made trial_dur_list (list) - trial duration in seconds (first element: slow , second element: fast) TR (float) - TR in seconds task_dur (float) - task duration in seconds display_trial_feedback (bool) - True: display feedback after trial, False: don't display feedback after trial target file fields: load (number of digits) stim (a string with digits including space between them) prob_stim (digits that will be shown during prob) condition_name (easy - medium - difficult) digit_dur (how long each digit stays on the screen) delay_dur (duration of the delay period) prob_dur (duration of the prob) trial_dur (trial duration) display_trial_feedback (True/False) trial_type (True/False) hand (left/right) iti_dur (iti duration) start_time (time when the trial starts) end_time (time when the trial ends) """ # path to save the target files path2task_target = consts.target_dir / study_name / 'sternberg_order' consts.dircheck(path2task_target) # loop over runs and create target files for run in range(nrun): T = {} # dictionary that will be converted to a dataframe later n_trials = int(task_dur / (trial_dur + iti_dur)) # total number of trials # assign trial_types n_trials_T = int(n_trials / 2) n_trials_F = n_trials - n_trials_T trials_True = np.tile(True, n_trials_T) trials_False = np.tile(False, n_trials_F) trials_types = np.concatenate((trials_True, trials_False), axis=0) # randomly shuffle trials np.random.shuffle(trials_types) # generate random numbers betweem 1 and 9 rand_nums = [ np.random.choice(range(1, 10), size=6, replace=False) for i in range(n_trials) ] ## convert the random numbers to str and concatenate them stim_str = [] for nums in rand_nums: rand_str = "" for x in nums: rand_str += str(x) + " " stim_str.append(rand_str) # fill in fields T['stim'] = stim_str T['trial_type'] = trials_types T['trial_dur'] = [trial_dur for i in range(n_trials)] T['iti_dur'] = [iti_dur for i in range(n_trials)] T['delay_dur'] = [delay_dur for i in range(n_trials)] T['digit_dur'] = [digit_dur for i in range(n_trials)] T['prob_dur'] = [prob_dur for i in range(n_trials)] T['hand'] = [hand for i in range(n_trials)] T['display_trial_feedback'] = [ display_trial_feedback for i in range(n_trials) ] T['start_time'] = [(trial_dur + iti_dur) * i for i in range(n_trials)] T['end_time'] = [(i + 1) * trial_dur + i * iti_dur for i in range(n_trials)] # determine the prob stim for each trial based on trial type prob_stim = [] for t in range(n_trials): # get the trial_type for the current trial current_tt = T['trial_type'][t] # get the current stims current_stim = T['stim'][t] current_stim_digits = current_stim.split() if ~current_tt: # if it's False: # the trial is false so two wrong digits with wrong order can be generated ## generate two random numbers in the same range rand_probs = np.random.choice(range(1, 10), size=2, replace=False) probs_str = [str(x) for x in rand_probs] # convert them to str ## are the numbers in the sequence? if they are get the indices prob_order = [ current_stim_digits.index(x) for x in probs_str if x in current_stim_digits ] ## if prob order is not empty, then the order has to be changed if len( prob_order ) <= 1: # at least one number is in the generated prob numbers rand_str = "" for dig in probs_str: rand_str += str(dig) + " " prob_stim.append(rand_str) else: # then the digit is not in the stim sequence ## find the one that comes last and put it as the first digit in the prob first_prob_digit = current_stim_digits[max(prob_order)] last_prob_digit = current_stim_digits[min(prob_order)] # generate the prob stim and append it prob_stim.append(first_prob_digit + " " + last_prob_digit) else: # if it's True # pick two random digits from current stimulus probs_str = np.random.choice(current_stim_digits, 2, replace=False) # determine the order prob_order = [current_stim_digits.index(x) for x in probs_str] ## find the one that comes last and put it as the first digit in the prob first_prob_digit = current_stim_digits[min(prob_order)] last_prob_digit = current_stim_digits[max(prob_order)] # generate the prob stim and append it prob_stim.append(first_prob_digit + " " + last_prob_digit) T['prob_stim'] = prob_stim df_tmp = pd.DataFrame(T) target_filename = path2task_target / f"sternberg_order_{task_dur}sec_{run+1:02d}.csv" df_tmp.to_csv(target_filename) return
def visuospatial_order_v2(nrun=5, study_name='behavioral', dot_dur=0.75, delay_dur=0.5, prob_dur=1, iti_dur=0.5, trial_dur=6, task_dur=30, hand='right', TR=1, display_trial_feedback=True, num_trials=1, max_range=5, load=6): """ creates target file for the visuospatial_order task target file fields: trial_num (a column with no name - just the trial number starting from 0) load (number of dots) dot_dur (time duration when the dot remains on the screen and then disapears) delay_dur (duration of the delay) trial_type (True/False) prob_dots (the dots that are chosen for the prob number or coordinates?) prob_dur (duration when prob stayes on the screen) trial_dur (duration of the trial) display_trial_feedback (True/False) hand (left/right) iti_dur (duration of iti) start_time (time when the trial starts) end_time (time when the trial ends) """ # path to save the target files path2task_target = consts.target_dir / study_name / 'visuospatial_order' consts.dircheck(path2task_target) # Version 1. Simple: Considers a circle with a certain radius and draws random dots from the circle # loop over runs and create target for run in range(nrun): T = {} # dictionary that will be converted to a dataframe later n_trials = int(task_dur / (trial_dur + iti_dur)) # total number of trials # assign trial_types n_trials_T = int(n_trials / 2) n_trials_F = n_trials - n_trials_T trials_True = np.tile(True, n_trials_T) trials_False = np.tile(False, n_trials_F) trials_types = np.concatenate((trials_True, trials_False), axis=0) # randomly shuffle trials np.random.shuffle(trials_types) # fill in fields T['trial_type'] = trials_types T['trial_dur'] = [trial_dur for i in range(n_trials)] T['iti_dur'] = [iti_dur for i in range(n_trials)] T['delay_dur'] = [delay_dur for i in range(n_trials)] T['dot_dur'] = [dot_dur for i in range(n_trials)] T['prob_dur'] = [prob_dur for i in range(n_trials)] T['hand'] = [hand for i in range(n_trials)] T['display_trial_feedback'] = [ display_trial_feedback for i in range(n_trials) ] T['start_time'] = [(trial_dur + iti_dur) * i for i in range(n_trials)] T['end_time'] = [(i + 1) * trial_dur + i * iti_dur for i in range(n_trials)] T['circle_radius'] = [max_range for i in range(n_trials)] T['xys_stim'] = [] T['xys_prob'] = [] for t in range(n_trials): # randomly generate #load x and y coordinates ## the coordinates will be drawn from a uniform distribution x = np.random.uniform(-max_range, max_range, load) y = np.random.uniform(-max_range, max_range, load) x = np.sort(x) y = np.sort(y) dot_xys = [[x[i], y[i]] for i in range(len(x))] T['xys_stim'].append(dot_xys) # randomly pick two of the dots for probe based on the trial type # get the trial_type for the current trial current_tt = T['trial_type'][t] # pick two dots rand_probs = np.random.choice(len(dot_xys), size=2, replace=False) if ~current_tt: # False trial # the trial is false so two wrong digits with wrong order can be generated # sort the indices in descending order to make sure that their order is flipped probs_idx = np.sort(rand_probs)[::-1] else: # True trial # sort the indices in ascending order to make sure that their order is conserved probs_idx = np.sort(rand_probs) probs_xys = [dot_xys[i] for i in probs_idx] T['xys_prob'].append(probs_xys) df_tmp = pd.DataFrame(T) target_filename = path2task_target / f"visuospatial_order_{task_dur}sec_{run+1:02d}.csv" df_tmp.to_csv(target_filename) return