Geant4 가이드

Primary Generator Action

G4ParticleGun, G4ParticleTable 

초기 입자를 정의 하기 위해서 G4ParticleGun, G4ParticleTable 클래스를 사용한다.

fParticleGun = new G4ParticleGun(1);

G4ParticleTable* particleTable = G4ParticleTable::GetParticleTable();
G4ParticleDefinition* particle = particleTable -> FindParticle("proton");

fParticleGun -> SetParticlePosition(G4ThreeVector(0.,0.,1.));
fParticleGun -> SetParticleDefinition(particle);
fParticleGun -> SetParticleMomentumDirection(G4ThreeVector(0.,0.,1.));
fParticleGun -> SetParticleEnergy(40.*MeV);

위 코드는 G4ParticleGun은 초기 입자의 시작 위치, 방향, 에너지 등을 정의한다. 위에서 볼 수 있듯이 함수의 이름이 명확하다.

 G4ParticleTable은 입자들이 정의 되어 있는 리스트 이며 이름, PDGEncoding, 원자번호 등의 방법으로 찾을 수 있다. 위 예제에서는 입자의 이름을 이용하여 찾았다. G4ParticleTable에서 입자를 가져오는 함수는 일반적으로 아래와 같이 있다.

  • FindParticle (G4int PDGEncoding)
  • FindParticle (const G4String &particle_name)

Ion 의 경우 G4ParticleTable 대신 G4IonTable을 사용한다.

  • FindIon (G4int atomicNumber, G4int atomicMass, G4double excitationEnergy)
    • ground state일 경우 excitationEnergy는 0이다.

Geant4에 정의 되어 있는 입자의 이름이나 PDGcode는 아래 리스트에서 찾을 수 있다.

Primary Generator Acction

입자를 쏘는 일은 G4VUserPrimaryGeneratorAction 클래스의 GeneratePrimaries(G4Event* event) 함수에서 한다. 아래와 같이 G4ParticleGun의 GeneratorPrimaryVertex(G4Event *) 함수를 이용한다.

void OTPrimaryGeneratorAction::GeneratePrimaries(G4Event* anEvent)
{
  fParticleGun -> GeneratePrimaryVertex(anEvent);
} 

이 함수는 이벤트가 시작할때마다 불러온다. 그렇기 때문에 물질을 정의할 때 처럼 초기 입자를 이 함수에서 정의 하는것이 아니라 클래스의 맴버 변수로 생성자에서 정의하고, 이벤트마다 속성만 바꿔주는 식으로 코드를 작성한다.

GeneratePrimaryVertex(G4Event*) 함수는 G4ParticeGun의 입자 초기 입자 하나를 다음 이벤트에 넣어준다. 즉, 위 코드는 이벤트마다 같은 초기 입자를 넣어준다. 만약에 이벤트 마다 여러개의 입자를 다른 입자를 넣어주고 싶다면  fParticleGun의 특성을 바꾸면서 GenearatePrimaryVertex(G4Event *) 함수를 여러번 써주면 된다. 예를 들어서 아래와 같은 식이다.

{                                   
  G4int pdg;
  G4double vx, vy, vz, px, py, pz;  
                                    
  fEventGenerator -> ReadNextEvent(vx, vy, vz);
  fParticleGun -> SetParticlePosition(G4ThreeVector(vx,vy,vz));

  while (fEventGenerator -> ReadNextTrack(pdg, px, py, pz))
  {
    G4ParticleDefinition* particle = G4ParticleTable::GetParticleTable() -> FindParticle(pdg);
    fParticleGun -> SetParticleDefinition(particle);

    G4ThreeVector momentum(px,py,pz);
    fParticleGun -> SetParticleMomentum(momentum.mag()*MeV);
    fParticleGun -> SetParticleMomentumDirection(momentum.unit());
    fParticleGun -> GeneratePrimaryVertex(anEvent);
  }
} 

위 코드는 흐름만 참고하도록 하자.

참고

댓글

