Index: /fact/FADctrl/FAD.cc
===================================================================
--- /fact/FADctrl/FAD.cc	(revision 10912)
+++ /fact/FADctrl/FAD.cc	(revision 10913)
@@ -30,10 +30,10 @@
    {"reset", &FAD::cmd_reset, true, 0, "", "Reset internal trigger counter"},
    {"runnumber", &FAD::cmd_runnumber, true, 1, "<n>", "Set runnumber"},
-   {"roi", &FAD::cmd_roi, true, 2, "<channel range> <value>", "Set region-of-interest to value"},
+   {"roi", &FAD::cmd_roi, true, 2, "<range> <value>", "Set ROI to for channel range to value"},
    {"dac", &FAD::cmd_dac, true, 2, "<range> <value>", "Set DAC numbers in range to value"},
    {"address", &FAD::cmd_address, true, 2, "<range> <value>", "Set addresses in range to value"},
    {"send", &FAD::cmd_send, true, 1, "<value>", "Send arbitrary data to board"},
-   {"take", &FAD::cmd_take, true, 1, "<n> <dir>", "Start run with n events, write to directory"},
-   {"acalib", &FAD::cmd_acalib, true, 0, "[n|invalidate|file]", "Perform or read amplitude calibration (n events)"},
+   {"take", &FAD::cmd_take, true, 1, "<n> <dir>", "Start run with n events (n=0 -> unlimited)"},
+   {"acalib", &FAD::cmd_acalib, true, 0, "[n|inval|file]", "Perform or read amplitude calibration (n events)"},
    //{"wmode", &FAD::cmd_wmode, 0, "<run|stop>", "Domino wave running or stopped during read out"},
    //{"rmode", &FAD::cmd_rmode, 0, "<first|stop>", "Readout start at first bin or stop position (DRS4)"},
