Beispiel #1
0
def getDM(exp, driftCorr = True, excludeErrors = True, saccTooFast = None, saccTooSlow = None,\
		rtTooFast = None, rtTooSlow = None, rtVar = 'rtFromStim', \
		exclFailedChecks = True, \
		fixCheck1TooLong = 1000, fixCheck2TooLong = 1000, cutoffHeavy = 0, \
		onlyControl = True, excludeFillers = True):
	
	"""
	Applies several exclusion criteria to obtain a filtered dm.
	
	Arguments:
	dm					--- data matrix
	exp 				--- {"004A", "004B"}, string indicating whether first or second
							experiment is analysed
	
	Keyword arguments:
	excludeErrors		--- Boolean indicating whether error trials should be
							excluded. Default = False.
	saccTooFast			--- Cutoff for exclusion of too-fast saccades. Set to None
							to deactivate this filter. Default = 80.
	saccTooSlow 			--- Cutoff for exclusion of too-slow saccades. Set to None
							to deactivate this filter.
	rtTooFast			--- Cutoff for exclusion of too-fast RTs. Set to None to
							deactivate this filter.
	rtTooSlow			--- Cutoff for exclusion of too-slow RTs. Set to None to 
							deactivate this filter.
	rtVar				--- rt variable to use for excluding too fast and/or
							too slow response times.
	exclFailedChecks	--- Boolean indicating whether or not to excude trials on
							which one or more fix checks failed. Default = False
	fixCheckTooLong1	--- Cutoff for excluding too long fixation checks. Set
							to None to deactivate this filter. Default = 700, 
							based on looking at plt.hist(dm['durCheck1'])
	fixCheckTooLong2	--- Cutoff for excluding too long fixation check on 
							object. Set to None to deactivate. Default = 450,
							based on looking at plt.hist(dm['durCheck2'])
	drifCorr			--- 
	cutoffHeavy			--- minimum deviation necessary to indicate one side of the object
							as heavier. In px. Default = 8.
	onlyControl			--- indicates whether only trials in which manipulation was not 
							manipulated, should be included. Default = True.
	excludeFillers		--- Default = True.
	"""


	if driftCorr:
		fName = "selected_dm_%s_WITH_drift_corr.csv" % exp
	else:
		fName = "selected_dm_%s_NO_drift_corr.csv" % exp
	
	if exp == "004C":

		
		data = "./dm_004C_simulation.csv"
		
		a = np.genfromtxt(data, dtype=None, delimiter=",")
		dm = DataMatrix(a)
		
		# Add some important column headers:
		dm = dm.addField("file", dtype = str)
		dm = dm.addField("accuracy")
		dm = dm.addField("contrast_side", dtype = str)

		dm["file"] = "simulation"
		dm["accuracy"] = 1

		dm["contrast_side"] = "test"
		dm["contrast_side"][np.where(dm["mask_side"] == "right")] = "_left"
		dm["contrast_side"][np.where(dm["mask_side"] == "control")] = "control"
		dm["contrast_side"][np.where(dm["mask_side"] == "left")] = "right"
		
		
		
	else:

		dm = ascParser.parseAsc(exp = exp, driftCorr = driftCorr)
	
	# Start by applying some general selections (such that 
	# the reported exclusion percentages will not differ depending
	# on when you execute those):

	# Exclude practice trials:
	dm = dm.select("rep != 'practice'")
	
	# For the second experiment, exclude Dash and Sebastiaan:
	if exp == "004B":
	
		# Exclude Sebastiaan:
		dm = dm.select('file != "00401.asc"')
		# Exclude Dash because he's left handed:
		dm = dm.select('file != "00402.asc"')
	
	if onlyControl:
		dm = dm.select("mask_side == 'control'")
	
	if excludeFillers:
		dm = dm.select("symm == 'asymm'")

	if excludeErrors:
		dm = dm.select('accuracy == 1')
		
	# 'Real' selections:
	
	# During parsing, tirals on which the variable 'response' did not contain
	# an int were given the value -1. Otherwise the dm will make all the 
	# 'response' values strings. Therefore, start by excluding those eventual
	# -1's:
	dm = dm.select("response != -1")


	# Remove all trials on which saccLat1 doesn't have a value:
	dm = dm.select("saccLat1 != ''")

	# Negative initial saccade latencies should not happen:
	dm = dm.select('saccLat1 > 0.')

	# Add column header indicating whether drift correction was used:
	dm = dm.addField("driftCorr", dtype = str)
	dm["driftCorr"] = driftCorr
	
	# Add a column header indicating which experiment is analysed:
	dm = dm.addField("exp", dtype = str)
	dm["exp"] = exp
		
	# Add variable indicating whether CoG is to the left or to the
	# right:
	# For objects with handle right, and without mask applied: 
	# - negative xCoG means: heavier on the left
	# - pos means: heavier on the right
	dm = dm.addField('heavySide', dtype = str)
	dm["heavySide"] = 'control'
	dm["heavySide"][np.where(dm["xCoG"] >= cutoffHeavy)] = 'right__'
	dm["heavySide"][np.where(dm["xCoG"] <= -cutoffHeavy)] = 'left__'


	# Some stuff we can't do for the simulation, because those columns don't 
	# exist:
	if exp != "004C":
		# Add variable indicating experimental half (first or second):
		dm = dm.addField("half", dtype = str)
		dm["half"] = "first"
		dm["half"][np.where(dm["block_count"] >= 3)] = "second"
		
	if saccTooFast != None:
		dm = dm.select('saccLat1 > %s'%saccTooFast)
	
	if saccTooSlow != None:
		dm = dm.select('saccLat1 < %s'%saccTooSlow)

	if rtTooFast != None:
		dm = dm.select('%s > %s'%(rtVar,rtTooFast))
	
	if rtTooSlow != None:
		dm = dm.select('%s < %s'%(rtVar,rtTooSlow))
	
	# Filter on screen coordinates:
	# Y:
	if exp != "004C":
		dm = dm.select("endYRaw1 < %s" % constants.screenH)
		dm = dm.select("endYRaw1 > 0")
		# X:
		dm = dm.select("endXRaw1 < %s" % constants.screenW)
		dm = dm.select("endXRaw1 > 0")
		
		# Re-code initial y coordinates such that we can use one cutoff
		# for both upwards and downwards saccade to see whether they were in
		# the right direction (i.e. > center coordinate):
		dm = dm.addField("sacc_dir")
		dm["sacc_dir"] = dm["endYRaw1"]
		dm["sacc_dir"][dm.where("visual_field == 'upper'")] = \
			dm["endYRaw1"][dm.where("visual_field == 'upper'")]+\
			constants.yCen
			
		# Select saccades that were in the right vertical direction:
		dm.select("sacc_dir > %s" % str(constants.yCen))
	
	# Exclude trials on which a fixation check failed or took too long:
	if exp == "004A":
		
		if exclFailedChecks:
			# Note why those will probably never lead to exclusions anymore: 
			# in those cases durCheck1 or durCheck2 would have the value -1000 (because they 
			# couldnt be calculated) and therefore are already excluded above.
			dm = dm.select('checkFixDotFailed == "False"')
			dm = dm.select('checkObjectFailed == "False"')

		if fixCheck1TooLong != None:
			dm = dm.select('durCheck1 < %s' % fixCheck1TooLong)
		if fixCheck2TooLong != None:
			dm = dm.select('durCheck2 < %s' % fixCheck2TooLong)

	if exp != "004C":
		# Negative new RT's should not happen:
		dm = dm.select('rtFromStim > 0')

	dm.save(fName)
	
	return dm
