Exemple #1
0
    def _validate_field_names(self, fieldnames, filename):

        if not self._case_sensitive_col_names:
            fieldnames = [field.lower() for field in fieldnames]

        if self.FLD_LINE_NUM in fieldnames:
            raise ttrk.BadFormatError(
                "An invalid field name ({:}) was found im {:} - this is a reserved field name"
                .format(self.FLD_LINE_NUM, filename))

        for field in self._fields:
            if field not in fieldnames and not self._fields[field]['optional']:
                raise ttrk.BadFormatError(
                    "Mandatory field '{:} is missing in file {:}".format(
                        field, filename))
Exemple #2
0
def update_text_target_for_trial(exp_info, trial, use_numeric_target_as_default=False):
    """
    Update properties of the text stimuli according to the current trial info

    :param exp_info:
    :type exp_info: trajtracker.paradigms.common.BaseExperimentInfo

    :param trial:
    :type trial: trajtracker.paradigms.common.BaseTrialInfo
    
    :param use_numeric_target_as_default: For number-to-position paradigm: if this is set to True, the text.target column 
            in the CSV input file becomes optional, and the "target" column is used as the default text to show. 
    """
    if not trial.use_text_targets:
        # No text in this trial
        exp_info.text_target.texts = []
        return

    if "text.target" in trial.csv_data:
        # -- Set the text to show as target (or several, semicolon-separated texts, in case of RSVP)
        trial.text_target = trial.csv_data["text.target"]
    elif use_numeric_target_as_default and 'target' in dir(trial):
        trial.text_target = str(trial.target)
    else:
        raise ttrk.BadFormatError("The input CSV file does not contain a 'text.target' column!")

    exp_info.text_target.texts = trial.text_target.split(";")

    update_attr_by_csv_config(exp_info, trial, exp_info.text_target, 'text.font', 'text_font')
    update_attr_by_csv_config(exp_info, trial, exp_info.text_target, 'text.text_size', 'text_size')
    update_attr_by_csv_config(exp_info, trial, exp_info.text_target, 'text.bold', 'text_bold')
    update_attr_by_csv_config(exp_info, trial, exp_info.text_target, 'text.italic', 'text_italic')
    update_attr_by_csv_config(exp_info, trial, exp_info.text_target, 'text.underline', 'text_underline')
    update_attr_by_csv_config(exp_info, trial, exp_info.text_target, 'text.justification',
                              'text_justification')
    update_attr_by_csv_config(exp_info, trial, exp_info.text_target, 'text.text_colour', 'text_colour')
    update_attr_by_csv_config(exp_info, trial, exp_info.text_target, 'text.background_colour',
                              'background_colour')
    update_attr_by_csv_config(exp_info, trial, exp_info.text_target, 'text.size', 'size')
    update_attr_by_csv_config(exp_info, trial, exp_info.text_target, 'text.onset_time', 'onset_time')
    update_attr_by_csv_config(exp_info, trial, exp_info.text_target, 'text.duration', 'duration')

    upd_xy = update_attr_by_csv_config(exp_info, trial, exp_info.text_target, 'text.position', 'position')
    upd_x = _update_target_stimulus_position(exp_info, trial, exp_info.text_target, 'text', 'x')
    upd_y = _update_target_stimulus_position(exp_info, trial, exp_info.text_target, 'text', 'y')


    #-- Save stimulus coordinates in output file
    if upd_xy or upd_x or upd_y:
        exp_info.exported_trial_result_fields['text.position'] = None
        trial.results['text.position'] = format_coord_to_csv(exp_info.text_target.position)
Exemple #3
0
    def _transform_types(self, row, filename):

        for field in row:

            if field not in self._fields:
                continue

            field_type = self._fields[field]['type']

            if field_type != str:
                try:
                    row[field] = field_type(row[field])
                except BaseException as e:
                    raise ttrk.BadFormatError(
                        "Invalid CSV file format (line {:} in {:}): {:}".
                        format(row[self.FLD_LINE_NUM], filename, e))

        return row
