Beispiel #1
0
def applyConstraints(dm_exp, dm_fillers):
    

    """
    Arguments:
    dm_exp        --- dm containing exp scene-object combinations
    dm_fillers    --- dm containing filler scene-object combinations
    
    Returns:
    final_dm_test_feedback        --- final datamatrix for the test feedback blockloop
    final_dm_criterion_test        --- final datamatrix for the test feedback blockloop
    """
    
    
    # Add distractors:
    dm_exp = addDistractors.addDistractors(dm_exp)
    dm_fillers = addDistractors.addDistractors(dm_fillers)
    
    # Make sure we will collect two dms
    list_dms = []
    
    for block in ["test_feedback", "criterion_test"]:
    
        # Shuffle the fillers:
        dm_fillers = ops.shuffle(dm_fillers)
        
        # Merge first 8 fillers to the main dm
        # NOTE: we leave out four fillers because we will use them for the
        # very first and the very last trials
        dm_fillers_slice = dm_fillers[0:8]
        main_dm = dm_exp << dm_fillers_slice
        
        # Shuffle the main dm:
        main_dm = ops.shuffle(main_dm)
        
        # Create an Enforce object, and add two constraints
        ef = Enforce(main_dm)
        ef.add_constraint(MaxRep, cols=[main_dm.Emotion], maxrep=3)
        ef.add_constraint(MinDist, cols=[main_dm.Trial_ID], mindist=2)
        
        # Enforce the constraints
        main_dm = ef.enforce()
        # See the resulting DataFrame and a report of how long the enforcement took.
        
        
        # Add two fillers to the beginning of the final dm:
        dm_fillers_slice_first = dm_fillers[8:10]
        final_dm = dm_fillers_slice_first << main_dm
        
        # And to the end fo the final dm:
        dm_fillers_slice_last = dm_fillers[10:]
        final_dm = final_dm << dm_fillers_slice_last
        
        # Append to the dm list:
        list_dms.append(final_dm)

    # Unpack the list so we can return two separate dms
    dm1, dm2 = list_dms

    return dm1, dm2
Beispiel #2
0
def check_shuffle(col_type):

    dm = DataMatrix(length=3, default_col_type=col_type)
    dm.col1 = 11, 12, 13
    dm.col2 = 1, 2, 3
    dm = operations.shuffle(dm)
    for row in dm:
        ok_(row.col1 == row.col2 + 10)
    dm.col1 = operations.shuffle(dm.col1)
    dm.col2 = operations.shuffle(dm.col2)
    check_integrity(dm)
def check_shuffle(col_type):

	dm = DataMatrix(length=3, default_col_type=col_type)
	dm.col1 = 11,12,13
	dm.col2 = 1,2,3
	dm = operations.shuffle(dm)
	for row in dm:
		ok_(row.col1 == row.col2+10)
	dm.col1 = operations.shuffle(dm.col1)
	dm.col2 = operations.shuffle(dm.col2)
	check_integrity(dm)
def check_mixedcolumn_sorting():

    dm = DataMatrix(length=24)
    dm.c = [
        1, '1', 2, '2', 1.1, '1.1', 2.1, '2.1', INF, -INF, 'inf', '-inf', NAN,
        NAN, 'nan', 'nan', None, None, None, None, 'alpha', 'beta', 'None', ''
    ]
    dm.c = ops.shuffle(dm.c)
    dm = ops.sort(dm, by=dm.c)
    check_col(dm.c, [
        -INF,
        -INF,
        1,
        1,
        1.1,
        1.1,
        2,
        2,
        2.1,
        2.1,
        INF,
        INF,
        '',
        'None',
        'alpha',
        'beta',
        None,
        None,
        None,
        None,
        NAN,
        NAN,
        NAN,
        NAN,
    ])