Beispiel #2
0
def getDM(driftCorr, excludeErrors = False, saccTooFast = 80, saccTooSlow = None,\
		rtTooFast = None, rtTooSlow = None, rtVar = 'rtFromStim'):
	
	"""
	Applies several exclusion criteria to obtain a filtered dm.
	
	Arguments:
	dm		--- data matrix
	
	Keyword arguments:
	excludeErrors		--- Boolean indicating whether error trials should be
							excluded. Default = False.
	saccTooFast			--- Cutoff for exclusion of too-fast saccades. Set to None
							to deactivate this filter. Default = 80.
	saccTooSlow 			--- Cutoff for exclusion of too-slow saccades. Set to None
							to deactivate this filter.
	rtTooFast			--- Cutoff for exclusion of too-fast RTs. Set to None to
							deactivate this filter.
	rtTooSlow			--- Cutoff for exclusion of too-slow RTs. Set to None to 
							deactivate this filter.
	rtVar				--- rt variable to use for excluding too fast and/or
							too slow response times.
	drifCorr			--- 
	"""

	# Declare constants:
	#src = '/home/lotje/python-libs/studies/_004'

	if driftCorr:
		fName = "selected_dm_WITH_drift_corr.csv"
	else:
		fName = "selected_dm_NO_drift_corr.csv"
	
	if '--shortcut' in sys.argv:
		
		
		a = np.genfromtxt(fName, dtype=None, delimiter=",")
		dm = DataMatrix(a)
		
		#dm = CsvReader(fName, delimiter=',').dataMatrix()

		return dm
		
	dm = ascParser004B.parseAsc(driftCorr = driftCorr)
	
	# Exclude Sebastiaan:
	dm = dm.select('file != "00401.asc"')
	
	# Exclude Dash because he's left handed:
	dm = dm.select('file != "00402.asc"')
	
	
	# Add column header indicating whether drift correction was used:
	dm = dm.addField("driftCorr", dtype = str)
	dm["driftCorr"] = driftCorr
	
	# Make a new variable (instead of 'mask_side') that indicates the
	# highest contrast side:
	dm = dm.addField('contrast_side', dtype = str)
	dm['contrast_side'][np.where(dm['mask_side'] == "right")] = "_left"
	dm['contrast_side'][np.where(dm['mask_side'] == "left")] = "right"
	dm['contrast_side'][np.where(dm['mask_side'] == "control")] = "control"
	
	# Add variable indicating whether CoG is to the left or to the
	# right:
	# For objects with handle right, and without mask applied: 
	# - negative xCoG means: heavier on the left
	# - pos means: heavier on the right
	dm = dm.addField('heavySide', dtype = str)
	dm["heavySide"] = 'left'
	dm["heavySide"][np.where(dm["xCoG"] >= 0)] = 'right'

	# Add variable indicating experimental half (first or second):
	dm = dm.addField("half", dtype = str)
	dm["half"] = "first"
	dm["half"][np.where(dm["block_count"] >= 3)] = "second"

	# Exclude practice trials:
	dm = dm.select("rep != 'practice'")
	
	# During parsing, tirals on which the variable 'response' did not contain
	# an int were given the value -1. Otherwise the dm will make all the 
	# 'response' values strings. Therefore, start by excluding those eventual
	# -1's:
	dm = dm.select("response != -1")

	# Saccade latencies of 0 (or -1) should not happen:
	# If no saccade is detected during a trial, 'saccLat' is changed from -1000
	# to -1 during parsing:
	dm = dm.select('saccLat1 > 0')
	
	# Negative new RT's should not happen:
	dm = dm.select('rtFromStim > 0')
	
	# Add values indicating whether the eyes landed towards the handle (positive
	# values) or towards the other side of the object (negative values):
	# Also, make sure all values are eventually converted to visual degrees:
	
	# If first landing position is empty, skip the trial:
	dm = dm.select("endX1 != ''")
	
	# Without any correction:
	dm = dm.addField("pxTowardsHandle")
	dm = dm.addField("degrTowardsHandle")
	indicesRight = np.where(dm["handle_side"] == 'right')
	indicesLeft = np.where(dm["handle_side"] == 'left')
	dm["pxTowardsHandle"][indicesRight] = (dm["endX1"][indicesRight])
	dm["pxTowardsHandle"][indicesLeft] = dm["endX1"][indicesRight]*-1
	dm["degrTowardsHandle"] = dm["pxTowardsHandle"]/studies._004.constants.ratioPxDegr

	## With CoG correction based on the original bitmap (without mask):
	#dm = dm.addField("pxTowardsHandleCorr")
	#dm = dm.addField("degrTowardsHandleCorr")
	#indicesRight = np.where(dm["handle_side"] == 'right')
	#indicesLeft = np.where(dm["handle_side"] == 'left')
	#dm["pxTowardsHandleCorr"][indicesRight] = (dm["endXCorr"][indicesRight])
	#dm["pxTowardsHandleCorr"][indicesLeft] = dm["endXCorr"][indicesRight]*-1
	#dm["degrTowardsHandleCorr"] = dm["pxTowardsHandleCorr"]/constants.ratioPxDegr

	## Wit CoG correction with taking mask into account::
	#dm = dm.addField("pxTowardsHandleCorrMask")
	#dm = dm.addField("degrTowardsHandleCorrMask")
	#indicesRight = np.where(dm["handle_side"] == 'right')
	#indicesLeft = np.where(dm["handle_side"] == 'left')
	#dm["pxTowardsHandleCorrMask"][indicesRight] = \
		#(dm["endXCorrMask"][indicesRight])
	#dm["pxTowardsHandleCorrMask"][indicesLeft] = \
		#dm["endXCorrMask"][indicesRight]*-1
	#dm["degrTowardsHandleCorrMask"] = \
		#dm["pxTowardsHandleCorrMask"]/constants.ratioPxDegr

	# Convert landing positions to visual degrees:
	dm = dm.addField("endXDegr")
	#dm = dm.addField("endXCorrDegr")
	#dm = dm.addField("endXCorrMaskDegr")
	dm["endXDegr"] = dm["endX1"]/studies._004.constants.ratioPxDegr
	#dm["endXCorrDegr"] = dm["endXCorr"]/constants.ratioPxDegr
	#dm["endXCorrMaskDegr"] = dm["endXCorrMask"]/constants.ratioPxDegr

	# Convert starting position to visual degrees:
	dm = dm.addField("startX1Degr")
	dm["startX1Degr"] = dm["startX1"]/studies._004.constants.ratioPxDegr
	
	#dm = dm.addField("rtFromLanding")
	#dm['rtFromLanding'] = dm['rtFromStim']-dm['saccLandingTime1']
	
	if saccTooFast != None:
		dm = dm.select('saccLat1 > %s'%saccTooFast)
	if saccTooSlow != None:
		dm = dm.select('saccLat1 < %s'%saccTooSlow)

	if rtTooFast != None:
		dm = dm.select('%s > %s'%(rtVar,rtTooFast))
	
	if rtTooSlow != None:
		dm = dm.select('%s < %s'%(rtVar,rtTooSlow))
	
	
	if excludeErrors:
		dm = dm.select('accuracy == 1')
	
	dm.save(fName)
	
	return dm