<!-- ******************************************************** -->
<!--                                                          -->
<!--  [History]                                               -->
<!--    Created by: Makoto Asai,   24-Nov-2006                -->
<!--    Converted to DocBook: Katsuya Amako, Dec-2006         -->
<!--                                                          -->
<!-- ******************************************************** -->


<!-- ******************* Section (Level#1) ****************** -->
<sect1 id="sect.ParaGeom">
<title>
Parallel Geometries
</title>

<!-- ******************* Section (Level#2) ****************** -->
<sect2 id="sect.ParaGeom.ParaWrld">
<title>
A parallel world
</title>

<para>
Occasionally, it is not straightforward to define geometries for
sensitive detectors, importance geometries or envelopes for shower
parameterization to be coherently assigned to volumes in the
tracking (mass) geometry. The parallel navigation functionality
introduced since release 8.2 of Geant4, allows the user to define
more than one worlds simultaneously.
The <literal>G4Transportation</literal> process will see all worlds
simultaneously; steps will be limited by both boundaries of the
mass and parallel geometries.
</para>

<para>
In a parallel world, the user can define volumes in arbitrary
manner with sensitivity, regions, shower parameterization setups,
and/or importance weight for biasing. Volumes in different worlds
can overlap.
</para>

<para>
Here are restrictions to be considered for the parallel
geometry:

<itemizedlist spacing="compact">
  <listitem><para>
    Materials, production thresholds and EM field are used only
    from the mass geometry. Even if such <emphasis>physical</emphasis> 
    quantities are defined in a parallel world, they do not affect to the
    simulation.
  </para></listitem>
  <listitem><para>
    Although all worlds will be comprehensively taken care by the
    <literal>G4Transportation</literal> process for the navigation, 
    each parallel world must have its own process assigned to achieve 
    its purpose.
    For example: in case the user defines a sensitive detector to a
    parallel world, a process dedicated to the parallel world is
    responsible to invoke this detector. 
    The <literal>G4SteppingManager</literal>
    treats only the detectors in the mass geometry. For this case of
    detector sensitivity defined in a parallel world, a
    <literal>G4ParallelWorldScoringProcess</literal> process must be defined 
    in the physics list (see 
    <xref linkend="sect.ParaGeom.SenstivParaWrld" />).
  </para></listitem>
</itemizedlist>
</para>

</sect2>


<!-- ******************* Section (Level#2) ****************** -->
<sect2 id="sect.ParaGeom.DefParaWrld">
<title>
Defining a parallel world
</title>

<para>
A parallel world should be defined in the <literal>Construct()</literal>
virtual method of the user's class derived from the abstract base
class <emphasis>G4VUserParallelWorld</emphasis>.

<example>
<title>
An example header file of a concrete user parallel world class.
</title>
<programlisting>
#ifndef MyParallelWorld_h
#define MyParallelWorld_h 1

#include "globals.hh"
#include "G4VUserParallelWorld.hh"

class MyParallelWorld : <emphasis role="color_red">public G4VUserParallelWorld</emphasis>
{
  public:
    MyParallelWorld(G4String worldName);
    virtual ~MyParallelWorld();

  public:
    <emphasis role="color_red">virtual void Construct();</emphasis>
};

#endif
</programlisting>
</example>
</para>    

<para>
A parallel world must have its unique name, which should be set
to the <literal>G4VUserParallelWorld</literal> base class as an argument of
the base class constructor.
</para>

<para>
The world physical volume of the parallel world is provided by
the <literal>G4RunManager</literal> as a clone of the mass geometry. In the
<literal>Construct()</literal> virtual method of the user's class, the
pointer to this cloned world physical volume is available through
the <literal>GetWorld()</literal> method defined in the base class. The user
should fill the volumes in the parallel world by using this
provided world volume. For a logical volume in a parallel world,
the material pointer can be <literal>0</literal>. Even if specified a
valid material pointer, it will not be taken into account by any
physics process.


<example>
<title>
An example source code of a concrete user parallel world class.
</title>
<programlisting>
#include "MyParallelWorld.hh"
#include "G4LogicalVolume.hh"
#include "G4VPhysicalVolume.hh"
#include "G4Box.hh"
#include "G4PVPlacement.hh"

MyParallelWorld::MyParallelWorld(G4String worldName)
<emphasis role="color_red">:G4VUserParallelWorld(worldName)</emphasis>
{;}

MyParallelWorld::~MyParallelWorld() 
{;}

void MyParallelWorld::Construct() 
{
  G4VPhysicalVolume* ghostWorld = <emphasis role="color_red">GetWorld();</emphasis>
  G4LogicalVolume* worldLogical = ghostWorld-&gt;GetLogicalVolume();

  // place volumes in the parallel world here. For example ...
  //
  G4Box * ghostSolid = new G4Box("GhostdBox", 60.*cm, 60.*cm, 60.*cm);
  G4LogicalVolume * ghostLogical
        = new G4LogicalVolume(ghostSolid, 0, "GhostLogical", 0, 0, 0);
  new G4PVPlacement(0, G4ThreeVector(), ghostLogical,
                    "GhostPhysical", worldLogical, 0, 0);
}
</programlisting>
</example>
</para>    

<para>
In case the user needs to define more than one parallel worlds,
each of them must be implemented through its dedicated class. Each
parallel world should be registered to the mass geometry class
using the method <literal>RegisterParallelWorld()</literal> available through
the class <literal>G4VUserDetectorConstruction</literal>. The registration
must be done -before- the mass world is registed to the
<literal>G4RunManager</literal>.

<example>
<title>
Typical implementation in the <literal>main()</literal> to define a parallel
world.
</title>
<programlisting>
  // RunManager construction
  //
  G4RunManager* runManager = new G4RunManager;

  // mass world
  //
  MyDetectorConstruction* massWorld = new MyDetectorConstruction;

  // parallel world
  //
  massWorld-&gt;<emphasis role="color_red">RegisterParallelWorld</emphasis>(new MyParallelWorld("ParallelScoringWorld"));

  // set mass world to run manager
  //
  runManager-&gt;SetUserInitialization(massWorld);
</programlisting>
</example>
</para>    

</sect2>

<!-- ******************* Section (Level#2) ****************** -->
<sect2 id="sect.ParaGeom.SenstivParaWrld">
<title>
Detector sensitivity in a parallel world
</title>

<para>
Any kind of <literal>G4VSensitiveDetector</literal> object can be defined
in volumes in a parallel world, exactly at the same manner for the
mass geometry. Once the user defines the sensitive detector in a
parallel world, he/she must define a process which takes care of
these detectors.
</para>

<para>
The <literal>G4ParallelWorldScoringProcess</literal> is the class provided
for this purpose. This process must be defined to all kinds of
particles which need to be "detected". This process must be ordered
<emphasis role="color_red">
just after <literal>G4Transporation</literal> and prior
to any other physics processes</emphasis>. The name of the parallel
world where the <literal>G4ParallelWorldScoringProcess</literal> is
responsible for, must be defined through the method
<literal>SetParallelWorld()</literal> available from the class
<literal>G4ParallelWorldScoringProcess</literal>. If the user has more than
one parallel worlds with detectors, for each of the parallel
worlds, dedicated <literal>G4ParallelWorldScoringProcess</literal> objects
must be instantiated with the name of each parallel world
respectively and registered to the particles.

<example>
<title>
Define <literal>G4ParallelWorldScoringProcess</literal>.
</title>
<programlisting>
  // Add parallel world scoring process
  //
  G4ParallelWorldScoringProcess* theParallelWorldScoringProcess 
      = new <emphasis role="color_red">G4ParallelWorldScoringProcess</emphasis>("ParaWorldScoringProc");
  theParallelWorldScoringProcess-&gt;<emphasis role="color_red">SetParallelWorld</emphasis>("ParallelScoringWorld");

  theParticleIterator-&gt;reset();
  while( (*theParticleIterator)() )
  {
    G4ParticleDefinition* particle = theParticleIterator-&gt;value();
    if (!particle-&gt;IsShortLived())
    {
      G4ProcessManager* pmanager = particle-&gt;GetProcessManager();
      pmanager-&gt;AddProcess(theParallelWorldScoringProcess);
      pmanager-&gt;SetProcessOrderingToLast(theParallelWorldScoringProcess, idxAtRest);
      pmanager-&gt;SetProcessOrdering(theParallelWorldScoringProcess, idxAlongStep, 1);
      pmanager-&gt;SetProcessOrderingToLast(theParallelWorldScoringProcess, idxPostStep);
    }
  }
</programlisting>
</example>
</para>    

<para>
At the end of processing an event, all hits collections made for
the parallel world are stored in <literal>G4HCofThisEvent</literal> as well
as those for the mass geometry.
</para>


</sect2>
</sect1>
