Skip to content

Commit

Permalink
Merge pull request #38 from jfkominsky/0.10.0
Browse files Browse the repository at this point in the history
0.10.0
  • Loading branch information
jfkominsky committed May 29, 2022
2 parents 9aceba3 + 9188b04 commit a4f6872
Show file tree
Hide file tree
Showing 14 changed files with 2,921 additions and 2,122 deletions.
Binary file modified PyHab User Manual.pdf
Binary file not shown.
4 changes: 0 additions & 4 deletions PyHab/PyHab Launcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,16 +59,12 @@ def checkIfStim(setDict, tempOrd):
"""
tempMovs = eval(setDict['stimNames'])
tempBlocks = eval(setDict['blockList'])
tempHabList = eval(setDict['habTrialList'])
stPres = True
if len(tempMovs) > 0:
for i in tempOrd:
if i in tempMovs:
if len(tempMovs[i]) == 0:
stPres = False
elif i == 'Hab' and len(tempHabList) > 0:
if not checkIfStim(setDict, tempHabList):
stPres = False
elif i in tempBlocks.keys():
if not checkIfStim(setDict, tempBlocks[i]):
stPres = False
Expand Down
665 changes: 245 additions & 420 deletions PyHab/PyHabBuilder.py

Large diffs are not rendered by default.

643 changes: 384 additions & 259 deletions PyHab/PyHabClass.py

Large diffs are not rendered by default.

193 changes: 84 additions & 109 deletions PyHab/PyHabClassHPP.py

Large diffs are not rendered by default.

147 changes: 70 additions & 77 deletions PyHab/PyHabClassPL.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def __init__(self, settingsDict):
self.verbDatList = {'verboseOn': [], 'verboseOn2': [], 'verboseOff': []} # a dict of the verbose data arrays
self.verbBadList = {'verboseOn': [], 'verboseOn2': [], 'verboseOff': []} # Corresponding for bad data

def abortTrial(self, onArray, offArray, trial, ttype, onArray2, stimName = '', habTrialNo = 0):
def abortTrial(self, onArray, offArray, trial, ttype, onArray2, stimName = '', habTrialNo = 0, habCrit=0.0):
"""
Aborts a trial in progress, saves any data recorded thus far to the bad-data structures
Expand All @@ -41,6 +41,10 @@ def abortTrial(self, onArray, offArray, trial, ttype, onArray2, stimName = '', h
:type onArray2: list of dicts {trial, trialType, startTime, endTime, duration}
:param stimName: If presenting stimuli, name of the stim file
:type stimName: string
:param habTrialNo: Tracking if this is a habituation trial and if so what number
:type habTrialNo: int
:param habCrit: Habituation criterion, if it's been set
:type habCrit: float
:return:
:rtype:
"""
Expand Down Expand Up @@ -71,13 +75,13 @@ def abortTrial(self, onArray, offArray, trial, ttype, onArray2, stimName = '', h

tempData = {'sNum': self.sNum, 'sID': self.sID, 'months': self.ageMo, 'days': self.ageDay, 'sex': self.sex, 'cond': self.cond,
'condLabel': self.condLabel,
'trial': trial, 'GNG': 0, 'trialType': ttype, 'stimName': stimName, 'habCrit': self.habCrit, 'habTrialNo': habTrialNo,
'trial': trial, 'GNG': 0, 'trialType': ttype, 'stimName': stimName, 'habCrit': habCrit, 'habTrialNo': habTrialNo,
'sumOnL': sumOn, 'numOnL': len(onArray),
'sumOnR': sumOn2, 'numOnR': len(onArray2), 'sumOff': sumOff, 'numOff': len(offArray),
'trialDuration': totalduration}
self.badTrials.append(tempData)

def dataRec(self, onArray, offArray, trial, type, onArray2, stimName = '', habTrialNo = 0):
def dataRec(self, onArray, offArray, trial, type, onArray2, stimName = '', habTrialNo = 0, habCrit = 0.0):
"""
Records the data for a trial that ended normally.
Expand All @@ -93,6 +97,10 @@ def dataRec(self, onArray, offArray, trial, type, onArray2, stimName = '', habTr
:type onArray2: list of dicts {trial, trialType, startTime, endTime, duration}
:param stimName: If presenting stimuli, name of the stim file
:type stimName: string
:param habTrialNo: Tracking if this is a habituation trial and if so what number
:type habTrialNo: int
:param habCrit: Habituation criterion, if it's been set
:type habCrit: float
:return:
:rtype:
"""
Expand Down Expand Up @@ -123,7 +131,7 @@ def dataRec(self, onArray, offArray, trial, type, onArray2, stimName = '', habTr
totalduration = totalduration - offArray[-1]['duration']

tempData={'sNum':self.sNum, 'sID': self.sID, 'months':self.ageMo, 'days':self.ageDay, 'sex':self.sex, 'cond':self.cond,'condLabel':self.condLabel,
'trial':trial, 'GNG':1, 'trialType':type, 'stimName':stimName, 'habCrit':self.habCrit, 'habTrialNo': habTrialNo,
'trial':trial, 'GNG':1, 'trialType':type, 'stimName':stimName, 'habCrit':habCrit, 'habTrialNo': habTrialNo,
'sumOnL':sumOn, 'numOnL':len(onArray),
'sumOnR':sumOn2,'numOnR':len(onArray2),'sumOff':sumOff, 'numOff':len(offArray),
'trialDuration': totalduration}
Expand Down Expand Up @@ -165,6 +173,8 @@ def doTrial(self, number, ttype, disMovie):
Control function for individual trials, to be called by doExperiment
Returns a status value (int) that tells doExperiment what to do next
TODO: Hab trial revamp
:param number: Trial number
:type number: int
:param ttype: Trial type
Expand All @@ -176,20 +186,20 @@ def doTrial(self, number, ttype, disMovie):
"""
self.trialText.text = "Trial no. " + str(number)
habTrial = False
habBlock = ''
localType = deepcopy(ttype)
while '.' in localType:
localType = localType[localType.index('.') + 1:]
if ttype[0:3] == 'hab' and '.' in ttype: # Hab sub-trials. Hard to ID definitively, actually.
spliceType = ttype[ttype.index('.')+1:]
if '.' in spliceType:
spliceType = spliceType[0:spliceType.index('.')] # Isolate the part between '.'s, which will be what shows up in habtriallist.
if spliceType in self.habTrialList:
dataType = 'hab' + ttype[ttype.index('.'):] # Collapses down the number and ^ markings for the data file
habTrial = True
else:
dataType = ttype
elif len(self.habTrialList) == 0 and ttype == 'Hab':
dataType = ttype
if '*' in ttype: # Hab block trial
# Hab trials have this * marker, but also the hab block will always be the top-level block, i.e., before the first .
# Even if it's a one-trial block this will be true.
# datatype should be the full block-trial name minus *^
dataType = ttype.translate({94: None, 42: None})
habBlock = ttype[:ttype.index('*')]
# Now we need to trim out the hab number. Assume maxHab < 100
for b, c in self.habCount.items():
if habBlock[0:len(b)] == b and habBlock[len(b):] == str(c + 1):
habBlock = habBlock[0:len(b)]
habTrial = True
else:
dataType = ttype
Expand Down Expand Up @@ -524,9 +534,11 @@ def onDuration(adds=0, subs=0): # A function for the duration switch, while lea
'duration':offDur}
offArray.append(tempGazeArray)
if habTrial:
habDataRec = self.habCount + 1
habDataRec = self.habCount[habBlock] + 1
habCrit = self.habCrit[habBlock]
else:
habDataRec = 0
habCrit = -1
if self.stimPres:
# Reset everything, stop playing sounds and movies.
if disMovie['stimType'] == 'Movie':
Expand Down Expand Up @@ -570,71 +582,48 @@ def onDuration(adds=0, subs=0): # A function for the duration switch, while lea
if self.stimPres and disMovie['stimType'] == 'Movie':
disMovie['stim'].seek(0.0)
disMovie['stim'].pause()
self.abortTrial(onArray, offArray, number, dataType, onArray2, self.stimName, habDataRec)
self.abortTrial(onArray, offArray, number, dataType, onArray2, self.stimName, habDataRec, habCrit)
return 3
else:
self.dataRec(onArray, offArray, number, dataType, onArray2, self.stimName, habDataRec)
if self.habMetWhen == -1 and len(self.habTrialList) > 0 and not abort: # if still during habituation
if dataType[0:4] == 'hab.' and dataType[4:] in self.calcHabOver:
tempSum = 0
if self.habByDuration == 1:
for c in range(0, len(onArray)):
tempSum += onArray[c]['duration']
for d in range(0, len(onArray2)):
tempSum += onArray2[d]['duration']
for e in range(0, len(offArray)):
tempSum += offArray[e]['duration']
if self.durationInclude == 0 and len(offArray) > 0:
if offArray[-1]['endTime'] > onArray[-1]['endTime'] and offArray[-1]['endTime'] > onArray2[-1]['endTime']:
tempSum = tempSum - offArray[-1]['duration']
else:
for c in range(0, len(onArray)):
tempSum += onArray[c]['duration']
for d in range(0, len(onArray2)):
tempSum += onArray2[d]['duration']
self.habDataCompiled[self.habCount] += tempSum
if ttype == 4:
return 2
elif '^' in ttype:
self.habCount += 1
# Check if criteria need to be set or have been met
if self.checkStop(): # If criteria met
# Check if there are any trials FOLLOWING the hab trials.
if self.maxHabIndex < len(self.actualTrialOrder)-1:
return 1
self.dataRec(onArray, offArray, number, dataType, onArray2, self.stimName, habDataRec, habCrit)
if habTrial:
if self.habMetWhen[habBlock] == -1 and not abort: # if still during habituation
if localType in self.blockList[habBlock]['calcHabOver']:
tempSum = 0
if self.blockList[habBlock]['habByDuration']:
for c in range(0, len(onArray)):
tempSum += onArray[c]['duration']
for d in range(0, len(onArray2)):
tempSum += onArray2[d]['duration']
for e in range(0, len(offArray)):
tempSum += offArray[e]['duration']
if self.durationInclude == 0 and len(offArray) > 0:
if offArray[-1]['endTime'] > onArray[-1]['endTime'] and offArray[-1]['endTime'] > onArray2[-1]['endTime']:
tempSum = tempSum - offArray[-1]['duration']
else:
return 2 # End experiment.
for c in range(0, len(onArray)):
tempSum += onArray[c]['duration']
for d in range(0, len(onArray2)):
tempSum += onArray2[d]['duration']
self.habDataCompiled[habBlock][self.habCount[habBlock]] += tempSum
if ttype == 4:
return 2
elif '^' in ttype:
self.habCount[habBlock] += 1
# Check if criteria need to be set or have been met
if self.checkStop(habBlock): # If criteria met
# First we find the last hab trial in THIS hab block.
maxHab = 0
if habBlock in self.actualTrialOrder[number][0:len(habBlock)] and '^' in self.actualTrialOrder[number]:
maxHab = number
if maxHab < len(self.actualTrialOrder) - 1:
return 1
else:
return 2 # End experiment.
else:
return 0
else:
return 0
else:
return 0
elif ttype == 'Hab' and self.habMetWhen == -1 and not abort:
tempSum = 0
if self.habByDuration == 1:
for c in range(0, len(onArray)):
tempSum += onArray[c]['duration']
for d in range(0, len(onArray2)):
tempSum += onArray2[d]['duration']
for e in range(0, len(offArray)):
tempSum += offArray[e]['duration']
if self.durationInclude == 0 and len(offArray) > 0:
if offArray[-1]['endTime'] > onArray[-1]['endTime'] and offArray[-1]['endTime'] > onArray2[-1]['endTime']:
tempSum = tempSum - offArray[-1]['duration']
else:
for c in range(0, len(onArray)):
tempSum += onArray[c]['duration']
for d in range(0, len(onArray2)):
tempSum += onArray2[d]['duration']
self.habDataCompiled[self.habCount] += tempSum
self.habCount += 1
if self.checkStop(): # If criteria met
# Check if there are any trials FOLLOWING the hab trials.
if self.actualTrialOrder[-1] != 'Hab':
return 1
else:
return 2 # End experiment.
else:
return 0
elif number >= len(self.actualTrialOrder) or ttype == 4:
# End experiment
return 2
Expand Down Expand Up @@ -681,7 +670,11 @@ def endExperiment(self):

# If there is habituation data, create hab summary file. Similar to the block one, but a little easier thanks to
# the tagging of habituation trial numbers.
if self.habSetWhen > 0 and len(self.habTrialList) > 0: # If there's a 'Hab' trial type, the main summary file does the trick just fine.
wasHab = False
for q, r in self.blockList.items():
if r['habituation'] in [1, '1', True, 'True']:
wasHab = True
if wasHab:
habMatrix = self.saveHabFile()
# Now, actually write the file
nDupe = '' # This infrastructure eliminates the risk of overwriting existing data
Expand Down

0 comments on commit a4f6872

Please sign in to comment.