ちょいめも

物理/Python/Cの雑記帳

混合モデルフィッティング

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from scipy.optimize import curve_fit


# フィッティング式
def mixed_model(x, w, a_n, sigma_n, mu_n, a_logn, sigma_logn, mu_logn, c1, c2, x_c):
    # 正規分布
    norm = a_n * (1 / (np.sqrt(2 * np.pi * sigma_n**2)) * np.exp(-((x - mu_n) ** 2) / (2 * sigma_n**2))) + c1
    # 対数正規分布
    # x_cがプラスの時にlogの中身がマイナスになるので、x>x_cのマスクをかけてlogの中身がゼロ以上になるようにしている
    lognorm = np.zeros_like(x)
    mask = x > x_c
    lognorm[mask] = (
        a_logn
        * (
            1
            / (np.sqrt(2 * np.pi * sigma_logn**2) * (x[mask] - x_c))
            * np.exp(-((np.log(x[mask] - x_c) - mu_logn) ** 2) / (2 * sigma_logn**2))
        )
        + c2
    )
    return w * norm + (1 - w) * lognorm


# === 分布作成 ===
num_data = 1000  # データ数
# 混合モデル設定
weight_n = 0.7  # 正規分布の混合比率
weight_logn = 1 - weight_n  # 対数正規分布の比率
num_n = int(num_data * weight_n)  # 正規分布のサンプル数
num_logn = num_data - num_n  # 対数正規分布のサンプル数

# 正規分布作成
np.random.seed(1)  # 乱数を再現できるように
sigma_n = 10
mu_n = 75
data_n = np.random.normal(mu_n, sigma_n, num_n)
# 対数正規分布作成
np.random.seed(1)  # 乱数を再現できるように
sigma_logn = 1
mu_logn = 3
data_logn = np.random.lognormal(mu_logn, sigma_logn, num_logn) + 100  # 対数正規分布をx方向に適当にシフト

# 混合データ 生成したデータを結合
data_mixed = np.concatenate([data_logn, data_n])

# dataframeに格納
label = "mixed model"
df = pd.DataFrame(data_mixed, columns=[label])

# === ヒストグラム作成 ===
# ヒストグラムをplt.histで作成するのでここでfigureオブジェクト生成
plt.figure(1)
plt.style.use("ggplot")
freq, bins, _ = plt.hist(
    [df[label]],
    bins=100,
    alpha=0.5,  # グラフの透過率 0が透明、1が不透明 未指定の場合は1
    # 		color=['#f46d43'] #グラフの色 未指定の場合は自動
    ec="navy",
    label=[label],  # グラフのラベル
    # range=(x_range_min, x_range_max),  # グラフの横軸の範囲 未指定の場合はデータの最大、最小値に合わせられる
    rwidth=1.0,  # グラフの棒の幅 身指定の場合は1
    # 		stacked=False #複数データを積み上げグラフにするか、横に並べるか 未指定の場合はFalse
)

# === フィッティング ===
# 分布のx,yの値を設定
# plt.histは端の値が返ってくるのでbins+1のデータ数がある
# フィッティングはビンの中心の値を使うのでビンの差分を2で割って足す
pdf_x = bins[0:-1] + np.diff(bins) / 2
pdf_y = freq

# 混合分布フィッティング
# paramはフィッティングパラメータ、covは共分散行列
param_ini = (weight_n, 2500, sigma_n, mu_n, 4500, sigma_logn, mu_logn, 0, 0, 100)  # 初期値
param, cov = curve_fit(
    mixed_model,
    pdf_x,
    pdf_y,
    p0=param_ini,
    bounds=(
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [1, np.inf, np.inf, np.inf, np.inf, np.inf, np.inf, 10, 10, 200],
    ),  # 制約 [param1_min,param2_min,...,param10_min],[param1_max,param2_max,...,param10_max]の形式
)
# 共分散のルートでフィッティングパラメータの不確かさ
err = np.sqrt(np.diag(cov))
# fitting関数からデータ作成
pdf_y_fit = mixed_model(
    pdf_x,
    param[0],
    param[1],
    param[2],
    param[3],
    param[4],
    param[5],
    param[6],
    param[7],
    param[8],
    param[9],
)