def applyConstraints(dm_exp, dm_fillers):
    """
    Arguments:
    dm_exp        --- dm containing exp scene-object combinations
    dm_fillers    --- dm containing filler scene-object combinations
    
    Returns:
    final_dm        --- final datamatrix for the IMDF MC memory task
    """

    # Add distractors:
    dm_exp = addDistractorsImdf.addDistractors(dm_exp)
    dm_fillers = addDistractorsImdf.addDistractors(dm_fillers)

    # Shuffle the fillers:
    dm_fillers = ops.shuffle(dm_fillers)

    # Merge first 4 fillers to the main dm
    # NOTE: we leave out four fillers because we will use them for the
    # very first and the very last trials

    # TODO: select 2 neg en 2 neutral
    dm_fillers_slice = dm_fillers[0:4]
    main_dm = dm_exp << dm_fillers_slice

    # Shuffle the main dm:
    main_dm = ops.shuffle(main_dm)

    # Create an Enforce object, and add two constraints
    ef = Enforce(main_dm)
    ef.add_constraint(MaxRep, cols=[main_dm.Emotion], maxrep=3)
    ef.add_constraint(MinDist, cols=[main_dm.Trial_ID], mindist=2)

    # Enforce the constraints
    main_dm = ef.enforce()
    # See the resulting DataFrame and a report of how long the enforcement took.

    # Add two fillers to the beginning of the final dm:
    dm_fillers_slice_first = dm_fillers[4:6]
    final_dm = dm_fillers_slice_first << main_dm

    # And to the end fo the final dm:
    dm_fillers_slice_last = dm_fillers[6:]
    final_dm = final_dm << dm_fillers_slice_last

    return final_dm
Beispiel #6
0
def check_intcolumn_sorting():

	dm = DataMatrix(length=8, default_col_type=IntColumn)
	dm.c = [
		1, '1', 2, '2',
		1.1, '1.1', 2.1, '2.8',
	]
	dm.c = ops.shuffle(dm.c)
	dm = ops.sort(dm, by=dm.c)
	check_col(dm.c, [
		1, 1, 1, 1, 2, 2, 2, 2
	])
def test_shuffle():

	dm = DataMatrix(length=2)
	dm.a = 'a', 'b'
	dm.b = 0, 1
	while True:
		dm.a = ops.shuffle(dm.a)
		check_col(dm.b, [0, 1])
		try:
			check_col(dm.a, ['b', 'a'])
			break
		except:
			pass
	dm = DataMatrix(length=2)
	dm.a = 'a', 'b'
	dm.b = 0, 1
	while True:
		dm = ops.shuffle(dm)
		try:
			check_col(dm.a, ['b', 'a'])
			check_col(dm.b, [1, 0])
			break
		except:
			pass
def test_shuffle():

    dm = DataMatrix(length=2)
    dm.a = 'a', 'b'
    dm.b = 0, 1
    while True:
        dm.a = ops.shuffle(dm.a)
        check_col(dm.b, [0, 1])
        try:
            check_col(dm.a, ['b', 'a'])
            break
        except:
            pass
    dm = DataMatrix(length=2)
    dm.a = 'a', 'b'
    dm.b = 0, 1
    while True:
        dm = ops.shuffle(dm)
        try:
            check_col(dm.a, ['b', 'a'])
            check_col(dm.b, [1, 0])
            break
        except:
            pass
def test_bin_split():

	dm = DataMatrix(length=4)
	dm.a = range(4)
	dm = ops.shuffle(dm)
	dm1, dm2 = ops.bin_split(dm.a, 2)
	check_col(dm1.a, [0,1])
	check_col(dm2.a, [2,3])
	dm1, dm2, dm3 = ops.bin_split(dm.a, 3)
	check_col(dm1.a, [0])
	check_col(dm2.a, [1])
	check_col(dm3.a, [2,3])
	dm1, = ops.bin_split(dm.a, 1)
	check_col(dm1.a, [0,1,2,3])
	@raises(ValueError)
	def _():
		x, = ops.bin_split(dm.a, 5)
	_()
Beispiel #10
0
def addDistractors(dm):
    """
    Adds distractors to a given datamatrix, making sure that both
    distractors are different from the target and from each other

    Arguments:
    dm        --- a DataMatrix() instance without distractors

    Returns:
    new_dm        --- a DataMatrix instance with distractors
    """

    # Shuffle the dm:
    dm = ops.shuffle(dm)

    # Split the original dm by emotion:
    neg_dm = dm.Emotion == "neg"
    neu_dm = dm.Emotion == "neu"

    # Make a list of potential scenes for negative distractor 1
    L_NEG_DIST1 = list(neg_dm.Scene)
    # and negative distractor 2
    L_NEG_DIST2 = list(neg_dm.Scene)

    # Make a list of potential scenes for neutral distractor 1
    L_NEU_DIST1 = list(neu_dm.Scene)
    # and 2
    L_NEU_DIST2 = list(neu_dm.Scene)

    new_dm = combine(dm, L_NEG_DIST1[:], L_NEG_DIST2[:], L_NEU_DIST1[:],
                     L_NEU_DIST2[:])

    # Make sure target, distractor 1 and distractor 2 are different scenes:
    while any(row.distractor_scene_1 == row.distractor_scene_2
              or row.distractor_scene_1 == row.Scene
              or row.distractor_scene_2 == row.Scene for row in new_dm):
        # If not, try again:
        print("try again")
        new_dm = combine(dm, L_NEG_DIST1[:], L_NEG_DIST2[:], L_NEU_DIST1[:],
                         L_NEU_DIST2[:])

    return new_dm
