We considered three ways that the standard data-access program of an experiment might be designed :
In other words, if upper case indicates user supplied routines, and lower case the routines in the standard programs, the three cases schematically look like this :
1 : main initialisation USER_INITIALISATION (*) eventloop event-access USER_ANALYSIS (*) termination USER_TERMINATION (*) 2 : MAIN initialisation USER_INITIALISATION eventloop event-access USER_ANALYSIS (*) termination USER_TERMINATION 3 : MAIN initialisation USER_INITIALISATION EVENTLOOP event-access USER_ANALYSIS termination USER_TERMINATION
The routines marked with (*) have names and parameter-lists defined by the standard soft-ware, but user-supplied contents.
With these possibilities in mind we designed the main program of SGV like this :
* STEER(1,1) : Type of run : * 0 : Normal SGV run * 1 : External data read * 2 : External simulated data read * 3 : External simulated data read, filling * JETSET commons. * 4 : Read-back of previously generaed and * simulated SGV-events (FZ) STEER(1,1) = 0.0 . CALL ZXINI(STEER) ! calls initialisation DO I = 1, INT(STEER(1,7)) CALL ZXLOOP(I,STEER) ! stuff to do at each event ENDDO CALL ZXEND(STEER) ! call run ending END
Hence, in case 3 above, this main program would simply change to
STEER(1,1) = 1 or 2 or 3 call initialisation CALL ZXINI(STEER) ! calls initialisation DO I = 1, INT(STEER(1,7)) call event-access CALL ZXLOOP(I,STEER) ! stuff to do at each event ENDDO call termination CALL ZXEND(STEER) ! call run ending ENDand in case 2 to
STEER(1,1) = 1.0 call initialisation CALL ZXINI(STEER) ! calls initialisation call eventloop call termination CALL ZXEND(STEER) ! call run ending ENDThe event-loop body ZXLOOP looks schematically like this :
. . . (stuff for random number seed input (VMS only), and seed backup. They will not be called if You set SEED_BACKUP to FALSE in the steering-file or if STEER(1,1) <> 0 ) . . . * Cast event in the shape needed to send it * to the analysing code. (In normal SGV running * this also implies generating the event.) CALL ZXCEST(I,STEER) IF ( STEER(1,0) .EQ. 0.0 ) THEN * (ie. event OK ) * send event to the analysing code CALL ZXSEND(I,STEER,LHEAD) * Output event to external file if requested CALL ZXEVOT(I,LHEAD,IOMODEC) . . . (print statistics etc.) . . . ENDIF * Make a copy into common of stuff that would be * needed by the error handler if there is an error * in the next event. CALL UCOPY(STEER,STEERC,4*MAXSTE) EVT = I LHEADC = LHEAD ENDThis routine can therefore be used without changes in all the cases, but in cases 1 and 2, one needs an interface routine, to get the right name and parameter-list :
SUBROUTINE USER_ANALYSIS (or whatever name it should have) +CDE,ZXSIZ. +CDE,ZXSTE. (contains a copy of the steering array in STEERC. it is initially filled by ZXINI, and updated by ZXLOOP) INTEGER I DATA I /0/ * Note that the argument is STEERC, the copy of STEER * kept in /ZXSTE/. This is because You are not directly * calling this routine, so the parameter-list is defined * by some standard calling sequence, and hence You can't * have STEER as an input argument I = I + 1 CALL ZXLOOP(I,STEERC) ENDIn case 1 above, the user needs to write interface routines for initialisation and termination as well, ie something like :
SUBROUTINE USER_INITIALISATION (or whatever name it should have) +CDE,ZXSIZ. REAL STEER(4,0:MAXSTE) CALL Any_initialisation_needed_by_the_program_You_are_using_ that_is_not_done_by_the_SGV_initialisation STEER(1,1) = 1 or 2 or 3 CALL ZXINI(STEER) ENDand
SUBROUTINE USER_TERMINATION (or whatever name it should have) +CDE,ZXSIZ. +CDE,ZXSTE. (contains a copy of the steering array in STEERC) CALL Any_termination_needed_by_the_program_You_are_using_ that_is_not_done_by_the_SGV_ending CALL ZXEND(STEERC) ENDThe event-casting routine ZXCEST looks schematically like this :
. . . * Generate event CALL ZEUGEN(I,STEER,IERR) IF (IERR .NE. 0 ) THEN GOTO 999 ENDIF . . . * Simulate detector CALL ZDETSI(I,STEER,IERR) IF (IERR .NE. 0 ) THEN GOTO 999 ENDIF RETURN 999 STEER(1,0) = 1.0 ! error return ENDExcept for the simple alias routines, the packaging routine to replace ZXCEST is what must be written to allow the SGV data- dispatcher to work correctly. This routine must fill the common block /ZXEVT/ correctly. The best way produce such a routine is to closely follow how the different arrays are filled in ZDETSI, and fill them with the appropriate values obtained from the alternative data-source.