# fitting係数出力
print("・混合分布")
print(f"w          : {param[0]:.6f} +- {err[0]:.6f}")
print(f"a_n        : {param[1]:.6f} +- {err[1]:.6f}")
print(f"sigma_n    : {param[2]:.6f} +- {err[2]:.6f}")
print(f"mu_n       : {param[3]:.6f} +- {err[3]:.6f}")
print(f"a_logn     : {param[4]:.6f} +- {err[4]:.6f}")
print(f"sigma_logn : {param[5]:.6f} +- {err[5]:.6f}")
print(f"mu_logn    : {param[6]:.6f} +- {err[6]:.6f}")
print(f"c1         : {param[7]:.6f} +- {err[7]:.6f}")
print(f"c2         : {param[8]:.6f} +- {err[8]:.6f}")
print(f"x_c        : {param[9]:.6f} +- {err[9]:.6f}")
print("\n")

# フィッティングデータ保存
# パラメータ
name_pdf = np.array(["w", "a_n", "sigma_n", "mu_n", "a_logn", "sigma_logn", "mu_logn", "c1", "c2", "x_c"])
data_param = np.array(
    [param[0], param[1], param[2], param[3], param[4], param[5], param[6], param[7], param[8], param[9]]
)
data_err = np.array([err[0], err[1], err[2], err[3], err[4], err[5], err[6], err[7], err[8], err[9]])
data_pdf_df = pd.DataFrame(np.round(np.vstack((data_param, data_err)), 6))
data_pdf_df.to_csv("pdf_fitting_param.csv", header=name_pdf, index=False)
# フィッティングy
name_pdf = np.array(["pdf_x", "pdf_y", "pdf_y_fit"])
data_pdf_df = pd.DataFrame(np.round(np.vstack((pdf_x, pdf_y, pdf_y_fit)).T, 6))
data_pdf_df.to_csv("pdf_fitting.csv", header=name_pdf, index=False)

# === グラフ描画 ===
# plt.plot(pdf_x, pdf_y, label="data")
plt.plot(pdf_x, pdf_y_fit, label="fit")
plt.title("mixed model")
plt.xlabel("x")
plt.ylabel("Frequency")
plt.legend()  # 凡例表示
plt.savefig("mixed_hist.png")
plt.show()

フィッティング2次元

2次元フィッティングのメモ

"""
# 第一引数:2次元分布データ
# 第二引数:xデータ
# 第三引数:yデータ
"""
import os
import sys

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.patches import Ellipse
from scipy.optimize import curve_fit

# 定義
C393 = 1.000  # 確率長円 39%
C500 = 1.177  # 確率長円 50%
C900 = 2.146  # 確率長円 90%
C950 = 2.448  # 確率長円 95%
C990 = 3.035  # 確率長円 99%


def fit_2d_normal_distribution(XY, a, rho, sigma_x, sigma_y, mu_x, mu_y, c):
    x, y = XY[0:2]
    z = (
        a
        * (1 / (2 * np.pi * sigma_x * sigma_y * np.sqrt(1 - rho**2)))
        * np.exp(
            -1
            / (2 * (1 - rho**2))
            * (
                ((x - mu_x) / sigma_x) ** 2
                + ((y - mu_y) / sigma_y) ** 2
                - 2 * rho * ((x - mu_x) * (y - mu_y)) / (sigma_x * sigma_y)
            )
        )
        + c
    )
    return z.ravel()  # 1次元に変換する


argvs = sys.argv
argc = len(argvs)

if argc != 4:
    print("arg1 : data\n")
    print("arg2 : x\n")
    print("arg3 : y\n")
    input("Press any key to exit\n")
    sys.exit()

# データ読み込み
data = np.loadtxt(argvs[1], delimiter=",")
data_x = np.loadtxt(argvs[2], delimiter=",")
data_y = np.loadtxt(argvs[3], delimiter=",")
X, Y = np.meshgrid(data_x, data_y)

# initial guesses
parameter_initial = (1000, 0.5, 8, 6, 0.5, -0.5, 0)
param, cov = curve_fit(fit_2d_normal_distribution, (X, Y), data.ravel(), p0=parameter_initial)
print(f"a       : {param[0]}")
print(f"rho     : {param[1]}")
print(f"sigma_x : {param[2]}")
print(f"sigma_y : {param[3]}")
print(f"mu_x    : {param[4]}")
print(f"mu_y    : {param[5]}")
print(f"c       : {param[6]}")

a = param[0]
rho = param[1]
sigma_x = param[2]
sigma_y = param[3]
mu_x = param[4]
mu_y = param[5]
c = param[6]