@@ -827,30 +827,31 @@
 void FAD::EventThread() {
 
-  struct timeval Time, RunStart;
+  struct timeval Time;
   struct timeval LastUpdate; 
   struct FADBoard::BoardStatus S;
   vector<unsigned long> EventNumbers(Boards.size());
   vector<bool> AcalibDone(Boards.size());
+  map<unsigned int, class FADBoard *> ActiveBoards;
   double Temp;
   string IDString;
   char Buffer[100];
   int Ret;
-  unsigned long long FileSize = 0;
+  struct stat FileStat;
+  float FileSizeMB = 0;
+  RunHeader FileRHeader;
 
   gettimeofday(&LastUpdate, NULL);
-  RunStart = LastUpdate; // only to avoid 'uninitialized' warning from compiler
   
   // Create DIM event data and number services
-  int EventSize = sizeof(RunHeader)+ Boards.size()*sizeof(BoardStructure)+sizeof(EventHeader) + Boards.size()*(NChips*NChannels*NBins*sizeof(short) + NChips*sizeof(int));
-  char *EventData = new char [EventSize];
-
-  memset(EventData, 0, EventSize);
+  char *EventData = new char [sizeof(RunHeader)+ Boards.size()*sizeof(BoardStructure)+sizeof(EventHeader) + Boards.size()*(NChips*NChannels*NBins*sizeof(short) + NChips*sizeof(int))];
 
   DimService EventService(SERVER_NAME"/EventData", (char *) "C", NULL, 0);
   DimService EventNumService(SERVER_NAME"/EventNumber", NumEvents);
-
-  // Calculate pointers to EventData array
+  DimService FileSizeService(SERVER_NAME"/FileSizeMB", FileSizeMB);
+
+  // Calculate pointers to EventData array (will be updated when active number of boards changes)
   RunHeader *RHeader = (RunHeader *) EventData;
   BoardStructure **BStruct = new BoardStructure * [Boards.size()];
+
   for (unsigned int i=0; i<Boards.size(); i++) BStruct[i] = ((BoardStructure *) (RHeader + 1)) + i;
   EventHeader *EHeader = (EventHeader *) ((char *) (RHeader + 1) + Boards.size()*sizeof(BoardStructure));
@@ -858,5 +859,6 @@
   short *Data = (short *) (TriggerCell + NChips*Boards.size());
 
-  // M0 RunHeader
+  // Fill fixed entries in M0 RunHeader
+  RHeader->MagicNum = MAGICNUM_CLOSED;
   RHeader->DataFormat = DATA_FORMAT;
   RHeader->RunHeaderSize = sizeof(RunHeader);
@@ -865,12 +867,11 @@
   RHeader->SoftwareRevision = atoi(REVISION) * (strchr(REVISION, 'M')==NULL ? 1:-1);
   RHeader->Identification = 0;
-
   RHeader->Type = 0;				// Run type: 0=data, 1=pedestal, 3=test
-
   RHeader->RunNumber = -1;
   RHeader->FileNumber = 0;
   snprintf(RHeader->Description, sizeof(RHeader->Description), "FADctrl");       
-
-  RHeader->NBoards = Boards.size();
+  RHeader->Events = 1;
+  RHeader->StartSecond = LastUpdate.tv_sec;			
+  RHeader->StartMicrosecond = LastUpdate.tv_usec;		
   RHeader->NChips = NChips;
   RHeader->NChannels = NChannels;
@@ -879,7 +880,4 @@
   RHeader->NBytes = sizeof(short);
 
-  // M0 EventHeader
-  EHeader->EventSize = Boards.size()*(NChips*NChannels*NBins*sizeof(short) + NChips*sizeof(int));
-
   // Update loop
   while (!ExitRequest) {
@@ -896,5 +894,18 @@
 	IDString.append(string(Buffer, Ret));
 
-	// If amplitude calibration mode, check if board finished procedure
+	// Active boards for DIM and data taking must only change when idle
+	if (Mode == idle) {
+	  ActiveBoards.clear();
+	  for (unsigned int i=0; i<Boards.size(); i++) if (Boards[i]->Active) ActiveBoards[i] = Boards[i];
+	  RHeader->NBoards = ActiveBoards.size();
+	  
+	  // Calculate updated pointers to EventData array
+	  for (unsigned int i=0; i<ActiveBoards.size(); i++) BStruct[i] = ((BoardStructure *) (RHeader + 1)) + i;
+	  EHeader = (EventHeader *) ((char *) (RHeader + 1) + ActiveBoards.size()*sizeof(BoardStructure));
+	  TriggerCell = (int *) (EHeader + 1);
+	  Data = (short *) (TriggerCell + NChips*ActiveBoards.size());
+	}
+
+	// If amplitude calibration mode, check if all boards finished procedure
 	if (Mode == acalib) {
 	  bool Done = true;
@@ -912,50 +923,19 @@
 	else for (unsigned int i=0; i<Boards.size(); i++) AcalibDone[i] = false;
 
-	// Update run and event header with current time
+	// Update run and event header
 	gettimeofday(&Time, NULL);
-
-	RHeader->MagicNum = MAGICNUM_CLOSED;
 	RHeader->EndSecond = Time.tv_sec;			
 	RHeader->EndMicrosecond = Time.tv_usec;		
 
+    EHeader->EventSize = RHeader->NBoards * (NChips*NChannels*NBins*sizeof(short) + NChips*sizeof(int));
 	EHeader->Second = Time.tv_sec;
 	EHeader->Microsecond = Time.tv_usec;
 
-	// Close data file if requested or requested number of events reached
-	if((IDString.find("stop")!=string::npos || NumEvents==NumEventsRequested) && Mode==datarun) {
-
-	  // Update run header	
-	  RHeader->Events = NumEvents;
-	  RHeader->StartSecond = RunStart.tv_sec;
-	  RHeader->StartMicrosecond = RunStart.tv_usec;		
-
-	  if (lseek(Datafile, 0, SEEK_SET) == -1) {
-	    Message(ERROR, "Could not rewind file to write updated run header (%s)", strerror(errno));
-	  }
-	  else if (write(Datafile, RHeader, sizeof(RunHeader)) != sizeof(RunHeader)) {
-		Message(ERROR, "Could not write updated run header (%s)", strerror(errno));
-	  }
-
-	  // Close data file and terminate run
-	  if(close(Datafile) == -1) Message(ERROR, "Could not close data file (%s)", strerror(errno));
-	  else PrintMessage("Data file closed (size %.1f MByte).\n", FileSize/1024.0/1024);
-
-	  Datafile = -1;
-	  Mode = idle;
-	  Message(INFO, "Data run ended, mode set to IDLE");	  
-	}
-
-	// These values might have changed while close file
-	RHeader->StartSecond = Time.tv_sec;
-	RHeader->StartMicrosecond = Time.tv_usec;		
-    RHeader->Events = 1;
-
 	// Check all boards that have new data
-	for (unsigned int Brd=0; Brd<Boards.size(); Brd++) {
-	  // Identify board
+	for (unsigned int Brd=0; Brd<ActiveBoards.size(); Brd++) {
 	  if (IDString.find(string("EVENT")+Boards[Brd]->Name) == string::npos) continue;
 
 	  // Fill M0 BoardStructure		
-	  S = Boards[Brd]->GetStatus();
+	  S = ActiveBoards[Brd]->GetStatus();
 	  BStruct[Brd]->SerialNo = (U32) S.DNA;
 	  BStruct[Brd]->NomFreq = S.Frequency;
@@ -978,12 +958,12 @@
 	  memset(Data+Count, 0, NChips*NChannels*NBins*sizeof(short));
 
-	  Boards[Brd]->Lock();
+	  ActiveBoards[Brd]->Lock();
 	  for (unsigned int Chip=0; Chip<NChips; Chip++) for (unsigned int Chan=0; Chan<NChannels; Chan++) {
 		for (int i=0; i<S.ROI[Chip][Chan]; i++) {
-		  if (Boards[Brd]->ACalib.Time == -1) Data[Count++] = Boards[Brd]->Data[Chip][Chan][i];
+		  if (ActiveBoards[Brd]->ACalib.Time == -1) Data[Count++] = ActiveBoards[Brd]->Data[Chip][Chan][i];
 		  else {
-		    Temp = (Boards[Brd]->Data[Chip][Chan][i] - Boards[Brd]->ACalib.Baseline[Chip][Chan][(i+S.TriggerCell[Chip])%NBins]);
-			Temp *= Boards[Brd]->ACalib.Gain[Chip][Chan][0]/Boards[Brd]->ACalib.Gain[Chip][Chan][(i+S.TriggerCell[Chip])%NBins];
-			//Temp -= Boards[Brd]->ACalib.Secondary[Chip][Chan][i];
+		    Temp = (ActiveBoards[Brd]->Data[Chip][Chan][i] - ActiveBoards[Brd]->ACalib.Baseline[Chip][Chan][(i+S.TriggerCell[Chip])%NBins]);
+			Temp *= ActiveBoards[Brd]->ACalib.Gain[Chip][Chan][0]/ActiveBoards[Brd]->ACalib.Gain[Chip][Chan][(i+S.TriggerCell[Chip])%NBins];
+			//Temp -= ActiveBoards[Brd]->ACalib.Secondary[Chip][Chan][i];
 			Data[Count++] = (short) Temp;
 		  }
@@ -991,6 +971,10 @@
 		Count += NBins - S.ROI[Chip][Chan];
 	  }
-
-	  // Inform TCP/IP thread that data has been processed	  
+  	  ActiveBoards[Brd]->Unlock();
+	}
+
+	// Inform TCP/IP thread of all boards that send data that processing is finished
+	for (unsigned int Brd=0; Brd<Boards.size(); Brd++) if (IDString.find(string("EVENT")+Boards[Brd]->Name) != string::npos) {
+	  Boards[Brd]->Lock();
 	  Boards[Brd]->Continue = true;
 	  Boards[Brd]->Unlock();
@@ -999,15 +983,15 @@
 		Message(FATAL, "pthread_cond_signal() failed (%s)", strerror(Ret));
 	  }
-	} // Loop over boards
+	}
 
 	// Check if DIM service should be updated
 	if ((Time.tv_sec-LastUpdate.tv_sec)*1e6 + Time.tv_usec-LastUpdate.tv_usec > EventUpdateDelay*1e6) {
 	  gettimeofday(&LastUpdate, NULL);
-	  EventService.updateService(EventData, EventSize);
+	  EventService.updateService(EventData, sizeof(RunHeader) + sizeof(EventHeader) + ActiveBoards.size()*(sizeof(BoardStructure) + NChips*NChannels*NBins*sizeof(short) + NChips*sizeof(int)));
 	  EventNumService.updateService();
+	  if (Mode == datarun) FileSizeService.updateService();
 	}
 	
-	// ===== Data writing ===
-	
+	// ===== Data writing ===	
 	if (Mode != datarun) continue;
 	
@@ -1024,19 +1008,54 @@
 	if (CommonEventNum == numeric_limits<unsigned long>::max()) continue;
 
-	// Write also run header if this is the first event
-	int Offset;	
+	int Error = 0;
+
+	// Initialize run
 	if (NumEvents == 0) {
-	  RHeader->MagicNum = MAGICNUM_OPEN;
-	  RunStart = Time;
-	  Offset = 0;
-	  FileSize = 0;
-	}
-	else Offset = sizeof(RunHeader) + Boards.size()*sizeof(BoardStructure);
+	  FileSizeMB = 0;
+
+	  FileRHeader = *RHeader;
+	  FileRHeader.MagicNum = MAGICNUM_OPEN;
+	  FileRHeader.StartSecond = Time.tv_sec;
+	  FileRHeader.StartMicrosecond = Time.tv_usec;		
+
+	  // Write run header and board structures
+	  if (write(Datafile, &FileRHeader, sizeof(RunHeader)) == -1) Error = errno;
+	  else if (write(Datafile, BStruct[0], FileRHeader.NBoards*sizeof(BoardStructure)) == -1) Error = errno;
+	}
+
+	// Write event header, trigger cells and ADC data to file
+	if (write(Datafile, EHeader, sizeof(EventHeader)+NChips*sizeof(int)+ActiveBoards.size()*NChips*NChannels*NBins*sizeof(short)) == -1) Error = errno;
+
+	NumEvents++;
+
+	// Write event header to file
+	//if(write(Datafile, EHeader, sizeof(EventHeader)) != sizeof(EventHeader)) Error = true;
+
+	// Write trigger cells
+	//for (unsigned int i=0; i<ActiveBoards.size(); i++) {
+	  //if(write(Datafile, TriggerCell + i*NChips, NChips*sizeof(int)) != NChips*sizeof(int)) Error = true;
+	//}
+
+	// Write ADC data
+	//unsigned int Bins = NChips*NChannels*NBins;
+	//for (unsigned int i=0; i<ActiveBoards.size(); i++) {
+	  //if(write(Datafile, Data+i*Bins, Bins*sizeof(short)) != (ssize_t) (Bins*sizeof(short))) Error = true;
+	//}
 	
-	// Write data to file
-	if(write(Datafile, EventData+Offset, EventSize-Offset) != (ssize_t) EventSize-Offset) {
-	  Message(ERROR, "Could not write all data to file, terminating run, setting mode to IDLE (%s)", strerror(errno));
-
-	  // Close file if error
+	// Update file size
+	if (fstat(Datafile, &FileStat) == -1) Error = errno;
+    else FileSizeMB = FileStat.st_size/1024.0/1024.0;
+
+	// Check for write errors and for correct file size
+	if (Error !=0) {
+	  Message(ERROR, "Error writing to data data file (%s), terminating run, setting mode to IDLE", strerror(Error));
+	}
+	else if ((size_t) FileStat.st_size != sizeof(RunHeader)+ FileRHeader.NBoards*sizeof(BoardStructure)+NumEvents*(sizeof(EventHeader) + FileRHeader.NBoards*(NChips*NChannels*NBins*sizeof(short) + NChips*sizeof(int)))) {
+	  Message(ERROR, "Could not write all data to file, terminating run, setting mode to IDLE");
+	  Error = 1;
+	}
+
+	// Close file if error
+	if (Error != 0) {
 	  if (close(Datafile) == -1) Message(ERROR, "Could not close data file (%s)", strerror(errno));
 	  Datafile = -1;
@@ -1045,11 +1064,32 @@
 	}
 	
-	NumEvents++;
-	FileSize += EventSize-Offset;
+	// Close data file if requested or requested number of events reached
+	if(IDString.find("stop")!=string::npos || (NumEvents==NumEventsRequested && NumEventsRequested!=0)) {
+
+	  // Update run header for writing	
+	  FileRHeader.MagicNum = MAGICNUM_CLOSED; 
+	  FileRHeader.Events = NumEvents;
+	  FileRHeader.EndSecond = Time.tv_sec;			
+	  FileRHeader.EndMicrosecond = Time.tv_usec;		
+
+	  if (lseek(Datafile, 0, SEEK_SET) == -1) {
+	    Message(ERROR, "Could not rewind file to write updated run header (%s)", strerror(errno));
+	  }
+	  else if (write(Datafile, &FileRHeader, sizeof(RunHeader)) != sizeof(RunHeader)) {
+		Message(ERROR, "Could not write updated run header (%s)", strerror(errno));
+	  }
+
+	  // Close data file and terminate run
+	  if(close(Datafile) == -1) Message(ERROR, "Could not close data file (%s)", strerror(errno));
+	  else PrintMessage("Data file closed (size %.1f MByte).\n", FileSizeMB);
+
+	  Datafile = -1;
+	  Mode = idle;
+	  Message(INFO, "Data run ended, mode set to IDLE");	  
+	}
   }
 
   delete[] BStruct;
   delete[] EventData;
-
 }
 
Index: /fact/FADctrl/History.txt
===================================================================
--- /fact/FADctrl/History.txt	(revision 10912)
+++ /fact/FADctrl/History.txt	(revision 10913)
@@ -30,2 +30,3 @@
 			cancelled
 25/5/2011	dcm_lock and dcm_ready bits were incorrectly evaluated.
+3/6/2011	Raw data files will only contain boards active at the start of the run.
Index: /fact/drsdaq/History.txt
===================================================================
--- /fact/drsdaq/History.txt	(revision 10912)
+++ /fact/drsdaq/History.txt	(revision 10913)
@@ -74,4 +74,5 @@
 			drsdaq is 264.
 30/7/2010	Published some run-related information as DIM service.
-3/6/2011	Added 'write' command (for PEBS application)
+3/6/2011	Added 'write' command (for PEBS application).
+6/6/2011	Event header is printed in RawDataCTX.cc before trying to seek.
 			
Index: /fact/drsdaq/RawDataCTX.cc
===================================================================
--- /fact/drsdaq/RawDataCTX.cc	(revision 10912)
+++ /fact/drsdaq/RawDataCTX.cc	(revision 10913)
@@ -84,5 +84,5 @@
   // If requested, print run header (including board structures) to file 
   if(fptr != NULL) {
-    fprintf(fptr, "Magic number          %x (%s)\n", RHeader->MagicNum, RHeader->MagicNum==MAGICNUM_CLOSED?"OK":(RHeader->MagicNum==MAGICNUM_OPEN?"File not closed":"Error"));
+    fprintf(fptr, "Magic number          0x%X (%s)\n", RHeader->MagicNum, RHeader->MagicNum==MAGICNUM_CLOSED?"OK":(RHeader->MagicNum==MAGICNUM_OPEN?"File not closed":"Error"));
     fprintf(fptr, "Data format:          %u\n", RHeader->DataFormat);
     fprintf(fptr, "Software revision:    %d\n", RHeader->SoftwareRevision);         
@@ -113,5 +113,5 @@
     for (unsigned int i=0; i<RHeader->NBoards; i++) {
       fprintf(fptr, "*** Board %d ***\n", i);
-      fprintf(fptr, "Serial number:            %d\n", BStruct[i].SerialNo);
+      fprintf(fptr, "Serial number:            0x%X\n", BStruct[i].SerialNo);
       fprintf(fptr, "Sampling frequency:       %.3f GHz\n", BStruct[i].NomFreq);
       fprintf(fptr, "Temperature:              %.3f deg C\n", BStruct[i].BoardTemp);  
@@ -165,20 +165,4 @@
     }
   }
-  if(!SEEK_OK) {
-    if(!Silent) printf("Error: Could not move to requested event\n");
-    return CTX_SEEK;
-  }
-
-  // Allocate memory for event data (enlarge if necessary)
-  if(Data==NULL || (sizeof(Data) < EHeader->EventSize)) {
-    delete[] Data;
-    Data = new char[EHeader->EventSize];
-  }
-
-  // Read event data
-  if(fread(Data, 1, EHeader->EventSize, Rawfile) != EHeader->EventSize) {
-    if(!Silent) printf("Error: Could not read (all) event data\n");
-    return CTX_DATA;    
-  }
 
   // If requested, print event header to file 
@@ -190,4 +174,22 @@
     fprintf(fptr, "Size [byte]:     %u\n",        EHeader->EventSize);
   }
