在不完全指南三种,简单分析了四个intercoms 中的四个类,由于目前还没有接触太多的实例,对接口这一块的应用也理解的不是很深,在这里,我们只需要理解借口在交互式命令以及宏文件处理的应用即可,在后面如果遇到复杂的接口类的设置,可以在一次分享。指南4是指南3的延续,为了更好的阅读,特此将3和4分开,具体可以先看4在回过头看3会好理解一点。
write by jack in hubei 2019.7.25 21:02
下面内容主要参考用户手册,只是做了简单的相关总结!
首先,先来简单了解一下"intercoms"类的组成,该组类提供了一个可扩展的命令解释器。它是G4实现用户交互的一个关键机制,使得用户不必关心各个大类之间的相互关系。用户可以在C++程序中直接使用G4中提供的类,已提供最底层的交互特性,如批处理会话方式,G4命令和宏是被嵌入到程序代码中的。下图是intercoms 类中的类成员
为了避免大量的编程工作,"intercoms"提供了抽象类G4UIsession,可以捕获交互命令。用户接口和图形用户接口的具体实现也是在intercoms这一大类中,目前我们不需要掌握这些接口,只需要了解我们可以用字符终端(哑终端和类tcsh(bash)终端),这是G4的缺省用户接口,可以不需要我们用户自己去定义,直接在C++中编程即可使用 。
1.G4UIterminal和 G4UItcsh
这些接口在一个字符终端上建立一个会话。G4UIterminal可以运行在G4支持的所有平台上,而 G4UItcsh 只运行在 Solaris 和 Linux 上。
2 如何建立交互式接口
要在用户程序中使用指定的接口( G4UIxxx 这里的 xxx = terminal,Xm, Xaw, Win32, GAG,
GainServer, Wo ),需要在主程序中加入如下几行代码:
// to include the class definition in his main program:
#include "G4Uixxx.hh"
// to instantiate a session of his choice and start the session
G4UIsession* session = new G4UIxxx;
session->SessionStart();
/ /the line next to the "SessionStart" is usually to finish the session
delete session;
在大部分例子中,都是使用终端作为会话接口。可以使用环境变量选择一个给定的接口,但是为了方便,其中有一些已经被设置。
• G4UIterminal, G4UItcsh, G4UIGAG 和 G4UIGainServer 可以直接使用,不需要设置
环境变量。这些会话接口不需要使用外部软件包或库(参看"G4UI_BUILD.gmk"),
因此,用户不需要设置任何环境变量,也不要重建任何库,就可以实例化这些会话接
口中的任何一个。为了用户应用程序的向下兼容,与上述三个环境变量(G4UI_USE_TERMINAL, G4UI_USE_TCSH 和 G4UI_USE_GAG ) 相对应的 C 预编译变量应被设置。如果用户不设置任何环境变量,C 预编译变量G4UI_USE_TERMINAL 缺 省 将被设置,虽然没有必要使用它
简单总结一下3和4 ,通过第4节,可G4UIterminal类以发现G4UIsession类是一个基类,G4UIterminal类是一个已经设置好的接口类,可以直接在main()函数中添加相应的代码实现在终端的字符交互处理。G4UIExecutive.hh是一个自动根据环境变量设置接口的一个类。从基本例子中可以看到,目前常用的都是G4UIterminal类来实现程序命令行的交互运行。需要重点了解和掌握。另外,在intercoms类组中,还有一个很重要并且很常用的类 G4UImessenger类,来实现命令参数的改变,这个会在后面进行详细的介绍
G4中有以下集中方式来运行程序
1 'purely hard-coded' 批处理模式
简单的来说就是直接通过写好的主函数来运行程序,在运行过程中,即使是事件数也不能更改,用户要改变事件数,就必须重新写main()函数。该处理方式中,main()函数没有参数传递,直接定义为 int main() {}
2 使用宏命令的批处理模式
函数的格式大致为:
.......
int main(int argc ,char ** argv) {
//read a marco file of commmands
G4UImanager * UI = G4UImanager::getUIpointer();
G4String command = "/control/execute ";
G4String fileName = argv[1];
UI->applyCommand(command+fileName);
...
}
在cmake 编译,ubuntu 的环境下,以exampleB1 可执行程序为例,run1.mac 是一个宏文件,那么可以这样执行宏文件批处理
./ exampleB1 run1.mac 就可以直接运行宏文件定义好的运行方式。其中,argv[0] 指的是可执行文件exampleB1,argv[1] 指的是run1.mac 。所以在UI->applyCommand(command+fileName);就是在执行/control/execute run1.mac
注意:
Geant4 的各个模块的类都有一个冗余标志,用于控制冗余信息的输出。
通常 verbose=0 意味这没有信息输出。例如
/run/verbose 用于设置 RunManager 的冗余标志
/event/verbose 用于设置 EventManager 的冗余标志
/tracking/verbose 用于设置 TrackingManager 的冗余标志
...等...
3 命令行驱动的交互模式
这种交互式的应用程序的mian()函数,由命令行驱动,它将等待用户的命令的输入。主函数的格式为:
....
int main(int argc,char** argv) {
// Define UI terminal for interactive mode
G4UIsession * session = new G4UIterminal;
session->SessionStart();
delete session;
...
}
在这里,直接运行可执行程序./ exampleB1,会出现G4的内核提示符
Idle> 然后用户可以开始输入会话命令。前面提到过,G4是一个状态机,Idle 是其一个空闲状态,表明其可以接受外界的命令。在调试模式中运行一些事件并显示他们,这个模式是非常有用的。需要注意在main()函数中建立VisManager 和一些可以建立可视化的命令。
4 通常情况
一般来说会复合上面提到的2宏文件命令批处理模式和交互命令行处理模式,主函数的格式为:
...
int main(int argc,char ** argv) {
if (argc==1)
{
// Define UI terminal for interactive mode
G4UIsession * session = new G4UIterminal;
UI->ApplyCommand("/control/execute prerunN03.mac");
session->SessionStart();
delete session;
}
else
// Batch mode
{
G4String command = "/control/execute ";
G4String fileName = argv[1];
UI->ApplyCommand(command+fileName);
}
...
}
当输入命令行
./exampleB1 时 argc==1
./exampleB1 run1.mac argc==2 其中 argv[0] 指的是可执行程序exampleB1 ,grav[1]指的是run1,mac
从上面看出,在交互式命令中,用户也可以执行一个宏命令
Idle > /control/execute/ run1.mac
通过本小节的总结,我们可以大致了解到intercoms 类组的功能,给用户提供交互的接口,在大部分程序中,默认的都是终端交互处理,目前来看并不会用到外部的一些接口,以后碰到了相应的情况在详细总结归纳,在后面一部分,总结了程序运行时的一些模式,结合3中总结的main()函数中参数的传递情况,可以理解本节中宏命令处理和交互式命令行处理的具体方式,在大多数程序中,都是将两者有机的结合起来,方便用户选择自己喜欢的模式。