Exemplo n.º 1
0
class ExperimentTimeline(QtGui.QWidget):
    def __init__(self):
        QtGui.QWidget.__init__(self)
        self.channels = None
        self.start_time = None  # starting time according to NWB file

        self.layout = QtGui.QGridLayout()
        self.setLayout(self.layout)
        self.layout.setContentsMargins(0, 0, 0, 0)

        self.plots = PlotGrid()
        self.plots.set_shape(config.n_headstages, 1)
        self.plots.setXLink(self.plots[0, 0])
        self.layout.addWidget(self.plots, 0, 0)

        self.ptree = pg.parametertree.ParameterTree(showHeader=False)
        self.layout.addWidget(self.ptree, 0, 1)
        self.ptree.setMaximumWidth(250)

        self.params = pg.parametertree.Parameter.create(name='params',
                                                        type='group',
                                                        addText='Add pipette')
        self.params.addNew = self.add_pipette_clicked  # monkey!
        self.ptree.setParameters(self.params, showTop=False)

    def list_channels(self):
        return self.channels

    def get_channel_plot(self, chan):
        return self.plots[chan, 0]

    def add_pipette_clicked(self):
        self.add_pipette(channel=self.channels[0], start=0, stop=500)

    def remove_pipettes(self):
        for ch in self.params.children():
            self.params.removeChild(ch)
            ch.region.scene().removeItem(ch.region)
        for i in range(self.plots.shape[0]):
            self.plots[i, 0].clear()

    def load_site(self, site_dh):
        """Generate pipette list for this site
        """
        self.remove_pipettes()

        # automatically fill pipette fluorophore field
        expt_dh = site_dh.parent().parent()
        expt_info = expt_dh.info()
        dye = expt_info.get('internal_dye', None)
        internal = expt_info.get('internal', None)

        # automatically select electrode regions
        self.channels = list(range(config.n_headstages))
        site_info = site_dh.info()
        for i in self.channels:
            hs_state = site_info.get('Headstage %d' % (i + 1), None)
            status = {
                'NS': 'No seal',
                'LS': 'Low seal',
                'GS': 'GOhm seal',
                'TF': 'Technical failure',
                'NA': 'No attempt',
                None: 'Not recorded',
            }.get(hs_state, hs_state)
            self.add_pipette(i,
                             status=status,
                             internal_dye=dye,
                             internal=internal)

    def load_nwb(self, nwb_handle):
        with pg.BusyCursor():
            self._load_nwb(nwb_handle)

    def _load_nwb(self, nwb_handle):
        self.nwb_handle = nwb_handle
        self.nwb = MiesNwb(nwb_handle.name())

        # load all recordings
        recs = {}
        for srec in self.nwb.contents:
            for chan in srec.devices:
                recs.setdefault(chan, []).append(srec[chan])

        chans = sorted(recs.keys())

        # find time of first recording
        start_time = min([rec[0].start_time for rec in recs.values()])
        self.start_time = start_time
        end_time = max([rec[-1].start_time for rec in recs.values()])
        self.plots.setXRange(0, (end_time - start_time).seconds)

        # plot all recordings
        for i, chan in enumerate(chans):
            n_recs = len(recs[chan])
            times = np.empty(n_recs)
            i_hold = np.empty(n_recs)
            v_hold = np.empty(n_recs)
            v_noise = np.empty(n_recs)
            i_noise = np.empty(n_recs)

            # load QC metrics for all recordings
            for j, rec in enumerate(recs[chan]):
                dt = (rec.start_time - start_time).seconds
                times[j] = dt
                v_hold[j] = rec.baseline_potential
                i_hold[j] = rec.baseline_current
                if rec.clamp_mode == 'vc':
                    v_noise[j] = np.nan
                    i_noise[j] = rec.baseline_rms_noise
                else:
                    v_noise[j] = rec.baseline_rms_noise
                    i_noise[j] = np.nan

            # scale all qc metrics to the range 0-1
            pass_brush = pg.mkBrush(100, 100, 255, 200)
            fail_brush = pg.mkBrush(255, 0, 0, 200)
            v_hold = (v_hold + 60e-3) / 20e-3
            i_hold = i_hold / 400e-12
            v_noise = v_noise / 5e-3
            i_noise = i_noise / 100e-12

            plt = self.get_channel_plot(chan)
            plt.setLabels(left=("Ch %d" % chan))
            for data, symbol in [(np.zeros_like(times), 'o'), (v_hold, 't'),
                                 (i_hold, 'x'), (v_noise, 't1'),
                                 (i_noise, 'x')]:
                brushes = np.where(np.abs(data) > 1.0, fail_brush, pass_brush)
                plt.plot(times,
                         data,
                         pen=None,
                         symbol=symbol,
                         symbolPen=None,
                         symbolBrush=brushes)

        for i in recs.keys():
            start = (recs[i][0].start_time - start_time).seconds - 1
            stop = (recs[i][-1].start_time - start_time).seconds + 1
            pip_param = self.params.child('Pipette %d' % (i + 1))
            pip_param.set_time_range(start, stop)

            got_data = len(recs[i]) > 2
            pip_param['got data'] = got_data

    def add_pipette(self, channel, status=None, **kwds):
        elec = PipetteParameter(self, channel, status=status, **kwds)
        self.params.addChild(elec, autoIncrementName=True)
        elec.child('channel').sigValueChanged.connect(
            self._pipette_channel_changed)
        elec.region.sigRegionChangeFinished.connect(
            self._pipette_region_changed)
        self._pipette_channel_changed(elec.child('channel'))

    def _pipette_channel_changed(self, param):
        plt = self.get_channel_plot(param.value())
        plt.addItem(param.parent().region)
        self._rename_pipettes()

    def _pipette_region_changed(self):
        self._rename_pipettes()

    def _rename_pipettes(self):
        # sort electrodes by channel
        elecs = {}
        for elec in self.params.children():
            elecs.setdefault(elec['channel'], []).append(elec)

        for chan in elecs:
            # sort all electrodes on this channel by start time
            chan_elecs = sorted(elecs[chan],
                                key=lambda e: e.region.getRegion()[0])

            # assign names
            for i, elec in enumerate(chan_elecs):
                # rename all first to avoid name colisions
                elec.setName('rename%d' % i)
            for i, elec in enumerate(chan_elecs):
                # If there are multiple electrodes on this channel, then
                # each extra electrode increments its name by the number of
                # headstages (for example, on AD channel 3, the first electrode
                # is called "Electrode 4", and on an 8-headstage system, the
                # second electrode will be "Electrode 12").
                e_id = (chan + 1) + (i * config.n_headstages)
                elec.id = e_id
                elec.setName('Pipette %d' % e_id)

    def save(self):
        state = {}
        for elec in self.params.children():
            rgn = elec.region.getRegion()
            if self.start_time is None:
                start = None
                stop = None
            else:
                start = self.start_time + datetime.timedelta(seconds=rgn[0])
                stop = self.start_time + datetime.timedelta(seconds=rgn[1])

            state[elec.id] = OrderedDict([
                ('pipette_status', elec['status']),
                ('got_data', elec['got data']),
                ('ad_channel', elec['channel']),
                ('patch_start', start),
                ('patch_stop', stop),
                ('cell_labels', {
                    'biocytin': '',
                    'red': '',
                    'green': '',
                    'blue': ''
                }),
                #('cell_qc', {'holding': None, 'access': None, 'spiking': None}),
                ('target_layer', elec['target layer']),
                ('morphology', elec['morphology']),
                ('internal_solution', elec['internal']),
                ('internal_dye', elec['internal dye']),
                ('synapse_to', None),
                ('gap_to', None),
                ('notes', ''),
            ])
        return state
