- 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:
@@ -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 */
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user