我在Geant 4软件中主要完成三大功能需求:构建自己所需要的探测器模型;建立TCP客户端;自定义宏命令来输出指定探测器能量沉积。

Geant 4中的蒙特卡罗方法是指一个粒子发射出去之后,会和周围的环境发生反应,一直到发射出去的粒子和它产生的次级粒子都完全发生反应并且泯灭之后,才会发射下面一个粒子,两个事件的发射粒子之间不会发生任何反应,并且Geant 4软件本身不做模拟计算,所有产生的数据都是通过对保存的实验数据进行随机抽样得到的,比如本论文中使用的物理模型为粒子散射到探测器中产生出能量能量沉积,发射一种特定的散射粒子,在相同发射初始能量下,探测器中每个event沉积能量的数据重复率非常高。

  • 探测器构建

正方体的探测器边长为15毫米,10乘10堆叠放置100个探测器,如图3.2所示,展示出探测器的堆叠形状,150代表10个探测器堆叠的总长度为150毫米,15代表一个探测器的边长为15毫米,省略号代表其余没有画出的探测器。对每个探测器在G4中进行编号,右上方为第100个,并且从上向下、从右到左开始累减依次编号。

  // Absorber//G4Box*sAbsor = new G4Box("Absorber",                                //nameworld_hx, world_hy, world_hz);    //dimensionsfLAbsor = new G4LogicalVolume(sAbsor,                //shapefAbsorMaterial,                 //material"SensitiveDetector");     //nameint Absorber_number = 100;for(int i=1; i<11; i++){for(int j=1; j<11; j++)          // x axis{std::string s1;std::string s2;   // location parameters1 = std ::to_string(10-i);s2 = std ::to_string(10-j);new G4PVPlacement(0,            //no rotation//100 detector locationG4ThreeVector(2*(10-i)*world_hx ,2*(10-j)*world_hx , 0),   fLAbsor,                        //logical volumestd::string("Det") + "_L" + s1 + "_R" + s2,      //namefLContain,                      //mother  volumefalse,                          //no boolean operationAbsorber_number);               //copy numberAbsorber_number--;}                    }PrintParameters();
  • TCP客户端

建立一个TCP客户端通过TCP通道发送数据,这样就很方便的把G4产生的数据发送到其他应用中进行处理,我是发送到上位机软件中显示图像。

 //mao add TCP protocol 2struct sockaddr_in server_addr2;bzero(&server_addr2, sizeof(server_addr2)); server_addr2.sin_family = AF_INET;    server_addr2.sin_addr.s_addr = inet_addr("172.20.157.166");server_addr2.sin_port = htons(SERVER_PORT_Qt);int Qt_sfd;Qt_sfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if (Qt_sfd < 0){G4cout << "socket error\n";exit(0);}if (connect(Qt_sfd, (struct sockaddr*) & server_addr2, sizeof(server_addr2)) < 0){G4cout << "Can Not Connect To    "<< "172.20.157.166"<< G4endl;exit(1);}//open file reading datastd::fstream event_file1;event_file1.open(STEPPING_FILE, std::ios::in);if (!event_file1.is_open()){G4cout << "the file was not opened"<< G4endl;exit(1);}std::vector<float> floats;char Qt_data[500][3] = { '\0' };  //Fill in all blank charactersstd::string line;//read float datafloat max_number = 0;while (std::getline(event_file1, line)){std::string strr1 = line;std::string strr2;std::vector<float> array1;//Starting at the zero bit, the length is 4strr2 = strr1.substr(0, 4); std::istringstream iss(line);//Save the maximum valuefloat val;iss >> val;if (val > max_number){max_number = val;}if (val > 2)//Numerical fill algorithm for values greater than 2{floats.push_back(0.0);array1 = fix_data(val);  //Numerical filling algorithm    for(G4int jj=0; jj < (int)array1.size(); jj++){floats.push_back(array1[jj]);}}else {G4cout << "vector<float> floats = "<< val<< G4endl;floats.push_back(val);}}// close and delete file//需要对QT传输的数据进行重新修改,不能直接传输字节数据event_file1.close();for (int ff = 0; ff < (int)floats.size()+1; ff++){int num1 = 0;int num2 = 0;int num3 = 0;float Qt_number = 0.0;if(ff==0) //0 data processed separately{//Convert int to ASCII