Exemplo n.º 2
0
params = pg.parametertree.Parameter.create(name='params',
                                           type='group',
                                           children=[
                                               dict(name='data',
                                                    type='list',
                                                    values=trace_names),
                                               evd.params,
                                           ])

pt.setParameters(params, showTop=False)
hs.addWidget(pt)

plots = PlotGrid()
plots.set_shape(2, 1)
plots.setXLink(plots[0, 0])
hs.addWidget(plots)

evd.set_plots(plots[0, 0], plots[1, 0])


def update(auto_range=False):
    evd.process(traces[params['data']])
    if auto_range:
        plots[0, 0].autoRange()


evd.parameters_changed.connect(lambda: update(auto_range=False))
params.child('data').sigValueChanged.connect(lambda: update(auto_range=True))

update(auto_range=True)
            plt = plots[i, j]
            plt.setLabels(left=('%s-%s  n=%d'%(pre_type, post_type, len(rg)), 'V'), bottom=('Time', 's'))
            base = np.median(avg.data[:100])
            plt.plot(avg.time_values, avg.data - base)

            # for first pulse
            fit = fit_psp(avg, yoffset=0, amp_ratio=(0, 'fixed'), mask_stim_artifact=True)
            # for later pulses
            #fit = fit_psp(avg, yoffset=0, mask_stim_artifact=True)
            
            amps[(pre_type, post_type)] = fit.best_values['amp']
            plt.plot(avg.time_values, fit.eval()-base, pen='g')


    plots.setXLink(plots[0,0])
    for i in range(2):
        for j in range(len(types)):
            plots[i,j].setYLink(plots[0,0])
    for i in range(2,len(types)):
        for j in range(len(types)):
            plots[i,j].setYLink(plots[2,0])


    plt = pg.plot()
    typs = amps.keys()
    bar = pg.BarGraphItem(x=np.arange(len(amps)), width=0.6, height=np.array(amps.values()))
    plt.addItem(bar)

    ax = plt.getAxis('bottom')
    ax.setTicks([[(i,"%s-%s"%amps.keys()[i]) for i in range(len(amps))]])
