如何在数码显微照片中在 dm-script 和 python 之间进行通信
How to communicate between dm-script and python in Digital Micrograph
我如何在 dm-script
代码和 python
代码之间进行通信,两者都在数码显微照片中执行?
在我的具体情况下,我有复杂的对话。因为对话框在 python
中不受支持,但在 dm-script
中,我在 dm-script
中编写了我的对话框。现在的问题是从对话框传递到 python 代码。
考虑以下示例:
import DigitalMicrograph as DM
script = """string field_value = "";
class ButtonDialog : UIFrame{
void field_changed(object self, TagGroup field){
field_value = field.DLGGetStringValue();
}
object init(object self){
TagGroup dlg, dlg_items, field;
dlg = DLGCreateDialog("Type in a number", dlg_items);
dlg.DLGAddElement(DLGCreateLabel("Number:"));
field = DLGCreateIntegerField(0, 10, "field_changed");
dlg.DLGAddElement(field);
self.super.init(dlg);
return self;
}
}
object dialog = alloc(ButtonDialog).init();
dialog.pose();
"""
DM.ExecuteScriptString(script)
# how do I get this?
field_value = ""
要在 dm-script
和 python
之间同步数据,而两者都是 运行 在同一实例中(本例中的线程,也可以针对不同的线程进行修改)可以使用持久性标签.
dm-script
正在设置永久标签。 python
然后可以再次读取持久性标签。
更新:Python 模块
由于下面提到的限制以及不断增长和不可读的代码,我决定为此编写自己的 python 模块。使用 execdmscript
可以很容易地从数码显微照片执行带有变量同步的 dm-script 代码。
查看以下示例:
from execdmscript import exec_dmscript
# some script to execute
dmscript = """
number input;
number s = GetNumber("Enter a number between " + min + " and " + max + ".", init, input);"
"""
# variables that will be defined for the dm-scripts (and readable later on in python)
sv = {"min": 1, "max": 10, "init": 2}
# variables the dm-script defines and that should be readable in the python file
rv = {"input": "number", "s": "number"}
with exec_dmscript(dmscript, readvars=rv, setvars=sv) as script:
if script["s"]:
print(script["input"])
else:
print("User pressed cancel.")
这隐藏了所有 dm-script 相关的保存和问题(如下所述)。它允许使用 list
和 dict
以及 bool
、str
、int
和 float
等基本类型。所有类型和值都可以以 pythonic 方式使用,无需关心 dm-script 类型。 dm-script 可以移动到单独的文件中以进一步清理代码。
请注意,对于调试,有一个 exec_dmscript(debug=True, debug_file="path/to/file")
开关可以将代码保存到给定的 debug_file
。然后可以在显示错误的 GMS 中手动执行此文件。
Disclaimer: As mentioned, I am the author of the execdmscript
module. Still I think this is the best solution for this case. In fact this question was the reason I wrote the module.
基本数据类型
对于 string
和 number
等基本数据类型,可以手动创建和添加代码。下面的例子展示了这个想法:
import DigitalMicrograph as DM
import time
sync_id = "sync-{}".format(int(time.time() * 100))
dmscript = """
number input;
number s = GetNumber("Enter a number between {min} and {max}.", {init}, input);
TagGroup p = GetPersistentTagGroup();
p.TagGroupSetTagAsBoolean("{id}-success", s);
p.TagGroupSetTagAsLong("{id}-input", input);
"""
DM.ExecuteScriptString(dmscript.format(min=1, max=10, init=2, id=sync_id))
# cannot save TagGroups to variables, check below
s, success = DM.GetPersistentTagGroup().GetTagAsBoolean("{}-success".format(sync_id))
if s and success:
# cannot save TagGroups to variables, check below
s, input = DM.GetPersistentTagGroup().GetTagAsLong("{}-input".format(sync_id))
if s:
print(input)
else:
print("Did not find 'input' in persistent tags.")
elif not s:
print("Did not find 'success' in persistent tags.")
else:
print("User clicked cancel.")
# cannot save TagGroups to variables, check below
# delete tag, otherwise the persistent tags gets filled with garbage
DM.GetPersistentTagGroup().DeleteTagWithLabel("{}-success".format(sync_id))
DM.GetPersistentTagGroup().DeleteTagWithLabel("{}-input".format(sync_id))
可以看到这种方法有一些缺点。有很多代码创建设置和仅输入一个数字的同步。这使代码变得混乱。也有人可能想将 dm-script 代码保存在一个单独的文件中,添加 python 文件打开。在此代码中调试 dm-script 代码也很困难。最后,TagGroup 在 python 一侧旅行有限制(查看下方)。
限制
更新:下面提到的python模块可以处理TagGrou
s和TagList
s,因为它保存了它们线性化和分开键和类型。
请注意 TagGroup
很难同步。 TagGroup
s 不得分配给变量。一旦它们存在,它们就不再可用了。这可以通过以下非常简单的代码来说明:
import DigitalMicrograph as DM
# create group for the example
group1 = DM.NewTagGroup()
group1.SetTagAsString("test-string", "test content")
print("Group 1 valid:", group1.IsValid(), "(type:", type(group1), ")")
# save to persistent tags
DM.GetPersistentTagGroup().SetTagAsTagGroup("test", group1)
# get the group without assigning to a variable, works
s, group2 = DM.GetPersistentTagGroup().GetTagAsTagGroup("test")
print("Group 2 success:", s, ", valid:", group2.IsValid(), "(type:", type(group2), ")")
# assign one parent group to a variable, doesn't work
tags = DM.GetPersistentTagGroup()
s, group3 = tags.GetTagAsTagGroup("test")
print("Group 3 success:", s, ", valid:", group3.IsValid(), "(type:", type(group3), ")")
此代码将产生输出
Group 1 valid: True (type: <class 'DigitalMicrograph.Py_TagGroup'> )
Group 2 success: True , valid: True (type: <class 'DigitalMicrograph.Py_TagGroup'> )
Group 3 success: True , valid: False (type: <class 'DigitalMicrograph.Py_TagGroup'> )
这表明您不能将 TagGroup
分配给 python 变量。
异步想法
这可以针对异步应用程序进行扩展。 dm-script
和 python
实现可以设置观察持久性标签的线程。 (请注意,您可以使用 TagGroupMarkAsChanged()
将 TagGroup
标记为已修改),最好使用不同的标签。然后两者都可以将命令 and/or 数据添加到标签中。另一个“实例”可以读取和处理它们。
这必须手动编码。这(目前)未包含在 execdmscript
模块中。
DM-scripts 调用 Python 个脚本
这个答案显示了 Python 和 DM-script 之间的一些交流,但形成了相反的一面。它还使用持久性 tagGroup 作为 transfer-proxy.
从 DM 脚本Python传入和传出简单值
// //////////////////////////////////////////////////
// Helper methods
// Build the DM-String representing the PythonScript
// which is then called
// //////////////////////////////////////////////////
string AddPythonValueIN( number val, string valName, string valType )
{
string py
py += "\n#Get value DM->Python via global tags" + "\n"
py += "success, " + valName + " = DM.GetPersistentTagGroup().GetTagAs" + valType + "('Python_temp:in:" + valName + "')" + "\n"
py += "if False == success:" + "\n"
py += " print( 'Error. No value passed in by DM-script sucessfully.' )" + "\n"
py += " exit(0)" + "\n"
return py
}
string AddPythonValueIN( string val, string valName, string valType )
{
string py
py += "\n#Get value DM->Python via global tags" + "\n"
py += "success, " + valName + " = DM.GetPersistentTagGroup().GetTagAs" + valType + "('Python_temp:in:" + valName + "')" + "\n"
py += "if False == success:" + "\n"
py += " print( 'Error. No value passed in by DM-script sucessfully.' )" + "\n"
py += " exit(0)" + "\n"
return py
}
string AddPythonValueOut( string valName, string valType )
{
string py
py += "\n#Get value Python->DM via global tags" + "\n"
py += "DM.GetPersistentTagGroup().SetTagAs" + valType + "('Python_temp:out:" + valName + "'," + valName + ")" + "\n"
return py
}
string AddPythonPrintModifyPrint()
{
string py
py += "\n#Print InValue, modify, print OutValue" + "\n"
py += "print('InValue',InValue)"+ "\n"
py += "OutValue = InValue * 2" + "\n"
py += "print('OutValue',OutValue)"+ "\n"
return py
}
// //////////////////////////////////////////////////
// Example calls
// Demonstrating value passing from DM script to a
// called Python snippet. TagTypes need to be
// explicit in Python.
// //////////////////////////////////////////////////
void PythonValueInAndOut_Float()
{
number value = 13.2
GetPersistentTagGroup().TagGroupSetTagAsFloat("Python_temp:in:InValue",value)
Result( " DM-Script passed value in: " + value + "\n")
string py = "#Script to demonstrate value passing in Hybrid scripts. DM calling Python." + "\n"
py += AddPythonValueIN( value, "InValue", "Float" )
py += AddPythonPrintModifyPrint()
py += AddPythonValueOut( "OutValue", "Float" )
Result( "\n PYTHON CODE EXECUTES\n --------------------- \n\n" )
ExecutePythonScriptString( py, 1 )
Result( "\n --------------------- \n PYTHON CODE FINISHED \n\n" )
if ( !GetPersistentTagGroup().TagGroupGetTagAsFloat("Python_temp:out:OutValue",value))
Throw("Python value passed out not found.")
Result( "DM-Script received value: " + value + "\n")
GetPersistentTagGroup().TagGroupDeleteTagWithLabel("Python_temp")
}
void PythonValueInAndOut_Double()
{
number value = 13.2
GetPersistentTagGroup().TagGroupSetTagAsDouble("Python_temp:in:InValue",value)
Result( " DM-Script passed value in: " + value + "\n")
string py = "#Script to demonstrate value passing in Hybrid scripts. DM calling Python." + "\n"
py += AddPythonValueIN( value, "InValue", "Double" )
py += AddPythonPrintModifyPrint()
py += AddPythonValueOut( "OutValue", "Double" )
Result( "\n PYTHON CODE EXECUTES\n --------------------- \n\n" )
ExecutePythonScriptString( py, 1 )
Result( "\n --------------------- \n PYTHON CODE FINISHED \n\n" )
if ( !GetPersistentTagGroup().TagGroupGetTagAsDouble("Python_temp:out:OutValue",value))
Throw("Python value passed out not found.")
Result( "DM-Script received value: " + value + "\n")
GetPersistentTagGroup().TagGroupDeleteTagWithLabel("Python_temp")
}
void PythonValueInAndOut_String()
{
string value = "hallo"
GetPersistentTagGroup().TagGroupSetTagAsString("Python_temp:in:InValue",value)
Result( " DM-Script passed value in: " + value + "\n")
string py = "#Script to demonstrate value passing in Hybrid scripts. DM calling Python." + "\n"
py += AddPythonValueIN( value, "InValue", "String" )
py += AddPythonPrintModifyPrint()
py += AddPythonValueOut( "OutValue", "String" )
Result( "\n PYTHON CODE EXECUTES\n --------------------- \n\n" )
ExecutePythonScriptString( py, 1 )
Result( "\n --------------------- \n PYTHON CODE FINISHED \n\n" )
if ( !GetPersistentTagGroup().TagGroupGetTagAsString("Python_temp:out:OutValue",value))
Throw("Python value passed out not found.")
Result( "DM-Script received value: " + value + "\n")
GetPersistentTagGroup().TagGroupDeleteTagWithLabel("Python_temp")
}
ClearResults()
PythonValueInAndOut_float()
PythonValueInAndOut_double()
PythonValueInAndOut_string()
从 DM 脚本Python传入和传出图像数据
// Images and other objects which are in memory can be most easily passed
// by passing their ID value and then finding them by ID.
// However, this does not work if the object would go out of scope at the
// end of a script (like an image which is not displayed)
//
// To pass a NumpyArray out of Python without showing an image, one can
// instead write the array to the global tags directly, together with the
// information needed to read the tags out into a DM-image
void PythonImageInOut( )
{
image img := RealImage("test",4,5,5)
img = icol
Result( " DM-Script passed image ["+img.ImageGetLabel()+"] in.\n")
string py
py += "\n#Get image DM->Python via imageLabel" + "\n"
py += "img = DM.FindImageByID("+ img.ImageGetID()+")" + "\n"
py += "if None == img:" + "\n"
py += " print( 'Error.No image passed in by DM-script sucessfully.' )" + "\n"
py += " exit(0)" + "\n"
py += "\n"
py += "print('Image from DM: Label = ', img.GetLabel())" + "\n"
py += "print('Image from DM: Name = ', img.GetName())" + "\n"
py += "print('Image from DM: Value = \n', img.GetNumArray())" + "\n"
py += "del img #ALWAYS delete DM objects in Python scripts" + "\n"
py += "\n"
py += "\n#Create DM image in Python and pass out as ID via global tags" + "\n"
py += "import numpy as np" + "\n"
py += "data = np.arange(48).reshape(6,8)" + "\n"
py += "outImg = DM.CreateImage(data.copy(order='C'))" + "\n"
py += "DM.GetPersistentTagGroup().SetTagAsLong('Python_temp:out:ID',outImg.GetID())" + "\n"
py += "print('Create new image with ID:',outImg.GetID())"+"\n"
py += "outImg.ShowImage() #Image needs to be shown or it will not stay in memory" + "\n"
py += "del outImg #ALWAYS delete DM objects in Python scripts" + "\n"
Result( "\n PYTHON CODE EXECUTES\n --------------------- \n\n" )
ExecutePythonScriptString( py, 1 )
Result( "\n --------------------- \n PYTHON CODE FINISHED \n\n" )
number imgID
if ( !GetPersistentTagGroup().TagGroupGetTagAsLong("Python_temp:out:ID",imgID))
Throw("Python imageID value passed out not found.")
image outImg := FindImageByID(imgID)
if ( !outImg.ImageIsValid() )
Throw("Python imageID value passed out but no matching image found.")
Result( "DM-Script received image: " + outImg.ImageGetLabel()+ "\n")
GetPersistentTagGroup().TagGroupDeleteTagWithLabel("Python_temp")
}
void PythonArrayOut( )
{
string py
py += "#Passing Numpy array values via global tags" + "\n"
py += "import numpy as np" + "\n"
py += "data = np.arange(6*8*3).reshape(6,8,3)" + "\n"
py += "outImg = DM.CreateImage(data.copy(order='C'))" + "\n"
py += "DM.GetPersistentTagGroup().SetTagAsArray('Python_temp:out:array',outImg)" + "\n"
py += "DM.GetPersistentTagGroup().SetTagAsLong('Python_temp:out:type',outImg.GetDataType())" + "\n"
py += "for i in range(data.ndim,0,-1):" + "\n"
py += " DM.GetPersistentTagGroup().SetTagAsLong('Python_temp:out:dim:' + str(i-1),data.shape[i-1])" + "\n"
py += "\n"
py += "del outImg #ALWAYS delete DM objects in Python scripts" + "\n"
Result( "\n PYTHON CODE EXECUTES\n --------------------- \n\n" )
ExecutePythonScriptString( py, 1 )
Result( "\n --------------------- \n PYTHON CODE FINISHED \n\n" )
number dataType
if ( !GetPersistentTagGroup().TagGroupGetTagAsLong("Python_temp:out:type",dataType))
Throw("Python dataType value passed out not found.")
TagGroup dimTG
if ( !GetPersistentTagGroup().TagGroupGetTagAsTagGroup("Python_temp:out:dim",dimTG))
Throw("Python dimensions passed out not found.")
number nDim = dimTG.TagGroupCountTags()
number n0, n1, n2, n3, n4
dimTG.TagGroupGetIndexedTagAsLong(0,n0)
dimTG.TagGroupGetIndexedTagAsLong(1,n1)
dimTG.TagGroupGetIndexedTagAsLong(2,n2)
dimTG.TagGroupGetIndexedTagAsLong(3,n3)
dimTG.TagGroupGetIndexedTagAsLong(4,n4)
image outImg
if ( 1 == nDim )
outImg := NewImage("Test", dataType, n0 )
else if ( 2 == nDim )
outImg := NewImage("Test", dataType, n0, n1 )
else if ( 3 == nDim )
outImg := NewImage("Test", dataType, n0, n1, n2 )
else if ( 4 == nDim )
outImg := NewImage("Test", dataType, n0, n1, n2, n3 )
else if ( 5 == nDim )
outImg := NewImage("Test", dataType, n0, n1, n2, n3, n4 )
if ( !GetPersistentTagGroup().TagGroupGetTagAsArray("Python_temp:out:array",outImg))
Throw("Python array data passed out not found.")
Result("\n DM recreated image from array values: " + outImg.ImageGetLabel()+ "\n")
GetPersistentTagGroup().TagGroupDeleteTagWithLabel("Python_temp")
}
clearresults()
Result("\n\nEXAMPLE Python<->DM image passing\n")
PythonImageInOut()
Result("\n\nEXAMPLE Python-->DM array passing\n")
PythonArrayOut( )
我如何在 dm-script
代码和 python
代码之间进行通信,两者都在数码显微照片中执行?
在我的具体情况下,我有复杂的对话。因为对话框在 python
中不受支持,但在 dm-script
中,我在 dm-script
中编写了我的对话框。现在的问题是从对话框传递到 python 代码。
考虑以下示例:
import DigitalMicrograph as DM
script = """string field_value = "";
class ButtonDialog : UIFrame{
void field_changed(object self, TagGroup field){
field_value = field.DLGGetStringValue();
}
object init(object self){
TagGroup dlg, dlg_items, field;
dlg = DLGCreateDialog("Type in a number", dlg_items);
dlg.DLGAddElement(DLGCreateLabel("Number:"));
field = DLGCreateIntegerField(0, 10, "field_changed");
dlg.DLGAddElement(field);
self.super.init(dlg);
return self;
}
}
object dialog = alloc(ButtonDialog).init();
dialog.pose();
"""
DM.ExecuteScriptString(script)
# how do I get this?
field_value = ""
要在 dm-script
和 python
之间同步数据,而两者都是 运行 在同一实例中(本例中的线程,也可以针对不同的线程进行修改)可以使用持久性标签.
dm-script
正在设置永久标签。 python
然后可以再次读取持久性标签。
更新:Python 模块
由于下面提到的限制以及不断增长和不可读的代码,我决定为此编写自己的 python 模块。使用 execdmscript
可以很容易地从数码显微照片执行带有变量同步的 dm-script 代码。
查看以下示例:
from execdmscript import exec_dmscript
# some script to execute
dmscript = """
number input;
number s = GetNumber("Enter a number between " + min + " and " + max + ".", init, input);"
"""
# variables that will be defined for the dm-scripts (and readable later on in python)
sv = {"min": 1, "max": 10, "init": 2}
# variables the dm-script defines and that should be readable in the python file
rv = {"input": "number", "s": "number"}
with exec_dmscript(dmscript, readvars=rv, setvars=sv) as script:
if script["s"]:
print(script["input"])
else:
print("User pressed cancel.")
这隐藏了所有 dm-script 相关的保存和问题(如下所述)。它允许使用 list
和 dict
以及 bool
、str
、int
和 float
等基本类型。所有类型和值都可以以 pythonic 方式使用,无需关心 dm-script 类型。 dm-script 可以移动到单独的文件中以进一步清理代码。
请注意,对于调试,有一个 exec_dmscript(debug=True, debug_file="path/to/file")
开关可以将代码保存到给定的 debug_file
。然后可以在显示错误的 GMS 中手动执行此文件。
Disclaimer: As mentioned, I am the author of the
execdmscript
module. Still I think this is the best solution for this case. In fact this question was the reason I wrote the module.
基本数据类型
对于 string
和 number
等基本数据类型,可以手动创建和添加代码。下面的例子展示了这个想法:
import DigitalMicrograph as DM
import time
sync_id = "sync-{}".format(int(time.time() * 100))
dmscript = """
number input;
number s = GetNumber("Enter a number between {min} and {max}.", {init}, input);
TagGroup p = GetPersistentTagGroup();
p.TagGroupSetTagAsBoolean("{id}-success", s);
p.TagGroupSetTagAsLong("{id}-input", input);
"""
DM.ExecuteScriptString(dmscript.format(min=1, max=10, init=2, id=sync_id))
# cannot save TagGroups to variables, check below
s, success = DM.GetPersistentTagGroup().GetTagAsBoolean("{}-success".format(sync_id))
if s and success:
# cannot save TagGroups to variables, check below
s, input = DM.GetPersistentTagGroup().GetTagAsLong("{}-input".format(sync_id))
if s:
print(input)
else:
print("Did not find 'input' in persistent tags.")
elif not s:
print("Did not find 'success' in persistent tags.")
else:
print("User clicked cancel.")
# cannot save TagGroups to variables, check below
# delete tag, otherwise the persistent tags gets filled with garbage
DM.GetPersistentTagGroup().DeleteTagWithLabel("{}-success".format(sync_id))
DM.GetPersistentTagGroup().DeleteTagWithLabel("{}-input".format(sync_id))
可以看到这种方法有一些缺点。有很多代码创建设置和仅输入一个数字的同步。这使代码变得混乱。也有人可能想将 dm-script 代码保存在一个单独的文件中,添加 python 文件打开。在此代码中调试 dm-script 代码也很困难。最后,TagGroup 在 python 一侧旅行有限制(查看下方)。
限制
更新:下面提到的python模块可以处理TagGrou
s和TagList
s,因为它保存了它们线性化和分开键和类型。
请注意 TagGroup
很难同步。 TagGroup
s 不得分配给变量。一旦它们存在,它们就不再可用了。这可以通过以下非常简单的代码来说明:
import DigitalMicrograph as DM
# create group for the example
group1 = DM.NewTagGroup()
group1.SetTagAsString("test-string", "test content")
print("Group 1 valid:", group1.IsValid(), "(type:", type(group1), ")")
# save to persistent tags
DM.GetPersistentTagGroup().SetTagAsTagGroup("test", group1)
# get the group without assigning to a variable, works
s, group2 = DM.GetPersistentTagGroup().GetTagAsTagGroup("test")
print("Group 2 success:", s, ", valid:", group2.IsValid(), "(type:", type(group2), ")")
# assign one parent group to a variable, doesn't work
tags = DM.GetPersistentTagGroup()
s, group3 = tags.GetTagAsTagGroup("test")
print("Group 3 success:", s, ", valid:", group3.IsValid(), "(type:", type(group3), ")")
此代码将产生输出
Group 1 valid: True (type: <class 'DigitalMicrograph.Py_TagGroup'> )
Group 2 success: True , valid: True (type: <class 'DigitalMicrograph.Py_TagGroup'> )
Group 3 success: True , valid: False (type: <class 'DigitalMicrograph.Py_TagGroup'> )
这表明您不能将 TagGroup
分配给 python 变量。
异步想法
这可以针对异步应用程序进行扩展。 dm-script
和 python
实现可以设置观察持久性标签的线程。 (请注意,您可以使用 TagGroupMarkAsChanged()
将 TagGroup
标记为已修改),最好使用不同的标签。然后两者都可以将命令 and/or 数据添加到标签中。另一个“实例”可以读取和处理它们。
这必须手动编码。这(目前)未包含在 execdmscript
模块中。
DM-scripts 调用 Python 个脚本
这个答案显示了 Python 和 DM-script 之间的一些交流,但形成了相反的一面。它还使用持久性 tagGroup 作为 transfer-proxy.
从 DM 脚本Python传入和传出简单值
// //////////////////////////////////////////////////
// Helper methods
// Build the DM-String representing the PythonScript
// which is then called
// //////////////////////////////////////////////////
string AddPythonValueIN( number val, string valName, string valType )
{
string py
py += "\n#Get value DM->Python via global tags" + "\n"
py += "success, " + valName + " = DM.GetPersistentTagGroup().GetTagAs" + valType + "('Python_temp:in:" + valName + "')" + "\n"
py += "if False == success:" + "\n"
py += " print( 'Error. No value passed in by DM-script sucessfully.' )" + "\n"
py += " exit(0)" + "\n"
return py
}
string AddPythonValueIN( string val, string valName, string valType )
{
string py
py += "\n#Get value DM->Python via global tags" + "\n"
py += "success, " + valName + " = DM.GetPersistentTagGroup().GetTagAs" + valType + "('Python_temp:in:" + valName + "')" + "\n"
py += "if False == success:" + "\n"
py += " print( 'Error. No value passed in by DM-script sucessfully.' )" + "\n"
py += " exit(0)" + "\n"
return py
}
string AddPythonValueOut( string valName, string valType )
{
string py
py += "\n#Get value Python->DM via global tags" + "\n"
py += "DM.GetPersistentTagGroup().SetTagAs" + valType + "('Python_temp:out:" + valName + "'," + valName + ")" + "\n"
return py
}
string AddPythonPrintModifyPrint()
{
string py
py += "\n#Print InValue, modify, print OutValue" + "\n"
py += "print('InValue',InValue)"+ "\n"
py += "OutValue = InValue * 2" + "\n"
py += "print('OutValue',OutValue)"+ "\n"
return py
}
// //////////////////////////////////////////////////
// Example calls
// Demonstrating value passing from DM script to a
// called Python snippet. TagTypes need to be
// explicit in Python.
// //////////////////////////////////////////////////
void PythonValueInAndOut_Float()
{
number value = 13.2
GetPersistentTagGroup().TagGroupSetTagAsFloat("Python_temp:in:InValue",value)
Result( " DM-Script passed value in: " + value + "\n")
string py = "#Script to demonstrate value passing in Hybrid scripts. DM calling Python." + "\n"
py += AddPythonValueIN( value, "InValue", "Float" )
py += AddPythonPrintModifyPrint()
py += AddPythonValueOut( "OutValue", "Float" )
Result( "\n PYTHON CODE EXECUTES\n --------------------- \n\n" )
ExecutePythonScriptString( py, 1 )
Result( "\n --------------------- \n PYTHON CODE FINISHED \n\n" )
if ( !GetPersistentTagGroup().TagGroupGetTagAsFloat("Python_temp:out:OutValue",value))
Throw("Python value passed out not found.")
Result( "DM-Script received value: " + value + "\n")
GetPersistentTagGroup().TagGroupDeleteTagWithLabel("Python_temp")
}
void PythonValueInAndOut_Double()
{
number value = 13.2
GetPersistentTagGroup().TagGroupSetTagAsDouble("Python_temp:in:InValue",value)
Result( " DM-Script passed value in: " + value + "\n")
string py = "#Script to demonstrate value passing in Hybrid scripts. DM calling Python." + "\n"
py += AddPythonValueIN( value, "InValue", "Double" )
py += AddPythonPrintModifyPrint()
py += AddPythonValueOut( "OutValue", "Double" )
Result( "\n PYTHON CODE EXECUTES\n --------------------- \n\n" )
ExecutePythonScriptString( py, 1 )
Result( "\n --------------------- \n PYTHON CODE FINISHED \n\n" )
if ( !GetPersistentTagGroup().TagGroupGetTagAsDouble("Python_temp:out:OutValue",value))
Throw("Python value passed out not found.")
Result( "DM-Script received value: " + value + "\n")
GetPersistentTagGroup().TagGroupDeleteTagWithLabel("Python_temp")
}
void PythonValueInAndOut_String()
{
string value = "hallo"
GetPersistentTagGroup().TagGroupSetTagAsString("Python_temp:in:InValue",value)
Result( " DM-Script passed value in: " + value + "\n")
string py = "#Script to demonstrate value passing in Hybrid scripts. DM calling Python." + "\n"
py += AddPythonValueIN( value, "InValue", "String" )
py += AddPythonPrintModifyPrint()
py += AddPythonValueOut( "OutValue", "String" )
Result( "\n PYTHON CODE EXECUTES\n --------------------- \n\n" )
ExecutePythonScriptString( py, 1 )
Result( "\n --------------------- \n PYTHON CODE FINISHED \n\n" )
if ( !GetPersistentTagGroup().TagGroupGetTagAsString("Python_temp:out:OutValue",value))
Throw("Python value passed out not found.")
Result( "DM-Script received value: " + value + "\n")
GetPersistentTagGroup().TagGroupDeleteTagWithLabel("Python_temp")
}
ClearResults()
PythonValueInAndOut_float()
PythonValueInAndOut_double()
PythonValueInAndOut_string()
从 DM 脚本Python传入和传出图像数据
// Images and other objects which are in memory can be most easily passed
// by passing their ID value and then finding them by ID.
// However, this does not work if the object would go out of scope at the
// end of a script (like an image which is not displayed)
//
// To pass a NumpyArray out of Python without showing an image, one can
// instead write the array to the global tags directly, together with the
// information needed to read the tags out into a DM-image
void PythonImageInOut( )
{
image img := RealImage("test",4,5,5)
img = icol
Result( " DM-Script passed image ["+img.ImageGetLabel()+"] in.\n")
string py
py += "\n#Get image DM->Python via imageLabel" + "\n"
py += "img = DM.FindImageByID("+ img.ImageGetID()+")" + "\n"
py += "if None == img:" + "\n"
py += " print( 'Error.No image passed in by DM-script sucessfully.' )" + "\n"
py += " exit(0)" + "\n"
py += "\n"
py += "print('Image from DM: Label = ', img.GetLabel())" + "\n"
py += "print('Image from DM: Name = ', img.GetName())" + "\n"
py += "print('Image from DM: Value = \n', img.GetNumArray())" + "\n"
py += "del img #ALWAYS delete DM objects in Python scripts" + "\n"
py += "\n"
py += "\n#Create DM image in Python and pass out as ID via global tags" + "\n"
py += "import numpy as np" + "\n"
py += "data = np.arange(48).reshape(6,8)" + "\n"
py += "outImg = DM.CreateImage(data.copy(order='C'))" + "\n"
py += "DM.GetPersistentTagGroup().SetTagAsLong('Python_temp:out:ID',outImg.GetID())" + "\n"
py += "print('Create new image with ID:',outImg.GetID())"+"\n"
py += "outImg.ShowImage() #Image needs to be shown or it will not stay in memory" + "\n"
py += "del outImg #ALWAYS delete DM objects in Python scripts" + "\n"
Result( "\n PYTHON CODE EXECUTES\n --------------------- \n\n" )
ExecutePythonScriptString( py, 1 )
Result( "\n --------------------- \n PYTHON CODE FINISHED \n\n" )
number imgID
if ( !GetPersistentTagGroup().TagGroupGetTagAsLong("Python_temp:out:ID",imgID))
Throw("Python imageID value passed out not found.")
image outImg := FindImageByID(imgID)
if ( !outImg.ImageIsValid() )
Throw("Python imageID value passed out but no matching image found.")
Result( "DM-Script received image: " + outImg.ImageGetLabel()+ "\n")
GetPersistentTagGroup().TagGroupDeleteTagWithLabel("Python_temp")
}
void PythonArrayOut( )
{
string py
py += "#Passing Numpy array values via global tags" + "\n"
py += "import numpy as np" + "\n"
py += "data = np.arange(6*8*3).reshape(6,8,3)" + "\n"
py += "outImg = DM.CreateImage(data.copy(order='C'))" + "\n"
py += "DM.GetPersistentTagGroup().SetTagAsArray('Python_temp:out:array',outImg)" + "\n"
py += "DM.GetPersistentTagGroup().SetTagAsLong('Python_temp:out:type',outImg.GetDataType())" + "\n"
py += "for i in range(data.ndim,0,-1):" + "\n"
py += " DM.GetPersistentTagGroup().SetTagAsLong('Python_temp:out:dim:' + str(i-1),data.shape[i-1])" + "\n"
py += "\n"
py += "del outImg #ALWAYS delete DM objects in Python scripts" + "\n"
Result( "\n PYTHON CODE EXECUTES\n --------------------- \n\n" )
ExecutePythonScriptString( py, 1 )
Result( "\n --------------------- \n PYTHON CODE FINISHED \n\n" )
number dataType
if ( !GetPersistentTagGroup().TagGroupGetTagAsLong("Python_temp:out:type",dataType))
Throw("Python dataType value passed out not found.")
TagGroup dimTG
if ( !GetPersistentTagGroup().TagGroupGetTagAsTagGroup("Python_temp:out:dim",dimTG))
Throw("Python dimensions passed out not found.")
number nDim = dimTG.TagGroupCountTags()
number n0, n1, n2, n3, n4
dimTG.TagGroupGetIndexedTagAsLong(0,n0)
dimTG.TagGroupGetIndexedTagAsLong(1,n1)
dimTG.TagGroupGetIndexedTagAsLong(2,n2)
dimTG.TagGroupGetIndexedTagAsLong(3,n3)
dimTG.TagGroupGetIndexedTagAsLong(4,n4)
image outImg
if ( 1 == nDim )
outImg := NewImage("Test", dataType, n0 )
else if ( 2 == nDim )
outImg := NewImage("Test", dataType, n0, n1 )
else if ( 3 == nDim )
outImg := NewImage("Test", dataType, n0, n1, n2 )
else if ( 4 == nDim )
outImg := NewImage("Test", dataType, n0, n1, n2, n3 )
else if ( 5 == nDim )
outImg := NewImage("Test", dataType, n0, n1, n2, n3, n4 )
if ( !GetPersistentTagGroup().TagGroupGetTagAsArray("Python_temp:out:array",outImg))
Throw("Python array data passed out not found.")
Result("\n DM recreated image from array values: " + outImg.ImageGetLabel()+ "\n")
GetPersistentTagGroup().TagGroupDeleteTagWithLabel("Python_temp")
}
clearresults()
Result("\n\nEXAMPLE Python<->DM image passing\n")
PythonImageInOut()
Result("\n\nEXAMPLE Python-->DM array passing\n")
PythonArrayOut( )