# 対角化後の分散共分散行列のsigma_u, siguma_v計算
t1 = sigma_x**2 + sigma_y**2
t2 = sigma_x**2 - sigma_y**2
t3 = 4 * (rho * sigma_x * sigma_y) ** 2  # 4*sigma_xy^2 = 4*(rho*sigma_x*sigma_y)^2
sigma_u = np.sqrt((t1 + np.sqrt(t2**2 + t3)) / 2)
sigma_v = np.sqrt((t1 - np.sqrt(t2**2 + t3)) / 2)
deg = np.rad2deg(np.arctan((sigma_u**2 - sigma_x**2) / np.sqrt(t3)))
sigma_u95 = 2 * C950 * sigma_u
sigma_v95 = 2 * C950 * sigma_v
print("・楕円長")
print(f"sigma_u(95%) : {sigma_u95}")
print(f"sigma_v(95%) : {sigma_v95}")
print(f"theta(deg)   : {deg}")

# fitting result
fitting_data = fit_2d_normal_distribution(
    (X, Y), param[0], param[1], param[2], param[3], param[4], param[5], param[6]
).reshape(data.shape[0], data.shape[1])

# plot graph
fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(10, 8), sharex=False)
im = axes[0, 0].pcolormesh(X, Y, data, shading="auto", cmap="jet")
axes[0, 0].set_title("input data")
axes[0, 0].set_xlabel("x")
axes[0, 0].set_ylabel("y")
fig.colorbar(im, ax=axes[0, 0])

im = axes[0, 1].pcolormesh(X, Y, fitting_data, shading="auto", cmap="jet")
axes[0, 1].set_title("fit data")
axes[0, 1].set_xlabel("x")
axes[0, 1].set_ylabel("y")
fig.colorbar(im, ax=axes[0, 1])

im = axes[1, 0].pcolormesh(X, Y, data - fitting_data, shading="auto", cmap="jet")
axes[1, 0].set_title("diff(input - fit)")
axes[1, 0].set_xlabel("x")
axes[1, 0].set_ylabel("y")
fig.colorbar(im, ax=axes[1, 0])

# pcolormeshは図形描画ができないのでimshowで描画
im = axes[1, 1].imshow(data, extent=(data_x[0], data_x[-1], data_y[0], data_y[-1]), cmap="Greys")  # xy座標設定
axes[1, 1].set_title("check sigma (vs input)")
axes[1, 1].set_xlabel("x")
axes[1, 1].set_ylabel("y")
axes[1, 1].add_patch(
    Ellipse(
        xy=(mu_x, mu_y),
        width=sigma_u95,
        height=sigma_v95,
        angle=-deg,
        edgecolor="red",
        fill=False,
        label=f"2sigma(95%)\n sigma_u={sigma_u95:.1f}\n sigma_v={sigma_v95:.1f}\ntheta={deg:.1f}deg",
    )
)  # add_patchinvert_yaxisで反転しないのでangleにマイナスを掛ける
axes[1, 1].invert_yaxis()  # imshowは反転するのでここで反転
fig.colorbar(im, ax=axes[1, 1])
axes[1, 1].legend()

fig.tight_layout()
plt.savefig(f"{os.path.splitext(argvs[0])[0]}_fit.png")
plt.show()

フィッティング

pythonでフィッティングするときのためのめも。

コード
fitlin.py

"""
線形フィッティング
"""
import matplotlib.pyplot as plt
import numpy as np
from scipy.optimize import curve_fit


# fitting関数
def fit(x, a, b):
    return a * x + b


# データ入力
array_x = np.array([0, 1, 2, 3, 4, 5, 6])
array_y = np.array([0.2, 1.4, 2.2, 3.1, 4.5, 5.2, 5.8])

# paramはフィッティングパラメータ、covは共分散行列
param, cov = curve_fit(fit, array_x, array_y)
# 共分散のルートでフィッティングパラメータの誤差
error = np.sqrt(np.diag(cov))

# fitting係数出力
print("a:{:.6f} b:{:.6f}".format(param[0], param[1]))
print("sigma_a:{:.6f} sigma_b:{:.6f}".format(error[0], error[1]))

# fitting関数からデータ作成
array_y_fit = fit(array_x, param[0], param[1])

# グラフ描画
plt.plot(array_x, array_y)
plt.plot(array_x, array_y_fit)
plt.show()

・入力データ
lognormal_dat.csv

0.01,0.0001
0.1,0.017
1,0.24
2,0.2
3,0.13
4,0.09
5,0.06
6,0.04
7,0.03
8,0.03
9,0.02
10,0.01

fitlognorm.py

"""
対数正規分布をフィッティング
"""
import os
import sys

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from scipy.optimize import curve_fit


# 対数正規分布
def lognormal(x, a, sigma, mu, c):
    return a * (1 / (np.sqrt(2 * np.pi * sigma**2) * x) * np.exp(-((np.log(x) - mu) ** 2) / (2 * sigma**2))) + c


