F1 Software Considerations

From Hchkswiki
Jump to: navigation, search

DAQ Configuration Issues

Programming of Modules

The individual modules (actually the 8 chips of ech module) must be programmed for the desired operation. What options exist and what to program them for can be learned from the manual, found here. The main considerations are high or low resolution mode, and the time window of interest.

To facilitate this, the CODA setup currently used in Hall C reads a parameter file that can be created and interpreted using scripts provided by the JLab DAQ group:

~/hks09/coda25/crl/F1TDC/cfg_file_make

and

~/hks09/coda25/crl/F1TDC/cfg_file_display  file_name

The name of the parameter file will need to be indicated during the "cfg_file_make" process, and this same file must be identified in the corresponding ROC's boot script. For this reason, the script should be run from the ~/hks09/coda25/crl/F1TDC/ directory and the file should be located there as well.

An explanation of the various parameters can be found in this document (PDF) provided by the DAQ experts.

In the boot script of the ROC controlling the F1 TDCs, additional information to be provided includes the base address of the modules address space, i.e. the address of the first module, see aforementioned external pages. Other parameters may need updating, see the corresponding boot scripts and CRL files.

Verifying Operation

While the universal data scanning tool xcefdmp will happily display the F1's data, the sheer number and inconsistent count of header words makes interpreting them rather difficult. Instead, the script

~/hks09/coda25/scripts/check_vme_data.tcl

(to be executed via: tclsh check_vme_data.tcl runnumber ) should be used, as this identifies header and decodes the data.


Analysis Software Considerations

The peculiarities of the F1 TDCs also require special handling in the unpacking and interpreting of the data in the analysis code. The current CVS versions in the Hall C repository should include the general updates and also provide sample implementations for the specific applications, but the following provides an overview of the needed changes.

Cable Map & Data Header Decoding

To properly decode the data stream, the analysis software must know whether a module is VME or FastBus electronics. This is done by adding the tag

Module= 1

to the cable map header blocks. A value of "1" identifies a VME module and a value of "0" FastBus. For backward compatibility, a missing declaration is interpreted as "0" (FastBus). The current implementation meets the needs of the F1 TDC, as this is to date the only non-scaler VME module being read; other VME modules may require different header decoding, see the files g_decode_fb_bank.f and g_decode_fb_detector.f of the replay engine code. This correction must be made wherever the "subaddress" must be determined:

       if (g_decode_modtyp(roc,slot).eq.0) then ! FastBus
         subadd = jiand(jishft(bank(pointer),-g_decode_subaddbit(roc,slot)),'7F'X)
       elseif (g_decode_modtyp(roc,slot).eq.1) then !VME F1 TDC
         * F1 uses 1 as the first channel, not 0!!!	
         if (jiand(ishft(bank(pointer),-23),'1'X).eq.0) then  !header
           subadd = jiand(bank(pointer),'3F'X) + 1
         else  !data
           subadd = jiand(jishft( bank(pointer),-g_decode_subaddbit(roc,slot) ),'3F'X) + 1
         endif
       endif

Additionally, for hi-res operation, the following must be used to modify the subadd:

           * For hi res mode, have to take in pairs
           subadd = (subadd - 1) / 2 + 1

This logic is based on the definiton of the data and header words as documented in the manual. Here is the summary I have added to the relevant codes for quick reference:

for F1 TDCs, the traditional subadd cut will not work!
we need the header word which contains the trigger time to
handle roll-over, but the header has the subadd at the very LSB 

so we branch depending on externally supplied VME ROC flag to
properly handle these headers and all data words
note that we really WANT to see the header words for trigger timing!

 for F1 TDC, there are two types of data:
  header/trailer words and data words

                                ,overflow              Xor
 header/trailer: xxxx xxxx  0  ?  ?? ????  ???? ???? ?  ?  ?? ?  ???
                                    |        T_trigger       |   channel
                                event no                  chip

           data: xxxx xxxx  1 0  ?? ?  ???  ???? ???? ???? ????
                                 chip  chan ------ data -------

 in both cases, the first 8 bits (xxxx xxxx) are as follows:

     ???? ?   ???
       slot   error flags

 data have 16 bits for TDC count, i.e. 0-65535
 but header's T_trigger only has 9 bits, i.e. 0-511

