如何在Digital Micrograph中的dm-script和python之间进行通信

如何解决如何在Digital Micrograph中的dm-script和python之间进行通信

如何在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脚本调用Python脚本

此答案显示了Python与DM脚本之间的某些通信,但形成了反面。它还将持久性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," + 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","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","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,-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",n0,n1 )
    else if ( 3 == nDim  )
        outImg := NewImage("Test",n2 )
    else if ( 4 == nDim  )
        outImg := NewImage("Test",n3 )
    else if ( 5 == nDim  )
        outImg := NewImage("Test",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-scriptpython之间同步数据时,两者都在同一实例中运行(在此示例中,线程也可以修改为不同的线程),可以使用 persistent标签

dm-script正在设置持久标记。 python然后可以再次读取持久性标签。


更新:Python模块

由于下面提到的限制以及难以理解的增长和不可读的代码,我决定为此编写自己的python模块。借助execdmscript,可以轻松地从Digital Micrograph中执行具有可变同步功能的dm脚本代码。

查看以下示例:

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脚本相关的保存和问题(如下所述)。它允许使用listdict和基本类型,例如boolstrintfloat。所有类型和值都可以pythonic方式使用,而无需关心dm-script类型。可以将dm脚本移动到单独的文件中,以进一步清理代码。

请注意,为了进行调试,有一个exec_dmscript(debug=True,debug_file="path/to/file")开关会将代码保存到给定的debug_file中。然后可以在GMS中手动执行该文件,显示错误。

免责声明:如上所述,我是execdmscript模块的作者。我仍然认为这是针对这种情况的最佳解决方案。实际上,这个问题是我编写模块的原因。


基本数据类型

对于stringnumber这样的基本数据类型,可以手动创建和添加代码。下面的示例说明了这个想法:

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模块可以处理TagGrouTagList,因为它可以保存它们的线性化以及单独的键和类型。

请注意,TagGroup很难同步。 TagGroup不得分配给变量。一旦它们可用,它们就不再可用。可以通过以下非常简单的代码来说明这一点:

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(group2),")")

# assign one parent group to a variable,doesn't work
tags = DM.GetPersistentTagGroup()
s,group3 = tags.GetTagAsTagGroup("test")
print("Group 3 success:",group3.IsValid(),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-scriptpython实现可以设置观察持久性标记的线程。 (请注意,您可以使用TagGroupTagGroupMarkAsChanged()标记为已修改),标记可能会有所不同。然后两者都可以将命令和/或数据添加到标签。另一个“实例”可以读取和处理它们。

必须手动编码。 (当前)未包含在execdmscript模块中。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-