5 * Revision 1.1.1.1 1995/10/24 10:21:45 cernlib
9 #include "geant321/pilot.h"
10 #if defined(CERNLIB_OLD)
11 *CMZ : 3.21/02 29/03/94 15.41.24 by S.Giani
13 SUBROUTINE GTMEDI (X, NUMED)
15 C. ******************************************************************
17 C. * Finds in which volume/medium the point X is, and updates the *
18 C. * common /GCVOLU/ and the structure JGPAR accordingly. *
20 C. * NUMED returns the tracking medium number, or 0 if point is *
21 C. * outside the experimental setup. *
23 C. * Note : For INWVOL = 2, INFROM set to a positive number is *
24 C. * interpreted by GTMEDI as the number IN of the content *
25 C. * just left by the current track within the mother volume *
26 C. * where the point X is assumed to be. *
28 C. * Note : INFROM is set correctly by this routine but it is *
29 C. * used on entrance only in the case GSNEXT has been called *
30 C. * by the user. In other words the value of INFROM received *
31 C. * on entrance is not considered necessarily valid. This *
32 C. * assumption has been made for safety. A wrong value of *
33 C. * INFROM can cause wrong tracking. *
35 C. * Called by : GTRACK *
36 C. * Authors : S.Banerjee, R.Brun, F.Bruyant, A.McPherson *
38 C. ******************************************************************
40 #include "geant321/gcbank.inc"
41 #include "geant321/gcvolu.inc"
42 #include "geant321/gctrak.inc"
43 #if defined(CERNLIB_USRJMP)
44 #include "geant321/gcjump.inc"
53 C. ------------------------------------------------------------------
55 * SECTION I: The /GCVOLU/ table contains the initial guess for a path
56 * in the geometry tree on which X may be found. Look along this
57 * path until X is found inside. This is the starting position.
58 * If this is an ONLY volume with no daughters, we are done;
59 * otherwise reset search record variables, proceed to section II.
61 * *** Check if point is in current volume
67 * *** LSAMVL is a logical variable that indicates whether we are still
68 * *** in the current volume or not. It is used in GTRACK to detect
69 * *** precision problems.
71 C***** Code Expanded From Routine: GTRNSF
73 100 IF (GRMAT(10,NLEVEL) .EQ. 0.) THEN
74 XC(1) = X(1) - GTRAN(1,NLEVEL)
75 XC(2) = X(2) - GTRAN(2,NLEVEL)
76 XC(3) = X(3) - GTRAN(3,NLEVEL)
79 XL1 = X(1) - GTRAN(1,NLEVEL)
80 XL2 = X(2) - GTRAN(2,NLEVEL)
81 XL3 = X(3) - GTRAN(3,NLEVEL)
82 XC(1) = XL1*GRMAT(1,NLEVEL) + XL2*GRMAT(2,NLEVEL) + XL3*
84 XC(2) = XL1*GRMAT(4,NLEVEL) + XL2*GRMAT(5,NLEVEL) + XL3*
86 XC(3) = XL1*GRMAT(7,NLEVEL) + XL2*GRMAT(8,NLEVEL) + XL3*
90 C***** End of Code Expanded From Routine: GTRNSF
92 JVO = LQ(JVOLUM-LVOLUM(NLEVEL))
94 * Note: At entry the variable INGOTO may contain the index of a volume
95 * contained within the current one at NLEVEL. If so, begin by checking
96 * if X lies inside. This improves the search speed over that of GMEDIA.
99 IF ((INGOTO.LE.0).OR.(INGOTO.GT.NIN)) THEN
103 * *** Entrance in content INGOTO predicted by GTNEXT
107 JVOT = LQ(JVOLUM-IVOT)
108 JPAR = LQ(JGPAR-NLEVEL-1)
111 C***** Code Expanded From Routine: GITRAN
113 C. ------------------------------------------------------------------
115 IF (IROTT .EQ. 0) THEN
116 XT(1) = XC(1) - Q(5+JIN)
117 XT(2) = XC(2) - Q(6+JIN)
118 XT(3) = XC(3) - Q(7+JIN)
121 XL1 = XC(1) - Q(5+JIN)
122 XL2 = XC(2) - Q(6+JIN)
123 XL3 = XC(3) - Q(7+JIN)
125 XT(1) = XL1*Q(JR+1) + XL2*Q(JR+2) + XL3*Q(JR+3)
126 XT(2) = XL1*Q(JR+4) + XL2*Q(JR+5) + XL3*Q(JR+6)
127 XT(3) = XL1*Q(JR+7) + XL2*Q(JR+8) + XL3*Q(JR+9)
130 C***** End of Code Expanded From Routine: GITRAN
132 * * Check if point is in content
134 CALL GINME (XT, Q(JVOT+2), Q(JPAR+1), IYES)
137 * If so, prepare information for volume retrieval, and return
142 NAMES(NL1) = IQ(JVOLUM+IVOT)
143 NUMBER(NL1) = Q(JIN+3)
145 LINMX(NL1) = Q(JVO+3)
146 GONLY(NL1) = Q(JIN+8)
147 IF (LQ(LQ(JVOLUM-IVOT)).EQ.0) THEN
148 NLDEV(NL1) = NLDEV(NLEVEL)
152 CALL GTRMUL (GTRAN(1,NLEVEL), GRMAT(1,NLEVEL), Q(JIN+5),
153 + IROTT, GTRAN(1,NL1), GRMAT(1,NL1))
164 * End of INGOTO processing
166 JPAR = LQ(JGPAR-NLEVEL)
167 CALL GINME (XC, Q(JVO+2), Q(JPAR+1), IYES)
170 * ** Point not in current volume, go up the tree
174 IF (NLEVEL.GT.1) THEN
176 JVO = LQ(JVOLUM-LVOLUM(NLEVEL))
179 INFROM=LINDEX(NLEVEL+1)
187 * * Point is outside setup
194 * * Point in current volume but not in INGOTO. We block the
195 * * corresponding volume
197 IF (INGOTO.GT.0) THEN
200 IQ(JIN) = IBSET(IQ(JIN),4)
204 * * Found a volume up the tree which contains our point. We block
205 * * the branch we came up from.
209 IQ(JIN) = IBSET(IQ(JIN),4)
213 * ** Point is in current volume
217 IF (INWVOL.NE.2) INFROM = 0
220 * SECTION II: X is found inside current node at NLEVEL in /GCVOLU/.
221 * Search all contents recursively for any containing X.
222 * Take the first one found, if any, and continue at that
223 * level, incrementing NLEVEL and extending /GCVOLU/ tables.
224 * This is continued until a level is reached where X is not
225 * found in any of the contents, or there are no contents.
226 * Note: Since Section II is re-entered from Section III, a blocking word
227 * is used to mark those contents already checked. Upon exit from Section
228 * II, these blocking words are cleared at NLEVEL, but may remain set in
229 * levels between NLEVEL-1 and NLMIN, if any. They must be cleared at exit.
231 * ** Check contents, if any
233 200 JVO = LQ(JVOLUM-LVOLUM(NLEVEL))
236 * * Case with no contents
241 * * Case with contents defined by division
243 ELSEIF (NIN.LT.0) THEN
244 CALL GMEDIV (JVO, IN, XC, 1)
253 * * Case with contents positioned
256 JCONT = LQ(JVO-NIN-1)+1
259 IF (ISEARC.LT.0) THEN
261 * Prepare access to contents, when ordered by GSORD
263 JSB = LQ(LQ(JVO-NIN-1))
269 CALL GFCOOR (XC, IAX, CX)
271 IDIV = ABS(LOCATF (Q(JSB+3), NSB, CX))
273 IF (IAX.NE.6) GO TO 260
275 ELSEIF (IDIV.EQ.NSB) THEN
276 IF (IAX.NE.6) GO TO 260
279 NCONT = IQ(JSC0+IDIV)
280 JCONT = LQ(JSC0-IDIV)
283 * otherwise, scan contents (possibly a user selection of them)
285 JNEAR = LQ(JVO-NIN-1)
286 IF (ISEARC.GT.0) THEN
287 #if !defined(CERNLIB_USRJMP)
288 CALL GUNEAR (ISEARC, 1, XC, JNEAR)
290 #if defined(CERNLIB_USRJMP)
291 CALL JUMPT4(JUNEAR,ISEARC, 1, XC, JNEAR)
293 ELSEIF (INFROM.GT.0) THEN
294 JNUP = LQ(LQ(JVO-INFROM)-1)
303 * For each selected content in turn, check if point is inside
309 * If the value IQ(JCONT+ICONT)=0 then we are back in the mother.
310 * So jump to 260, the search is finished. Clean-up should be done
311 * only up to ICONT-1, so we set:
317 IF (.NOT.BTEST(IQ(JIN),4)) THEN
318 CALL GMEPOS (JVO, IN, XC, 1)
320 IF (GONLY(NLEVEL).NE.0.) NLMANY = 0
327 IQ(JIN) = IBSET(IQ(JIN),4)
333 260 IF(NCONT.EQ.NIN) THEN
336 IQ(JIN) = IBCLR(IQ(JIN),4)
342 IQ(JIN) = IBCLR(IQ(JIN),4)
346 IQ(JIN) = IBCLR(IQ(JIN),4)
351 IQ(JIN) = IBCLR(IQ(JIN),4)
358 * SECTION III: X is found at current node (NLEVEL in /GCVOLU) but not in
359 * any of its contents, if any. If this is a MANY volume,
360 * save it as a candidate best-choice, and continue the search
361 * by backing up the tree one node and proceed to Section II.
362 * If this is an ONLY volume, proceed to Section IV.
364 * *** Point is in current volume/medium, and not in any content
366 300 IF (GONLY(NLEVEL).EQ.0.) THEN
368 * ** Lowest level is 'NOT ONLY'
370 IF (NLEVEL.GT.NLMANY) THEN
375 * * Go up the tree up to a volume with positioned contents
377 310 INFROM = LINDEX(NLEVEL)
379 JVO = LQ(JVOLUM-LVOLUM(NLEVEL))
381 IF (NIN.LT.0) GO TO 310
383 C***** Code Expanded From Routine: GTRNSF
385 IF (GRMAT(10,NLEVEL) .EQ. 0.) THEN
386 XC(1) = X(1) - GTRAN(1,NLEVEL)
387 XC(2) = X(2) - GTRAN(2,NLEVEL)
388 XC(3) = X(3) - GTRAN(3,NLEVEL)
391 XL1 = X(1) - GTRAN(1,NLEVEL)
392 XL2 = X(2) - GTRAN(2,NLEVEL)
393 XL3 = X(3) - GTRAN(3,NLEVEL)
394 XC(1) = XL1*GRMAT(1,NLEVEL) + XL2*GRMAT(2,NLEVEL) +
395 + XL3* GRMAT(3,NLEVEL)
396 XC(2) = XL1*GRMAT(4,NLEVEL) + XL2*GRMAT(5,NLEVEL) +
397 + XL3* GRMAT(6,NLEVEL)
398 XC(3) = XL1*GRMAT(7,NLEVEL) + XL2*GRMAT(8,NLEVEL) +
399 + XL3* GRMAT(9,NLEVEL)
402 C***** End of Code Expanded From Routine: GTRNSF
406 IQ(JIN) = IBSET(IQ(JIN),4)
407 NLMIN = MIN(NLEVEL,NLMIN)
411 * SECTION IV: This is the end of the search. The current node (NLEVEL
412 * in /GCVOLU/) is the lowest ONLY volume in which X is found.
413 * If X was also found in any of its contents, they are MANY
414 * volumes: the best-choice is the one among them at the greatest
415 * level in the tree, and it is stored. Otherwise the current
416 * volume is the solution. Before exit, all of the blocking
417 * words leftover in the tree must be reset to zero.
418 * Note: A valid structure is assumed, in which no ONLY volumes overlap.
419 * If this rule is violated, or if a daughter is not entirely contained
420 * within the mother volume, the results are unpredictable.
422 DO 419 NL=NLMIN,NLEVEL-1
423 JVO = LQ(JVOLUM-LVOLUM(NL))
427 IQ(JIN) = IBCLR(IQ(JIN),4)
431 IF (NLMANY.GT.0) CALL GFCVOL
432 JVO = LQ(JVOLUM-LVOLUM(NLEVEL))
433 IF(JVIN.NE.0) IQ(JVIN) = IBCLR(IQ(JVIN),4)
436 999 IF(JGSTAT.NE.0) CALL GFSTAT(4)