SUBROUTINE DERIVE_MORE_DATA ( COMMAND ) C---------------------------------------------------------------------- C- C- Purpose and Methods : Use the raw monitoring pool information C- to compute all derived rates, percentages... C- C- Inputs : COMMAND The type of information to request C- and raw data in common block in LV1_MPOOL_RAW.INC C- Outputs : common block data in LV1_MPOOL_DERIVED.INC C- Controls: none C- C- Created 25-AUG-1994 Philippe Laurens - MSU L1 Trigger C- Rework structure of TRGMON data collection C- With most of the code coming from old GET_MONITBLOCK.FOR C- Updated 5-MAY-1995 Philippe Laurens - MSU L1 Trigger C- Add computation of per bunch and total luminosity C- Updated 15-MAY-1995 Philippe Laurens - MSU L1 Trigger C- Add double single diffraction correction C- Updated 6-JUN-1995 Philippe Laurens - MSU L1 Trigger C- Fix missing Jet List from Global Calorimeter Display C- by capturing the Trg Mask later copied in IQ(6) C- C---------------------------------------------------------------------- IMPLICIT NONE INCLUDE 'LV1_MPOOL.PARAMS' INCLUDE 'LV1_MPOOL_RAW.INC' INCLUDE 'LV1_MPOOL_DERIVED.INC' INCLUDE 'LV1_MON_SCREEN.INC' INCLUDE 'LV1_MPOOL_FORMATTED.INC' C INCLUDE 'LEVEL1_LOOKUP.PARAMS' INCLUDE 'LEVEL1_CAL_TRIG.PARAMS' INCLUDE 'LEVEL1_FRAMEWORK.PARAMS' INCLUDE 'LEVEL1_TRIGGER_DATA_BLOCK.INC' INCLUDE 'D0$INC:ZEBCOM.INC' C INCLUDE 'CROSS_SECTIONS.PARAMS' C INTEGER COMMAND C EXTERNAL TIME_SINCE_INIT INTEGER TIME_SINCE_INIT REAL EXTRACT_GLOB_E_SUM EXTERNAL EXTRACT_GLOB_E_SUM LOGICAL STATE_AOTERM EXTERNAL STATE_AOTERM INTEGER NUMBIT EXTERNAL NUMBIT REAL DERIVED_LUMINOSITY, DERIVED_LUM_SD_COR EXTERNAL DERIVED_LUMINOSITY, DERIVED_LUM_SD_COR C INTEGER TEMP INTEGER SPTRG_NUM INTEGER GSECT_NUM INTEGER AO_TERM_NUM INTEGER REFSET_NUM INTEGER ENTRY_NUM INTEGER BUNCH_NUM INTEGER SCALER_NUM INTEGER L15_TERM_NUM INTEGER SCALER_COUNT(2) INTEGER ADDRESS C INTEGER DB_GLOBAL_LIVEX_SCALER(2) INTEGER DB_LIVEX_PER_BUNCH(2, 6) INTEGER DB_LIVEX_FASTZ_GOOD_PER_BUNCH(2, 6) INTEGER DB_LIVEX_L0SINGLE_PER_BUNCH(2, 6) INTEGER DB_SLOW_L0_PER_BUNCH(2, 6) C INTEGER EM_ET_LIST, TOT_ET_LIST, LT_LIST PARAMETER ( EM_ET_LIST = 0, TOT_ET_LIST = 1, LT_LIST = 2 ) INTEGER EM_JET_LIST_LENGTH INTEGER TOT_JET_LIST_LENGTH INTEGER LG_TILE_LIST_LENGTH C REAL BUNCH_CROSSING_FREQ REAL CROSSING_PER_BUNCH C PARAMETER H8000 = 32768 PARAMETER H7FFF = 32767 C----------------------------------------------------------------------- C C Define pair of functions for converting from 32-bit to 40-bit integers C with 40-bit integers split in Units (low 30 bit) and Gigas (high 10 bit) C C and another pair of functions for converting from 40-bit integers split C in Low 3 bytes (low 24 bit) and hig 2 bytes (high 16 bit) to 40-bit C integers split in Units and Gigas (as defined above) C INTEGER I32TO40_G, I32TO40_U INTEGER I24TO40_G, I24TO40_U C INTEGER I32, I40_LOW24, I40_HIGH16 C I32TO40_G( I32 ) = IAND( ISHFT( I32, -30), 3 ) I32TO40_U( I32 ) = IAND( I32, 2**30-1 ) I24TO40_G( I40_HIGH16, I40_LOW24) = IAND( ISHFT( I40_HIGH16, -6 ), & 1023 ) I24TO40_U( I40_HIGH16, I40_LOW24) = IAND( IOR( I40_LOW24, & ISHFT( I40_HIGH16, & 24 )), & 2**30-1) C---------------------------------------------------------------------- C C Grab Current Time C ----------------- C CURRENT_TIME = ' ' CALL DATE(CURRENT_TIME(1:9)) CALL TIME(CURRENT_TIME(11:18)) C C Unpack general information from the GLOBAL portion of MPOOL Message C ------------------------------------------------------------------- C INIT_TIME = TIME_SINCE_INIT() C FRAMEWORK_RUNNING = & IBITS(FRAMEWORK_STATUS, FS_PAUSED_LOC, FS_PAUSED_LEN) .EQ. 0 INFO_FRESH = & IBITS(FRAMEWORK_STATUS, FS_STALE_LOC, FS_STALE_LEN) .EQ. 0 C LV1_TRIGGER_RATE = FLOAT(DELTA_GLOBAL_FIRED) * COUNT_TO_HZ LV0_TRIGGER_RATE = FLOAT(DELTA_LEVEL_0) * COUNT_TO_HZ C C The total number of events transferred C CALL NUM_EVENTS_TRANSFERRED( TRANSFERRED, GTRANSFERRED) C GLOB_TRANSFER_RATE = FLOAT(DELTA_EVENT_TRANSFER) * COUNT_TO_HZ C C Unpack Level 1.5 information from the GLOBAL portion of MPOOL Message C --------------------------------------------------------------------- C IF ( (COMMAND .EQ. COMMAND_GLOBAL_ALLOC) & .OR. (COMMAND .EQ. COMMAND_GLOBAL_L15) & .OR. (COMMAND .EQ. COMMAND_SPECIFIC_TRIGGER) & .OR. (COMMAND .EQ. COMMAND_SPECTRIG_L15) & .OR. (COMMAND .EQ. COMMAND_GEO_SECT) & .OR. (COMMAND .EQ. COMMAND_PER_BUNCH) & .OR. (COMMAND .EQ. COMMAND_LUMINOSITY) & .OR. (COMMAND .EQ. COMMAND_FOREIGN_SCALERS) ) THEN C C Is L15 running? C CALL CHECK_L15_OPERATIONAL(GLOB_L15_DATA.L15_RUNNING) C C Did this event use L15? C Check the 3rd [31,0] bit of Item 529. C IF ((GLOB_L15_DATA.L15_RUNNING .EQV. .TRUE.) & .AND. (BTEST(DATABLOCK(L1_5_RESERVED), 3) .EQV. .TRUE.)) THEN GLOB_L15_DATA.EVENT_USED_L15 = .TRUE. ELSE GLOB_L15_DATA.EVENT_USED_L15 = .FALSE. ENDIF C C DELTA_L15_ACCEPT and DELTA_L15_REJECT must be forced to 0 if C DELTA_L15_CYCLE is 0. C IF (DELTA_L15_CYCLE .EQ. 0) THEN DELTA_L15_ACCEPT = 0 DELTA_L15_REJECT = 0 ENDIF C GLOB_L15_DATA.GLOB_L15_INPUT_HZ & = FLOAT(DELTA_L15_CYCLE) * COUNT_TO_HZ C IF (DELTA_GLOBAL_FIRED .NE. 0) THEN GLOB_L15_DATA.GLOB_L15_INPUT_PCT & = FLOAT(DELTA_L15_CYCLE) / FLOAT(DELTA_GLOBAL_FIRED) * 100. ELSE GLOB_L15_DATA.GLOB_L15_INPUT_PCT = 0. ENDIF C GLOB_L15_DATA.GLOB_L15_REJECT_HZ & = FLOAT(DELTA_L15_REJECT) * COUNT_TO_HZ C IF (DELTA_L15_CYCLE .NE. 0) THEN GLOB_L15_DATA.GLOB_L15_REJECT_PCT & = FLOAT(DELTA_L15_REJECT) / FLOAT(DELTA_L15_CYCLE) * 100. ELSE GLOB_L15_DATA.GLOB_L15_REJECT_PCT = 0. ENDIF C IF (DELTA_BEAM_CROSSING .NE. 0) THEN GLOB_L15_DATA.GLOB_DEAD_BEAM_X_PCT & = FLOAT(DELTA_L15_DEAD_CROSSING) & / FLOAT(DELTA_BEAM_CROSSING) & * 100. ELSE GLOB_L15_DATA.GLOB_DEAD_BEAM_X_PCT = 0. ENDIF C GLOB_L15_DATA.GLOB_PURE_L1_FIRE_HZ & = FLOAT(DELTA_GLOBAL_FIRED - DELTA_L15_CYCLE) * COUNT_TO_HZ C IF (DELTA_GLOBAL_FIRED .NE. 0) THEN GLOB_L15_DATA.GLOB_PURE_L1_FIRE_PCT = & FLOAT(DELTA_GLOBAL_FIRED - DELTA_L15_CYCLE) & / FLOAT(DELTA_GLOBAL_FIRED) * 100. ELSE GLOB_L15_DATA.GLOB_PURE_L1_FIRE_PCT = 0. ENDIF C GLOB_L15_DATA.GLOB_POTEN_L15_HZ & = FLOAT(DELTA_L15_POTENTIAL) * COUNT_TO_HZ C GLOB_L15_DATA.GLOB_L15_SKIP_HZ & = FLOAT(DELTA_L15_SKIP) * COUNT_TO_HZ C IF (DELTA_L15_POTENTIAL .NE. 0) THEN GLOB_L15_DATA.GLOB_L15_SKIP_PCT & = FLOAT(DELTA_L15_SKIP) / FLOAT(DELTA_L15_POTENTIAL) * 100. ELSE GLOB_L15_DATA.GLOB_L15_SKIP_PCT = 0. ENDIF C GLOB_L15_DATA.GLOB_L15_CONFIRM_HZ & = FLOAT(DELTA_L15_ACCEPT) * COUNT_TO_HZ C IF (DELTA_L15_CYCLE .NE. 0) THEN GLOB_L15_DATA.GLOB_L15_CONFIRM_PCT & = FLOAT(DELTA_L15_ACCEPT) / FLOAT(DELTA_L15_CYCLE) * 100. ELSE GLOB_L15_DATA.GLOB_L15_CONFIRM_PCT = 0. ENDIF C IF (DELTA_L15_CYCLE .NE. 0) THEN GLOB_L15_DATA.GLOB_L15_TIMEOUT_PCT & = FLOAT(DELTA_L15_TIMEOUT) / FLOAT(DELTA_L15_CYCLE) * 100. ELSE GLOB_L15_DATA.GLOB_L15_TIMEOUT_PCT = 0. ENDIF C C Get the luminosity per bunch, and the total C ---------- TOTAL_LUM_RAW_SLOW_Z = 0. TOTAL_LUM_DELIV_SLOW_Z = 0. C CROSSING_PER_BUNCH = FLOAT( DELTA_BEAM_CROSSING ) / 6. BUNCH_CROSSING_FREQ = 1. / BEAM_CROSS_PERIOD / 6. C DO BUNCH_NUM = PER_BUNCH_MIN, PER_BUNCH_MAX C C Slow Z lumnosity per bunch C BUNCH_LUM_RAW_SLOW_Z( BUNCH_NUM ) = & DERIVED_LUMINOSITY( BUNCH_CROSSING_FREQ, & CROSSING_PER_BUNCH, & FLOAT(SLOW_L0_PER_BUNCH(BUNCH_NUM)), & CROSS_SECTION_L0_SLOW_Z_GOOD ) C C Double single diffraction corrective term C BUNCH_LUM_DELIV_SLOW_Z( BUNCH_NUM ) = & BUNCH_LUM_RAW_SLOW_Z( BUNCH_NUM ) & + DERIVED_LUM_SD_COR( BUNCH_CROSSING_FREQ, & BUNCH_LUM_DELIV_SLOW_Z(BUNCH_NUM), & CROSS_SECTION_L0_SLOW_Z_GOOD, & CROSS_SECTION_L0_SLOW_SD_CORR ) C C Increment Total Luminosity, using correction C TOTAL_LUM_RAW_SLOW_Z = TOTAL_LUM_RAW_SLOW_Z & + BUNCH_LUM_RAW_SLOW_Z( BUNCH_NUM ) C TOTAL_LUM_DELIV_SLOW_Z = TOTAL_LUM_DELIV_SLOW_Z & + BUNCH_LUM_DELIV_SLOW_Z( BUNCH_NUM ) C END DO C ENDIF C C Unpack ANDOR Terms for those displays which need them C ----------------------------------------------------- C IF ( (COMMAND .EQ. COMMAND_SPECIFIC_TRIGGER) & .OR. (COMMAND .EQ. COMMAND_GLOBAL_MONIT) ! for large tile terms & .OR. (COMMAND .EQ. COMMAND_ANDOR) ) THEN DO AO_TERM_NUM = ANDOR_NUM_MIN, ANDOR_NUM_MAX ANDOR_STATE(AO_TERM_NUM) = STATE_AOTERM(AO_TERM_NUM) END DO ENDIF C C Find the Trigger mask for those displays which need it. C ------------------------------------------------------- C IF ( (COMMAND .EQ. COMMAND_GLOBAL_ALLOC) & .OR. (COMMAND .EQ. COMMAND_GLOBAL_L15) & .OR. (COMMAND .EQ. COMMAND_SPECIFIC_TRIGGER) & .OR. (COMMAND .EQ. COMMAND_SPECTRIG_L15) & .OR. (COMMAND .EQ. COMMAND_GLOBAL_MONIT) ! for jet list & .OR. (COMMAND .EQ. COMMAND_JET_LIST) & .OR. (COMMAND .EQ. COMMAND_PRTRGR_DBLOCK) & ) THEN C DO SPTRG_NUM = TRG_NUM_MIN, TRG_NUM_MAX TRIGGER_DATA(SPTRG_NUM).TRIGGER_FIRED = & BTEST(DATABLOCK(SP_TRG_FIRED + SPTRG_NUM / 8), & MOD(SPTRG_NUM, 8)) C IF ((GLOB_L15_DATA.EVENT_USED_L15 .EQV. .TRUE.) & .AND. (SPTRG_NUM .LT. 16)) THEN TRIGGER_DATA(SPTRG_NUM).TRIGGER_FIRED & = BTEST(DATABLOCK(L15_STATUS+SPTRG_NUM/8), & MOD(SPTRG_NUM, 8) ) ENDIF C END DO ENDIF C C The following block of code interprets information in the common blocks C MONIT_POOL_SPTRG_GEOSECT [specific trigger and geographic sections] and C MONIT_POOL_DBLOCK [trigger data block]. C ----------------------------------------------------------------------- C IF ( (COMMAND .EQ. COMMAND_GLOBAL_ALLOC) & .OR. (COMMAND .EQ. COMMAND_GLOBAL_L15) & .OR. (COMMAND .EQ. COMMAND_SPECIFIC_TRIGGER) & .OR. (COMMAND .EQ. COMMAND_SPECTRIG_L15) & .OR. (COMMAND .EQ. COMMAND_DIAGNOST) & .OR. (COMMAND .EQ. COMMAND_GEO_SECT) ) THEN C DO SPTRG_NUM = TRG_NUM_MIN, TRG_NUM_MAX C C Compute Specific trigger rates C SPTRG_FIRE_RATE(SPTRG_NUM) = & SPTRG_INCR(COUNT_ST_TRGFIRED, SPTRG_NUM) * COUNT_TO_HZ SPTRG_EXPOS_RATE(SPTRG_NUM) = & SPTRG_INCR(COUNT_ST_TRG_EXPOS, SPTRG_NUM) * COUNT_TO_HZ C C Determine if this is a L15 Specific Trigger C IF (IBITS(SPTRGPROG(PG_TRG_ALLOC, SPTRG_NUM), & PG_TRG_IS_L15_BYTE, 8) & .EQ. 1) THEN TRIGGER_DATA(SPTRG_NUM).IS_L15 = .TRUE. ELSE TRIGGER_DATA(SPTRG_NUM).IS_L15 = .FALSE. ENDIF C CALL EXTRACT_TERMS(SPTRG_NUM, PG_ANDOR, NUM_ANDOR, & TRIGGER_DATA(SPTRG_NUM).ANDOR_ACTIVE, & TRIGGER_DATA(SPTRG_NUM).NUM_ANDOR_ACTIVE, & .FALSE., .FALSE. ) C CALL EXTRACT_TERMS(SPTRG_NUM, PG_ANDOR, NUM_ANDOR, & TRIGGER_DATA(SPTRG_NUM).ANDOR_POLARIZATION, & TRIGGER_DATA(SPTRG_NUM).NUM_POLARIZED, & .TRUE., .TRUE. ) C C Find if trigger #SPTRG_NUM is allocated. C TEMP = 0 CALL MVBITS(SPTRGPROG(PG_TRG_ALLOC, SPTRG_NUM), & PG_TRG_ALLOC_LSB, PG_TRG_ALLOC_MSB - PG_TRG_ALLOC_LSB + 1, & TEMP, 0) IF (TEMP .NE. 0) THEN TRIGGER_DATA(SPTRG_NUM).ALLOCATED = .TRUE. ELSE TRIGGER_DATA(SPTRG_NUM).ALLOCATED = .FALSE. ENDIF C C C The total number of events transferred due to each Specific Trigger C CALL NUM_SPEC_TRIG_FIRED(SPTRG_NUM, & TRIGGER_DATA(SPTRG_NUM).TRIGGER_FIRE_COUNT, & TRIGGER_DATA(SPTRG_NUM).TRIGGER_FIRE_COUNT_GIGAS) C TRIGGER_DATA(SPTRG_NUM).EVENT_TRANS_COUNT = & TRIGGER_DATA(SPTRG_NUM).TRIGGER_FIRE_COUNT TRIGGER_DATA(SPTRG_NUM).EVENT_TRANS_COUNT_GIGAS = & TRIGGER_DATA(SPTRG_NUM).TRIGGER_FIRE_COUNT_GIGAS C IF (TRIGGER_DATA(SPTRG_NUM).IS_L15 .EQV. .TRUE.) THEN C C Correct number of events transferred C CALL MONSUB40( & TRIGGER_DATA(SPTRG_NUM).EVENT_TRANS_COUNT_GIGAS, & TRIGGER_DATA(SPTRG_NUM).EVENT_TRANS_COUNT, & I32TO40_G(SPTRG_COUNT(COUNT_ST_L15_REJECT, SPTRG_NUM)), & I32TO40_U(SPTRG_COUNT(COUNT_ST_L15_REJECT, SPTRG_NUM)), & TRIGGER_DATA(SPTRG_NUM).EVENT_TRANS_COUNT_GIGAS, & TRIGGER_DATA(SPTRG_NUM).EVENT_TRANS_COUNT ) C ENDIF C IF ((DELTA_VETO_CROSSING .NE. 0) .AND. & (BEAM_CROSS_PERIOD .NE. 0)) THEN TRIGGER_DATA(SPTRG_NUM).ANDOR_FIRE_RATE = & FLOAT(SPTRG_INCR(COUNT_ST_ANDORFIRED, SPTRG_NUM)) & / (FLOAT(DELTA_VETO_CROSSING) * BEAM_CROSS_PERIOD) ELSE TRIGGER_DATA(SPTRG_NUM).ANDOR_FIRE_RATE = 0. ENDIF C C Find the Trigger's Global Exposition count and percentage. C CALL L1_EXTRACT_5BYTE_SCALER(L1_CRATE_HEADER, & SP_TRG_SCALERS + SCALER_L & + 2 * SCALER_L * SPTRG_NUM, & TRIGGER_DATA(SPTRG_NUM).TRIGGER_EXPOS_COUNT, & TRIGGER_DATA(SPTRG_NUM).TRIGGER_EXPOS_COUNT_GIGAS ) C IF (DELTA_BEAM_CROSSING .NE. 0) THEN TRIGGER_DATA(SPTRG_NUM).GLOB_EXPOS_PERCENT = & SPTRG_INCR(COUNT_ST_TRG_EXPOS, SPTRG_NUM) & / FLOAT(DELTA_BEAM_CROSSING) * 100. ELSE TRIGGER_DATA(SPTRG_NUM).GLOB_EXPOS_PERCENT = 0. ENDIF C TRIGGER_DATA(SPTRG_NUM).GLOB_EXPOS_HZ = & SPTRG_INCR(COUNT_ST_TRG_EXPOS, SPTRG_NUM) * COUNT_TO_HZ C C Find the Trigger's Global Exposition and Level 0 count and rate C CALL MONSUB40( & TRIGGER_DATA(SPTRG_NUM).TRIGGER_EXPOS_COUNT_GIGAS, & TRIGGER_DATA(SPTRG_NUM).TRIGGER_EXPOS_COUNT, & I32TO40_G(SPTRG_COUNT(COUNT_ST_EXPOS_NOT_L0, SPTRG_NUM)), & I32TO40_U(SPTRG_COUNT(COUNT_ST_EXPOS_NOT_L0, SPTRG_NUM)), & TRIGGER_DATA(SPTRG_NUM).TRIGGER_EXPOS_AND_L0_GIGAS, & TRIGGER_DATA(SPTRG_NUM).TRIGGER_EXPOS_AND_L0) C TRIGGER_DATA(SPTRG_NUM).TRIGGER_EXPOS_AND_L0_HZ = & (SPTRG_INCR(COUNT_ST_TRG_EXPOS, SPTRG_NUM) & - SPTRG_INCR(COUNT_ST_EXPOS_NOT_L0, SPTRG_NUM) & ) * COUNT_TO_HZ C TRIGGER_DATA(SPTRG_NUM).PRSCL_RATIO = & SPTRGPROG(PG_PRSCL_RATIO, SPTRG_NUM) C TRIGGER_DATA(SPTRG_NUM).READ_TIME = & SPTRGPROG(PG_READ_TIME, SPTRG_NUM) C CALL EXTRACT_TERMS( SPTRG_NUM, PG_ST_DIG, NUM_TOT_GEO, & TRIGGER_DATA(SPTRG_NUM).ST_DIG, & TRIGGER_DATA(SPTRG_NUM).NUM_ST_DIG, & .FALSE., .TRUE.) C CALL EXTRACT_TERMS( SPTRG_NUM, PG_WATCHBUSY, NUM_TOT_GEO, & TRIGGER_DATA(SPTRG_NUM).WATCHBUSY, & TRIGGER_DATA(SPTRG_NUM).NUM_WATCHBUSY, & .TRUE., .TRUE.) C TRIGGER_DATA(SPTRG_NUM).PRSCLV_PROG = & BTEST(SPTRGPROG(PG_FSTD_VETO, SPTRG_NUM), PG_PRSCLV_BIT) IF (DELTA_VETO_CROSSING .NE. 0) THEN TRIGGER_DATA(SPTRG_NUM).PRSCLV_PERCENT = & SPTRG_INCR(COUNT_ST_PRSCLV, SPTRG_NUM) & / FLOAT(DELTA_VETO_CROSSING) * 100. ELSE TRIGGER_DATA(SPTRG_NUM).PRSCLV_PERCENT = 0. ENDIF C TRIGGER_DATA(SPTRG_NUM).LEV15V_PROG = & BTEST(SPTRGPROG(PG_FSTD_VETO, SPTRG_NUM), PG_LEV15V_BIT) IF (DELTA_VETO_CROSSING .NE. 0) THEN TRIGGER_DATA(SPTRG_NUM).LEV15V_PERCENT = & SPTRG_INCR(COUNT_ST_LEV15V, SPTRG_NUM) / & FLOAT(DELTA_VETO_CROSSING) * 100. ELSE TRIGGER_DATA(SPTRG_NUM).LEV15V_PERCENT = 0. ENDIF C TRIGGER_DATA(SPTRG_NUM).LEV20V_PROG = & BTEST(SPTRGPROG(PG_FSTD_VETO, SPTRG_NUM), PG_LEV20V_BIT) TRIGGER_DATA(SPTRG_NUM).LEV20V_STATE = & BTEST(DATABLOCK(SCND_LVL_DSBL + (SPTRG_NUM)/8), & MOD(SPTRG_NUM, 8)) IF (DELTA_VETO_CROSSING .NE. 0) THEN TRIGGER_DATA(SPTRG_NUM).LEV20V_PERCENT = & SPTRG_INCR(COUNT_ST_LEV20V, SPTRG_NUM) / & FLOAT(DELTA_VETO_CROSSING) * 100. ELSE TRIGGER_DATA(SPTRG_NUM).LEV20V_PERCENT = 0. ENDIF C TRIGGER_DATA(SPTRG_NUM).GLOBV_PROG = & BTEST(SPTRGPROG(PG_FSTD_VETO, SPTRG_NUM), PG_GLOBV_BIT) IF (DELTA_VETO_CROSSING .NE. 0) THEN TRIGGER_DATA(SPTRG_NUM).GLOBV_PERCENT = & SPTRG_INCR(COUNT_ST_GLOBV, SPTRG_NUM) / & FLOAT(DELTA_VETO_CROSSING) * 100. ELSE TRIGGER_DATA(SPTRG_NUM).GLOBV_PERCENT = 0. ENDIF C TRIGGER_DATA(SPTRG_NUM).FEV_PROG = & BTEST(SPTRGPROG(PG_FSTD_VETO, SPTRG_NUM), PG_FEV_BIT) TRIGGER_DATA(SPTRG_NUM).FEV_STATE = & BTEST(DATABLOCK(FRONT_END_DSBL + (SPTRG_NUM)/8), & MOD(SPTRG_NUM, 8)) IF (DELTA_VETO_CROSSING .NE. 0) THEN TRIGGER_DATA(SPTRG_NUM).FEV_PERCENT = & SPTRG_INCR(COUNT_ST_FEV, SPTRG_NUM) / & FLOAT(DELTA_VETO_CROSSING) * 100. ELSE TRIGGER_DATA(SPTRG_NUM).FEV_PERCENT = 0. ENDIF C TRIGGER_DATA(SPTRG_NUM).AUX2V_PROG = & BTEST(SPTRGPROG(PG_FSTD_VETO, SPTRG_NUM), PG_AUX2V_BIT) IF (DELTA_VETO_CROSSING .NE. 0) THEN TRIGGER_DATA(SPTRG_NUM).AUX2V_PERCENT = & SPTRG_INCR(COUNT_ST_AUX2V, SPTRG_NUM) / & FLOAT(DELTA_VETO_CROSSING) * 100. ELSE TRIGGER_DATA(SPTRG_NUM).AUX2V_PERCENT = 0. ENDIF C TRIGGER_DATA(SPTRG_NUM).AUTOV_PROG = & BTEST(SPTRGPROG(PG_FSTD_VETO, SPTRG_NUM), PG_AUTOV_BIT) IF (DELTA_VETO_CROSSING .NE. 0) THEN TRIGGER_DATA(SPTRG_NUM).AUTOV_PERCENT = & SPTRG_INCR(COUNT_ST_AUTOV, SPTRG_NUM) / & FLOAT(DELTA_VETO_CROSSING) * 100. ELSE TRIGGER_DATA(SPTRG_NUM).AUTOV_PERCENT = 0. ENDIF C C L1.5 Reject C TRIGGER_DATA(SPTRG_NUM).L15_REJECT_HZ & = SPTRG_INCR(COUNT_ST_L15_REJECT, SPTRG_NUM) & * COUNT_SBSC_TO_HZ IF (SPTRG_INCR(COUNT_ST_L15_CYCLE, SPTRG_NUM) & .NE. 0) THEN TRIGGER_DATA(SPTRG_NUM).ST_L15_REJECT_PCT & = FLOAT(SPTRG_INCR(COUNT_ST_L15_REJECT, SPTRG_NUM)) & / FLOAT(SPTRG_INCR(COUNT_ST_L15_CYCLE, & SPTRG_NUM)) & * 100. ELSE TRIGGER_DATA(SPTRG_NUM).ST_L15_REJECT_PCT = 0. ENDIF C C Level 1.5 input rate C TRIGGER_DATA(SPTRG_NUM).L15_INPUT_HZ = & SPTRG_INCR(COUNT_ST_L15_CYCLE, SPTRG_NUM) & * COUNT_SBSC_TO_HZ C IF (SPTRG_INCR(COUNT_ST_TRGFIRED, SPTRG_NUM) .NE. 0) THEN TRIGGER_DATA(SPTRG_NUM).L15_INPUT_PCT & = FLOAT(SPTRG_INCR(COUNT_ST_L15_CYCLE, SPTRG_NUM)) & / FLOAT(SPTRG_INCR(COUNT_ST_TRGFIRED, SPTRG_NUM)) * 100. ELSE TRIGGER_DATA(SPTRG_NUM).L15_INPUT_PCT = 0. ENDIF C C Level 1.5 Skip C C Potential L15 for ST is now defined as the count of trigger firings, C since any time a Level 1.5 trigger fires the event is a potential C L15 event. C DELTA_ST_L15_POTENTIAL C & = SPTRG_INCR(COUNT_ST_L15_SKIP, SPTRG_NUM) C & + SPTRG_INCR(COUNT_ST_L15_CYCLE, SPTRG_NUM) C TRIGGER_DATA(SPTRG_NUM).L15_SKIP_HZ & = FLOAT(SPTRG_INCR(COUNT_ST_L15_SKIP, SPTRG_NUM)) & * COUNT_SBSC_TO_HZ IF (SPTRG_INCR(COUNT_ST_TRGFIRED, SPTRG_NUM) .NE. 0) THEN TRIGGER_DATA(SPTRG_NUM).L15_SKIP_PCT & = FLOAT(SPTRG_INCR(COUNT_ST_L15_SKIP, SPTRG_NUM)) & / FLOAT(SPTRG_INCR(COUNT_ST_TRGFIRED, SPTRG_NUM)) * 100. ELSE TRIGGER_DATA(SPTRG_NUM).L15_SKIP_PCT = 0. ENDIF C C Level 1.5 confirm C TRIGGER_DATA(SPTRG_NUM).L15_CONFIRM_HZ & = FLOAT(SPTRG_INCR(COUNT_ST_L15_CONFIRM, SPTRG_NUM)) & * COUNT_SBSC_TO_HZ IF (SPTRG_INCR(COUNT_ST_L15_CYCLE, SPTRG_NUM) .NE. 0) THEN TRIGGER_DATA(SPTRG_NUM).L15_CONFIRM_PCT & = FLOAT(SPTRG_INCR(COUNT_ST_L15_CONFIRM, & SPTRG_NUM)) & / FLOAT(SPTRG_INCR(COUNT_ST_L15_CYCLE, SPTRG_NUM)) & * 100. ELSE C C guard against inconsistent data where C COUNT_ST_L15_CONFIRM would not be zero C while COUNT_ST_L15_CYCLE is zero C - > Use big number that will display as stars *** C IF (SPTRG_INCR(COUNT_ST_L15_CONFIRM, & SPTRG_NUM) .NE. 0) THEN TRIGGER_DATA(SPTRG_NUM).L15_CONFIRM_PCT = 300000. ELSE TRIGGER_DATA(SPTRG_NUM).L15_CONFIRM_PCT = 0. ENDIF ENDIF C C Level 1.5 Dead Beam Crossing % C IF (DELTA_VETO_CROSSING .NE. 0) THEN TRIGGER_DATA(SPTRG_NUM).L15_DEADX_PCT & = FLOAT(SPTRG_INCR(COUNT_ST_DEADX, SPTRG_NUM)) & / FLOAT(DELTA_VETO_CROSSING) * 100. ELSE TRIGGER_DATA(SPTRG_NUM).L15_DEADX_PCT = 0 ENDIF C C Level 1.5 Timeout C IF (SPTRG_INCR(COUNT_ST_L15_CYCLE, SPTRG_NUM) & .NE. 0) THEN TRIGGER_DATA(SPTRG_NUM).L15_TIMEOUT_PCT & = FLOAT(SPTRG_INCR(COUNT_ST_L15_TIMEOUT, & SPTRG_NUM)) & / FLOAT(SPTRG_INCR(COUNT_ST_L15_CYCLE, SPTRG_NUM)) & * 100. ELSE TRIGGER_DATA(SPTRG_NUM).L15_TIMEOUT_PCT = 0. ENDIF C TRIGGER_DATA(SPTRG_NUM).L15_TIMEOUT_CNT & = SPTRG_COUNT(COUNT_ST_L15_TIMEOUT, SPTRG_NUM) C C Number of Level 1.5 Terms required C TRIGGER_DATA(SPTRG_NUM).NUM_L15_TERM & = NUMBIT(SPTRGPROG(PG_L15_TERM_REQ, SPTRG_NUM)) C C Which Level 1.5 Terms required C DO L15_TERM_NUM = L15_TERM_NUM_MIN, L15_TERM_NUM_MAX TRIGGER_DATA(SPTRG_NUM).L15_TERM_REQUIRED(L15_TERM_NUM) & = BTEST(SPTRGPROG(PG_L15_TERM_REQ, SPTRG_NUM), & L15_TERM_NUM) END DO C C Record information for Ntuple log file C NTUP_FIRING_RATES(SPTRG_NUM) = SPTRG_FIRE_RATE(SPTRG_NUM) NTUP_EXPOS_RATES(SPTRG_NUM) & = TRIGGER_DATA(SPTRG_NUM).GLOB_EXPOS_HZ NTUP_ANDOR_RATES(SPTRG_NUM) & = TRIGGER_DATA(SPTRG_NUM).ANDOR_FIRE_RATE C C End of looping over each specific trigger number C END DO C C A few other items needed C C Unpack the Level 1.5 Term info from Data Block. C DO L15_TERM_NUM = L15_TERM_NUM_MIN, L15_TERM_NUM_MAX GLOB_L15_DATA.L15_TERM_DONE(L15_TERM_NUM) & = BTEST( & DATABLOCK(L15_STATUS + 12 + L15_TERM_NUM/BYTE_LENGTH), & MOD(L15_TERM_NUM, BYTE_LENGTH) ) C GLOB_L15_DATA.L15_TERM_STATE(L15_TERM_NUM) & = BTEST( & DATABLOCK(L15_STATUS + 8 + L15_TERM_NUM/BYTE_LENGTH), & MOD(L15_TERM_NUM, BYTE_LENGTH) ) END DO C ENDIF C C Unpack geographic section MPOOL data C ------------------------------------ C IF ( (COMMAND .EQ. COMMAND_GEO_SECT) & .OR. (COMMAND .EQ. COMMAND_SPECIFIC_TRIGGER) & .OR. (COMMAND .EQ. COMMAND_DIAGNOST) ) THEN C C Get information about geographic sections C DO GSECT_NUM = GEO_NUM_MIN, GEO_NUM_MAX C C Get Start Digitize rate C GEOSECT_ST_DIGITIZE_RATE(GSECT_NUM) & = GEOSECT_STDGT_INCR(GSECT_NUM) & * COUNT_SBSC_TO_HZ C C Find which geographic sections are active C IF (IBITS(GEOSECTPROG(GSECT_NUM),8,8) .EQ. 0) THEN GEO_SECT_DATA(GSECT_NUM).ALLOCATED = .FALSE. ELSE GEO_SECT_DATA(GSECT_NUM).ALLOCATED = .TRUE. ENDIF C C Get the start digitize status (test mode) of each geographic section C IF (IBITS(GEOSECTPROG(GSECT_NUM), 16, 8) .EQ. 0) THEN GEO_SECT_DATA(GSECT_NUM).STATUS = GEO_SECT_STATUS_NORMAL ELSE GEO_SECT_DATA(GSECT_NUM).STATUS = GEO_SECT_STATUS_TEST ENDIF C C Get Front end busy state C GEO_SECT_DATA(GSECT_NUM).FE_BUSY_STATE = & BTEST(DATABLOCK(FRONT_END_BUSY + (GSECT_NUM)/8), & MOD(GSECT_NUM, 8)) C C Get Front End Busy % C IF (DELTA_VETO_CROSSING .NE. 0) THEN GEO_SECT_DATA(GSECT_NUM).FE_BUSY_PERCENT = & FLOAT(GEOSECT_BUSY_INCR(GSECT_NUM)) & / FLOAT(DELTA_VETO_CROSSING) * 100. ELSE GEO_SECT_DATA(GSECT_NUM).FE_BUSY_PERCENT = 0. ENDIF C C Get start digitize state C GEO_SECT_DATA(GSECT_NUM).ST_DIG_STATE = & BTEST(DATABLOCK(START_DIGITIZE + (GSECT_NUM)/8), & MOD(GSECT_NUM, 8)) C C Find how many specific triggers are disabled by the front end busy C signal from this geographic section. C GEO_SECT_DATA(GSECT_NUM).NUM_TRG_FEB = 0 DO SPTRG_NUM = TRG_NUM_MIN, TRG_NUM_MAX IF (BTEST(SPTRGPROG(PG_WATCHBUSY + GSECT_NUM / 16, & SPTRG_NUM), MOD(GSECT_NUM, 16) * 2 + 1) & .EQV. .TRUE.) THEN GEO_SECT_DATA(GSECT_NUM).NUM_TRG_FEB = & GEO_SECT_DATA(GSECT_NUM).NUM_TRG_FEB + 1 ENDIF END DO C C Find how many specific triggers use this geographic section start C digitize signal C GEO_SECT_DATA(GSECT_NUM).NUM_TRG_STD = 0 DO SPTRG_NUM = TRG_NUM_MIN, TRG_NUM_MAX IF (BTEST(SPTRGPROG(PG_ST_DIG + GSECT_NUM / 16, SPTRG_NUM), & MOD(GSECT_NUM, 16) * 2) .EQV. .TRUE.) THEN GEO_SECT_DATA(GSECT_NUM).NUM_TRG_STD = & GEO_SECT_DATA(GSECT_NUM).NUM_TRG_STD + 1 ENDIF END DO C C Stop looping over geographic sections C END DO C ENDIF C C Unpack data for the Calorimeter Trigger monitoring display. C ----------------------------------------------------------- C IF (COMMAND .EQ. COMMAND_GLOBAL_MONIT) THEN C C Level 0 information C CALTRIG_DATA.LV0_GOOD = & BTEST(DATABLOCK(FAST_VERTEX), DB_LV0_GOOD_BIT) IF (BTEST(DATABLOCK(FAST_VERTEX), DB_LV0_BIN_SIGN) & .EQ. .TRUE.) THEN CALTRIG_DATA.LV0_BIN = -1 ELSE CALTRIG_DATA.LV0_BIN = 0 ENDIF CALL MVBITS(DATABLOCK(FAST_VERTEX), DB_LV0_BIN_START, & DB_LV0_BIN_LEN, CALTRIG_DATA.LV0_BIN, 0) C C The lookup pages are not available yet C C Global Energy Sums C CALTRIG_DATA.EM_ET_E = & EXTRACT_GLOB_E_SUM(EM_ET_TOTAL, ET_COUNT_SCALE, DB_SIGNED) C CALTRIG_DATA.HD_ET_E = & EXTRACT_GLOB_E_SUM(HD_ET_TOTAL, ET_COUNT_SCALE, DB_SIGNED) C CALTRIG_DATA.TOT_ET_E = & EXTRACT_GLOB_E_SUM(TOT_ET_TOTAL, ET_COUNT_SCALE, DB_SIGNED) C CALTRIG_DATA.EM_L2_E = & EXTRACT_GLOB_E_SUM(EM_L2_TOTAL, L2_COUNT_SCALE, DB_SIGNED) C CALTRIG_DATA.HD_L2_E = & EXTRACT_GLOB_E_SUM(HD_L2_TOTAL, L2_COUNT_SCALE, DB_SIGNED) C CALTRIG_DATA.TOT_L2_E = & EXTRACT_GLOB_E_SUM(TOT_L2_TOTAL, L2_COUNT_SCALE, DB_SIGNED) C CALTRIG_DATA.PX_PT = & EXTRACT_GLOB_E_SUM(PX_TOTAL, PT_COUNT_SCALE, DB_SIGNED) C CALTRIG_DATA.PY_PT = & EXTRACT_GLOB_E_SUM(PY_TOTAL, PT_COUNT_SCALE, DB_SIGNED) C CALTRIG_DATA.MIS_PT = & FLOAT(IAND(255, DATABLOCK(MPT_TOTAL))) * PT_COUNT_SCALE C C Trigger tower count above ref sets C DO REFSET_NUM = 0, RS_SET_MAX - RS_SET_MIN CALTRIG_DATA.EM_TOWER_RS_COUNT(REFSET_NUM+RS_SET_MIN) = 0 CALL MVBITS( & DATABLOCK(HOT_TOWER_FINAL+REFSET_NUM*2), 0, 8, & CALTRIG_DATA.EM_TOWER_RS_COUNT(REFSET_NUM+RS_SET_MIN), 0) CALL MVBITS( & DATABLOCK(HOT_TOWER_FINAL+REFSET_NUM*2+1), 0, 8, & CALTRIG_DATA.EM_TOWER_RS_COUNT(REFSET_NUM+RS_SET_MIN), 8) C CALTRIG_DATA.TOT_TOWER_RS_COUNT(REFSET_NUM+RS_SET_MIN) = 0 CALL MVBITS( DATABLOCK( HOT_TOWER_FINAL & + REFSET_NUM*2 & +(RS_SET_MAX-RS_SET_MIN+1)*2), & 0, 8, & CALTRIG_DATA.TOT_TOWER_RS_COUNT(REFSET_NUM & +RS_SET_MIN), & 0) CALL MVBITS( DATABLOCK( HOT_TOWER_FINAL & + REFSET_NUM*2 & +(RS_SET_MAX-RS_SET_MIN+1)*2+1), & 0, 8, & CALTRIG_DATA.TOT_TOWER_RS_COUNT(REFSET_NUM & +RS_SET_MIN), & 8) END DO C C Global thresholds cleared information C CALL GLOB_THRSH_AO() C ENDIF C C Copy the Data Block to IQ for those screens which need it C --------------------------------------------------------- C C NOTE: This routine writes to the common block ZEBCOM without regard to C any ZEBRA structures. If ZEBCOM is ever used by ZEBRA in TRGMON, this C portion of the code will have to be re-written to book banks, etc. This C is true if the routine INZCOM is ever called. C IF ( (COMMAND .EQ. COMMAND_GLOBAL_MONIT) & .OR. (COMMAND .EQ. COMMAND_JET_LIST) & .OR. (COMMAND .EQ. COMMAND_ADC) & .OR. (COMMAND .EQ. COMMAND_PRTRGR_DBLOCK) ) THEN C C Copy the Datablock to IQ C CALL OTS$MOVE3(%VAL(DATA_BLOCK_LENGTH*2), DATABLOCK, IQ(8) ) C C Copy the Trigger Fired Mask to the Data Block header in IQ C IQ(6) = 0 DO SPTRG_NUM = TRG_NUM_MIN, TRG_NUM_MAX IF (TRIGGER_DATA(SPTRG_NUM).TRIGGER_FIRED .EQV. .TRUE.) THEN IQ(6) = IBSET(IQ(6), SPTRG_NUM) ENDIF END DO C LHEAD = 0 IQ(0) = 0 C ENDIF C C C Jet list information C -------------------- C IF ( (COMMAND .EQ. COMMAND_GLOBAL_MONIT) & .OR. (COMMAND .EQ. COMMAND_JET_LIST) & .OR. (COMMAND .EQ. COMMAND_PRTRGR_DBLOCK) ) THEN C CALL L1UTIL_JET_LIST_BUILDER_FIRST( EM_ET_LIST) CALL L1UTIL_JET_LIST_BUILDER_FIRST(TOT_ET_LIST) CALL L1UTIL_JET_LIST_BUILDER_FIRST( LT_LIST) C CALL L1UTIL_JET_LIST_BUILDER( 1, EM_ET_LIST, & DB_MAX_JET_LIST_LENGTH, & CALTRIG_DATA.EM_JET_LIST_DBLENGTH, & CALTRIG_DATA.EM_JET_LIST) CALL L1UTIL_JET_LIST_BUILDER( 1, TOT_ET_LIST, & DB_MAX_JET_LIST_LENGTH, & CALTRIG_DATA.TOT_JET_LIST_DBLENGTH, & CALTRIG_DATA.TOT_JET_LIST) CALL L1UTIL_JET_LIST_BUILDER( 1, LT_LIST, & DB_MAX_JET_LIST_LENGTH, & CALTRIG_DATA.LG_TILE_LIST_DBLENGTH, & CALTRIG_DATA.LG_TILE_LIST) C EM_JET_LIST_LENGTH = CALTRIG_DATA.EM_JET_LIST_DBLENGTH TOT_JET_LIST_LENGTH = CALTRIG_DATA.TOT_JET_LIST_DBLENGTH LG_TILE_LIST_LENGTH = CALTRIG_DATA.LG_TILE_LIST_DBLENGTH C IF (IAND(EM_JET_LIST_LENGTH, H8000) .NE. 0) THEN CALTRIG_DATA.EM_JET_LIST_COMPLETE = .FALSE. ELSE CALTRIG_DATA.EM_JET_LIST_COMPLETE = .TRUE. ENDIF CALTRIG_DATA.EM_JET_LIST_LENGTH & = IAND(H7FFF, EM_JET_LIST_LENGTH) C IF (IAND(TOT_JET_LIST_LENGTH, H8000) .NE. 0) THEN CALTRIG_DATA.TOT_JET_LIST_COMPLETE = .FALSE. ELSE CALTRIG_DATA.TOT_JET_LIST_COMPLETE = .TRUE. ENDIF CALTRIG_DATA.TOT_JET_LIST_LENGTH & = IAND(H7FFF, TOT_JET_LIST_LENGTH) C IF (IAND(LG_TILE_LIST_LENGTH, H8000) .NE. 0) THEN CALTRIG_DATA.LG_TILE_LIST_COMPLETE = .FALSE. ELSE CALTRIG_DATA.LG_TILE_LIST_COMPLETE = .TRUE. ENDIF CALTRIG_DATA.LG_TILE_LIST_LENGTH & = IAND(H7FFF, LG_TILE_LIST_LENGTH) C DO ENTRY_NUM = 1, CALTRIG_DATA.EM_JET_LIST_LENGTH ADDRESS = CALTRIG_DATA.EM_JET_LIST(1, ENTRY_NUM) IF (IAND(ADDRESS,1) .EQ. 0) THEN CALTRIG_DATA.EM_JET_LIST_PHI(ENTRY_NUM) = 1 ELSE CALTRIG_DATA.EM_JET_LIST_PHI(ENTRY_NUM) = 17 ENDIF ADDRESS = ADDRESS/2 C CALTRIG_DATA.EM_JET_LIST_PHI(ENTRY_NUM) & = CALTRIG_DATA.EM_JET_LIST_PHI(ENTRY_NUM) & + IAND(ADDRESS, 15) ADDRESS = ADDRESS / 16 C CALTRIG_DATA.EM_JET_LIST_ETA(ENTRY_NUM) & = MOD(ADDRESS, 20) + 1 ADDRESS = ADDRESS / 20 IF (ADDRESS .NE. 0) THEN CALTRIG_DATA.EM_JET_LIST_ETA(ENTRY_NUM) & = - CALTRIG_DATA.EM_JET_LIST_ETA(ENTRY_NUM) ENDIF END DO C DO ENTRY_NUM = 1, CALTRIG_DATA.TOT_JET_LIST_LENGTH ADDRESS = CALTRIG_DATA.TOT_JET_LIST(1, ENTRY_NUM) IF (IAND(ADDRESS,1) .EQ. 0) THEN CALTRIG_DATA.TOT_JET_LIST_PHI(ENTRY_NUM) = 1 ELSE CALTRIG_DATA.TOT_JET_LIST_PHI(ENTRY_NUM) = 17 ENDIF ADDRESS = ADDRESS/2 C CALTRIG_DATA.TOT_JET_LIST_PHI(ENTRY_NUM) & = CALTRIG_DATA.TOT_JET_LIST_PHI(ENTRY_NUM) & + IAND(ADDRESS, 15) ADDRESS = ADDRESS / 16 C CALTRIG_DATA.TOT_JET_LIST_ETA(ENTRY_NUM) & = MOD(ADDRESS, 20) + 1 ADDRESS = ADDRESS / 20 IF (ADDRESS .NE. 0) THEN CALTRIG_DATA.TOT_JET_LIST_ETA(ENTRY_NUM) & = - CALTRIG_DATA.TOT_JET_LIST_ETA(ENTRY_NUM) ENDIF END DO C DO ENTRY_NUM = 1, CALTRIG_DATA.LG_TILE_LIST_LENGTH ADDRESS = CALTRIG_DATA.LG_TILE_LIST(1, ENTRY_NUM) IF (IAND(ADDRESS,1) .EQ. 0) THEN CALTRIG_DATA.LG_TILE_LIST_PHI(ENTRY_NUM) = 1 ELSE CALTRIG_DATA.LG_TILE_LIST_PHI(ENTRY_NUM) = 17 ENDIF ADDRESS = ADDRESS/2 C CALTRIG_DATA.LG_TILE_LIST_PHI(ENTRY_NUM) & = CALTRIG_DATA.LG_TILE_LIST_PHI(ENTRY_NUM) & + IAND(ADDRESS, 15) ADDRESS = ADDRESS / 16 C CALTRIG_DATA.LG_TILE_LIST_ETA(ENTRY_NUM) & = MOD(ADDRESS, 20) + 1 ADDRESS = ADDRESS / 20 IF (ADDRESS .NE. 0) THEN CALTRIG_DATA.LG_TILE_LIST_ETA(ENTRY_NUM) & = - CALTRIG_DATA.LG_TILE_LIST_ETA(ENTRY_NUM) ENDIF END DO C C Copy the Jet List into IQ C CALL OTS$MOVE3(%VAL(JET_LIST_L*2), & CALTRIG_DATA.EM_JET_LIST_DBLENGTH, IQ(8+EM_ET_JET_LIST/2) ) CALL OTS$MOVE3(%VAL(JET_LIST_L*2), & CALTRIG_DATA.TOT_JET_LIST_DBLENGTH, IQ(8+TOT_ET_JET_LIST/2) ) C C ENDIF C C Unpack PER_BUNCH information C ---------------------------- C IF ( (COMMAND .EQ. COMMAND_PER_BUNCH) &.OR. (COMMAND .EQ. COMMAND_LUMINOSITY) ) THEN C CALL L1EXTRACT_LIVEX_SCALERS(L1_CRATE_HEADER, & DB_GLOBAL_LIVEX_SCALER, & DB_LIVEX_PER_BUNCH, & DB_LIVEX_FASTZ_GOOD_PER_BUNCH, & DB_LIVEX_L0SINGLE_PER_BUNCH, & DB_SLOW_L0_PER_BUNCH) C TOTAL_LUM_DELIV_FAST_Z = 0. TOTAL_LUM_USED_FAST_Z = 0. TOTAL_LUM_SLOWZ_FRACT = 0. TOTAL_LUM_SLOWZ_OCCUP = 0. TOTAL_LUM_USED_VS_DELIV = 0. TOTAL_LIVE_X_PERCENT = 0. TOTAL_L1_TRIG_FRAC = 0. C DO BUNCH_NUM = PER_BUNCH_MIN, PER_BUNCH_MAX C PER_BUNCH_DATA(BUNCH_NUM).L1_PER_BUNCH_RATE = & L1_PER_BUNCH(BUNCH_NUM) * COUNT_TO_HZ C PER_BUNCH_DATA(BUNCH_NUM).L0_PER_BUNCH_RATE = & L0_PER_BUNCH(BUNCH_NUM) * COUNT_TO_HZ C PER_BUNCH_DATA(BUNCH_NUM).LIVE_CROSSING_RATE = & LIVEX_PER_BUNCH(BUNCH_NUM) * COUNT_TO_HZ C PER_BUNCH_DATA(BUNCH_NUM).L0_LIVEX_RATE = & LIVEX_FASTZGOOD_PER_BUNCH(BUNCH_NUM) * COUNT_TO_HZ C PER_BUNCH_DATA(BUNCH_NUM).L0S_LIVEX_RATE = & LIVEX_L0SINGLE_PER_BUNCH(BUNCH_NUM) * COUNT_TO_HZ C PER_BUNCH_DATA(BUNCH_NUM).L0S_CENT_RATE = & SLOW_L0_PER_BUNCH(BUNCH_NUM) * COUNT_TO_HZ C CALL L1_EXTRACT_PER_BUNCH(L1_CRATE_HEADER, BUNCH_NUM, & PER_BUNCH_DATA(BUNCH_NUM).L1_PER_BUNCH_COUNT, & PER_BUNCH_DATA(BUNCH_NUM).L1_PER_BUNCH_COUNT_GIGAS, & PER_BUNCH_DATA(BUNCH_NUM).L0_PER_BUNCH_COUNT, & PER_BUNCH_DATA(BUNCH_NUM).L0_PER_BUNCH_COUNT_GIGAS ) C PER_BUNCH_DATA(BUNCH_NUM).LIVE_CROSSING_COUNT_GIGAS & = I24TO40_G(DB_LIVEX_PER_BUNCH(2,BUNCH_NUM), & DB_LIVEX_PER_BUNCH(1,BUNCH_NUM)) PER_BUNCH_DATA(BUNCH_NUM).LIVE_CROSSING_COUNT & = I24TO40_U(DB_LIVEX_PER_BUNCH(2,BUNCH_NUM), & DB_LIVEX_PER_BUNCH(1,BUNCH_NUM)) C PER_BUNCH_DATA(BUNCH_NUM).L0_LIVEX_COUNT_GIGAS & = I24TO40_G(DB_LIVEX_FASTZ_GOOD_PER_BUNCH(2,BUNCH_NUM), & DB_LIVEX_FASTZ_GOOD_PER_BUNCH(1,BUNCH_NUM)) PER_BUNCH_DATA(BUNCH_NUM).L0_LIVEX_COUNT & = I24TO40_U(DB_LIVEX_FASTZ_GOOD_PER_BUNCH(2,BUNCH_NUM), & DB_LIVEX_FASTZ_GOOD_PER_BUNCH(1,BUNCH_NUM)) C PER_BUNCH_DATA(BUNCH_NUM).L0S_LIVEX_COUNT_GIGAS & = I24TO40_G(DB_LIVEX_L0SINGLE_PER_BUNCH(2,BUNCH_NUM), & DB_LIVEX_L0SINGLE_PER_BUNCH(1,BUNCH_NUM)) PER_BUNCH_DATA(BUNCH_NUM).L0S_LIVEX_COUNT & = I24TO40_U(DB_LIVEX_L0SINGLE_PER_BUNCH(2,BUNCH_NUM), & DB_LIVEX_L0SINGLE_PER_BUNCH(1,BUNCH_NUM)) C PER_BUNCH_DATA(BUNCH_NUM).L0S_CENT_COUNT_GIGAS & = I24TO40_G(DB_SLOW_L0_PER_BUNCH(2, BUNCH_NUM), & DB_SLOW_L0_PER_BUNCH(1, BUNCH_NUM)) PER_BUNCH_DATA(BUNCH_NUM).L0S_CENT_COUNT & = I24TO40_U(DB_SLOW_L0_PER_BUNCH(2, BUNCH_NUM), & DB_SLOW_L0_PER_BUNCH(1, BUNCH_NUM)) C C C ---- Get the rest of luminosity related information for luminosity display C (some is used in per bunch display too) C C -- Slow Z luminosity per bunch C BUNCH_LUM_DELIV_FAST_Z( BUNCH_NUM ) = & DERIVED_LUMINOSITY( BUNCH_CROSSING_FREQ, & CROSSING_PER_BUNCH, & FLOAT(L0_PER_BUNCH(BUNCH_NUM)), & CROSS_SECTION_L0_FAST_Z_GOOD ) C C Increment Total Luminosity, using correction C TOTAL_LUM_DELIV_FAST_Z = TOTAL_LUM_DELIV_FAST_Z & + BUNCH_LUM_DELIV_FAST_Z( BUNCH_NUM ) C C -- Luminosity used C BUNCH_LUM_USED_FAST_Z( BUNCH_NUM ) = & DERIVED_LUMINOSITY ( & PER_BUNCH_DATA(BUNCH_NUM).LIVE_CROSSING_RATE, & FLOAT(LIVEX_PER_BUNCH(BUNCH_NUM)), & FLOAT(LIVEX_FASTZGOOD_PER_BUNCH(BUNCH_NUM)), & CROSS_SECTION_L0_FAST_Z_GOOD ) C C Increment Total Luminosity, using correction C TOTAL_LUM_USED_FAST_Z = TOTAL_LUM_USED_FAST_Z & + BUNCH_LUM_USED_FAST_Z( BUNCH_NUM ) C C C -- Fraction of luminosity seen on each bunch C IF ( TOTAL_LUM_DELIV_SLOW_Z .GT. 1.0E-6 ) THEN BUNCH_LUM_SLOWZ_FRACT( BUNCH_NUM ) = & 100. * BUNCH_LUM_DELIV_SLOW_Z( BUNCH_NUM ) & / TOTAL_LUM_DELIV_SLOW_Z TOTAL_LUM_SLOWZ_FRACT = TOTAL_LUM_SLOWZ_FRACT & + BUNCH_LUM_SLOWZ_FRACT(BUNCH_NUM) ELSE BUNCH_LUM_SLOWZ_FRACT( BUNCH_NUM ) = 0. ENDIF C C -- Occupancy (i.e. fraction of Beam X) of Slow Z per bunch scalers C IF ( CROSSING_PER_BUNCH .GT. 1.0E-6 ) THEN BUNCH_LUM_SLOWZ_OCCUP( BUNCH_NUM ) = & 100. * FLOAT( SLOW_L0_PER_BUNCH( BUNCH_NUM ) ) & / CROSSING_PER_BUNCH C This is a special sum, see below TOTAL_LUM_SLOWZ_OCCUP = TOTAL_LUM_SLOWZ_OCCUP & + FLOAT( SLOW_L0_PER_BUNCH(BUNCH_NUM)) ELSE BUNCH_LUM_SLOWZ_OCCUP( BUNCH_NUM ) = 0. ENDIF C C -- Luminosity used vs luminosity delivered C IF ( BUNCH_LUM_DELIV_FAST_Z(BUNCH_NUM) .GT. 1.0E-6 ) THEN BUNCH_LUM_USED_VS_DELIV( BUNCH_NUM ) = & 100. * BUNCH_LUM_USED_FAST_Z( BUNCH_NUM ) & / BUNCH_LUM_DELIV_FAST_Z( BUNCH_NUM ) C This is a special sum, see below ELSE BUNCH_LUM_USED_VS_DELIV( BUNCH_NUM ) = 0. ENDIF C C -- Percentage of live crossings C IF ( CROSSING_PER_BUNCH .GT. 1.0E-6 ) THEN BUNCH_LIVE_X_PERCENT( BUNCH_NUM ) = & 100. * FLOAT( LIVEX_PER_BUNCH( BUNCH_NUM ) ) & / CROSSING_PER_BUNCH C This is a special sum, see below TOTAL_LIVE_X_PERCENT = TOTAL_LIVE_X_PERCENT & + FLOAT( LIVEX_PER_BUNCH( BUNCH_NUM ) ) ELSE BUNCH_LIVE_X_PERCENT( BUNCH_NUM ) = 0. ENDIF C C -- Fraction of Level 1 triggers seen on each bunch C IF ( DELTA_GLOBAL_FIRED .GT. 1.0E-6 ) THEN BUNCH_L1_TRIG_FRAC( BUNCH_NUM ) = & 100. * FLOAT( L1_PER_BUNCH( BUNCH_NUM ) ) & / FLOAT( DELTA_GLOBAL_FIRED ) TOTAL_L1_TRIG_FRAC = TOTAL_L1_TRIG_FRAC & + BUNCH_L1_TRIG_FRAC(BUNCH_NUM) ELSE BUNCH_L1_TRIG_FRAC( BUNCH_NUM ) = 0. ENDIF C END DO C C ---- Now finish the special sums of the luminosity page C IF ( DELTA_BEAM_CROSSING .GT. 0 ) THEN C C -- Total occupancy is the average of the per bunch percentages, C which is same as total percentage C TOTAL_LUM_SLOWZ_OCCUP = 100. & * TOTAL_LUM_SLOWZ_OCCUP & / FLOAT( DELTA_BEAM_CROSSING ) C C -- Total live crossing is the average of the per bunch percentages, C which is same as total percentage C TOTAL_LIVE_X_PERCENT = 100. & * TOTAL_LIVE_X_PERCENT & / FLOAT( DELTA_BEAM_CROSSING ) ELSE TOTAL_LUM_SLOWZ_OCCUP = 0. TOTAL_LIVE_X_PERCENT = 0. ENDIF C IF ( TOTAL_LUM_DELIV_FAST_Z .GT. 1.0E-6 ) THEN C C -- Total comparison of lum used vs delivered is based on the C total luminosity numbers, not an average of per bunch numbers. C TOTAL_LUM_USED_VS_DELIV = 100. & * TOTAL_LUM_USED_FAST_Z & / TOTAL_LUM_DELIV_FAST_Z ELSE TOTAL_LUM_USED_VS_DELIV = 0. ENDIF C ENDIF C C Unpack Foreign Scaler information C --------------------------------- C IF (COMMAND .EQ. COMMAND_FOREIGN_SCALERS) THEN DO SCALER_NUM = FOREIGN_MIN, FOREIGN_MAX CALL L1UTIL_GET_FOREIGN_SCALER( L1_CRATE_HEADER, SCALER_NUM, & SCALER_COUNT ) FOREIGN_SCALER_DATA(SCALER_NUM).FS_COUNT = & I24TO40_U(SCALER_COUNT(2), SCALER_COUNT(1)) FOREIGN_SCALER_DATA(SCALER_NUM).FS_COUNT_GIGAS = & I24TO40_G(SCALER_COUNT(2), SCALER_COUNT(1)) FOREIGN_SCALER_DATA(SCALER_NUM).FS_RATE & = FOREIGN_SCALER(SCALER_NUM) * COUNT_TO_HZ END DO ENDIF C C---------------------------------------------------------------------- 999 RETURN END C####################################################################### REAL FUNCTION DERIVED_LUMINOSITY( CROSSING_FREQ, & BASE_CROSSING_COUNT, & LUM_SCALER_COUNT, & CROSS_SECTION ) C---------------------------------------------------------------------- C- C- Purpose and Methods : derive a luminosity from a Level 0 scaler C- C- The general formula used for computing the luminosity is: C- C- crossing_freq C- L = - ------------- * Loge ( fraction_of_beam_X_with_no_interaction ) C- cross_section C- C- Returned value : [Real] Luminosity quantity C- Inputs : C- CROSSING_FREQ [R] beam crossing frequency C- (in fact the bunch crossing frequency) C- BASE_CROSSING_COUNT [R] base count of beam crossings C- LUM_SCALER_COUNT [R] hit count of monitored scaler C- (this corresponds to a fraction of C- BASE_CROSSING_COUNT) C- CROSS_SECTION [R] cross section of the process monitored C- (accounting for detector efficiency) C- Outputs : None C- Controls: None C- C- Created 18-MAY-1995 Philippe Laurens - MSU L1 Trigger C- C---------------------------------------------------------------------- IMPLICIT NONE REAL CROSSING_FREQ REAL BASE_CROSSING_COUNT REAL LUM_SCALER_COUNT REAL CROSS_SECTION REAL FRACTION_NOT_GOOD C---------------------------------------------------------------------- C C prepare an overflow in case of problem DERIVED_LUMINOSITY = 1.0E22 FRACTION_NOT_GOOD = 1. C IF ( BASE_CROSSING_COUNT .GT. 1.0E-6 ) & FRACTION_NOT_GOOD = & ( BASE_CROSSING_COUNT - LUM_SCALER_COUNT ) & / BASE_CROSSING_COUNT C IF ( FRACTION_NOT_GOOD .GT. 1.0E-6 ) & DERIVED_LUMINOSITY = & - CROSSING_FREQ & * ALOG( FRACTION_NOT_GOOD ) & / CROSS_SECTION ! in units of millibarn & / 1000. ! for result in units of E30*s-1*cm-2 C 999 RETURN END C####################################################################### REAL FUNCTION DERIVED_LUM_SD_COR( CROSSING_FREQ, & LUM_VALUE, & CROSS_SECTION_MIN_BIAS, & CROSS_SECTION_SGL_DIFF ) C---------------------------------------------------------------------- C- C- Purpose and Methods : derive the luminosity diffractive correction C- C- The formula used in correcting the luminosity for double single C- diffractive events is: C- C- X_freq X_sect_SD * Lum X_sect_SD * Lum C- Delta_L = --------- * Loge( 2 - exp( - --------------- ) ) - --------------- C- X_sect_MB 2 * X_freq 2 * X_sect_MB C- C- C- where X_freq is the beam crossing frequency C- (in fact the bunch crossing frequency) C- and X_sect_MB is the normal cross section for the process (Min Bias) C- and X_sect_SD is the single diffraction cross section C- C- Returned value : [Real] Luminosity quantity C- Inputs : C- CROSSING_FREQ [R] beam crossing frequency C- (in fact the bunch crossing frequency) C- LUM_VALUE [R] Luminosity quantity to correct for C- CROSS_SECTION_MIN_BIAS [R] cross section of the process monitored C- (accounting for detector efficiency) C- CROSS_SECTION_SGL_DIFF [R] cross section of the diffractive process C- C- Outputs : None C- C- Created 18-MAY-1995 Philippe Laurens - MSU L1 Trigger C- C---------------------------------------------------------------------- IMPLICIT NONE REAL CROSSING_FREQ REAL LUM_VALUE REAL CROSS_SECTION_MIN_BIAS REAL CROSS_SECTION_SGL_DIFF C REAL TEMP C DERIVED_LUM_SD_COR = 0.0 C TEMP = CROSS_SECTION_SGL_DIFF * LUM_VALUE & / ( 2. * CROSSING_FREQ / 1000. ) C C It is fair to asume that the cross sections will be > 0, (and the C lumnosity >= 0) but the frequency could be wrong and negative. C IF ( TEMP .GE. 0.0 ) & DERIVED_LUM_SD_COR = CROSSING_FREQ / 1000. & / CROSS_SECTION_MIN_BIAS & * ALOG( 2 - EXP( - TEMP ) ) & - ( CROSS_SECTION_SGL_DIFF * LUM_VALUE ) & / ( 2. * CROSS_SECTION_MIN_BIAS ) C C---------------------------------------------------------------------- 999 RETURN END