Пример #1
0
def funcFitSmoothList(argsOfList, expList, xanesList, smoothType, targetFunc,
                      normType):
    l2 = []
    diffs = []
    es = []
    for j in range(len(expList)):
        exp = expList[j]
        arg = getOneArg(argsOfList, exp, smoothType)
        norm = getNorm(normType, argsOfList, arg)
        smoothed_xanes, normOut = funcFitSmoothHelper(arg, xanesList[j],
                                                      smoothType, exp, norm)
        # print(normOut)
        i = (exp.fit_intervals['smooth'][0] <= exp.xanes.energy) & (
            exp.xanes.energy <= exp.fit_intervals['smooth'][1])
        diff = abs(smoothed_xanes.absorb[i] - exp.xanes.absorb[i])**2
        diffs.append(diff)
        es.append(exp.xanes.energy[i])
        partial_func_val = np.sqrt(utils.integral(exp.xanes.energy[i], diff))
        l2.append(partial_func_val)
    if len(expList) == 1: return l2[0]
    l2 = np.array(l2)
    if targetFunc == 'mean': return np.mean(l2)
    elif targetFunc == 'max(l2)': return np.max(l2)
    elif targetFunc == 'l2(max)':
        e = es[0]
        newDiffs = np.zeros([len(expList), e.size])
        newDiffs[0] = diffs[0]
        for j in range(1, len(expList)):
            newDiffs[j] = np.interp(e, es[j], diffs[j])
        maxDiff = np.max(newDiffs, axis=0)
        return np.sqrt(utils.integral(e, maxDiff))
    else:
        assert False, 'Unknown target func'
Пример #2
0
def simpleSmooth(e, xanes, sigma):
    new_xanes = np.zeros(e.shape)
    for i in range(e.size):
        kern = kernelCauchy(e, e[i], sigma)
        norm = utils.integral(e, kern)
        if norm == 0: norm = 1
        new_xanes[i] = utils.integral(e, xanes * kern) / norm
    return new_xanes
Пример #3
0
def smooth_my_fdmnes(e, xanes, Gamma_hole, Ecent, Elarg, Gamma_max, Efermi):
    xanes = np.copy(xanes)
    xanes[e < Efermi] = 0
    new_xanes = np.zeros(e.shape)
    sigma = YvesWidth(e, Gamma_hole, Ecent, Elarg, Gamma_max, Efermi)
    for i in range(e.size):
        kern = kernelCauchy(e, e[i], sigma[i])
        norm = utils.integral(e, kern)
        new_xanes[i] = utils.integral(e, xanes * kern) / norm
    return e, new_xanes
Пример #4
0
def smooth_linear_conv(e, xanes, Gamma_hole, Gamma_max, Efermi):
    xanes = np.copy(xanes)
    xanes[e < Efermi] = 0
    new_xanes = np.zeros(e.shape)
    sigma = Gamma_hole + (Gamma_max - Gamma_hole) * (e - e[0]) / (e[-1] - e[0])
    sigma[sigma <= 0] = 1e-3
    for i in range(e.size):
        kern = kernelCauchy(e, e[i], sigma[i])
        norm = utils.integral(e, kern)
        new_xanes[i] = utils.integral(e, xanes * kern) / norm
    return e, new_xanes
Пример #5
0
def generalSmooth(e, xanes, sigma):
    eleft = np.linspace(e[0] - 10, e[0] - (e[1] - e[0]), 10)
    xleft = np.zeros(eleft.shape)
    eright = np.linspace(e[-1] + (e[-1] - e[-2]), e[-1] + 50, 10)
    xright = np.zeros(eleft.shape) + xanes[-1]
    e_new = np.hstack((eleft, e, eright))
    xanes = np.hstack((xleft, xanes, xright))
    new_xanes = np.zeros(e.shape)
    for i in range(e.size):
        kern = kernelCauchy(e_new, e[i], sigma[i])
        norm = utils.integral(e_new, kern)
        new_xanes[i] = utils.integral(e_new, xanes * kern) / norm
    return e, new_xanes
Пример #6
0
def smooth_Muller(e, xanes, group, Gamma_hole, Efermi, alpha1, alpha2, alpha3):
    xanes = np.copy(xanes)
    # xanes = simpleSmooth(e, xanes, Gamma_hole)
    xanes[e < Efermi] = 0
    new_xanes = np.zeros(e.shape)
    sigma = MullerWidth(e, group, Gamma_hole, Efermi, alpha1, alpha2, alpha3)
    for i in range(e.size):
        kern = kernelCauchy(e, e[i], sigma[i])
        norm = utils.integral(e, kern)
        new_xanes[i] = utils.integral(e, xanes * kern) / norm
        # print(e[i], sigma[i])
    # exit(0)
    return e, new_xanes
