def measure_limit(pair, session, classifier): pair_id = pair.experiment.acq_timestamp, pair.pre_cell.ext_id, pair.post_cell.ext_id print(pair_id) amps = strength_analysis.get_amps(session, pair) base_amps = strength_analysis.get_baseline_amps(session, pair, amps=amps, clamp_mode='ic') q = strength_analysis.response_query(session) q = q.join(strength_analysis.PulseResponseStrength) q = q.filter(strength_analysis.PulseResponseStrength.id.in_(amps['id'])) q = q.join(db.MultiPatchProbe) q = q.filter(db.MultiPatchProbe.induction_frequency < 100) fg_recs = q.all() traces = [] deconvs = [] #for rec in fg_recs[:100]: #result = strength_analysis.analyze_response_strength(rec, source='pulse_response', lpf=True, lowpass=2000, #remove_artifacts=False, bsub=True) #trace = result['raw_trace'] #trace.t0 = -result['spike_time'] #trace = trace - np.median(trace.time_slice(-0.5e-3, 0.5e-3).data) #traces.append(trace) #trace_plot.plot(trace.time_values, trace.data, pen=(0, 0, 0, 20)) #trace = result['dec_trace'] #trace.t0 = -result['spike_time'] #trace = trace - np.median(trace.time_slice(-0.5e-3, 0.5e-3).data) #deconvs.append(trace) #deconv_plot.plot(trace.time_values, trace.data, pen=(0, 0, 0, 20)) ## plot average trace #mean = TraceList(traces).mean() #trace_plot.plot(mean.time_values, mean.data, pen={'color':'g', 'width': 2}, shadowPen={'color':'k', 'width': 3}, antialias=True) #mean = TraceList(deconvs).mean() #deconv_plot.plot(mean.time_values, mean.data, pen={'color':'g', 'width': 2}, shadowPen={'color':'k', 'width': 3}, antialias=True) #bins = np.arange(-0.001, 0.015, 0.0005) #field = 'pos_dec_amp' #n = min(len(amps), len(base_amps)) #hist_y, hist_bins = np.histogram(base_amps[:n][field], bins=bins) #hist_plot.plot(hist_bins, hist_y, stepMode=True, pen=None, brush=(200, 0, 0, 150), fillLevel=0) #hist_y, hist_bins = np.histogram(amps[:n][field], bins=bins) #hist_plot.plot(hist_bins, hist_y, stepMode=True, pen='k', brush=(0, 150, 150, 100), fillLevel=0) q = strength_analysis.baseline_query(session) q = q.join(strength_analysis.BaselineResponseStrength) q = q.filter(strength_analysis.BaselineResponseStrength.id.in_(base_amps['id'])) bg_recs = q.all() # measure background connection strength bg_results = [strength_analysis.analyze_response_strength(rec, 'baseline') for rec in bg_recs] bg_results = strength_analysis.str_analysis_result_table(bg_results, bg_recs) # for this example, we use background data to simulate foreground # (but this will be biased due to lack of crosstalk in background data) fg_recs = bg_recs # now measure foreground simulated under different conditions amps = 2e-6 * 2**np.arange(9) amps[0] = 0 rtime = 2e-3 dt = 1 / db.default_sample_rate results = np.empty(len(amps), dtype=[('results', object), ('prediction', float), ('confidence', float), ('traces', object), ('rise_time', float), ('amp', float)]) print(" Simulating synaptic events..") # pool = multiprocessing.Pool(4) limit_entry = DetectionLimit(pair=pair) results = [] avg_conf = [] limit = None for i,amp in enumerate(amps): print("----- %d/%d %0.3g \r" % (i, len(amps), amp),) result = strength_analysis.simulate_connection(fg_recs, bg_results, classifier, amp, rtime) results.append({'amp': amp, 'rise_time': rtime, 'predictions': list(result['predictions']), 'confidence': list(result['confidence'])}) avg_conf.append(result['confidence'].mean()) print(results[-1]) # if we crossed threshold, interpolate to estimate the minimum amplitude # and terminate the loop early if limit is None and i > 0 and avg_conf[-1] > classifier.prob_threshold: a1 = amps[i-1] a2 = amp c1,c2 = avg_conf[-2:] s = (classifier.prob_threshold - c1) / (c2 - c1) limit = a1 + s * (a2 - a1) break limit_entry.simulation_results = results limit_entry.minimum_amplitude = limit session.add(limit_entry) session.commit()
def measure_limit(pair, session, classifier): pair_id = pair.experiment.acq_timestamp, pair.pre_cell.ext_id, pair.post_cell.ext_id print(pair_id) amps = strength_analysis.get_amps(session, pair) base_amps = strength_analysis.get_baseline_amps(session, pair, amps=amps, clamp_mode='ic') q = strength_analysis.response_query(session) q = q.join(strength_analysis.PulseResponseStrength) q = q.filter(strength_analysis.PulseResponseStrength.id.in_(amps['id'])) q = q.join(db.MultiPatchProbe) q = q.filter(db.MultiPatchProbe.induction_frequency < 100) fg_recs = q.all() traces = [] deconvs = [] #for rec in fg_recs[:100]: #result = strength_analysis.analyze_response_strength(rec, source='pulse_response', lpf=True, lowpass=2000, #remove_artifacts=False, bsub=True) #trace = result['raw_trace'] #trace.t0 = -result['spike_time'] #trace = trace - np.median(trace.time_slice(-0.5e-3, 0.5e-3).data) #traces.append(trace) #trace_plot.plot(trace.time_values, trace.data, pen=(0, 0, 0, 20)) #trace = result['dec_trace'] #trace.t0 = -result['spike_time'] #trace = trace - np.median(trace.time_slice(-0.5e-3, 0.5e-3).data) #deconvs.append(trace) #deconv_plot.plot(trace.time_values, trace.data, pen=(0, 0, 0, 20)) ## plot average trace #mean = TSeriesList(traces).mean() #trace_plot.plot(mean.time_values, mean.data, pen={'color':'g', 'width': 2}, shadowPen={'color':'k', 'width': 3}, antialias=True) #mean = TSeriesList(deconvs).mean() #deconv_plot.plot(mean.time_values, mean.data, pen={'color':'g', 'width': 2}, shadowPen={'color':'k', 'width': 3}, antialias=True) #bins = np.arange(-0.001, 0.015, 0.0005) #field = 'pos_dec_amp' #n = min(len(amps), len(base_amps)) #hist_y, hist_bins = np.histogram(base_amps[:n][field], bins=bins) #hist_plot.plot(hist_bins, hist_y, stepMode=True, pen=None, brush=(200, 0, 0, 150), fillLevel=0) #hist_y, hist_bins = np.histogram(amps[:n][field], bins=bins) #hist_plot.plot(hist_bins, hist_y, stepMode=True, pen='k', brush=(0, 150, 150, 100), fillLevel=0) q = strength_analysis.baseline_query(session) q = q.join(strength_analysis.BaselineResponseStrength) q = q.filter( strength_analysis.BaselineResponseStrength.id.in_(base_amps['id'])) bg_recs = q.all() # measure background connection strength bg_results = [ strength_analysis.analyze_response_strength(rec, 'baseline') for rec in bg_recs ] bg_results = strength_analysis.str_analysis_result_table( bg_results, bg_recs) # for this example, we use background data to simulate foreground # (but this will be biased due to lack of crosstalk in background data) fg_recs = bg_recs # now measure foreground simulated under different conditions amps = 2e-6 * 2**np.arange(9) amps[0] = 0 rtime = 2e-3 dt = 1 / db.default_sample_rate results = np.empty(len(amps), dtype=[('results', object), ('prediction', float), ('confidence', float), ('traces', object), ('rise_time', float), ('amp', float)]) print(" Simulating synaptic events..") # pool = multiprocessing.Pool(4) limit_entry = DetectionLimit(pair=pair) results = [] avg_conf = [] limit = None for i, amp in enumerate(amps): print("----- %d/%d %0.3g \r" % (i, len(amps), amp), ) result = strength_analysis.simulate_connection(fg_recs, bg_results, classifier, amp, rtime) results.append({ 'amp': amp, 'rise_time': rtime, 'predictions': list(result['predictions']), 'confidence': list(result['confidence']) }) avg_conf.append(result['confidence'].mean()) print(results[-1]) # if we crossed threshold, interpolate to estimate the minimum amplitude # and terminate the loop early if limit is None and i > 0 and avg_conf[-1] > classifier.prob_threshold: a1 = amps[i - 1] a2 = amp c1, c2 = avg_conf[-2:] s = (classifier.prob_threshold - c1) / (c2 - c1) limit = a1 + s * (a2 - a1) break limit_entry.simulation_results = results limit_entry.minimum_amplitude = limit session.add(limit_entry) session.commit()
def add_connection_plots(i, name, timestamp, pre_id, post_id): global session, win, filtered p = pg.debug.Profiler(disabled=True, delayed=False) trace_plot = win.addPlot(i, 1) trace_plots.append(trace_plot) deconv_plot = win.addPlot(i, 2) deconv_plots.append(deconv_plot) hist_plot = win.addPlot(i, 3) hist_plots.append(hist_plot) limit_plot = win.addPlot(i, 4) limit_plot.addLegend() limit_plot.setLogMode(True, True) # Find this connection in the pair list idx = np.argwhere((abs(filtered['acq_timestamp'] - timestamp) < 1) & (filtered['pre_cell_id'] == pre_id) & (filtered['post_cell_id'] == post_id)) if idx.size == 0: print("not in filtered connections") return idx = idx[0,0] p() # Mark the point in scatter plot scatter_plot.plot([background[idx]], [signal[idx]], pen='k', symbol='o', size=10, symbolBrush='r', symbolPen=None) # Plot example traces and histograms for plts in [trace_plots, deconv_plots]: plt = plts[-1] plt.setXLink(plts[0]) plt.setYLink(plts[0]) plt.setXRange(-10e-3, 17e-3, padding=0) plt.hideAxis('left') plt.hideAxis('bottom') plt.addLine(x=0) plt.setDownsampling(auto=True, mode='peak') plt.setClipToView(True) hbar = pg.QtGui.QGraphicsLineItem(0, 0, 2e-3, 0) hbar.setPen(pg.mkPen(color='k', width=5)) plt.addItem(hbar) vbar = pg.QtGui.QGraphicsLineItem(0, 0, 0, 100e-6) vbar.setPen(pg.mkPen(color='k', width=5)) plt.addItem(vbar) hist_plot.setXLink(hist_plots[0]) pair = session.query(db.Pair).filter(db.Pair.id==filtered[idx]['pair_id']).all()[0] p() amps = strength_analysis.get_amps(session, pair) p() base_amps = strength_analysis.get_baseline_amps(session, pair) p() q = strength_analysis.response_query(session) p() q = q.join(strength_analysis.PulseResponseStrength) q = q.filter(strength_analysis.PulseResponseStrength.id.in_(amps['id'])) q = q.join(db.Recording, db.Recording.id==db.PulseResponse.recording_id).join(db.PatchClampRecording).join(db.MultiPatchProbe) q = q.filter(db.MultiPatchProbe.induction_frequency < 100) # pre_cell = db.aliased(db.Cell) # post_cell = db.aliased(db.Cell) # q = q.join(db.Pair).join(db.Experiment).join(pre_cell, db.Pair.pre_cell_id==pre_cell.id).join(post_cell, db.Pair.post_cell_id==post_cell.id) # q = q.filter(db.Experiment.id==filtered[idx]['experiment_id']) # q = q.filter(pre_cell.ext_id==pre_id) # q = q.filter(post_cell.ext_id==post_id) fg_recs = q.all() p() traces = [] deconvs = [] for rec in fg_recs[:100]: result = strength_analysis.analyze_response_strength(rec, source='pulse_response', lpf=True, lowpass=2000, remove_artifacts=False, bsub=True) trace = result['raw_trace'] trace.t0 = -result['spike_time'] trace = trace - np.median(trace.time_slice(-0.5e-3, 0.5e-3).data) traces.append(trace) trace_plot.plot(trace.time_values, trace.data, pen=(0, 0, 0, 20)) trace = result['dec_trace'] trace.t0 = -result['spike_time'] trace = trace - np.median(trace.time_slice(-0.5e-3, 0.5e-3).data) deconvs.append(trace) deconv_plot.plot(trace.time_values, trace.data, pen=(0, 0, 0, 20)) # plot average trace mean = TraceList(traces).mean() trace_plot.plot(mean.time_values, mean.data, pen={'color':'g', 'width': 2}, shadowPen={'color':'k', 'width': 3}, antialias=True) mean = TraceList(deconvs).mean() deconv_plot.plot(mean.time_values, mean.data, pen={'color':'g', 'width': 2}, shadowPen={'color':'k', 'width': 3}, antialias=True) # add label label = pg.LabelItem(name) label.setParentItem(trace_plot) p("analyze_response_strength") # bins = np.arange(-0.0005, 0.002, 0.0001) # field = 'pos_amp' bins = np.arange(-0.001, 0.015, 0.0005) field = 'pos_dec_amp' n = min(len(amps), len(base_amps)) hist_y, hist_bins = np.histogram(base_amps[:n][field], bins=bins) hist_plot.plot(hist_bins, hist_y, stepMode=True, pen=None, brush=(200, 0, 0, 150), fillLevel=0) hist_y, hist_bins = np.histogram(amps[:n][field], bins=bins) hist_plot.plot(hist_bins, hist_y, stepMode=True, pen='k', brush=(0, 150, 150, 100), fillLevel=0) p() pg.QtGui.QApplication.processEvents() # Plot detectability analysis q = strength_analysis.baseline_query(session) q = q.join(strength_analysis.BaselineResponseStrength) q = q.filter(strength_analysis.BaselineResponseStrength.id.in_(base_amps['id'])) # q = q.limit(100) bg_recs = q.all() def clicked(sp, pts): traces = pts[0].data()['traces'] print([t.amp for t in traces]) plt = pg.plot() bsub = [t.copy(data=t.data - np.median(t.time_slice(0, 1e-3).data)) for t in traces] for t in bsub: plt.plot(t.time_values, t.data, pen=(0, 0, 0, 50)) mean = TraceList(bsub).mean() plt.plot(mean.time_values, mean.data, pen='g') # first measure background a few times N = len(fg_recs) N = 50 # temporary for testing print("Testing %d trials" % N) bg_results = [] M = 500 print(" Grinding on %d background trials" % len(bg_recs)) for i in range(M): amps = base_amps.copy() np.random.shuffle(amps) bg_results.append(np.median(amps[:N]['pos_dec_amp']) / np.std(amps[:N]['pos_dec_latency'])) print(" %d/%d \r" % (i, M),) print(" done. ") print(" ", bg_results) # now measure foreground simulated under different conditions amps = 5e-6 * 2**np.arange(6) amps[0] = 0 rtimes = 1e-3 * 1.71**np.arange(4) dt = 1 / db.default_sample_rate results = np.empty((len(amps), len(rtimes)), dtype=[('pos_dec_amp', float), ('latency_stdev', float), ('result', float), ('percentile', float), ('traces', object)]) print(" Simulating synaptic events..") for j,rtime in enumerate(rtimes): for i,amp in enumerate(amps): trial_results = [] t = np.arange(0, 15e-3, dt) template = Psp.psp_func(t, xoffset=0, yoffset=0, rise_time=rtime, decay_tau=15e-3, amp=1, rise_power=2) for l in range(20): print(" %d/%d %d/%d \r" % (i,len(amps),j,len(rtimes)),) r_amps = amp * 2**np.random.normal(size=N, scale=0.5) r_latency = np.random.normal(size=N, scale=600e-6, loc=12.5e-3) fg_results = [] traces = [] np.random.shuffle(bg_recs) for k,rec in enumerate(bg_recs[:N]): data = rec.data.copy() start = int(r_latency[k] / dt) length = len(rec.data) - start rec.data[start:] += template[:length] * r_amps[k] fg_result = strength_analysis.analyze_response_strength(rec, 'baseline') fg_results.append((fg_result['pos_dec_amp'], fg_result['pos_dec_latency'])) traces.append(Trace(rec.data.copy(), dt=dt)) traces[-1].amp = r_amps[k] rec.data[:] = data # can't modify rec, so we have to muck with the array (and clean up afterward) instead fg_amp = np.array([r[0] for r in fg_results]) fg_latency = np.array([r[1] for r in fg_results]) trial_results.append(np.median(fg_amp) / np.std(fg_latency)) results[i,j]['result'] = np.median(trial_results) / np.median(bg_results) results[i,j]['percentile'] = stats.percentileofscore(bg_results, results[i,j]['result']) results[i,j]['traces'] = traces assert all(np.isfinite(results[i]['pos_dec_amp'])) print(i, results[i]['result']) print(i, results[i]['percentile']) # c = limit_plot.plot(rtimes, results[i]['result'], pen=(i, len(amps)*1.3), symbol='o', antialias=True, name="%duV"%(amp*1e6), data=results[i], symbolSize=4) # c.scatter.sigClicked.connect(clicked) # pg.QtGui.QApplication.processEvents() c = limit_plot.plot(amps, results[:,j]['result'], pen=(j, len(rtimes)*1.3), symbol='o', antialias=True, name="%dus"%(rtime*1e6), data=results[:,j], symbolSize=4) c.scatter.sigClicked.connect(clicked) pg.QtGui.QApplication.processEvents() pg.QtGui.QApplication.processEvents()
def add_connection_plots(i, name, timestamp, pre_id, post_id): global session, win, filtered p = pg.debug.Profiler(disabled=True, delayed=False) trace_plot = win.addPlot(i, 1) trace_plots.append(trace_plot) trace_plot.setYRange(-1.4e-3, 2.1e-3) # deconv_plot = win.addPlot(i, 2) # deconv_plots.append(deconv_plot) # deconv_plot.hide() hist_plot = win.addPlot(i, 2) hist_plots.append(hist_plot) limit_plot = win.addPlot(i, 3) limit_plot.addLegend() limit_plot.setLogMode(True, False) limit_plot.addLine(y=classifier.prob_threshold) # Find this connection in the pair list idx = np.argwhere((abs(filtered['acq_timestamp'] - timestamp) < 1) & (filtered['pre_cell_id'] == pre_id) & (filtered['post_cell_id'] == post_id)) if idx.size == 0: print("not in filtered connections") return idx = idx[0, 0] p() # Mark the point in scatter plot scatter_plot.plot([background[idx]], [signal[idx]], pen='k', symbol='o', size=10, symbolBrush='r', symbolPen=None) # Plot example traces and histograms for plts in [trace_plots]: #, deconv_plots]: plt = plts[-1] plt.setXLink(plts[0]) plt.setYLink(plts[0]) plt.setXRange(-10e-3, 17e-3, padding=0) plt.hideAxis('left') plt.hideAxis('bottom') plt.addLine(x=0) plt.setDownsampling(auto=True, mode='peak') plt.setClipToView(True) hbar = pg.QtGui.QGraphicsLineItem(0, 0, 2e-3, 0) hbar.setPen(pg.mkPen(color='k', width=5)) plt.addItem(hbar) vbar = pg.QtGui.QGraphicsLineItem(0, 0, 0, 100e-6) vbar.setPen(pg.mkPen(color='k', width=5)) plt.addItem(vbar) hist_plot.setXLink(hist_plots[0]) pair = session.query( db.Pair).filter(db.Pair.id == filtered[idx]['pair_id']).all()[0] p() amps = strength_analysis.get_amps(session, pair) p() base_amps = strength_analysis.get_baseline_amps(session, pair, amps=amps, clamp_mode='ic') p() q = strength_analysis.response_query(session) p() q = q.join(strength_analysis.PulseResponseStrength) q = q.filter(strength_analysis.PulseResponseStrength.id.in_( amps['id'])) q = q.join(db.MultiPatchProbe) q = q.filter(db.MultiPatchProbe.induction_frequency < 100) # pre_cell = db.aliased(db.Cell) # post_cell = db.aliased(db.Cell) # q = q.join(db.Pair).join(db.Experiment).join(pre_cell, db.Pair.pre_cell_id==pre_cell.id).join(post_cell, db.Pair.post_cell_id==post_cell.id) # q = q.filter(db.Experiment.id==filtered[idx]['experiment_id']) # q = q.filter(pre_cell.ext_id==pre_id) # q = q.filter(post_cell.ext_id==post_id) fg_recs = q.all() p() traces = [] deconvs = [] for i, rec in enumerate(fg_recs[:100]): result = strength_analysis.analyze_response_strength( rec, source='pulse_response', lpf=True, lowpass=2000, remove_artifacts=False, bsub=True) trace = result['raw_trace'] trace.t0 = -result['spike_time'] trace = trace - np.median(trace.time_slice(-0.5e-3, 0.5e-3).data) traces.append(trace) trace_plot.plot(trace.time_values, trace.data, pen=(0, 0, 0, 20)) write_csv( csv_file, trace, "Figure 3B; {name}; trace {trace_n}".format(name=name, trace_n=i)) # trace = result['dec_trace'] # trace.t0 = -result['spike_time'] # trace = trace - np.median(trace.time_slice(-0.5e-3, 0.5e-3).data) # deconvs.append(trace) # # deconv_plot.plot(trace.time_values, trace.data, pen=(0, 0, 0, 20)) # plot average trace mean = TSeriesList(traces).mean() trace_plot.plot(mean.time_values, mean.data, pen={ 'color': 'g', 'width': 2 }, shadowPen={ 'color': 'k', 'width': 3 }, antialias=True) write_csv(csv_file, mean, "Figure 3B; {name}; average".format(name=name)) # mean = TSeriesList(deconvs).mean() # # deconv_plot.plot(mean.time_values, mean.data, pen={'color':'g', 'width': 2}, shadowPen={'color':'k', 'width': 3}, antialias=True) # add label label = pg.LabelItem(name) label.setParentItem(trace_plot) p("analyze_response_strength") # bins = np.arange(-0.0005, 0.002, 0.0001) # field = 'pos_amp' bins = np.arange(-0.001, 0.015, 0.0005) field = 'pos_dec_amp' n = min(len(amps), len(base_amps)) hist_y, hist_bins = np.histogram(base_amps[:n][field], bins=bins) hist_plot.plot(hist_bins, hist_y, stepMode=True, pen=None, brush=(200, 0, 0, 150), fillLevel=0) write_csv( csv_file, hist_bins, "Figure 3C; {name}; background noise amplitude distribution bin edges (V)" .format(name=name)) write_csv( csv_file, hist_y, "Figure 3C; {name}; background noise amplitude distribution counts per bin" .format(name=name)) hist_y, hist_bins = np.histogram(amps[:n][field], bins=bins) hist_plot.plot(hist_bins, hist_y, stepMode=True, pen='k', brush=(0, 150, 150, 100), fillLevel=0) write_csv( csv_file, hist_bins, "Figure 3C; {name}; PSP amplitude distribution bin edges (V)". format(name=name)) write_csv( csv_file, hist_y, "Figure 3C; {name}; PSP amplitude distribution counts per bin". format(name=name)) p() pg.QtGui.QApplication.processEvents() # Plot detectability analysis q = strength_analysis.baseline_query(session) q = q.join(strength_analysis.BaselineResponseStrength) q = q.filter( strength_analysis.BaselineResponseStrength.id.in_(base_amps['id'])) # q = q.limit(100) bg_recs = q.all() def clicked(sp, pts): data = pts[0].data() print("-----------------------\nclicked:", data['rise_time'], data['amp'], data['prediction'], data['confidence']) for r in data['results']: print({k: r[k] for k in classifier.features}) traces = data['traces'] plt = pg.plot() bsub = [ t.copy(data=t.data - np.median(t.time_slice(0, 1e-3).data)) for t in traces ] for t in bsub: plt.plot(t.time_values, t.data, pen=(0, 0, 0, 50)) mean = TSeriesList(bsub).mean() plt.plot(mean.time_values, mean.data, pen='g') # def analyze_response_strength(recs, source, dtype): # results = [] # for i,rec in enumerate(recs): # result = strength_analysis.analyze_response_strength(rec, source) # results.append(result) # return str_analysis_result_table(results) # measure background connection strength bg_results = [ strength_analysis.analyze_response_strength(rec, 'baseline') for rec in bg_recs ] bg_results = strength_analysis.str_analysis_result_table( bg_results, bg_recs) # for this example, we use background data to simulate foreground # (but this will be biased due to lack of crosstalk in background data) fg_recs = bg_recs # now measure foreground simulated under different conditions amps = 2e-6 * 2**np.arange(9) amps[0] = 0 rtimes = [1e-3, 2e-3, 4e-3, 6e-3] dt = 1 / db.default_sample_rate results = np.empty((len(amps), len(rtimes)), dtype=[('results', object), ('predictions', object), ('confidence', object), ('traces', object), ('rise_time', float), ('amp', float)]) print(" Simulating synaptic events..") cachefile = 'fig_3_cache.pkl' if os.path.exists(cachefile): cache = pickle.load(open(cachefile, 'rb')) else: cache = {} pair_key = (timestamp, pre_id, post_id) pair_cache = cache.setdefault(pair_key, {}) for j, rtime in enumerate(rtimes): new_results = False for i, amp in enumerate(amps): print( "--------------------------------------- %d/%d %d/%d \r" % (i, len(amps), j, len(rtimes)), ) result = pair_cache.get((rtime, amp)) if result is None: result = strength_analysis.simulate_connection( fg_recs, bg_results, classifier, amp, rtime) pair_cache[rtime, amp] = result new_results = True for k, v in result.items(): results[i, j][k] = v x, y = amps, [np.mean(x) for x in results[:, j]['confidence']] c = limit_plot.plot(x, y, pen=pg.intColor(j, len(rtimes) * 1.3, maxValue=150), symbol='o', antialias=True, name="%dus" % (rtime * 1e6), data=results[:, j], symbolSize=4) write_csv( csv_file, x, "Figure 3D; {name}; {rise_time:0.3g} ms rise time; simulated PSP amplitude (V)" .format(name=name, rise_time=rtime * 1000)) write_csv( csv_file, y, "Figure 3D; {name}; {rise_time:0.3g} ms rise time; classifier decision probability" .format(name=name, rise_time=rtime * 1000)) c.scatter.sigClicked.connect(clicked) pg.QtGui.QApplication.processEvents() if new_results: pickle.dump(cache, open(cachefile, 'wb')) pg.QtGui.QApplication.processEvents()
def add_connection_plots(i, name, timestamp, pre_id, post_id): global session, win, filtered p = pg.debug.Profiler(disabled=True, delayed=False) trace_plot = win.addPlot(i, 1) trace_plots.append(trace_plot) trace_plot.setYRange(-1.4e-3, 2.1e-3) # deconv_plot = win.addPlot(i, 2) # deconv_plots.append(deconv_plot) # deconv_plot.hide() hist_plot = win.addPlot(i, 2) hist_plots.append(hist_plot) limit_plot = win.addPlot(i, 3) limit_plot.addLegend() limit_plot.setLogMode(True, False) limit_plot.addLine(y=classifier.prob_threshold) # Find this connection in the pair list idx = np.argwhere((abs(filtered['acq_timestamp'] - timestamp) < 1) & (filtered['pre_cell_id'] == pre_id) & (filtered['post_cell_id'] == post_id)) if idx.size == 0: print("not in filtered connections") return idx = idx[0,0] p() # Mark the point in scatter plot scatter_plot.plot([background[idx]], [signal[idx]], pen='k', symbol='o', size=10, symbolBrush='r', symbolPen=None) # Plot example traces and histograms for plts in [trace_plots]:#, deconv_plots]: plt = plts[-1] plt.setXLink(plts[0]) plt.setYLink(plts[0]) plt.setXRange(-10e-3, 17e-3, padding=0) plt.hideAxis('left') plt.hideAxis('bottom') plt.addLine(x=0) plt.setDownsampling(auto=True, mode='peak') plt.setClipToView(True) hbar = pg.QtGui.QGraphicsLineItem(0, 0, 2e-3, 0) hbar.setPen(pg.mkPen(color='k', width=5)) plt.addItem(hbar) vbar = pg.QtGui.QGraphicsLineItem(0, 0, 0, 100e-6) vbar.setPen(pg.mkPen(color='k', width=5)) plt.addItem(vbar) hist_plot.setXLink(hist_plots[0]) pair = session.query(db.Pair).filter(db.Pair.id==filtered[idx]['pair_id']).all()[0] p() amps = strength_analysis.get_amps(session, pair) p() base_amps = strength_analysis.get_baseline_amps(session, pair, amps=amps, clamp_mode='ic') p() q = strength_analysis.response_query(session) p() q = q.join(strength_analysis.PulseResponseStrength) q = q.filter(strength_analysis.PulseResponseStrength.id.in_(amps['id'])) q = q.join(db.MultiPatchProbe) q = q.filter(db.MultiPatchProbe.induction_frequency < 100) # pre_cell = db.aliased(db.Cell) # post_cell = db.aliased(db.Cell) # q = q.join(db.Pair).join(db.Experiment).join(pre_cell, db.Pair.pre_cell_id==pre_cell.id).join(post_cell, db.Pair.post_cell_id==post_cell.id) # q = q.filter(db.Experiment.id==filtered[idx]['experiment_id']) # q = q.filter(pre_cell.ext_id==pre_id) # q = q.filter(post_cell.ext_id==post_id) fg_recs = q.all() p() traces = [] deconvs = [] for i,rec in enumerate(fg_recs[:100]): result = strength_analysis.analyze_response_strength(rec, source='pulse_response', lpf=True, lowpass=2000, remove_artifacts=False, bsub=True) trace = result['raw_trace'] trace.t0 = -result['spike_time'] trace = trace - np.median(trace.time_slice(-0.5e-3, 0.5e-3).data) traces.append(trace) trace_plot.plot(trace.time_values, trace.data, pen=(0, 0, 0, 20)) write_csv(csv_file, trace, "Figure 3B; {name}; trace {trace_n}".format(name=name, trace_n=i)) # trace = result['dec_trace'] # trace.t0 = -result['spike_time'] # trace = trace - np.median(trace.time_slice(-0.5e-3, 0.5e-3).data) # deconvs.append(trace) # # deconv_plot.plot(trace.time_values, trace.data, pen=(0, 0, 0, 20)) # plot average trace mean = TraceList(traces).mean() trace_plot.plot(mean.time_values, mean.data, pen={'color':'g', 'width': 2}, shadowPen={'color':'k', 'width': 3}, antialias=True) write_csv(csv_file, mean, "Figure 3B; {name}; average".format(name=name)) # mean = TraceList(deconvs).mean() # # deconv_plot.plot(mean.time_values, mean.data, pen={'color':'g', 'width': 2}, shadowPen={'color':'k', 'width': 3}, antialias=True) # add label label = pg.LabelItem(name) label.setParentItem(trace_plot) p("analyze_response_strength") # bins = np.arange(-0.0005, 0.002, 0.0001) # field = 'pos_amp' bins = np.arange(-0.001, 0.015, 0.0005) field = 'pos_dec_amp' n = min(len(amps), len(base_amps)) hist_y, hist_bins = np.histogram(base_amps[:n][field], bins=bins) hist_plot.plot(hist_bins, hist_y, stepMode=True, pen=None, brush=(200, 0, 0, 150), fillLevel=0) write_csv(csv_file, hist_bins, "Figure 3C; {name}; background noise amplitude distribution bin edges (V)".format(name=name)) write_csv(csv_file, hist_y, "Figure 3C; {name}; background noise amplitude distribution counts per bin".format(name=name)) hist_y, hist_bins = np.histogram(amps[:n][field], bins=bins) hist_plot.plot(hist_bins, hist_y, stepMode=True, pen='k', brush=(0, 150, 150, 100), fillLevel=0) write_csv(csv_file, hist_bins, "Figure 3C; {name}; PSP amplitude distribution bin edges (V)".format(name=name)) write_csv(csv_file, hist_y, "Figure 3C; {name}; PSP amplitude distribution counts per bin".format(name=name)) p() pg.QtGui.QApplication.processEvents() # Plot detectability analysis q = strength_analysis.baseline_query(session) q = q.join(strength_analysis.BaselineResponseStrength) q = q.filter(strength_analysis.BaselineResponseStrength.id.in_(base_amps['id'])) # q = q.limit(100) bg_recs = q.all() def clicked(sp, pts): data = pts[0].data() print("-----------------------\nclicked:", data['rise_time'], data['amp'], data['prediction'], data['confidence']) for r in data['results']: print({k:r[k] for k in classifier.features}) traces = data['traces'] plt = pg.plot() bsub = [t.copy(data=t.data - np.median(t.time_slice(0, 1e-3).data)) for t in traces] for t in bsub: plt.plot(t.time_values, t.data, pen=(0, 0, 0, 50)) mean = TraceList(bsub).mean() plt.plot(mean.time_values, mean.data, pen='g') # def analyze_response_strength(recs, source, dtype): # results = [] # for i,rec in enumerate(recs): # result = strength_analysis.analyze_response_strength(rec, source) # results.append(result) # return str_analysis_result_table(results) # measure background connection strength bg_results = [strength_analysis.analyze_response_strength(rec, 'baseline') for rec in bg_recs] bg_results = strength_analysis.str_analysis_result_table(bg_results, bg_recs) # for this example, we use background data to simulate foreground # (but this will be biased due to lack of crosstalk in background data) fg_recs = bg_recs # now measure foreground simulated under different conditions amps = 2e-6 * 2**np.arange(9) amps[0] = 0 rtimes = [1e-3, 2e-3, 4e-3, 6e-3] dt = 1 / db.default_sample_rate results = np.empty((len(amps), len(rtimes)), dtype=[('results', object), ('predictions', object), ('confidence', object), ('traces', object), ('rise_time', float), ('amp', float)]) print(" Simulating synaptic events..") cachefile = 'fig_3_cache.pkl' if os.path.exists(cachefile): cache = pickle.load(open(cachefile, 'rb')) else: cache = {} pair_key = (timestamp, pre_id, post_id) pair_cache = cache.setdefault(pair_key, {}) for j,rtime in enumerate(rtimes): new_results = False for i,amp in enumerate(amps): print("--------------------------------------- %d/%d %d/%d \r" % (i,len(amps),j,len(rtimes)),) result = pair_cache.get((rtime, amp)) if result is None: result = strength_analysis.simulate_connection(fg_recs, bg_results, classifier, amp, rtime) pair_cache[rtime, amp] = result new_results = True for k,v in result.items(): results[i,j][k] = v x, y = amps, [np.mean(x) for x in results[:,j]['confidence']] c = limit_plot.plot(x, y, pen=pg.intColor(j, len(rtimes)*1.3, maxValue=150), symbol='o', antialias=True, name="%dus"%(rtime*1e6), data=results[:,j], symbolSize=4) write_csv(csv_file, x, "Figure 3D; {name}; {rise_time:0.3g} ms rise time; simulated PSP amplitude (V)".format(name=name, rise_time=rtime*1000)) write_csv(csv_file, y, "Figure 3D; {name}; {rise_time:0.3g} ms rise time; classifier decision probability".format(name=name, rise_time=rtime*1000)) c.scatter.sigClicked.connect(clicked) pg.QtGui.QApplication.processEvents() if new_results: pickle.dump(cache, open(cachefile, 'wb')) pg.QtGui.QApplication.processEvents()