Index: /trunk/FACT++/src/EventBuilder.c
===================================================================
--- /trunk/FACT++/src/EventBuilder.c	(revision 11520)
+++ /trunk/FACT++/src/EventBuilder.c	(revision 11521)
@@ -275,20 +275,50 @@
 
 
-int mBufEvt( int evID, uint runID, int nRoi, int sk, int fadlen) {
+int mBufEvt( int evID, uint runID, int nRoi[8], int sk, int fadlen) {
 // generate a new Event into mBuffer:   
 // make sure only complete Event are possible, so 'free' will always work
 // returns index into mBuffer[], or negative value in case of error
-
-
-   int i, k, evFree ;
+// error: <-9000 if roi screwed up (not consistent with run)
+//        <-8000                   (not consistent with event)
+//        <-7000                   (not consistent with board)
+//        < 0    if no space left
+
+   struct timeval  *tv, atv;
+   tv=&atv;
+   uint32_t tsec, tusec ;
+
+   int i, k, jr, b, evFree ;
    int headmem=0 ;
    size_t needmem = 0 ;
 
-   if (nRoi <0 || nRoi > 1024) {
-      snprintf(str,MXSTR,"illegal nRoi: %d",nRoi) ;
-      factOut(kError, 1, str ) ;
+
+   b = sk/7 ;
+
+   if (nRoi[0] <0 || nRoi[0] > 1024) {
+      snprintf(str,MXSTR,"illegal nRoi[0]: %d",nRoi[0]) ;
+      factOut(kError, 999, str ) ;
+      gj.badRoiR++ ;
+      gj.badRoi[b]++ ;
       return -9999 ;
    }
 
+   for (jr=1; jr<8; jr++) {
+      if ( nRoi[jr] != nRoi[0] ) {
+         snprintf(str,MXSTR,"wrong nRoi[%d]: %d %d",jr,nRoi[jr],nRoi[0]) ;
+         factOut(kError,711, str ) ;
+         gj.badRoiB++ ;
+         gj.badRoi[b]++ ;
+         return -7101 ;
+      }
+   }
+   if ( nRoi[8] < nRoi[0] ) {
+         snprintf(str,MXSTR,"wrong nRoi_TM: %d %d",nRoi[8],nRoi[0]) ;
+         factOut(kError,712, str ) ;
+         gj.badRoiB++ ;
+         gj.badRoi[b]++ ;
+         return -7102 ;
+   }
+
+
    i = evID % MAX_EVT ;
    evFree = -1 ;
@@ -296,5 +326,16 @@
    for ( k=0; k<MAX_RUN; k++) {
       if ( mBuffer[i].evNum == evID
-        && mBuffer[i].runNum== runID ) {
+        && mBuffer[i].runNum== runID ) {   //event is already registered;
+                                           // is it ok ????
+         if ( mBuffer[i].nRoi   != nRoi[0] 
+           || mBuffer[i].nRoiTM != nRoi[8] ) {
+            snprintf(str,MXSTR,"illegal evt_roi %d %d ; %d %d",
+              nRoi[0],nRoi[8], mBuffer[i].nRoi, mBuffer[i].nRoiTM );
+            factOut(kError,821, str ) ;
+            gj.badRoiE++ ;
+            gj.badRoi[b]++ ;
+            return -8201 ;
+         }
+         //everything seems fine so far ==> use this slot ....
          return i ;  
       }
@@ -304,5 +345,5 @@
 
 
-   //event does not yet exist; create
+   //event does not yet exist; create it
    if (evFree < 0 ) {        //no space available in ctrl
         snprintf(str,MXSTR,"no control slot to keep event %d",evID) ;
@@ -312,6 +353,57 @@
    i = evFree ;   //found free entry; use it ...
 
+   gettimeofday( tv, NULL);
+   tsec = atv.tv_sec ;
+   tusec= atv.tv_usec ; 
+
+   //check if runId already registered in runCtrl
+   evFree = -1 ;
+   for (k=0; k<MAX_RUN; k++) {
+      if (runCtrl[k].runId == runID ) {
+         if ( runCtrl[k].roi0 != nRoi[0]
+           || runCtrl[k].roi8 != nRoi[8] ) {
+            snprintf(str,MXSTR,"illegal run_roi %d %d ; %d %d",
+               nRoi[0],nRoi[8],runCtrl[k].roi0,runCtrl[k].roi8 );
+            factOut(kError,931, str ) ;
+            gj.badRoiR++ ;
+            gj.badRoi[b]++ ;
+            return -9301 ;
+         }
+         goto RUNFOUND ;
+      }
+      else if (evFree < 0 && runCtrl[k].runId == 0 ) evFree = k ;
+   }
    
-   needmem = sizeof(EVENT) + NPIX*nRoi*2 + NTMARK*nRoi*2; //
+   if (evFree <0 ) {
+      snprintf(str,MXSTR,"not able to register the new run %d",runID);
+      factOut(kFatal,883, str ) ;
+      return -1001 ;
+   } else {
+      snprintf(str,MXSTR,"register new run %d roi: %d %d",runID,nRoi[0],nRoi[8]) ;
+      factOut(kInfo,503, str ) ;
+      runCtrl[evFree].runId = runID ;
+      runCtrl[evFree].roi0  = nRoi[0] ;
+      runCtrl[evFree].roi8  = nRoi[8] ;
+      runCtrl[evFree].fileId = -2 ;
+      runCtrl[evFree].lastEvt= -1 ;
+      runCtrl[evFree].nextEvt= 0;
+      runCtrl[evFree].actEvt = 0;
+      runCtrl[evFree].maxEvt = 999999999 ; //max number events allowed
+      runCtrl[evFree].firstUsec=tusec ;
+      runCtrl[evFree].firstTime=
+      runCtrl[evFree].lastTime=tsec ;
+      runCtrl[evFree].closeTime=tsec + 3600*24 ; //max time allowed
+      runCtrl[evFree].lastTime = 0 ;
+
+      runTail[evFree].nEventsOk =
+      runTail[evFree].nEventsRej =
+      runTail[evFree].nEventsBad =
+      runTail[evFree].PCtime0 =
+      runTail[evFree].PCtimeX = 0 ;
+   }
+   
+RUNFOUND:
+
+   needmem = sizeof(EVENT) + NPIX*nRoi[0]*2 + NTMARK*nRoi[0]*2; //
 
    headmem = NBOARDS* sizeof(PEVNT_HEADER) ;
@@ -346,4 +438,6 @@
    }
 
+
+
    //flag all boards as unused
    mBuffer[i].nBoard = 0 ;
@@ -351,10 +445,8 @@
       mBuffer[i].board[k] = -1;
    }
-
    //flag all pixels as unused
    for (k=0; k<NPIX; k++ ) {
       mBuffer[i].fEvent->StartPix[k] = -1 ;
    }
-
    //flag all TMark as unused
    for (k=0; k<NTMARK; k++ ) {
@@ -362,8 +454,10 @@
    }
 
-   mBuffer[i].fEvent->PCUsec = g_actUsec ;
+   mBuffer[i].fEvent->NumBoards = 0 ;
+   mBuffer[i].fEvent->PCUsec = tusec ;
    mBuffer[i].fEvent->PCTime = 
-   mBuffer[i].pcTime  = g_actTime ;
-   mBuffer[i].nRoi    = nRoi ;
+   mBuffer[i].pcTime  = tsec ;
+   mBuffer[i].nRoi    = nRoi[0] ;
+   mBuffer[i].nRoiTM  = nRoi[8] ;
    mBuffer[i].evNum   = evID  ;
    mBuffer[i].runNum  = runID ;
@@ -383,6 +477,6 @@
 
 
-   snprintf(str,MXSTR,"%5d start new evt  %8d %8d sock %3d len %5d t %10d",
-      evID,i,evtCtrl.lastPtr,sk,fadlen,mBuffer[i].pcTime);
+   snprintf(str,MXSTR,"%5d %8d start new evt  %8d %8d sock %3d len %5d t %10d",
+      evID,runID,i,evtCtrl.lastPtr,sk,fadlen,mBuffer[i].pcTime);
    factOut(kDebug,-11, str ) ;
    evtCtrl.lastPtr++ ;
@@ -391,34 +485,4 @@
    gi.evtGet++ ;
 
-   //check if runId already registered in runCtrl
-   evFree = -1 ;
-   for (k=0; k<MAX_RUN; k++) {
-      if (runCtrl[k].runId == runID ) return i ;//run exists already
-      else if (evFree < 0 && runCtrl[k].runId == 0 ) evFree = k ;
-   }
-   
-   if (evFree <0 ) {
-      snprintf(str,MXSTR,"not able to register the new run %d",runID);
-      factOut(kFatal,883, str ) ;
-   } else {
-      runCtrl[evFree].runId = runID ;
-      runCtrl[evFree].fileId = -2 ;
-      runCtrl[evFree].lastEvt= -1 ;
-      runCtrl[evFree].nextEvt= 0;
-      runCtrl[evFree].actEvt = 0;
-      runCtrl[evFree].maxEvt = 999999999 ; //max number events allowed
-      runCtrl[evFree].firstUsec=g_actUsec ;
-      runCtrl[evFree].firstTime=
-      runCtrl[evFree].lastTime=g_actTime ;
-      runCtrl[evFree].closeTime=g_actTime + 3600*24 ; //max time allowed
-      runCtrl[evFree].lastTime = 0 ;
-
-      runTail[evFree].nEventsOk =
-      runTail[evFree].nEventsRej =
-      runTail[evFree].nEventsBad =
-      runTail[evFree].PCtime0 =
-      runTail[evFree].PCtimeX = 0 ;
-   }
-
    return i ;
  
@@ -469,4 +533,5 @@
      gi.gotByte[i] = 0 ;
      gi.gotErr[i]  = 0 ;
+
   }
 
@@ -508,5 +573,5 @@
   int32_t jrd ;
   uint gi_SecTime ;        //time in seconds
-  int boardId, roi,drs,px,src,pixS,pixH,pixC,pixR,tmS ;
+  int boardId, roi[8],drs,px,src,pixS,pixH,pixC,pixR,tmS ;
 
   int goodhed = 0 ;
@@ -525,5 +590,4 @@
 
 
-  gi_myRun   = g_actTime ;
   snprintf(str,MXSTR,"start initializing");
   factOut(kInfo,-1, str ) ;
@@ -560,4 +624,8 @@
 
 START:
+  gettimeofday( tv, NULL);
+  g_actTime = tsec = atv.tv_sec ;
+  g_actUsec = tusec= atv.tv_usec ; 
+  gi_myRun  = g_actTime ;
   evtCtrl.frstPtr = 0 ;
   evtCtrl.lastPtr = 0 ;
@@ -592,6 +660,9 @@
      gj.totMem = g_maxMem ;
      gj.bufNew = gj.bufEvt = 0 ;
-     gj.evtSkip= gj.evtWrite = gj.evtErr = 0 ;
-
+     gj.badRoiE = gj.badRoiR = gj.badRoiB = 
+     gj.evtSkip = gj.evtWrite = gj.evtErr = 0 ;
+
+     int b ;
+     for (b=0; b<NBOARDS; b++) gj.badRoi[b]=0 ;
 
      mBufInit() ;    //initialize buffers
@@ -608,4 +679,8 @@
     gi_runStat = g_runStat;
     gj.readStat= g_runStat;
+    gettimeofday( tv, NULL);
+    g_actTime = tsec = atv.tv_sec ;
+    g_actUsec = tusec= atv.tv_usec ; 
+
 
     int b,p,p0,s0,nch; 
@@ -649,8 +724,4 @@
       if (sockDef[b] > 0) s0= +1 ;
       else                s0= -1 ;
-
-      gettimeofday( tv, NULL);
-      g_actTime = tsec = atv.tv_sec ;
-      g_actUsec = tusec= atv.tv_usec ; 
 
       if (rd[i].sockStat <0 ) {         //try to connect if not yet done
@@ -749,10 +820,16 @@
 
              //we have a complete buffer, copy to WORK area
-             roi = ntohs(rd[i].rBuf->S[ head_len/2 + 2 ]) ; 
+             int jr ;
+             roi[0] = ntohs(rd[i].rBuf->S[ head_len/2 + 2 ]) ; 
+             for (jr=0; jr<9; jr++) {
+                roi[jr] = ntohs(rd[i].rBuf->S[ head_len/2 + 2 + jr*(roi[0]+4) ]) ; 
+             }
              //get index into mBuffer for this event (create if needed)
              evID = mBufEvt( rd[i].evtID, rd[i].runID, roi, i, rd[i].fadLen ) ;
 
-             if (evID <-9000) goto EndBuf ;  //illegal event, skip it ...
-             if (evID < 0) {
+             if (evID <-1000) {
+                goto EndBuf ;  //not usable board/event/run --> skip it
+             }
+             if (evID < 0) {    //no space left, retry later
 
      if ( rd[i].bufLen != 0) { 
@@ -803,5 +880,5 @@
              memcpy( &mBuffer[evID].FADhead[boardId].start_package_flag,
                         &rd[i].rBuf->S[0], head_len) ;
-             roi  = mBuffer[evID].nRoi ;
+//  xxx          roi  = mBuffer[evID].nRoi ;
 
              src  = head_len/2 ;
@@ -816,36 +893,37 @@
                    src++  ;
 
-                   if ( ( px != 8 && pixR == roi )
-                     || ( px == 8 && pixR >= roi ) ) {   //we have a reasonable roi
+//  xxx                 if ( ( px != 8 && pixR == roi )
+//  xxx                   || ( px == 8 && pixR >= roi ) ) {   //we have a reasonable roi
                       
                       mBuffer[evID].fEvent->StartPix[pixS] =pixC;
-                      dest= pixS * roi ;
+                      dest= pixS * roi[0] ;
                       memcpy(
                            &mBuffer[evID].fEvent->Adc_Data[dest],
-                           &rd[i].rBuf->S[src],  roi * 2) ;
+                           &rd[i].rBuf->S[src],  roi[0] * 2) ;
                       src+= pixR ;
 
                       if ( px==8 ) {
-                         if ( pixR > roi) {          //and we have additional TM info
+                         if ( pixR > roi[0]) {          //and we have additional TM info
                             tmS =boardId*4 + drs ;
-                            dest= tmS * roi + NPIX* roi ;
-                            int srcT= src - roi ;
-                            mBuffer[evID].fEvent->StartTM[tmS] = (pixC+pixR-roi)%1024 ;
+                            dest= tmS * roi[0] + NPIX* roi[0] ;
+                            int srcT= src - roi[0] ;
+                            mBuffer[evID].fEvent->StartTM[tmS] = (pixC+pixR-roi[0])%1024 ;
                             memcpy(
                               &mBuffer[evID].fEvent->Adc_Data[dest],
-                              &rd[i].rBuf->S[srcT],  roi * 2) ;
+                              &rd[i].rBuf->S[srcT],  roi[0] * 2) ;
                          } else {
                             mBuffer[evID].fEvent->StartTM[tmS] = -1 ;
                          }
                       }
-                   } else {
-                      snprintf(str,MXSTR,"wrong roi %d %d %d %d",px,pixR,roi,src-2);
-                      gi.evtErr++ ;
-                      factOut(kError,202, str ) ;
-                      goto EndBuf ;
-                   }
+//  xxx                 } else {
+//  xxx                    snprintf(str,MXSTR,"wrong roi %d %d %d %d",px,pixR,roi,src-2);
+//  xxx                    gi.evtErr++ ;
+//  xxx                    factOut(kError,202, str ) ;
+//  xxx                    goto EndBuf ;
+//  xxx                 }
                 }
              }// now we have stored a new board contents into Event structure
 
+             mBuffer[evID].fEvent->NumBoards++ ;
              mBuffer[evID].board[ boardId ] = boardId ;
              evtCtrl.evtStat[ iDx ]++ ;
@@ -857,10 +935,9 @@
 
                 if (mBuffer[evID].runNum != actrun ) {        // have we already reported first event of this run ???
-                   actrun = mBuffer[i].runNum ;
+                   actrun = mBuffer[evID].runNum ;
                    int ir ;
                    for ( ir=0; ir<MAX_RUN; ir++) {
                       if ( runCtrl[ir].runId == actrun) {
-                         if ( runCtrl[ir].lastEvt <0 ) {
-                            runCtrl[ir].lastEvt = +1 ;
+                         if ( ++runCtrl[ir].lastEvt ==0 ) {
                             gotNewRun( actrun, mBuffer[evID].FADhead ); 
                 snprintf(str,MXSTR,"gotNewRun %d (ev %d)",mBuffer[evID].runNum,mBuffer[evID].evNum);
@@ -1010,6 +1087,6 @@
        factStat(gj);
        factStatNew(gi) ;
-
        gj.rateNew = gj.rateWrite = 0 ;
+       gj.maxMem  = gj.usdMem ; 
        for ( b=0; b<NBOARDS; b++) gj.rateBytes[b] =0 ;
     }
@@ -1390,6 +1467,4 @@
                  factOut(kFatal,901, str ) ;
                  gi.wrtErr++ ;
-for ( j=0; j<MAX_RUN; j++) printf("j %d   run.j %d   run %d\n",j,runCtrl[j].runId,irun );
-exit(111);
               }
               lastRun = j ;
@@ -1398,6 +1473,9 @@
            if (runCtrl[j].fileId < 0 ) {
               actRun.Version =  1 ;
-              actRun.RunType = -1 ;
-
+              actRun.RunType = -1 ;      //to be adapted
+
+              actRun.Nroi    = runCtrl[j].roi0 ;
+              actRun.NroiTM  = runCtrl[j].roi8 ;
+              if ( actRun.Nroi == actRun.NroiTM ) actRun.NroiTM = 0 ;
               actRun.RunTime = runCtrl[j].firstTime ;
               actRun.RunUsec = runCtrl[j].firstTime ;
@@ -1414,5 +1492,5 @@
                  runCtrl[j].fileId = 91 ;
               } else {
-                 snprintf(str,MXSTR,"W opened new run_file %d",irun) ;
+                 snprintf(str,MXSTR,"W opened new run_file %d evt %d",irun,ievt) ;
                  factOut(kInfo,-1, str ) ;
                  runCtrl[j].fileId = 0 ;
Index: /trunk/FACT++/src/FAD.h
===================================================================
--- /trunk/FACT++/src/FAD.h	(revision 11520)
+++ /trunk/FACT++/src/FAD.h	(revision 11521)
@@ -119,4 +119,7 @@
   uint16_t TriggerType ;    // Trigger Type from FTM
 
+  uint32_t NumBoards ;      // number of active boards included
+  uint32_t reserved ;       // not yet used
+
   uint32_t SoftTrig ;       // SoftTrigger Info (TBD)
   uint32_t PCTime ;         // epoch
@@ -145,8 +148,9 @@
   uint32_t RunTime ;  //unix epoch for first event
   uint32_t RunUsec ;  //microseconds
-  uint16_t NBoard  ;
-  uint16_t NPix ;
-  uint16_t NTm  ;
-  uint16_t Nroi ;
+  uint16_t NBoard  ;  //#boards (always 40)
+  uint16_t NPix ;     //#pixels (always 1440)
+  uint16_t NTm  ;     //#TM     (always 160)
+  uint16_t Nroi ;     //roi for pixels
+  uint16_t NroiTM ;   //roi for TM  <=0 if TM is empty 
 
 //headers of all FAD-boards for first event ==> all FAD configs
@@ -193,7 +197,10 @@
   uint32_t waitEvt ;     //event that would be ready to be written
    int32_t fileId  ;     //<0 never opened, 0=open, >0 closed
+   int16_t roi0 ;        //roi for normal pixels
+   int16_t roi8 ;        //roi for pixels8
+
   FileHandle_t fileHd ;   //fileHandle (NULL if not open)
-   int16_t ctrlId[MAX_EVT] ; //index to buffId (sorted list; -1 =end)
-  uint16_t buffId[MAX_EVT] ; //index to mBuffer(buffered raw data)
+//   int16_t ctrlId[MAX_EVT] ; //index to buffId (sorted list; -1 =end)
+//  uint16_t buffId[MAX_EVT] ; //index to mBuffer(buffered raw data)
 } RUN_CTRL ;
 
@@ -209,5 +216,6 @@
   int32_t  nBoard ;
   int16_t  board[ NBOARDS ];
-  int32_t  nRoi   ;
+  int16_t  nRoi   ;
+  int16_t  nRoiTM ;
   uint32_t pcTime ;
   int32_t  evtLen ;
@@ -304,4 +312,8 @@
    int32_t  evtWrite ;          //# Events written (or flushed if noWrite) 
    int32_t  evtErr ;            //# Events with errors 
+   int32_t  badRoiE;            //# boards with wrong roi (inconsistent in event)
+   int32_t  badRoiR;            //# boards with wrong roi (inconsistent in run)
+   int32_t  badRoiB;            //# boards with wrong roi (inconsistent in board)
+   int32_t  badRoi[NBOARDS];    //# boards with wrong roi 
 
   //rates
