<!-- ******************************************************** -->
<!--                                                          -->
<!--  [History]                                               -->
<!--    Converted to DocBook: Katsuya Amako, Aug-2006         -->
<!--    Changed by: Katsuya Amako, 21-Sep-1998                -->
<!--    Proof read by: Joe Chuma,  30-Jun-1999                -->
<!--    Changed by: Dennis Wright, 29-Nov-2001                -->
<!--    Changed by: Makoto Asai,   30-Nov-2005                -->
<!--                                                          -->
<!-- ******************************************************** -->

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


<!-- ******************* Section (Level#2) ****************** -->
<sect2 id="sect.Hits.Hit">
<title>
Hit
</title>

<para>
A hit is a snapshot of the physical interaction of a track in the
sensitive region of a detector. In it you can store information
associated with a <emphasis>G4Step</emphasis> object. This information can be

<itemizedlist spacing="compact">
  <listitem><para>
    the position and time of the step,
  </para></listitem>
  <listitem><para>
    the momentum and energy of the track,
  </para></listitem>
  <listitem><para>
    the energy deposition of the step,
  </para></listitem>
  <listitem><para>
    geometrical information,
  </para></listitem>
</itemizedlist>

or any combination of the above.
</para>

<!-- ******* Bridgehead ******* -->
<bridgehead renderas='sect4'>
G4VHit
</bridgehead>

<para>
<emphasis>G4VHit</emphasis> is an abstract base class which represents a hit.
You must inherit this base class and derive your own concrete hit
class(es). The member data of your concrete hit class can be, and
should be, your choice.
</para>

<para>
<emphasis>G4VHit</emphasis> has two virtual methods, <literal>Draw()</literal> and
<literal>Print()</literal>. To draw or print out your concrete hits, these
methods should be implemented. How to define the drawing method is
described in <xref linkend="sect.VisPlylMrkTxt" />.
</para>

<!-- ******* Bridgehead ******* -->
<bridgehead renderas='sect4'>
G4THitsCollection
</bridgehead>

<para>
<emphasis>G4VHit</emphasis> is an abstract class from which you derive your
own concrete classes. During the processing of a given event,
represented by a <emphasis>G4Event</emphasis> object, many objects of the hit
class will be produced, collected and associated with the event.
Therefore, for each concrete hit class you must also prepare a
concrete class derived from <emphasis>G4VHitsCollection</emphasis>, an abstract
class which represents a vector collection of user defined
hits.
</para>

<para>
<emphasis>G4THitsCollection</emphasis> is a template class derived from
<emphasis>G4VHitsCollection</emphasis>, and the concrete hit collection class of
a particular <emphasis>G4VHit</emphasis> concrete class can be instantiated from
this template class. Each object of a hit collection must have a
unique name for each event.
</para>

<para>
<emphasis>G4Event</emphasis> has a <emphasis>G4HCofThisEvent</emphasis> class 
object, that is a container class of collections of hits. Hit collections are
stored by their pointers, whose type is that of the base class.
</para>

<!-- ******* Bridgehead ******* -->
<bridgehead renderas='sect4'>
An example of a concrete hit class
</bridgehead>

<para>
<xref linkend="programlist_Hits_1" /> shows an example of a concrete hit class.

<example id="programlist_Hits_1">
<title>
An example of a concrete hit class.
</title>

<programlisting>
#ifndef ExN04TrackerHit_h
#define ExN04TrackerHit_h 1

#include "G4VHit.hh"
#include "G4THitsCollection.hh"
#include "G4Allocator.hh"
#include "G4ThreeVector.hh"

class ExN04TrackerHit : public G4VHit
{
  public:

      ExN04TrackerHit();
      ~ExN04TrackerHit();
      ExN04TrackerHit(const ExN04TrackerHit &amp;right);
      const ExN04TrackerHit&amp; operator=(const ExN04TrackerHit &amp;right);
      int operator==(const ExN04TrackerHit &amp;right) const;

      inline void * operator new(size_t);
      inline void operator delete(void *aHit);

      void Draw() const;
      void Print() const;

  private:
      G4double edep;
      G4ThreeVector pos;

  public:
      inline void SetEdep(G4double de)
      { edep = de; }
      inline G4double GetEdep() const
      { return edep; }
      inline void SetPos(G4ThreeVector xyz)
      { pos = xyz; }
      inline G4ThreeVector GetPos() const
      { return pos; }

};

typedef G4THitsCollection&lt;ExN04TrackerHit&gt; ExN04TrackerHitsCollection;

extern G4Allocator&lt;ExN04TrackerHit&gt; ExN04TrackerHitAllocator;

inline void* ExN04TrackerHit::operator new(size_t)
{
  void *aHit;
  aHit = (void *) ExN04TrackerHitAllocator.MallocSingle();
  return aHit;
}

inline void ExN04TrackerHit::operator delete(void *aHit)
{
  ExN04TrackerHitAllocator.FreeSingle((ExN04TrackerHit*) aHit);
}

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

<para>
<emphasis>G4Allocator</emphasis> is a class for fast allocation of objects to
the heap through the paging mechanism. For details of
<emphasis>G4Allocator</emphasis>, refer to <xref linkend="sect.GeneManage" />. 
Use of <emphasis>G4Allocator</emphasis>
is not mandatory, but it is recommended, especially for users who
are not familiar with the C++ memory allocation mechanism or
alternative tools of memory allocation. On the other hand, note
that <emphasis>G4Allocator</emphasis> is to be used 
<emphasis role="bold">only</emphasis> for the concrete
class that is <emphasis role="bold">not</emphasis> used as a base 
class of any other classes.
For example, do <emphasis role="bold">not</emphasis> use the 
<emphasis>G4Trajectory</emphasis> class as a
base class for a customized trajectory class, since
<emphasis>G4Trajectory</emphasis> uses <emphasis>G4Allocator</emphasis>.
</para>

<!-- ******* Bridgehead ******* -->
<bridgehead renderas='sect4'>
G4THitsMap
</bridgehead>

<para>
<emphasis>G4THitsMap</emphasis> is an alternative to 
<emphasis>G4THitsCollection</emphasis>.
<emphasis>G4THitsMap</emphasis> does not demand <emphasis>G4VHit</emphasis>, 
but instead any variable which can be mapped with an integer key. Typically the key
is a copy number of the volume, and the mapped value could for
example be a double, such as the energy deposition in a volume.
<emphasis>G4THitsMap</emphasis> is convenient for applications which do not need
to output event-by-event data but instead just accumulate them. All
the <emphasis>G4VPrimitiveScorer</emphasis> classes discussed in 
<xref linkend="sect.Hits.G4Multi" /> use <emphasis>G4THitsMap</emphasis>.
</para>

<para>
<emphasis>G4THitsMap</emphasis> is derived from the 
<emphasis>G4VHitsCollection</emphasis>
abstract base class and all objects of this class are also stored
in <emphasis>G4HCofThisEvent</emphasis> at the end of an event. How to access a
<emphasis>G4THitsMap</emphasis> object is discussed in the 
following section (<xref linkend="sect.Hits.G4Multi" />).
</para>

</sect2>


<!-- ******************* Section (Level#2) ****************** -->
<sect2 id="sect.Hits.SensDet">
<title>
Sensitive detector
</title>

<!-- ******* Bridgehead ******* -->
<bridgehead renderas='sect4'>
G4VSensitiveDetector
</bridgehead>

<para>
<emphasis>G4VSensitiveDetector</emphasis> is an abstract base class which
represents a detector. The principal mandate of a sensitive
detector is the construction of hit objects using information from
steps along a particle track. The <literal>ProcessHits()</literal> method of
<emphasis>G4VSensitiveDetector</emphasis> performs this task using 
<emphasis>G4Step</emphasis>
objects as input. In the case of a "Readout" geometry (see 
<xref linkend="sect.Hits.ReadGeom" />), objects of the
<emphasis>G4TouchableHistory</emphasis> class may be used as an optional input.
</para>

<para>
Your concrete detector class should be instantiated with the
unique name of your detector. The name can be associated with one
or more global names with "/" as a delimiter for categorizing your
detectors. For example

<informalexample>
<programlisting>
     myEMcal = new MyEMcal("/myDet/myCal/myEMcal");
</programlisting>
</informalexample> 

where <literal>myEMcal</literal> is the name of your detector. The pointer to
your sensitive detector must be set to one or more
<emphasis>G4LogicalVolume</emphasis> objects to set the sensitivity of these
volumes. The pointer should also be registered to
<emphasis>G4SDManager</emphasis>, as described in 
<xref linkend="sect.Hits.G4SDMan" />.
</para>

<para>
<emphasis>G4VSensitiveDetector</emphasis> has three major virtual methods.

<variablelist><title></title>
  <varlistentry>
    <term>
      <literal>ProcessHits()</literal>
    </term>
    <listitem><para>
      This method is invoked by <emphasis>G4SteppingManager</emphasis> when a step
      is composed in the <emphasis>G4LogicalVolume</emphasis> which has the pointer 
      to this sensitive detector. The first argument of this method is a
      <emphasis>G4Step</emphasis> object of the current step. The second argument is a
      <emphasis>G4TouchableHistory</emphasis> object for the ``Readout geometry''
      described in the next section. The second argument is <literal>NULL</literal>
      if ``Readout geometry'' is not assigned to this sensitive detector.
      In this method, one or more <emphasis>G4VHit</emphasis> objects should be
      constructed if the current step is meaningful for your
      detector.
    </para></listitem>
  </varlistentry>
  <varlistentry>
    <term>
      <literal>Initialize()</literal>
    </term>
    <listitem><para>
      This method is invoked at the beginning of each event. The
      argument of this method is an object of the <emphasis>G4HCofThisEvent</emphasis>
      class. Hit collections, where hits produced in this particular
      event are stored, can be associated with the <emphasis>G4HCofThisEvent</emphasis>
      object in this method. The hit collections associated with the
      <emphasis>G4HCofThisEvent</emphasis> object during this method can be used for
      ``during the event processing'' digitization.
    </para></listitem>
  </varlistentry>
  <varlistentry>
    <term>
      <literal>EndOfEvent()</literal>
    </term>
    <listitem><para>
      This method is invoked at the end of each event. The argument
      of this method is the same object as the previous method. Hit
      collections occasionally created in your sensitive detector can be
      associated with the <emphasis>G4HCofThisEvent</emphasis> object.
    </para></listitem>
  </varlistentry>
</variablelist>
</para>

</sect2>


<!-- ******************* Section (Level#2) ****************** -->
<sect2 id="sect.Hits.ReadGeom">
<title>
Readout geometry
</title>

<para>
This section describes how a ``Readout geometry'' can be defined. A
Readout geometry is a virtual, parallel geometry for obtaining the
channel number.
</para>

<para>
As an example, the accordion calorimeter of <emphasis role="bold">ATLAS</emphasis> 
has a complicated tracking geometry, however the readout can be done by
simple cylindrical sectors divided by theta, phi, and depth. Tracks
will be traced in the tracking geometry, the ``real'' one, and the
sensitive detector will have its own readout geometry Geant4 will
message to find to which ``readout'' cell the current hit
belongs.

<figure id="fig.Hits_1">
<title>
Association of tracking and readout geometry.
</title>
<mediaobject>
  <imageobject role="fo">
    <imagedata fileref="./AllResources/Detector/hit.src/RO.jpg"
               format="JPG" contentwidth="10.0cm" align="center" />
  </imageobject>
  <imageobject role="html">
    <imagedata fileref="./AllResources/Detector/hit.src/RO.jpg"
               format="JPG" align="center" />
  </imageobject>
</mediaobject>
</figure>
</para>

<para>
<xref linkend="fig.Hits_1" /> shows how this association is done in Geant4. 
The first step is to associate a sensitive detector to a volume of the
tracking geometry, in the usual way (see 
<xref linkend="sect.Hits.SensDet" />). The next step is to associate your
<emphasis>G4VReadoutGeometry</emphasis> object to the sensitive detector.
</para>

<para>
At tracking time, the base class <emphasis>G4VReadoutGeometry</emphasis> will
provide to your sensitive detector code the
<emphasis>G4TouchableHistory</emphasis> in the Readout geometry at the beginning
of the step position (position of <emphasis>PreStepPoint</emphasis> of
<emphasis>G4Step</emphasis>) and at this position only.
</para>

<para>
This <emphasis>G4TouchableHistory</emphasis> is given to your sensitive
detector code through the <emphasis>G4VSensitiveDetector</emphasis> virtual
method:

<informalexample>
<programlisting>
        G4bool processHits(G4Step* aStep, G4TouchableHistory* ROhist);
</programlisting>
</informalexample>

by the <literal>ROhist</literal> argument.
</para>

<para>
Thus, you will be able to use information from both the
<emphasis>G4Step</emphasis> and the <emphasis>G4TouchableHistory</emphasis> 
coming from your
Readout geometry. Note that since the association is done through a
sensitive detector object, it is perfectly possible to have several
Readout geometries in parallel.
</para>


<!-- ******* Bridgehead ******* -->
<bridgehead renderas='sect4'>
Definition of a virtual geometry setup
</bridgehead>

<para>
The base class for the implementation of a Readout geometry is
<emphasis>G4VReadoutGeometry</emphasis>. This class has a single pure virtual
protected method:

<informalexample>
<programlisting>
        virtual G4VPhysicalVolume* build() = 0;
</programlisting>
</informalexample>

which you must override in your concrete class. The
<emphasis>G4VPhysicalVolume</emphasis> pointer you will have to return is of the
physical world of the Readout geometry.
</para>

<para>
The step by step procedure for constructing a Readout geometry is:

<itemizedlist spacing="compact">
  <listitem><para>
    inherit from <emphasis>G4VReadoutGeometry</emphasis> to define a
    <emphasis>MyROGeom</emphasis> class;
  </para></listitem>
  <listitem><para>
    implement the Readout geometry in the <literal>build()</literal> method,
    returning the physical world of this geometry.
    <para>
    The world is specified in the same way as for the detector
    construction: a physical volume with no mother. The axis system of
    this world is the same as the one of the world for tracking.
    </para>
    <para>
    In this geometry you need to declare the sensitive parts in the
    same way as in the tracking geometry: by setting a
    non-<literal>NULL</literal> <emphasis>G4VSensitiveDetector</emphasis> 
    pointer in, say, the
    relevant <emphasis>G4LogicalVolume</emphasis> objects. This sensitive class needs
    to be there, but will not be used.
    </para>
    <para>
    You will also need to assign well defined materials to the
    volumes you place in this geometry, but these materials are
    irrelevant since they will not be seen by the tracking. It is
    foreseen to allow the setting of a <literal>NULL</literal> pointer in this
    case of the parallel geometry.
    </para>
  </para></listitem>
  <listitem><para>
    in the <literal>construct()</literal> method of your concrete
    <emphasis>G4VUserDetectorConstruction</emphasis> class:
    <para>
    <itemizedlist spacing="compact">
      <listitem><para>
        instantiate your Readout geometry:
        <informalexample>
        <programlisting>
        MyROGeom* ROgeom = new MyROGeom("ROName");
        </programlisting>
        </informalexample>            
      </para></listitem>
      <listitem><para>
        build it:
        <informalexample>
        <programlisting>
        ROgeom-&gt;buildROGeometry();
        </programlisting>
        </informalexample>
        That will invoke your <literal>build()</literal> method.
      </para></listitem>
      <listitem><para>
        Instantiate the sensitive detector which will receive the
        <literal>ROGeom</literal> pointer, <literal>MySensitive</literal>, 
        and add this sensitive to the <emphasis>G4SDManager</emphasis>. 
        Associate this sensitive to
        the volume(s) of the tracking geometry as usual.
      </para></listitem>
      <listitem><para>
        Associate the sensitive to the Readout geometry:
        <informalexample>
        <programlisting>
        MySensitive-&gt;SetROgeometry(ROgeom);
        </programlisting>
        </informalexample>            
      </para></listitem>
    </itemizedlist>
    </para>
  </para></listitem>
</itemizedlist>
</para>

</sect2>


<!-- ******************* Section (Level#2) ****************** -->
<sect2 id="sect.Hits.G4SDMan">
<title>
G4SDManager
</title>

<para>
<emphasis>G4SDManager</emphasis> is the singleton manager class for sensitive
detectors.
</para>

<!-- ******* Bridgehead ******* -->
<bridgehead renderas='sect4'>
Activation/inactivation of sensitive detectors
</bridgehead>

<para>
The user interface commands <literal>activate</literal> and
<literal>inactivate</literal> are available to control your sensitive
detectors. For example:

<informalexample>
<programlisting>
/hits/activate detector_name
/hits/inactivate detector_name
</programlisting>
</informalexample>

where <literal>detector_name</literal> can be the detector name or the
category name. 
</para>

<para>
For example, if your EM calorimeter is named

<informalexample>
<programlisting>
/myDet/myCal/myEMcal
/hits/inactivate myCal
</programlisting>
</informalexample>

will inactivate all detectors belonging to the <literal>myCal</literal>
category.
</para>

<!-- ******* Bridgehead ******* -->
<bridgehead renderas='sect4'>
Access to the hit collections
</bridgehead>


<para>Hit collections are accessed for various cases.

<itemizedlist spacing="compact">
  <listitem><para>
    Digitization
  </para></listitem>
  <listitem><para>
    Event filtering in <emphasis>G4VUserStackingAction</emphasis>
  </para></listitem>
  <listitem><para>
    ``End of event'' simple analysis
  </para></listitem>
  <listitem><para>
    Drawing / printing hits
  </para></listitem>
</itemizedlist>
</para>

<para>
The following is an example of how to access the hit collection
of a particular concrete type:

<informalexample>
<programlisting>
  G4SDManager* fSDM = G4SDManager::GetSDMpointer();
  G4RunManager* fRM = G4RunManager::GetRunManager();
  G4int collectionID = fSDM-&gt;GetCollectionID("collection_name");
  const G4Event* currentEvent = fRM-&gt;GetCurrentEvent();
  G4HCofThisEvent* HCofEvent = currentEvent-&gt;GetHCofThisEvent();
  <emphasis>MyHitsCollection</emphasis>* myCollection = (<emphasis>MyHitsCollection</emphasis>*)(HC0fEvent-&gt;GetHC(collectionID));
</programlisting>
</informalexample> 
</para>

</sect2>


<!-- ******************* Section (Level#2) ****************** -->
<sect2 id="sect.Hits.G4Multi">
<title>
<emphasis>G4MultiFunctionalDetector</emphasis> and
<emphasis>G4VPrimitiveScorer</emphasis>
</title>
 
<para>
<emphasis>G4MultiFunctionalDetector</emphasis> is a concrete class derived from
<emphasis>G4VSensitiveDetector</emphasis>. Instead of implementing a
user-specific detector class, <emphasis>G4MultiFunctionalDetector</emphasis>
allows the user to register <emphasis>G4VPrimitiveScorer</emphasis> classes to
build up the sensitivity. <emphasis>G4MultiFunctionalDetector</emphasis> should
be instantiated in the users detector construction with its unique
name and should be assigned to one or more <emphasis>G4LogicalVolume</emphasis>s.
</para>

<para>
<emphasis>G4VPrimitiveScorer</emphasis> is an abstract base class representing
a class to be registered to <emphasis>G4MultiFunctionalDetector</emphasis> that
creates a <emphasis>G4THitsMap</emphasis> object of one physics quantity for an
event. Geant4 provides many concrete primitive scorer classes
listed in <xref linkend="sect.Hits.G4VPrim" />, and the user can
also implement his/her own primitive scorers. Each primitive scorer
object must be instantiated with a name that must be unique among
primitive scorers registered in a <emphasis>G4MultiFunctionalDetector</emphasis>.
Please note that a primitive scorer object must <emphasis role="bold">not</emphasis> be
shared by more than one <emphasis>G4MultiFunctionalDetector</emphasis>
object.
</para>

<para>As mentioned in <xref linkend="sect.Hits.Hit" />, 
each <emphasis>G4VPrimitiveScorer</emphasis> generates one 
<emphasis>G4THitsMap</emphasis> object
per event. The name of the map object is the same as the name of
the primitive scorer. Each of the concrete primitive scorers listed
in <xref linkend="sect.Hits.G4VPrim" /> generates a 
<emphasis>G4THitsMap&lt;G4double&gt;</emphasis> that maps a 
<emphasis>G4double</emphasis> value
to its key integer number. By default, the key is taken as the copy
number of the <emphasis>G4LogicalVolume</emphasis> to which
<emphasis>G4MultiFunctionalDetector</emphasis> is assigned. In case the logical
volume is uniquely placed in its mother volume and the mother is
replicated, the copy number of its mother volume can be taken by
setting the second argument of the <emphasis>G4VPrimitiveScorer</emphasis>
constructor, "<emphasis>depth</emphasis>" to 1, i.e. one level up. Furthermore,
in case the key must consider more than one copy number of a
different geometry hierarchy, the user can derive his/her own
primitive scorer from the provided concrete class and implement the
<emphasis>GetIndex(G4Step*)</emphasis> virtual method to return the unique
key.
</para>

<para>
<xref linkend="programlist_Hits_2" /> shows an example of primitive sensitivity
class definitions.

<example id="programlist_Hits_2">
<title>
An example of defining primitive sensitivity classes taken from
<emphasis>ExN07DetectorConstruction</emphasis>.
</title>
<programlisting>
void ExN07DetectorConstruction::SetupDetectors()
{ 
  G4String filterName, particleName;
  
  G4SDParticleFilter* gammaFilter = 
    new G4SDParticleFilter(filterName="gammaFilter",particleName="gamma");
  G4SDParticleFilter* electronFilter = 
    new G4SDParticleFilter(filterName="electronFilter",particleName="e-");
  G4SDParticleFilter* positronFilter = 
    new G4SDParticleFilter(filterName="positronFilter",particleName="e+");
  G4SDParticleFilter* epFilter = new G4SDParticleFilter(filterName="epFilter");
  epFilter-&gt;add(particleName="e-");
  epFilter-&gt;add(particleName="e+");
    
    
  for(G4int i=0;i&lt;3;i++)
  {
   for(G4int j=0;j&lt;2;j++)
   {
    // Loop counter j = 0 : absorber
    //                = 1 : gap
    G4String detName = calName[i];
    if(j==0)
    { detName += "_abs"; }
    else
    { detName += "_gap"; }
    G4MultiFunctionalDetector* det = new G4MultiFunctionalDetector(detName);
  
    //  The second argument in each primitive means the "level" of geometrical hierarchy,
    // the copy number of that level is used as the key of the G4THitsMap.
    //  For absorber (j = 0), the copy number of its own physical volume is used.
    //  For gap (j = 1), the copy number of its mother physical volume is used, since there
    // is only one physical volume of gap is placed with respect to its mother.
    G4VPrimitiveScorer* primitive;
    primitive = new G4PSEnergyDeposit("eDep",j);
    det-&gt;RegisterPrimitive(primitive);
    primitive = new G4PSNofSecondary("nGamma",j);
    primitive-&gt;SetFilter(gammaFilter);
    det-&gt;RegisterPrimitive(primitive);
    primitive = new G4PSNofSecondary("nElectron",j);
    primitive-&gt;SetFilter(electronFilter);
    det-&gt;RegisterPrimitive(primitive);
    primitive = new G4PSNofSecondary("nPositron",j);
    primitive-&gt;SetFilter(positronFilter);
    det-&gt;RegisterPrimitive(primitive);
    primitive = new G4PSMinKinEAtGeneration("minEkinGamma",j);
    primitive-&gt;SetFilter(gammaFilter);
    det-&gt;RegisterPrimitive(primitive);
    primitive = new G4PSMinKinEAtGeneration("minEkinElectron",j);
    primitive-&gt;SetFilter(electronFilter);
    det-&gt;RegisterPrimitive(primitive);
    primitive = new G4PSMinKinEAtGeneration("minEkinPositron",j);
    primitive-&gt;SetFilter(positronFilter);
    det-&gt;RegisterPrimitive(primitive);
    primitive = new G4PSTrackLength("trackLength",j);
    primitive-&gt;SetFilter(epFilter);
    det-&gt;RegisterPrimitive(primitive);
    primitive = new G4PSNofStep("nStep",j);
    primitive-&gt;SetFilter(epFilter); 
    det-&gt;RegisterPrimitive(primitive);
  
    G4SDManager::GetSDMpointer()-&gt;AddNewDetector(det);
    if(j==0)
    { layerLogical[i]-&gt;SetSensitiveDetector(det); }
    else
    { gapLogical[i]-&gt;SetSensitiveDetector(det); }
   }
  }
}
</programlisting>
</example>
</para>

<para>
Each <emphasis>G4THitsMap</emphasis> object can be accessed from
<emphasis>G4HCofThisEvent</emphasis> with a unique collection ID number. This ID
number can be obtained from <emphasis>G4SDManager::GetCollectionID()</emphasis>
with a name of <emphasis>G4MultiFunctionalDetector</emphasis> and
<emphasis>G4VPrimitiveScorer</emphasis> connected with a slush ("/").
<emphasis>G4THitsMap</emphasis> has a [] operator taking the key value as an
argument and returning <emphasis role="bold">the pointer</emphasis> of the value. 
Please note that the [] operator returns 
<emphasis role="bold">the pointer</emphasis> of the value. If
you get zero from the [] operator, it does <emphasis role="bold">not</emphasis> mean the
value is zero, but that the provided key does not exist. The value
itself is accessible with an astarisk ("*"). It is advised to check
the validity of the returned pointer before accessing the value.
<emphasis>G4THitsMap</emphasis> also has a += operator in order to accumulate
event data into run data. <xref linkend="programlist_Hits_3" /> shows the use of
<emphasis>G4THitsMap</emphasis>.

<example id="programlist_Hits_3">
<title>
An example of accessing to <emphasis>G4THitsMap</emphasis> objects.
</title>

<programlisting>
#include "ExN07Run.hh"
#include "G4Event.hh"
#include "G4HCofThisEvent.hh"
#include "G4SDManager.hh"

ExN07Run::ExN07Run()
{
  G4String detName[6] = {"Calor-A_abs","Calor-A_gap","Calor-B_abs","Calor-B_gap",
                         "Calor-C_abs","Calor-C_gap"};
  G4String primNameSum[6] = {"eDep","nGamma","nElectron","nPositron","trackLength","nStep"};
  G4String primNameMin[3] = {"minEkinGamma","minEkinElectron","minEkinPositron"};

  G4SDManager* SDMan = G4SDManager::GetSDMpointer();
  G4String fullName;
  for(size_t i=0;i&lt;6;i++)
  {
    for(size_t j=0;j&lt;6;j++)
    {
      fullName = detName[i]+"/"+primNameSum[j];
      colIDSum[i][j] = SDMan-&gt;GetCollectionID(fullName);
    }
    for(size_t k=0;k&lt;3;k++)
    {
      fullName = detName[i]+"/"+primNameMin[k];
      colIDMin[i][k] = SDMan-&gt;GetCollectionID(fullName);
    }
  }
}


void ExN07Run::RecordEvent(const G4Event* evt)
{
  G4HCofThisEvent* HCE = evt-&gt;GetHCofThisEvent();
  if(!HCE) return;
  numberOfEvent++;
  for(size_t i=0;i&lt;6;i++)
  {
    for(size_t j=0;j&lt;6;j++)
    {
      G4THitsMap&lt;G4double&gt;* evtMap = (G4THitsMap&lt;G4double&gt;*)(HCE-&gt;GetHC(colIDSum[i][j]));
      mapSum[i][j] += *evtMap;
    }
    for(size_t k=0;k&lt;3;k++)
    {
      G4THitsMap&lt;G4double&gt;* evtMap = (G4THitsMap&lt;G4double&gt;*)(HCE-&gt;GetHC(colIDMin[i][k]));
      std::map&lt;G4int,G4double*&gt;::iterator itr = evtMap-&gt;GetMap()-&gt;begin();
      for(; itr != evtMap-&gt;GetMap()-&gt;end(); itr++)
      {
        G4int key = (itr-&gt;first);
        G4double val = *(itr-&gt;second);
        G4double* mapP = mapMin[i][k][key];
        if( mapP &amp;&amp; (val&gt;*mapP) ) continue;
        mapMin[i][k].set(key,val);
      }
    }
  }
}
</programlisting>
</example>
</para>

</sect2>


<!-- ******************* Section (Level#2) ****************** -->
<sect2 id="sect.Hits.G4VPrim">
<title>
Concrete classes of <emphasis>G4VPrimitiveScorer</emphasis>
</title>

<para>
With Geant4 version 8.0, several concrete primitive scorer classes
are provided, all of which are derived from the
<emphasis>G4VPrimitiveScorer</emphasis> abstract base class and which are to be
registered to <emphasis>G4MultiFunctionalDetector</emphasis>. Each of them
contains one <emphasis>G4THitsMap</emphasis> object and scores a simple double
value for each key.
</para>

<!-- ******* Bridgehead ******* -->
<bridgehead renderas='sect4'>
Track length scorers
</bridgehead>

<para>
<variablelist><title></title>
  <varlistentry>
    <term>
      G4PSTrackLength
    </term>
    <listitem><para>
      The track length is defined as the sum of step lengths of the
      particles inside the cell. Bt default, the track weight is not
      taken into account, but could be used as a multiplier of each step
      length if the <emphasis>Weighted()</emphasis> method of this class object is
      invoked.
    </para></listitem>
  </varlistentry>
  <varlistentry>
    <term>
      G4PSPassageTrackLength
    </term>
    <listitem><para>
      The passage track length is the same as the track length in
      <emphasis>G4PSTrackLength</emphasis>, except that only tracks which pass 
      through the volume are taken into account. It means newly-generated or
      stopped tracks inside the cell are excluded from the calculation.
      By default, the track weight is not taken into account, but could
      be used as a multiplier of each step length if the
      <emphasis>Weighted()</emphasis> method of this class object is invoked.
    </para></listitem>
  </varlistentry>
</variablelist>
</para>


<!-- ******* Bridgehead ******* -->
<bridgehead renderas='sect4'>
<emphasis role="bold">Deposited energy scorers</emphasis>
</bridgehead>

<para>
<variablelist><title></title>
  <varlistentry>
    <term>
      G4PSEnergyDeposit
    </term>
    <listitem><para>
      This scorer stores a sum of particles' energy deposits at each
      step in the cell. The particle weight is multiplied at each
      step.
    </para></listitem>
  </varlistentry>
  <varlistentry>
    <term>
      G4PSDoseDeposit
    </term>
    <listitem><para>
      In some cases, dose is a more convenient way to evaluate the
      effect of energy deposit in a cell than simple deposited energy.
      The dose deposit is defined by the sum of energy deposits at each
      step in a cell divided by the mass of the cell. The mass is
      calculated from the density and volume of the cell taken from the
      methods of <emphasis>G4VSolid</emphasis> and 
      <emphasis>G4LogicalVolume</emphasis>. The particle
      weight is multiplied at each step.
    </para></listitem>
  </varlistentry>
</variablelist>
</para>

<!-- ******* Bridgehead ******* -->
<bridgehead renderas='sect4'>
<emphasis role="bold">Current and flux scorers</emphasis>
</bridgehead>

<para>
There are two different definitions of a particle's flow for a
given geometry. One is a current and the other is a flux. In our
scorers, the current is simply defined as the number of particles
(with the particle's weight) at a certain surface or volume, while
the flux takes the particle's injection angle to the geometry into
account. The current and flux are usually defined at a surface, but
volume current and volume flux are also provided.
</para>

<para>
<variablelist><title></title>
  <varlistentry>
    <term>
      G4PSFlatSurfaceCurrent
    </term>
    <listitem><para>
      Flat surface current is a surface based scorer. The present
      implementation is limited to scoring only at the -Z surface of a
      <emphasis>G4Box</emphasis> solid. The quantity is defined by the number 
      of tracks that reach the surface. The user must choose a direction of the
      particle to be scored. The choices are fCurrent_In, fCurrent_Out,
      or fCurrent_InOut, one of which must be entered as the second
      argument of the constructor. Here, fCurrent_In scores incoming
      particles to the cell, while fCurrent_Out scores only outgoing
      particles from the cell. fCurrent_InOut scores both directions. The
      current is multiplied by particle weight and is normalized for a
      unit area.
    </para></listitem>
  </varlistentry>
  <varlistentry>
    <term>
      G4PSSphereSurfaceCurrent
    </term>
    <listitem><para>
      Sphere surface current is a surface based scorer, and similar
      to the G4PSFlatSurfaceCurrent. The only difference is that the
      surface is defined at the <emphasis role="bold">inner surface</emphasis> 
      of a G4Sphere solid.
    </para></listitem>
  </varlistentry>
  <varlistentry>
    <term>
      G4PSPassageCurrent
    </term>
    <listitem><para>
      Passage current is a volume-based scorer. The current is
      defined by the number of tracks that pass through the volume. A
      particle weight is applied at the exit point. A passage current is
      defined for a volume.
    </para></listitem>
  </varlistentry>
  <varlistentry>
    <term>
      G4PSFlatSurfaceFlux
    </term>
    <listitem><para>
      Flat surface flux is a surface based flux scorer. The surface
      flux is defined by the number of tracks that reach the surface. The
      expression of surface flux is given by the sum of W/cos(t)/A, where
      W, t and A represent particle weight, injection angle of particle
      with respect to the surface normal, and area of the surface. The
      user must enter one of the particle directions, fFlux_In,
      fFlux_Out, or fFlux_InOut in the constructor. Here, fFlux_In scores
      incoming particles to the cell, while fFlux_Out scores outgoing
      particles from the cell. fFlux_InOut scores both directions.
    </para></listitem>
  </varlistentry>
  <varlistentry>
    <term>
      G4PSCellFlux
    </term>
    <listitem><para>
      Cell flux is a volume based flux scorer. The cell flux is
      defined by a track length (L) of the particle inside a volume
      divided by the volume (V) of this cell. The track length is
      calculated by a sum of the step lengths in the cell. The expression
      for cell flux is given by the sum of (W*L)/V, where W is a particle
      weight, and is multiplied by the track length at each step.
    </para></listitem>
  </varlistentry>
  <varlistentry>
    <term>
      G4PSPassageCellFlux
    </term>
    <listitem><para>
      Passage cell flux is a volume based scorer similar to
      <emphasis>G4PSCellFlux</emphasis>. The only difference is that tracks 
      which pass through a cell are taken into account. It means generated or
      stopped tracks inside the volume are excluded from the
      calculation.
    </para></listitem>
  </varlistentry>
</variablelist>
</para>

<!-- ******* Bridgehead ******* -->
<bridgehead renderas='sect4'>
<emphasis role="bold">Other scorers</emphasis>
</bridgehead>

<para>
<variablelist><title></title>
  <varlistentry>
    <term>
      G4PSMinKinEAtGeneration
    </term>
    <listitem><para>
      This scorer records the minimum kinetic energy of secondary
      particles at their production point in the volume in an event. This
      primitive scorer does not integrate the quantity, but records the
      minimum quantity.
    </para></listitem>
  </varlistentry>
  <varlistentry>
    <term>
      G4PSNofSecondary
    </term>
    <listitem><para>
      This class scores the number of secondary particles generated
      in the volume. The weight of the secondary track is taken into
      account.
    </para></listitem>
  </varlistentry>
  <varlistentry>
    <term>
      G4PSNofStep
    </term>
    <listitem><para>
      This class scores the number of steps in the cell. A particle
      weight is not applied.
    </para></listitem>
  </varlistentry>
  <varlistentry>
    <term>
      G4PSCellCharge
    </term>
    <listitem><para>
      This class scored the total charge of particles which has stoped 
      in the volume.
    </para></listitem>
  </varlistentry>
</variablelist>
</para>

</sect2>


<!-- ******************* Section (Level#2) ****************** -->
<sect2 id="sect.Hits.G4VSDFil">
<title>
<emphasis>G4VSDFilter</emphasis> and its derived classes
</title>

<para>
<emphasis>G4VSDFilter</emphasis> is an abstract class that represents a track
filter to be associated with <emphasis>G4VSensitiveDetector</emphasis> or
<emphasis>G4VPrimitiveScorer</emphasis>. It defines a virtual method

<informalexample>
<programlisting>
  <emphasis>G4bool Accept(const G4Step*)</emphasis>
</programlisting>
</informalexample>

that should return <emphasis>true</emphasis> if this particular step should be
scored by the <emphasis>G4VSensitiveDetector</emphasis> or
<emphasis>G4VPrimitiveScorer</emphasis>.
</para>

<para>
While the user can implement his/her own filter class, Geant4
version 8.0 provides the following concrete filter classes:

<variablelist><title></title>
  <varlistentry>
    <term>
      G4SDChargedFilter
    </term>
    <listitem><para>
      All charged particles are accepted.
    </para></listitem>
  </varlistentry>
  <varlistentry>
    <term>
      G4SDNeutralFilter
    </term>
    <listitem><para>
      All neutral particles are accepted.
    </para></listitem>
  </varlistentry>
  <varlistentry>
    <term>
      G4SDParticleFilter
    </term>
    <listitem><para>
      Particle species which are registered to this filter object by
      <emphasis>Add("particle_name")</emphasis> are accepted. More than one 
      species can be registered.
    </para></listitem>
  </varlistentry>
  <varlistentry>
    <term>
      G4SDKineticEnergyFilter
    </term>
    <listitem><para>
      A track with kinetic energy greater than or equal to EKmin and
      smaller than EKmin is accepted. EKmin and EKmax should be defined
      as arguments of the constructor. The default values of EKmin and
      EKmax are zero and DBL_MAX.
    </para></listitem>
  </varlistentry>
  <varlistentry>
    <term>
      G4SDParticleWithEnergyFilter
    </term>
    <listitem><para>
      Combination of <emphasis>G4SDParticleFilter</emphasis> and
      <emphasis>G4SDParticleWithEnergyFilter</emphasis>.
    </para></listitem>
  </varlistentry>
</variablelist>
</para>

<para>
The use of the <emphasis>G4SDParticleFilter</emphasis> class is demonstrated
in <xref linkend="programlist_Hits_2" />, where filters which accept gamma,
electron, positron and electron/positron are defined.
</para>


</sect2>


<!-- ******************* Section (Level#2) ****************** -->
<sect2 id="sect.EvtBias.ScorImpRoul.Scor">
<title>
Scoring for Event Biasing
</title>

<para>
Scoring for Event Biasing (described in <xref linkend="sect.EvtBias" />) is a
very specific use case whereby particle weights and fluxes through importance 
cells are required.  The goals of the scoring technique are to:

<itemizedlist spacing="compact">
  <listitem><para>
    appraise particle quantities related to special regions or
    surfaces,
  </para></listitem>
  <listitem><para>
    be applicable to all "cells" (physical volumes or replicas) of
    a given geometry,
  </para></listitem>
  <listitem><para>
    be customizable.
  </para></listitem>
</itemizedlist>
</para>

<para>
Standard scoring must be provided for quantities such as tracks
entering a cell, average weight of entering tracks, energy of
entering tracks, and collisions inside the cell.
</para>

<para>
A number of scorers have been created for this specific appliction:
</para>

<para>
<variablelist><title></title>
  <varlistentry>
    <term>
      G4PSNofCollision
    </term>
    <listitem><para>
    This scorer records the number of collisions that occur within a scored volume/cell.
    There is the additional possibility to take into account the track weight
    whilst scoring the number of collisions, via the following command:
<informalexample>
<programlisting>
  G4PSNofCollision*   scorer1 = new G4PSNofCollision(psName="CollWeight");  
  scorer1->Weighted(true);
</programlisting>
</informalexample>
      </para></listitem>
  </varlistentry>
  <varlistentry>
    <term>
      G4PSPopulation
    </term>
    <listitem><para>
      This scores the number of tracks within in a given cell per event.
   </para></listitem>
  </varlistentry>
  <varlistentry>
    <term>
      G4PSTrackLength
    </term>
    <listitem><para>
      The track lengths within a cell are measured and if, additionally, the result is desired
      to be weighted then the following code has to be implemented:
<informalexample>
<programlisting>
  G4PSTrackLength* scorer5 = new G4PSTrackLength(psName="SLW");  
  scorer5->Weighted(true);
</programlisting>
</informalexample>
  Further if the energy track flux is required then the following should be
  implemented:
<informalexample>
<programlisting>
  G4PSTrackLength* scorer6 = new G4PSTrackLength(psName="SLWE");  
  scorer6->Weighted(true);
  scorer6->MultiplyKineticEnergy(true);
  MFDet->RegisterPrimitive(scorer6);
</programlisting>
</informalexample>

     Alternatively to measure the flux per unit velocity then:
<informalexample>
<programlisting>
  G4PSTrackLength* scorer7 = new G4PSTrackLength(psName="SLW_V");  
  scorer7->Weighted(true);
  scorer7->DivideByVelocity(true);
  MFDet->RegisterPrimitive(scorer7);
</programlisting>
</informalexample>

   Finally to measure the flux energy per unit velocity then:
<informalexample>
<programlisting>
  G4PSTrackLength* scorer8 = new G4PSTrackLength(psName="SLWE_V");  
  scorer8->Weighted(true);
  scorer8->MultiplyKineticEnergy(true);
  scorer8->DivideByVelocity(true);
  MFDet->RegisterPrimitive(scorer8);
</programlisting>
</informalexample>
    </para></listitem>
  </varlistentry>
</variablelist>
</para>


</sect2>

</sect1>
