- Enhanced and debugged histogram memory for AMOR

* added PROJECT both in HM and driver code
  * added single detector support.
- Removed several bugs in the AMOR data bit.
- Updated documentation
This commit is contained in:
cvs
2001-08-17 14:33:05 +00:00
parent a538361516
commit db6c355f44
56 changed files with 4060 additions and 426 deletions

View File

@@ -24,6 +24,9 @@
#define MAX_TOF_CNTR 1024 /* The maximum number of individual counters ..
** which can be handled in TOF mode */
#define MAX_PSD_CNTR 1048576 /* maximum number of PSD elements */
#define MAX_PSD_ED 2 /* maximum number of additional
single detectors at AMOR
*/
#define MAX_TOF_NBINS 32768 /* The maximum number of bins in a TOF histog */
#define MAX_TOF_EDGE 16 /* The maximum number of TOF edge arrays */
#define VMIO_BASE_ADDR 0x1900 /* VME address of a (possible) VMIO10 module */
@@ -111,6 +114,10 @@
*/
#define PROJECT__ON_Y 0x0001 /* Project onto y-axis */
#define PROJECT__1_DIM 0x0002 /* Make projection of a 1-dim histogram */
#define PROJECT__COLL 0x0003 /* collapse PSD on one time channel */
#define PROJECT__SAMPLE 0x0004 /* sum a rectangular part of the PSD
detector in time
*/
/*
** ----------------------------------------------------------
** Definition of bits in <flag> of TOF edge-array
@@ -215,12 +222,14 @@
#define LWL_PSD_TSI 0x0E000000 /* PSD-Mode TSI datagram */
#define LWL_PSD_DATA 0x12000000 /* PSD-mode data datagram */
#define LWL_PSD_ED 0x03000000 /* PSD-mode single detector datagram */
#define LWL_PSD_PWF 0x20000000 /* PSD-mode Power Fail bit */
#define LWL_PSD_TIME 0x000fffff /* PSD-mode time stamp extraction
mask */
#define LWL_PSD_FLASH_MASK 0x00ff /* mask for flash count */
#define LWL_PSD_XORF 0x2000 /* mask for TDC-XORF bit */
#define LWL_PSD_CONF 0x0100 /* mask for TDC-CONF flag */
#define LWL_HDR_ED_MASK 0x1C000000 /* mask for extracting ds4-ds2 */
#define LWL_SM_NC (0x10000000) /* Strobo-Mode/No-Coinc 0 chan dgrm hdr */
#define LWL_SM_NC_C1 (0x11000000) /* Strobo-Mode/No-Coinc 1 chan dgrm hdr */

View File

