/*************************************************************************** incub8r3: Replay program for compressed triple coincidence cubes. Allows use of non-linear gains through look-up tables to convert gain-matched ADC outputs to cube channels. Uses disk buffering to .scr "scratch" file. This version for 1/6 cubes. D.C Radford Sept 1997 ****************************************************************************/ #include #include #include #include #ifdef VMS #include #else /* #include */ #endif #include #include #include #include #include #include #include #include "incub8r3.h" #include "rwutils.c" #define VERSION "23 Sept 1997 Beta" /* Some global data */ struct GlobalData { FILE *CubeFile; FILE *ScrFile; FILE *LogFile; char CubeFileName[256]; int ScrSize, RecordSize; char TapeDev[256]; int SwapTapeBytes; int length; /* length of axis on cube */ int nummc; /* number of minicubes */ int numscr; /* number of records written to scrfile */ int adcmax; int numrecs; /* current number of records in cube file */ int gotsignal; /* a signal was caught by signal handler */ } gd; int dbinfo[10]; /* lookup table stuff */ char *tbuf; /* tape buffer */ short luch[16384]; /* look-up table, maps ADC channels to cube channels */ int lumx[RW_MAXCH]; /* look-up table, maps 3d ch to linear minicube */ int lumy[RW_MAXCH]; int lumz[RW_MAXCH]; /* look up minicube addr */ #define LUMC(x,y,z) lumx[x] + lumy[y] + lumz[z] /* look up addr in minicube */ #define LUIMC(x,y,z) (x&7) + ((y&7)<<3) + ((z&3)<<6) /* increment buffers */ unsigned short buf1[RW_LB1][RW_DB1]; unsigned short buf2[RW_LB2][RW_DB2][RW_DB1+1]; int nbuf1[RW_LB1]; /* number in each row of buf1 */ int nbuf2[RW_LB2]; /* number in each row of buf2 */ int scrptr[RW_LB2]; /* last record # written to scr file */ /* for each row of buf2 */ #define MCLEN(mcptr) (mcptr[0] + (mcptr[0] >= 7*32 ? mcptr[1]*32+2 : 1)) FILE *open_3cube (char *name, int length, FILE *mesg); FILE *open_scr (char *name, int length, FILE *mesg); /*************************************************************************** setup_replay: reads in data file that describes cube, opens and initializes cube, scr and log */ void setup_replay(void) { FILE *file; char cbuf[256], dnam[256], title[256], tnam[256], snam[256], cnam[256]; char lnam[256], recs[256], scrs[256], stb[256]; char *c; int nclook, lmin, lmax, i, ovrtprompt = 1; printf("\n\n" " Incub8r3: A replay program for compressed-format RadWare\n" " triple-coincidence cubes.\n" " Allows use of non-linear gains through look-up tables\n" " to convert gain-matched ADC outputs to cube channels.\n" " Uses disk buffering to .scr scratch file.\n" " This version for 1/6 cubes.\n\n" " Author D.C Radford Sept 1997\n\n" " Version "VERSION"\n\n"); if ((c=getenv("RADWARE_OVERWRITE_FILE")) && (*c == 'y' || *c == 'Y')) ovrtprompt = 0; while (1) { /* while data(inc) file is valid */ /* First read in the data file */ printf("Enter replay data file name (%s): ",RW_DATFILE); if (!fgets(dnam, 250, stdin)) continue; dnam[strlen(dnam)-1] = 0; /* remove \n */ if (dnam[0] == 0) { strncpy(dnam, RW_DATFILE, 256); } setfnamext(dnam,".inc",0); if (!(file = fopen(dnam,"r"))) { printf("\007 ERROR: cannot open file %s\n",dnam); continue; } #define GETDATA(a,b) \ fgets(a, 256, file);\ if (a[0] == 0) {\ printf("\007 ERROR -- reading %s.\n",b);\ fclose(file);\ continue;\ }\ a[strlen(a)-1] = 0; /* remove trailing \n */ \ while (a[0] == ' ') memmove(a, a+1, strlen(a)); /* remove leading spaces */ \ for(c=a+strlen(a)-1;*c==' ';c--) *c=0; /* remove trailing spaces */ GETDATA(title,"title"); GETDATA(tnam, "tape drive"); GETDATA(snam, "scratch file name"); GETDATA(cnam, "cube file name"); GETDATA(lnam, "look-up table file name"); GETDATA(recs, "record blocksize"); GETDATA(scrs, "scratch file size"); GETDATA(stb, "swap bytes from tape"); #undef GETDATA fclose(file); if (stb[0] == 'y' || stb[0] == 'Y') { strcpy(stb,"y"); gd.SwapTapeBytes = 1; } else { strcpy(stb,"n"); gd.SwapTapeBytes = 0; } printf("\n Replay data file name = %s\n" " Tape drive = %s\n" " Scratch file name = %s\n" " Cube file name = %s\n" " Look-up table file name = %s\n" " Record BlockSize (Bytes) = %s\n" " Scratch File Size (MBytes) = %s\n" " Swap Bytes from Tape (y/n) = %s\n\n", dnam,tnam,snam,cnam,lnam,recs,scrs,stb); printf("Are these values correct? (N/Y) "); fgets(cbuf,256,stdin); if (cbuf[0] != 'y' && cbuf[0] != 'Y') continue; strcpy(gd.TapeDev, tnam); /* test values */ gd.RecordSize = strtol(recs, NULL, 0); if (gd.RecordSize < 512) { printf("\007 ERROR -- record blocksize too small.\n"); continue; } gd.ScrSize = strtol(scrs, NULL, 0); if (gd.ScrSize < 1) { printf("\007 ERROR -- scratch file size too small.\n"); continue; } strcpy(tnam,cnam); setfnamext(tnam,".log",1); while (1) { if ((gd.LogFile=fopen(tnam,"r"))) { fclose(gd.LogFile); if (ovrtprompt) { printf(" WARNING: Log file (%s) already exists\n",tnam); printf(" Enter new name or to overwrite: "); if (fgets(cbuf,256,stdin) && cbuf[0] != '\n') { cbuf[strlen(cbuf)-1]=0; strcpy(tnam,cbuf); setfnamext(tnam,".log",0); continue; } } else printf(" Overwriting Log file (%s).\n",tnam); } if (!(gd.LogFile=fopen(tnam,"w"))) { printf("\007 ERROR -- Could not open %s for writing.\n",tnam); printf(" Enter new log file name: "); if (fgets(cbuf,256,stdin) && cbuf[0] != '\n') { strncpy(tnam,cbuf,strlen(cbuf)-1); setfnamext(tnam,".log",0); continue; } } break; } /* read in lookup table */ if (read_tab(lnam,&nclook,&lmin,&lmax,luch)) { fclose(gd.LogFile); continue; } gd.adcmax = nclook; printf("\nNo. of values in lookup table = %d\n",lmax); if (lmax > RW_MAXCH) { printf("\007 ERROR -- number of values in lookup file is too" "large (max = %d).\n",RW_MAXCH); fclose(gd.LogFile); continue; } gd.length = lmax; /* Inform the log file */ fprintf(gd.LogFile,"Replay log for program Incub8r3, %s\n\n",datim()); fprintf(gd.LogFile,"\n Replay data file name = %s\n" " Tape drive = %s\n" " Scratch file name = %s\n" " Cube file name = %s\n" " Look-up table file name = %s\n" " Record BlockSize (Bytes) = %s\n" " Scratch File Size (MBytes) = %s\n" " Swap Bytes from Tape (y/n) = %s\n\n", dnam,gd.TapeDev,snam,cnam,lnam,recs,scrs,stb); fprintf(gd.LogFile," No. of values in lookup table = %d\n\n",lmax); fprintf(gd.LogFile,"-------------------------------------------\n\n"); /* calculate look-up tables to convert (x,y,z) cube address to linearized minicube address. xgd.nummc-1) maxmc = gd.nummc - 1; dbinfo[0]=11; dbinfo[2]=0; dbinfo[3]=0; printf("\r ...chunk %d, recs %d %d ",chunknum,recnumIn,recnumOut); fflush(stdout); /* loop through all the minicubes in the chunk */ for (mc=minmc; mc<=maxmc; mc++) { dbinfo[2]=mc; if (mc > recIn.h.minmc + recIn.h.nummc - 1) { /* next compressed minicube starts in the next input record */ if (!fread (&recIn, 4096, 1, gd.CubeFile)) { printf("\007 ERROR -- Corrupted cube, aborting...\n"); exit(-1); } recnumIn++; mcptrIn = recIn.d + recIn.h.offset - 8; /* at this point our minicube should be at the start of the record */ if (recIn.h.minmc != mc) { printf("Severe ERROR 1 - fatal!\n PLEASE send a bug report" " to radfordd@mail.phy,ornl.gov with this information\n" " and a copy of your get_event.c and incub8r3.h.\n"); printf("rec: %d mc: %d should be %d\n", recnumIn, mc, recIn.h.minmc); exit(-1); } } else if (mcptrIn > recIn.d + 4088 ) { printf("Severe ERROR 2 - fatal!\n PLEASE send a bug report" " to radfordd@mail.phy,ornl.gov with this information\n" " and a copy of your get_event.c and incub8r3.h.\n"); printf("rec: %d mc: %d should be > %d\n", recnumIn, mc, recIn.h.minmc + recIn.h.nummc - 1); exit(-1); } mcl=MCLEN(mcptrIn); if (mcptrIn + mcl > recIn.d + 4088 ) { /* compressed minicube spills over into the next input record */ nbytes = mcptrIn + mcl - (recIn.d + 4088); memcpy (cbuf, mcptrIn, mcl-nbytes); if (!fread (&recIn, 4096, 1, gd.CubeFile)) { printf("\007 ERROR -- Corrupted cube, aborting...\n"); exit(-1); } if (nbytes != (recIn.h.offset-8)) { printf("Severe ERROR 3 - fatal!\n PLEASE send a bug report" " to radfordd@mail.phy,ornl.gov with this information\n" " and a copy of your get_event.c and incub8r3.h.\n"); printf("rec, offset, nbytes, mcl, mcptr: %d %d %d %d %ld\n" "mc minmc nummc: %d %d %d\n", recnumIn+1, recIn.h.offset, nbytes ,mcl, (long int) (mcptrIn-recIn.d+8), mc, recIn.h.minmc, recIn.h.nummc); exit(-1); } if (recIn.h.minmc != mc+1) { printf("Severe ERROR 4 - fatal!\n PLEASE send a bug report" " to radfordd@mail.phy,ornl.gov with this information\n" " and a copy of your get_event.c and incub8r3.h.\n"); printf("rec: %d mc: %d should be %d\n", recnumIn+1, mc+1, recIn.h.minmc); exit(-1); } recnumIn++; memcpy (&cbuf[mcl-nbytes], recIn.d, nbytes); decompress3d (cbuf, &chunk[(mc-minmc)<<8]); mcptrIn = recIn.d + recIn.h.offset - 8; } else { decompress3d (mcptrIn, &chunk[(mc-minmc)<<8]); mcptrIn += mcl; } } /* increment the chunk from the buffers */ addr8b = chunknum; /* first empty the corresponding parts of buf1 */ dbinfo[0]=12; dbinfo[2]=0; dbinfo[3]=0; for (addr13b=addr8b*RW_CHNK_S; addr13b<(addr8b+1)*RW_CHNK_S; addr13b++) { addr21b = (addr13b - addr8b*RW_CHNK_S)<<16; for (j=0; j0) { fseek(gd.ScrFile, ((long)scrptr[addr8b]-1)*RW_SCR_RECL, SEEK_SET); if (!fread(inbuf, RW_SCR_RECL, 1, gd.ScrFile)) { fprintf(stderr,"\007 ERROR -- Could not read scr file.. fatal.\n"); exit(-1); } for (j=0; j recOut.d + 4088) { /* the minicube spills over the end of the output record */ if (mcptrOut + 2 > recOut.d + 4088) { /* need at least first 2 bytes of minicube in current record */ /* so move whole minicube to next record */ recOut.h.nummc = mc - recOut.h.minmc; if (!fwrite(&recOut, 4096, 1, OutFile)) { printf("\007 ERROR -- Cannot write cube, aborting...\n"); exit(-1); } recOut.h.minmc = mc; recOut.h.offset = 8; memcpy (recOut.d, cbuf, mcl); mcptrOut = recOut.d + recOut.h.offset - 8 + mcl; } else { /* move only part of minicube to next record */ nbytes = mcptrOut + mcl - (recOut.d + 4088); memcpy (mcptrOut, cbuf, mcl-nbytes); recOut.h.nummc = mc - recOut.h.minmc + 1; if (!fwrite(&recOut, 4096, 1, OutFile)) { printf("\007 ERROR -- Cannot write cube, aborting...\n"); exit(-1); } recOut.h.minmc = mc + 1; recOut.h.offset = nbytes + 8; memcpy (recOut.d, cbuf+mcl-nbytes, nbytes); mcptrOut = recOut.d + recOut.h.offset - 8; } recnumOut++; } else { memcpy (mcptrOut, cbuf, mcl); mcptrOut += mcl; } } } /* end of loop through chunks in the file */ /* write out the last record */ dbinfo[0]=16; recOut.h.nummc = gd.nummc - recOut.h.minmc; if (!fwrite(&recOut, 4096, 1, OutFile)) { printf("\007 ERROR -- Cannot write cube, aborting...\n"); exit(-1); } recnumOut++; fseek (OutFile, 0, SEEK_SET); if (!fread (&filehead, 1024, 1, OutFile)) { printf("\007 ERROR -- Corrupted file header, aborting...\n"); exit(-1); } filehead.numrecs = recnumOut; fseek (OutFile, 0, SEEK_SET); if (!fwrite (&filehead, 1024, 1, OutFile)) { printf("\007 ERROR -- Cannot write file header, aborting...\n"); exit(-1); } fflush(OutFile); free(chunk); fclose(gd.CubeFile); gd.CubeFile = OutFile; if (rename(filname, gd.CubeFileName)) { printf("\007 ERROR -- Cannot rename file, aborting...\n"); exit(-1); } fprintf(gd.LogFile," ...Done updating cube: %s\n" " There are now %d records.\n", datim(), recnumOut); fflush(gd.LogFile); printf("\n ...Done updating cube: %s\n" " There are now %d records.\n", datim(), recnumOut); dbinfo[0]=17; } void dbuf2(int addr8b) { char outbuf[RW_SCR_RECL]; dbinfo[0]=8; dbinfo[4]=scrptr[addr8b]; dbinfo[5]=gd.numscr; memcpy(outbuf, &(buf2[addr8b][0][0]), RW_DB2*2*(RW_DB1+1)); memcpy(outbuf+RW_DB2*2*(RW_DB1+1), &(scrptr[addr8b]), 4); if (!fwrite(outbuf,RW_SCR_RECL,1,gd.ScrFile)) { fprintf(stderr,"\007 ERROR -- Could not write to scr file.. fatal.\n"); exit(-1); } gd.numscr++; scrptr[addr8b] = gd.numscr; dbinfo[0]=9; if (gd.numscr*RW_SCR_RECL >= gd.ScrSize*1024*1024) { dbinfo[0]=10; /* scr full, inc cub */ fprintf(gd.LogFile," Scratch File full...\n"); printf("\n Scratch File full...\n"); dscr(); gd.numscr = 0; rewind(gd.ScrFile); } } /*--------------------------------------------------------*/ void breakhandler(int dummy) { gd.gotsignal = 1; } /*--------------------------------------------------------*/ void segvhandler(int dummy) { char cbuf[256]; gd.gotsignal = 1; printf("\007\n ACKKK!!! Segmentation Violation!!! Debug info follows.\n" "%d %d %d %d %d %d %d %d %d %d\n", dbinfo[0],dbinfo[1],dbinfo[2],dbinfo[3],dbinfo[4], dbinfo[5],dbinfo[6],dbinfo[7],dbinfo[8],dbinfo[9]); while (1) { printf(" ... Kill? (N/Y)\n"); if (!fgets(cbuf,256,stdin)) continue; if (cbuf[0] == 'y' || cbuf[0] == 'Y') exit (1); if (cbuf[0] == 'n' || cbuf[0] == 'N') break; } } /*--------------------------------------------------------*/ void sighandler() { /* See signal(2) for details: 2 = SIGINT, 11 = SIGSEGV */ /* Maybe this'll be different on different OSs so watch out. */ signal(SIGINT, breakhandler); signal(SIGSEGV, segvhandler); gd.gotsignal = 0; } /*--------------------------------------------------------*/ #include "get_event.c" int main (int argc, char **argv) { char cbuf[512]; int maxrecords = RW_MAXRECORDS, numrecords, totnumrecords=0; int maxfiles = RW_MAXFILES, numfiles, totnumfiles=0; int numtapes; int scanning = 1; int prompt_tape = 1; int tfd=0; int mc_addr, inmc_addr, addr13b, addr16b, addr8b; int ex, ey, ez; int i,j,k,l,tmp; int elist[RW_MAXMULT], gemult; unsigned long numincr = 0, numevents = 0; int skipforward = 0; int spec[16384]; FILE *file; memset(spec,0,4096*4*4); setup_replay(); numtapes = 0; while (scanning) { /* loop through tapes */ sighandler(); /* set up signal handling */ maxfiles = 0; numfiles = 0; maxrecords = 0; numrecords = 0; skipforward = 0; if ((file=fopen("incub8r3.spn","w+"))) { fwrite(spec,4096*4,4,file); fclose(file); } while (prompt_tape) { /* Prompt to enter new tape */ printf ("\nInsert tape and press Return,\n" " S to skip forward over some data,\n" " C to change tape drives,\n" " or E to end. "); if (!fgets(cbuf,512,stdin)) continue; if (cbuf[0] == 'e' || cbuf[0] == 'E') { scanning = 0; break; } else if (cbuf[0] == 's' || cbuf[0] == 'S') skipforward = 1; else if (cbuf[0] == 'c' || cbuf[0] == 'C') { printf (" ...Enter new tape device: "); if (!fgets(cbuf,256,stdin)) continue; if (strlen(cbuf)<2) continue; cbuf[strlen(cbuf)-1] = 0; /* remove trailing \n */ while (cbuf[strlen(cbuf)-1]==' ') cbuf[strlen(cbuf)-1] = 0; /* remove trailing spaces */ if (strlen(cbuf)>2) { strcpy(gd.TapeDev, cbuf); printf (" New tape device is %s.\n", gd.TapeDev); } continue; } /* open tape device */ if ((tfd = open(gd.TapeDev, O_RDONLY, 0)) <= 0) { printf("\007 ERROR -- Could not open %s for reading.\n",gd.TapeDev); continue; } numtapes++; prompt_tape = 0; } if (!scanning) break; /* Get the maximum number of files on tape to be scanned */ while (1) { if (skipforward) printf("\nNumber of files to skip (Return for all, or E to end): "); else printf("\nNumber of files to scan (Return for all, or E to end): "); if (!fgets(cbuf,512,stdin)) continue; if (cbuf[0] == 'e' || cbuf[0] == 'E') { scanning = 0; break; } if (cbuf[0] == '\n') { maxfiles = RW_MAXFILES; break; } maxfiles = strtol(cbuf, NULL, 0); if (maxfiles < 0) { printf("\007 ERROR -- Cannot be less than 0.\n"); } else if (maxfiles == 0 && cbuf[0] != 0) { printf("\007 ERROR -- Invalid response.\n"); } else if (maxfiles == 0) { scanning = 0; } else if (maxfiles > RW_MAXFILES) { maxfiles = 0; printf("\007 ERROR -- Value too large (max = %d).\n",RW_MAXFILES); } else { break; } } if (!scanning) break; /* Get the max number of records on tape to be scanned */ while (1) { if (skipforward) printf("\nNumber of records to skip (Return for all): "); else printf("\nNumber of records to scan (Return for all): "); if (!fgets(cbuf,512,stdin)) continue; if (cbuf[0] == '\n') { maxrecords = RW_MAXRECORDS; break; } maxrecords = strtol(cbuf, NULL, 0); if (maxrecords < 0) { printf("\007 ERROR -- Cannot be less than 0.\n"); } else if (maxrecords == 0 && cbuf[0] != 0) { printf("\007 ERROR -- Invalid response.\n"); } else if (maxrecords == 0) { scanning = 0; } else if (maxrecords > RW_MAXRECORDS) { maxrecords = 0; printf("\007 ERROR -- Value too large (max = %d).\n",RW_MAXRECORDS); } else { break; } } if (!scanning) break; sprintf(cbuf,"Scan started: %s\n\n", datim()); printf("%s",cbuf); fflush(stdin); fprintf(gd.LogFile,"%s",cbuf); fflush(gd.LogFile); /* process events */ while (numrecords < maxrecords && numfiles < maxfiles) { if (gd.gotsignal) break; /* read in buffer */ dbinfo[0]=0; i = read_tape(tfd); if (i<0) { /* read returned unknown error */ printf("\007\n ERROR -- Could not read from %s.\n", gd.TapeDev); sprintf(cbuf,"End-of-Tape reached?? %s\n\n", datim()); printf("%s",cbuf); fprintf(gd.LogFile,"%s",cbuf); prompt_tape = 1; printf("Closing tape device %s...\n",gd.TapeDev); fprintf(gd.LogFile,"Closing tape device %s...\n",gd.TapeDev); if (close(tfd)) { printf("\007 Ooops, could not close tape device!\n"); fprintf(gd.LogFile," Ooops, could not close tape device!\n"); } break; } else if (i==0) { /* end of file */ /* first check to see if we are testing the program */ if (strcmp(gd.TapeDev,"/dev/null")) { /* no, we are not using a null device */ sprintf(cbuf,"End-of-File reached %s\n\n", datim()); printf("\n%s",cbuf); fprintf(gd.LogFile,"%s",cbuf); numfiles++; totnumfiles++; continue; } } else if (i= 0) { dbinfo[0]=2; dbinfo[1]=gemult; spec[8192+gemult]++; numevents++; dbinfo[8]=numevents; if (gemult < 3) continue; for (i=0; i=0) spec[elist[i]]++; } /* convert from ADC to cube channel numbers */ dbinfo[0]=3; j = 0; for (i=0; i= 0 && elist[i] < gd.adcmax && luch[elist[i]]>0) elist[j++] = luch[elist[i]]-1; } gemult = j; if (gemult < 3) continue; spec[12288+gemult]++; dbinfo[0]=4; dbinfo[1]=gemult; /* order elist */ for (i=gemult-1; i>0; i--) { if(elist[i] < elist[i-1]) { tmp=elist[i]; elist[i]=elist[i-1]; elist[i-1]=tmp; j=i; while (j elist[j+1]) { tmp=elist[j]; elist[j]=elist[j+1]; elist[j+1]=tmp; j++; } } } dbinfo[0]=5; /* loop through all possible combinations */ for(l=2;l