def test_bin_split():

    dm = DataMatrix(length=4)
    dm.a = range(4)
    dm = ops.shuffle(dm)
    dm1, dm2 = ops.bin_split(dm.a, 2)
    check_col(dm1.a, [0, 1])
    check_col(dm2.a, [2, 3])
    dm1, dm2, dm3 = ops.bin_split(dm.a, 3)
    check_col(dm1.a, [0])
    check_col(dm2.a, [1])
    check_col(dm3.a, [2, 3])
    dm1, = ops.bin_split(dm.a, 1)
    check_col(dm1.a, [0, 1, 2, 3])

    def _():
        with pytest.raises(ValueError):
            x, = ops.bin_split(dm.a, 5)

    _()
Beispiel #12
0
    def enforce(self, maxreshuffle=100, maxpass=100):
        """
		desc:
			Enforces constraints.

		keywords:
			maxpass:
				desc:	The maximum number of times that the enforce algorithm
						may be restarted.
				type:	int

		returns:
			desc:	A `DataMatrix` that respects the constraints.
			type:	DataMatrix
		"""

        t0 = time.time()
        reverse = False
        for i in range(maxreshuffle):
            self.dm = operations.shuffle(self.dm)
            for j in range(maxpass):
                if not self._enforce(reverse=reverse):
                    break
                reverse = not reverse
            else:
                # If the maximum passes were exhausted, restart the loop
                continue
            # If the maximum passes were not exhausted, we are done
            break
        else:
            raise EnforceFailed(
             u'Failed to enforce constraints (maxreshuffle = %d)' \
             % maxreshuffle)
        t1 = time.time()
        self.report = {
            u'time': t1 - t0,
            u'reshuffle': i + 1,
        }
        return self.dm
Beispiel #13
0
	def run(self):

		"""See item."""

		self.set_item_onset()
		if self.live_dm is None or self.var.continuous == u'no':
			self.live_dm = self._create_live_datamatrix()
			self.live_row = 0
		first = True
		while self.live_row < len(self.live_dm):
			self.experiment.var.repeat_cycle = 0
			self.experiment.var.live_row = self.live_row
			self.experiment.var.set('live_row_%s' % self.name, self.live_row)
			for name, val in self.live_dm[self.live_row]:
				if isinstance(val, basestring) and val.startswith(u'='):
					val = self.python_workspace._eval(val[1:])
				self.experiment.var.set(name, val)
			# Evaluate the run if statement
			if self._break_if is not None and \
				(not first or self.var.break_if_on_first == u'yes'):
				self.python_workspace[u'self'] = self
				if self.python_workspace._eval(self._break_if):
					break
			# Run the item!
			self.experiment.items.execute(self._item)
			# If the repeat_cycle flag was set, run the item again later
			if self.experiment.var.repeat_cycle:
				self.live_dm <<= self.live_dm[self.live_row:self.live_row+1]
				if self.var.order == u'random':
					self.live_dm = self.live_dm[:self.live_row+1] \
						<< operations.shuffle(self.live_dm[self.live_row+1:])
			self.live_row += 1
			first = False
		else:
			# If the loop finished without breaking, it needs to be reset on
			# the next run of the loop item
			self.live_row = None
			self.live_dm = None
Beispiel #14
0
def check_floatcolumn_sorting():

    dm = DataMatrix(length=24, default_col_type=FloatColumn)
    with pytest.warns(UserWarning):
        dm.c = [
            1, '1', 2, '2', 1.1, '1.1', 2.1, '2.1', INF, -INF, 'inf', '-inf',
            NAN, NAN, 'nan', 'nan', None, None, None, None, 'alpha', 'beta',
            'None', ''
        ]
    dm.c = ops.shuffle(dm.c)
    dm = ops.sort(dm, by=dm.c)
    check_col(dm.c, [
        -INF,
        -INF,
        1,
        1,
        1.1,
        1.1,
        2,
        2,
        2.1,
        2.1,
        INF,
        INF,
        NAN,
        NAN,
        NAN,
        NAN,
        NAN,
        NAN,
        NAN,
        NAN,
        NAN,
        NAN,
        NAN,
        NAN,
    ])
