예제 #1
0
    def sendFreq(self, duration, freqhz, duration_is_cycles=False):
        """
        Sends a train of pulses at a given frequency on TTL2
        NOTE: MUST CALL configFreq FIRST TO GET ACCURATE RESULTS

        INPUT ARGS:
            duration - Duration of the train (defaults to seconds,
                       can override with 3rd argument)
            freqhz   - Frequency at which to stimulate in Hz
            duration_is_cycles - Whether duration provided is 
                                 in seconds or number of pulses
                                 (default: False)
        """

        if not self.labjack:
            raise (Exception('CAN ONLY USE THIS FUNCTION ON LABJACK'))

        # Time at which to send the pulse
        trainTime = timing.now()
        (timeInterval, returnValue) = timing.timedCall(\
                trainTime,\
                self.labjack.pulseTrain,\
                duration,\
                freqhz,\
                duration_is_cycles)

        if duration_is_cycles:
            self.logMessage(
                'STIM_TRAIN\t%d\t%d' %
                (int(round(float(duration) / freqhz)), freqhz), timeInterval)
        else:
            self.logMessage('STIM_TRAIN\t%d\t%d' % (duration, freqhz),
                            timeInterval)

        return timeInterval
예제 #2
0
    def scalpCallback(self):
        """
        Callback to make logs using the real-time scalp interface.
        """
        # is it time to do another alignment?
        if timing.now() >= self.last_align + self.align_interval:
            # query for offset
            (timeInterval, offset) = timing.timedCall(None, EEGGetOffset)
            # get info for log message
            self.logMessage("%s\t%s" % (self.dat_filename, offset),
                            timeInterval)

            # update last_align
            self.last_align = timeInterval[0]
예제 #3
0
 def clientLowNow(self, clk=None):
     """
     Do a non-blocking low on channel 2
     """
     if self.labjack == None:
         raise EPLPulseEEGException(
             "Client pulse methods are only callable with multiple outputs."
         )
     if clk is None:
         # no clock, so use time
         clk = timing.now()
     (timeInterval,
      returnValue) = timing.timedCall(clk, self.labjack.setChannel2Low)
     pulsePrefix = "CHANNEL_2_"
     self.logMessage("%s" % pulsePrefix + "DN", timeInterval)
예제 #4
0
    def startRecording(self, basename=None, t=None, **sfargs):
        """
        Starts recording and returns a tuple of the AudioClip and the time
        of recording onset.

        INPUT ARGS:
          t- optional PresentationClock for timing.
	  sfargs- keyword arguments for FileAudioClip constructor

        OUTPUT ARGS:
          recClip- The AudioClip object that will contain the recorded data.
          timestamp- time and latency when sound recording began.
        """
        if not self.recording:
            # get a new audio clip to record to
            if not basename is None:
                # send output to file
                self.recClip = FileAudioClip(self.archive, basename, **sfargs)
            else:
                # record in memory
                if len(sfargs) > 0:
                    raise SoundException(
                        "Cannot pass sfargs to AudioClip constructor; you must be recording to file."
                    )
                self.recClip = AudioClip()

        # start recording
            if isinstance(t, exputils.PresentationClock):
                t = t.get()
            (timeInterval, val) = timing.timedCall(t, self.eplsound.recstart)

            # Add the callback to continue recording
            self.recording = True
            self.last_rec = timeInterval[0]
            addPollCallback(self.__recCallback__)

            # log message
            if basename:
                shortName = self.recClip.filename
            else:
                shortName = "NOFILE"
            self.logMessage("%s\t%s" % ("RB", shortName), timeInterval)

            return (self.recClip, timeInterval)
