Esempio n. 1
0
    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()
Esempio n. 2
0
    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)
Esempio n. 3
0
    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)
Esempio n. 4
0
    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)
Esempio n. 5
0
    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)
Esempio n. 6
0
    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()
Esempio n. 7
0
    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)