### ViewScansBL3A ### JupyterNotebookで以下のcellを実行 #cell 1:最初に実行する #cell 2:csvに書かれたスキャン情報に従ってデータ処理してdatファイルを書き出す #cell 3:指定したスキャン番号のrawdataを標示する(1つだけ) #cell 4:指定したスキャン番号のrawdataを標示する(3つまで重ねて標示可能) ################ cell 1 ############### # 最初に実行 import numpy as np import os import csv import matplotlib.pyplot as plt import time from IPython.display import display, clear_output raw_dir = "rawdata4" # rawdataフォルダ名 save_dir = "data4" # data 保存フォルダ名 os.makedirs(save_dir, exist_ok=True) def load_file(filepath): data = [] with open(filepath, 'r') as f: for line in f: if line.startswith("#"): continue parts = line.split() if len(parts) > 0: data.append([float(x) for x in parts]) return np.array(data) def bindata(xx0, yy0, err0, cnts0, mon0, dxmin): while True: dx0 = np.abs(xx0[1:] - xx0[:-1]) dx0 = np.append(dx0, dx0[-1]) if np.min(dx0) >= dxmin: break ii = 0 while ii < len(xx0) - 1: dx = abs(xx0[ii+1] - xx0[ii]) if dx < dxmin: xx0[ii+1] = (xx0[ii] + xx0[ii+1]) / 2 yy0[ii+1] = (yy0[ii] + yy0[ii+1]) / 2 err0[ii+1] = np.sqrt(err0[ii]**2 + err0[ii+1]**2) / 2 cnts0[ii+1] = cnts0[ii] + cnts0[ii+1] mon0[ii+1] = mon0[ii] + mon0[ii+1] xx0 = np.delete(xx0, ii) yy0 = np.delete(yy0, ii) err0 = np.delete(err0, ii) cnts0 = np.delete(cnts0, ii) mon0 = np.delete(mon0, ii) ii += 1 else: ii += 1 return xx0, yy0, err0, cnts0, mon0 ####### ここまで ###### ############### cell 2 ############### start_line = 81 # CSVの処理範囲.最初の行番号(1はカラムの名前) end_line = 91 # 最後の行番号 plt.ion() #fig, ax = plt.subplots() plt.close('all') # ← 余計な空図を全部消す with open("scanlist3.csv", newline='', encoding='utf-8-sig') as f: # CSV filename reader = csv.reader(f) header = [h.strip() for h in next(reader)] for lineno, row_values in enumerate(reader, start=2): if lineno < start_line: continue if lineno > end_line: break row = dict(zip(header, row_values)) scan_numbers = [int(row[f"scan{i}"]) for i in range(1, 8)] scan_numbers = [s for s in scan_numbers if s != 0] xcol = int(row["xcol"]) moncol = int(row["moncol"]) datcol = int(row["datcol"]) mon1s = float(row["mon1s"]) bindx = float(row["bindx"]) # --- データ処理 --- xx0, yy0, err0, cnts0, mon0 = [], [], [], [], [] for i, scn in enumerate(scan_numbers): data = load_file(os.path.join(raw_dir, f"{scn}.txt")) x = data[:, xcol - 1] cnts = data[:, datcol] mon = data[:, moncol] y = cnts / mon * mon1s err = np.sqrt(cnts) / mon * mon1s if i == 0: xx0, yy0, err0, cnts0, mon0 = x, y, err, cnts, mon else: xx0 = np.concatenate([xx0, x]) yy0 = np.concatenate([yy0, y]) err0 = np.concatenate([err0, err]) cnts0 = np.concatenate([cnts0, cnts]) mon0 = np.concatenate([mon0, mon]) idx = np.argsort(xx0) xx0, yy0, err0, cnts0, mon0 = xx0[idx], yy0[idx], err0[idx], cnts0[idx], mon0[idx] xx0, yy0, err0, cnts0, mon0 = bindata(xx0, yy0, err0, cnts0, mon0, bindx) yy0 = cnts0 / mon0 * mon1s err0 = np.sqrt(cnts0) / mon0 * mon1s outfile = os.path.join(save_dir, f"scan{scan_numbers[0]}.dat") np.savetxt(outfile, np.column_stack([xx0, yy0, err0]), fmt="%.7g") # --- 図更新 --- clear_output(wait=True) plt.figure() plt.errorbar(xx0, yy0, yerr=err0, fmt='o-') plt.title(f"scan {scan_numbers[0]}") plt.show() input("Press Enter to continue (Ctrl+C to quit)") plt.close() plt.ioff() plt.show() ####### ここまで ###### ################# cell 3 ################## # 指定したスキャン番号のrawdata表示(1つずつ) import numpy as np import os import ipywidgets as widgets import matplotlib.pyplot as plt from IPython.display import display, clear_output raw_dir = "rawdata4" # rawdata フォルダ名 # ===== ファイル読み込み+ヘッダ抽出 ===== def load_scan(scnum): filepath = os.path.join(raw_dir, f"{scnum}.txt") header = { "scan": "-", "title": "-", "lambda": "-", "E": "-", "CEN": "-", "MAX": "-", "FWHM": "-", "MAX-y": "-", "abc": "-","Q": "-", "slits": "-", "datetime": "-" } data_lines = [] with open(filepath, "r") as f: for line in f: line = line.strip() if line.startswith("#S"): header["scan"] = line elif line.startswith("#D"): header["datetime"] = line[3:] elif line.startswith("#G1"): parts = line.split() header["abc"] = " ".join(parts[1:7]) elif line.startswith("#G4"): parts = line.split() lam = float(parts[4]) header["lambda"] = lam header["E"] = 12.39842 / lam elif line.startswith("#L"): header["title"] = line[3:] elif line.startswith("#Q"): header["Q"] = line[3:] elif line.startswith("#Tail1"): header["CEN"] = line elif line.startswith("#Tail2"): header["MAX-y"] = line elif line.startswith("# Slit1(v*h):"): header["slits"] = line elif not line.startswith("#") and len(line) > 0: data_lines.append([float(x) for x in line.split()]) data = np.array(data_lines) return header, data # ===== GUI ===== scan_box = widgets.IntText(value=1, description="Scan:") xcol_box = widgets.IntText(value=0, description="X col:") ycol_box = widgets.IntText(value=-1, description="Y col:") output = widgets.Output() def update(change=None): with output: clear_output(wait=True) scnum = scan_box.value xcol = xcol_box.value ycol = ycol_box.value header, data = load_scan(scnum) # 負のインデックス対応 if xcol < 0: xcol = data.shape[1] + xcol if ycol < 0: ycol = data.shape[1] + ycol x = data[:, xcol] y = data[:, ycol] err = np.sqrt(y) # ===== プロット ===== plt.figure(figsize=(5,4)) plt.errorbar(x, y, yerr=err, fmt='o-') plt.title(f"Scan {scnum}") plt.xlabel(f"col {xcol}") plt.ylabel(f"col {ycol}") plt.grid() plt.show() # ===== 情報表示 ===== print(header["scan"]) print(header["datetime"]) print(header["title"]) print(f"Q={header['Q']},lambda={header['lambda']}, E={header['E']}") print(f"lattice params = {header['abc']}") print(header["CEN"]) print(header["MAX-y"]) print(header["slits"]) # ===== イベント登録 ===== scan_box.observe(update, names='value') xcol_box.observe(update, names='value') ycol_box.observe(update, names='value') display(scan_box, xcol_box, ycol_box, output) update() ####### ここまで ###### ################## cell 4 #################### # 指定したスキャン番号のrawdata表示(3つまで重ねて表示可能) import numpy as np import os import ipywidgets as widgets import matplotlib.pyplot as plt from IPython.display import display, clear_output raw_dir = "rawdata4" # rawdata フォルダ名 # ===== ファイル読み込み+ヘッダ抽出 ===== def load_scan(scnum): filepath = os.path.join(raw_dir, f"{scnum}.txt") header = { "scan": "-", "title": "-", "lambda": "-", "E": "-", "CEN": "-", "MAX": "-", "FWHM": "-", "MAX-y": "-", "abc": "-", "angles": "-", "datetime": "-" } data_lines = [] with open(filepath, "r") as f: for line in f: line = line.strip() if line.startswith("#S"): header["scan"] = line elif line.startswith("#D"): header["datetime"] = line[3:] elif line.startswith("#G1"): parts = line.split() header["abc"] = " ".join(parts[1:4]) header["angles"] = " ".join(parts[4:7]) elif line.startswith("#G4"): parts = line.split() lam = float(parts[4]) header["lambda"] = lam header["E"] = 12.39842 / lam elif line.startswith("#L"): header["title"] = line[3:] elif line.startswith("#Tail1"): header["CEN"] = line elif line.startswith("#Tail2"): header["MAX-y"] = line elif not line.startswith("#") and len(line) > 0: data_lines.append([float(x) for x in line.split()]) data = np.array(data_lines) return header, data # ===== GUI ===== scan_box1 = widgets.IntText(value=1, description="Scan1:") scan_box2 = widgets.IntText(value=0, description="Scan2:") scan_box3 = widgets.IntText(value=0, description="Scan3:") moncol_box = widgets.IntText(value=-2, description="Mon col:") scale_box = widgets.FloatText(value=1.0, description="Scale:") use2 = widgets.Checkbox(value=False, description="Use 2") use3 = widgets.Checkbox(value=False, description="Use 3") #scan_box = widgets.IntText(value=1, description="Scan:") xcol_box = widgets.IntText(value=0, description="X col:") ycol_box = widgets.IntText(value=-1, description="Y col:") output = widgets.Output() def update(change=None): with output: clear_output(wait=True) scans = [scan_box1.value] if use2.value: scans.append(scan_box2.value) if use3.value: scans.append(scan_box3.value) xcol = xcol_box.value ycol = ycol_box.value moncol = moncol_box.value scale = scale_box.value plt.figure(figsize=(5,4)) for scnum in scans: header, data = load_scan(scnum) xc = xcol if xcol >= 0 else data.shape[1] + xcol yc = ycol if ycol >= 0 else data.shape[1] + ycol x = data[:, xc] # y = data[:, yc] # err = np.sqrt(y) mc = moncol if moncol >= 0 else data.shape[1] + moncol y_raw = data[:, yc] mon = data[:, mc] # ゼロ割り防止 mask = mon > 0 x = x[mask] y_raw = y_raw[mask] mon = mon[mask] y = y_raw / mon * scale err = np.sqrt(y_raw) / mon * scale plt.errorbar(x, y, yerr=err, fmt='o-', label=f"{scnum}") plt.title("Overlay Scans") plt.xlabel(f"col {xcol}") plt.ylabel(f"col {ycol}") plt.legend() plt.grid() plt.show() # --- 情報表示(1つ目だけでOKなら) --- header, data = load_scan(scans[0]) print(header["scan"]) print(header["title"]) # ===== rawデータ表示 ===== for i in range(min(3, data.shape[0])): row = data[i] print(" ".join(f"{v:.6g}" for v in row)) # ===== イベント登録 ===== scan_box1.observe(update, names='value') scan_box2.observe(update, names='value') scan_box3.observe(update, names='value') use2.observe(update, names='value') use3.observe(update, names='value') #scan_box.observe(update, names='value') xcol_box.observe(update, names='value') ycol_box.observe(update, names='value') display(scan_box1, widgets.HBox([use2, scan_box2]), widgets.HBox([use3, scan_box3]), xcol_box, ycol_box, moncol_box, scale_box, output) update() ####### ここまで ######