Beispiel #15
0
    def run(self):
        """See item."""

        self.set_item_onset()
        if self.live_dm is None or self.var.continuous == u'no':
            self.live_dm = self._create_live_datamatrix()
            self.live_row = 0
        first = True
        while self.live_row < len(self.live_dm):
            self.experiment.var.repeat_cycle = 0
            self.experiment.var.live_row = self.live_row
            self.experiment.var.set('live_row_%s' % self.name, self.live_row)
            for name, val in self.live_dm[self.live_row]:
                if isinstance(val, basestring) and val.startswith(u'='):
                    val = self.python_workspace._eval(val[1:])
                self.experiment.var.set(name, val)
            # Evaluate the run if statement
            if self._break_if is not None and \
             (not first or self.var.break_if_on_first == u'yes'):
                self.python_workspace[u'self'] = self
                if self.python_workspace._eval(self._break_if):
                    break
            # Run the item!
            self.experiment.items.execute(self._item)
            # If the repeat_cycle flag was set, run the item again later
            if self.experiment.var.repeat_cycle:
                self.live_dm <<= self.live_dm[self.live_row:self.live_row + 1]
                if self.var.order == u'random':
                    self.live_dm = self.live_dm[:self.live_row+1] \
                     << operations.shuffle(self.live_dm[self.live_row+1:])
            self.live_row += 1
            first = False
        else:
            # If the loop finished without breaking, it needs to be reset on
            # the next run of the loop item
            self.live_row = None
            self.live_dm = None
Beispiel #16
0
def splitFillers(dm):
    """
    Splits filler trials into:
    - 2 first fillers, one negative, one neutral
    - 2 last fillers, one negative, one neutral
    - remaining fillers, that should be mixed with the experimental trials
    
    Arguments:
    dm        --- DataMatrix containing filler objects
    
    Returns:
    dm_first    --- dm containing only 2 rows, corresponding to the first 2 fillers
    dm_last     --- dm containing only 2 rows, corresponding to the last 2 fillers
    dm_remaining    --- dm containing the remainder (if any) of the fillers
    
    NOTE the order
    """

    # Below is an awful piece of script to make sure the first and last two fillers
    # consist of one neg and one neu trial.
    # I just don't see a way to do this more elegantly

    # Shuffle the fillers:
    dm = ops.shuffle(dm)

    # Split the fillers on the basis of valence:
    (cat1, filler_dm_negative), (cat2,
                                 filler_dm_neutral) = ops.split(dm["Emotion"])

    # Select 2 fillers, one from each valence category, as first 2 fillers:
    identifier_filler1_neg = filler_dm_negative["Object"][0]
    identifier_filler1_neu = filler_dm_neutral["Object"][0]

    dm_filler1_neg = filler_dm_negative["Object"] == identifier_filler1_neg
    dm_filler1_neu = filler_dm_neutral["Object"] == identifier_filler1_neu

    # Merge the two first trial_dms
    dm_first = dm_filler1_neg << dm_filler1_neu
    # Shuffle
    dm_first = ops.shuffle(dm_first)
    # Add a column indicating the type of filler (for later debugging/cross
    # checking)
    dm_first["filler_type"] = "first"

    # Remove the already selected pairs from the dms
    # (i.e., select WITHOUT replacement):
    filler_dm_negative = filler_dm_negative[1:]
    filler_dm_neutral = filler_dm_neutral[1:]

    # Do the same thing for the last 2 fillers:
    # Select 2 fillers, one from each valence category, as first 2 fillers:
    identifier_filler2_neg = filler_dm_negative["Object"][0]
    identifier_filler2_neu = filler_dm_neutral["Object"][0]

    dm_filler2_neg = filler_dm_negative["Object"] == identifier_filler2_neg
    dm_filler2_neu = filler_dm_neutral["Object"] == identifier_filler2_neu
    # Merge:
    dm_last = dm_filler2_neg << dm_filler2_neu
    # And shuffle:
    dm_last = ops.shuffle(dm_last)
    # Add column with filler type
    dm_last["filler_type"] = "last"

    # Remove from the dms:
    filler_dm_negative = filler_dm_negative[1:]
    filler_dm_neutral = filler_dm_neutral[1:]

    # Merge the remaining filler dms:
    dm_remaining = filler_dm_negative << filler_dm_neutral
    # Shuffle:
    dm_remaining = ops.shuffle(dm_remaining)
    # Add column with filler type
    dm_remaining["filler_type"] = "middle"

    return dm_first, dm_last, dm_remaining
