Problem 172 - Tracking reports hits outside sensitive volume?
Summary: Tracking reports hits outside sensitive volume?
Status: RESOLVED FIXED
Alias: None
Product: Geant4
Classification: Unclassified
Component: tracking (show other problems)
Version: 2.0
Hardware: PC Linux
: P2 normal
Assignee: Makoto.Asai
URL:
Depends on:
Blocks:
 
Reported: 2000-11-09 10:53 CET by christopher.lester
Modified: 2000-11-10 08:51 CET (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this problem.
Description christopher.lester 2000-11-09 10:53:13 CET
Dear G4 Experts,

In brief, G4 seems to be regularly returning incorrect local positions for some
particular hits.  Please read the rest of this for a more detailed explanation.

I have a logical volume, si_log, which represents a wafer of silicon, thickness
320 micron.  I require tracks inside si_log to have a maximum step length of 60
micron (NOTE: 60 micron does not divide 320 exactly ... this will be important
later!).  The surface normal of the wafer is oriented parallel to the z axis.

I have two placements of si_log (one centred at z=0 and one at z=10cm) inside a
mother volume whose shape is the disjoint boolean union of its daughters.  This
mother volume is then placed inside a large experimental hall of air.  Find the
geometry in "DetectorConstruction.cc" in the associated tarfile.

si_log is sensitive, so when particles traverse it I examine their hits.  This
happens in "SCT_DoubleWaferSD.cc", which is also in the tarfile.  Here is how I
obtain local hit postion inside SCT_DoubleWaferSD::processHits:

G4ThreeVector global_pos = step->GetPreStepPoint()->GetPosition();
G4Navigator* navigator = G4TransportationManager::GetTransportationManager()
                ->GetNavigatorForTracking();
G4ThreeVector local_pos = navigator->
                GetGlobalToLocalTransform().TransformPoint(global_pos);

NB: The effects I observe (see later) do not change if I use GetPostStepPoint()
instead of GetPreStepPoint() above.

What happens:
I fire 180 GeV negative pions through the experimental hall from the positive
z-axis toward the negative axis.  The pions first strike the silicon at z=+10cm,
and then the silicon wafer at z=0cm.

There should be 6 hits in the first wafer (at local z positions of 160, 100, 40,
-20, -80, and -140 microns, i.r. 60 micron step starting at (320/2)mum) followed
by 6 hits in the second wafer at the same local positions.  I.e., I expect hits
with local z-positions as follows:

  (160, 100, 40, -20, -80,  -140, 160, 100, 40, -20, -80, -140)

HOWEVER, what I am ACTUALLY given is the following:

  (160, 100, 40, -20, -80, 99860, 160, 100, 40, -20, -80, -140)   !
                           ^^^^^

The explanation of the 99860 seems to be that the local position of the last hit
from the FIRST piece of silicon (this is a "small" hit - only covering the 20
microns in [-160,-140] which is the left over bit after the main 60 micron
steps) is being returned w.r.t. the origin of the SECOND piece of silicon.
(NOTE: 99860mum = 10cm - 140mum)  So to summarise; instead of 6 hits in the
first piece of silicon, and then 6 in the next piece of silicon, I actually get
5 in the first, and then 7 in the second.  The first of the hits in the second
wafer is WAY OUTSIDE the boundary of the wafer, because it actually appened in a
different volume!  The problem goes away completely when I use a step length (eg
64mum) which exactly divides the wafer thickness.   This is not a realisitic fix
for tracks which cover the silicon at a angles other than right angles, though!

Is this a problem with a G4Navigator or a GlobalToLocalTransform? I don't know.

I would appreciate any help that can be offered.  Either the test program is
misusing geant4, or geant4 has a problem. Hopefully you guys will be able to see
whether I am doing anything illegal or not.  In the SCT and pixel group we will
have trouble experimenting with variation of the step lengths if we are unable
to fix this problem.

( The program in the tarfile depends only on HTL and CLHEP )

Many thanks,

Chris
Comment 1 Makoto.Asai 2000-11-10 08:51:59 CET
The correction to your code is at the bottom of this mail but let me start
with explaining what was wrong in your code.

 First of all, you mis-interpreted your results.

> There should be 6 hits in the first wafer (at local z positions of 160, 100,
40,
> -20, -80, and -140 microns, i.r. 60 micron step starting at (320/2)mum)
followed
> by 6 hits in the second wafer at the same local positions.  I.e., I expect
hits
> with local z-positions as follows:
>
>   (160, 100, 40, -20, -80,  -140, 160, 100, 40, -20, -80, -140)
>
> HOWEVER, what I am ACTUALLY given is the following:
>
>   (160, 100, 40, -20, -80, 99860, 160, 100, 40, -20, -80, -140)   !
>                            ^^^^^

Here, you got TWO wrong numbers. The 6th and 12th. These two were measured with
respect to the origin of their mother volume. Eventually your second silicon
wafer is placed at the origin of its mother (i.e. z=0), the 12th number seemed
to be correct.

 As you know, G4Step has two G4StepPoint objects, one is PreStepPoint and the
other is PostStepPoint. In case the step is limited by the volume boundary,
PostStepPoint physically stands on the boundary and logically belongs to the
next volume. Note that G4Navigator has only one transformation matrix. This
matrix
is for the PostStepPoint. Thus, in case PostStepPoint belongs to your silicon
wafer, you got the correct results. But, in case step is limited by the
boundary and PostStepPoint belongs to the mother volume (this is the case for
the 6th and 12th), G4Navigator has a transformation matrix for the mother
volume and thus you got the wrong numbers.

 The problematic part of your code is in SCT_DoubleWaferSD.cc. Followings
are your code fragments.

  // We want to store the local position, not the global one
  G4ThreeVector global_pos = step->GetPreStepPoint()->GetPosition();
  G4Navigator* navigator = G4TransportationManager::GetTransportationManager()
                ->GetNavigatorForTracking();
  G4ThreeVector local_pos = navigator->
                GetGlobalToLocalTransform().TransformPoint(global_pos);

These must be as follows.

  G4StepPoint* preStepPoint = step->GetPreStepPoint();
  G4TouchableHistory* theTouchable
    = (G4TouchableHistory*)(preStepPoint->GetTouchable());
  G4ThreeVector global_pos = preStepPoint->GetPosition();
  G4ThreeVector local_pos
    = theTouchable->GetHistory()->GetTopTransform().TransformPoint(global_pos);

G4TouchableHistory is the class which keeps the geometrical hierarchy of the
point even after G4Navigator has forgotten it. Note that even for getting the
local coordinates of the PostStepPoint position in your silicon, you have to
use
the G4TouchableHistory object of PreStepPoint, because PostStepPoint has its
touchable for the next volume (mother volume).