def loadClicked(self, *args): file = gb.session.calibrationFile.value dataDir = gb.session.dataDir.value if file: file = misc.absolutePath(file, dataDir) else: file = dataDir file = gui.openFile(config.SETTINGS_FILTER, file) if not file: return # use a temp copy for loading new calibration calibrationTemp = gb.calibration.copy() log.info('Loading calibration from "%s"', file) calibrationTemp.loadFile(file, float) # on successful load, copy the temp back to the original calibrationTemp.copyTo(gb.calibration) file = misc.relativePath(file, dataDir) gb.session.calibrationFile.value = file gb.session.saveFile(config.LAST_SESSION_FILE) self.updateCal()
def dataDirButtonClicked(self, *args): dataDir = self.dataDir.text() dataDir = gui.openDirectory(dataDir) if not dataDir: return dataDir = misc.absolutePath(dataDir) self.dataDir.setText(dataDir) self.dataDir.textEdited.emit(dataDir)
def paradigmFileButtonClicked(self, *args): file = self.paradigmFile.currentText() dataDir = self.dataDir.text() if file: file = misc.absolutePath(file, dataDir) else: file = dataDir file = gui.openFile(config.SETTINGS_FILTER, file) if not file: return file = misc.relativePath(file, dataDir) self.paradigmFile.setCurrentText(file)
def dataFileButtonClicked(self, *args): file = self.dataFile.text() dataDir = self.dataDir.text() if file: file = misc.absolutePath(file, dataDir) else: file = dataDir file = gui.saveFile(config.DATA_FILTER, file) if not file: return file = misc.relativePath(file, dataDir) self.dataFile.setText(file)
def saveClicked(self, *args): file = gb.session.calibrationFile.value dataDir = gb.session.dataDir.value if file: file = misc.absolutePath(file, dataDir) else: file = dataDir file = gui.saveFile(config.SETTINGS_FILTER, file) if not file: return log.info('Saving calibration to "%s"', file) gb.calibration.saveFile(file) file = misc.relativePath(file, dataDir) gb.session.calibrationFile.value = file gb.session.saveFile(config.LAST_SESSION_FILE)
def accept(self): dataDir = misc.absolutePath(self.dataDir.text()) # verify data file path dataFile = misc.absolutePath(self.dataFile.text(), dataDir) if gb.appMode == 'Experiment': if not dataFile: gui.showError('Entered data file is not valid', 'File path cannot be empty') return dir_, file = os.path.split(dataFile) if dir_ and not os.path.isdir(dir_): res = gui.showQuestion('Directory "%s" doesn\'t exist' % dir_, 'Would you like to create it?') if not res: return os.makedirs(dir_) fileName, fileExt = os.path.splitext(file) if fileExt != config.DATA_EXT: gui.showError( 'Entered data file extension is not valid', 'Please change the extension to "%s"' % config.DATA_EXT) return if os.path.isfile(dataFile): gui.showError('Entered data file already exists', 'Please enter a different file path') return # verify calibration file path calibrationFile = self.calibrationFile.text() if calibrationFile: calibrationFile = misc.absolutePath(calibrationFile, dataDir) if not os.path.isfile(calibrationFile): gui.showError('Entered calibration file doesn\'t exist', 'Please enter a different file path') return # verify paradigm file path paradigmFile = self.paradigmFile.currentText() if paradigmFile and gb.appMode == 'Experiment': paradigmFile = misc.absolutePath(paradigmFile, dataDir) if not os.path.isfile(paradigmFile): gui.showError('Entered paradigm file doesn\'t exist', 'Please enter a different file path') return # verify rove parameters rove = [] if not paradigmFile: for i in range(self.rove.count()): item = self.rove.item(i) if item.checkState() == QtCore.Qt.Checked: rove += [self.roveParams[i]] if not rove and gb.appMode == 'Experiment': gui.showError('No rove parameters selected', 'Please select at least one parameter') return # transfer all widget values to gb.session autoDataFile = self.autoDataFile.checkState() == QtCore.Qt.Checked gb.session.clearValues() gb.session.dataDir.value = dataDir gb.session.subjectID.value = self.subjectID.currentText() gb.session.experimentName.value = self.experimentName.currentText() gb.session.experimentMode.value = self.experimentMode.currentText() gb.session.recording.value = self.recording.currentText() gb.session.autoDataFile.value = autoDataFile gb.session.dataFile.value = dataFile gb.session.calibrationFile.value = calibrationFile gb.session.paradigmFile.value = paradigmFile gb.session.rove.value = rove gb.session.sessionTime.value = gb.sessionTimeComplete gb.session.computerName.value = platform.node() gb.session.commitHash.value = misc.getCommitHash() super().accept()
def updateSound(self): # do nothing if neither sound file nor sound amplification have changed newFile = self.lstFiles.currentItem().text() newAmp = self.spnAmp.value() if self.file == newFile and self.amp == newAmp: return # load new sound file if self.file != newFile: try: try: log.info('Loading sound file: "%s"', newFile) file = misc.absolutePath(newFile, config.STIM_DIR) fs, data = sp.io.wavfile.read(file, mmap=True) except Exception as e: raise ValueError('Cannot load sound file: "%s"' % newFile) from e # check for sampling frequency if fs != daqs.analogOutput.fs: raise ValueError('Sampling frequency of sound file: "%s" ' 'should be %g' % (newFile, daqs.analogOutput.fs)) # check if file is empty if not len(data): raise ValueError('Specified sound file: "%s" is empty' % newFile) data = data.astype('float64') data -= data.mean() data *= 1 / np.sqrt((data**2).mean()) amp1 = np.log10(daqs.MIN_VOLTAGE / data.min()) * 20 amp2 = np.log10(daqs.MAX_VOLTAGE / data.max()) * 20 self.spnAmp.blockSignals(True) self.spnAmp.setMaximum(np.floor(max(amp1, amp2))) self.spnAmp.blockSignals(False) newAmp = self.spnAmp.value() except: log.exception('') gui.showException() data = None fs = daqs.analogOutput.fs # where to insert the updated sound ns = daqs.analogOutput.nsGenerated if self.active: ns += int(daqs.UPDATE_DELAY * fs) dataLength = int(daqs.analogOutput.dataChunk * fs) rampLength = int(.5 * fs) ramp = self.getRamp(rampLength) # ramp down old masker and zero-pad oldData = self.getSound(ns, rampLength) oldData *= ramp[::-1] oldData = np.r_[oldData, np.zeros(dataLength - rampLength)] if self.file != newFile: self.data = data # save starting sample of the new sound self.startNS = ns # update local copies of masker file and level self.file = newFile self.amp = newAmp # ramp up new masker newData = self.getSound(ns, dataLength) newData[0:rampLength] *= ramp # mix old and new sound data data = oldData + newData log.debug( 'Updating analog output buffer at %.3f for %.3f duration ' '(generation at %.3f)' % (ns / fs, dataLength / fs, daqs.analogOutput.nsGenerated / fs)) daqs.analogOutput.write(data, ns)