if __name__ == "__main__":
    argvs = sys.argv
    argc = len(argvs)

    # エラー処理
    if argc != 2:
        print("引数1:対数正規分布データ")
        input("キーを何か押すと終了します。")
        sys.exit()

    # ファイル保存設定
    savedir = os.path.dirname(os.path.abspath(argvs[1]))
    filename, ext = os.path.splitext(os.path.basename(argvs[1]))

    # データ読み込み
    data = np.loadtxt(argvs[1], delimiter=",")
    pdf_x = data[:, 0]
    pdf_y = data[:, 1]

    # === 対数正規分布フィッティング ===
    # paramはフィッティングパラメータ、covは共分散行列
    param_ini = (1, 1, 1, 0)  # 初期値
    param, cov = curve_fit(lognormal, pdf_x, pdf_y, p0=param_ini)
    # 共分散のルートでフィッティングパラメータの不確かさ
    err = np.sqrt(np.diag(cov))

    # fitting係数出力
    print("・対数正規分布")
    print("a     : {:.6f} +- {:.6f}".format(param[0], err[0]))
    print("sigma : {:.6f} +- {:.6f}".format(param[1], err[1]))
    print("mu    : {:.6f} +- {:.6f}".format(param[2], err[2]))
    print("c     : {:.6f} +- {:.6f}".format(param[3], err[3]))
    print("\n")

    # fitting関数からデータ作成
    pdf_y_fit = lognormal(pdf_x, param[0], param[1], param[2], param[3])

    # フィッティングデータ保存
    # パラメータ
    name_pdf = np.array(["a", "sigma", "mu", "c", "a_sigma", "sigma_sigma", "mu_sigma", "c_sigma"])
    data_pdf = np.array([param[0], param[1], param[2], param[3], err[0], err[1], err[2], err[3]])
    data_pdf_df = pd.DataFrame([np.round(data_pdf, 6)])
    data_pdf_df.to_csv(savedir + "\\" + filename + "_pdf_fitting_param.csv", header=name_pdf, index=False)
    # フィッティングy
    name_pdf = np.array(["x", "fit_y"])
    data_pdf = np.vstack((pdf_x, pdf_y_fit)).T
    data_pdf_df = pd.DataFrame(np.round(data_pdf, 6))
    data_pdf_df.to_csv(savedir + "\\" + filename + "_pdf_fitting.csv", header=name_pdf, index=False)

    # === グラフ描画 ===
    plt.plot(pdf_x, pdf_y, "o", label="data")
    plt.plot(pdf_x, pdf_y_fit, label="fit")
    plt.title("log-normal PDF\n{0}".format(filename))
    plt.xlabel("x")
    plt.ylabel("PDF")
    plt.grid(which="major", axis="x", color="gray", alpha=0.8, linestyle="--", linewidth=0.5)
    plt.grid(which="major", axis="y", color="gray", alpha=0.8, linestyle="--", linewidth=0.5)
    plt.legend()
    plt.savefig(savedir + "\\" + filename + "_pdf.png")
    plt.show()


fitlognormlhist.py

"""
ヒストグラムをフィッティング
累積分布関数を生成してフィッティング
"""

import os
import sys

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from scipy.optimize import curve_fit
from scipy.special import erf
from scipy.stats import norm


# 対数正規分布
def lognormal(x, a, sigma, mu, c):
    return a * (1 / (np.sqrt(2 * np.pi * sigma**2) * x) * np.exp(-((np.log(x) - mu) ** 2) / (2 * sigma**2))) + c


# 対数正規分布 累積分布関数
def lognormal_erf(x, sigma, mu):
    return (1 / 2) * (1 + erf((np.log(x) - mu) / (np.sqrt(2 * sigma**2))))