댓글 본문
작성자
비밀번호
  1. ejungwoo
    질문을 읽어보니 제가 데이터 파일 관리에 대한 내용을 가이드에 적지 않은 것이 실수라는 생각이 들었습니다. 이 내용을 가이드에 업데이트 하였으니 참고해 주시기 바랍니다.

    - 데이터 파일 관리 (https://opentutorials.org......621)
    : 데이터 파일 이름을 매크로 파일 이름으로 설정 하는 방법을 다룹니다.

    - GPS 이용하기 (https://opentutorials.org......622)
    : 초기입자를 컴파일 하지 않고 매크로 파일을 통해서 설정할 수 있는 (Geant4 고유) 기능에 대해서 알아보고 런을 여러번 하더라도 같은 파일에 저장 하는 방법을 다룹니다.
    대화보기
    • auto run
      답변정말 감사드립니다
      제가원하는바를 정확히 적지 않아 고생만 시키는거 같아 죄송하네요

      제가원하는 건
      1MeV 100 2MeV 200 3MeV 100 4MeV 250 .........................................
      이렇게 에너지에 따라 따른 횟수의 시뮬레이션을 하는데
      각각의 결과과 ntuple에 차곡차곡 쌓이는 방법이 있나해서 문의드린겁니다

      일반적으로 1MeV100 2MV 200을 두번 컴파일하여 수행하면 앞의 결과는 지워지고 뒤에 결과만 결과 ntuple에 남는데요 1번결과와 2변 결과가 누적되서 나오게 하는방법이 궁금해서 문의드린겁니다

      감사합니다!
    • ejungwoo
      두가지 방법이 있습니다.

      첫번째는 PrimaryGneratorAction의 GeneratePrimaries(G4Event* anEvent) 함수에서 트랙을 넣을 때 다음과 같이 GeneratorPrimaryVertex(anEvent) 함수를 이용하는데 이 함수를 여러번 반복하시면 됩니다. 예를 들어서 100번이라면

      for (auto i = 0; i < 100; ++i)
      fParticleGun -> GeneratePrimaryVertex(anEvent)

      와 같습니다. 이렇게 되면 한 이벤트에 100개의 초기 입자가 생성되는데 한 이벤트에 들어간다는 말은 EventAction에서 BeginOfEventAction와 EndOfEventAction 함수를 한번씩 불러올 동안 100개의 트랙이 한번에 생성되는 것을 의미합니다.



      두번째 방법은 example.cc 에서 runManager -> Initialize(); 직후에 runManager -> BeaomOn(100); 을 적어서 매크로 파일 없이 실행하는 방법입니다. 적고보니 이 방법이 쉽고 빠르겠네요. 실행 방법은 매크로 파일 없이 ./example 입니다.

      int main(int argc, char** argv)
      {
      G4RunManager* runManager = new G4RunManager;

      G4VModularPhysicsList* physicsList = new QGSP_BERT;
      runManager -> SetUserInitialization(physicsList);
      runManager -> SetUserInitialization(new OTDetectorConstruction());
      runManager -> SetUserAction(new OTPrimaryGeneratorAction());
      runManager -> SetUserAction(new OTRunAction());
      runManager -> SetUserAction(new OTEventAction());
      runManager -> SetUserAction(new OTSteppingAction());
      runManager -> Initialize();
      runManager -> BeamOn(100);

      delete runManager;

      return 0;
      }
      대화보기
      • autorun
        답변 정말 감사합니다.

        단순히 (1MeV neutron 100개 2MeV neutron 200개 3MeV neutron 50개) 를 원하신다면 histogram을 사용하시는 것 보다는 PrimaryGeneratorAction 드를 3번 바꾸고 컴파일 해서 돌리는 것이 효율적인 면에서 가장 좋습니다.

        이 코드를 작성하려하는데 PrimaryGeneratorAction 에서는 particle Energy, Particle type, momentum direction 등은 정해줄 수 있지만 시뮬레이션 횟수는 정해줄수 없는걸로 아는데 저는보통 command line에서 /run/beamOn/ 1000과 같이 작성해서 사용하거든요, 혹시 PrimaryGeneratorAction 에서 위의 에너지를 바꿔가면서 particlegun의 수를 달리하는걸 코딩해서 사용 할 수 있나요?

        혹은 매크로에서 위와같이 연달아 계산하는걸 coding 할 수 있는지 궁금합니다
        대화보기
        • ejungwoo
          1. Histogram 을 이용하는 것이 가능하긴 하지만 ROOT 혹은 histogram를 지원하는 타 라이브러리를 알아야 합니다. 그리고 해당 라이브러리를 Geant4와 함께 컴파일 해야 하는데 이 내용을 댓글로 설명해 드리기에는 양이 조금 많을 것 같네요.

          단순히 (1MeV neutron 100개 2MeV neutron 200개 3MeV neutron 50개) 를 원하신다면 histogram을 사용하시는 것 보다는 PrimaryGeneratorAction 드를 3번 바꾸고 컴파일 해서 돌리는 것이 효율적인 면에서 가장 좋습니다.

          이것 보다 더 복잡한 input을 원하시게 된다면 토픽 "이벤트 파일을 읽어서 시뮬레이션에 쏘기"
          (https://opentutorials.org......260) 를 참고해서 이벤트 파일의 형태로 input을 넣을 수 있습니다. Histogram 데이터를 이벤트 파일로 출력하고 이 방법을 통하여 사용하는 것도 가능합니다.

          2. 검출기의 replica는 복제되는 검출기의 모양이 모두 같다고 가정할 때, logical detector(logicDetector)를 하나를 만들고 G4PVPlacement의 두번째 매개변수에 offset을 다르게 해주면 됩니다. 끝에서 두번째 매개변수인 copyNo도 매 볼륨마다 다르게 해주면 나중에 편리해 지겠죠.

          예를 들어서 아래 코드는 같은 모양의 검출기를 (검출기의 중심이) z축 방향으로 매 10 mm 간격으로 위치하도록 생성하는 방법입니다.

          for (G4int copy = 0; copy < 10; ++copy)
          new G4PVPlacement(0, G4ThreeVector(0,0,detector_offset_z + copy*10*mm), logicDetector, "Detector", logicWorld, false, copy+1, true);

          위 코드는 이 가이드의 OTDetectorConstruction.cc 코드 (https://github.com......L70) 에서 변형하였습니다.
          대화보기
          • Auto Run
            안녕하세요 ~ 이번에 Geant4 를 막배우기 시작한 초보 유저입니다.

            제가 많이 미숙하여 혹시나 도움을 주실 수 있으면 정말 감사드리겠습니다.

            첫번째는, 특정 histogram 을 primary generator action 에 input으로 넣는게 가능한가요?

            예를들면 1MeV neutron 100개 2MeV neutron 200개 3MeV neutron 50개 이런 시뮬레이션을 한번에 돌릴 수 있는지 궁금합니다

            두번쨰는, replica 관련된 option인데 Si Box를 3d로 10cm 간격으로 할려면 어떻게 해야되는지 잘모르겠어서 문의드립니다 감사합니다
          • ejungwoo
            안녕하세요.

            Geant4 시뮬레이션은 기본적으로 Monte-Carlo method(컴퓨터의 난수를 이용한 확률적인 계산)를 사용합니다. 그리고 Geant4가 확률적인 계산에 의존하는 이유는 실제 나타나는 현상이 그렇기 때문입니다. 다른 학문도 그렇지만 특히 핵/입자 물리는 확률과 통계 없이 설명할 수 없습니다.

            예를 들어서 유명한 러더포드 산란 실험에서 알 수 있듯이 얇은 금박을 통과하는 알파 입자는 여러 방향으로 산란합니다. 만약 모든 알파 입자가 금박을 통과하여 직진하거나 특정한 각도로 산란했다면 (조금 과장해서) Geant4 같은 프로그램은 필요하지 않았겠죠. 하지만 현상이 그렇기 때문에 핵/입자 물리학은 결과의 분포를 통하여 통계적으로 접근 하는 것이 바람직 합니다.

            과학자들은 실험과 이론을 통하여 여러 조건에서 입자 간에 나타날 수 있는 현상의 확률을 구했습니다. 이런 확률을 핵/입자 물리학에서 넓은 의미로 cross section이라고 합니다. Geant4는 수많은 cross section 계산을 통하여 사용자에게 결과를 제공합니다. 따라서 input이 같아도 매번 다른 결과가 나오는 것이 당연합니다. 하지만 같은 input을 사용하였을 때 특정한 값의 통계 분포, 또는 cross section은 일관됩니다.

            간단하게 말하면 입자간 혹은 입자와 매질 사이에서 일어나는 상호작용은 확률적인 분포안에서 여러 방향으로 일어날 수 있는 과정이기 때문에 시뮬레이션의 조건이 같아도 매번 결과가 다릅니다.
            대화보기
            • Random Simulation
              안녕하세요 한방향으로 쏘는 시뮬레이션은 시작 input이 모두 같은데 왜 매번 다른결과가 나오는지 이해가 잘안됩니다. 어떤값이 계산 마다 random하게 바뀌어서 계산결과가 매번 다르게 나오는지 알 수 있을까요?
            • ejungwoo
              검출기의 크기와 점선원의 중심까지의 거리, 그리고 생성된 빔의 개수로 볼 때 빔이 검출기에 들어갈 확률이 매우 작아보긴 합니다. 따로 background 시뮬레이션을 염두해 둔것이 아니라면, 빔이 검출기 안으로 들어가는 각도를 계산을 해서 그 각도 안에서 빔을 생성하는 것이 좋아보입니다.

              시뮬레이션이 오래 걸리는 이유는 아마도 이벤트 뷰어(/vis/viewer/...)를 사용해서 이벤트를 화면에 그리기 때문일 것입니다. 이벤트 뷰어는 시뮬레이션을 눈으로 확인할 때만 테스트용으로 사용하고, 많은 빔을 생성할 때는 뷰어를 끄고 시뮬레이션을 돌리면 시간을 단축할 수 있습니다.
              대화보기
              • 이핑크
                감사합니다. 알려주신대로 작성해서 돌리니까 잘 생성되었습니다.

                그런데 점선원과 검출기와 거리가 1m여서 그런지 반구 모양으로 1000개의 빔을 생성해도 검출기까지 간 빔이 없더라구요. 그냥 /gps/direction 으로 하는게 나을까요??

                걱정되는 부분은 보통 점선원이라는 것이 등방형으로 방출하는데 그렇게 돌리면 시간이 많이 걸려서 검출기 있는 방향 즉, 반구 모양으로 생성하는 것이 효율적이라고 생각했거든요. 근데 이렇게 반응 하나도 안하는 것이라면..
                대화보기
                • ejungwoo
                  타입을 "iso"로 두시고 theta 혹은 phi 의 최소 최대 각을 조절하면 됩니다. 예를 들어서 아래와 같이 하면 +z 방향을 중심에 둔 반구 모양으로 빔이 생성됩니다.

                  /gps/ang/type iso
                  /gps/ang/mintheta 90 deg
                  /gps/ang/maxtheta 180 deg

                  아래 링크를 보시면 명령어 설명이 잘 되어있습니다.

                  http://geant4-userdoc.web.cern.ch......ure
                  대화보기
                  • 이핑크
                    점선원에 대해서 한쪽 방향으로만 빔을 생성하고 싶습니다.

                    보통 /gps/direction 0 0 1의 경우면 z축으로 일직선으로만 빔이 생성되는데

                    iso 타입으로 한쪽 방향으로만 즉, 반구 모양으로 방출하려면 어떻게 해야하는지 알 수 있을까요??
                  버전 관리
                  ejungwoo
                  현재 버전
                  선택 버전
                  graphittie 자세히 보기