質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

811閲覧

スペクトルのピーク付近についてのMinuitによるガウシアンフィッティング

kagakun1

総合スコア2

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2022/12/26 10:27

編集2022/12/26 10:30

前提・質問内容

スペクトルのガウスフィットを行う為に、Minuitライブラリを用いて最小二乗法でグラフをガウス関数でフィッティングを行い適当なパラメータを推定するプログラムを作成してます。
プロット自体は問題なくできたのですが、フィッティングがデータのピーク値と、ピーク値から半分程度の値となるスペクトルの領域でフィッティングしたいのですが、その方法が分かりません。物理的にはスペクトルの半値幅までガウウス関数でフィッティングする問題です。どうかよろしくお願いします。

実現したいこと

PythonでMinuitのライブラリを使用してグラフのガウシアンフィットをピークの領域を再現できるように行うことが目的です。

使用したデータ[Na1copy.txt]

300 10419
301 10401
302 10302
303 10321
304 10302
305 10427
306 10418
307 10477
308 10355
309 10373
310 10530
311 10264
312 10479
313 10384
314 10628
315 10686
316 10537
317 10710
318 10602
319 10734
320 10846
321 10789
322 10820
323 10993
324 11101
325 10940
326 11132
327 11358
328 11380
329 11395
330 11616
331 11599
332 11640
333 11759
334 11958
335 12066
336 12357
337 12462
338 12435
339 12721
340 12732
341 12878
342 13331
343 13471
344 13585
345 13644
346 13819
347 14322
348 14279
349 14421
350 14818
351 14787
352 15172
353 15255
354 15820
355 16006
356 15763
357 16286
358 16513
359 16658
360 17103
361 17332
362 17595
363 17812
364 17967
365 18402
366 18634
367 18914
368 18925
369 19432
370 19792
371 20251
372 20288
373 20185
374 20813
375 20818
376 21383
377 21762
378 21909
379 22354
380 22251
381 22257
382 23075
383 22870
384 22959
385 22988
386 23916
387 23831
388 23915
389 24090
390 24184
391 24372
392 24300
393 24635
394 24693
395 24945
396 24953
397 24473
398 24937
399 24990
400 25106
401 25239
402 24742
403 25287
404 24446
405 24702
406 24957
407 24519
408 24371
409 24368
410 24487
411 24068
412 23992
413 24073
414 23884
415 23418
416 23377
417 22849
418 22562
419 22727
420 22267
421 21637
422 21386
423 21520
424 20860
425 20657
426 20412
427 20179
428 19361
429 19441
430 19190
431 18843
432 18696
433 18016
434 17743
435 17562
436 16919
437 16672
438 16226
439 15981
440 15529
441 15289
442 15007
443 14400
444 14052
445 13431
446 13433
447 13141
448 12627
449 12250

出力の結果

イメージ説明
テキストエディタはVSCコードで、Anacondaを使用してます。
出力コマンド操作はPythonで行なってます。

該当のソースコード

#!/usr/bin/env python

import numpy as np
import matplotlib as mtb
import matplotlib.pyplot as plt
import pandas as pd

from iminuit import Minuit
from probfit import BinnedChi2,Extended,gaussian,doublegaussian,Chi2Regression

from scipy.stats import norm

df = pd.read_csv('Na1copy.txt',delim_whitespace=True,names=['channel','number'])

'''
x_vals = np.linspace(start=300, stop=450, num=150)
density = norm.pdf(x=x_vals, loc=400.0, scale=25.0) * 1000000
df = pd.DataFrame(np.hstack([x_vals.reshape((-1, 1)), density.reshape((-1, 1))]), columns=['channel', 'number'])
'''

error = np.sqrt(df['number'])

fig,ax = plt.subplots(1,1,figsize=(13,7))
ax.plot(df['channel'] ,df['number'],'o')

ax.set_ylabel('count')
ax.set_xlabel('channel[ch]')

fig.savefig('out')

ext_gauss = Extended(gaussian)
#bc2 = BinnedChi2(ext_gauss,df['channel'],df['number'],error)

#これより最小二乗法でフィッティングする。
#データのx,y,yeを用いて線形のフィッティングの準備をする
x2r = Chi2Regression(ext_gauss,np.array(df['channel']),np.array(df['number']),np.array(error))

#初期値をm,cのようにしてx2rを解析する
fit = Minuit(x2r,mean=400,sigma=50,N=100,errordef=1.0)

#フィッティングを行う
fit.migrad()

#フィットして非対称的にエラーを評価する
fit.minos()

#結果を出力する
print(fit.params)

#最適化した値らを出力
print(fit.values)
#最適化したエラーを出力
print(fit.errors)

mean_fit = fit.values[0]
sigma_fit = fit.values[1]

fig = plt.figure(figsize=(10,5))
plt.subplot(111)
x2r.draw(fit)

fig.savefig('gauss_plot')

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

jbpb0

2022/12/26 10:36

> ピーク値から半分程度の値となるスペクトルの領域でフィッティングしたい 上記の「半分程度の値」とは、グラフの最大値25000くらいの、半分の12500くらいですか? それとも、グラフの最小値10000くらいと、最大値25000くらいの、中間の17500くらいですか?
kagakun1

2022/12/28 01:49

またありがとうございます!少しコメントから開けてしまい申し訳ありません。 フィッティングは後者の、グラフの最小値10000と、最大値25000の、中間の17500でフィッティングを行いたいです。つまり、ピークの部分についてのみ関数でフィッティングすることが目的です。
jbpb0

2022/12/28 03:01

> ピークの部分についてのみ関数でフィッティング ピーク以外を無視していいのなら、17500未満のデータを削除してからフィッティングを行えばいいのではないですかね
kagakun1

2022/12/28 08:25

自力で頑張ってみたらなんとかコードを作成できました! ありがとうございました!それではBAにしたいと思います。
jbpb0

2022/12/28 09:28

> 自力で頑張ってみたらなんとかコードを作成できました! とは、 > 17500未満のデータを削除してからフィッティングを行えば をやった、ということでしょうか?
kagakun1

2022/12/28 09:35

そうなりますね。 今まではNa1copy.txtのみで削除を行いながらフィッティングを行なってました。 そこで新しく一切削除を行わないオリジナルのデータNa.txtも用意し、それにMinuitで得られたパラメータのガウス関数を重ねてプロットしました。 助言をたくさんくださり、本当にありがとうございます!
guest

回答1

0

ベストアンサー

フィッティングがデータのピーク値と、ピーク値から半分程度の値となるスペクトルの領域でフィッティングしたい

「ピーク値から半分程度の値」よりも小さい値を削除してからフィッティングすればいいと思います

投稿2022/12/28 09:48

jbpb0

総合スコア7651

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問