Beispiel #17
0
	def _create_live_datamatrix(self):

		"""
		desc:
			Builds a live DataMatrix. That is, it takes the orignal DataMatrix
			and applies all the operations as specified.

		returns:
			desc:	A live DataMatrix.
			type:	DataMatrix
		"""

		if self.var.source == u'table':
			src_dm = self.dm
		else:
			from datamatrix import io
			src = self.experiment.pool[self.var.source_file]
			if src.endswith(u'.xlsx'):
				try:
					src_dm = io.readxlsx(src)
				except Exception as e:
					raise osexception(u'Failed to read .xlsx file: %s' % src,
						exception=e)
			else:
				try:
					src_dm = io.readtxt(src)
				except Exception as e:
					raise osexception(u'Failed to read text file (perhaps it has the wrong format or it is not utf-8 encoded): %s' % src,
						exception=e)
		for column_name in src_dm.column_names:
			if not self.syntax.valid_var_name(column_name):
				raise osexception(
					u'The loop table contains an invalid column name: 'u'\'%s\'' \
					% column_name)
		# The number of repeats should be numeric. If not, then give an error.
		# This can also occur when generating a preview of a loop table if
		# repeat is variable.
		if not isinstance(self.var.repeat, (int, float)):
			raise osexception(
				u'Don\'t know how to generate a DataMatrix for "%s" repeats' \
				% self.var.repeat)
		length = int(len(src_dm) * self.var.repeat)
		dm = DataMatrix(length=0)
		while len(dm) < length:
			i = min(length-len(dm), len(src_dm))
			if self.var.order == u'random':
				dm <<= operations.shuffle(src_dm)[:i]
			else:
				dm <<= src_dm[:i]
		if self.var.order == u'random':
			dm = operations.shuffle(dm)
		if self.ef is not None:
			self.ef.dm = dm
			dm = self.ef.enforce()
		for cmd, arglist in self.operations:
			# The column name is always specified last, or not at all
			if arglist:
				try:
					colname = arglist[-1]
					col = dm[colname]
				except:
					raise osexception(
						u'Column %s does not exist' % arglist[-1])
			if cmd == u'fullfactorial':
				dm = operations.fullfactorial(dm)
			elif cmd == u'shuffle':
				if not arglist:
					dm = operations.shuffle(dm)
				else:
					dm[colname] = operations.shuffle(col)
			elif cmd == u'shuffle_horiz':
				if not arglist:
					dm = operations.shuffle_horiz(dm)
				else:
					dm = operations.shuffle_horiz(
						*[dm[_colname] for _colname in arglist])
			elif cmd == u'slice':
				self._require_arglist(cmd, arglist, minlen=2)
				dm = dm[arglist[0]: arglist[1]]
			elif cmd == u'sort':
				self._require_arglist(cmd, arglist)
				dm[colname] = operations.sort(col)
			elif cmd == u'sortby':
				self._require_arglist(cmd, arglist)
				dm = operations.sort(dm, by=col)
			elif cmd == u'reverse':
				if not arglist:
					dm = dm[::-1]
				else:
					dm[colname] = col[::-1]
			elif cmd == u'roll':
				self._require_arglist(cmd, arglist)
				steps = arglist[0]
				if not isinstance(steps, int):
					raise osexception(u'roll steps should be numeric')
				if len(arglist) == 1:
					dm = dm[-steps:] << dm[:-steps]
				else:
					dm[colname] = list(col[-steps:]) + list(col[:-steps])
			elif cmd == u'weight':
				self._require_arglist(cmd, arglist)
				dm = operations.weight(col)
		return dm