@@ -731,9 +731,9 @@
uint ui4;
usint ui2[2];
uchar ui1[4];
} lwl_hdr, xData, yData;
} lwl_hdr, xData, yData, edData;
int xPos, yPos, iTime, dataPos;
int xPos, yPos, iTime, dataPos, edNum;
signed int sPosx, sPosy;
int i, j, is, ts, left, right, middl, not_finished;
uint *edge_pntr;
@@ -868,6 +868,122 @@
*/
dataPos = yPos*psdXSize*Tof_edges[0]->n_bins +
xPos*Tof_edges[0]->n_bins + middl;
/* UD must come but the bit is not yet defined
if ((Hm_mode_UD != 0) &&
((lwl_hdr.ui4 & LWL_HDR_UD_MASK) != 0)) {
dataPos +=
(psdXSize*psdYSize+MAX_PSD_ED)*Tof_edges[0]->n_bins ;
}
*/
switch(Bytes_per_bin)
{
case 1:
histcPtr[dataPos]++;
break;
case 2:
histsPtr[dataPos]++;
break;
case 4:
histlPtr[dataPos]++;
break;
}
VmioBase[VMIO_PORT_A] = 0x00; /* Reset timer level (if present) */
N_events++;
}else if ( (lwl_hdr.ui4 & LWL_HDR_ED_MASK) == 0) {
/*
we have located a single detector packet from AMOR. We need to
read the detector number
*/
VmioBase[VMIO_PORT_A] = 0xff; /* Set timer level (if present) */
for (i=0; i<1000; i++) {
edData.ui4 = *Lwl_fifo; /* Get the detector number */
if (edData.ui4 != LWL_FIFO_EMPTY) break;
taskDelay (0); /* But wait if FIFO is slow! */
}
if (xData.ui4 == LWL_FIFO_EMPTY) {
printf ("Time-out getting detector number !\n");
continue;
}
/*
check if data aquisition is active
*/
if ((lwl_hdr.ui4 & Lwl_hdr_daq_mask) != Lwl_hdr_daq_soll) {
/* Some header bits are not what they should be (e.g. NRL
** ow PWF may be set) so skip the event.
*/
N_skipped++;
if (Dbg_lev1) {
printf("Skipped header: 0x%08x\n"
" Mask: 0x%08x\n"
" Soll: 0x%08x\n",
lwl_hdr.ui4, Lwl_hdr_daq_mask, Lwl_hdr_daq_soll);
}
continue;
}
/*
We have a valid single detector packet.
*/
edNum = edData.ui2[1];
if(edNum < 0 || edNum >= MAX_PSD_ED){
printf("Got invalid detector number %d\n",edNum);
continue;
}
/*
Extract time stamp and match to the appropriate time bin.
*/
iTime = lwl_hdr.ui4 & LWL_PSD_TIME;
if(Dbg_lev1){
printf("Received single detector hit at no, time: %d, %d\n",
edNum, iTime);
}
edge_pntr = Tof_edges[0]->edges;
left = 0;
right = Tof_edges[0]->n_bins;
middl = (left + right)/2;
not_finished = True;
iTime -= Tof_dts_soll;
while (not_finished) {
switch (right - left) {
case 0:
not_finished = False;
break;
case 1:
middl = (iTime >= edge_pntr[right]) ? right : left;
not_finished = False;
break;
default:
middl = (left + right)/2;
if (iTime == edge_pntr[middl]) {
not_finished = False;
}else if (iTime > edge_pntr[middl]) {
left = middl;
}else {
right = middl;
}
}
}
if(Dbg_lev1){
printf("Matched time stamp %d into bin %d\n", iTime,middl);
}
/*
calculate histogram position to update
*/
dataPos = (psdYSize*psdXSize + edNum)*Tof_edges[0]->n_bins + middl;
/* UD must come but the UD bit is not defined......
if ((Hm_mode_UD != 0) &&
((lwl_hdr.ui4 & LWL_HDR_UD_MASK) != 0)) {
dataPos +=
(psdXSize*psdYSize+MAX_PSD_ED)*Tof_edges[0]->n_bins ;
}
*/
switch(Bytes_per_bin)
{
case 1:

View File

@@ -21,6 +21,8 @@
** 1B01 11-Jun-1999 DM Add SQHM__HRPT mode.
** 1B02 10-Aug-1999 DM Make Lwl_hdr_daq_mask/Lwl_hdr_daq_soll dependent
** on the instrument.
** 1B03 May-2001 MK Added code for AMOR/TRICS PSD
** 1B04 August 2001 MK Added code for AMOR to PROJECT handling
**---------------------------------------------------------------------------
** SinqHM_srv_routines.c is part of the SINQ Histogram Memory process
** which will run in a front-end processor and perform the necessary
@@ -1555,44 +1557,14 @@
return ERROR;
}
Total_bytes += (n_cntrs * n_bins * bytes_per_bin);
if (Hm_mode_UD != 0) Total_bytes += (n_cntrs * n_bins * bytes_per_bin);
/* This is useful,but a waste of memory for a PSD. It would need
2.6MB. Let us try if we can live without it.
for (j = first; j < (first + n_cntrs); j++) {
if (Tof_descr[j] != NULL) {
printf ("do_SQHM__PSD_alloc: Doubly defined counter: %d.\n",
(j));
rply_status_setup (reply, KER__BAD_VALUE, 0, "Doubly defined counter");
free_HM_memory (NULL);
if (n_extra_bytes != 0) free (my_rqst);
return ERROR;
}
Tof_descr[j] = calloc (1, sizeof (struct tof_histog));
if (Tof_descr[j] == NULL) {
printf ("do_SQHM__PSD_alloc: unable to alloc memory for "
"histogram structure.\n");
rply_status_setup (reply, KER__BAD_ALLOC, 0,
"Failed to get buffer for Tof_descr structure");
free_HM_memory (NULL);
if (n_extra_bytes != 0) free (my_rqst);
return ERROR;
}
Tof_descr[j]->cntr_nmbr = first + j;
Tof_descr[j]->lo_edge = edge_info_pntr->edges[0];
Tof_descr[j]->hi_edge = edge_info_pntr->hi_edge;
Tof_descr[j]->flag = flag;
Tof_descr[j]->bytes_per_bin = bytes_per_bin;
Tof_descr[j]->n_bins = n_bins;
Tof_descr[j]->cnt_early_up = 0;
Tof_descr[j]->cnt_late_up = 0;
Tof_descr[j]->cnt_early_down = 0;
Tof_descr[j]->cnt_late_down = 0;
Tof_descr[j]->bin_edge = edge_info_pntr->edges;
Tof_descr[j]->u.b_bin_data = NULL;
}
/*
here there is a tricky bit: AMOR has two additional single
detectors which need to be binned. They are appended after the
normal PSD-histogram
*/
Total_bytes += ((n_cntrs + MAX_PSD_ED) * n_bins * bytes_per_bin);
if (Hm_mode_UD != 0)
Total_bytes += ((n_cntrs + MAX_PSD_ED) * n_bins * bytes_per_bin);
if (i == 0) { /* Use the first counter bank to define some .. */
N_hists = n_cntrs; /* .. globals since we expect there usually to .. */
@@ -1615,7 +1587,7 @@
i = memFindMax (); /* Get size of biggest free memory block */
if (i > Total_bytes) {
Hist_base_addr = calloc (Total_bytes, sizeof (char));
Hist_base_addr = calloc (Total_bytes, sizeof (char));
}else {
Hist_base_addr = NULL;
}
@@ -1629,17 +1601,6 @@
return ERROR;
}
/* as wee decided not to use Tof_descr, this is surplus as well.
nxt_hist_addr = Hist_base_addr;
for (i = 0; i < MAX_PSD_CNTR; i++) {
if (Tof_descr[i] != NULL) {
Tof_descr[i]->u.b_bin_data = nxt_hist_addr;
j = Tof_descr[i]->n_bins * Tof_descr[i]->bytes_per_bin;
if (Hm_mode_UD != 0) j = j * 2;
nxt_hist_addr += j;
}
}
*/
Cnts_lo = Cnts_hi = 0;
N_events = N_skipped = N_no_coin_tsi = N_coin_tsi = 0;
Print_hdr = True;
@@ -2240,7 +2201,7 @@
** Read a "rectangular" region of Hist Mem and send it
** to the client.
*/
register int i, j, offs;
register int i, j, k, offs, dataPtr, nTime;
register uint my_bin_lo, my_bin_hi;
register uint my_hist_lo, my_hist_hi;
@@ -2403,6 +2364,35 @@
** for reserving buffer space.
*/
break;
case SQHM__HM_PSD:
/*
** code for TRICS, AMOR PSD
*/
if(sub_code == PROJECT__COLL){
my_nbins = psdXSize * psdYSize;
nTime = Tof_edges[0]->n_bins;
} else if(sub_code == PROJECT__SAMPLE) {
if(x_lo < 0 || x_lo + nx > psdXSize){
printf ("\n\007%s -- SQHM_PROJECT:Bad x_range lo %d, n %d,max %d\n",
Tsk_name[index], x_lo,nx,psdXSize);
is = rply_status_send (rw_skt, rply_bf);
return OK;
}
if(y_lo < 0 || y_lo + ny > psdYSize){
printf ("\n\007%s -- SQHM_PROJECT:Bad y_range lo %d, n %d,max %d\n",
Tsk_name[index], y_lo,ny,psdYSize);
is = rply_status_send (rw_skt, rply_bf);
return OK;
}
my_nbins = Tof_edges[0]->n_bins;
nTime = Tof_edges[0]->n_bins;
} else {
printf ("\n\007%s -- SQHM_PROJECT:Bad subcode for PSD\n",
Tsk_name[index]);
is = rply_status_send (rw_skt, rply_bf);
return OK;
}
break;
/*-----------------------------------------------------------*/
default: /* SQHM_PROJECT is not supported in other modes. */
printf ("\n\007%s -- SQHM_PROJECT: bad Hm_mode!\n", Tsk_name[index]);
@@ -2417,8 +2407,11 @@
** need for the projection depends on whether the
** projection is onto the x-axis or y-axis.
*/
my_nbins = ((sub_code & PROJECT__ON_Y) == 0) ?
(my_bin_hi - my_bin_lo + 1) : (my_hist_hi - my_hist_lo + 1);
if(Hm_mode != SQHM__HM_PSD){
my_nbins = ((sub_code & PROJECT__ON_Y) == 0) ?
(my_bin_hi - my_bin_lo + 1) : (my_hist_hi - my_hist_lo + 1);
}
my_pntr.base = calloc (my_nbins, sizeof (uint));
if (my_pntr.base == NULL) {
@@ -2521,6 +2514,52 @@
}
}
break;
case SQHM__HM_PSD:
/*
** code for TRICS/AMOR PSD
**
*/
if(sub_code == PROJECT__COLL){
hm_pntr.base = Hist_base_addr;
for(i = 0; i < psdXSize; i++){
for(j = 0; j < psdYSize; j++){
offs = j * psdXSize + i;
dataPtr = j*psdXSize*nTime + i*nTime;
my_pntr.i4[offs] = 0;
for(k = 0; k < nTime; k++){
switch(Bytes_per_bin)
{
case 1:
my_pntr.i4[offs] += hm_pntr.ch[dataPtr + k];
break;
case 2:
my_pntr.i4[offs] += hm_pntr.i2[dataPtr + k];
break;
case 4:
my_pntr.i4[offs] += hm_pntr.i4[dataPtr + k];
if(hm_pntr.i4[dataPtr +k] > 0 ) {
printf("Data found at %d, %d, %d\n",i,j,k);
}
break;
}
}
}
}
} else if(sub_code == PROJECT__SAMPLE){
hm_pntr.base = Hist_base_addr;
for(i = 0; i < nTime; i++){
my_pntr.i4[i] = 0;
}
for(i = x_lo; i < x_lo + nx; i++){
for(j = y_lo; j < y_lo + ny; j++){
dataPtr = j*psdXSize*nTime + i*nTime;
for(k = 0; k < nTime; k++){
my_pntr.i4[k] += hm_pntr.i4[dataPtr +k];
}
}
}
}
break;
default:
}
@@ -2535,11 +2574,13 @@
rply_bf->u.project.cnts_lo = htonl (Cnts_lo);
rply_bf->u.project.cnts_hi = htonl (Cnts_hi);
if (rply_bf->bigend != 0x12345678) { /* If byte swapping needed, ...
** .. then swap them! */
for (i = 0; i < my_nbins; i++) my_pntr.i4[i] = htonl (my_pntr.i4[i]);
}
is = rply_status_setup_and_send (rw_skt, rply_bf, KER__SUCCESS, 0, NULL);
bytes_to_go = my_nbins * sizeof (uint);