Additionally, some error conditions result in data words meant to flag these occurances and should be skipped in the analysis, e.g. in g_decode_fb_detector.f :

signal =jiand(evfrag(pointer),g_decode_slotmask(roc,slot))
if (signal.eq.65535) then   ! skip overflow entries
  pointer = pointer + 1
  goto 987
endif


Roll-Over

As is discussed in the other pages, the F1 uses a free running clock which will roll over when the bit space is exhausted. Since events can occur on either side of the roll-over even for the same trigger, this occurance must be detected and corrected for. The basic approach is that the low-resolution time of the trigger event rolls over at the same time as the data clocks. Since the data always have to come before the trigger, they will have smaller time values. Comparing the (properly rescaled) times tells us if a roll-over intervened (g_decode_fb_detector.f):

      if (g_decode_modtyp(roc,slot).eq.0) then  ! fastbus
      ...
      elseif (g_decode_modtyp(roc,slot).eq.1) then  ! VME F1 TDC
        * F1 uses 1 as the first channel, not 0!!!	
        if (jiand(ishft(evfrag(pointer),-23),'1'X).eq.1) then  !data
        else  !header
          trigger_time = jiand(ishft(evfrag(pointer),-7),'1FF'X)
          trigger_time = trigger_time*128 + 127  ! trigger time has 7 bits less resolution!!
        endif
      endif
             * fix roll-over if module is F1 TDC
             if (g_decode_modtyp(roc,slot).eq.1) then
               if (signal.lt.trigger_time) then  ! roll-over!!
                 signal = signal + F1TDC_WINDOW_SIZE(roc)
               endif
             endif

The constant refered to as F1TDC_WINDOW_SIZE(roc) is the very last value in the parameter file read in by the ROCs boot script to program the F1 chips, see "programming" above. It is not quite properly named, as it does not refer to the trigger window but instead to the maximum time value that can occur. For a 4-bit counter, this would be 1111 (or 0xF), but the F1 actually reduces the maximum time before roll-over. The implementation cited here requires all modules in a given crate to be programmed identically. Again, this is not about the trigger time window!!

Conversion to Time Difference

Again, the F1 does not report time differences but absolute times. Therefore, the times must be compared to some reference time corresponding to a known event. A recent implementation of the analysis engine used non-existant detector element numbers to encode this signal, which was then searched out before the actual event times were processed so they could be converted from absolute times to time differences. Unfortunately, the reference time is here refered to as "trigger time" (h_trans_fpp.f):

      * find TDC trigger time!!  skip whatever we can!
      do rawhitidx=1, HFPP_raw_tot_hits
        if (HFPP_raw_plane(rawhitidx).ne.HFPP_trigger_plane) CYCLE
        if (HFPP_raw_wire(rawhitidx) .ne.HFPP_trigger_wire)  CYCLE

        ROC = g_decode_roc(HFPP_ID,HFPP_raw_plane(rawhitidx),HFPP_raw_wire(rawhitidx),0)
        HFPP_trigger_TDC(ROC) = HFPP_raw_TDC(rawhitidx)
      enddo !rawhitidx

followed later by:

         * although we operate in COMMON STOP mode, the F1 TDCs are free-running
         * counters, so as time passes the count value increases
         * ignoring the overflow due to the limited counting range that means
         * earlier events should have a smaller TDC count than later events
         * the trigger should be the last signal and ought to have the largest
         * value; if it does not, we have a roll-over of the trigger time
         if (HFPP_raw_TDC(rawhitidx) .gt. HFPP_trigger_TDC(ROC)) then
           tdiff = HFPP_raw_TDC(rawhitidx) - HFPP_trigger_TDC(ROC) - F1TDC_WINDOW_SIZE(ROC)
         else
           tdiff = HFPP_raw_TDC(rawhitidx) - HFPP_trigger_TDC(ROC)
         endif

The above code snippets are based on the assumption that the reference time (here called "trigger time") is the only time value recorded for the reference signal's channel. For a properly formed signal and a well adjusted trigger time window, this is easily achieved...