/* $Id: gsII_bufp.c,v 1.137 2010/09/30 20:27:07 tl Exp $ */ #define DEBUG1 0 #define FERADEBUG 0 #include #include #include #include #ifdef SOLARIS #include #endif #ifdef LINUX #include #endif #ifdef MAC #include #endif #include "efftape.h" #include "GSudpReceiver.h" #include "gsII.h" #define MAXCLOCK 3 #define NFERAERRORS 256 /* using namespace std; */ /* other globals */ unsigned int nFERAErrToPr = 20; unsigned int nFERAErrPrinted = 0; unsigned int nFERACals = 0; unsigned int FERAErrors[NFERAERRORS] = { 0 }; unsigned int NFERATotalErrors = 0; unsigned int NFERAPartialErrors = 0; unsigned int nFERAtype[MAXFERATYPE] = { 0 }; int FERAtypeVSN[MAXVSN] = { 0 }; int FERAvsntable[MAXVSN] = { 0 }; static unsigned int nposprob = 0; static unsigned int nev = 0; static int NwarnMAX = 0; static int Nwarn = 0; static int gs2k008_format = 0; static int gsfma233_timeFix = 0; static int ExportModNWords[256] = { 0 }; static int longRangeTDCNWords[256] = { 0 }; static float clockScale[MAXCLOCK] = { 0 }; static float clockMax[MAXCLOCK] = { 0 }; static int nFeraDebug = 0; static int VSNHits[MAXVSN]; /*------------------------------------------------------------*/ void SetnFeraDebug (int ii) { nFeraDebug = ii; printf ("setting nFeraDebug=%i\n", nFeraDebug); } /*------------------------------------------------------------*/ void SetClockPar (int clock, float factor, float max) { int i1; if (clock < 1 || clock >= MAXCLOCK) { i1 = MAXCLOCK; printf ("clock must be between 1 and %i\n", i1); exit (1); }; /* set parameters */ clockScale[clock] = factor; clockMax[clock] = max; /* confirm what we did */ printf ("SetClockPar: set clock%i factor to %f\n", clock, clockScale[clock]); printf ("SetClockPar: set clock%i max to %f\n", clock, clockMax[clock]); /* done */ return; } /*------------------------------------------------------------*/ int GetExportModNWords (int vsn) { return (ExportModNWords[vsn]); } /*------------------------------------------------------------*/ void SetExportModNWords (char *str, int nwords) { int i; int str_decomp (char *, int, int *); int tmparr[256]; /* decompose string and fill tmp lookup array */ str_decomp (str, 256, tmparr); /* add info for # FERAs serviced from export module */ for (i = 0; i < 256; i++) if (tmparr[i]) { ExportModNWords[i] = nwords; printf ("__exportmod, vsn=%i, set words= %i\n", i, ExportModNWords[i]); }; } /*---------------------------------------------------*/ void SetlongRangeTDCNWords (char *str, int nwords) { int i; int str_decomp (char *, int, int *); int tmparr[256]; /* decompose string and fill tmp lookup array */ str_decomp (str, 256, tmparr); /* add info for # FERAs serviced from export module */ for (i = 0; i < 256; i++) if (tmparr[i]) { longRangeTDCNWords[i] = nwords; printf ("__exportmod, vsn=%i, set words= %i\n", i, ExportModNWords[i]); }; } /*------------------------------------------------------------*/ void SetSpecial (char *str) { /* declarations */ char *p; /* set special sort flags */ if ((p = strstr (str, "gs2k008_format")) != NULL) gs2k008_format = 1; else if ((p = strstr (str, "gsfma233_timeFix")) != NULL) gsfma233_timeFix = 1; else { printf ("gsII_bufp/SetSpecial:\n"); printf ("<%s> not recognized\n", str); printf ("quit!\n"); exit (1); } } /*------------------------------------------------------------*/ void SetNPosWarn (int n) { NwarnMAX = n; printf ("will document the first %i buffer position errors\n", NwarnMAX); } /*------------------------------------------------------------*/ void ResetGSII_bufpCounters () { Nwarn = 0; nposprob = 0; nev = 0; printf ("reset\n"); } /*------------------------------------------------------------*/ void ReportBufPosErrors (void) { printf ("\n"); printf ("gsII_bufp: processed %i events\n", nev); printf ("__%i had position errors, ", nposprob); printf ("%9.2f %%\n", 100 * (float) nposprob / (float) nev); printf ("\n"); } /*------------------------------------------------------------*/ void InitializeFERAvsntable () { /* Initially all FERA VSNs map to themselves */ int i; for (i = 0; i < MAXVSN; i++) FERAvsntable[i] = i; } /*------------------------------------------------------------*/ void ZeroFERAtypeVSN () { int i; for (i = 0; i < MAXVSN; i++) FERAtypeVSN[i] = FERATYPEUNDEF; i = FERATYPEUNDEF; printf ("FERAtypeVSN identification array set to default type %i\n", i); for (i = 0; i < MAXFERATYPE; i++) nFERAtype[i] = 0; printf ("__associated type counters reset\n"); } /*------------------------------------------------------------*/ int PrintThisFERAType (int i) { printf ("VSN=%3.3i(0x%2.2x): ", i, i); if (FERAtypeVSN[i] >= 0 && FERAtypeVSN[i] <= FERATYPEUNDEF) { switch (FERAtypeVSN[i]) { case FERATYPE0: printf ("Lecroy (type 0).........................."); break; case FERATYPE1: printf ("Silena (type 1).........................."); break; case FERATYPE2: printf ("Ortec (type 2)..........................."); break; case FERATYPE3: printf ("Export mod (type 3), #FERAs= %3i ........", ExportModNWords[i]); break; case FERATYPE4: printf ("clock1 (type 4).........................."); break; case FERATYPE5: printf ("clock2 (type 5).........................."); break; case FERATYPE6: printf ("LeCroy long range TDC (type 6), #TDCs=%3i", longRangeTDCNWords[i]); break; case FERATYPEUNDEF: printf ("undeclared VSN..........................."); break; default: printf ("FERA data type %3i unknown...............", FERAtypeVSN[i]); return (1); }; } else printf ("fera VSN out of range 0...%3i .............", FERATYPEUNDEF); /* done */ return (0); } /*------------------------------------------------------------*/ void PrintFERATypes () { int i, st; printf ("\n"); printf ("declared FERA types:\n"); for (i = 0; i < MAXVSN; i++) if (FERAtypeVSN[i] >= 0 && FERAtypeVSN[i] < FERATYPEUNDEF) { st = PrintThisFERAType (i); printf ("\n"); if (st != 0) exit (1); }; printf ("\n"); } /*------------------------------------------------------------*/ void SetFERAvsntable (int i, int j) { if (i < MAXVSN) FERAvsntable[i] = j; else printf ("SetFERAvsntable: Bad channel number: %i > 255\n", i); } /*------------------------------------------------------------*/ int SetFERAVSN (char *str, int type) { int i; int str_decomp (char *, int, int *); int tmparr[2000]; /* decompose string and fill tmp lookup array */ str_decomp (str, 2000, tmparr); /* mark type */ for (i = 0; i < MAXVSN; i++) if (tmparr[i]) FERAtypeVSN[i] = type; return (0); } /*------------------------------------------------------------*/ void SetFERAErrorPrint (int ntp) { nFERAErrPrinted = 0; nFERAErrToPr = ntp; } /*------------------------------------------------------------*/ void ZapFERAErrors () { int i; NFERATotalErrors = 0; NFERAPartialErrors = 0; nFERACals = 0; for (i = 0; i < 16; i++) nFERAtype[i] = 0; for (i = 0; i < NFERAERRORS; i++) FERAErrors[i] = 0; for (i = 0; i < MAXVSN; i++) VSNHits[i] = 0; } /*------------------------------------------------------------*/ void PrintFERAErrors (int EvProc) { float r1, sumerr; int i; if (nFERACals > 0) { r1 = 100.0 * (float) nFERACals / (float) EvProc; printf (">> %6.2f%% of the events had external data\n", r1); printf (">> processed: %i events with external data\n", nFERACals); r1 = 100 * (float) NFERATotalErrors / (float) nFERACals; printf (">> %6.2f%% of the FERA interpretations were total failures;\n", r1); r1 = 100 * (float) NFERAPartialErrors / (float) nFERACals; printf (">> %6.2f%% of the FERA interpretations were partial failures;\n", r1); for (i = 0; i < 16; i++) if (nFERAtype[i] > 0) printf (">> %9i type %i FERA headers\n", nFERAtype[i], i); for (i = 0; i < NFERAERRORS; i++) if (FERAErrors[i] > 0) { switch (i) { case FERAERRNOHEAD: printf ("missing header................ "); break; case FERAERRNEWHEAD: printf ("unexpected new header......... "); break; case FERAERRBADVSN: printf ("bad VSN number................ "); break; case FERAERRWDS: printf ("word-count too big............ "); break; default: printf ("onknown FERA return error= %3i ", i); break; }; r1 = 100.0 * (float) FERAErrors[i] / (float) nFERACals; printf ("%10i %6.2f%%\n", FERAErrors[i], r1); }; sumerr = 0; for (i = 0; i < MAXVSN; i++) if (VSNHits[i] > 0) { PrintThisFERAType (i); r1 = 100 * (float) VSNHits[i] / (float) nFERACals; sumerr += r1; printf (">> %12i, %6.2f%%\n", VSNHits[i], r1); }; printf ("sum of errors in list %6.2f%%\n", sumerr); } else printf ("there were no FERA interpretation calls\n"); } /*----------------------------------------------*/ int print_buffer_data (EVENT_BUFFER * eb, int lo, int hi) { /* declarations */ int i; unsigned short int val; /* constrain limits */ if (lo < 0) lo = 0; if (hi > 8191) hi = 8191; printf ("\nbuffer print: from %i to %i\n", lo, hi); /* print in simple format */ for (i = lo; i < hi; i++) { printf ("%4i[%4i]: ", i, i - EB_HEADER_LEN / 2); printf ("%5.5i ", eb->EventData[i]); printf ("[0x%4.4x]", eb->EventData[i]); val = (eb->EventData[i] & 0xff00); val = val >> 8; printf ("{0x%4.4x/%3.3i,", val, val); val = (eb->EventData[i] & 0x00ff); printf ("0x%4.4x/%3.3i}", val, val); printf ("____________________\n"); if (eb->EventData[i] == 0xffff) printf ("============================================\n"); }; /* done */ return (SUCCESS); } /* ------------------------------------- */ int print_event (struct EVHDR hdr, struct EVENT ev, int nn, int geoff, int bgooff, float tac2FacGE, float tac2FacBGO, int extra) { /* declarations */ int i, j; /* print the header only if first event */ if (nn == 0) { printf ("EV len"); printf (" cln"); printf (" dty"); printf (" bgo"); printf (" ttH "); printf (" ttM "); printf (" ttL "); printf ("tac1"); printf (" tac2 "); printf (" sge "); printf (" sbgo \n"); printf ("** %2.2i", hdr.len); printf (" %2.2i", hdr.len_clean); printf (" %2.2i", hdr.len_dirty); printf (" %2.2i", hdr.len_bgo); printf (" %5.5i ", hdr.ttH); printf ("%5.5i ", hdr.ttM); printf ("%5.5i ", hdr.ttL); printf ("%4.4i ", hdr.tac1); printf ("%4.4i ", hdr.tac2); printf ("%4.4i ", hdr.sumge); printf (" %4.4i\n", hdr.sumbgo); }; if (nn == 0) { printf (" ev# "); printf (" id "); printf (" ehi "); printf ("g "); printf ("p "); printf ("o "); printf (" tge "); printf ("ebgo "); printf ("tbgo "); printf (" elo "); printf ("esid "); printf (" tc "); printf ("bgohitp "); printf (" tRF misc"); printf ("\n"); fflush (stdout); }; printf ("%4i ", nn); printf ("%3.3i ", ev.id); printf ("%5.5i ", ev.ehi); printf ("%1.1i ", ev.gebit); printf ("%1.1i ", ev.pu); printf ("%1.1i ", ev.over); printf ("%4.4i ", ev.tge); printf ("%4.4i ", ev.ebgo); printf ("%4.4i ", ev.tbgo); printf ("%4.4i ", ev.elo); printf ("%4.4i ", ev.eside); printf ("%4.4i ", ev.tc); printf ("0x%4.4x=0b_", ev.bgohit); j = 0x0040; for (i = 0; i < 7; i++) { if (i == 3) printf ("|"); if ((ev.bgohit & j) == j) printf ("1"); else printf ("0"); j = j / 2; }; if (ev.gebit && ev.bgohit == 0) printf (" cge:%5.4i ", ev.tge - (int) ((float) hdr.tac2 * tac2FacGE) + geoff); else if (ev.gebit && ev.bgohit != 0) printf (" dge:%5.4i ", ev.tge - (int) ((float) hdr.tac2 * tac2FacGE) + geoff); else printf (" bgo:%5.4i ", ev.tbgo - (int) ((float) hdr.tac2 * tac2FacBGO) + bgooff); if (nn < hdr.len_clean) { if (ev.hs != 0) printf ("hs "); if (ev.pu != 0) printf ("pu "); if (ev.over != 0) printf ("over "); }; /* print the user extra value */ if (extra > 0) printf ("{%i}", extra); printf ("\n"); fflush (stdout); return (SUCCESS); } /*-------------------------------------------------------*/ int decode_fera (unsigned int *extdata, unsigned int *next, unsigned int *xtype, unsigned int *xvsn, unsigned int *xch, unsigned int *xdata, double *clock1, double *clock2) /* input */ /* extdata[]; fera data */ /* output */ /* next; # external fera data words found */ /* xtype[]; LeCroy/Silena type array */ /* xvsn[]; VSN array */ /* xch[]; channel array */ /* xdata[]; data array */ { /* general purpose FERA decoding routine. */ /* declarations */ static int nnUnknownVSN = 0; int i, k, l, vsn, wds, chan, data, last, len, nn, CurExportAdc; int FERAtype, nbad, pw, nadc; static unsigned int bincode[16] = { 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000 }; static double ClockFac[4] = { 1.0, 4096.0, 16777216.0, 68719476736.0 }; /* prototypes */ int GetBufferNo_disk (void); int time_stamp (void); /* count how many times we are called. */ /* We should only be called if ext[0]>0 */ /* or the counting statistics will be wrong */ nFERACals++; /* initialize */ nn = 0; /* number of FERA modules */ i = 1; nbad = 0; *clock1 = 0; *clock2 = 0; /* first word tells the lenght */ len = extdata[0]; last = i + len; if (nFeraDebug > 0) { /* debug print out */ printf ("\nFERADEBUG #%i ----------------\n", nFeraDebug); printf ("i=%i,last=%i\n", i, last); for (k = 0; k < last; k++) printf ("decode_fera:%2i --> 0x%4.4x\n", k, extdata[k]); fflush (stdout); }; /* parse and print fera data */ while (i < last) { /* first word better be a fera header */ if ((extdata[i] & 0x8000) != 0x8000) { if (nn == 0) NFERATotalErrors++; else NFERAPartialErrors++; FERAErrors[FERAERRNOHEAD]++; return (FERAERRNOHEAD); }; /* extract VSN number and lookup FERA type */ vsn = (extdata[i] & 0x00ff); /* allow for translation of VSN #s */ vsn = FERAvsntable[vsn]; /* lookup the FERA type */ FERAtype = FERAtypeVSN[vsn]; /* statistics and debug */ if (nFeraDebug > 0) { printf ("found VSN=%i(0x%4.4x) at pos %i, type=%i\n", vsn, vsn, i, FERAtype); }; if (FERAtype >= 0 && FERAtype < FERATYPEUNDEF) nFERAtype[FERAtype]++; if (vsn < MAXVSN) VSNHits[vsn]++; /*---------------------*/ /* extract header info */ /*---------------------*/ pw = 0; nadc = 0; wds = 0; if (FERAtype == 0) { /* LeCroy FERA */ wds = (extdata[i] & 0x7800) >> 11; if (wds == 0) wds = 16; } else if (FERAtype == 1) { /* Silena FERA */ wds = (extdata[i] & 0x0f00) >> 8; pw = (extdata[++i] & 0x00ff); /* ...and forward one */ } else if (FERAtype == 2) { /* Ortec FERA */ wds = (extdata[i] & 0x1800) >> 11; } else if (FERAtype == 3) { /* EXPORT module */ if (nFERAErrPrinted < nFERAErrToPr) { nadc = (extdata[i] & 0x7f00) >> 8; /* complain if header is wrong */ if (nadc != ExportModNWords[vsn]) { nFERAErrPrinted++; printf ("Warning: declared #FERAs=%i not equal to header #FERAS=%i ", ExportModNWords[vsn], nadc); printf ("for VSN=%i\n", vsn); }; }; /* # FERAs serviced by an export module is now */ /* declared, we no longer rely on header info. */ nadc = ExportModNWords[vsn]; if (nFeraDebug > 0) { printf ("a:export header: 0x%4.4x\n", extdata[i]); printf ("__nadc=%i\n", nadc); }; } else if (FERAtype == 6) { /* long range TDC EXPORT module */ if (nFERAErrPrinted < nFERAErrToPr) { nadc = (extdata[i] & 0x7f00) >> 8; /* complain if header is wrong */ if (nadc != longRangeTDCNWords[vsn]) { nFERAErrPrinted++; printf ("Warning: declared #TDCs=%i not equal to header #TDC=%i ", longRangeTDCNWords[vsn], nadc); printf ("for VSN=%i\n", vsn); }; }; /* # FERAs serviced by an export module is now */ /* declared, we no longer rely on header info. */ nadc = longRangeTDCNWords[vsn]; if (nFeraDebug > 0) { printf ("a:long range TDC export header: 0x%4.4x\n", extdata[i]); printf ("__nadc=%i\n", nadc); }; } else if (FERAtype == 4 || FERAtype == 5) { /* clock module */ wds = 1 + ((extdata[i] & 0x7800) >> 11); wds = 4; /* always */ } else if (FERAtype == FERATYPEUNDEF) { /* undeclared VSN, warn and return as much as we have */ if (nnUnknownVSN < 100 || nFeraDebug > 0) { printf ("warning: VSN=%4i,0x%4.4x @ pos %4i (data=0x%4.4x) not declared ", vsn, vsn, i, extdata[i]); printf ("in block %4i on ", GetBufferNo_disk ()); time_stamp (); fflush (stdout); }; if (nnUnknownVSN == 100) printf ("___VSN warnings will now be suspended!!!!!\n"); nnUnknownVSN++; *next = nn; if (nn == 0) NFERATotalErrors++; else NFERAPartialErrors++; FERAErrors[FERAERRBADVSN]++; return (FERAERRBADVSN); }; if (nFeraDebug > 0) { printf ("wds=%i(0x%4.4x)\n", wds, wds); printf ("pw=%i(0x%4.4x)\n", pw, pw); printf ("nadc=%i(0x%4.4x)\n", nadc, nadc); }; /* position at first data word */ i++; /*--------------*/ /* extract data */ /*--------------*/ if (FERAtype == 3) { for (CurExportAdc = 0; CurExportAdc < nadc; CurExportAdc++) { if (nFeraDebug > 0) { printf ("CurExportAdc=%i,i=%i -> %4.4x\n", CurExportAdc, i, extdata[i]); }; if (extdata[i++] != 0) { if (nFeraDebug > 0) { printf ("nonzero bitpattern 0x%4.4x at pos %i\n", extdata[i - 1], i - 1); }; /* find word count */ wds = 0; for (l = 0; l < 16; l++) if ((bincode[l] & (unsigned int) extdata[i - 1]) != 0) wds++; if (nFeraDebug > 0) { printf ("FERAtype == 3; wds=%i\n", wds); }; /* does wordcount make sense? */ if ((i + wds) > last) { /* the word count makes is read too far */ /* yell bloody hell and quit */ if (nFeraDebug > 0) printf ("FERA word count error, (i+wds)=%i > last=%i\n", (i + wds), last); FERAErrors[FERAERRWDS]++; return (FERAERRWDS); }; for (l = 0; l < wds; l++) { /* determine channel and data */ chan = (extdata[i] & 0xf000) >> 12; data = (extdata[i++] & 0x0fff); if (nFeraDebug > 0) { printf ("chan=%i, data=%i\n", chan, data); }; /* transfer to parsed external array */ xtype[nn] = FERAtype; xvsn[nn] = vsn + CurExportAdc; xch[nn] = chan; xdata[nn++] = data; }; } } } else if (FERAtype == 4) { /* does wordcount make sense? */ if ((i + wds) > last) { /* the word count makes is read too far */ /* yell bloody hell and quit */ if (nFeraDebug > 0) printf ("FERA word count error, (i+wds)=%i > last=%i\n", (i + wds), last); FERAErrors[FERAERRWDS]++; return (FERAERRWDS); }; /* clock 1 */ for (l = 0; l < wds; l++) { if (nFeraDebug > 0) { printf ("clock1:w%i=%4.4x\n", l, extdata[i]); }; *clock1 += ClockFac[l] * (extdata[i++] & 0x0fff); if (nFeraDebug > 0) { printf ("clock1=%f\n", *clock1); }; } /* scale and limit */ *clock1 *= clockScale[1]; if (*clock1 > clockMax[1]) *clock1 = clockMax[1]; } else if (FERAtype == 5) { /* clock 2 */ /* does wordcount make sense? */ if ((i + wds) > last) { /* the word count makes is read too far */ /* yell bloody hell and quit */ if (nFeraDebug > 0) printf ("FERA word count error, (i+wds)=%i > last=%i\n", (i + wds), last); FERAErrors[FERAERRWDS]++; return (FERAERRWDS); }; for (l = 0; l < wds; l++) { if (nFeraDebug > 0) { printf ("clock2:w%i=%4.4x\n", l, extdata[i]); }; *clock2 += ClockFac[l] * (extdata[i++] & 0x0fff); if (nFeraDebug > 0) { printf ("clock2=%f\n", *clock2); }; } /* scale and limit */ *clock2 *= clockScale[2]; if (*clock2 > clockMax[2]) *clock2 = clockMax[2]; } else if (FERAtype == 6) { /* New type Xport module with Lecroy long range TDCs */ /* code from Andrew Robinson */ for (CurExportAdc = 0; CurExportAdc < nadc; CurExportAdc++) { wds = (extdata[i] & 0x00ff); if (nFeraDebug > 0) { printf ("FERAtype == 6; extdata[%i]= 0x%4.4x, wds = %i\n", i, extdata[i], wds); printf ("base vsn= %i\n", vsn); }; i++; /* does wordcount make sense? */ if ((i + wds) > last) { /* the word count makes is read too far */ /* yell bloody hell and quit */ if (nFeraDebug > 0) printf ("FERA word count error, (i+wds)=%i > last=%i\n", (i + wds), last); FERAErrors[FERAERRWDS]++; return (FERAERRWDS); }; l = 0; while (l < wds) { if (nFeraDebug > 0) { printf ("wds loop: l=%i; i=%i, nn=%i\n", l, i, nn); }; if ((extdata[i] != 0 || extdata[i + 1] != 0) || 1) { chan = l / (int) 2; data = ((extdata[i + 1] & 0x00ff) * 65536) + extdata[i]; /* Fill returned arrays */ xtype[nn] = FERAtype; xvsn[nn] = vsn + CurExportAdc; xch[nn] = chan; xdata[nn] = data; if (nFeraDebug > 0) { printf ("extdata[%i]=0x%4.4x, %6i; ", i, extdata[i], extdata[i]); printf ("extdata[%i]=0x%4.4x, %6i\n", i + 1, extdata[i + 1], extdata[i + 1]); printf ("xtype[%i]=0x%4.4x, %6i\n", nn, xtype[nn], xtype[nn]); printf ("xvsn[%i]=0x%4.4x, %6i\n", nn, xvsn[nn], xvsn[nn]); printf ("xch[%i]=0x%4.4x, %6i\n", nn, xch[nn], xch[nn]); printf ("xdata[%i]=0x%8.8x, %6i\n", nn, xdata[nn], xdata[nn]); }; nn++; } i++; i++; l++; l++; } } } else for (k = 0; k < wds; k++) { /* extract channel and data */ if (FERAtype == 0) { chan = (extdata[i] & 0x7800) >> 11; data = (extdata[i] & 0x07ff); } else if (FERAtype == 1) { chan = (extdata[i] & 0x7000) >> 12; data = (extdata[i] & 0x0fff); } else if (FERAtype == 2) { chan = (extdata[i] & 0x6000) >> 13; data = (extdata[i] & 0x1fff); }; /* pass to return arrays */ xtype[nn] = FERAtype; xvsn[nn] = vsn; xch[nn] = chan; xdata[nn] = data; if (nFeraDebug > 0) { printf ("chan=%i, data=%i,0x%4.4x\n", chan, data, data); printf (" xch=%i, xdata=%i,0x%4.4x\n", xch[nn], xdata[nn], xdata[nn]); }; /* check highest bit isn't set */ if (FERAtype != 2) if ((extdata[i] & 0x8000) == 0x8000) { nbad++; FERAErrors[FERAERRNEWHEAD]++; if (nFeraDebug > 0) { printf ("next word=0x%4.4x should not be a header\n", extdata[i]); }; return(FERAERRNEWHEAD); }; /* get ready for next fera data word */ i++; nn++; }; }; /* done */ *next = nn; if (nbad == 0) { /* limit ranges */ for (i = 0; i < nn; i++) { if (xtype[i] >= M12BITS) xtype[i] = M12BITS; if (xvsn[i] >= MAXVSN) xvsn[i] = MAXVSN - 1; if (xch[i] >= MAXFERACH) xch[i] = MAXFERACH - 1; }; if (nFeraDebug > 0) { printf ("succesfully interpreted fera data\n"); nFeraDebug--; }; return (SUCCESS); } else { if (nFeraDebug > 0) { printf ("failed to interpret fera data\n"); nFeraDebug--; }; if (nn == 0) NFERATotalErrors++; else NFERAPartialErrors++; return (FERAERRNEWHEAD); }; } /*-----------------------------------------------------------*/ int fera_print (int nfera, unsigned int *fera_type, unsigned int *fera_vsn, unsigned int *fera_ch, unsigned int *fera_data) /* nfera; # fera words */ /* fera_type[]; LeCroy/Silena type array */ /* fera_vsn[]; VSN array */ /* fera_ch[]; channel array */ /* fera_data[]; data array */ { /* declarations */ int j, i; static int bincode[16] = { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768 }; /* print */ for (j = 0; j < nfera; j++) { printf ("%2i-> ", j); switch (fera_type[j]) { case FERATYPE0: printf ("LeCroy ; "); break; case FERATYPE1: printf ("Silena ; "); break; case FERATYPE2: printf ("Ortec..; "); break; case FERATYPE3: printf ("Export.; "); break; case FERATYPE4: printf ("Clock..; "); break; case FERATYPE6: printf ("longTDC; "); break; }; printf ("vsn: %4i(0x%2.2x); ", fera_vsn[j], fera_vsn[j]); printf ("ch: %2i; ", fera_ch[j]); printf ("data: %9i 0x%8.8x ", fera_data[j], fera_data[j]); printf ("|"); for (i = 15; i >= 0; i--) { if (fera_data[j] & bincode[i]) printf ("1"); else printf ("0"); if (i == 4 || i == 8 || i == 12) printf ("|"); }; printf ("|"); printf ("\n"); }; return (0); } /*--------------------------------------------------------------------*/ int get_ev (EVENT_BUFFER * eb, int bitset[], int maxword, int DataLen, struct EVHDR *hdr, struct EVENT ev[], unsigned int ext[]) /* get the next event in the data buffer and return it */ /* in the simplified ev event array (a structure) */ /* the return structure will fill zero in where it */ /* does not have any information. In that way the */ /* the caller function need not know about the event */ /* structure */ { /* declarations */ static int pos = REALDATAPOS; /* current buffer index */ int i, j, hi, i1, l1, l2; unsigned short int len_words; /* total # words in event */ static int nbad = 0; int next, nextwords; /* prototypes */ int print_buffer_data (EVENT_BUFFER *, int, int); int GetBufferNo_tape (void); int GetBufferNo_disk (void); int GetBufferNo_net (void); if (DEBUG1) { printf ("---> entered gsII_bufp\n"); fflush (stdout); }; #if(1) /* DEBUG: check the event length when we have a new buffer */ if (pos == REALDATAPOS) if (eb->EventData[maxword] != 0xffff) { printf ("no 0xffff at the end of buffer, found 0x%4.4x\n", eb->EventData[maxword]); printf ("maxword: %i\n", maxword); printf ("maxword+EB_HEADER_LEN/2: %i\n", maxword + EB_HEADER_LEN / 2); printf ("buffer number tape: %i,", GetBufferNo_tape ()); printf ("disk: %i, ", GetBufferNo_disk ()); printf ("net: %i\n", GetBufferNo_net ()); l1 = maxword - 50; l2 = maxword + 40; print_buffer_data (eb, l1, l2); } #endif #if(0) /*---------------------------------------------*/ /* repair for bad buffer data in old data sets */ /*---------------------------------------------*/ /* check that we have a valid event here */ #if(DEBUG1) printf ("check for valid event at pos: %i\n", pos); fflush (stdout); #endif if ((eb->EventData[pos] & 0xc000) != 0x8000) { #if(1) printf ("not a valid event at pos: %i\n", pos); fflush (stdout); if (pos > 100) { l1 = pos - 2; l2 = pos + 5; printf ("maxword: %i\n", maxword); print_buffer_data (eb, l1, l2); }; #endif /* search forward for 0xffff */ while (eb->EventData[pos] != 0xffff && pos < maxword) pos++; pos++; }; #if(0) printf ("pos now: %i\n", pos); fflush (stdout); #endif #endif /*-------------------------------------------------*/ /* check we have 80nn type of word or return error */ /*-------------------------------------------------*/ if ((eb->EventData[pos] & 0xc000) != 0x8000) { #if(1) printf ("%4.4x at pos: %i, error 6, not start of event\n", eb->EventData[pos], pos); #endif pos = REALDATAPOS; return (GSIIERRSTART); }; /* printf("pos: %4i, ",pos); */ /* check we have enough space to read the header */ if ((pos + 7) > EB_SIZE) { pos = REALDATAPOS; return (GSIIERRSPACE); }; /*-----------------------------*/ /* read the event header words */ /*-----------------------------*/ #if(DEBUG1) printf ("header read, pos=%i\n", pos); #endif /* 1_:get total length of the event (in words) */ len_words = (eb->EventData[pos++] & 0x0fff); /* 2_:get clean number of germaniums + mtm word */ hdr->mtm = (eb->EventData[pos] & 0xff00) >> 8; hdr->len_clean = (eb->EventData[pos++] & 0x00ff); /* 3_:get clean number of ge in event */ hdr->len_dirty = (unsigned short int) (eb->EventData[pos] & 0xff00) >> 8; /* 3_:number of bgo only in event */ hdr->len_bgo = (eb->EventData[pos++] & 0x00ff); #if(DEBUG1) printf ("header; len_words=%i\n", len_words); printf ("header; hdr->len_clean=%i\n", hdr->len_clean); printf ("header; hdr->len_dirty=%i\n", hdr->len_dirty); printf ("header; hdr->len_bgo=%i\n", hdr->len_bgo); #endif /* other header info */ hdr->ttH = eb->EventData[pos++]; /* 4 */ hdr->ttM = eb->EventData[pos++]; /* 5 */ hdr->ttL = eb->EventData[pos++]; /* 6 */ hdr->tac1 = eb->EventData[pos++] & M12; /* 7 */ hdr->tac2 = eb->EventData[pos++] & M12; /* 8 */ hdr->sumge = eb->EventData[pos++]; /* 9 */ hdr->sumbgo = eb->EventData[pos++]; /* 10 */ /*---------------------*/ /* done reading header */ /*---------------------*/ /* determine # of detectors to read in the events (len) */ /* ---- we always have the clean detectors */ hdr->len = hdr->len_clean; /* ---- if the dirty ones are read out also... */ if (bitset[7]) hdr->len += hdr->len_dirty; /* ---- and if the bgos with no ges are read out too... */ if (bitset[8]) hdr->len += hdr->len_bgo; if (hdr->len > MAXSANE) { pos = REALDATAPOS; #if(1) printf ("MAXSANE condition\n"); printf ("hdr->len_clean=%i\n", hdr->len_clean); printf ("hdr->len_dirty=%i\n", hdr->len_dirty); printf ("hdr->len_bgo =%i\n", hdr->len_bgo); printf ("hdr->len =%i\n", hdr->len); #endif hdr->len = 0; return (GSIIERRMAXSANE); }; /* check we have enough buffer left to read event */ if ((pos + DataLen) > EB_SIZE) { pos = REALDATAPOS; return (GSIIERRBUFLEFT); }; /*-----------------------------*/ /* fill the ev structure array */ /*-----------------------------*/ /* first zero out the entire event */ for (i = 0; i < (int) hdr->len; i++) { ev[i].id = 0; ev[i].gebit = 0; ev[i].bgohit = 0; ev[i].ehi = 0; ev[i].pu = 0; ev[i].over = 0; ev[i].tge = 0; ev[i].tc = 0; ev[i].elo = 0; ev[i].eside = 0; ev[i].tbgo = 0; ev[i].ebgo = 0; ev[i].hs = 0; }; /* read clean germanium data */ #if(DEBUG1) printf ("pos at loop start: %i, i= %i\n", pos, i); printf ("hdr->len_clean=%i\n", hdr->len_clean); printf ("hdr->len_dirty=%i\n", hdr->len_dirty); printf ("hdr->len=%i\n", hdr->len); #endif i = 0; hi = (int) hdr->len_clean; while (i < hi) { /* read germanium data (always there) */ ev[i].id = (eb->EventData[pos] & 0x00ff); ev[i].bgohit = (unsigned short int) (eb->EventData[pos] & 0xfe00) >> 9; ev[i].gebit = (unsigned short int) (eb->EventData[pos++] & 0x0100) >> 8; #if(DEBUG1) printf ("i=%i, pos=%i, id=%i\n", i, pos, ev[i].id); fflush (stdout); #endif /* make sure the ge id is from 0...110 only */ if ((int) ev[i].id > MAXID) ev[i].id = 0; ev[i].ehi = (eb->EventData[pos] & 0x3fff); ev[i].pu = (unsigned short int) (eb->EventData[pos] & 0x8000) >> 15; ev[i].over = (unsigned short int) (eb->EventData[pos++] & 0x4000) >> 14; ev[i].eside = eb->EventData[pos++] & M12; /* germanium time */ if (bitset[4] || bitset[5]) ev[i].tge = (eb->EventData[pos++] & 0x1fff); /* full ge data */ if (bitset[5]) { ev[i].tc = (eb->EventData[pos++] & M12); ev[i].elo = (eb->EventData[pos++] & M12); }; #if(0) /* do pu and over range by hand? */ if ((ev[i].ehi & 0x3fff) == 0 && ev[i].elo > 0) ev[i].pu = 1; if (ev[i].ehi > MAXVALIDHIE) ev[i].over = 1; #endif /* bgo data */ if (bitset[6] && eb->RecordVer == 0) { ev[i].tbgo = (eb->EventData[pos++]); ev[i].ebgo = (eb->EventData[pos++]); }; /* next event */ i++; }; #if(DEBUG1) printf ("debug print---> after reading clean\n"); for (j = 0; j < i; j++) print_event (*hdr, ev[j], j, 0, 0, 1.0, 1.0, 0); fflush (stdout); #endif /* read dirty germanium */ if (bitset[7]) { hi += (int) hdr->len_dirty; while (i < hi) { /* read germanium data (allways there) */ ev[i].id = (eb->EventData[pos] & 0x00ff); ev[i].bgohit = (unsigned short int) (eb->EventData[pos] & 0xfe00) >> 9; ev[i].gebit = (unsigned short int) (eb->EventData[pos++] & 0x0100) >> 8; #if(DEBUG1) printf ("i=%i, pos=%i, id=%i\n", i, pos, ev[i].id); fflush (stdout); #endif /* make sure the ge id is from 0...110 only */ if ((int) ev[i].id > MAXID) ev[i].id = 0; ev[i].ehi = (eb->EventData[pos] & 0x3fff); ev[i].pu = (unsigned short int) (eb->EventData[pos] & 0x8000) >> 15; ev[i].over = (unsigned short int) (eb->EventData[pos++] & 0x4000) >> 14; ev[i].eside = (eb->EventData[pos++] & M12); /* germanium time */ if (bitset[4] || bitset[5]) ev[i].tge = (eb->EventData[pos++] & 0x1fff); /* full ge data */ if (bitset[5]) { ev[i].tc = eb->EventData[pos++] & M12; ev[i].elo = eb->EventData[pos++] & M12; }; /* bgo data */ if (bitset[6]) { ev[i].tbgo = eb->EventData[pos++]; ev[i].ebgo = eb->EventData[pos++]; }; /* next event */ i++; }; #if(DEBUG1) printf ("debug print---> after reading dirty\n"); for (j = 0; j < i; j++) print_event (*hdr, ev[j], j, 0, 0, 1.0, 1.0, 0); fflush (stdout); #endif }; /* clean bgo */ if (bitset[8]) { hi = (int) hdr->len; while (i < hi) { /* read germanium data (allways there) */ ev[i].id = (eb->EventData[pos] & 0x00ff); ev[i].bgohit = (unsigned short int) (eb->EventData[pos] & 0xfe00) >> 9; ev[i].gebit = (unsigned short int) (eb->EventData[pos++] & 0x0100) >> 8; #if(DEBUG1) printf ("i=%i, pos=%i, id=%i\n", i, pos, ev[i].id); fflush (stdout); #endif /* make sure the ge id is from 0...110 only */ if ((int) ev[i].id > MAXID) ev[i].id = 0; if (eb->RecordVer == 0) { /* old format 0 wrote a lot of zeroes here */ ev[i].ehi = (eb->EventData[pos] & 0x3fff); ev[i].pu = (unsigned short int) (eb->EventData[pos] & 0x8000) >> 15; ev[i].over = (unsigned short int) (eb->EventData[pos++] & 0x4000) >> 14; ev[i].eside = (eb->EventData[pos++] & M12); /* germanium time */ ev[i].tge = (eb->EventData[pos++] & 0x1fff); /* full ge data */ ev[i].tc = (eb->EventData[pos++] & M12); ev[i].elo = (eb->EventData[pos++] & M12); }; /* bgo data */ ev[i].tbgo = (eb->EventData[pos++]); ev[i].ebgo = (eb->EventData[pos++]); /* next event */ i++; }; #if(DEBUG1) printf ("debug print---> after reading bgo\n"); for (j = 0; j < i; j++) print_event (*hdr, ev[j], j, 0, 0, 1.0, 1.0, 0); fflush (stdout); #endif }; #if(1) /* check position, warn if necessary */ /* don't do this unless you really are debugging */ /* there are way too many errors in the GS data */ /* stream to write it out every time */ if (!(eb->EventData[pos] == 0xffff || eb->EventData[pos] == 0xff00)) { nposprob++; if (Nwarn < NwarnMAX) { Nwarn++; printf ("get_ev: read error report # %i\n", Nwarn); printf ("expected 0xffff or 0xff00 but found 0x%4.4x\n", eb->EventData[pos]); printf ("debug print--->\n"); for (j = 0; j < i; j++) print_event (*hdr, ev[j], j, 0, 0, 1.0, 1.0, 0); #if(1) printf ("buffer number %i,", GetBufferNo_tape ()); printf ("%i, ", GetBufferNo_disk ()); printf ("%i", GetBufferNo_net ()); printf ("\n"); #endif fflush (stdout); if (pos < 6000) { printf ("pos: %i\n", pos); print_buffer_data (eb, pos - 30, pos + 30); } else printf ("____no print out since it is at the end of buffer\n"); if (Nwarn == NwarnMAX) { printf ("\n"); printf ("no more data read errors will be reported\n"); printf ("(max # writeouts = %i reached)\n", NwarnMAX); printf ("\n"); }; }; }; #endif /* now check that we have a 0xff00 or 0xfff */ /* here or hunt for one or the other */ while (!((eb->EventData[pos] == 0xffff) || (eb->EventData[pos] == 0xff00)) && pos < maxword) pos++; /* end of buffer ? */ if (pos > maxword) { /* reset buffer index and send error code back */ /* requesting new buffer read */ if (DEBUG1) printf ("end of buffer, pos=%i, maxword=%i\n", pos, maxword); pos = REALDATAPOS; return (GSIIERRNEWBUF); }; /* set honeycomb suppress flag */ for (i = 0; i < hdr->len; i++) ev[i].hs = 0; for (i = 0; i < hdr->len_clean; i++) { i1 = (int) ev[i].bgohit; if (i1 > 0 && i1 < NGE) ev[i].hs = 1; } #if(0) /* fix bad tge in gsfma233 */ if (gsfma233_timeFix) { for (i = 0; i < hdr->len; i++) switch (ev[i].id) { #include "gsfma233.h" } }; #endif /*--------------------------------------------------------*/ /* check whether we have external detectors at this point */ /*--------------------------------------------------------*/ #if(0) printf ("pos: %i, val: 0x%4.4x\n", pos, eb->EventData[pos]); fflush (stdout); #endif if (eb->EventData[pos] == 0xffff) { /* no external data */ #if(0) printf ("no external data\n"); fflush (stdout); #endif ext[0] = 0; } else if ((eb->EventData[pos] & 0xff00) == 0xff00) { /* we have external detector data */ /* keep reading it until we hit an */ /* 0xffff end-of-event marker */ /* (no interpretation in this routine) */ #if(0) printf ("have external data...\n"); fflush (stdout); #endif /* put number of external events in first slot */ pos++; /* position at the first external data word */ next = 0; if (gs2k008_format) { /* the length of external was not written to tape */ /* so we have to find nextwords by hand */ i1 = pos + 1; while (eb->EventData[i1] != 0xffff && i1 < 16384) i1++; nextwords = i1 - pos; ext[next++] = nextwords; #if(0) printf ("gs2k008_format, nextwords=%i\n", nextwords); #endif } else { /* first word tells how many external words there are */ nextwords = eb->EventData[pos++]; ext[next++] = nextwords; }; /* trap unreasonable long external here */ if (nextwords > 500) { /* reset buffer index and send error code back */ /* requesting new buffer read */ printf ("WARNING: found external longer than 500\n"); printf (" ignoring rest of buffer\n"); fflush (stdout); pos = REALDATAPOS; return (GSIIERRNEWBUF); }; /* then copy the external data to external vector */ while (next <= nextwords && next < (4000 - 1) && pos < maxword) ext[next++] = eb->EventData[pos++]; /* mark the end of external data */ ext[next++] = 0xffff; #if(0) for (i = 0; i <= ext[0]; i++) printf ("gsII_bufp: ext[%2i]=%6i,0x%4.4x\n", i, ext[i], ext[i]); #endif } else { /* this should not happen */ printf ("ooooops, pos: %i\n", pos); print_buffer_data (eb, pos - 30, pos + 30); exit (0); }; /* end of buffer ? */ if (pos > maxword) { /* reset buffer index and send error code back */ /* requesting new buffer read */ pos = REALDATAPOS; return (GSIIERRNEWBUF); }; /*-----------------------------------------------------*/ /* check next entry is an end-of-event as it should be */ /*-----------------------------------------------------*/ #if(0) printf ("\npos at check: %i (true buffer pos:%i);", pos, pos + EB_HEADER_LEN / 2); printf ("maxword: %i\n", maxword); printf ("buffer number tape: %i,", GetBufferNo_tape ()); printf ("disk: %i, ", GetBufferNo_disk ()); printf ("net: %i\n", GetBufferNo_net ()); printf ("eb->EventData[pos] = 0x%4.4x\n", eb->EventData[pos]); #endif if (eb->EventData[pos] == 0xffff) { /* position pointer at the start of the next event */ pos++; /* end of buffer ? (or that we are not too far to continue) */ if (pos > maxword) { #if(DEBUG1) printf ("pos=%i, maxword=%i\n", pos, maxword); #endif pos = REALDATAPOS; return (GSIIERRNEWBUF); }; nev++; return (SUCCESS); /* declare victory */ } else { /* return error */ /* this position should have been an end of the event */ /* and it was not! - so we have a problem */ /* we now write lots of stuff so we can figure out */ /* what happened */ nbad++; if (nbad < NBADMAX) { fflush (stdout); printf ("\n* no end_of_event - found: %i", eb->EventData[pos]); printf (" at pos: %i\n", pos); printf ("buffer number tape: %i,", GetBufferNo_tape ()); printf ("disk: %i, ", GetBufferNo_disk ()); printf ("net: %i\n", GetBufferNo_net ()); printf ("event len: %i\n", hdr->len); printf ("maxword: %i\n", maxword); print_buffer_data (eb, pos - 80, pos + 40); printf ("hdr->len_clean=%i\n", hdr->len_clean); printf ("hdr->len_dirty=%i\n", hdr->len_dirty); printf ("hdr->len_bgo =%i\n", hdr->len_bgo); printf ("hdr->len =%i\n", hdr->len); printf ("done dumping from gsII_buffp.c, return GSIIERRBLOCK\n"); fflush (stdout); }; /* reset index and return error */ /* This should cause the reading of */ /* a new buffer */ pos = REALDATAPOS; hdr->len = 0; return (GSIIERRBLOCK); }; } /*----------------------------------------------------------------*/ /* this function is called whenever we have */ /* a buffer to process */ int gsII_bufp (EVENT_BUFFER * eb, struct EVHDR *hdr, struct EVENT *ev, unsigned int *ext) { /* declarations */ int i; static int first_time = 1; static int DataLen; static int bitset[16]; static int maxword; static int st = 1; static int evno = 0; static unsigned int oldModeFlags = 0; static int bincode[15] = { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384 }; /* prototypes */ int print_buffer_header (EVENT_BUFFER *, int *); int GetBufferNo_tape (void); int GetBufferNo_disk (void); int GetBufferNo_net (void); #if(0) printf ("data>\n"); for (i = 0; i < 30; i++) printf ("%2i -> 0x%4.4x\n", i, eb->EventData[i]); if (1 == 1) exit (0); #endif if (st != 0) { /*----------------------------*/ /* new buffer, so read header */ /*----------------------------*/ evno = 0; /* warn if mode flag changed */ if (eb->ModeFlags != oldModeFlags) if (oldModeFlags != 0) { printf ("WARNING: "); printf ("modeflag changed from 0x%4.4x ", oldModeFlags); printf ("to 0x%4.4x\n", eb->ModeFlags); printf ("__buffer number %i,", GetBufferNo_tape ()); printf ("%i, ", GetBufferNo_disk ()); printf ("%i", GetBufferNo_net ()); printf ("\n"); }; oldModeFlags = eb->ModeFlags; /* extract data structure information from the */ /* buffer header. We need this information to */ /* read the data correctly in get_ev */ for (i = 0; i < 16; i++) if ((eb->ModeFlags & bincode[i]) == bincode[i]) bitset[i] = 1; else bitset[i] = 0; #if(0) /* quit if isomertag flag is on */ /* since we do not know how to */ /* read that data */ if (bitset[9] == 1) { printf ("this data set has the WriteIsomerTag set\n"); printf ("This code does not know how to handle\n"); printf ("this data format!\n"); printf ("\n"); printf ("Quitting....\n"); printf ("\n"); fflush (stdout); exit (0); }; #endif /* find max # words we have */ /* careful: we pass the buffer from where */ /* the data starts, not the beginning of the buffer */ maxword = eb->DataLength; maxword -= EB_HEADER_LEN / 2; if (maxword >= EB_SIZE) return (GSIIERREBSIZE); /*-------------------*/ /* find event length */ /*-------------------*/ /* not actually true for RecordVer=1; but it then takes */ /* the meaning of max len which is what the EFF code */ /* does */ /* __ always hpid, ge_high and ge_side */ DataLen = 3; /* __ ge_time */ if (bitset[4] || bitset[5]) DataLen += 1; /* __ ge_trap and ge_low */ if (bitset[5]) DataLen += 2; /* __ bgo_time and bgo_low */ if (bitset[6]) DataLen += 2; /* debug info */ if (first_time == 1) { first_time = 0; print_buffer_header (eb, bitset); fflush (stdout); }; /* extract events from the buffer */ /* note: negative st is true error whereas st=1 */ /* signals that all data in present buffer have been read */ }; /* get the next event */ st = get_ev (eb, bitset, maxword, DataLen, (struct EVHDR *) hdr, (struct EVENT *) ev, ext); /* done */ return (st); }