Exemplo n.º 4
0
        'bottom': ('baseline rms error', 'V')
    })
plt.addLegend()

grid = PlotGrid()
grid.set_shape(3, 1)
grid.show()

for r, c in ((1, 'r'), (2, 'g'), (3, 'b')):
    mask = rig == r
    rig_data = rms[mask]
    y, x = np.histogram(rig_data, bins=np.linspace(0, 0.002, 1000))
    plt.plot(x,
             y / len(rig_data),
             stepMode=True,
             connect='finite',
             pen=c,
             name="Rig %d" % r)

    p = grid[r - 1, 0]
    p.plot(ts[mask],
           rig_data,
           pen=None,
           symbol='o',
           symbolPen=None,
           symbolBrush=(255, 255, 255, 100))
    p.setLabels(left=('rig %d baseline rms noise' % r, 'V'))

grid.setXLink(grid[0, 0])
grid.setYLink(grid[0, 0])
rms = np.array([row[0] for row in rows])
rig = np.array([row[1] for row in rows]).astype(int)
hs = np.array([row[2] for row in rows]).astype(int)
col = rig*8 + hs

ts = np.array([time.mktime(row[3].timetuple()) for row in rows])
#ts -= ts[0]

pg.plot(col + np.random.uniform(size=len(col))*0.7, rms, pen=None, symbol='o', symbolPen=None, symbolBrush=(255, 255, 255, 50))

plt = pg.plot(labels={'left': 'number of sweeps (normalized per rig)', 'bottom': ('baseline rms error', 'V')})
plt.addLegend()

grid = PlotGrid()
grid.set_shape(3, 1)
grid.show()

for r, c in ((1, 'r'), (2, 'g'), (3, 'b')):
    mask = rig==r
    rig_data = rms[mask]
    y, x = np.histogram(rig_data, bins=np.linspace(0, 0.002, 1000))
    plt.plot(x, y/len(rig_data), stepMode=True, connect='finite', pen=c, name="Rig %d" % r)

    p = grid[r-1, 0]
    p.plot(ts[mask], rig_data, pen=None, symbol='o', symbolPen=None, symbolBrush=(255, 255, 255, 100))
    p.setLabels(left=('rig %d baseline rms noise'%r, 'V'))

grid.setXLink(grid[0, 0])
grid.setYLink(grid[0, 0])