if __name__ == "__main__":
    # === 対数正規分布作成 ===
    np.random.seed(1)  # 乱数を再現できるように
    mu = 3
    sigma = 1
    data_num = 1000
    lognorm_dat = np.random.lognormal(mu, sigma, data_num)

    # dataframeに格納
    label = "lognormal"
    df = pd.DataFrame(lognorm_dat, columns=[label])

    # ヒストグラム作成
    # ヒストグラムをplt.histで作成するのでここでfigureオブジェクト生成
    plt.figure(1)
    plt.style.use("ggplot")
    freq, bins, _ = plt.hist(
        [df[label]],
        bins=100,
        alpha=0.5,  # グラフの透過率 0が透明、1が不透明 未指定の場合は1
        # 		color=['#f46d43'] #グラフの色 未指定の場合は自動
        ec="navy",
        label=[label],  # グラフのラベル
        # range=(x_range_min, x_range_max),  # グラフの横軸の範囲 未指定の場合はデータの最大、最小値に合わせられる
        rwidth=1.0  # グラフの棒の幅 身指定の場合は1
        # 		stacked=False #複数データを積み上げグラフにするか、横に並べるか 未指定の場合はFalse
    )

    # 分布のx,yの値を設定
    # plt.histは端の値が返ってくるのでbins+1のデータ数がある
    # フィッティングはビンの中心の値を使うのでビンの差分を2で割って足す
    pdf_x = bins[0:-1] + np.diff(bins) / 2
    pdf_y = freq

    # 対数正規分布フィッティング
    # paramはフィッティングパラメータ、covは共分散行列
    param_ini = (10000, sigma, mu, 0)  # 初期値
    param, cov = curve_fit(lognormal, pdf_x, pdf_y, p0=param_ini)
    # 共分散のルートでフィッティングパラメータの不確かさ
    err = np.sqrt(np.diag(cov))
    # fitting関数からデータ作成
    pdf_y_fit = lognormal(pdf_x, param[0], param[1], param[2], param[3])

    # fitting係数出力
    print("・対数正規分布")
    print("a     : {:.6f} +- {:.6f}".format(param[0], err[0]))
    print("sigma : {:.6f} +- {:.6f}".format(param[1], err[1]))
    print("mu    : {:.6f} +- {:.6f}".format(param[2], err[2]))
    print("c     : {:.6f} +- {:.6f}".format(param[3], err[3]))
    print("\n")

    # フィッティングデータ保存
    # パラメータ
    name_pdf = np.array(["a", "sigma", "mu", "c", "a_sigma", "sigma_sigma", "mu_sigma", "c_sigma"])
    data_pdf = np.array([param[0], param[1], param[2], param[3], err[0], err[1], err[2], err[3]])
    data_pdf_df = pd.DataFrame([np.round(data_pdf, 6)])
    data_pdf_df.to_csv("pdf_fitting_param.csv", header=name_pdf, index=False)
    # フィッティングy
    name_pdf = np.array(["pdf_x", "pdf_y", "pdf_y_fit"])
    data_pdf = np.vstack((pdf_x, pdf_y, pdf_y_fit)).T
    data_pdf_df = pd.DataFrame(np.round(data_pdf, 6))
    data_pdf_df.to_csv("pdf_fitting.csv", header=name_pdf, index=False)

    # === 累積分布フィッティング ===
    cdf_x = sorted(df[label])
    cdf_y = [i / data_num for i in range(data_num)]

    param, cov = curve_fit(lognormal_erf, cdf_x, cdf_y)
    err = np.sqrt(np.diag(cov))
    print("・対数正規分布 累積分布関数")
    print("sigma : {:.6f} +- {:.6f}".format(param[0], err[0]))
    print("mu    : {:.6f} +- {:.6f}".format(param[1], err[1]))
    print("\n")
    cdf_y_fit = lognormal_erf(cdf_x, param[0], param[1])

    # フィッティングデータ保存
    # パラメータ
    name_cdf = np.array(["sigma", "mu", "sigma_sigma", "mu_sigma"])
    data_cdf = np.array([param[0], param[1], err[0], err[1]])
    data_cdf_df = pd.DataFrame([np.round(data_cdf, 6)])
    data_cdf_df.to_csv("cdf_fitting_param.csv", header=name_cdf, index=False)
    # フィッティングy
    name_cdf = np.array(["cdf_x", "cdf_y", "cdf_y_fit"])
    data_cdf = np.vstack((cdf_x, cdf_y, cdf_y_fit)).T
    data_cdf_df = pd.DataFrame(np.round(data_cdf, 6))
    data_cdf_df.to_csv("cdf_fitting.csv", header=name_cdf, index=False)

    # === グラフ描画 ===
    plt.plot(pdf_x, pdf_y_fit, label="fit")
    plt.title("log-normal")
    plt.xlabel("x")
    plt.ylabel("Frequency")
    plt.legend()  # 凡例表示
    plt.savefig("lognormal_hist.png")

    plt.figure(2)
    plt.plot(cdf_x, cdf_y, "o", label="data")
    plt.plot(cdf_x, cdf_y_fit, label="fit")
    plt.title("log-normal CDF")
    plt.xlabel("x")
    plt.ylabel("CDF")
    plt.legend()
    plt.savefig("lognormal_hist_cdf.png")
    plt.show()

Gitの使い方 覚書

リモートリポジトリを共有サーバーとするときのgitの操作などの覚書
リモートリポジトリ:D:\python\repository\git_test.git
ローカルリポジトリ:D:\python\PythonScript\git_test
としてメモ

