<!-- ******************************************************** -->
<!--                                                          -->
<!--  [History]                                               -->
<!--    Changed by: Katsuya Amako,       4-Aug-1998           -->
<!--    Changed by: Katsuya Amako,       9-Jul-1998           -->
<!--    Proof read by: Joe Chuma,        2-Jul-1999           -->
<!--    few corrections in 3.18.7: mma, 11-Jan-2001           -->
<!--    Converted to DocBook: Katsuya Amako, Aug-2006         -->
<!--                                                          -->
<!-- ******************************************************** -->


<!-- ******************* Section (Level#1) ****************** -->
<sect1 id="sect.ProThres">
<title>
Production Threshold versus Tracking Cut
</title>


<!-- ******************* Section (Level#2) ****************** -->
<sect2 id="sect.ProThres.Gen">
<title>
General considerations
</title>

<para>
We have to fulfill two contradictory requirements. It is the
responsibility of each individual <emphasis role="bold">process</emphasis> 
to produce secondary particles according to its own capabilities. On 
the other hand, it is only the Geant4 kernel (i.e., tracking) which can
ensure an overall coherence of the simulation.
</para>

<para>
The general principles in Geant4 are the following:

<orderedlist spacing="compact">
  <listitem><para>
    Each <emphasis role="bold">process</emphasis> has its intrinsic limit(s) 
    to produce secondary particles.
  </para></listitem>
  <listitem><para>
    All particles produced (and accepted) will be tracked up to
    <emphasis role="bold">zero range</emphasis>.
  </para></listitem>
  <listitem><para>
    Each <emphasis role="bold">particle</emphasis> has a suggested cut in range 
    (which is converted to energy for all materials), and defined via a
    <literal>SetCut()</literal> method (see 
    <xref linkend="sect.HowToSpecParti.RangeCuts" />).
  </para></listitem>
</orderedlist>
</para>

<para>
Points 1 and 2 imply that the cut associated with the
<emphasis role="bold">particle</emphasis> is a (recommended) 
<emphasis role="bold">production</emphasis> threshold of secondary particles.
</para>

</sect2>

<!-- ******************* Section (Level#2) ****************** -->
<sect2 id="sect.ProThres.Set">
<title>
Set production threshold (<literal>SetCut</literal> methods)
</title>

<para>
As already mentioned, each kind of particle has a suggested
production threshold. Some of the processes will not use this
threshold (e.g., decay), while other processes will use it as a
default value for their intrinsic limits (e.g., ionisation and
bremsstrahlung).
</para>

<para>See 
<xref linkend="sect.HowToSpecParti.RangeCuts" /> to see how to set 
the production threshold.
</para>

</sect2>


<!-- ******************* Section (Level#2) ****************** -->
<sect2 id="sect.ProThres.Apply">
<title>
Apply cut
</title>

<para>
The <literal>DoIt</literal> methods of each process can produce secondary
particles. Two cases can happen:

<itemizedlist spacing="compact">
  <listitem><para>
    a process sets its intrinsic limit greater than or equal to the
    recommended production threshold. OK. Nothing has to be done
    (nothing can be done !).
  </para></listitem>
  <listitem><para>
    a process sets its intrinsic limit smaller than the production
    threshold (for instance 0).
  </para></listitem>
</itemizedlist>
</para>

<para>
The list of secondaries is sent to the <emphasis>SteppingManager</emphasis>
via a <emphasis>ParticleChange</emphasis> object.
</para>

<para>
<emphasis>Before</emphasis> being recopied to the temporary stack for later 
tracking, the particles below the production threshold will be kept or
deleted according to the safe mechanism explained hereafter.

<itemizedlist spacing="compact">
  <listitem><para>
    The <emphasis>ParticleDefinition</emphasis> 
    (or <emphasis>ParticleWithCuts</emphasis>) has a boolean data member: 
    <literal>ApplyCut</literal>.</para></listitem>
    <listitem><para><literal>ApplyCut</literal> is OFF: do nothing. 
    All the secondaries are stacked (and then tracked later on), regardless 
    of their initial energy. The Geant4 kernel respects the best that the 
    physics can do, but neglects the overall coherence and the efficiency. 
    Energy conservation is respected as far as the processes know how to
    handle correctly the particles they produced!
  </para></listitem>
  <listitem><para>
    <literal>ApplyCut</literal> in ON: the <emphasis>TrackingManager</emphasis> 
    checks the range of each secondary against the production threshold and
    against the safety. The particle is stacked if <literal>range &gt;
    min(cut,safety).</literal>
    <itemizedlist spacing="compact">
      <listitem><para>
        If not, check if the process has nevertheless set the flag
        ``good for tracking'' and then stack it (see 
        <xref linkend="sect.ProThres.WhyProd" />
        below for the explanation of the <literal>GoodForTracking</literal> flag).
      </para></listitem>
      <listitem><para>
        If not, recuperate its kinetic energy in the
        <literal>localEnergyDeposit</literal>, and set 
        <literal>tkin=0</literal>.
      </para></listitem>
      <listitem><para>
        Then check in the <emphasis>ProcessManager</emphasis> if the vector of
        <emphasis>ProcessAtRest</emphasis> is not empty. If yes, stack the
        particle for performing the ``Action At Rest'' later. If not, and only
        in this case, abandon this secondary.
      </para></listitem>
    </itemizedlist>
  </para></listitem>
</itemizedlist>
</para>

<para>
With this sophisticated mechanism we have the global cut that we
wanted, but with energy conservation, and we respect boundary
constraint (safety) and the wishes of the processes (via ``good for
tracking'').
</para>

</sect2>


<!-- ******************* Section (Level#2) ****************** -->
<sect2 id="sect.ProThres.WhyProd">
<title>
Why produce secondaries below threshold?
</title>

<para>
A process may have good reasons to produce particles below the
recommended threshold:

<itemizedlist spacing="compact">
  <listitem><para>
    checking the range of the secondary versus geometrical
    quantities like safety may allow one to realize the possibility
    that the produced particle, even below threshold, will reach a
    sensitive part of the detector;
  </para></listitem>
  <listitem><para>
    another example is the gamma conversion: the positron is always
    produced, even at zero energy, for further annihilation.
  </para></listitem>
</itemizedlist>
</para>

<para>
These secondary particles are sent to the ``Stepping Manager''
with a flag <literal>GoodForTracking</literal> to pass the filter explained
in the previous section (even when <literal>ApplyCut</literal> is ON).
</para>

</sect2>


<!-- ******************* Section (Level#2) ****************** -->
<sect2 id="sect.ProThres.RangOrEner">
<title>
Cuts in stopping range or in energy?
</title>

<para>
The cuts in stopping range allow one to say that the energy has
been released at the correct space position, limiting the
approximation within a given distance. On the contrary, cuts in
energy imply accuracies of the energy depositions which depend on
the material.
</para>

</sect2>


<!-- ******************* Section (Level#2) ****************** -->
<sect2 id="sect.ProThres.Sum">
<title>
Summary
</title>

<para>
In summary, we do not have tracking cuts; we only have production
thresholds in range. All particles produced and accepted are
tracked up to zero range.
</para>

<para>
It must be clear that the overall coherency that we provide
cannot go beyond the capability of processes to produce particles
down to the recommended threshold.
</para>

<para>
In other words a process can produce the secondaries down to the
recommended threshold, and by interrogating the geometry, or by
realizing when mass-to-energy conversion can occur, recognize when
particles below the threshold have to be produced.
</para>

</sect2>


<!-- ******************* Section (Level#2) ****************** -->
<sect2 id="sect.ProThres.Spe">
<title>
Special tracking cuts
</title>

<para>
One may need to cut given particle types in given volumes for
optimisation reasons. This decision is under user control, and can
happen for particles during tracking as well.
</para>

<para>
The user must be able to apply these special cuts only for the
desired particles and in the desired volumes, without introducing
an overhead for all the rest.
</para>

<para>
The approach is as follows:

<itemizedlist spacing="compact">
  <listitem><para>
    special user cuts are registered in the <emphasis>UserLimits</emphasis> 
    class (or its descendant), which is associated with the logical volume
    class.
    <para>
    The current default list is:
    <itemizedlist spacing="compact">
      <listitem><para>
        max allowed step size
      </para></listitem>
      <listitem><para>
        max total track length
      </para></listitem>
      <listitem><para>
        max total time of flight
      </para></listitem>
      <listitem><para>
        min kinetic energy
      </para></listitem>
      <listitem><para>
        min remaining range
      </para></listitem>
    </itemizedlist>
    </para>
    <para>
    The user can instantiate a <emphasis>UserLimits</emphasis> object only 
    for the desired logical volumes and do the association.
    </para>
    <para>
    The first item (max step size) is automatically taken into
    account by the G4 kernel while the others items must be managed by
    the user, as explained below.
    </para>
    <para>
    <emphasis role="bold">Example</emphasis>(see novice/N02): 
    in the Tracker region, in order to force the step size not to exceed 
    1/10 of the Tracker thickness, it is enough to put the following code in
    <literal>DetectorConstruction::Construct()</literal>:
    <informalexample>
    <programlisting>
       G4double maxStep = 0.1*TrackerLength;
       logicTracker-&gt;SetUserLimits(new G4UserLimits(maxStep));
    </programlisting>
    </informalexample>
    and in <literal>PhysicsList</literal>, the process 
    <literal>G4StepLimiter</literal> needs to be attached to each
    particle's process manager where step limitation in the Tracker region
    is required:
    <informalexample>
    <programlisting>
       // Step limitation seen as a process
       G4StepLimiter* stepLimiter = new G4StepLimiter();
       pmanager-&gt;AddDiscreteProcess(StepLimiter);
    </programlisting>
    </informalexample>
    </para>
    <para>
    The <emphasis>G4UserLimits</emphasis> class is in
    <literal>source/global/management</literal>.
    </para>
  </para></listitem>
  <listitem><para>
    Concerning the others cuts, the user must define 
    dedicaced process(es). He registers this process (or its descendant) 
    only for the desired particles in their process manager. He can apply 
    his cuts in the <literal>DoIt</literal> of this process, since, via
    <emphasis>G4Track</emphasis>, he can access the logical volume and
    <emphasis>UserLimits</emphasis>.

    <para>
    An example of such process (called <emphasis>UserSpecialCuts</emphasis>) is
    provided in the repository, but not inserted in any process manager
    of any particle.
    </para>
    <para>
    <emphasis role="bold">Example: neutrons.</emphasis> One may need to abandon 
    the tracking of neutrons after a given time of flight (or a charged
    particle in a magnetic field after a given total track length ... etc ...).
    </para>
    <para>
    Example(see novice/N02): in the Tracker region, in order to
    force the total time of flight of the neutrons not to exceed 10
    milliseconds, put the following code in
    <literal>DetectorConstruction::Construct()</literal>:

    <informalexample>
    <programlisting>
        G4double maxTime = 10*ms;
        logicTracker-&gt;SetUserLimits(new G4UserLimits(DBL_MAX,DBL_MAX,maxTime));
    </programlisting>
    </informalexample>      

    and put the following code in <literal>N02PhysicsList</literal>:

    <informalexample>
    <programlisting>
        G4ProcessManager* pmanager = G4Neutron::Neutron-&gt;GetProcessManager();
        pmanager-&gt;AddProcess(new G4UserSpecialCuts(),-1,-1,1);
    </programlisting>
    </informalexample>
    </para>
    <para>
    (The default <emphasis>G4UserSpecialCuts</emphasis> class is in
     <literal>source/processes/transportation</literal>.)
    </para>
  </para></listitem>
</itemizedlist>
</para>

</sect2>
</sect1>
