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
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).