Beispiel #18
0
    def _create_live_datamatrix(self):
        """
		desc:
			Builds a live DataMatrix. That is, it takes the orignal DataMatrix
			and applies all the operations as specified.

		returns:
			desc:	A live DataMatrix.
			type:	DataMatrix
		"""

        if self.var.source == u'table':
            src_dm = self.dm
        else:
            from datamatrix import io
            src = self.experiment.pool[self.var.source_file]
            if src.endswith(u'.xlsx'):
                try:
                    src_dm = io.readxlsx(src)
                except Exception as e:
                    raise osexception(u'Failed to read .xlsx file: %s' % src,
                                      exception=e)
            else:
                try:
                    src_dm = io.readtxt(src)
                except Exception as e:
                    raise osexception(u'Failed to read text file: %s' % src,
                                      exception=e)
        length = int(len(src_dm) * self.var.repeat)
        dm = DataMatrix(length=0)
        while len(dm) < length:
            i = min(length - len(dm), len(src_dm))
            if self.var.order == u'random':
                dm <<= operations.shuffle(src_dm)[:i]
            else:
                dm <<= src_dm[:i]
        if self.var.order == u'random':
            dm = operations.shuffle(dm)
        if self.ef is not None:
            self.ef.dm = dm
            dm = self.ef.enforce()
        for cmd, arglist in self.operations:
            # The column name is always specified last, or not at all
            if arglist:
                try:
                    colname = arglist[-1]
                    col = dm[colname]
                except:
                    raise osexception(u'Column %s does not exist' %
                                      arglist[-1])
            if cmd == u'fullfactorial':
                dm = operations.fullfactorial(dm)
            elif cmd == u'shuffle':
                if not arglist:
                    dm = operations.shuffle(dm)
                else:
                    dm[colname] = operations.shuffle(col)
            elif cmd == u'shuffle_horiz':
                if not arglist:
                    dm = operations.shuffle_horiz(dm)
                else:
                    dm = operations.shuffle_horiz(
                        *[dm[_colname] for _colname in arglist])
            elif cmd == u'slice':
                self._require_arglist(cmd, arglist, minlen=2)
                dm = dm[arglist[0]:arglist[1]]
            elif cmd == u'sort':
                self._require_arglist(cmd, arglist)
                dm[colname] = operations.sort(col)
            elif cmd == u'sortby':
                self._require_arglist(cmd, arglist)
                dm = operations.sort(dm, by=col)
            elif cmd == u'reverse':
                if not arglist:
                    dm = dm[::-1]
                else:
                    dm[colname] = col[::-1]
            elif cmd == u'roll':
                self._require_arglist(cmd, arglist)
                steps = arglist[0]
                if not isinstance(steps, int):
                    raise osexception(u'roll steps should be numeric')
                if len(arglist) == 1:
                    dm = dm[-steps:] << dm[:-steps]
                else:
                    dm[colname] = list(col[-steps:]) + list(col[:-steps])
            elif cmd == u'weight':
                self._require_arglist(cmd, arglist)
                dm = operations.weight(col)
        return dm
Beispiel #19
0
	def _create_live_datamatrix(self):

		"""
		desc:
			Builds a live DataMatrix. That is, it takes the orignal DataMatrix
			and applies all the operations as specified.

		returns:
			desc:	A live DataMatrix.
			type:	DataMatrix
		"""

		if self.var.source == u'table':
			src_dm = self.dm
		else:
			from datamatrix import io
			src = self.experiment.pool[self.var.source_file]
			if src.endswith(u'.xlsx'):
				try:
					src_dm = io.readxlsx(src)
				except Exception as e:
					raise osexception(u'Failed to read .xlsx file: %s' % src,
						exception=e)
			else:
				try:
					src_dm = io.readtxt(src)
				except Exception as e:
					raise osexception(u'Failed to read text file: %s' % src,
						exception=e)
		length = int(len(src_dm) * self.var.repeat)
		dm = DataMatrix(length=0)
		while len(dm) < length:
			i = min(length-len(dm), len(src_dm))
			if self.var.order == u'random':
				dm <<= operations.shuffle(src_dm)[:i]
			else:
				dm <<= src_dm[:i]
		if self.var.order == u'random':
			dm = operations.shuffle(dm)
		if self.ef is not None:
			self.ef.dm = dm
			dm = self.ef.enforce()
		for cmd, arglist in self.operations:
			# The column name is always specified last, or not at all
			if arglist:
				try:
					colname = arglist[-1]
					col = dm[colname]
				except:
					raise osexception(
						u'Column %s does not exist' % arglist[-1])
			if cmd == u'fullfactorial':
				dm = operations.fullfactorial(dm)
			elif cmd == u'shuffle':
				if not arglist:
					dm = operations.shuffle(dm)
				else:
					dm[colname] = operations.shuffle(col)
			elif cmd == u'shuffle_horiz':
				if not arglist:
					dm = operations.shuffle_horiz(dm)
				else:
					dm = operations.shuffle_horiz(
						*[dm[_colname] for _colname in arglist])
			elif cmd == u'slice':
				self._require_arglist(cmd, arglist, minlen=2)
				dm = dm[arglist[0]: arglist[1]]
			elif cmd == u'sort':
				self._require_arglist(cmd, arglist)
				dm[colname] = operations.sort(col)
			elif cmd == u'sortby':
				self._require_arglist(cmd, arglist)
				dm = operations.sort(dm, by=col)
			elif cmd == u'reverse':
				if not arglist:
					dm = dm[::-1]
				else:
					dm[colname] = col[::-1]
			elif cmd == u'roll':
				self._require_arglist(cmd, arglist)
				steps = arglist[0]
				if not isinstance(steps, int):
					raise osexception(u'roll steps should be numeric')
				if len(arglist) == 1:
					dm = dm[-steps:] << dm[:-steps]
				else:
					dm[colname] = list(col[-steps:]) + list(col[:-steps])
			elif cmd == u'weight':
				self._require_arglist(cmd, arglist)
				dm = operations.weight(col)
		return dm