Пример #7
0
def funcFitSmooth(args, xanes, smoothType, exp, norm=None):
    smoothed_xanes, _ = funcFitSmoothHelper(args, xanes, smoothType, exp, norm)
    i = (exp.fit_intervals['smooth'][0] <= exp.xanes.energy) & (
        exp.xanes.energy <= exp.fit_intervals['smooth'][1])
    return np.sqrt(
        utils.integral(exp.xanes.energy[i],
                       abs(smoothed_xanes.absorb[i] - exp.xanes.absorb[i])**2))
Пример #8
0
def smooth_piecewise(e0, xanes, Gamma_hole, Gamma_max, Ecent):
    eleft = np.linspace(e0[0] - 10, e0[0] - (e0[1] - e0[0]), 10)
    xleft = np.zeros(eleft.shape)
    eright = np.linspace(e0[-1] + (e0[-1] - e0[-2]), e0[-1] + 50, 10)
    xright = np.zeros(eleft.shape) + xanes[-1]
    e = np.hstack((eleft, e0, eright))
    xanes = np.hstack((xleft, xanes, xright))
    new_xanes = np.zeros(e0.shape)
    sigma = np.zeros(e0.shape) + Gamma_hole
    sigma[e0 > Ecent] = Gamma_max
    sigma[sigma <= 0] = 1e-3
    for i in range(e0.size):
        kern = kernelCauchy(e, e0[i], sigma[i])
        norm = utils.integral(e, kern)
        new_xanes[i] = utils.integral(e, xanes * kern) / norm
    return e0, new_xanes
Пример #9
0
def deconvolve(e, xanes, smooth_params):
    xanes = utils.simpleSmooth(e, xanes, 1)
    Gamma_hole = value(smooth_params, 'Gamma_hole')
    Ecent = value(smooth_params, 'Ecent')
    Elarg = value(smooth_params, 'Elarg')
    Gamma_max = value(smooth_params, 'Gamma_max')
    Efermi = value(smooth_params, 'Efermi')
    n = e.size
    A = np.zeros([n, n])
    for i in range(n):
        #sigma = superWidth(e[i], Gamma_hole, Ecent, Elarg, Gamma_max, Efermi)
        sigma = 5
        kern = kernel(e, e[i], sigma)
        A[i] = kern / utils.integral(e, kern)
    res, _, _, s = np.linalg.lstsq(A, xanes, rcond=0.001)
    return res