Exemple #4
0
def create_feedback_stimuli(exp_info):
    """
    Create the stimuli to be used as feedback for the participant's response
    :param exp_info:
    :type exp_info: trajtrackerp.dchoice.ExperimentInfo
    """

    common.validate_config_param_values("feedback_stim_type",
                                        exp_info.config.feedback_stim_type,
                                        ['rectangle', 'picture', None])
    common.validate_config_param_values("feedback_select_by",
                                        exp_info.config.feedback_select_by,
                                        ['response', 'expected', 'accuracy'])
    common.validate_config_param_type("feedback_duration", numbers.Number,
                                      exp_info.config.feedback_duration)

    if exp_info.config.feedback_select_by in ('accuracy', 'expected') and \
                    len(exp_info.trials) > 0 and 'expected_response' not in exp_info.trials[0]:
        raise ttrk.BadFormatError(
            'Invalid format for {:}: when config.feedback_select_by=accuracy, you must include an expected_response column in the file'
            .format(exp_info.config.data_source))

    fb_type = exp_info.config.feedback_stim_type
    if fb_type == 'picture':
        _create_feedback_pictures(exp_info)

    elif fb_type == 'rectangle':
        _create_feedback_rectangles(exp_info)

    positions = _get_feedback_stim_positions(exp_info)

    for i in range(len(exp_info.feedback_stimuli)):

        feedback_stim = exp_info.feedback_stimuli[i]
        feedback_stim.position = positions[i]
        feedback_stim.visible = False

        #-- Hide feedback stimuli after delay
        exp_info.event_manager.register_operation(
            ttrk.events.TRIAL_SUCCEEDED + exp_info.config.feedback_duration,
            lambda t1, t2: hide_feedback_stimuli(exp_info),
            recurring=True,
            cancel_pending_operation_on=ttrk.events.TRIAL_STARTED,
            description="Hide feedback stimulus")
Exemple #5
0
    def load_from_csv(self, filename, id_type=str):
        """
        Load trajectories from a CSV file.

        The file should have the following columns:

        - x, y: the coordinates
        - time: a time point of these coordinates
        - visible: whether the stimulus should be visible in this time point
        - traj_id: use this column to specify several trajectories in a single file. If this column
          is missing, the class assumes that there is only one trajectory in the file, and its ID will be 1.

        The file should be sorter properly: all lines of a single trajectory should be grouped together, and
        times should appear in ascending order.

        :param filename: Name of the file (full path)
        :param id_type: Convert the traj_id column in the file from str to this type
        """

        _u.validate_func_arg_type(self, "load_from_csv", "filename", filename, str)

        fp, reader = self._open_and_get_reader(filename)
        has_traj_id_col = 'traj_id' in reader.fieldnames
        has_visible_col = 'visible' in reader.fieldnames

        if len(self._trajectories) > 0 and not has_traj_id_col:
            raise trajtracker.BadFormatError(("Invalid file format in {:}.load_from_csv('{:}'): " +
                                             "there is no traj_id column in the file").format(type(self).__name__, filename))

        loaded_traj_ids = set()

        try:
            #-- Validate file format
            for col_name in ['x', 'y', 'time']:
                if col_name not in reader.fieldnames:
                    raise trajtracker.BadFormatError(
                        "Invalid file format in {:}.load_from_csv('{:}'): there is no '{:}' column".format(
                            type(self).__name__, filename, col_name))


            prev_traj_id = None
            traj_data = []

            for row in reader:

                traj_id = id_type(row['traj_id']) if has_traj_id_col else 1
                if traj_id in loaded_traj_ids:
                    raise trajtracker.BadFormatError(
                        "Invalid file format in {:}.load_from_csv('{:}'): the lines of trajectory '{:}' are not consecutive".format(
                            type(self).__name__, filename, traj_id))


                if prev_traj_id is None:
                    # First trajectory in the file
                    prev_traj_id = traj_id

                elif prev_traj_id is not None and prev_traj_id != traj_id:
                    #-- A new trajectory is starting; save the trajectory that has just ended
                    self.set_trajectory(prev_traj_id, traj_data)
                    loaded_traj_ids.add(prev_traj_id)
                    traj_data = []
                    prev_traj_id = traj_id

                #-- Save current line as a time point

                time = float(row['time'])
                x = int(row['x'])
                y = int(row['y'])

                if has_visible_col:
                    visible = not (row['visible'] == '0' or row['visible'].lower().startswith('f'))
                    timepoint = (time, x, y, visible)
                else:
                    timepoint = (time, x, y)

                traj_data.append(timepoint)


            if len(traj_data) > 0:
                self.set_trajectory(prev_traj_id, traj_data)


        finally:
            fp.close()