Beispiel #20
0
    def _create_live_datamatrix(self):
        """
		desc:
			Builds a live DataMatrix. That is, it takes the orignal DataMatrix
			and applies all the operations as specified.

		returns:
			desc:	A live DataMatrix.
			type:	DataMatrix
		"""

        if self.var.source == u'table':
            src_dm = self.dm
        else:
            from datamatrix import io
            src = self.experiment.pool[self.var.source_file]
            if src.endswith(u'.xlsx'):
                try:
                    src_dm = io.readxlsx(src)
                except Exception as e:
                    raise osexception(u'Failed to read .xlsx file: %s' % src,
                                      exception=e)
            else:
                try:
                    src_dm = io.readtxt(src)
                except Exception as e:
                    raise osexception(
                        u'Failed to read text file (perhaps it has the wrong format or it is not utf-8 encoded): %s'
                        % src,
                        exception=e)
        for column_name in src_dm.column_names:
            if not self.syntax.valid_var_name(column_name):
                raise osexception(
                 u'The loop table contains an invalid column name: 'u'\'%s\'' \
                 % column_name)
        # The number of repeats should be numeric. If not, then give an error.
        # This can also occur when generating a preview of a loop table if
        # repeat is variable.
        if not isinstance(self.var.repeat, (int, float)):
            raise osexception(
             u'Don\'t know how to generate a DataMatrix for "%s" repeats' \
             % self.var.repeat)
        length = int(len(src_dm) * self.var.repeat)
        dm = DataMatrix(length=0)
        while len(dm) < length:
            i = min(length - len(dm), len(src_dm))
            if self.var.order == u'random':
                dm <<= operations.shuffle(src_dm)[:i]
            else:
                dm <<= src_dm[:i]
        if self.var.order == u'random':
            dm = operations.shuffle(dm)
        if self.ef is not None:
            self.ef.dm = dm
            dm = self.ef.enforce()
        for cmd, arglist in self.operations:
            # The column name is always specified last, or not at all
            if arglist:
                try:
                    colname = arglist[-1]
                    col = dm[colname]
                except:
                    raise osexception(u'Column %s does not exist' %
                                      arglist[-1])
            if cmd == u'fullfactorial':
                dm = operations.fullfactorial(dm)
            elif cmd == u'shuffle':
                if not arglist:
                    dm = operations.shuffle(dm)
                else:
                    dm[colname] = operations.shuffle(col)
            elif cmd == u'shuffle_horiz':
                if not arglist:
                    dm = operations.shuffle_horiz(dm)
                else:
                    dm = operations.shuffle_horiz(
                        *[dm[_colname] for _colname in arglist])
            elif cmd == u'slice':
                self._require_arglist(cmd, arglist, minlen=2)
                dm = dm[arglist[0]:arglist[1]]
            elif cmd == u'sort':
                self._require_arglist(cmd, arglist)
                dm[colname] = operations.sort(col)
            elif cmd == u'sortby':
                self._require_arglist(cmd, arglist)
                dm = operations.sort(dm, by=col)
            elif cmd == u'reverse':
                if not arglist:
                    dm = dm[::-1]
                else:
                    dm[colname] = col[::-1]
            elif cmd == u'roll':
                self._require_arglist(cmd, arglist)
                steps = arglist[0]
                if not isinstance(steps, int):
                    raise osexception(u'roll steps should be numeric')
                if len(arglist) == 1:
                    dm = dm[-steps:] << dm[:-steps]
                else:
                    dm[colname] = list(col[-steps:]) + list(col[:-steps])
            elif cmd == u'weight':
                self._require_arglist(cmd, arglist)
                dm = operations.weight(col)
        return dm
