def costfun(param0): return evaluateCross(param0, imx, fig=None, istepmodel=istepmodel, usemask=False, istep=istep, use_abs=use_abs)[0]
def fitModel(param0, imx, verbose=1, cfig=None, ksizemv=41, istep=None, istepmodel=.5, cb=None, use_abs=False, w=2.5): """ Fit model of an anti-crossing This is a wrapper around evaluateCross and the scipy optimization routines. Args: param0 (array): parameters for the anti-crossing model imx (array): input image """ samplesize = [int(ksizemv / istepmodel), int(ksizemv / istepmodel)] costfun = lambda param0: evaluateCross(param0, imx, fig=None, istepmodel=istepmodel, usemask=False, istep=istep, use_abs=use_abs)[0] vv = [] def fmCallback(plocal, pglobal): """ Helper function to store intermediate results """ vv.append((plocal, pglobal)) if cfig is not None: cb = lambda x: fmCallback(x, None) #cb= lambda param0: evaluateCross(param0, imx, ksize, fig=cfig)[0] #cb = lambda param0: print('fitModel: cost %.3f' % evaluateCross(param0, imx, ksize, fig=None)[0] ) if 1: # simple brute force ranges = list([slice(x, x + .1, 1) for x in param0]) for ii in range(2): ranges[ii] = slice(param0[ii] - 13, param0[ii] + 13, 1) ranges = tuple(ranges) res = scipy.optimize.brute(costfun, ranges) paramy = res else: paramy = param0 res = scipy.optimize.minimize(costfun, paramy, method='nelder-mead', options={ 'maxiter': 1200, 'maxfev': 101400, 'xatol': 1e-8, 'disp': verbose >= 2 }, callback=cb) #res = scipy.optimize.minimize(costfun, res.x, method='Powell', options={'maxiter': 3000, 'maxfev': 101400, 'xtol': 1e-8, 'disp': verbose>=2}, callback=cb) if verbose: print('fitModel: score %.2f -> %.2f' % (costfun(param0), res.fun)) return res
def fit_anticrossing(dataset, width_guess=None, angles_guess=None, psi=None, w=2.5, diff_dir='dx', plot=False, verbose=1, param={}): """ Fits an anti-crossing model to a 2D scan. The model fitted is without tunnel coupling. Args: dataset (qcodes dataset): the 2D scan measurement dataset width_guess (None or float): Initial estimate for width of anti-crossing in the same unit as the dataset axis. angles_guess (None or float): Initial estimate for angles of anti-crossing in radians psi (None or float): angle for cross section of anti-crossing w (float): Width of lines in anti-crossing model diff_dir (str): differentiation direction plot (int): If non-zero, then plot into specified matplotlib window verbose (int): verbosity level param (dict): additional parameters Returns: anticross_fit: (dict) the parameters describing the fitted anti-cross optionally the cost for fitting and the figure number The main fields in the result structure are: * centre (2x1 array): position of the fitted anti-crossing * fit_params (array): fitting parameters of the model. See :func:`fitModel` * fitpoints (dict): a dictionary with fitted points. centre is the centre point; left_point and right_point are the corners of the anti-crossing. the four lines outwards are define by inner_points and outer_points """ abs_val = True set_arrays = dataset.default_parameter_array().set_arrays labels = [x.name for x in set_arrays] im, tr = qtt.data.dataset2image(dataset) imextent = tr.scan_image_extent() # get parameters of the algorithm istep = param.get('istep', 0.25) # resolution to convert the data into istepmodel = param.get('istepmodel', 0.5) # resolution in which to perform model fitting ksizemv = param.get('ksizemv', 31) # kernel size in mV diffvals = {'dx': 0, 'dy': 1, 'dxy': 2, 'xmy': 'xmy', 'g': 'g'} imc = cleanSensingImage(im, sigma=0.93, dy=diffvals[diff_dir]) imx, (fw, fh, mvx, mvy, Hstraight) = qtt.algorithms.images.straightenImage(imc, imextent, mvx=istep, verbose=verbose) imx = imx.astype(np.float64) * \ (100. / np.percentile(imx, 99)) # scale image # initialization of anti-crossing model param0 = [(imx.shape[0] / 2 + .5) * istep, (imx.shape[0] / 2 + .5) * istep, 3.5, 1.17809725, 3.5, 4.3196899, 0.39269908] if width_guess is not None: param0[2] = width_guess if angles_guess is not None: param0[3:] = angles_guess if psi is not None: param0e = np.hstack((param0, [psi])) else: psi = np.pi / 4 param0e = copy.copy(param0) # fit anti-crossing (twice) res = fitModel(param0e, imx, verbose=verbose, cfig=10, istep=istep, istepmodel=istepmodel, ksizemv=ksizemv, use_abs=abs_val, model_line_width=w) fitparam = res.x res = fitModel(fitparam, imx, verbose=verbose, cfig=10, istep=istep, istepmodel=istepmodel, ksizemv=ksizemv, use_abs=abs_val, model_line_width=w) fitparam = res.x cost, patch, cdata, _ = evaluateCross(fitparam, imx, verbose=0, fig=None, istep=istep, istepmodel=istepmodel) ccpixel_straight = cdata[0] ccpixel = qtt.pgeometry.projectiveTransformation( np.linalg.inv(Hstraight), (istepmodel / istep) * ccpixel_straight) if verbose: print('fit_anticrossing: patch size %s' % (patch.shape, )) def convert_coordinates(xpix): ccpixel = qtt.pgeometry.projectiveTransformation( np.linalg.inv(Hstraight), (istepmodel / istep) * xpix) return tr.pixel2scan(ccpixel) (cc, lp, hp, ip, op, _, _, _) = cdata centre = convert_coordinates(np.array(cc)) lp = convert_coordinates(np.array(lp)) hp = convert_coordinates(np.array(hp)) ip = convert_coordinates(np.array(ip).T) op = convert_coordinates(np.array(op).T) anticross_fit = {'labels': labels} anticross_fit['centre'] = tr.pixel2scan(ccpixel) anticross_fit['fitpoints'] = { 'centre': centre, 'left_point': lp, 'right_point': hp, 'inner_points': ip, 'outer_points': op } if len(param) == 7: param = np.append(fitparam, psi) anticross_fit['fit_params'] = fitparam anticross_fit['params'] = param if plot: if isinstance(plot, int): fig = plot else: fig = None fig_anticross = plt.figure(fig) cost, patch, cdata, _ = evaluateCross(fitparam, imx, verbose=verbose, fig=fig_anticross.number, istep=istep, istepmodel=istepmodel, w=w) anticross_fit['cost'] = cost anticross_fit['patch'] = patch anticross_fit['cdata'] = cdata anticross_fit['fig_num'] = fig_anticross.number anticross_fit['imx'] = imx return anticross_fit