Exemplo n.º 6
0
class ExperimentTimeline(QtGui.QWidget):
    def __init__(self):
        QtGui.QWidget.__init__(self)
        self.channels = None

        self.layout = QtGui.QGridLayout()
        self.setLayout(self.layout)
        self.layout.setContentsMargins(0, 0, 0, 0)

        self.plots = PlotGrid()
        self.layout.addWidget(self.plots, 0, 0)

        self.ptree = pg.parametertree.ParameterTree(showHeader=False)
        self.layout.addWidget(self.ptree, 0, 1)
        self.ptree.setMaximumWidth(250)

        self.params = pg.parametertree.Parameter.create(name='params',
                                                        type='group',
                                                        addText='Add pipette')
        self.params.addNew = self.add_pipette_clicked  # monkey!
        self.ptree.setParameters(self.params, showTop=False)

    def list_channels(self):
        return self.channels

    def get_channel_plot(self, chan):
        i = self.channels.index(chan)
        return self.plots[i, 0]

    def add_pipette_clicked(self):
        self.add_pipette(channel=self.channels[0], start=0, stop=500)

    def remove_pipettes(self):
        for ch in self.params.children():
            self.params.removeChild(ch)
            ch.region.scene().removeItem(ch.region)

    def load_experiment(self, nwb_handle):
        self.nwb_handle = nwb_handle
        self.nwb = MiesNwb(nwb_handle.name())

        # load all recordings
        recs = {}
        for srec in self.nwb.contents:
            for chan in srec.devices:
                recs.setdefault(chan, []).append(srec[chan])

        chans = sorted(recs.keys())
        self.channels = chans
        self.plots.set_shape(len(chans), 1)
        self.plots.setXLink(self.plots[0, 0])

        # find time of first recording
        start_time = min([rec[0].start_time for rec in recs.values()])
        self.start_time = start_time
        end_time = max([rec[-1].start_time for rec in recs.values()])
        self.plots.setXRange(0, (end_time - start_time).seconds)

        # plot all recordings
        for i, chan in enumerate(chans):
            n_recs = len(recs[chan])
            times = np.empty(n_recs)
            i_hold = np.empty(n_recs)
            v_hold = np.empty(n_recs)
            v_noise = np.empty(n_recs)
            i_noise = np.empty(n_recs)

            # load QC metrics for all recordings
            for j, rec in enumerate(recs[chan]):
                dt = (rec.start_time - start_time).seconds
                times[j] = dt
                v_hold[j] = rec.baseline_potential
                i_hold[j] = rec.baseline_current
                if rec.clamp_mode == 'vc':
                    v_noise[j] = np.nan
                    i_noise[j] = rec.baseline_rms_noise
                else:
                    v_noise[j] = rec.baseline_rms_noise
                    i_noise[j] = np.nan

            # scale all qc metrics to the range 0-1
            pass_brush = pg.mkBrush(100, 100, 255, 200)
            fail_brush = pg.mkBrush(255, 0, 0, 200)
            v_hold = (v_hold + 60e-3) / 20e-3
            i_hold = i_hold / 400e-12
            v_noise = v_noise / 5e-3
            i_noise = i_noise / 100e-12

            plt = self.plots[i, 0]
            plt.setLabels(left=("Ch %d" % chan))
            for data, symbol in [(np.zeros_like(times), 'o'), (v_hold, 't'),
                                 (i_hold, 'x'), (v_noise, 't1'),
                                 (i_noise, 'x')]:
                brushes = np.where(np.abs(data) > 1.0, fail_brush, pass_brush)
                plt.plot(times,
                         data,
                         pen=None,
                         symbol=symbol,
                         symbolPen=None,
                         symbolBrush=brushes)

        # automatically select electrode regions
        self.remove_pipettes()
        site_info = self.nwb_handle.parent().info()
        for i in self.channels:
            hs_state = site_info.get('Headstage %d' % i, None)
            if hs_state is None:
                continue
            status = {
                'NS': 'No seal',
                'LS': 'Low seal',
                'GS': 'GOhm seal',
                'TF': 'Technical failure',
            }[hs_state]
            start = (recs[i][0].start_time - start_time).seconds - 1
            stop = (recs[i][-1].start_time - start_time).seconds + 1

            # assume if we got more than two recordings, then a cell was present.
            got_cell = len(recs[i]) > 2

            self.add_pipette(i, start, stop, status=status, got_cell=got_cell)

    def add_pipette(self, channel, start, stop, status=None, got_cell=None):
        elec = PipetteParameter(self,
                                channel,
                                start,
                                stop,
                                status=status,
                                got_cell=got_cell)
        self.params.addChild(elec, autoIncrementName=True)
        elec.child('channel').sigValueChanged.connect(
            self._pipette_channel_changed)
        elec.region.sigRegionChangeFinished.connect(
            self._pipette_region_changed)
        self._pipette_channel_changed(elec.child('channel'))

    def _pipette_channel_changed(self, param):
        plt = self.get_channel_plot(param.value())
        plt.addItem(param.parent().region)
        self._rename_pipettes()

    def _pipette_region_changed(self):
        self._rename_pipettes()

    def _rename_pipettes(self):
        # sort electrodes by channel
        elecs = {}
        for elec in self.params.children():
            elecs.setdefault(elec['channel'], []).append(elec)

        for chan in elecs:
            # sort all electrodes on this channel by start time
            chan_elecs = sorted(elecs[chan],
                                key=lambda e: e.region.getRegion()[0])

            # assign names
            for i, elec in enumerate(chan_elecs):
                # rename all first to avoid name colisions
                elec.setName('rename%d' % i)
            for i, elec in enumerate(chan_elecs):
                # If there are multiple electrodes on this channel, then
                # each extra electrode increments its name by the number of
                # headstages (for example, on AD channel 3, the first electrode
                # is called "Electrode 4", and on an 8-headstage system, the
                # second electrode will be "Electrode 12").
                e_id = (chan + 1) + (i * n_headstages)
                elec.id = e_id
                elec.setName('Pipette %d' % e_id)

    def save(self):
        state = []
        for elec in self.params.children():
            rgn = elec.region.getRegion()
            start = self.start_time + datetime.timedelta(seconds=rgn[0])
            stop = self.start_time + datetime.timedelta(seconds=rgn[1])
            state.append({
                'id': elec.id,
                'status': elec['status'],
                'got_cell': elec['got cell'],
                'channel': elec['channel'],
                'start': start,
                'stop': stop,
            })
        return state