Beispiel #21
0
    exp_phase = block.split("_")[-1]
    dst = "trial list %s/block loops TNT %s" % (exp_phase, exp_phase)

    for pp_ID in range(1, 71):

        main_dm = io.readtxt(src_exp)

        # Read in fillers:
        dm = io.readtxt(src_fillers)
        dm_first, dm_last, dm_remaining = helpers.splitFillers(dm)

        # Merge the remaining fillers with the main dm:
        merged_dm = main_dm << dm_remaining

        # Shuffle the merged dm:
        merged_dm = ops.shuffle(merged_dm)

        # Create an Enforce object, and add constraint
        ef = Enforce(merged_dm)
        ef.add_constraint(MaxRep, cols=[merged_dm.Emotion], maxrep=3)
        ef.add_constraint(MinDist, cols=[merged_dm.Trial_ID], mindist=2)

        # Enforce the constraints
        merged_dm = ef.enforce()

        # Add the first fillers:
        merged_dm = dm_first << merged_dm
        # Add the last fillers:
        merged_dm = merged_dm << dm_last

        # Add exp ID to the dm:
Beispiel #22
0
    def _create_live_datamatrix(self):
        """
		desc:
			Builds a live DataMatrix. That is, it takes the orignal DataMatrix
			and applies all the operations as specified.

		returns:
			desc:	A live DataMatrix.
			type:	DataMatrix
		"""

        src_dm = self.dm if self.var.source == u'table' else self._read_file()
        for column_name in src_dm.column_names:
            if not self.syntax.valid_var_name(column_name):
                raise osexception(
                    u'The loop table contains an invalid column name: '
                    u'\'%s\'' % column_name)
        # The number of repeats should be numeric. If not, then give an error.
        # This can also occur when generating a preview of a loop table if
        # repeat is variable.
        if not isinstance(self.var.repeat, (int, float)):
            raise osexception(
                u'Don\'t know how to generate a DataMatrix for "%s" repeats' %
                self.var.repeat)
        length = int(len(src_dm) * self.var.repeat)
        dm = DataMatrix(length=0)
        while len(dm) < length:
            i = min(length - len(dm), len(src_dm))
            if self.var.order == u'random':
                dm <<= operations.shuffle(src_dm)[:i]
            else:
                dm <<= src_dm[:i]
        if self.var.order == u'random':
            dm = operations.shuffle(dm)
        # Constraints come before loop operations
        if self._constraints:
            self.ef = Enforce(dm)
            for constraint_cls, colname, kwargs in self._constraints:
                self.ef.add_constraint(constraint_cls,
                                       cols=dm[colname],
                                       **kwargs)
            dm = self.ef.enforce()
        # Operations come last
        for cmd, arglist in self._operations:
            # The column name is always specified last, or not at all
            if arglist:
                try:
                    colname = arglist[-1]
                    col = dm[colname]
                except:
                    raise osexception(u'Column %s does not exist' %
                                      arglist[-1])
            if cmd == u'fullfactorial':
                dm = operations.fullfactorial(dm)
            elif cmd == u'shuffle':
                if not arglist:
                    dm = operations.shuffle(dm)
                else:
                    dm[colname] = operations.shuffle(col)
            elif cmd == u'shuffle_horiz':
                if not arglist:
                    dm = operations.shuffle_horiz(dm)
                else:
                    # There can be multiple column names, so we need to check
                    # if all of them exist, rather than only the last one as
                    # we did above.
                    for _colname in arglist:
                        try:
                            dm[_colname]
                        except:
                            raise osexception(u'Column %s does not exist' %
                                              _colname)
                    dm = operations.shuffle_horiz(
                        *[dm[_colname] for _colname in arglist])
            elif cmd == u'slice':
                self._require_arglist(cmd, arglist, minlen=2)
                dm = dm[arglist[0]:arglist[1]]
            elif cmd == u'sort':
                self._require_arglist(cmd, arglist)
                dm[colname] = operations.sort(col)
            elif cmd == u'sortby':
                self._require_arglist(cmd, arglist)
                dm = operations.sort(dm, by=col)
            elif cmd == u'reverse':
                if not arglist:
                    dm = dm[::-1]
                else:
                    dm[colname] = col[::-1]
            elif cmd == u'roll':
                self._require_arglist(cmd, arglist)
                steps = arglist[0]
                if not isinstance(steps, int):
                    raise osexception(u'roll steps should be numeric')
                if len(arglist) == 1:
                    dm = dm[-steps:] << dm[:-steps]
                else:
                    dm[colname] = list(col[-steps:]) + list(col[:-steps])
            elif cmd == u'weight':
                self._require_arglist(cmd, arglist)
                try:
                    dm = operations.weight(col)
                except TypeError:
                    raise osexception(
                        u'weight values should be non-negative numeric values')
        return dm