def __init__(self, parent=None):
        QtGui.QWidget.__init__(self)
        self.ui = Ui_Form_spike_rates()
        self.ui.setupUi(self)

        self.filename = ''

        self.checkboxes = []
        self.comboboxes = []
        self.spnboxes = []

        # TODO Enable when implemented
        self.ui.pushButton_auto_threshold.setEnabled(False)
        self.ui.horizontalSlider.setEnabled(False)
        self.ui.doubleSpinBox.setEnabled(False)

        QtCore.QObject.connect(self.ui.pushButton_spike_rates, QtCore.SIGNAL("clicked()"), self.graph_spike_rates)
        QtCore.QObject.connect(self.ui.pushButton_auto_threshold, QtCore.SIGNAL("clicked()"), self.estimate_thresholds)
        QtCore.QObject.connect(self.ui.horizontalSlider, QtCore.SIGNAL("valueChanged(int)"), self.update_spontaneous)
        QtCore.QObject.connect(self.ui.doubleSpinBox, QtCore.SIGNAL("valueChanged(const QString&)"), self.update_spontaneous2)
class SpikeRatesDialog(QtGui.QMainWindow):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self)
        self.ui = Ui_Form_spike_rates()
        self.ui.setupUi(self)

        self.filename = ''

        self.checkboxes = []
        self.comboboxes = []
        self.spnboxes = []

        # TODO Enable when implemented
        self.ui.pushButton_auto_threshold.setEnabled(False)
        self.ui.horizontalSlider.setEnabled(False)
        self.ui.doubleSpinBox.setEnabled(False)

        QtCore.QObject.connect(self.ui.pushButton_spike_rates, QtCore.SIGNAL("clicked()"), self.graph_spike_rates)
        QtCore.QObject.connect(self.ui.pushButton_auto_threshold, QtCore.SIGNAL("clicked()"), self.estimate_thresholds)
        QtCore.QObject.connect(self.ui.horizontalSlider, QtCore.SIGNAL("valueChanged(int)"), self.update_spontaneous)
        QtCore.QObject.connect(self.ui.doubleSpinBox, QtCore.SIGNAL("valueChanged(const QString&)"), self.update_spontaneous2)

    def populate_checkboxes(self, filename):
        self.filename = filename

        self.ui.label_title.setText(str.split(str(filename), '/')[-1])
        h_file = h5py.File(unicode(filename), 'r')

        tests = {}
        for key in h_file.keys():
            if 'segment' in key:
                for test in h_file[key].keys():
                    tests[test] = int(test.replace('test_', ''))

        sorted_tests = sorted(tests.items(), key=operator.itemgetter(1))

        # Create the layout to populate
        layout = QtGui.QGridLayout()

        title_test = QtGui.QLabel('Test')
        title_chan = QtGui.QLabel('Channel')
        title_thresh = QtGui.QLabel('Threshold')

        font = QtGui.QFont()
        font.setPointSize(10)
        font.setBold(True)

        title_test.setFont(font)
        title_chan.setFont(font)
        title_thresh.setFont(font)

        layout.addWidget(title_test, 0, 0)
        layout.addWidget(title_chan, 0, 1)
        layout.addWidget(title_thresh, 0, 2)

        row_count = 1
        for test in sorted_tests:
            checkbox = QtGui.QCheckBox(test[0])
            combobox = QtGui.QComboBox()
            spnbox = QtGui.QDoubleSpinBox()

            layout.addWidget(checkbox, row_count, 0)
            self.checkboxes.append(checkbox)

            # Find target segment
            for segment in h_file.keys():
                for s_test in h_file[segment].keys():
                    if test[0] == s_test:
                        target_seg = segment
                        target_test = s_test

            if len(h_file[target_seg][target_test].value.shape) > 3:
                channels = h_file[target_seg][target_test].value.shape[2]
            else:
                channels = 1

            if channels == 1:
                combobox.addItem('channel_1')
            else:
                for i in range(channels):
                    combobox.addItem('channel_' + str(i+1))

            if combobox.count() < 2:
                combobox.setEnabled(False)

            layout.addWidget(combobox, row_count, 1)
            self.comboboxes.append(combobox)

            spnbox.setSuffix(' V')
            spnbox.setDecimals(4)
            spnbox.setSingleStep(0.0001)
            spnbox.setMinimum(-100)
            spnbox.setMaximum(100)
            # spnbox.setValue(thresh)

            # TODO Enable when implemented
            spnbox.setEnabled(False)

            layout.addWidget(spnbox, row_count, 2)
            self.spnboxes.append(spnbox)

            row_count += 1

        self.ui.scrollAreaWidgetContents.setLayout(layout)

        # Add values to QSlider
        window_time = h_file[target_seg][target_test].value.shape[-1] / h_file[target_seg].attrs['samplerate_ad']
        self.ui.horizontalSlider.setMaximum(window_time * 1000)
        self.ui.horizontalSlider.setValue(window_time * 500)

        h_file.close()

    def estimate_thresholds(self):
        thresh_fraction = 0.7

        h_file = h5py.File(unicode(self.filename), 'r')

        for row in range(len(self.checkboxes)):

            for segment in h_file.keys():
                for test in h_file[segment].keys():
                    if self.checkboxes[row].text() == test:
                        target_seg = segment
                        target_test = test

            trace_data = h_file[target_seg][target_test].value

            if len(trace_data.shape) == 4:
                trace_data = trace_data.squeeze()

            # Still shape of 4
            if len(trace_data.shape) == 4:

                tchan = int(self.comboboxes[row].currentText().replace('channel_', '')) - 1

                trace_data = trace_data[:, :, tchan, :]
                trace_data = trace_data.squeeze()

            # Compute threshold from average maximum of traces
            max_trace = []
            for n in range(len(trace_data[1, :, 0])):
                max_trace.append(np.max(np.abs(trace_data[1, n, :])))
            average_max = np.array(max_trace).mean()
            thresh = thresh_fraction * average_max

            self.spnboxes[row].setValue(thresh)

    def get_spike_trains(self, h_file, test_num, spontStim=1):

        for segment in h_file.keys():
                for test in h_file[segment].keys():
                    if self.checkboxes[test_num].text() == test:
                        target_seg = segment
                        target_test = test

        fs = h_file[target_seg].attrs['samplerate_ad']
        reps = h_file[target_seg][target_test].attrs['reps']

        startTime = h_file[target_seg][target_test].attrs['start']
        trace_data = h_file[target_seg][target_test].value

        if len(trace_data) == 4:
            trace_data = trace_data.squeeze()
        # Still shape of 4
        if len(trace_data.shape) == 4:
            tchan = int(self.comboboxes[test_num].currentText().replace('channel_', '')) - 1
            trace_data = trace_data[:, :, tchan, :]
            trace_data = trace_data.squeeze()

        thresh = self.spnboxes[test_num].value()

        # ----- AutoThreshold -----
        maxTrace = []
        for n in range(len(trace_data[0, :, 0])):
            maxTrace.append(np.max(np.abs(trace_data[spontStim, n, :])))
        aveMax = np.array(maxTrace).mean()
        #         if max(maxTrace) > 1 * np.std(maxTrace):  # remove an extreme outlyer caused by an electrical glitch
        #             maxTrace.remove(max(maxTrace))
        th = 0.7 * aveMax
        thresh = th

        spikeTrains = pd.DataFrame([])
        nspk = 0

        for n in range(len(trace_data[0, :, 0])):
            spikes = spikestats.spike_times(trace_data[spontStim, n, :], threshold=thresh, fs=fs)
            spikeTimes = 1000 * np.array(spikes)
            spikeTimesS = pd.Series(spikeTimes)
            if spikeTimesS.size > nspk:
                spikeTrains = spikeTrains.reindex(spikeTimesS.index)
                nspk = spikeTimesS.size
            spikeTrains[str(n)] = spikeTimesS

        # print 'thresh:', thresh, '\nspikes\n', spikes

        duration = trace_data.shape[-1] / fs

        return spikeTrains, duration, startTime

    def graph_spike_rates(self):
        print 'Spike Rates'

        h_file = h5py.File(unicode(self.filename), 'r')

        target_rows = []
        for i in range(len(self.checkboxes)):
            if self.checkboxes[i].checkState():
                target_rows.append(i)

        axes = []
        timeStamp = []
        spontAve = []
        spontSTD = []
        responseAve = []
        responseSTD = []
        for row in target_rows:

            for segment in h_file.keys():
                for test in h_file[segment].keys():
                    if self.checkboxes[row].text() == test:
                        target_seg = segment
                        target_test = test

            stim_info = eval(h_file[target_seg][target_test].attrs['stim'])
            start_time = h_file[target_seg][target_test].attrs['start']

            spikeTrains, dur, time = self.get_spike_trains(h_file, row, spontStim=0)
            # print '\n----------\n1 SPIKETRAINS:', row, '\n', spikeTrains, '\n----------'

            # --- SpontaneousStats ---
            spontSpikeCount = []
            for k in spikeTrains.keys():
                spk = spikeTrains[k]
                spontSpikeCount.append(len(spk.dropna()) / float(dur))
                if len(spontSpikeCount) > 0:
                    spontStats = [np.mean(spontSpikeCount), np.std(spontSpikeCount)]
                else:
                    spontStats = [0, 0]

            spikeTrains, dur, time = self.get_spike_trains(h_file, row, spontStim=1)
            # print '\n----------\n2 SPIKETRAINS:', row, '\n', spikeTrains, '\n----------'

            # Assumes all stim are the same for the test
            # print 'stim start:', stim_info[1]['components'][0]['start_s']
            # print 'stim duration:', stim_info[1]['components'][0]['duration']
            stimStart = stim_info[1]['components'][0]['start_s']
            stimDuration = stim_info[1]['components'][0]['duration']

            # --- ResponseStats ---
            dur = stimDuration
            responseSpikeCount = []

            for k in spikeTrains.keys():
                spk = spikeTrains[k]
                responseSpikeCount.append(len(spk[spk < stimStart*1000 + stimDuration*1000 + 10]) / dur)
                if len(responseSpikeCount) > 0:
                    responseStats = [np.mean(responseSpikeCount), np.std(responseSpikeCount)]
                else:
                    responseStats = [0, 0]

            timeStamp.append(time)
            spontAve.append(spontStats[0])
            spontSTD.append(spontStats[1])
            responseAve.append(responseStats[0])
            responseSTD.append(responseStats[1])

        # --- Plot the time dependent change in rates ---
        if target_rows:
            # print 'target_rows:', target_rows
            # print self.ui.timeEdit_on_time.date(), self.ui.timeEdit_on_time.time()
            # print self.ui.timeEdit_off_time.date(), self.ui.timeEdit_off_time.time()
            timeOn = str(self.ui.timeEdit_on_time.time().hour()) + ':' \
                     + str(self.ui.timeEdit_on_time.time().minute()) + ':' \
                     + str(self.ui.timeEdit_on_time.time().second())
            timeOff = str(self.ui.timeEdit_off_time.time().hour()) + ':' \
                      + str(self.ui.timeEdit_off_time.time().minute()) \
                      + ':' + str(self.ui.timeEdit_off_time.time().second())
            rateEffects = pd.DataFrame({'Spontaneous': spontAve, 'spontSTD': spontSTD, 'Response': responseAve,
                                        'responseSTD': responseSTD}, index=pd.to_datetime(timeStamp))

        if len(target_rows) > 1:
            fig = plt.figure()
            rateEffects['Response'].plot(yerr=rateEffects['responseSTD'], capthick=1)
            rateEffects['Spontaneous'].plot(yerr=rateEffects['spontSTD'], capthick=1)
            plt.legend(loc='upper right', fontsize=12, frameon=True)
            sns.despine()
            plt.grid(False)
            plt.xlabel('Time (ms)', size=14)
            plt.ylabel('Rate (Hz)', size=14)
            plt.title(str.split(str(self.filename), '/')[-1].replace('.hdf5', ''), size=14)
            plt.tick_params(axis='both', which='major', labelsize=14)
            ax = plt.gca()
            lineY = ax.get_ylim()[1] - 0.01 * ax.get_ylim()[1]
            if timeOff == timeOn: timeOff = rateEffects.index[-1]
            if timeOn != 0 and (isinstance(timeOn, str) and isinstance(timeOff, str)):
                plt.plot((timeOn, timeOff), (lineY, lineY), 'k-', linewidth=4)
            for i, n in enumerate(target_rows):
                plt.annotate(str(n), (rateEffects.index[i], rateEffects['Spontaneous'][i]))

            plt.show()
            h_file.close()

        elif len(target_rows) > 0:
            return rateEffects
        else:
            return []

    def get_pharma_times(self, data):
        pass

    def update_spontaneous(self):
        # print self.ui.horizontalSlider.value()
        self.ui.doubleSpinBox.setValue(self.ui.horizontalSlider.value())

    def update_spontaneous2(self):
        # print self.ui.doubleSpinBox.value()
        self.ui.horizontalSlider.setValue(self.ui.doubleSpinBox.value())