Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

daq_bin2dump.c

Go to the documentation of this file.
00001 
00002 #include <stdio.h>
00003 /* #include <getopt.h> seems to be part of <unistd.h> */
00004 #include <unistd.h>
00005 /* stdlib.h:  malloc and atoi */
00006 #include <stdlib.h>
00007 /* string.h: strrchr */
00008 #include <string.h>
00009 
00010 #include "OnlineUtil/msgLogLib/msgLog.h"
00011 
00012 /* timeval etc */
00013 #include <time.h>
00014 #include <sys/time.h>
00015 
00016 #include "OnlineUtil/rototalk.h"
00017 #include "OnlineUtil/rdChecksum.h"
00018 
00019 /* forward declarations */
00020 int dump_whole_file(const char* fname, long* buffer, int bsize, 
00021                     int mxrec, int nooutrec);
00022 int dump_one_record(const char* fname, int nrecord, long* buffer,
00023                     int nbytes, char* time_buff);
00024 const char* blockname(int rbid, int *blkisheader);
00025 
00026 /* (default) maximum buffer size for raw records (in bytes) */
00027 #define MAXBUFFER 8388608
00028 
00029 /* subset of RunControl's MinosOnlineEntities */
00030 enum MinosOnlineEntities {
00031    MINOS_DCP = 0x63,
00032    MINOS_DCS = 0x64,
00033    MINOS_ROOTER = 0x66,
00034    MINOS_UNIDENTIFIED_CLIENT = 0x79
00035 };
00036 
00037 /*
00038  *=========================================================================
00039  * main(int argc, char **argv)
00040  * 
00041  * Purpose:
00042  *    Dump a series of binary file of DAQ records
00043  *
00044  *   usage: daq_bin2roto -i<hostname> -b<buffer size> 
00045  *           -w<whoami> -p<port #> 
00046  *           -c"autosave_configstring" -C"compress_configstring" <filenames..>
00047  *
00048  *     -b: buffer size to use
00049  *     -v: how verbose to be
00050  *     -n: maximum number of records from each file
00051  *     -N: don't print the first N records
00052  *     -h: print this message
00053  *
00054  * Return Value:
00055  *    non-zero indicates there was an error
00056  *=========================================================================
00057  */
00058 int main(int argc, char **argv)
00059 {
00060 
00061    /* this is C ... all declarations must come first */
00062    int bsize = MAXBUFFER;
00063    long* buffer = 0;
00064    int nerr = 0;
00065    int mxrec = 0;
00066    int nooutrec = 0;
00067    int whoami = 0xFF;
00068    int echoMsgLog = 0;
00069    int copt;
00070 
00071    /*
00072     * parse the options and filenames
00073     * -i and -p take args
00074     */
00075    while ((copt = getopt(argc, argv, "b:ev:n:N:h")) != EOF) {
00076       switch (copt) {
00077       case 'b':  /* buffer size */
00078          bsize = atoi(optarg);
00079          break;
00080       case 'e':  /* msgLog messages to stdout as well */
00081          echoMsgLog = 1;
00082          break;
00083       case 'v':  /* verbosity */
00084          roto_verbose = atoi(optarg);
00085          break;
00086       case 'n':  /* maximum number of records */
00087          mxrec = atoi(optarg);
00088          break;
00089       case 'N':  /* maximum number of records */
00090          nooutrec = atoi(optarg);
00091          break;
00092       case 'h':  /* help */
00093          printf(" usage: %s -i<hostname> -b<buffer size> -w<whoami> -p<port #> <filenames..>\n", argv[0]);
00094          printf("   -b: buffer size to use\n");
00095          printf("   -v: how verbose to be\n");
00096          printf("   -n: maximum number of records from each file\n");
00097          printf("   -N: don't output first N records\n");
00098          printf("   -h: print this message\n");
00099          exit(1);
00100       default:
00101          printf(" unrecognized option '%c' ignored\n",(char)optopt);
00102          break;
00103       }
00104    }
00105 
00106    msgLogInit(argv[0]);
00107    msgLogNodeIdSet(whoami);
00108    msgLogLocalEchoSet(echoMsgLog);
00109    logDebugLevelSet(3);
00110    /* logNotice("starting %s",argv[0]); */
00111 
00112    /* allocate a buffer to use */
00113    buffer = (long*) malloc(bsize);
00114    if (!buffer) {
00115       printf("failed to allocate buffer of size %d\n",bsize);
00116       exit(1);
00117    }
00118    if (roto_verbose>1) printf("allocated buffer of size %d\n",bsize);
00119 
00120    /* process each file in turn */
00121    while (optind < argc) {
00122       nerr += dump_whole_file(argv[optind++],buffer,bsize,mxrec,nooutrec);
00123    }   
00124 
00125    /* set my buffer free */
00126    free(buffer);
00127 
00128    /* logNotice("stopping %s",argv[0]); */
00129    msgLogCleanup();
00130 
00131    exit(nerr);
00132 }
00133 
00134 /*
00135  *=========================================================================
00136  * dump_whole_file(const char* fname, long* buffer, int bsize, 
00137  *                 int mxrec, int nooutrec) 
00138  * 
00139  * Purpose:
00140  *    Dump a file of records
00141  *
00142  * Arguments:
00143  *    fname:    file name
00144  *    buffer:   ptr to pre-allocated buffer
00145  *    bsize:    buffer size
00146  *    mxrec:    maximum number of records to send (0=all)
00147  *    nooutrec: don't output first "nooutrec" records
00148  *
00149  * Return Value:
00150  *    non-zero indicates there was an error
00151  *=========================================================================
00152  */
00153 int dump_whole_file(const char* fname, long* buffer, int bsize, 
00154                     int mxrec, int nooutrec) 
00155 {
00156 
00157    FILE* file;
00158    long  size;
00159    int   nRecords=0;
00160    int   nbytes;
00161    char  time_first[100];
00162    char  time_last[100];
00163    char  *time_buff = time_first;
00164 
00165    int nerr = 0;
00166 
00167    nerr = 0;
00168 
00169    file=fopen(fname,"rb");
00170    if (file==NULL) {
00171       printf("Failed to open input file: '%s'\n",fname);
00172       return 1;
00173    }
00174 
00175 /*
00176  * NB These binary files are a temporary measure
00177  *    ROOT files will replace them soon
00178  *
00179  * Format is
00180  * [#bytes in record] [record data]
00181  * [#bytes in record] [record data]
00182  * and so on
00183  *
00184  * The record data contains the 'data' DAQ blocks
00185  * : TP singles summary
00186  * : Snarl header
00187  * : Crate Readout
00188  * - identify them by their block ID. 
00189  *
00190  * You may find others that are of no interest so branch on block ID
00191  *
00192  * See http://hepunx.rl.ac.uk/minos/daq/data-format/blocks/tp-singles.html
00193  * See http://hepunx.rl.ac.uk/minos/daq/data-format/blocks/snarl-header.html
00194  * See http://hepunx.rl.ac.uk/minos/daq/data-format/blocks/crate-readout.html
00195  *
00196  */
00197 
00198    while(!feof(file)){
00199       if (mxrec>0 && nRecords==mxrec) break;
00200       if (fread(&size,sizeof(long),1,file)==1) {
00201          nRecords++;
00202          nbytes = size-sizeof(long);  /* byte count is inclusive */
00203          if (nbytes>bsize) {
00204             printf("Record %d Size %d bytes too large for buffer (%d)\n",
00205                    nRecords,nbytes,bsize);
00206             printf("Skip the rest of '%s'\n",fname);
00207             break;
00208          }
00209 #ifdef OLDDUMPALL
00210          printf("Record %d Size = %ld bytes (0x%03lx words follow)\n",
00211                 nRecords,size,(size-sizeof(long))/sizeof(long));
00212 #endif
00213          if (fread(buffer,nbytes,1,file)==1) {
00214            if ( nRecords>nooutrec || nRecords==1 ) 
00215              nerr += dump_one_record(fname,nRecords,buffer,nbytes,time_buff);
00216            time_buff = time_last;
00217 #ifdef OLDDUMPALL
00218          /* this is the old "dump" code */
00219             for (i=0;i<(size-4)/sizeof(int);i++) {
00220                printf("0x%03x: 0x%08lx\n",i,buffer[i]);
00221             }
00222 #endif
00223          }
00224          else {
00225            printf("Failed to read record %d size %ld bytes\n",
00226                   nRecords,size);
00227            nerr++;
00228          }
00229       }
00230    }
00231 
00232    /* done: */
00233    fclose(file);
00234 
00235    printf("first time seen: %s\n",time_first);
00236    printf("last  time seen: %s (%d records)\n",time_last,nRecords);
00237 
00238    return nerr;
00239 }
00240 
00241 /*
00242  *=========================================================================
00243  * dump_one_record(const char* fname, int nrecord, long* buffer, int nbytes,
00244  *                 char* time_buff)
00245  * 
00246  * Purpose:
00247  *    Dump a record
00248  *
00249  * Arguments:
00250  *    fname:      file name
00251  *    nrecord:    record # in file
00252  *    buffer:     ptr to pre-allocated buffer
00253  *    nbytes:     record size in bytes
00254  *    time_buff: char buffer for formatted time of record
00255  *    
00256  *
00257  * Return Value:
00258  *    non-zero indicates there was an error
00259  *=========================================================================
00260  */
00261 int dump_one_record(const char* fname, int nrecord, long* buffer, 
00262                     int nbytes, char* time_buff)
00263 {
00264   int nlong = nbytes/sizeof(long);
00265   int i, inblk, blksiz, nblk;
00266   int blkisheader, subrun, runtype, xsumdiff = 0;
00267 
00268   time_t sec;
00269   struct tm *ptm;
00270   const char* ISO8601Z = "%Y-%m-%d %H:%M:%SZ";
00271   char fmttime[100];
00272   unsigned long xsumcalc = 0;
00273   const long* blkstart = 0;
00274 
00275   printf("Record %d in file %s - data %d bytes (%d long words)\n",
00276          nrecord,fname,nbytes,nlong);
00277 
00278   nblk = blksiz = inblk = i = -1;
00279 
00280   while ( 1 ) {
00281     i++;
00282     if (i == nlong ) break;
00283 
00284     inblk++;
00285     printf("0x%04x: 0x%08lx",i,buffer[i]);
00286     
00287     if (inblk == blksiz) inblk = 0;
00288     
00289     if (inblk == 0) {
00290       /* start of new block */
00291       nblk++;
00292       blksiz = buffer[i];
00293       printf(" size %d (start of block %d)",blksiz,nblk);
00294       blkstart = buffer + i;
00295       /* note rdxsum_test returns non-zero if there was a mismatch */
00296       xsumdiff = rdxsum_test(buffer+i);
00297       xsumcalc = rdxsum_calc(blkstart,(blkstart[1]>>30)&0x3);
00298     }
00299     else if (inblk == 1) {
00300       printf(" checksum %s",((xsumdiff)?"failed":"ok"));
00301       if (xsumdiff) printf(", calc 0x%08lx",xsumcalc);
00302     }
00303     else if (inblk == 2) {
00304       printf(" blockid %s",blockname(buffer[i],&blkisheader));
00305     }
00306     else if (blkisheader) {
00307       if      (inblk == 3) printf(" run %ld",buffer[i]);
00308       else if (inblk == 4) {
00309         subrun  = (buffer[i]>>16) & 0xFFFF;
00310         runtype =  buffer[i]      & 0xFFFF;
00311         printf(" subrun %d runtype %d",subrun,runtype);
00312         
00313       }
00314       else if (inblk == 5) {
00315         sec = buffer[i];
00316         ptm = gmtime(&sec);
00317         strftime(fmttime,sizeof(fmttime),ISO8601Z,ptm);
00318         printf(" %s",fmttime);
00319         sprintf(time_buff," %s 0.%9.9lds",fmttime,buffer[i+1]);
00320       }
00321       else if (inblk == 6) printf(" 0.%9.9lds",buffer[i]);
00322     }
00323 
00324     printf("\n");
00325       
00326   } /* while still within record length */
00327 
00328   return 0;
00329 }
00330 
00331 /*
00332  *=========================================================================
00333  * blockname(int rbid, int *blkisheader)
00334  * 
00335  * Purpose:
00336  *    Return a formatted string identifying the block
00337  *
00338  * Arguments:
00339  *    rbid:         the encoded raw block id
00340  *    blkisheader:  set true if block is a header block
00341  *
00342  * Return Value:
00343  *    pointer to the string
00344  *=========================================================================
00345  */
00346 char blkname[1000];
00347 const char* blockname(int rbid, int *blkisheader)
00348 {
00349   int minor  =  rbid      & 0xFF;
00350   int major  = (rbid>> 8) & 0xFFFF;
00351   int daqdcs = (rbid>>24) & 1;
00352   int det    = (rbid>>25) & 0x7;
00353   int cmpsim = (rbid>>28) & 0x3;
00354 
00355   const char* majorname = "UnknownBlock";
00356   const char* isdcs     = "DAQ";
00357   const char* detname   = "?Det";
00358   const char* sfname    = "?Data";
00359 
00360   *blkisheader = 0;
00361 
00362   if (!daqdcs) {
00363     isdcs = "DAQ";
00364     switch (major) {
00365     case 0x101: majorname = "SnarlHeader"; *blkisheader = 1; break;
00366     case 0x102: majorname = "CrateReadout"; break;
00367     case 0x103: majorname = "TdcRaw"; break;
00368     case 0x104: majorname = "TofReadout"; break;
00369       
00370     case 0x200: majorname = "MonitorHeader"; *blkisheader = 1; break;
00371     case 0x201: majorname = "PedestalTable"; break;
00372     case 0x202: majorname = "ChargeInjectInfo"; break;
00373     case 0x203: majorname = "VarcErrorInTf"; break;
00374     case 0x204: majorname = "SparsifierTable"; break;
00375     case 0x205: majorname = "CrateMonitor"; break;
00376     case 0x206: majorname = "TrcMonitor"; break;
00377     case 0x207: majorname = "VaTimingMonitor"; break;
00378     case 0x208: majorname = "SpillServerMonitor"; break;
00379       
00380     case 0x301: majorname = "TpSummarySingles"; break;
00381     case 0x302: majorname = "LiSummaryAdc"; break;
00382     case 0x303: majorname = "LiSummaryTiming"; break;
00383     case 0x304: majorname = "DaqDadTime"; break;
00384     case 0x305: majorname = "LiTpmtDigits"; break;
00385       
00386     case 0x401: majorname = "RunStart"; break;
00387     case 0x402: majorname = "RunEnd"; break;
00388     case 0x403: majorname = "RunComment"; break;
00389     case 0x404: majorname = "TriggerStats"; break;
00390     case 0x405: majorname = "ErrorStats"; break;
00391     case 0x406: majorname = "SubRunEnd"; break;
00392       
00393     case 0x501: majorname = "ConfigRunPrepare"; break;
00394     case 0x502: majorname = "ConfigFiles"; break;
00395       
00396     case 0x601: majorname = "QieData"; break;
00397     case 0x602: majorname = "LinearizedData"; break;
00398     case 0x603: majorname = "QieCalibrationData"; break;
00399     case 0x604: majorname = "CurrentInjectData"; break;
00400     case 0x605: majorname = "CalibrationFits"; break;
00401     case 0x606: majorname = "NDErrorBlock"; break;
00402     case 0x607: majorname = "VtmTimeInfo"; break;
00403     case 0x608: majorname = "LookUpTable"; break;
00404       
00405     case 0xf00: majorname = "VaDeadChips"; break;
00406     case 0xf01: majorname = "VaOvershoot"; break;
00407     }
00408   }
00409   else {
00410     isdcs = "DCS";
00411     switch (major) {
00412     case 0x001: majorname = "DcsHeader"; *blkisheader = 1; break;
00413 
00414     case 0x100: majorname = "DcsAlarm"; break;
00415     case 0x200: majorname = "DcsMonitor"; break;
00416 
00417     case 0x201: majorname = "DcsHvMonitor"; break;
00418     case 0x202: majorname = "DcsRpsMonitor"; break;
00419     case 0x203: majorname = "DcsMagnetMonitor"; break;
00420     case 0x204: majorname = "DcsEnvMonitor"; break;
00421     case 0x205: majorname = "DcsChillerMonitor"; break;
00422     case 0x206: majorname = "DcsUpsMonitor"; break;
00423     case 0x207: majorname = "DcsCanMonitor"; break;
00424 
00425     case 0x310: majorname = "BeamMonHeader"; *blkisheader = 1; break;
00426     case 0x311: majorname = "BeamMonPayload"; break;
00427     }
00428   }
00429   
00430   switch (det) {
00431   case 1: detname = "Near"; break;
00432   case 2: detname = "Far"; break;
00433   case 4: detname = "CalDet"; break;
00434   }
00435 
00436   switch (cmpsim) {
00437   case 0: sfname = "Data"; break;
00438   case 1: sfname = "DaqFakeData"; break;
00439   case 2: sfname = "MC"; break;
00440   case 3: sfname = "Reroot"; break;
00441   }
00442 
00443   sprintf(blkname,"%3s:%s;%3.3d(%s+%s)",isdcs,majorname,minor,detname,sfname);
00444 
00445   return blkname;
00446 }

Generated on Mon Feb 15 11:06:33 2010 for loon by  doxygen 1.3.9.1