まだわかっていないことも多いので、
間違っていることもあると思います。
なので適宜更新します。

基本的にはVSCode拡張機能GitHistoryを使うことを前提として書いています。
ターミナルからコマンド打つ方が楽なときはコマンドで。


■初期作成の場合
・サーバー側の作業
cd D:\python\repository

フォルダの作成
mkdir git_test.git
cd git_test.git

リポジトリを作成
git init --bare

・ローカルでの作業
ローカルリポジトリに移動して

リモートブランチの設定
git remote add origin D:\python\repository\git_test.git
origin:リモート名、originは習慣で使われているもの
リモートURL:D:\python\repository\git_test.git

プッシュ
git push origin master
マスターがプッシュされる

この初期作成のやり方だとHEADがつかない
git remote set-head origin master
でつけられる

workspaceを作っとかないと、VSCodeで開いたときにエクスプローラーのとこに
「フォルダがありません」となるので、作っといた方がよさそう。


■リモートリポジトリがある場合
リモートブランチの設定。
git remote add origin D:\python\repository\git_test.git

リモートブランチの確認
git remote -v

プッシュ
git push origin master
マスターがプッシュされる

■リモートURLを変更する
git remote set-url origin D:\python\repository\git_test.git


■クローン(ローカルリポジトリが存在しない場合、複製)
git clone D:\python\repository\git_test.git D:\python\PythonScript\git_clone
ローカルのフォルダは作られていなくてもOK


■フェッチ(更新を確認)
ローカルリポジトリで以下を実行
git fetch D:\python\repository\git_test.git\
リモートが設定されていれば
git fetch
でもOK

コマンドが実行されると、ローカルにリモート追跡のためのブランチが作られる。このブランチの名前を使ってリモートにどんな変更が記録されているかを見ることができる。
git log origin/master
で変更履歴が見れる。

フェッチではリモートからとってきた情報が「origin/master」ブランチに取り込まれる。


■マージ(フェッチしたものをローカルにマージする)
ローカルリポジトリで以下を実行
git merge origin/master
すでに最新の場合は
Already up to date.
とでてくる。


■プル
git pull は、git fetch と git merge を 1 つのコマンドで実行できる
ローカルリポジトリで以下を実行
git pull D:\python\repository\git_test.git\


VSCODEを使用してログからブランチを作成
Git Historyを使用

  1. Branchから作成して、

作成した後はブランチ名のところをクリックしてチェックアウト

この作業を行った後、Git Historyの絞り込みがブランチが絞り込まれているので、
All Branches
にすると全部出てくる。

VSCODEのウィンドウの左下のブランチ表示しているところをクリックして
作成したブランチからmasterに戻ることもできる。

masterに戻って
作成したブランチの
More
から、このブランチをカレントブランチにマージするを選んでマージする

内容がコンフリクトした場合は手動で直してステージングする

分岐して作ったブランチはmasterにマージしたら消す(Git Historyのブランチ名の×で消せる)

■リモートリポジトリが更新されていて
ローカルリポジトリも更新していて
プルしてコンフリクトした場合

手動で直してプッシュしなおす


■マージしてからプッシュする
分岐してるとリジェクトされるので


■Revert this commit
Git HistoryのMoreから操作
HEADより前に戻る場合は
ソースの方で
Accept Current Change
Accept Incoming Change ← 選択したコミットのとこに戻る
Accept Both Changes
Compare Changes
を選んでソースを戻したり直したり
選択したコミットの一つ前の状態に戻る
HEADよりも前に戻らない場合は自動的にそのコミットのところに戻りコミットされる模様


■Soft reset to this commit
VSCODEのGitHistoryのメニューから
戻りたい履歴のSoftを押すと、そこがmasterになる
ただしソースは戻らない。
戻りたいところからブランチを作成した方がいいかも


■Hard reset to this commit
履歴が完全に消える。
ファイルももとに戻る
なかったことになる。
使わない方が吉。

エッジ像からMTFを計算

下のエッジ像の中心ラインだけ抽出して計算

f:id:choimemo:20211207003418j:plain
エッジ像
#第1引数:画像ファイルパス
import sys
import numpy as np
import matplotlib.pyplot as plt
from imageio import imread

#設定
pixel_pitch = 0.005 #mm 画素ピッチ lp/mmを算出するため


