3

I'm trying to determine the target nucleus in an (n,gamma) reaction in Geant4. I have been unable to extract this information. The only place I have found it to be stored is in G4IsoParticleChange which is created by the G4HadronicProcess if Isotope Counting is enabled.

Unfortunately this information is lost (not in a nice way, either, but memory leak style) every time the process is invoked. I cannot find a user hook-in to ask for this information in between particle creations. G4UserStackingAction is not sufficient as far as I can tell because the secondary particles are all created for a step before they are stacked (* though writing that last sentence has given me an idea).

Could anyone help me determine the nucleus which captures the neutron in the (n,gamma) reaction? Is there an easier way to get this information?

Thanks

P.S. Since a neutron can only be absorbed once within a step, would it be safe to just wait until the secondaries are stacked to obtain the IsoParticleChange info or am I risking a memory leak?

Edit to be more clear:

I'm asking if someone knows how to retrieve the nucleus which was the target in the nCapture process in Geant4. It is clear from the source that a memory leak will occur whenever the G4HadronicProcess is invoked if the G4IsoParticleChange information is not retrieved. There appears to be no user hook in point which is appropriate to grab this without missing some information and causing said memory leak, and yet it is possible to turn this information storage on. I am wondering what the correct way to grab this information is, or if there is a better way to obtain this type of info about the target nucleus.

I have previously gotten some help on SO from people who are familiar with Geant. I have not been able to get a response from the Slac Geant4 forum to give me access to post there. The forum doesn't seem terribly active, anyway.

Thanks

Follow-up:

In case someone stumbles upon this, the answer I got from one of the authors of the G4HadronicProcess class was "This part of the implementation has not been maintained for many years" and "Getting the nucleus involved in the interaction is very difficult if not impossible without editing the source code." So I'm in the process of setting up a new Geant workspace where I can do that. FYI.