예제 #5
0
    def stopRecording(self, t=None):
        """
        Stops recording and returns the resulting audio clip and the time
        recording ended.

        INPUT ARGS:
          t- optional PresentationClock for timing.

        OUTPUT ARGS:
          recClip- The AudioClip object that contains the recorded data.
          timestamp- time and latency when sound recording ended.
          
        """
        if self.recording:
            # stop recording
            if isinstance(t, exputils.PresentationClock):
                t = t.get()
            (timeInterval, val) = timing.timedCall(t, self.eplsound.recstop)

            # Remove the recording callback
            self.recording = False
            removePollCallback(self.__recCallback__)

            # get the rest of the data from recbuffer
            newstuff = self.getBuffData()

            if len(newstuff) > 0:
                # append the data to the clip
                self.recClip.append(newstuff, self.eplsound.getRecChans())

            # log message
            if isinstance(self.recClip, FileAudioClip):
                shortName = self.recClip.filename
            else:
                shortName = "NOFILE"
            self.logMessage("%s\t%s" % ("RE", shortName), timeInterval)

            r = self.recClip
            del self.recClip
            return (r, timeInterval)
예제 #6
0
    def configFreq(self, frequency):
        """
        Configures stimulation so that stimulation trains can happen
        more quickly
         
        NOTE: ONLY FUNCTIONS ON TTL2

        INPUT ARGS:
            frequency - the frequency (Hz) at which to configure

        """

        # Log the frequency
        self.logMessage("CONFIG\t%d" % frequency)

        # Set the time at which to configure
        configTime = timing.now()
        if not self.labjack:
            raise (Exception('CAN ONLY CONFIGURE FREQUENCY ON LABJACK'))
        (timeInterval, returnValue)=timing.timedCall(configTime,\
                self.labjack.configFreq,\
                frequency)
        return timeInterval
예제 #7
0
    def pulseTrain(self, numPulses, trainName=""):
        """
        Send a train of pulses.

        INPUT ARGS:
          numPulses- Number of pulses in train.
          trainName- Name to use in the log.
        """
        #trainLen denotes the number of pulses in this train
        pulseLen = 10  #in milliseconds
        interPulseInterval = 5

        self.logMessage(trainName + "TRAIN")

        # set the desired pulsetime
        pulseTime = timing.now()
        for i in range(numPulses):
            # send a pulse
            (timeInterval,
             returnValue) = timing.timedCall(pulseTime, self.timedPulse,
                                             pulseLen, 'TRAIN_')
            # pause for the next pulse
            pulseTime += interPulseInterval
예제 #8
0
    def timedStim(self, duration, freq, doRelay=False):
        '''
        Start a sync box controlled train of pulses to trigger a stimulator.
        
        INPUT ARGS:
          duration - duration of stimulation (s)
          freq - frequency to send pulse (Hz)
        '''

        # use the current time
        clk = timing.now()

        # only labjack boxes support stimulation
        if self.labjack:
            (timeInterval,
             returnValue) = timing.timedCall(clk, self.labjack.StartStim,
                                             duration, freq, doRelay)

            # log start of stimulation
            self.logMessage("STIM_ON", timeInterval)
            return timeInterval
        else:
            raise EPLPulseEEGException(
                "timedStim only functions with labjack autostim boards.")
예제 #9
0
    def timedPulse(self,
                   pulseTime,
                   pulsePrefix='',
                   signal='',
                   clk=None,
                   output_channel=0):
        """
        Send a pulse and log it.

        INPUT ARGS:
          pulseTime- Duration of pulse.
          pulsePrefix- Name to log the pulse.
        """
        # see if using clock
        usingClock = True
        if clk is None:
            # no clock, so use time
            clk = timing.now()
            usingClock = False

        if self.awCard:
            if len(signal) > 0:
                (timeInterval,
                 returnValue) = timing.timedCall(clk, self.awCard.write,
                                                 signal)
            else:
                (timeInterval,
                 returnValue) = timing.timedCall(clk, self.awCard.allOn)
        elif self.labjack:
            (timeInterval,
             returnValue) = timing.timedCall(clk, self.labjack.setFIOState,
                                             output_channel,
                                             0 if output_channel == 4 else 1)
            pulsePrefix = "CHANNEL_" + str(output_channel) + "_"
        else:
            if len(signal) > 0:
                (timeInterval,
                 returnValue) = timing.timedCall(clk, self.parallel.setSignal,
                                                 True, signal)
            else:
                (timeInterval,
                 returnValue) = timing.timedCall(clk, self.parallel.setState,
                                                 True)
        self.logMessage("%s" % pulsePrefix + "UP", timeInterval)

        # wait for the pulse time
        if usingClock:
            clk.delay(pulseTime)
        else:
            clk = clk + pulseTime

        if self.awCard:
            (timeInterval,
             returnValue) = timing.timedCall(clk, self.awCard.allOff)
        elif self.labjack:
            (timeInterval,
             returnValue) = timing.timedCall(clk, self.labjack.setFIOState,
                                             output_channel,
                                             1 if output_channel == 4 else 0)
        else:
            (timeInterval,
             returnValue) = timing.timedCall(clk, self.parallel.setState,
                                             False)

        self.logMessage("%s" % pulsePrefix + "DN", timeInterval)

        # I'm not sure when if you want this to be the start or end of the pulse
        return timeInterval
