F1 Software Considerations
Contents
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...