[D0017] サンプリングケース生成

 

サンプリングケースの生成を行います。

import designer
import sys
import csv

app = designer.GetApplication()

def show_message_immediately(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()

if (sys.version_info < (3, 8)):
	title_en = u"Python Version Error"
	title_jp = u"Pythonバージョンエラー"
	message_en = u"Please use Python of newer version over 3.8"
	message_jp = u"バージョン3.8以上のPythonを使用してください。"
	show_message_immediately(title_en, title_jp, message_en, message_jp)
else:
	import numpy
	numpy.random.seed(None)

CURRENT_STUDY_OR_ANALYSISGROUP = app.GetCurrentAnalysisGroup()
if CURRENT_STUDY_OR_ANALYSISGROUP.IsValid() == False:
	CURRENT_STUDY_OR_ANALYSISGROUP = app.GetCurrentStudy()
OPTIMIZATION_TABLE = CURRENT_STUDY_OR_ANALYSISGROUP.GetOptimizationTable()

class DialogData:
	def __init__(self):
		self.method  = 1
		self.numcase = 1
		self.output  = ""
		self.isValid = False

def main():
	if (sys.version_info < (3, 8)):
		return

	dialogData = get_data_from_input_dialog()
	if dialogData.isValid == False:
		return

	# get parameters
	numParam   = OPTIMIZATION_TABLE.NumParameters()
	paramList  = dict()
	for i in range(numParam):
		param           = OPTIMIZATION_TABLE.GetParametricItem(i)
		name            = param.GetParameterName()
		varname         = param.GetItemName()
		varmin          = param.GetMin()
		varmax          = param.GetMax()
		if (varname == ""):
			paramList[name] = (varmin, varmax)
		else:
			paramList[varname] = (varmin, varmax)
	
	numParam = len(paramList)
	if numParam < 1:
		message_jp = u"パラメータ変数が指定されていません。"
		message_en = u"Parameter Variables are not specified."
		show_error_exit_message(message_en, message_jp)
		return

	numCases = dialogData.numcase
	data = dict()
	if dialogData.method == 1:
		lhs = lhs_function(numCases,numParam)
		for i, key in enumerate(paramList.keys()):
			varmin, varmax = paramList[key]
			data[key] = (varmax - varmin) * numpy.array([lhs[:,i]])[0] + varmin

	elif dialogData.method == 2:
		rng = numpy.random.RandomState()
		for key in paramList.keys():
			varmin, varmax = paramList[key]
			data[key] = numpy.random.uniform(varmin, varmax, numCases)
		
	else:
		message_jp = u"不明なエラー"
		message_en = u"Unknown Error"
		show_error_exit_message(message_en, message_jp)
		return

	try:
		with open(dialogData.output, 'w', newline='') as csvfile:
			field = ["Case", "Label", "Group"]
			for key in paramList.keys():
				field.append(key)
			writer = csv.DictWriter(csvfile, fieldnames=field, lineterminator='\n')
			writer.writeheader()
			for icase in range(numCases):
				row = {"Case":icase+1, "Label":"", "Group":""}
				for key in paramList.keys():
					row[key] = data[key][icase]
				writer.writerow(row)
	except:
		message_jp = u"\"%s\"を出力できませんでした。出力ファイルパスを見直してください。" % dialogData.output.decode()
		message_en = u"Cannot create \"%s\". Specify output file path." % dialogData.output.decode()
		show_error_exit_message(message_en, message_jp)
		return

	show_normal_exit_message()
	return

def get_data_from_input_dialog():
	dialog = create_input_dialog()
	return show_input_dialog(dialog)

def create_input_dialog():
	dialog = app.CreateDialogBox()

	title_jp = u"サンプリングケースの生成(β版)"
	title_en = u"Generate Sampling Cases(beta version)"

	method_jp  = u"サンプリング手法:"
	method_en  = u"Sampling Method:"
	random_jp  = u"ランダムサンプリング"
	random_en  = u"Random Sampling"
	lhs_jp     = u"ラテン超方格サンプリング"
	lhs_en     = u"Latin Hypercube Sampling"
	numcase_jp = u"生成ケース数:"
	numcase_en = u"Number of Generated Cases:"
	output_jp  = u"出力ファイル:"
	output_en  = u"Output File:"

	dialog.SetTranslation(title_en, title_jp)
	dialog.SetTranslation(method_en, method_jp)
	dialog.SetTranslation(random_en, random_jp)
	dialog.SetTranslation(lhs_en, lhs_jp)
	dialog.SetTranslation(numcase_en, numcase_jp)
	dialog.SetTranslation(output_en, output_jp)
	
	dialog.SetTitle(title_en)
	dialog.AddLabel(method_en)
	dialog.AddRadio("sampling_method", lhs_en, 1)
	dialog.AddRadio("sampling_method", random_en, 2)
	dialog.AddInteger("num_cases", numcase_en, 1)
	dialog.SetMinimum("num_cases", 1)
	dialog.AddSaveFilename("output_fname", output_en, "", "CSV file (*.csv)")

	return dialog

def show_input_dialog(dialog):
	dialog.Show()
	
	if dialog.WasCancelled() == False:
		data = get_values_from_input_dialog(dialog)
		if data.isValid == False:
			return show_input_dialog(dialog)
		return data
	return DialogData()

def get_values_from_input_dialog(dialog):
	data = DialogData()

	data.method  = dialog.GetValue("sampling_method")
	data.numcase = dialog.GetValue("num_cases")
	data.output  = dialog.GetValue("output_fname")

	if data.numcase == 0:
		message_en = u"Number of generated cases must be greater than zero."
		message_jp = u"生成ケース数はゼロより大きい値である必要があります。"
		show_error_exit_message(message_en, message_jp)
		return data

	if data.output == b"":
		message_en = u"Specify output file name."
		message_jp = u"出力ファイル名を指定してください。"
		show_error_exit_message(message_en, message_jp)
		return data

	data.isValid = True

	return data

def show_normal_exit_message():
	title_en = u"Finished"
	title_jp = u"終了"
	message_en = u"Finished."
	message_jp = u"終了"

	show_message(title_en, title_jp, message_en, message_jp)

def show_error_exit_message(message_en, message_jp):
	title_en = u"Error"
	title_jp = u"エラー"

	show_message(title_en, title_jp, message_en, message_jp)

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 lhs_function(n_sample, n_dim):
	grid_array = numpy.linspace(0, n_sample-1, n_sample)
	lhs_idx = numpy.zeros([n_sample, n_dim])
	for i in range(n_dim):
		lhs_idx[:, i] = numpy.random.permutation(grid_array)

	lhs_value = numpy.zeros([n_sample, n_dim])
	for i in range(n_sample):
		for j in range(n_dim):
			lhs_value[i, j] = (numpy.random.rand() + lhs_idx[i, j])/n_sample
	return lhs_value


if  __name__ == '__main__':
	main()

Download Python source code

ファイルご利用の注意点

JMAGスクリプトライブラリをご利用されるに際し、以下の利用規約をよくお読みいただき、ご同意の上ご利用下さるようお願い申し上げます。