class edge2mtf():

	def __init__(self, load_img):
		self.img = imread(load_img).astype(np.float64)

	#ESF
	def ESF(self):
		center = int(self.img.shape[0] / 2) #画像縦方向中心
		self.esf = self.img[center] #中心の輝度値を抽出 本来は横ライン全て取得して疑似的にサンプリング増やした方が良いらしい
		self.esf_x = np.arange(self.esf.shape[0]) #x軸
		
	#LSF
	def LSF(self):
		self.lsf = np.diff(self.esf)
		self.lsf_x = np.arange(self.lsf.shape[0]) #x軸

	#MTF
	def MTF(self):
		self.otf = np.fft.fft(self.lsf)
		self.mtf = np.abs(self.otf) / np.abs(self.otf).max()
		self.mtf_x = np.fft.fftfreq(len(self.lsf_x)) #freq  x軸

		half_idx = int(len(self.mtf)/2)+1 #フーリエ変換は正負対象なので、正部分を抽出するためのインデックス
		self.mtf = self.mtf[0:half_idx]
		self.mtf_norm_x = self.mtf_x[0:half_idx] #pix/mm
		self.mtf_x = self.mtf_norm_x / pixel_pitch #lp/mm

	#グラフ描画
	def PlotGraph(self):

		self.ESF()
		self.LSF()
		self.MTF()

		fig, (esf_g, lsf_g, mtf_norm_g, mtf_g) = plt.subplots(nrows = 4, figsize=(5, 10), sharex = False)
		plt.subplots_adjust(wspace = 0.5, hspace = 0.5) # 余白を設定

		esf_g.plot(self.esf_x, self.esf)
		esf_g.set_title('ESF')
		esf_g.set_xlabel('x (px)')
		esf_g.set_ylabel('Brightness')
		esf_g.set_xlim(self.esf_x.min(), self.esf_x.max())
		
		lsf_g.plot(self.lsf_x, self.lsf)
		lsf_g.set_title('LSF')
		lsf_g.set_xlabel('x (px)')
		lsf_g.set_ylabel('LSF')
		lsf_g.set_xlim(self.lsf_x.min(), self.lsf_x.max())

		mtf_norm_g.plot(self.mtf_norm_x, self.mtf)
		mtf_norm_g.set_title('MTF Normalize')
		mtf_norm_g.set_xlabel('cycles / pixel')
		mtf_norm_g.set_ylabel('MTF')
		mtf_norm_g.set_xlim(self.mtf_norm_x.min(), self.mtf_norm_x.max())

		mtf_g.plot(self.mtf_x, self.mtf)
		mtf_g.set_title('MTF')
		mtf_g.set_xlabel('lp / mm')
		mtf_g.set_ylabel('MTF')
		mtf_g.set_xlim(self.mtf_x.min(), self.mtf_x.max())

		fig.show()
		

if __name__ == '__main__':

	#エラー処理なし
	argvs = sys.argv
	argc = len(argvs)

	img = edge2mtf(argvs[1])
	img.PlotGraph()


LSFのデータからも

#第1引数:LSFの入ったCSV
import sys
import numpy as np
import matplotlib.pyplot as plt

#設定
pixel_pitch = 0.005 #mm 画素ピッチ lp/mmを算出するため

class lsf2csv():

	#LSF読み込み
	def __init__(self, load_img):
		self.lsf = np.loadtxt(load_img).astype(np.float64)
		self.lsf_x = np.arange(self.lsf.shape[0]) #x軸

	#MTF
	def MTF(self):
		self.otf = np.fft.fft(self.lsf)
		self.mtf = np.abs(self.otf) / np.abs(self.otf).max()
		self.mtf_x = np.fft.fftfreq(len(self.lsf_x)) #freq  x軸

		half_idx = int(len(self.mtf)/2)+1 #フーリエ変換は正負対象なので、正部分を抽出するためのインデックス
		self.mtf = self.mtf[0:half_idx]
		self.mtf_norm_x = self.mtf_x[0:half_idx] #pix/mm
		self.mtf_x = self.mtf_norm_x / pixel_pitch #lp/mm

	#グラフ描画
	def PlotGraph(self):

		self.MTF()

		fig, (lsf_g, mtf_norm_g, mtf_g) = plt.subplots(nrows = 3, figsize=(5, 10), sharex = False)
		plt.subplots_adjust(wspace = 0.5, hspace = 0.5) # 余白を設定
		
		lsf_g.plot(self.lsf_x, self.lsf)
		lsf_g.set_title('LSF')
		lsf_g.set_xlabel('x (px)')
		lsf_g.set_ylabel('LSF')
		lsf_g.set_xlim(self.lsf_x.min(), self.lsf_x.max())

		mtf_norm_g.plot(self.mtf_norm_x, self.mtf)
		mtf_norm_g.set_title('MTF Normalize')
		mtf_norm_g.set_xlabel('cycles / pixel')
		mtf_norm_g.set_ylabel('MTF')
		mtf_norm_g.set_xlim(self.mtf_norm_x.min(), self.mtf_norm_x.max())

		mtf_g.plot(self.mtf_x, self.mtf)
		mtf_g.set_title('MTF')
		mtf_g.set_xlabel('lp / mm')
		mtf_g.set_ylabel('MTF')
		mtf_g.set_xlim(self.mtf_x.min(), self.mtf_x.max())

		fig.show()
		

