--- /dev/null
+#include "hadaq/api.h"
+#include <time.h>
+
+void readSubEvents(hadaq::RawEvent* evnt);
+signed analyzeData(hadaq::RawSubevent* sub, unsigned ix, unsigned datalen, unsigned source);
+unsigned getSensor(unsigned sensorId);
+void writeResults();
+
+#define DEBUG 0
+#define MAX_SENSORS 12
+
+unsigned pixelMap[MAX_SENSORS][576][1152] = {{0}};
+unsigned pixelcount[MAX_SENSORS][1153] = {{0}};
+unsigned statistics[MAX_SENSORS][4] = {{0}};
+unsigned numSensors = 0;
+unsigned countMarkedFrames = 0;
+unsigned sensors[MAX_SENSORS];
+
+#define FRREALBROKEN 0
+#define FRBROKEN 1
+#define FRVALID 2
+#define FROVERFLOW 3
+
+const char* filename = "file.hld";
+const char* picPath = "./png";
+const char* mySystem = "NONE";
+
+
+int main(int argc, char** argv) {
+
+ if (argc>1) filename = argv[1];
+ if (argc>2) picPath = argv[2];
+ if (argc>3) mySystem = argv[3];
+
+ hadaq::ReadoutHandle ref = hadaq::ReadoutHandle::Connect(filename);
+ hadaq::RawEvent* evnt = 0;
+ while((evnt = ref.NextEvent(1.)) != 0) {
+ readSubEvents(evnt);
+#if DEBUG>=1
+ printf("------------------------\n");
+#endif
+ }
+ writeResults();
+ return 0;
+
+}
+
+unsigned getSensor(unsigned sensorId) {
+ for(unsigned i = 0; i < numSensors; i++) {
+ if (sensors[i] == sensorId) {
+ return i;
+ }
+ }
+ if (numSensors == MAX_SENSORS) { return -1;}
+
+ sensors[numSensors] = sensorId;
+ return numSensors++;
+ }
+
+
+void readSubEvents(hadaq::RawEvent* evnt) {
+ hadaq::RawSubevent* sub = 0;
+ while ((sub=evnt->NextSubevent(sub))!=0) {
+ unsigned trbSubEvSize = sub->GetSize() / 4 - 4;
+ unsigned ix = 0;
+ while (ix < trbSubEvSize) {
+ unsigned data = sub->Data(ix++);
+ unsigned datalen = (data >> 16) & 0xFFFF;
+ unsigned source = (data >> 0) & 0xFFFF;
+#if DEBUG>=1
+ printf("Source\t%04x\tLength\t%04x\n",
+ source, datalen);
+#endif
+ signed ret = analyzeData(sub, ix, datalen, source);
+ ix+=datalen;
+ if(ret == -32) {break;}
+ }
+ }
+ }
+
+signed analyzeData(hadaq::RawSubevent* sub, unsigned ix, unsigned datalen, unsigned source) {
+ if (source == 0x5555) return -32;
+ if (datalen == 0) return -33;
+ unsigned RocEnd = ix + datalen -1;
+ int v2 = 0;
+
+ unsigned rocHead = sub->Data(ix++);
+ if(((rocHead>>24) & 0xFF) != 1 || (rocHead & 0xFF) != 1) {
+ ix--; //assume it's old format
+ }
+ else {
+ unsigned externalTimer = sub->Data(ix++);
+ unsigned externalInput = (externalTimer&0x80000000)?1:0;
+ if(externalInput) countMarkedFrames++;
+ externalTimer &= 0x7FFFFFFF;
+ }
+ while(1) {
+ unsigned sensorHead = sub->Data(ix++);
+ unsigned sensorId = 0x0;
+ unsigned sensorStatus = 0x0;
+ unsigned external = 0x0;
+ unsigned internal_fr_num = 0x0;
+ unsigned mySensor = 0x0;
+ unsigned sensorError = 0x0;
+ unsigned sensorDebug = 0x0;
+
+ if (sub->Data(ix)>>16 == 0xf002){
+ // Version 2
+ ix++;
+ sensorId = (source << 16)|(sub->Data(ix++)>>16);
+ sensorStatus = sub->Data(ix++);
+ ix += 2; // skip reserved words
+ external = sub->Data(ix++);
+ internal_fr_num = sub->Data(ix++);
+ sensorError = 0x0;
+ sensorDebug = 0x0;
+ v2 = 1;
+ }
+ else{
+ sensorId = (source << 16)|(sub->Data(ix++)>>16);
+ sensorStatus = sub->Data(ix++);
+ sensorError = sub->Data(ix++);
+ sensorDebug = sub->Data(ix++);
+ ix += 2; //Skip time
+ v2 = 0;
+ }
+
+ mySensor = getSensor(sensorId);
+
+ #if DEBUG>=1
+ printf("Head\t%08x\tID\t%08x\tStatus\t%08x\tError\t%08x\tDebug\t%08x\n",
+ sensorHead, sensorId, sensorStatus, sensorError, sensorDebug);
+ #endif
+
+ if(sensorHead != 0xffffffff) {
+ //Something is really wrong with data. Skip SubEvent!
+ printf("Broken Sensor Header\n");
+ statistics[mySensor][FRREALBROKEN]++;
+ #if DEBUG==0
+ printf("Head\t%08x\tID\t%08x\tStatus\t%08x\tError\t%08x\tDebug\t%08x\n",
+ sensorHead, sensorId, sensorStatus, sensorError, sensorDebug);
+ #endif
+ return -1;
+ }
+
+ //Check Status Word
+ unsigned sensorIsValid = 0;
+ if((sensorStatus & 0xf000000f) == 0xf000000f) {
+ sensorIsValid = 1;
+ statistics[mySensor][FRVALID]++;
+ }
+ else {
+ sensorIsValid = 0;
+ statistics[mySensor][FRBROKEN]++;
+ }
+
+ if(sensorIsValid){
+ //Hey Sensor, tell me who you are!
+ unsigned sensorDummy = sub->Data(ix++);
+ unsigned sensorNumber = sub->Data(ix++);
+ unsigned sensorLength = sub->Data(ix++) & 0xffff;
+
+
+ unsigned frameEndPos = ix + sensorLength;
+ unsigned d,line = 0,column,pixels,statecnt = 0,ovf = 0;
+ #if DEBUG>=1
+ printf("\t\t\tHeader\t%08x\tFrame\t%08x\tLength\t%i\n",
+ sensorDummy, sensorNumber, sensorLength);
+ #endif
+ if(sensorLength > 580) {printf("Invalid lenght. Something wrong."); statistics[mySensor][FRBROKEN]++; return -1;}
+ if(sensorLength == 0) {
+ goto FrameEnd;
+ }
+
+
+ while(1) {
+ for(unsigned i = 0; i<=1; i++) {
+
+ if (v2==1){
+ if(i==0) d = (sub->Data(ix) << 16) >> 16;
+ else d = sub->Data(ix++) >> 16;
+ }
+ else{
+ if(i==0) d = sub->Data(ix) >> 16;
+ else d = sub->Data(ix++);
+ }
+
+ if(statecnt-- == 0) {
+ ovf += (d >> 15) & 1;
+ line = (d >> 4) & 0x7FF;
+ statecnt = d & 0xF;
+ pixelcount[mySensor][1152]++;
+ }
+ else {
+ pixels = (d & 0x3);
+ column = (d >> 2) & 0x7FF;
+ #if DEBUG>1
+ printf("\t%d, %d x %d\n",line,column,pixels+1);
+ #endif
+ pixelcount[mySensor][column] += pixels+1;
+
+ pixelMap[mySensor][line][column]++;
+ if (pixels) {
+ pixelMap[mySensor][line][column+1]++;
+ if (pixels > 1) {
+ pixelMap[mySensor][line][column+2]++;
+ if (pixels > 2) {
+ pixelMap[mySensor][line][column+3]++;
+ }
+ }
+ }
+ }
+ if(ix >= frameEndPos) {goto FrameEnd;}
+ if(ix >= RocEnd) {break;}
+ }
+ }
+ FrameEnd:
+ //Read end of frame marker without check
+ ix += 1;
+ }
+ else {
+ return -2;
+ }
+ if(ix >= RocEnd){break;}
+ }
+ return 0;
+ }
+
+
+
+
+void writeResults() {
+ printf ("===============\n");
+ printf ("== Summary ==\n");
+ printf ("===============\n");
+ printf ("Sensor\t\tStates\t\tGood\tBroken\tInvalid\tMarked\tBank0\t\tBank1\t\tBank2\t\tBank3\n");
+ for(unsigned i = 0; i < numSensors; i++) {
+ if(statistics[i][FRVALID] == 0) {continue;}
+ double hitrates[4];
+ unsigned pixcolcnt[MAX_SENSORS][4] = {{0}};
+ unsigned hitcount[MAX_SENSORS] = {0};
+ for(unsigned j = 0; j < 288; j++) {
+ pixcolcnt[i][0] += pixelcount[i][j];
+ pixcolcnt[i][1] += pixelcount[i][j+288];
+ pixcolcnt[i][2] += pixelcount[i][j+288+288];
+ pixcolcnt[i][3] += pixelcount[i][j+288+288+288];
+ }
+ hitcount[i] = pixcolcnt[i][0] + pixcolcnt[i][1] + pixcolcnt[i][2] + pixcolcnt[i][3];
+
+ printf("%08x\t%10i\t%i\t%i\t%i\t%i\t%10i\t%10i\t%10i\t%10i\n",
+ sensors[i],
+ hitcount[i],
+ statistics[i][FRVALID],
+ statistics[i][FRBROKEN],
+ statistics[i][FRREALBROKEN],
+ countMarkedFrames,
+ pixcolcnt[i][0],
+ pixcolcnt[i][1],
+ pixcolcnt[i][2],
+ pixcolcnt[i][3]
+ );
+ //printf ("\t\t\t\t\t\tHR Bank0\tHR Bank1\tHR Bank2\tHR Bank3\n");
+ hitrates[0] = (pixcolcnt[i][0]) /(288.*576*(statistics[i][FRVALID]));
+ hitrates[1] = (pixcolcnt[i][1]) /(288.*576*(statistics[i][FRVALID]));
+ hitrates[2] = (pixcolcnt[i][2]) /(288.*576*(statistics[i][FRVALID]));
+ hitrates[3] = (pixcolcnt[i][3]) /(288.*576*(statistics[i][FRVALID]));
+ printf("\t\t\t\t\t\t\t%e\t%e\t%e\t%e\n",
+ hitrates[0],
+ hitrates[1],
+ hitrates[2],
+ hitrates[3]
+ );
+
+ FILE* cvt;
+ int status;
+ cvt = popen("gnuplot", "w");
+ if (!cvt) {
+ printf("couldn't open a pipe; quitting\n");
+ exit(1);
+ }
+ fprintf(cvt, "set terminal png size 800,400 font \",9\";\n");
+ fprintf(cvt, "set palette model RGB;\n");
+ fprintf(cvt, "set xrange [0:1152];\n");
+ fprintf(cvt, "set yrange [0:576];\n");
+ fprintf(cvt, "set cbrange [0:%i];\n",statistics[i][FRVALID]);
+ fprintf(cvt, "set palette defined ( 0 'white', 1 'red', 5 'black', 10 'blue', %i 'green');\n",statistics[i][FRVALID]);
+
+ time_t rawtime;
+ struct tm * timeinfo;
+ time (&rawtime);
+ timeinfo = localtime (&rawtime);
+ char ts[200];
+ strftime (ts,200,"set label 100 \"%H:%M:%S\" at screen 0.98,0.02 right tc rgb \"#000044\" font \"monospace,8\"\n",timeinfo);
+ fprintf(cvt,ts);
+
+ fprintf(cvt, "set label 101 \"%i States, %i good, %i broken, %i invalid\" at screen 0.02,0.01 left tc rgb \"#000044\" font \"monospace,8\"\n",
+ hitcount[i],
+ statistics[i][FRVALID],
+ statistics[i][FRBROKEN],
+ statistics[i][FRREALBROKEN]);
+
+ fprintf(cvt, "set label 102 \"hit rates: A: %.3e B: %.3e C: %.3e D:%.3e\" at screen 0.4,0.01 left tc rgb \"#000044\" font \"monospace,8\"\n",
+ hitrates[0],
+ hitrates[1],
+ hitrates[2],
+ hitrates[3]);
+ fprintf(cvt, "set output '%s/%s_%08x.png';\n",picPath,mySystem,sensors[i]);
+ printf("\nset output '%s/%s_%08x.png';\n",picPath,mySystem,sensors[i]);
+ fprintf(cvt, "plot '-' matrix with image\n");
+
+ for(unsigned r = 0; r < 576; r++) {
+ for(unsigned c = 0; c < 1152; c++) {
+ fprintf(cvt,"%d ",pixelMap[i][r][c]);
+ }
+ fprintf(cvt,"\n");
+ }
+
+
+ fprintf(cvt, "e\n\n");
+ fflush(cvt);
+ status=pclose(cvt);
+ if (!WIFEXITED(status)) printf("error on closing the pipe\n");
+ }
+ }
+
+