Пример #1
0
 def set_tone_bins(self,
                   bins,
                   nsamp,
                   amps=None,
                   load=True,
                   normfact=None,
                   phases=None,
                   preset_norm=True):
     """
     Set the stimulus tones by specific integer bins
     
     bins : array of bins at which tones should be placed
         For Heterodyne system, negative frequencies should be placed in canonical FFT order
         If 2d, interpret as (nwaves,ntones)
     nsamp : int, must be power of 2
         number of samples in the playback buffer. Frequency resolution will be fs/nsamp
     amps : optional array of floats, same length as bins array
         specify the relative amplitude of each tone. Can set to zero to read out a portion
         of the spectrum with no stimulus tone.
     load : bool (debug only). If false, don't actually load the waveform, just calculate it.
     """
     if self.BYTES_PER_SAMPLE * nsamp > self.MEMORY_SIZE_BYTES:
         message = "Requested tone size ({:d} bytes) exceeds available memory ({:d} bytes)"
         raise ValueError(
             message.format(self.BYTES_PER_SAMPLE * nsamp,
                            self.MEMORY_SIZE_BYTES))
     if bins.ndim == 1:
         bins.shape = (1, bins.shape[0])
     nwaves = bins.shape[0]
     spec = np.zeros((nwaves, nsamp // 2 + 1), dtype='complex')
     self.tone_bins = bins.copy()
     self.tone_nsamp = nsamp
     if phases is None:
         phases = np.random.random(bins.shape[1]) * 2 * np.pi
     self.phases = phases.copy()
     if amps is None:
         amps = 1.0
     self.amps = amps
     for k in range(nwaves):
         spec[k, bins[k, :]] = amps * np.exp(1j * phases)
     wave = np.fft.irfft(spec, axis=1)
     if preset_norm and not normfact:
         self.wavenorm = tools.calc_wavenorm(bins.shape[1],
                                             nsamp,
                                             baseband=True)
     else:
         self.wavenorm = np.abs(wave).max()
         if normfact is not None:
             wn = (2.0 / normfact) * len(bins) / float(nsamp)
             logger.debug(
                 "Using user provide waveform normalization resulting in wavenorm %f versus optimal %f. "
                 "Ratio is %f" % (wn, self.wavenorm, self.wavenorm / wn))
             self.wavenorm = wn
     qwave = np.round((wave / self.wavenorm) * (2**15 - 1024)).astype('>i2')
     qwave.shape = (qwave.shape[0] * qwave.shape[1], )
     self.qwave = qwave
     if load:
         self.load_waveform(qwave)
     self.save_state()
Пример #2
0
 def set_tone_bins(self, bins, nsamp, amps=None, load=True, normfact=None, phases=None, preset_norm=True):
     """
     Set the stimulus tones by specific integer bins
     
     bins : array of bins at which tones should be placed
         For Heterodyne system, negative frequencies should be placed in canonical FFT order
         If 2d, interpret as (nwaves,ntones)
     nsamp : int, must be power of 2
         number of samples in the playback buffer. Frequency resolution will be fs/nsamp
     amps : optional array of floats, same length as bins array
         specify the relative amplitude of each tone. Can set to zero to read out a portion
         of the spectrum with no stimulus tone.
     load : bool (debug only). If false, don't actually load the waveform, just calculate it.
     """
     if self.BYTES_PER_SAMPLE * nsamp > self.MEMORY_SIZE_BYTES:
         message = "Requested tone size ({:d} bytes) exceeds available memory ({:d} bytes)"
         raise ValueError(message.format(self.BYTES_PER_SAMPLE * nsamp, self.MEMORY_SIZE_BYTES))
     if bins.ndim == 1:
         bins.shape = (1, bins.shape[0])
     nwaves = bins.shape[0]
     spec = np.zeros((nwaves, nsamp // 2 + 1), dtype='complex')
     self.tone_bins = bins.copy()
     self.tone_nsamp = nsamp
     if phases is None:
         phases = np.random.random(bins.shape[1]) * 2 * np.pi
     self.phases = phases.copy()
     if amps is None:
         amps = 1.0
     self.amps = amps
     for k in range(nwaves):
         spec[k, bins[k, :]] = amps * np.exp(1j * phases)
     wave = np.fft.irfft(spec, axis=1)
     if preset_norm and not normfact:
         self.wavenorm = tools.calc_wavenorm(bins.shape[1], nsamp, baseband=True)
     else:
         self.wavenorm = np.abs(wave).max()
         if normfact is not None:
             wn = (2.0 / normfact) * len(bins) / float(nsamp)
             logger.debug("Using user provide waveform normalization resulting in wavenorm %f versus optimal %f. "
                          "Ratio is %f" % (wn,self.wavenorm,self.wavenorm/wn))
             self.wavenorm = wn
     qwave = np.round((wave / self.wavenorm) * (2 ** 15 - 1024)).astype('>i2')
     qwave.shape = (qwave.shape[0] * qwave.shape[1],)
     self.qwave = qwave
     if load:
         self.load_waveform(qwave)
     self.save_state()
Пример #3
0
    def add_tone_bins(self, bins, amps=None, preset_norm=True):
        nsamp = self.tone_nsamp
        spec = np.zeros((nsamp // 2 + 1,), dtype='complex')
        self.tone_bins = np.vstack((self.tone_bins, bins))
        phases = self.phases
        if amps is None:
            amps = 1.0
        # self.amps = amps  # TODO: Need to figure out how to deal with this

        spec[bins] = amps * np.exp(1j * phases)
        wave = np.fft.irfft(spec)
        if preset_norm:
            self.wavenorm = tools.calc_wavenorm(self.tone_bins.shape[1], nsamp, baseband=True)
        else:
            self.wavenorm = np.abs(wave).max()
        qwave = np.round((wave / self.wavenorm) * (2 ** 15 - 1024)).astype('>i2')
        # self.qwave = qwave  # TODO: Deal with this, if we ever use it
        start_offset = self.tone_bins.shape[0] - 1
        self.load_waveform(qwave, start_offset=start_offset)
        self.save_state()
Пример #4
0
    def add_tone_bins(self, bins, amps=None, preset_norm=True):
        nsamp = self.tone_nsamp
        spec = np.zeros((nsamp // 2 + 1, ), dtype='complex')
        self.tone_bins = np.vstack((self.tone_bins, bins))
        phases = self.phases
        if amps is None:
            amps = 1.0
        # self.amps = amps  # TODO: Need to figure out how to deal with this

        spec[bins] = amps * np.exp(1j * phases)
        wave = np.fft.irfft(spec)
        if preset_norm:
            self.wavenorm = tools.calc_wavenorm(self.tone_bins.shape[1],
                                                nsamp,
                                                baseband=True)
        else:
            self.wavenorm = np.abs(wave).max()
        qwave = np.round((wave / self.wavenorm) * (2**15 - 1024)).astype('>i2')
        # self.qwave = qwave  # TODO: Deal with this, if we ever use it
        start_offset = self.tone_bins.shape[0] - 1
        self.load_waveform(qwave, start_offset=start_offset)
        self.save_state()