伝達関数のCSVファイルを作成する。
#from jmag.designer import designer
import designer
import csv
import traceback
import glob
import re
app = designer.GetApplication()
title_ja = u'伝達関数CSVファイルの作成'
title_en = u'Create transfer function csv file'
def show_message(title_en, title_jp, message_en, message_jp):
msgdlg = app.CreateDialogBox()
msgdlg.SetTranslation(title_en, title_jp)
msgdlg.SetTranslation(message_en, message_jp)
msgdlg.SetCancelButtonVisible(False)
msgdlg.SetTitle(title_en)
msgdlg.AddLabel(message_en)
msgdlg.Show()
def show_error_message(message_en, message_jp):
title_en = "Error"
title_jp = "エラー"
show_message(title_en, title_jp, message_en, message_jp)
class ForcePointData:
def __init__(self):
self.study_title = ""
self.probe_name = ""
self.type = ""
self.case_row = list()
self.case_group_row = list()
self.data_header_row = list()
self.freq = list()
self.val6d = list()
self.probe_names = list()
self.component_names = list()
self.num_observation_points = ""
def read_csv(self, csvreader, component_header):
row = next(csvreader)
self.study_title = row[0][row[0].find(":") + 1:]
row = next(csvreader)
self.probe_name = row[0]
row = next(csvreader)
self.type = row[0]
row = next(csvreader)
self.case_row = row
row = next(csvreader)
self.case_group_row = row
for row in csvreader:
if row[0].startswith('Frequency'):
break
if not row[0].startswith('Frequency'):
show_error_message(
f"The line beginning with \"Frequency\" was not found in the CSV.",
f"CSVファイルに Frequency で始まる行が見つかりませんでした。",
)
return False
self.data_header_row = row
items = [item.split(" (")[0] for item in self.data_header_row]
num_points = len(set(items)) - 1
self.num_observation_points = num_points
probe_namestmp = []
component_namestmp = []
NUM_VALUES_WRITTEN_PER_POINT = 12
for op in range(num_points):
pos_read = 7 + op * NUM_VALUES_WRITTEN_PER_POINT
probe_namestmp.extend(items[pos_read:pos_read+6])
component_namestmp.extend(component_header)
self.probe_names.append(probe_namestmp)
self.component_names.append(component_namestmp)
for row in csvreader:
self.freq.append(row[0])
val6dtmp = []
for op in range(num_points):
pos_read = 7 + op * NUM_VALUES_WRITTEN_PER_POINT
val6dtmp.extend(row[pos_read:pos_read+6])
self.val6d.append(val6dtmp)
return True
def reference_unit(self):
if self.type == "Velocity":
return "m/s"
elif self.type == "Acceleration":
return "m/s^2"
elif self.type == "Displacement":
return "m"
def read_files(fileList, component_header):
forcePoints = list()
for filePath in fileList:
try:
with open(filePath, "r", encoding="utf-8-sig") as f:
csvreader = csv.reader(f)
fp = ForcePointData()
success = fp.read_csv(csvreader, component_header)
if not success:
return None
forcePoints.append(fp)
except Exception as e:
(e)
show_error_message(
f"Error occurred while reading the CSV file.\n {filePath}\n\n{traceback.format_exc()}",
f"CSVファイル読み込み中にエラーが発生しました。\n {filePath}\n\n{traceback.format_exc()}",
)
return None
if not forcePoints:
show_error_message(
"No Force Points.",
"有効な加振点がありません。",
)
return forcePoints
def force_point_label(fp:ForcePointData, index:int):
dir_label = ("X","Y","Z")
return f"tooth:{index//3+1}:{dir_label[index%3]}"
def write_file(forcePoints, filePath):
try:
with open(filePath, "w", encoding="utf-8-sig", newline="") as f:
csvwriter = csv.writer(f)
csvwriter.writerow(["CSV Version","1.1.0"])
csvwriter.writerow(["Number of Force Points",str(len(forcePoints))])
observation_points_number = len(set(forcePoints[0].probe_names[0]))
csvwriter.writerow(["Number of Observation Points", observation_points_number])
csvwriter.writerow(["Number of Frequencies", len(forcePoints[0].freq)])
csvwriter.writerow(["Frequency Unit", "Hz"])
csvwriter.writerow(["Reference Unit", forcePoints[0].reference_unit()])
csvwriter.writerow(["Force Unit", "N"])
csvwriter.writerow(["Transfer Function Matrix"])
for i in range(len(forcePoints)):
fp: ForcePointData = forcePoints[i]
csvwriter.writerow(["Force Point Label", force_point_label(fp, i)])
probe_names = ['Observation Point Names'] + fp.probe_names[0]
csvwriter.writerow(probe_names)
component_names = ['Frequency'] + fp.component_names[0]
csvwriter.writerow(component_names)
for j in range(len(fp.freq)):
row = [fp.freq[j]]
row.extend(fp.val6d[j])
csvwriter.writerow(row)
except Exception as e:
(e)
show_error_message(
f"Error occurred while writing the CSV file.\n {filePath}\n\n{traceback.format_exc()}",
f"CSVファイル書き出し中にエラーが発生しました。\n {filePath}\n\n{traceback.format_exc()}",
)
return False
return True
def write_transfer_function_files(input_files, output_file_path, component_header):
force_points = read_files(input_files, component_header)
if not force_points:
return False
success = write_file(force_points, output_file_path)
return success
def atoi(text):
return int(text) if text.isdigit() else text
def natural_keys(text):
return [ atoi(c) for c in re.split(r'(\d+)', text) ]
def main():
xyz_component_header = ["x(real)", "x(imag)", "y(real)", "y(imag)", "z(real)", "z(imag)"]
rtz_component_header = ["r(real)", "r(imag)", "t(real)", "t(imag)", "z(real)", "z(imag)"]
label_study_csv_output_dir_ja = u'入力CSVファイルのフォルダ:'
label_study_csv_output_dir_en = u'Folder with Input CSV Files:'
label_explanation_ja = u'入力ファイルのフォルダに次のファイルが出力されます。'
label_explanation_en = u'The following files will be output in the folder.'
dialog = app.CreateDialogBox()
dialog.SetTranslation(title_en, title_ja)
dialog.SetTranslation(label_study_csv_output_dir_en, label_study_csv_output_dir_ja)
dialog.SetTranslation(label_explanation_en, label_explanation_ja)
dialog.SetTitle(title_en)
dialog.SetModal(True)
dialog.AddLabel(label_study_csv_output_dir_en, 0, 1)
dialog.AddDirectoryPath("study_csv_output_dir", "", "", 1, 2)
dialog.AddLabel("", 0, 1)
dialog.AddLabel(label_explanation_en, 1, 2)
dialog.AddLabel("", 0, 1)
dialog.AddLabel("transfer_function-xyz.csv", 1, 2)
dialog.AddLabel("", 0, 1)
dialog.AddLabel("transfer_function-rtz.csv", 1, 2)
ret = dialog.Show()
if ret==0:
return False
study_csv_output_dir = dialog.GetValue("study_csv_output_dir").decode(encoding='utf-8')
if study_csv_output_dir == "":
show_error_message("Folder with Input CSV Files is not specified.", "入力CSVファイルのフォルダが指定されていません。")
return False
XYZInputFiles = glob.glob(study_csv_output_dir+'/'+'*_probe_ObservationPoint-xyz(*).csv')
RTZInputFiles = glob.glob(study_csv_output_dir+'/'+'*_probe_ObservationPoint-rtz(*).csv')
XYZInputFiles = sorted(XYZInputFiles, key=natural_keys)
RTZInputFiles = sorted(RTZInputFiles, key=natural_keys)
success = write_transfer_function_files(XYZInputFiles, study_csv_output_dir+'/'+'transfer_function-xyz.csv', xyz_component_header)
if not success:
return False;
success = write_transfer_function_files(RTZInputFiles, study_csv_output_dir+'/'+'transfer_function-rtz.csv', rtz_component_header)
if not success:
return False;
message_finished_ja = u"伝達関数CSVファイルの作成が終了しました。"
message_finished_en = u"Creation of transfer function csv file has been completed,"
show_message(title_en, title_ja, message_finished_en, message_finished_ja)
main()