+
+  // Moce to requested event
+  if(!SEEK_OK) {
+    if(!Silent) printf("Error: Could not move to requested event\n");
+    return CTX_SEEK;
+  }
+
+  // Allocate memory for event data (enlarge if necessary)
+  if(Data==NULL || (sizeof(Data) < EHeader->EventSize)) {
+    delete[] Data;
+    Data = new char[EHeader->EventSize];
+  }
+
+  // Read event data
+  if(fread(Data, 1, EHeader->EventSize, Rawfile) != EHeader->EventSize) {
+    if(!Silent) printf("Error: Could not read (all) event data\n");
+    return CTX_DATA;    
+  }
   
   return CTX_OK;
Index: /fact/tools/Scripts/Logon
===================================================================
--- /fact/tools/Scripts/Logon	(revision 10912)
+++ /fact/tools/Scripts/Logon	(revision 10913)
@@ -12,17 +12,2 @@
 export LD_LIBRARY_PATH=$QWTDIR/lib:$DIMDIR/linux:$LD_LIBRARY_PATH
 export PATH=$DIMDIR/linux:$REPOS_DIR/tools/Scripts:$QTDIR/bin:.:$PATH
-
-# Check if repository is a mixed or locally modified version (only for login shell))
-# The revision warning is given only once at login.
-
-if [ "${USER}" = "daqct3" ]; then
-#if shopt -q login_shell; then
-if [[ `svnversion $REPOS_DIR/drsdaq -n` == *:* ]] || [[ `svnversion $REPOS_DIR/drsdaq -n` == *M ]]; then
-    xterm -e "echo 'Warning: drsdaq in repository does not have a single revision number';
-    echo 'Make an update before starting a run!';
-    echo 'Contact O.Grimm or Q.Weitzel in case you need help';
-    echo 'Hit return to continue';
-    read;"
-#fi
-fi
-fi