//TCP transmission of ASCII code data is very easy to handle at the receiving endQt_number = (int)floats.size();num1 = Qt_number / 100;Qt_data[ff][0] = num1 + '0';num2 = (Qt_number - num1 * 100) / 10;Qt_data[ff][1] = num2 + '0';num3 = (Qt_number - num1 * 100 - num2 * 10) / 1;Qt_data[ff][2] = num3 + '0';}else {Qt_number = floats[ff];num1 = Qt_number / 1;Qt_data[ff][0] = num1 + '0';num2 = (Qt_number - num1 * 1.0) / 0.1;Qt_data[ff][1] = num2 + '0';num3 = (Qt_number - num1 * 1.0 - num2 * 0.1) / 0.01;Qt_data[ff][2] = num3 + '0';}}for(int uu=0; uu<(int)floats.size()+1; uu++){G4cout << "Qt_data[uu][] = "<< Qt_data[uu][0] << Qt_data[uu][1]<< Qt_data[uu][2]<<G4endl;}int send_char_number2 = send(Qt_sfd, (char*)Qt_data, BUFFER_SIZE, 0);if (send_char_number2 < 0){G4cout << "send send char number2 error"<< G4endl;}else if (send_char_number2 == 0){G4cout << "send char number2 server disconnected"<< G4endl;}else{G4cout << "send char number 2="<< send_char_number2<< G4endl;}close(Qt_sfd);

在其中有一个数值填充算法,对一个输入数值进行两个多项式数值填充算法。通过建立顺序线性表来计算四次多项式的值,每一个多次项都作为一个节点,结构体节点之间是顺序存储,使用顺序链表原因主要有两点:各个节点之间相互独立又有前后顺序,一个节点作为一个结构体很好的保存各项系数和指数;不会有增加或者删除节点的需求,计算填充数值一直使用初始化好的四次多项式,为了代码结构更加简单和处理数据更快速,不选择使用链式而选择顺序线性表。

//ps Represents an array of coefficient terms
//es Represents an array of exponents
//n Represents the number of the unary polynomials
void EventAction::InitList(SqList & list1,G4double ps[],G4int es[],G4int n)
{for(int i=0;i<n;i++){list1.elem[list1.size].coe = ps[i];list1.elem[list1.size].exp = es[i];list1.size++;}
}float EventAction::GetResult(SqList & list1)
{float sum = 0;for(G4int i=0; i<list1.size;i++){sum += list1.elem[i].coe * (std::pow(list1.mx,list1.elem[i].exp));}return sum;
}float EventAction::up_equ(float value)
{SqList mylist;G4double up_coefficient[5]= {1.122e-08, - 5.613e-06 , 0.0008606, - 0.0378, 0.4916};G4int exponent1[5] = { 4, 3, 2,1 ,0};mylist.mx = value;//Initializes a linked listInitList(mylist, up_coefficient, exponent1, 5);float reslut = GetResult(mylist);reslut = ( (float)( (int)( (reslut + 0.005) * 100 ) ) ) / 100;return reslut;
}float EventAction::down_equ(float value)
{SqList mylist;G4double down_coefficient[5]= {-4.203e-09, 3.787e-06, - 0.00124, 0.1677, - 6.957};G4int exponent1[5] = {4, 3, 2,1 ,0};mylist.mx = value;//Initializes a linked listInitList(mylist, down_coefficient, exponent1, 5);float reslut = GetResult(mylist);reslut = ( (float)( (int)( (reslut + 0.005) * 100 ) ) ) / 100;return reslut;
}std::vector<float> EventAction::fix_data(float x)
{float x_mid1 = 0;float y_mid1 = 0;std::vector<float> array1;for(int i=0; i<13; i++){x_mid1 = 90 * i / 12 + 39;y_mid1 = x * up_equ(x_mid1);array1.push_back(y_mid1);}for(int j=0;j<13;j++){x_mid1 = 158 * j / 12 + 129;y_mid1 = x * down_equ(x_mid1);array1.push_back(y_mid1);}return array1;
}
  • 自定义宏命令