user487100
  • 918
  • 1
  • 11
  • 22
  • I'm a little confused about what you're asking. Are you asking about how to find a memory leak? Or are you asking how to use a specific library, Geant4? – Louis Marascio Jun 05 '11 at 18:13
  • I'm asking for specific help with Geant4. Geant4 is a high energy physics software developed by CERN. – user487100 Jun 05 '11 at 18:56
  • I presume that you are familiar with the [online documentation](http://www.geant4.org/geant4/support/userdocuments.shtml) and the [software reference manual](http://geant4.cern.ch/bin/SRM/G4GenDoc.csh?flag=1) in particular? I find that rooting through the class documentation is a slow and sometimes frustrating but reliable technique for solving these kinds of problems. – dmckee --- ex-moderator kitten Jun 05 '11 at 22:54
  • Also *"Slack Geant4 forum"* do you mean *"SLAC Geant4 forum"*? In any case you might consider asking on [the forum maintained by the Geant developers](http://hypernews.slac.stanford.edu/HyperNews/geant4/cindex) (which seems to be hosted at SLAC, so we may be talking about the same thing). – dmckee --- ex-moderator kitten Jun 05 '11 at 23:19
  • Yes, I did mean SLAC and I do think it's the same forum. I am familiar with the documentation, but if you use geant very much you probably notice that it is somewhat lacking! Rooting through the source code really is the only way to get any real information about how a class works in geant it seems. – user487100 Jun 05 '11 at 23:40
  • BTW--The question of *"Problems with big physics software package"* questions has not come up on [Physics.SE](http://physics.stackexchange.com) yet, so I won't suggest moving it there (we could discuss it on [meta.physics](http://meta.physics.stackexchange.com)..). But, you will find a concentration of physicists there. – dmckee --- ex-moderator kitten Jun 05 '11 at 23:41

2 Answers2

3

I finally found an effective solution to that problem: I search for a nucleus in the secondary track vector of a step ending by a neutron capture. This nucleus is the one which captured the neutron and which recoil is tracked by Geant4. Do not forget to subtract 1 neutron to this nucleus to get what you want (for a capture on hydrogen, you will get deuterium with this method).

So in my SteppingAction, I add:

// neutron capture
if ( aStep->GetPostStepPoint()->GetProcessDefinedStep()
  && aStep->GetPostStepPoint()->GetProcessDefinedStep()->GetProcessType() == fHadronic // see G4ProcessType.hh
  && aStep->GetPostStepPoint()->GetProcessDefinedStep()->GetProcessSubType() == fCapture // see G4HadronicProcessType.hh
) {
  if ( aStep->GetSecondary() != 0
    && aStep->GetSecondary()->size() != 0
  ) {
    std::vector<G4Track*>::const_iterator it;
    for (it=aStep->GetSecondary()->begin(); it!=aStep->GetSecondary()->end(); it++) {
    if ( !(*it)->GetCreatorProcess()
      ||  (*it)->GetCreatorProcess()->GetProcessSubType() != fCapture // see G4HadronicProcessType.hh
      ||  (*it)->GetCreatorProcess()->GetProcessType() != fHadronic // see G4ProcessType.hh
      || !(*it)->GetDynamicParticle()
      ||  (*it)->GetDynamicParticle()->GetParticleDefinition()->GetAtomicNumber() == 0 // keep only nucleus
      ||  (*it)->GetDynamicParticle()->GetParticleDefinition() == G4Neutron::NeutronDefinition() // but not the neutron (perhaps antiparticles could also be checked)
    ) { continue; }
      myEventAction->TreatNeutronCapture(*it);
      break;
    }
    if (it == aStep->GetSecondary()->end()) {
      G4cerr << "\n#### END OF SECONDARY VECTOR REACHED AFTER NEUTRON CAPTURE ! ###\n";
      myEventAction->TreatNeutronCapture(0);
    }
  } else { myEventAction->TreatNeutronCapture(0); }
}

As you can see, I defer the actual stepping treatment to methods of EventAction. This is my TreatNeutronCapture method :

void MyExperimentEventAction::TreatNeutronCapture(const G4Track* track)
{
  myParticle = myMC->GetParticle(ParticleMap[track->GetParentID()]);
  if (track == 0) { myParticle->SetFinalProcess(-1); } // if no nucleus is found in secondaries
  else { myParticle->SetFinalProcess(track->GetDynamicParticle()->GetPDGcode()); }
}

myParticle and myMC refers to my own data classes.

maRR
  • 46
  • 2
  • Yes I ended up doing the same and checking the secondary particles for the nucleus. It's been about two years, but thanks for posting the solution! I'll have to take a look back at my code, but I think there are some details that can reduce the number of checks needed to find the nucleus. I'll mark your answer as correct. – user487100 Sep 29 '13 at 04:02
1

Well, I haven't looked in detail to see if it actually meets you needs, but it seems that many problems related to keeping track of parents and products and the like can be solved in a manner analogous to that described in this Tip from the forum.

Aha! The tip on examining secondaries may be better because it shows how to select on the ending state of the parent particle and extract some information from the process that ended the step.

You might start there.

dmckee --- ex-moderator kitten
  • 98,632
  • 24
  • 142
  • 234
  • Well, the problem is that it would appear (and I could be wrong) that I need to call G4Hadronic::GetIsotopeProductionInfo() after every time the process is invoked to avoid a memory leak. Can a process be called more than once within a single step? – user487100 Jun 05 '11 at 23:49
  • @user: I'm not *that* familiar with the internals of geant, but I suspect that doing so would mess things up, so it seems unlikely in working code. – dmckee --- ex-moderator kitten Jun 06 '11 at 00:10
  • I just mean, if say, 2 secondaries are generated within a single step, which can happen, the process could be invoked twice, wouldn't you think? I really don't know either. – user487100 Jun 06 '11 at 00:29
  • @user: Er...I don't know. Good question. – dmckee --- ex-moderator kitten Jun 06 '11 at 00:35
  • it would seem according to the information in this link, it would appear each process is only invoked once per type of "DoIt" per step. A G4ParticleChange is returned by the process when its "DoIt" method(s) is/are invoked which contains the list of secondaries. So multiple secondaries can come from just one invocation of a "DoIt". http://www.google.com/url?sa=t&source=web&cd=3&ved=0CCcQFjAC&url=http%3A%2F%2Fconferences.fnal.gov%2Fg4tutorial%2Fg4cd%2FSlides%2FFermilab%2FAdvancedFeatures.pdf&ei=xBnsTf7VMc-Wtwe8wpm-AQ&usg=AFQjCNHHcybpV1I9wXHHKUS5FKpl_6omWg – user487100 Jun 06 '11 at 02:01