Пример #10
0
def fitSmooth(expList,
              xanesList0,
              smoothType='fdmnes',
              fixParamNames=[],
              commonParams0={},
              targetFunc='max(l2)',
              plotTrace=False,
              crossValidationExp=None,
              crossValidationXanes=None,
              minimizeMethodType='seq',
              useGridSearch=True,
              useRefinement=True):
    xanesList = copy.deepcopy(xanesList0)
    if 'norm' in fixParamNames: normType = 'fixed'
    else:
        if 'norm' in commonParams0: normType = 'variableCommon'
        else: normType = 'variablePrivate'
    folder = tempfile.mkdtemp(dir='./tmp', prefix='smooth_')
    for i in range(len(expList)):
        os.makedirs(folder + '/' + expList[i].name)
        if xanesList[i].folder is not None:
            copyfile(xanesList[i].folder + '/out.txt',
                     folder + '/' + expList[i].name + '/out.txt')
        xanesList[i].folder = folder + '/' + expList[i].name
        if xanesList[i].molecula is not None:
            xanesList[i].molecula.export_xyz(xanesList[i].folder +
                                             '/molecula.xyz')
    arg0 = createArg(expList, smoothType, fixParamNames, commonParams0)
    # 0.0001
    fmin, smooth_params, trace = optimize.minimizePokoord(
        funcFitSmoothList,
        arg0,
        minDeltaFunc=1e-4,
        enableOutput=False,
        methodType=minimizeMethodType,
        parallel=False,
        useRefinement=useRefinement,
        useGridSearch=useGridSearch,
        returnTrace=True,
        f_kwargs={
            'expList': expList,
            'xanesList': xanesList,
            'smoothType': smoothType,
            'targetFunc': targetFunc,
            'normType': normType
        })
    with open(folder + '/func_smooth_value.txt', 'w') as f:
        json.dump(fmin, f)
    with open(folder + '/args_smooth.txt', 'w') as f:
        json.dump(smooth_params, f)
    with open(folder + '/args_smooth_human.txt', 'w') as f:
        f.write(arg2string(smooth_params))
    # выдаем предостережение, если достигли границы одного из параметров
    for p in smooth_params:
        d = p['rightBorder'] - p['leftBorder']
        if (abs(p['value'] - p['leftBorder']) <= p['step']) or (
                abs(p['value'] - p['rightBorder']) <= p['step']):
            print('Warning: parameter ' + p['paramName'] + '=' +
                  str(p['value']) + ' is near border of domain [' +
                  str(p['leftBorder']) + '; ' + str(p['rightBorder']) + ']')
    # считаем по отдельности размазку каждого xanes
    smoothed_xanes = []
    argsOfList = copy.deepcopy(smooth_params)
    for j in range(len(expList)):
        exp = expList[j]
        arg = getOneArg(argsOfList, exp, smoothType)
        norm = getNorm(normType, argsOfList, arg)
        fdmnes_xan, _ = funcFitSmoothHelper(arg, xanesList[j], smoothType, exp,
                                            norm)
        smoothed_xanes.append(fdmnes_xan)
        with open(folder + '/' + expList[j].name + '/args_smooth.txt',
                  'w') as f:
            json.dump(arg, f)
        with open(folder + '/' + expList[j].name + '/args_smooth_human.txt',
                  'w') as f:
            f.write(arg2string(arg))
        shift = value(arg, 'shift')
        fdmnes.plotToFolder(folder + '/' + expList[j].name,
                            exp,
                            xanesList[j],
                            fdmnes_xan,
                            append=getSmoothWidth(smoothType,
                                                  exp.xanes.energy - shift,
                                                  arg))
        ind = (exp.fit_intervals['smooth'][0] <= exp.xanes.energy) & (
            exp.xanes.energy <= exp.fit_intervals['smooth'][1])
        partial_fmin = np.sqrt(
            utils.integral(
                exp.xanes.energy[ind],
                abs(fdmnes_xan.absorb[ind] - exp.xanes.absorb[ind])**2))
        with open(
                folder + '/' + expList[j].name +
                '/func_smooth_partial_value.txt', 'w') as f:
            json.dump(partial_fmin, f)
        plotSmoothWidthToFolder(smoothType, exp.xanes.energy[ind] - shift, arg,
                                folder + '/' + expList[j].name)
    if plotTrace:
        privateFuncData = np.zeros([len(expList), len(trace)])
        norms = np.zeros([len(expList), len(trace)])
        for j in range(len(trace)):
            step = trace[j]
            argsOfList = step[0]
            for i in range(len(expList)):
                arg = getOneArg(argsOfList, expList[i], smoothType)
                norm = getNorm(normType, argsOfList, arg)
                privateFuncData[i, j] = funcFitSmooth(arg, xanesList[i],
                                                      smoothType, expList[i],
                                                      norm)
                _, norms[i,
                         j] = funcFitSmoothHelper(arg, xanesList[i],
                                                  smoothType, expList[i], norm)
        fig, ax = plt.subplots()
        steps = np.arange(1, len(trace) + 1)
        targetFuncData = [step[1] for step in trace]
        for i in range(len(expList)):
            ax.plot(steps, privateFuncData[i], label=expList[i].name)
        ax.plot(steps, targetFuncData, label='target')
        if crossValidationExp is not None:
            crossValidationXanes = copy.deepcopy(crossValidationXanes)
            if smoothType == 'fdmnes':
                folder2 = folder + '/CV_' + crossValidationExp.name
                os.makedirs(folder2)
                if crossValidationXanes.folder is not None:
                    copyfile(crossValidationXanes.folder + '/out.txt',
                             folder2 + '/out.txt')
                crossValidationXanes.folder = folder2
            crossValidationData = []
            for step_i in range(len(trace)):
                step = trace[step_i]
                argsOfList = step[0]
                arg = getOneArg(argsOfList, crossValidationExp, smoothType)
                for a in arg:
                    if value(argsOfList, a['paramName']) is None:
                        mean = 0
                        for exp in expList:
                            mean += value(argsOfList,
                                          exp.name + '_' + a['paramName'])
                        mean /= len(expList)
                        print(
                            'Warning: parameter ' + a['paramName'] +
                            ' is not common. Take mean for cross validation: '
                            + str(mean))
                        a['value'] = mean
                fmin1 = funcFitSmooth(arg, crossValidationXanes, smoothType,
                                      crossValidationExp,
                                      np.mean(norms[:, step_i]))
                crossValidationData.append(fmin1)
                if step_i == len(trace) - 1:
                    with open(folder2 + '/func_smooth_check_value.txt',
                              'w') as f:
                        json.dump(fmin1, f)
                    with open(folder2 + '/args_smooth.txt', 'w') as f:
                        json.dump(arg, f)
                    fdmnes_xan, _ = funcFitSmoothHelper(
                        arg, crossValidationXanes, smoothType,
                        crossValidationExp, np.mean(norms[:, step_i]))
                    fdmnes.plotToFolder(folder2, crossValidationExp,
                                        crossValidationXanes, fdmnes_xan)
                    #print(np.mean(norms[:,step_i]))
            ax.plot(steps, crossValidationData, label='check')
        ax.set_xscale('log')
        ax.legend()
        fig.set_size_inches((16 / 3 * 2, 9 / 3 * 2))
        fig.savefig(folder + '/trace.png')
        plt.close(fig)
    return smoothed_xanes, smooth_params, fmin