예제 #10
0
    def playLoop(self, soundClip, t=None, ampFactor=1.0, doDelay=True):
        """
        Play an AudioClip and return the time and latency of when the
        sound played.

        INPUT ARGS:
          soundClip- AudioClip object of the sound to be played
          t- Optional PresentationClock for timing.
          ampFactor- Optional amplification of sound.  (default value is 1)
          doDelay- Optionally do not tare and move the presentation clock
            forward.  Defaults to True (moving the clock forward)
          
        OUTPUT ARGS:
          timestamp- time and latency when sound playing began.
          
        """

        # Must be sure to not get multiple callbacks at once, so
        # playing a soundclip while another is running causes that
        # other one to stop immediately, even if it is not done playing.
        # self.playStop()

        # handle special case: if it's a FileAudioClip and needs loading,
        # load it.
        self.currentClip = soundClip
        if isinstance(soundClip, FileAudioClip):
            if not soundClip.isLoaded():
                # load and append the sound
                soundClip.load()
            # for logging
            shortName = soundClip.filename
        else:
            shortName = "NOFILE"

        if isinstance(t, exputils.PresentationClock):
            clk = t
        else:
            clk = exputils.PresentationClock()

        t = clk.get()

        if not soundClip.snd is None:
            # first, compute how many bytes our initial chunk
            # to append is. ASSUMPTION: always starting from byte 0.
            firstbytes = min(self.bytes_per_append, len(soundClip.snd))
            self.total_samples = int(
                math.floor(len(soundClip.snd) / self.eplsound.FORMAT_SIZE))

            if self.playing:
                # stop the playing sound 5ms prior to the new time
                timing.timedCall(t - 5, self.playStop, False)
            self.playing = True
            self.eplsound.resetSamplesPlayed()
            (timeInterval, appended) = timing.timedCall(
                t, self.eplsound.append, soundClip.snd[0:firstbytes],
                len(soundClip.snd[0:firstbytes]) / self.eplsound.FORMAT_SIZE,
                0, ampFactor)

            if doDelay:
                # accumulate the error
                clk.accumulatedTimingError += timeInterval[0] - t
                # tare the clock and delay the proper amount
                clk.tare(timeInterval[0])
                clk.delay(soundClip.getDuration())

            # it would be great if the soundClip knew the formatsize...
            # mark the offset into the sound clip
            self.startInd = appended * self.eplsound.FORMAT_SIZE
            self.endInd = len(
                soundClip.snd)  #self.total_samples*self.eplsound.FORMAT_SIZE

            # Add the callback to continue playing
            self.last_play = timeInterval[0]
            #addPollCallback(self.__playLoopCallback__, soundClip.snd, 0, ampFactor)
            addPollCallback(self.__playLoopCallback__, 0, ampFactor)

            dur = soundClip.getDuration()

        else:
            dur = 0

        # log message
        self.logMessage("%s\t%s\t%s" % ("P", shortName, dur), timeInterval)

        return timeInterval