#include #include #include using std::cout; #include #include #include #include #include using namespace std; // ===================================================== unsigned int get_w32(const unsigned char* data) { // data decoding helper function return data[3]<<24 | data[2]<<16 | data[1]<<8 | data[0]; } //====================================================== unsigned int checkFecOn(unsigned int afla, unsigned int aflb, int fec, int verbosity) { // // check if this fec is on // unsigned int afl = (aflb<<16) | afla; if ( (afl) & (1<2) printf("FEC%02i is ON!\n", fec); return 1; } else { if (verbosity>2) printf("FEC%02i is OFF!\n", fec); return 0; } return 0; } //========================================================================================== //========================================================================================== //========================================================================================== int main(int argc, char ** argv) { // // Read a data file, analyse altro channel header information and check data // ////////////////////////////////////////////////////// ////////////////////////////////////////////////////// int32_t verbosity = 1; int32_t is_last = 0; int32_t nread = 0; int16_t hwaddr = 0; int16_t fecaddr = 0; int32_t nwords10 = 0; int32_t nwords32 = 0; int32_t samplectr = 0; int32_t samplesperbunch = 0; int pattern = 0x2AA; int ramp1 = 0; int ramp2 = 0; int nwords = 1008; int fecsA = 0x1FFF; int fecsB = 0xFFF; char ramp1ch[] = "ramp1"; char ramp2ch[] = "ramp2"; char *arg_copy = NULL; char *token = NULL; opterr = 0; int c; while ( (c = getopt (argc, argv, "v:P:n:f:")) != -1 ) { switch (c) { case 'v': verbosity = atoi(optarg); break; case 'P': if ( strcmp(optarg, ramp1ch) == 0 ) { ramp1 = 1; if (verbosity) printf("Expecting RAMP1 pattern\n"); } else if ( strcmp(optarg, ramp2ch) == 0 ) { ramp2 = 1; if (verbosity) printf("Expecting RAMP2 pattern\n"); } else { sscanf( optarg, "%i", &pattern ); if (verbosity) printf("Expecting constant pattern 0x%x\n", pattern); } break; case 'n': nwords= atoi(optarg); if (verbosity) printf("Expecting %d words in each channel\n", pattern); break; case '?': if (optopt == 'v') { fprintf (stderr, "ERROR: Option -%c requires an argument (verbosity).\n", optopt); } else if (isprint (optopt)) { fprintf (stderr, "Unknown option `-%c'.\n", optopt); } else { fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt); exit(EXIT_FAILURE); } case 'f': fecsA = 0x0; fecsB = 0x0; arg_copy = strdup(optarg); token = strtok(arg_copy, ","); do { int fec = atoi(token); if ( (0 <=fec) && (fec<=15) ) fecsA |= 1<= argc) { fprintf(stderr, "Usage: %s [-v VERBOSITY] FILENAME\n", argv[0]); exit(EXIT_FAILURE); } if ( verbosity>0 ) printf("Data file name: %s\n", argv[optind]); char *filename = argv[optind]; printf("Assuming AFL_A=0x%x, AFL_B=0x%x\n", fecsA, fecsB); // =========================================== // read DDL file // =========================================== FILE *ddlfile = fopen(filename, "rb"); if ( ddlfile == NULL ) { perror("Error opening file"); return 1; } // start reading unsigned char buffer[4096]; // event loop int evctr = 0; int phevctr = 0; bool readOK = true; do { // get size of this event int n = fread(buffer, 1, 4, ddlfile); // printf("hoge %8s",buffer); if ( n!=4 ) { readOK = false; } else { //unsigned int w32 = get_w32(&buffer[0]); unsigned int w32 = get_w32(buffer); int hsize = 20; int evtype = 0; int evsize = w32; int si10 ; int w10; int samplectr; int wordctr; int compvalue; int trailerctr = 0; int chctr[32]; for (int ii=0; ii<32; ii++) chctr[ii]=0; // loop over data for (int ii=1; ii1 ) printf("Evt%03d, header size=%d\n", evctr, hsize); } else if (ii == 4) { evtype = w32&0xff; if ( verbosity>1 ) printf("Evt%03d, event type=%d\n", evctr, evtype); } if (ii > hsize) { if (ii > hsize + 6) { if (ii == (hsize+7)) { if (evtype == 7) { if (verbosity) printf(" === Physics event %d: Nwords=%d ===\n", evctr-2, evsize/4); phevctr++; } } if (ii < hsize + 6 + 12) { // Why CDH has 11 words???? if ( verbosity>1 ) printf("Evt%03d, word%d, CDH 0x%08x\n", evctr, ii, w32); if ( ii == (hsize + 6 + 1)) { if ( w32 != 0xFFFFFFFF ) printf("Error in Evnt %d: CDH word00 is 0x%x (expect 0xFFFFFFFF)\n", evctr, w32); } if ( ii == (hsize + 6 + 2)) { if ( (w32>>24) != 0x3 ) printf("Error in Evnt %d: CDH word01 is 0x%x. Format version is 0x%x (expect 3)\n", evctr, w32, w32>>24); if ( (w32>>22)&0x3 != 0x0 ) printf("Error in Evnt %d, CDH word01 is 0x%x. MBZ field is 0x%x\n", evctr, w32, (w32>>22)&0x3); if ( (w32>>12)&0x3 != 0x0 ) printf("Error in Evnt %d, CDH word01 is 0x%x. MBZ field is 0x%x\n", evctr, w32, (w32>>12)&0x3); } if ( ii == (hsize + 6 + 5)) { if ( (w32>>12) != 0x0 ) printf("Warning in Evnt %d: CDH word04 is 0x%x. Status and Error bits are set: 0x%x!\n", evctr, w32, w32>>12); } if ( ii == (hsize + 6 + 9)) { if ( (w32>>4)&0xFFFFFF != 0x0 ) printf("Error in Evnt %d, CDH word08 is 0x%x. MBZ field is 0x%x\n", evctr, w32, (w32>>4)&0xFFFFFF); } } else { if ( verbosity>3 ) printf("Evt%03d, word%d, payload 0x%x\n", evctr, ii, w32); // // check data here // switch(w32>>30){ case 0x0: wordctr++; for (int n10w=0; n10w<3; ++n10w){ si10 = (2-n10w%3) * 10; w10 = (w32>>si10) & 0x3ff; if(samplectr==0){ // first 10bit word in a bunch: Bunch length if(verbosity>3) printf("Sample %d :: 0x%x (bunch length)\n", samplectr, w10); if ( w10 != nwords10) printf("Error in Evnt %d, hwaddr 0x%x: Bunch length (%d) != Number of words in header (%d)\n", evctr, hwaddr, w10, nwords10); samplectr++; } else if(samplectr==1){ // second word in a bunch: Time bin if(verbosity>3) printf("sample %d :: 0x%x (time bin)\n", samplectr, w10); samplectr++; } else { //if(verbosity>2) printf("sample %d :: 0x%x\n", samplectr, w10); if ( ramp1 ) { if ( w10 == (nwords-samplectr+1) ) { if(verbosity>4) printf(" ==> Sample %d :: 0x%x (payload is correct)\n", samplectr, w10); } else { printf("Error in Evt%03d, hwaddr 0x%x: Wrong value in word %d: 0x%x (expect 0x%x)\n", evctr, hwaddr, ii, w10, (nwords-samplectr+1)); } } else if ( ramp2 ) { if ( w10 == (0x3FF-nwords+samplectr-1) ) { if(verbosity>4) printf(" ==> Sample %d :: 0x%x (payload is correct)\n", samplectr, w10); } else { printf("Error in Evt%03d, hwaddr 0x%x: Wrong value in word %d: 0x%x (expect 0x%x)\n", evctr, hwaddr, ii, w10, (0x3FF-nwords+samplectr-1)); } } else { if ( w10 == pattern ) { if(verbosity>4) printf(" ==> Sample %d :: 0x%x (payload is correct)\n", samplectr, w10); } else { printf("Error in Evt%03d, hwaddr 0x%x: Wrong value in word %d: 0x%x (expect 0x%x)\n", evctr, hwaddr, ii, w10, pattern); } } // CHeck padding if ( samplectr > nwords10 ) { if ( samplectr < nwords32*3 ) { if ( w10 != 0 ) { printf("Error in Evt%03d, hwaddr 0x%x: 10bit padding words should be 0 (found 0x%x)\n", evctr, hwaddr, w10); } } printf("Error in Evt%03d, hwaddr 0x%x, word %d: Too many 10bit words for this channel (%d, should be %d)\n", evctr, hwaddr, ii, samplectr, nwords10); } samplectr++; } } break; case 0x1: //channel header // // This is a ALTRO CHANNEL HEADER // // Decode a header word hwaddr = w32&0xfff; // AltroChannelAddress(Hardwawre addres:HWA) fecaddr = hwaddr>>7; // FEC address (5 bit, including branch bit) nwords10 = w32>>16&0x3ff; // The Number of 10-bit words in payload nwords32 = (nwords10+2)/3; wordctr = 0; if ( !checkFecOn(fecsA, fecsB, fecaddr, verbosity) ) if (verbosity>1) printf("Error in Evt%03d: FEC%02d was not read, but there is data!\n", evctr, fecaddr); chctr[fecaddr]++; if ( verbosity>2 ) printf("Hwaddr 0x%03x :: N32=%02d, N10=%02d\n", hwaddr, nwords32, nwords10); if ( (nwords10-2) != nwords ) printf("Error in Evt%03d, Wrong number of 10 bit words: %d (expected %d)\n", evctr, nwords10, nwords); samplectr=0;; break; case 0x2: if ( verbosity>1 ) printf("Evt%03d, RCU trailer word %d: 0x%08x\n", evctr, trailerctr, w32); trailerctr++; break; case 0x3: if (trailerctr != 8) printf("Error in Evt%03d, unexpected LAST RCU trailer word: 0x%x (have seen %d trailer words)\n", evctr, w32, trailerctr); if ( verbosity>1 ) printf("Evt%03d, Last RCU trailer word: 0x%08x\n", evctr, w32); trailerctr++; break; } } } else { if ( verbosity>2 ) printf("Evt%03d, word%d, DATE words 0x%08x\n", evctr, ii, w32); } } else { if ( verbosity>2 ) printf("Evt%03d, word%d: 0x%08x\n", evctr, ii, w32); } } } // check number of channels per FEC received if (evtype == 7) { for (int ii=0; ii<32; ii++) { if ( checkFecOn(fecsA, fecsB, ii, verbosity) ) { if ( chctr[ii] == 0 ) printf("Error in Evt%03d: No data from FEC%02d received, but card was ON !!!!!\n", evctr, ii); else if ( chctr[ii] != 128 ) printf("Error in Evt%03d: Wrong number of channels in FEC%02d: %d != 128 header found\n", evctr, ii, chctr[ii]); } else { // Card should be off if ( chctr[ii] > 0 ) printf("Error in Evt%03d: Data from FEC%02d received, but card was OFF !!!!!\n", evctr, ii); } } } evctr++; trailerctr = 0; } // end check read } while ( readOK ); if ( verbosity>0 ) printf("Finished reading %d physics events\n", phevctr); /* // CDH for (int ii=0; ii<8; ++ii) { unsigned int w32 = get_w32(&buffer[ii*4]); if ( ii==1 ) { if ( verbosity>0 ) printf("CDH word %d: 0x%08x (%fs)\n", ii, w32, (w32&0xfff)/3564.*88e-6); } else if ( ii==2 ) { if ( verbosity>0 ) printf("CDH word %d: 0x%08x (%fs)\n", ii, w32, (w32&0xffffff)*88e-6); } else if ( verbosity>0 ) printf("CDH word %d: 0x%08x\n", ii, w32); } // The LOOP on the data file do { n = fread(buffer, 1, 4, ddlfile); uint32_t w32 = get_w32(buffer); if ( n!=4 ) { cerr << "Error: reading of payload header word failed." << endl; exit(EXIT_FAILURE); } switch (w32>>30) { case 0x0: fprintf(stderr, "Warning: expected channel header or RCU trailer but received 0x%08x. Continuing ...\n", w32); //exit(EXIT_FAILURE); break; case 0x1: // // This is a ALTRO CHANNEL HEADER // // Decode a header word hwaddr = w32&0xfff; nwords10 = w32>>16&0x3ff; nwords32 = (nwords10+2)/3; // Dump this header if ( verbosity>1 ) printf("Hwaddr 0x%03x :: N32=%02d, N10=%02d\n", hwaddr, nwords32, nwords10); // Now read the actual data from the DDL file (but we dont use it ...) nread = fread(buffer, 1, 4*nwords32, ddlfile); if ( nread!=nwords32*4 ) { fprintf(stderr, "Error: hwaddr 0x%03x: Reading of channel payload failed. Read %d instead of %d bytes.\n", hwaddr,nread,nwords32*4); exit(EXIT_FAILURE); } samplectr = 0; samplesperbunch = 0; for ( int32_t i10=0; i10>si10) & 0x3ff; if (samplectr==0) { if ( verbosity>5 ) printf(" ==> %d :: %d (bunch length)\n", i10, w10); samplesperbunch = w10; samplectr++; } else if (samplectr==1) { if ( verbosity>5 ) printf(" ==> %d :: %d (time bin)\n", i10, w10); samplectr++; } else if (samplectr==(samplesperbunch-1)) { if ( verbosity>5 ) printf(" ==> %d :: %d (sample %d, bunch word %d)\n", i10, w10, samplectr-2, samplectr); samplectr=0; } else { if ( verbosity>5 ) printf(" ==> %d :: %d (sample %d, bunch word %d)\n", i10, w10, samplectr-2, samplectr); samplectr++; } if (w32>>30 != 0x0) { fprintf(stderr,"Error: hwaddr 0x%03x: expected channel data, but read 0x%08x\n", hwaddr, w32); exit(EXIT_FAILURE); } } break; case 0x2: if ( verbosity>5 ) printf("RCU trailer word: 0x%08x\n", w32); break; case 0x3: if ( verbosity>5 ) printf("RCU trailer word: 0x%08x (last)\n", w32); is_last=1; break; } } while ( !is_last ); // data file loop fclose(ddlfile); // Summary of the data read from file if ( verbosity>0 ) { cout << "DATA SUMMARY " << endl; cout << " ==== " << endl; } ofstream ofs; ofs.open (filename, std::ofstream::app); if ( ofs.is_open() ) { ofs << side << "\t" << sector << "\t" << rcu << "\t" << event << "\t" << ddlTimeFull*1e3 << "\t" << ddlTimeSparse*1e3 << "\t" << Assembler.getFilledSlotsMAX() << "\t" << DDLIF.getFilledSlots() << "\t" << junk0 << "\t" << junk1 << "\t" << eventtime << endl; ofs.close(); } else { cerr << "Error opening file" << endl; } */ return 0; };