Пример #1
0
class Model:
    """ Holds all the pertinent information regarding the signals.
        It also caches the information so it isn't re-calculated unnecesarily (for example when re-dimensioning windows)
        It communicates with the Controller by emiting messages.
    """

    FFT_METHODS = ['process_gain', 'noise_floor', 'SFDR', 'SINAD', 'THD', 'SNR', 'ENOB']

    def __init__(self):
        self.signal = None
        self.fft_signal = None
        self.cache_signal()
        self.cache_fft_signal()
        
    def parse_file(self, path, max_peaks=0, dB = None, time_domain = None):
        """ Invoked when a new file needs to be parsed. Will raise an exception if the file contains syntax errors
            Emits the message 'SIGNAL CHANGED' if the file was cached succesfully
        """
      
        self.signal = None
        self.fft_signal = None
      
        try:
            config = ConfigParser.RawConfigParser()
            config.read(path)
            
            nbits = config.getint('SIGNAL', 'nbits')
            rate = config.getint('SIGNAL', 'rate')
            dataString = config.get('SIGNAL', 'data').split('\n')
            data = map(string.atoi, dataString)
        
            self.signal = Signal(nbits, rate, data)
            self.fft_signal = self.signal.FFT(dB, time_domain)
        
        finally:
            self.cache_signal()
            self.cache_fft_signal(max_peaks)
            pub.sendMessage("SIGNAL CHANGED")
    
    def reprocess_fft(self, window, slices, max_peaks):
        """ Invoked when the FFT controls on tab 3 have been changed. re-calculates fft
            Emits the message 'FFT CHANGED' when done calculating
        """
        

        if self.signal is None:
            self.fft_signal = None
        else:
            # TODO: figure out how window, slices and max_peax change the way fft is calculated
            # maybe they define dB and time_domain?
            dB = None
            time_domain = None
            
            self.fft_signal = self.signal.FFT(dB, time_domain)
          
        self.cache_fft_signal(max_peaks)
        pub.sendMessage("FFT CHANGED")
        
    
    def cache_signal(self):
        """ Invokes all methods in Signal and caches their result for later use (mainly window resizing)
            Resets values to safe values (0, []) if there was an error while processing the signal definition file
        """
    
        if self.signal is None:
            self.data = []
            self.INL, self.max_INL = [], 0
            self.DNL, self.max_DNL = [], 0
            self.histogram, self.ideal_histogram = [], []
        else:
            self.data = self.signal.data
            self.INL, self.max_INL = self.signal.INL()
            self.DNL, self.max_DNL = self.signal.DNL()
            self.histogram, self.ideal_histogram = self.signal.histogram(), self.signal.ideal_histogram()
    
    def cache_fft_signal(self, max_peaks=0):
        """ Invokes all methods in FFTSignal and caches their result for later use (mainly window resizing)
            Resets values to safe values (0, []) if there was an error while processing the signal definition file
        """

        if self.fft_signal is None:
            self.fft = []
            self.harmonic_peaks = []
            for name in Model.FFT_METHODS: 
                setattr(self, name, 0)
        else:
            self.fft = self.fft_signal.fft
            self.harmonic_peaks = self.fft_signal.harmonic_peaks(max_peaks)
            for name in Model.FFT_METHODS: 
                setattr( self, name, getattr(self.fft_signal, name)() )