为了可以在mac脚本文件中通过宏命令(/testhadr/stepping/seDSN  55)选择Geant 4中特定探测器输出能量沉积。先建立SteppingActionMessenger类继承于SteppingAction类并且初始化,因为探测器的序数为整数,所以把fsteppingCmd4设置为整数命令的构造函数,设置宏命令的名字为detector number范围为大于零。SetNewValue函数中判断是否为fsteppingCmd4命令,如果是就对seDSN宏命令传入的参数通过SetADetectorNumber函数对探测器序号赋值。当总体程序执行到SteppingAction类的时候,通过SetADetectorNumber函数获取探测器序号筛选出指定探测器能量沉积保存到文件中。

SteppingActionMessenger.hh

#ifndef SteppingActionMessenger_h
#define SteppingActionMessenger_h 1
#include "globals.hh"
#include "G4UImessenger.hh"
class G4UIcmdWithAnInteger;
class G4UIdirectory;
class SteppingAction;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
class SteppingActionMessenger : public G4UImessenger
{
public:SteppingActionMessenger(SteppingAction*);~SteppingActionMessenger();//其实完全可以不是纯虚函数,毕竟是自己设置接口virtual void SetNewValue(G4UIcommand*, G4String);
private:SteppingAction*   fstepping;using G4UImessenger::SetNewValue;G4UIdirectory*             fTesthadrDir;G4UIdirectory*             fstepDir;G4UIcmdWithAnInteger*      fsteppingCmd4;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#endif

SteppingActionMessenger.cc

#include "G4UIcmdWithAnInteger.hh"
#include "G4UIcommand.hh"
#include "G4UIparameter.hh"
#include "SteppingActionMessenger.hh"
#include "SteppingAction.hh"SteppingActionMessenger::SteppingActionMessenger(SteppingAction* stepping):fstepping(stepping)
{fTesthadrDir = new G4UIdirectory("/testhadr/");fTesthadrDir->SetGuidance("commands specific to this example");G4bool broadcast = false;fstepDir = new G4UIdirectory("/testhadr/stepping/", broadcast);fstepDir->SetGuidance("steping action commands");fsteppingCmd4 = new G4UIcmdWithAnInteger("/testhadr/stepping/seDSN", this);fsteppingCmd4->SetGuidance("Select detector sequence number");fsteppingCmd4->SetParameterName("number", false);fsteppingCmd4->SetRange("number>0");fsteppingCmd4->AvailableForStates(G4State_PreInit, G4State_Idle);fsteppingCmd4->SetToBeBroadcasted(false);
}SteppingActionMessenger::~SteppingActionMessenger()
{delete fsteppingCmd4;delete fTesthadrDir;delete fstepDir;
}void SteppingActionMessenger::SetNewValue(G4UIcommand* command, G4String MyValue)
{if (command == fsteppingCmd4){fstepping->SetADetectorNumber(fsteppingCmd4->GetNewIntValue(MyValue));}
}
  • 输出探测器能量沉积

输出探测器内的粒子能量沉积到文件中。

//Select a specific detector serial number
void SteppingAction::SetADetectorNumber(G4int value)
{select_number = value;
}
void SteppingAction::UserSteppingAction(const G4Step* aStep)
{
//前面部分代码省略auto touchable = aStep -> GetPreStepPoint() -> GetTouchable();auto physical = touchable -> GetVolume();Stepping_detector_Number = physical-> GetCopyNo();auto detector_name = physical->GetName();fEventAction->detector_Number=Stepping_detector_Number;fEventAction->AddEdep(aStepEdep);G4double edepStep = aStep->GetTotalEnergyDeposit();if (edepStep <= 0.) return;fEventAction->AddEdep(edepStep);Tstop = clock();//Record end timestd::ofstream step_file1;step_file1.open(STEPPING_FILE, std::ios::app);if(Stepping_detector_Number == select_number) //select detector number{if (step_file1.is_open()){step_file1 //Set the numerical accuracy of the output energy deposition<< setiosflags(std::ios::fixed) << setiosflags(std::ios::right)<< std::setprecision(4)//4 digit precision<< aStepEdep<< G4endl;}} step_file1.close();
}
  • acknowledgement

以后在工作中也不会再接触G4了,这是自己毕业设计的一部分,希望给你提供帮助,减少重复工作的时间!

非常感谢中科大的潘子文和Geant 4(564893516)群中的各位朋友提供的帮助!

Geant 4创建TCP客户端,自定义宏命令,输出探测器能量相关推荐

  1. TCP:创建TCP客户端