Exemplo n.º 7
0
class ExperimentTimeline(QtGui.QWidget):
    def __init__(self):
        QtGui.QWidget.__init__(self)
        self.channels = None
        self.start_time = None  # starting time according to NWB file
        
        self.layout = QtGui.QGridLayout()
        self.setLayout(self.layout)
        self.layout.setContentsMargins(0, 0, 0, 0)
        
        self.plots = PlotGrid()
        self.plots.set_shape(config.n_headstages, 1)
        self.plots.setXLink(self.plots[0, 0])
        self.layout.addWidget(self.plots, 0, 0)

        self.ptree = pg.parametertree.ParameterTree(showHeader=False)
        self.layout.addWidget(self.ptree, 0, 1)
        self.ptree.setMaximumWidth(250)
        
        self.params = pg.parametertree.Parameter.create(name='params',
            type='group', addText='Add pipette')
        self.params.addNew = self.add_pipette_clicked  # monkey!
        self.ptree.setParameters(self.params, showTop=False)
        
    def list_channels(self):
        return self.channels
        
    def get_channel_plot(self, chan):
        return self.plots[chan, 0]
        
    def add_pipette_clicked(self):
        self.add_pipette(channel=self.channels[0], start=0, stop=500)
        
    def remove_pipettes(self):
        for ch in self.params.children():
            self.params.removeChild(ch)
            ch.region.scene().removeItem(ch.region)
        for i in range(self.plots.shape[0]):
            self.plots[i,0].clear()

    def load_site(self, site_dh):
        """Generate pipette list for this site
        """
        self.remove_pipettes()
        
        # automatically fill pipette fluorophore field
        expt_dh = site_dh.parent().parent()
        expt_info = expt_dh.info()
        dye = expt_info.get('internal_dye', None)
        internal = expt_info.get('internal', None)

        # automatically select electrode regions
        self.channels = list(range(config.n_headstages))
        site_info = site_dh.info()
        for i in self.channels:
            hs_state = site_info.get('Headstage %d'%(i+1), None)
            status = {
                'NS': 'No seal',
                'LS': 'Low seal',
                'GS': 'GOhm seal',
                'TF': 'Technical failure',
                'NA': 'No attempt',
                None: 'Not recorded',                
            }.get(hs_state, hs_state)
            self.add_pipette(i, status=status, internal_dye=dye, internal=internal)
        
    def load_nwb(self, nwb_handle):
        with pg.BusyCursor():
            self._load_nwb(nwb_handle)
        
    def _load_nwb(self, nwb_handle):
        self.nwb_handle = nwb_handle
        self.nwb = MiesNwb(nwb_handle.name())
        
        # load all recordings
        recs = {}
        for srec in self.nwb.contents:
            for chan in srec.devices:
                recs.setdefault(chan, []).append(srec[chan])

        chans = sorted(recs.keys())
        
        # find time of first recording
        start_time = min([rec[0].start_time for rec in recs.values()])
        self.start_time = start_time
        end_time = max([rec[-1].start_time for rec in recs.values()])
        self.plots.setXRange(0, (end_time-start_time).seconds)
        
        # plot all recordings
        for i,chan in enumerate(chans):
            n_recs = len(recs[chan])
            times = np.empty(n_recs)
            i_hold = np.empty(n_recs)
            v_hold = np.empty(n_recs)
            v_noise = np.empty(n_recs)
            i_noise = np.empty(n_recs)
            
            # load QC metrics for all recordings
            for j,rec in enumerate(recs[chan]):
                dt = (rec.start_time - start_time).seconds
                times[j] = dt
                v_hold[j] = rec.baseline_potential
                i_hold[j] = rec.baseline_current
                if rec.clamp_mode == 'vc':
                    v_noise[j] = np.nan
                    i_noise[j] = rec.baseline_rms_noise
                else:
                    v_noise[j] = rec.baseline_rms_noise
                    i_noise[j] = np.nan
                    
            # scale all qc metrics to the range 0-1
            pass_brush = pg.mkBrush(100, 100, 255, 200)
            fail_brush = pg.mkBrush(255, 0, 0, 200)
            v_hold = (v_hold + 60e-3) / 20e-3
            i_hold = i_hold / 400e-12
            v_noise = v_noise / 5e-3
            i_noise = i_noise / 100e-12
            
            plt = self.get_channel_plot(chan)
            plt.setLabels(left=("Ch %d" % chan))
            for data,symbol in [(np.zeros_like(times), 'o'), (v_hold, 't'), (i_hold, 'x'), (v_noise, 't1'), (i_noise, 'x')]:
                brushes = np.where(np.abs(data) > 1.0, fail_brush, pass_brush)
                plt.plot(times, data, pen=None, symbol=symbol, symbolPen=None, symbolBrush=brushes)

        for i in recs.keys():
            start = (recs[i][0].start_time - start_time).seconds - 1
            stop = (recs[i][-1].start_time - start_time).seconds + 1
            pip_param = self.params.child('Pipette %d' % (i+1))
            pip_param.set_time_range(start, stop)
            
            got_data = len(recs[i]) > 2
            pip_param['got data'] = got_data
        
    def add_pipette(self, channel, status=None, **kwds):
        elec = PipetteParameter(self, channel, status=status, **kwds)
        self.params.addChild(elec, autoIncrementName=True)
        elec.child('channel').sigValueChanged.connect(self._pipette_channel_changed)
        elec.region.sigRegionChangeFinished.connect(self._pipette_region_changed)
        self._pipette_channel_changed(elec.child('channel'))
        
    def _pipette_channel_changed(self, param):
        plt = self.get_channel_plot(param.value())
        plt.addItem(param.parent().region)
        self._rename_pipettes()
        
    def _pipette_region_changed(self):
        self._rename_pipettes()
        
    def _rename_pipettes(self):
        # sort electrodes by channel
        elecs = {}
        for elec in self.params.children():
            elecs.setdefault(elec['channel'], []).append(elec)
        
        for chan in elecs:
            # sort all electrodes on this channel by start time
            chan_elecs = sorted(elecs[chan], key=lambda e: e.region.getRegion()[0])
            
            # assign names
            for i,elec in enumerate(chan_elecs):
                # rename all first to avoid name colisions
                elec.setName('rename%d' % i)
            for i,elec in enumerate(chan_elecs):
                # If there are multiple electrodes on this channel, then 
                # each extra electrode increments its name by the number of 
                # headstages (for example, on AD channel 3, the first electrode
                # is called "Electrode 4", and on an 8-headstage system, the
                # second electrode will be "Electrode 12").
                e_id = (chan+1) + (i*config.n_headstages)
                elec.id = e_id
                elec.setName('Pipette %d' % e_id)

    def save(self):
        state = {}
        for elec in self.params.children():
            rgn = elec.region.getRegion()
            if self.start_time is None:
                start = None
                stop = None
            else:
                start = self.start_time + datetime.timedelta(seconds=rgn[0])
                stop = self.start_time + datetime.timedelta(seconds=rgn[1])
            
            state[elec.id] = OrderedDict([
                ('pipette_status', elec['status']),
                ('got_data', elec['got data']),
                ('ad_channel', elec['channel']),
                ('patch_start', start),
                ('patch_stop', stop),
                ('cell_labels', {'biocytin': '', 'red': '', 'green': '', 'blue': ''}),
                #('cell_qc', {'holding': None, 'access': None, 'spiking': None}),
                ('target_layer', elec['target layer']),
                ('morphology', elec['morphology']),
                ('internal_solution', elec['internal']),
                ('internal_dye', elec['internal dye']),
                ('synapse_to', None),
                ('gap_to', None),
                ('notes', ''),
            ])
        return state