if __name__ == '__main__':

	#エラー処理なし
	argvs = sys.argv
	argc = len(argvs)

	img = lsf2csv(argvs[1])
	img.PlotGraph()

あってんのかな?

DokuWiki on a Stickの設定

ローカルで自分用のWIKIを作成する

  • DokuWiki on a Stickのダウンロード

参考サイト:
Dokuwiki on a Stickの構築から初期設定方法までを解説 | うみうまブログ

以下の階層にあるファイルを編集する
\DokuWikiStick\dokuwiki\inc\init.php
95行目あたりの「date_default_timezone_set~」を以下に変更

date_default_timezone_set('Asia/Tokyo');

参考サイト:
ja:tips:timezone [DokuWiki]

  • スタートページ名を変える

管理画面のサイト設定でスタートページ名が変えられる
indexにしておく
参考サイト:
DokuWiki はじめに行う10の設定

  • ページの作り方

http://localhost:8800/doku.php?id=newpage
上記のように「newpage」のようにページ名を付けて新規ページを作成

  • ページの削除

削除したいページにアクセスして、
文書の作成で内容をすべて消して保存。

  • サイドバーの作り方

http://localhost:8800/doku.php?id=sidebar
を作る。
これだと自分でサイドバーを作成しないといけないようなので、
サイトマップから自動的に作成してくれるようにしてくれるプラグインを入れる。
IndexMenu Plugin
plugin:indexmenu [DokuWiki]
上記からダウンロードして、
DokuWikiの管理画面→手動インストールでプラグインのZIPを選択してインストール
注意:設定のdefer_jsをオフにする。
とりあえず

{{indexmenu>..#1|js#phoenity.png navbar noscroll notoc tsort nsort skipfile=/sidebar/ }}

とした。
参考サイト:
DokuWikiプラグイン : Indexmenuでサイドバーにツリービュー。エクスプローラー風操作 [DokuWikiで情報発信]

  • その他の参考にしたサイト

📝DokuWiki初期設定(自分流) [あちあち情報局]

直交座標の強度マップを極座標の強度マップに変換

import numpy as np
from scipy import interpolate
import matplotlib.pyplot as plt
import matplotlib.cm as cm

data = np.loadtxt('data.csv', delimiter=',') #z value
data_x = np.loadtxt('xy.csv', delimiter=',')[:,0] #x座標
#極座標グラフと合わせるために、y座標はxyグラフでいうところの下が負になるようにするために反転
data_y = np.loadtxt('xy.csv', delimiter=',')[:,0][::-1] #y座標

#線形補間
f_r = interpolate.interp2d(data_x, data_y, data, kind='linear')

t = np.linspace(0, 2*np.pi, 100) #theta
r = np.linspace(0, data_x.max(), 100) #r 半径
T, R = np.meshgrid(t, r) #メッシュ
# np.savetxt('Theta_R.csv', np.vstack((t,r)).T, fmt='%0.3f', delimiter=',')

# f_r(r*np.cos(t), r*np.sin(t))で入力すると昇順にソートされてしまうのでリスト内包表記で処理する
Z = np.array([[f_r(i*np.cos(j), i*np.sin(j))[0] for j in t] for i in r])
# np.savetxt('Z_polar.csv', Z, fmt='%0.3f', delimiter=',')

#1D
deg1 = 0
Z_1d_1 = np.array([f_r(i*np.cos(deg1*np.pi/180), i*np.sin(deg1*np.pi/180))[0] for i in data_x])
#np.savetxt('rz.csv', np.vstack((data_x,Z_1d)).T, fmt='%0.3f', delimiter=',')
deg2 = 90
Z_1d_2 = np.array([f_r(i*np.cos(deg2*np.pi/180), i*np.sin(deg2*np.pi/180))[0] for i in data_x])


ax = plt.subplot(211, polar=True)
ctf = ax.contourf(T, R, Z, 100, cmap=cm.jet)
colb = plt.colorbar(ctf, pad=0.15,orientation="vertical")

#1D
ax = plt.subplot(212)
ax.plot(data_x, Z_1d_1)
ax.plot(data_x, Z_1d_2)

plt.show()