    创建TCP客户端不需像创建TCP服务器那样麻烦,创建TCP客户端就像我们打电话,只需要两步即可: 1.找电话亭. 2.输入号码. 即: #导入socket import socket #创建TCP/I ...

  2. 四步创建TCP客户端

    //四步简历TCP服务端 #include<iostream> #include<Windows.h> using namespace std;int main() {//初始 ...

  3. TCP 客户端程序开发

    TCP 客户端程序开发 1. 开发 TCP 客户端程序开发步骤回顾 创建客户端套接字对象 和服务端套接字建立连接 发送数据 接收数据 关闭客户端套接字 2. socket 类的介绍 导入 socket ...

  4. TCP 客户端程序开发步骤

    TCP 客户端程序开发 1. 开发 TCP 客户端程序开发步骤回顾 创建客户端套接字对象 和服务端套接字建立连接 发送数据 接收数据 关闭客户端套接字 2. socket 类的介绍 导入 socket ...

  5. Springboot实战:Springboot+Netty优雅的创建websocket客户端 (附源码下载)

    Springboot-cli 开发脚手架系列 Netty系列:Springboot+Netty优雅的创建websocket客户端 (附源码下载) 文章目录 Springboot-cli 开发脚手架系列 ...

  6. 网络编程之TCP客户端程序开发

    网络编程之TCP客户端程序开发 1. 开发 TCP 客户端程序开发步骤 2. socket 类的介绍 3. TCP 客户端程序开发示例代码 4. 小结 1. 开发 TCP 客户端程序开发步骤 创建客户 ...

  7. 【python网络编程】创建TCP/UDP服务器进行客户端/服务器间通信

    客户端/服务器网络编程介绍 套接字:通信端点 实例:客户端发送数据,接收服务器返回的时间戳 用Python 编写FTP 客户端程序 客户端/服务器网络编程介绍 软件服务器也运行在一块硬件之上,但是没有 ...

  8. python服务器qt客户端_python3+PyQt5 创建多线程网络应用-TCP客户端和TCP服务器实例...

    本文在上文的基础上重新实现支持多线程的服务器. 以下为TCP客户端的程序代码: #!/usr/bin/env python3 import sys from PyQt5.QtCore import ( ...

  9. go tcp客户端自动重连_使用 Go 语言创建 WebSocket 服务

    今天介绍如何用 Go 语言创建 WebSocket 服务,文章的前两部分简要介绍了 WebSocket 协议以及用 Go 标准库如何创建 WebSocket 服务.第三部分实践环节我们使用了 gori ...

最新文章

  1. linux-shell数据重定向详细分析
  2. 文件描述符在内核态下的一些小把戏
  3. 扫描到服务器的文件在哪个文件夹,云服务器的文件在哪个文件夹
  4. Message LongText(消息的详细长文本)
  5. 「技术人生」:技术同学应该如何理解业务?
  6. Android Studio运行报错:无法访问XXX......请删除该文件或确保该文件位于正确的类路径子目录中
  7. Could not obtain connection metadata
  8. java 进程崩溃_java程序崩溃自启脚本
  9. 有趣的编程代码_iPad amp; Mac 编程游戏推荐
  10. Scikit-Learn 新版本发布!一行代码秒升级
  11. 不重复数字(洛谷 P4305)
  12. 《Essential C++》笔记之return;分析
  13. CISCO路由器、交换机密码恢复
  14. WebService cxf视频教程
  15. lgg7刷机包下载_LG G7ThinQ刷机包
  16. 【元胞自动机】基于元胞自动机实现双车道靠右行驶交通流模型matlab代码
  17. js去掉字符串第一位和最后一位
  18. 今天是10月24日程序员节,祝所有程序员节日快乐!
  19. moss下载_无法为增值税MOSS混乱提供“简单的技术解决方案”
  20. mysql中生成时间维度表

热门文章

  1. kvo实现原理_KVO实现原理
  2. 倾斜以及3D动画笔记
  3. 城市轨道交通信息化架构
  4. 企业网络安全存在哪些主要问题
  5. 谁去出国学习(python)
  6. 推荐一个 Android 图片压缩框架
  7. 【计算机系统结构】Self-modifying code 自修改代码
  8. <a>标签 打开新窗口
  9. Java中转义字符反斜杠 \ 的代替方法 | repalceAll 内涵解析
  10. QT开发(十七)——QWT简介