def plot_onedot(results, ds=None, verbose=2, fig=100, linecolor='c', ims=None, extentImageMatlab=None, lv=None): """ Plot results of a barrier-barrier scan of a single dot Args: results (dict): results of the onedotGetBalance function ds (None or DataSet): dataset to use for plotting fig (int or None): figure window to plot to """ if ds is None: ds = qtt.data.get_dataset(results) if fig is not None: _plot_dataset(ds, fig) if verbose >= 2: pgeometry.plotPoints(results['balancefit'], '--', color=linecolor, linewidth=2, label='balancefit') if verbose >= 2: pgeometry.plotPoints(results['balancepoint0'], '.r', markersize=13, label='balancepoint0') pgeometry.plotPoints(results['balancepoint'], '.m', markersize=17, label='balancepoint') if ims is not None: qtt.utilities.tools.showImage(ims, extentImageMatlab, fig=fig + 1) # XX plt.axis('image') plt.title('Smoothed image') pgeometry.plotPoints(results['balancepoint'], '.m', markersize=16, label='balancepoint') qtt.utilities.tools.showImage(ims > lv, None, fig=fig + 2) pgeometry.plotPoints(results['balancefitpixel'], '--c', markersize=16, label='balancefit') pgeometry.plotLabels(results['balancefitpixel']) plt.axis('image') plt.title('thresholded area') if verbose >= 2: qq = ims.flatten() plt.figure(fig + 3) plt.clf() plt.hist(qq, 20) plot2Dline([-1, 0, np.percentile(ims, 1)], '--m', label='percentile 1') plot2Dline([-1, 0, np.percentile(ims, 2)], '--m', label='percentile 2') plot2Dline([-1, 0, np.percentile(ims, 99)], '--m', label='percentile 99') plot2Dline([-1, 0, lv], '--r', linewidth=2, label='lv') plt.legend(numpoints=1) plt.title('Histogram of image intensities') plt.xlabel('Image (smoothed) values')
def onedotGetBalance(dataset, verbose=1, fig=None, drawpoly=False, polylinewidth=2, linecolor='c', full_output=False, od=None): """ Determine tuning point from a 2D scan of a 1-dot This function performs a simple fitting of the open (conducting region). Args: od (one-dot structure or None): data for one-dot dd (2D dataset): data containing charge stability diagram Returns: fitresults (dict): dictionary with fitting results od (obj): modified one-dot object """ if od is not None: warnings.warn('od argument will be removed in the future', DeprecationWarning) extentscan, g0, g2, vstep, vsweep, arrayname = dataset2Dmetadata( dataset, arrayname=None) im, tr = qtt.data.dataset2image(dataset) extentImageMatlab = tr.matplotlib_image_extent() ims = im.copy() # simlpy smoothing of the image kk = np.ones((3, 3)) / 9. for ii in range(2): ims = scipy.ndimage.convolve(ims, kk, mode='nearest', cval=0.0) r = np.percentile(ims, 99) - np.percentile(ims, 1) lv = np.percentile(ims, 2) + r / 100 x = ims.flatten() lvstd = np.std(x[x < lv]) lv = lv + lvstd / 2 # works for very smooth images lv = (.45 * pgeometry.otsu(ims) + .55 * lv) # more robust if verbose >= 2: print('onedotGetBalance: threshold for low value %.1f' % lv) # balance point: method 1 (first point above threshold of 45 degree line) try: ww = np.nonzero(ims > lv) zz = -ww[0] + ww[1] idx = zz.argmin() pt = np.array([[ww[1][idx]], [ww[0][idx]]]) ptv = tr.pixel2scan(pt) except: print('qutechtnotools: error in onedotGetBalance: please debug') idx = 0 pt = np.array([[int(vstep.size / 2)], [int(vsweep.size / 2)]]) ptv = np.array([[vstep[pt[0, 0]]], [vsweep[-pt[1, 0]]]]) pass # balance point: method 2 (fit quadrilateral) wwarea = ims > lv x0 = np.array( [pt[0] - .1 * im.shape[1], pt[1] + .1 * im.shape[0], pt[0], pt[1]]).reshape(4, ) # initial square ff = lambda x: costscoreOD(x[0], x[1], x[2:4], wwarea) # scipy.optimize.show_options(method='Nelder-Mead') opts = dict({'disp': verbose >= 2, 'fatol': 1e-6, 'xatol': 1e-5}) powell_opts = dict({'disp': verbose >= 2, 'ftol': 1e-6, 'xtol': 1e-5}) xx = scipy.optimize.minimize(ff, x0, method='Nelder-Mead', options=opts) # print(' optimize: %f->%f' % (ff(x0), ff(xx.x)) ) opts['disp'] = verbose >= 2 xx = scipy.optimize.minimize(ff, xx.x, method='Powell', options=powell_opts) x = xx.x cost, pts, imx = costscoreOD(x0[0], x0[1], x0[2:4], wwarea, output=True) balancefitpixel0 = pts.reshape((-1, 2)).T.copy() cost, pts, imx = costscoreOD(x[0], x[1], x[2:4], wwarea, output=True) pt = pts[1, :, :].transpose() fitresults = {} fitresults['balancepoint0'] = ptv fitresults['balancepointpixel'] = pt fitresults['balancepointpolygon'] = tr.pixel2scan(pt) fitresults['balancepoint'] = tr.pixel2scan(pt) fitresults['balancefitpixel'] = pts.reshape((-1, 2)).T.copy() fitresults['balancefit'] = tr.pixel2scan(fitresults['balancefitpixel']) fitresults['balancefit1'] = tr.pixel2scan(balancefitpixel0) fitresults['setpoint'] = fitresults['balancepoint'] + 8 fitresults['x0'] = x0 fitresults['gatevalues'] = dataset.metadata.get('allgatevalues', None) if od is not None: fitresults['gatevalues'][od['gates'][2]] = float( fitresults['balancepoint'][0]) fitresults['gatevalues'][od['gates'][0]] = float( fitresults['balancepoint'][1]) ptv = fitresults['balancepoint'] if od is not None: # copy results into od structure for k in fitresults: od[k] = fitresults[k] od['onedotbalance'] = fitresults odname = od['name'] else: odname = 'one-dot' if verbose: print('onedotGetBalance %s: balance point 0 at: %.1f %.1f [mV]' % (odname, ptv[0, 0], ptv[1, 0])) print('onedotGetBalance: balance point at: %.1f %.1f [mV]' % (fitresults['balancepoint'][0, 0], fitresults['balancepoint'][1, 0])) if verbose >= 3: #% plt.figure(9) plt.clf() plt.imshow(im, interpolation='nearest') pgeometry.plotPoints(balancefitpixel0, '.-r', label='balancefitpixel0') pgeometry.plotLabels(balancefitpixel0) pgeometry.plotPoints(fitresults['balancefitpixel'], '.-m') pgeometry.plotLabels(fitresults['balancefitpixel']) cost, pts, imx = costscoreOD(x[0], x[1], x[2:4], wwarea, output=True, verbose=1) #% if fig is not None: plot_onedot(fitresults, ds=dataset, verbose=2, fig=100, linecolor='c', ims=ims, extentImageMatlab=extentImageMatlab, lv=lv) qtt.utilities.tools.showImage(im, extentImageMatlab, fig=fig) if verbose >= 2 or drawpoly: pgeometry.plotPoints(fitresults['balancefit'], '--', color=linecolor, linewidth=polylinewidth, label='balancefit') if verbose >= 2: pgeometry.plotPoints(fitresults['balancepoint0'], '.r', markersize=13, label='balancepoint0') pgeometry.plotPoints(fitresults['balancepoint'], '.m', markersize=17, label='balancepoint') plt.axis('image') if full_output: fitresults['ims'] = ims fitresults['lv'] = lv fitresults['wwarea'] = wwarea return fitresults, ptv
def evaluateCross(param, im, verbose=0, fig=None, istep=1, istepmodel=1, linewidth=2, usemask=False, use_abs=False, w=2.5): """ Calculate cross matching score Args: param (array or list): used by createCross to create image template im (numpy array): Returns: cost, patch, cdata, tuple See also: createCross """ samplesize = [int(im.shape[1] * istep / istepmodel), int(im.shape[0] * istep / istepmodel)] param = np.array(param) aa = param[3:] H = evaluateCross.scaling0.copy() H[0, 0] = istep / istepmodel H[1, 1] = istep / istepmodel dsize = (samplesize[0], samplesize[1]) patch = cv2.warpPerspective(im.astype(np.float32), H, dsize, None, (cv2.INTER_LINEAR), cv2.BORDER_CONSTANT, -1) if verbose: print('evaluateCross: patch shape %s' % (patch.shape,)) modelpatch, cdata = createCross(param, samplesize, centermodel=False, istep=istepmodel, verbose=verbose >= 2, w=w) (cc, lp, hp, ip, op, _, _, _) = cdata if use_abs: dd = np.abs(patch) - modelpatch else: dd = patch - modelpatch if usemask: # near model mask #mask = (modelpatch>1).astype(int) # distance centre mask imtmp = 10 + 0 * modelpatch.copy() imtmp[int(imtmp.shape[1] / 2), int(imtmp.shape[0] / 2)] = 0 mask = scipy.ndimage.distance_transform_edt(imtmp) mask = 1 - .75 * mask / mask.max() dd = dd * mask cost = np.linalg.norm(dd) # area of intersection rr = np.array([[0., im.shape[1]], [0, im.shape[0]]]) ppx = pgeometry.region2poly(np.array([[0, samplesize[0]], [0., samplesize[1]]])) ppimage = pgeometry.region2poly(rr) pppatch = pgeometry.projectiveTransformation(H, ppimage) ppi = pgeometry.polyintersect(ppx.T, pppatch.T).T A = pgeometry.polyarea(ppi.T) A0 = pgeometry.polyarea(ppx.T) # special rules if np.abs(A / A0) < .85: if verbose: print(' add cost for A/A0: A %f A0 %f' % (A, A0)) cost += 4000 if aa[0] < 0 or aa[0] > np.pi / 2 - np.deg2rad(5): cost += 10000 if aa[1] < np.pi or aa[1] > 3 * np.pi / 2: if verbose: print(' add cost for alpha') cost += 10000 if aa[2] < np.pi or aa[2] > 3 * np.pi / 2: if verbose: print(' add cost for alpha') cost += 10000 if aa[3] < 0 or aa[3] > np.pi / 2: if verbose: print(' add cost for alpha') cost += 10000 if 1: ccim = (np.array(im.shape) / 2 + .5) * istep tmp = np.linalg.norm(ccim - param[0:2]) dcost = 2000 * pgeometry.logistic(tmp, np.mean(ccim), istep) if verbose: print(' add cost for image cc: %.1f' % dcost) cost += dcost if pgeometry.angleDiff(aa[0], aa[1]) < np.deg2rad(30): if verbose: print(' add cost for angle diff') cost += 1000 if pgeometry.angleDiff(aa[2], aa[3]) < np.deg2rad(30): if verbose: print(' add cost for angle diff') cost += 1000 if pgeometry.angleDiffOri(aa[0], aa[2]) > np.deg2rad(10): cost += 10000 if pgeometry.angleDiffOri(aa[1], aa[3]) > np.deg2rad(10): cost += 10000 if param[2] < 0: if verbose: print(' add cost for negative param') cost += 10000 if np.abs(param[2]) > 7.: if verbose: print(' add cost large param[2]') cost += 10000 if np.abs(param[2] - 10) > 8: cost += 10000 if len(param) > 7: if np.abs(pgeometry.angleDiff(param[7], np.pi / 4)) > np.deg2rad(30): cost += 10000 if not fig is None: _showIm(patch, fig=fig) plt.title('Image patch: cost %.1f: istep %.2f' % (cost, istepmodel)) pgeometry.addfigurecopy(fig=fig) plt.plot([float(lp[0]), float(hp[0])], [float(lp[1]), float(hp[1])], '.--m', linewidth=linewidth, markersize=10, label='transition line') plt.plot(cc[0], cc[1], '.m', markersize=12) for ii in range(4): if ii == 0: lbl = 'electron line' else: lbl = None plt.plot([op[ii, 0], ip[ii, 0]], [op[ii, 1], ip[ii, 1]], '.-', linewidth=linewidth, color=[0, .7, 0], label=lbl) pgeometry.plotLabels(np.array((op[ii, :] + ip[ii, :]) / 2).reshape((2, -1)), '%d' % ii) if verbose >= 1: _showIm(modelpatch, fig=fig + 1) plt.title('Model patch: cost %.1f' % cost) _showIm(np.abs(dd), fig=fig + 2) plt.title('diff patch: cost %.1f' % cost) plt.colorbar() plt.show() if verbose: print('evaluateCross: cost %.4f' % cost) #print('evaluateCross: param %s' % (str(param), )) return cost, patch, cdata, (H, ) pass