Index: fact/FADctrl/FAD.cc
===================================================================
--- fact/FADctrl/FAD.cc	(revision 10077)
+++ fact/FADctrl/FAD.cc	(revision 10080)
@@ -32,6 +32,5 @@
    {"address", &FAD::cmd_address, true, 2, "<range> <value>", "Set addresses in range to value"},
    {"send", &FAD::cmd_send, true, 1, "<value>", "Set arbitrary data to board"},
-   {"acalib", &FAD::cmd_acalib, true, 0, "", "Amplitude calibration"},
-   //{"tcalib", &FAD::cmd_tcalib, 1, "<trig rate> ", "Time calibration"},
+   {"acalib", &FAD::cmd_acalib, true, 0, "[n]", "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)"},
@@ -39,5 +38,5 @@
    {"cancel", &FAD::cmd_cancel, false, 0, "", "Cancel current operation"},
    {"update", &FAD::cmd_update, false, 1, "<sec>", "Minimum delay between updates to DIM event service"},		  
-	 {"socketmode", &FAD::cmd_socketmode, true, 1, "<com|daq>", "Choose which Sockets are used for data transmission"},		  
+   {"socketmode", &FAD::cmd_socketmode, true, 1, "<com|daq>", "Choose which Sockets are used for data transmission"},		  
    {"exit", &FAD::cmd_exit, true, 0, "", "Exit program"},
    {"help", &FAD::cmd_help, false, 0, "", "Print help"}};
@@ -105,12 +104,11 @@
   int Ret;
 
+  // Wait for DIM service thread to quit
+  if (pthread_equal(Thread, pthread_self()) == 0) {
+	if ((Ret = pthread_join(Thread, NULL)) != 0) Message(ERROR, "pthread_join() failed in ~FAD() (%s)", strerror(Ret));
+  }
+
   // Delete all boards (cancels threads automatically)
   for (unsigned int i=0; i<Boards.size(); i++) delete Boards[i];
-
-  // Cancel SIM service thread and wait for it to quit
-  if (pthread_equal(Thread, pthread_self()) == 0) {
-	if ((Ret = pthread_cancel(Thread)) != 0) Message(ERROR, "Could not request thread cancellation (%s)", strerror(Ret));
-	if ((Ret = pthread_join(Thread, NULL)) != 0) Message(ERROR, "pthread_join() failed (%s)", strerror(Ret));
-  }
 
   delete Command;
@@ -456,5 +454,16 @@
   int Code;
 
-  // Set mode before lunching thread
+  // Invalidate calibration?
+  if (Parameter.size() == 2 && Match(Parameter[1], "invalidate")) {
+	for (unsigned int i=0; i<Boards.size(); i++) Boards[i]->ACalibTime = -1;
+	return;
+  }
+   
+  // Set number of events required for calibration
+  if (Parameter.size()==1 || !ConvertToInt(Parameter[1], &NumCalibEvents) || NumCalibEvents<=0) {
+	NumCalibEvents = DEFAULT_NUM_CALIB_EVENTS;
+  }
+
+  // Set mode before launching thread
   Mode = acalib;
   Cancel = false;
@@ -472,70 +481,4 @@
 }
 
-/*
-// Do time calibration
-void FAD::cmd_tcalib() {
-  
-  if (!IsDRSFreqSet()) {
-    PrintMessage("Set sampling frequency for all boards first\n");
-    return;
-  }
-  if (!ReadCalibration()) {
-    PrintMessage("Amplitude calibration has to be done first\n");
-    return;
-  }
-      
-  for (int i=FirstBoard; i<=LastBoard; i++) {
-    if (GetBoard(i)->GetDRSType() != 4 || GetBoard(i)->GetFirmwareVersion() < 13279) {
-      PrintMessage("Time calibration needs DRS4 and minimum firmware version 13279, skipping board %d\n", i);
-      continue;
-    }
-    PrintMessage("Creating time calibration of board %d (serial #%04d)\n  Note: No input signals should be connected\n", i, GetBoard(i)->GetBoardSerialNumber());
-    
-    GetBoard(i)->SetFrequency(DRSFreq[i], true);
-    if (GetBoard(i)->CalibrateTiming(this) != 1) {
-      PrintMessage("Time calibration method returned error status, stopping calibration\n");
-      return;
-    }
-
-    TCalib[i] = true;
-
-    // Write calibration data to file
-    float Time[NChipsMax][NBins];
-    char *Filename;
-    FILE *Calibfile;
-	bool WriteOK = true;
-	
-    // Copy calibration data into array
-	for (int Chip=0; Chip<GetBoard(i)->GetNumberOfChips(); Chip++) {
-      GetBoard(i)->GetTime(Chip, Time[Chip], true, false);
-	}
-
-	// Write calibration data to file
-    if (asprintf(&Filename, "%s/TCalib_%d_%.2fGHz.txt", fCalibDataPath, GetBoard(i)->GetBoardSerialNumber(), DRSFreq[i]) == -1) {
-      PrintMessage("Error: asprintf() failed, cannot generate filename (%s)\n", strerror(errno));
-      return; 
-    }
-    if ((Calibfile=fopen(Filename,"w")) == NULL) {
-      PrintMessage("Error: Could not open file '%s' \n", Filename);      
-    }
-    else {
-      if(fprintf(Calibfile, "# DRS time calibration\n") == -1) WriteOK = false;
-
-      for (int Bin=0; Bin<NBins; Bin++) {
-		for (int Chip=0; Chip<GetBoard(i)->GetNumberOfChips(); Chip++) {
-          if(fprintf(Calibfile, "%.2f ", Time[Chip][Bin]) == -1) WriteOK = false;
-		}
-        if(fprintf(Calibfile, "\n") == -1) WriteOK = false;
-	  }
-	  if (fclose(Calibfile) != 0) PrintMessage("Error closing file '%s'\n", Filename);
-	}
-	if (!WriteOK) PrintMessage("Error writing to file '%s'\n", Filename);
-	else PrintMessage("Calibration written to file '%s'\n", Filename);
-	
-    free(Filename);
-  }
-  PrintMessage("Time calibration finished\n");
-}
-*/
 
 //
@@ -604,6 +547,4 @@
 	else
 	  PrintMessage("   DMODE single shot\n");
-	if (GetBoard(i)->GetCtrlReg() & BIT_ENABLE_TRIGGER1)
-	  PrintMessage("   ENABLE_TRIGGER\n");
 	if (GetBoard(i)->GetCtrlReg() & BIT_ACAL_EN)
 	  PrintMessage("   ACAL enabled\n");
@@ -663,10 +604,14 @@
 void FAD::cmd_help() {
 
-  char Buffer[MAX_COM_SIZE];
+  char *Buffer;
 
   for(unsigned int i=0; i<sizeof(CommandList)/sizeof(CL_Struct); i++) {
-    snprintf(Buffer, sizeof(Buffer), "%s %s", CommandList[i].Name, CommandList[i].Parameters);
-    PrintMessage("%-28s%s\n", Buffer, CommandList[i].Help);
-  }     
+    if (asprintf(&Buffer, "%s %s", CommandList[i].Name, CommandList[i].Parameters) == -1) {
+	  PrintMessage("Error printing help, asprintf() failed\n");
+	  break;
+	}
+    else PrintMessage("%-28s%s\n", Buffer, CommandList[i].Help);
+	free(Buffer);
+  }
   PrintMessage(".<command>                  Execute shell command\n\n"
    "Items in <> are mandatory, in [] optional, | indicates mutual exclusive.\n"
@@ -706,7 +651,7 @@
 void FAD::AmplitudeCalibration() {
 
-  static unsigned int ReqNum = 10;
-  unsigned short Buffer[2*NChips*NChannels];
-  unsigned short DACCmd[] = {htons(CMD_Write | (BADDR_DAC + 0)), 0};
+  vector<struct FADBoard::BoardStatus> Status;
+  vector<unsigned short> ROICmd;
+  unsigned short DACCmd[] = {htons(CMD_Write | (BADDR_DAC + 2)), 0};
 
   /* Procedure
@@ -718,28 +663,33 @@
   11. Secondary calibration
 */
-  struct FADBoard::BoardStatus *Status = new struct FADBoard::BoardStatus [Boards.size()];
-
-  PrintMessage("Staring amplitude calibration of all active boards/n  Note: No input signals must be connected\n");
-  
+
+  PrintMessage("Staring amplitude calibration of all active boards (%d events)\n"
+			   "   Note: No input signals must be connected\n", NumCalibEvents);
+  
+  // Prepare command to set all ROIs to 1024
+  for (unsigned int i=0; i<NChips*NChannels; i++) {
+	ROICmd.push_back(htons(CMD_Write | (BADDR_ROI + i)));
+	ROICmd.push_back(htons(NBins));
+  }
+
   // Initialise settings for calibration
   for (unsigned int Brd=0; Brd<Boards.size(); Brd++) {
 
+	// Invalidate current calibration
+	Boards[Brd]->ACalibTime = -1;
+
 	// Save initial board status
-	Status[Brd] = Boards[Brd]->GetStatus();
+	Status.push_back(Boards[Brd]->GetStatus());
 	
     // Set all ROI to 1024
-	for (unsigned int i=0; i<NChips*NChannels; i++) {
-	  Buffer[2*i] = htons(CMD_Write | (BADDR_ROI + i));
-	  Buffer[2*i+1] = htons(NBins);
-	}
-	Boards[Brd]->Send(Buffer, sizeof(Buffer));
+	Boards[Brd]->Send(&ROICmd[0], ROICmd.size()*sizeof(unsigned short));
 
     // Set DAC first value
-    DACCmd[1] = htons(10);
+    DACCmd[1] = htons(0);
 	Boards[Brd]->Send(DACCmd, sizeof(DACCmd));
 
 	// Start accumulation
-    Boards[Brd]->AccumulateSum(ReqNum);	
-	Boards[Brd]->Send(CMD_Trigger_C);
+    Boards[Brd]->AccumulateSum(NumCalibEvents);	
+	//Boards[Brd]->Send(CMD_Trigger_C);
   }
 
@@ -753,15 +703,16 @@
 	}
   }
+  printf("Got first average\n");
 
   for (unsigned int Brd=0; Brd<Boards.size(); Brd++) {
 	// Determine baseline
 	for (unsigned int i=0; i<NChips; i++) for (unsigned int j=0; j<NChannels; j++) {
-	  for (unsigned int k=0; k<NBins; k++) Boards[Brd]->Baseline[i][j][k] = Boards[Brd]->Sum[i][j][k] / 10;
+	  for (unsigned int k=0; k<NBins; k++) Boards[Brd]->Baseline[i][j][k] = Boards[Brd]->Sum[i][j][k] / NumCalibEvents;
 	}
 	// Set second DAC value
-    DACCmd[1] = htons(30000);
+    DACCmd[1] = htons(50000);
 	Boards[Brd]->Send(DACCmd, sizeof(DACCmd));
 	// Start accumulation
-    Boards[Brd]->AccumulateSum(ReqNum);	
+    Boards[Brd]->AccumulateSum(NumCalibEvents);	
   }
 
@@ -778,18 +729,19 @@
   // Stop triggering, write back original ROI and DAC settings
   for (unsigned int Brd=0; Brd<Boards.size(); Brd++) {
-  	Boards[Brd]->Send(CMD_Trigger_S);
+  	//Boards[Brd]->Send(CMD_Trigger_S);
 
 	// Determine gain
 	for (unsigned int i=0; i<NChips; i++) for (unsigned int j=0; j<NChannels; j++) {
-	  for (unsigned int k=0; k<NBins; k++) Boards[Brd]->Gain[i][j][k] = (Boards[Brd]->Sum[i][j][k] / 10)/Boards[Brd]->Baseline[i][j][k];
-	}
-
+	  for (unsigned int k=0; k<NBins; k++) Boards[Brd]->Gain[i][j][k] = ((Boards[Brd]->Sum[i][j][k] / NumCalibEvents)-Boards[Brd]->Baseline[i][j][k])/3000;
+	}
+
+	ROICmd.clear();
 	for (unsigned int i=0; i<NChips*NChannels; i++) {
-	  Buffer[2*i] = htons(CMD_Write | (BADDR_ROI + i));
-	  Buffer[2*i+1] = htons(Status[Brd].ROI[i/NChannels][i%NChannels]);
-	}
-	Boards[Brd]->Send(Buffer, sizeof(Buffer));
-  
-    DACCmd[1] = htons(Status[Brd].DAC[0]);
+	  ROICmd.push_back(htons(CMD_Write | (BADDR_ROI + i)));
+	  ROICmd.push_back(htons(Status[Brd].ROI[i/NChannels][i%NChannels]));
+	}
+	Boards[Brd]->Send(&ROICmd[0], ROICmd.size()*sizeof(unsigned short));
+  
+    DACCmd[1] = htons(Status[Brd].DAC[2]);
   	Boards[Brd]->Send(DACCmd, sizeof(DACCmd));
 	
@@ -800,6 +752,4 @@
   }
 
-  delete[] Status;
-  
   PrintMessage("Amplitude calibration of all active boards finished, original ROI and DAC set\n");
   Mode = idle;
@@ -897,5 +847,5 @@
 	for (unsigned int Brd=0; Brd<Boards.size(); Brd++) {
 	  S = Boards[Brd]->GetStatus();
-	  if (S.Update.tv_sec>LastUpdate.tv_sec || ((S.Update.tv_sec==LastUpdate.tv_sec) && (S.Update.tv_sec>LastUpdate.tv_sec))) {
+	  if (S.Update.tv_sec>LastUpdate.tv_sec || ((S.Update.tv_sec==LastUpdate.tv_sec) && (S.Update.tv_usec>LastUpdate.tv_usec))) {
 
 		Update = true;
@@ -921,5 +871,8 @@
 		Boards[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++) Data[Count++] = Boards[Brd]->Data[Chip][Chan][i];
+		  for (int i=0; i<S.ROI[Chip][Chan]; i++) {
+			if (Boards[Brd]->ACalibTime == -1) Data[Count++] = Boards[Brd]->Data[Chip][Chan][i];
+			else Data[Count++] = (Boards[Brd]->Data[Chip][Chan][i] - Boards[Brd]->Baseline[Chip][Chan][(i+S.TriggerCell[Chip])%NBins]) * Boards[Brd]->Gain[Chip][Chan][(i+S.TriggerCell[Chip])%NBins];
+		  }
 		  Count += NBins - S.ROI[Chip][Chan];
 		}
Index: fact/FADctrl/FAD.h
===================================================================
--- fact/FADctrl/FAD.h	(revision 10077)
+++ fact/FADctrl/FAD.h	(revision 10080)
@@ -2,6 +2,6 @@
 #define FAD_H_SEEN
 
-//#define SERVER_NAME "FADctrl"       // Name to use in DIM
-#define SERVER_NAME "drsdaq"       // Name to use in DIM
+#define SERVER_NAME "FADctrl"       // Name to use in DIM
+//#define SERVER_NAME "drsdaq"       // Name to use in DIM
 #include "Evidence.h"
 
@@ -21,5 +21,5 @@
 #include "FADBoard.h"
 
-#define MAX_COM_SIZE 10000
+const int DEFAULT_NUM_CALIB_EVENTS = 100;
 
 enum ModeType {idle, acalib, tcalib};
@@ -44,4 +44,5 @@
 	int EventUpdateDelay;
 
+	int NumCalibEvents;
     //const char *fCalibDataPath;
     //char CalibInfoFilename[MAX_PATH];
@@ -70,6 +71,5 @@
 	void cmd_dwrite();		void cmd_domino();
     void cmd_wmode();		void cmd_rmode();
-    void cmd_dmode();
-	void cmd_tcalib();		void cmd_dac();
+    void cmd_dmode();		void cmd_dac();
 	void cmd_roi();			void cmd_address();
 	void cmd_phase();		void cmd_send();
Index: fact/FADctrl/FADBoard.cc
===================================================================
--- fact/FADctrl/FADBoard.cc	(revision 10077)
+++ fact/FADctrl/FADBoard.cc	(revision 10080)
@@ -55,9 +55,9 @@
   ID << SERVER_NAME"/Board" << setfill('0') << setw(2) << Num << "/";
 
-  NameService = new DimService((ID.str()+"Server").c_str(), Name);
-  IDService = new DimService((ID.str()+"BoardID").c_str(), (char *) "S", NULL, 0);
-  TempService = new DimService((ID.str()+"Temperature").c_str(), (char *) "F", NULL, 0);
-  DACService = new DimService((ID.str()+"DAC").c_str(), (char *) "S", NULL, 0);
-  ROIService = new DimService((ID.str()+"ROI").c_str(), (char *) "S", NULL, 0);
+  DIM_Name = new DimService((ID.str()+"Server").c_str(), Name);
+  DIM_ID = new DimService((ID.str()+"BoardID").c_str(), (char *) "S", NULL, 0);
+  DIM_Temp = new DimService((ID.str()+"Temperature").c_str(), (char *) "F", NULL, 0);
+  DIM_DAC = new DimService((ID.str()+"DAC").c_str(), (char *) "S", NULL, 0);
+  DIM_ROI = new DimService((ID.str()+"ROI").c_str(), (char *) "S", NULL, 0);
 
   // Initialise mutex for synchronization
@@ -74,5 +74,5 @@
   // Create thread that receives data
   if ((Ret = pthread_create(&Thread, NULL, (void * (*)(void *)) LaunchThread,(void *) this)) != 0) {
-    m->PrintMessage("pthread_create() failed (%s)\n", strerror(Ret));
+    m->Message(m->ERROR, "pthread_create() failed in FADBoard() (%s)\n", strerror(Ret));
 	Thread = pthread_self();
 	return;
@@ -91,18 +91,18 @@
   // Cancel thread and wait for it to quit
   if (pthread_equal(Thread, pthread_self()) == 0) {
-	if ((Ret = pthread_cancel(Thread)) != 0) m->PrintMessage("Error: Could not request thread cancellation (%s)\n", strerror(Ret));
-	if ((Ret = pthread_join(Thread, NULL)) != 0) m->PrintMessage("pthread_join() failed (%s)\n", strerror(Ret));
+	if ((Ret = pthread_cancel(Thread)) != 0) m->Message(m->ERROR, "pthread_cancel() failed in ~FADBoard() (%s)", strerror(Ret));
+	if ((Ret = pthread_join(Thread, NULL)) != 0) m->Message(m->ERROR, "pthread_join() failed in ~FADBoard (%s)", strerror(Ret));
   }
 
   // Delete mutex  
   if (InitOK && ((Ret = pthread_mutex_destroy(&Mutex)) != 0)) {
-	m->PrintMessage("pthread_mutex_destroy() failed (%s)", strerror(Ret));
-  }
-
-  delete NameService;
-  delete IDService;
-  delete TempService;
-  delete DACService;
-  delete ROIService;
+	m->Message(m->ERROR, "pthread_mutex_destroy() failed in ~FADBoard (%s)", strerror(Ret));
+  }
+
+  delete DIM_Name;
+  delete DIM_ID;
+  delete DIM_Temp;
+  delete DIM_DAC;
+  delete DIM_ROI;
   delete[] Name;
 
@@ -277,5 +277,5 @@
 		for (unsigned int Chip=0; Chip<NChips; Chip++) for (unsigned int Chan=0; Chan<NChannels; Chan++) {
 		  for (int i=0; i<Status.ROI[Chip][Chan]; i++) {
-			Sum[Chip][Chan][(i+ntohs(Channel[Chip+NChips*Chan]->start_cell)) % NBins] = Data[Chip][Chan][i];
+			Sum[Chip][Chan][(i+Status.TriggerCell[Chip]) % NBins] += Data[Chip][Chan][i];
 		  }
 		}
@@ -288,14 +288,14 @@
 	  // Update DIM services if necessary
 	  if (memcmp(PrevStatus.Temp, Status.Temp, sizeof(Status.Temp)) != 0) {
-		TempService->updateService(Status.Temp, sizeof(Status.Temp));
+		DIM_Temp->updateService(Status.Temp, sizeof(Status.Temp));
 	  }
 	  if (memcmp(PrevStatus.DAC, Status.DAC, sizeof(Status.DAC)) != 0) {
-		DACService->updateService(Status.DAC, sizeof(Status.DAC));
+		DIM_DAC->updateService(Status.DAC, sizeof(Status.DAC));
 	  }  
 	  if (memcmp(PrevStatus.ROI, Status.ROI, sizeof(Status.ROI)) != 0) {
-		ROIService->updateService(Status.ROI, sizeof(Status.ROI));
+		DIM_ROI->updateService(Status.ROI, sizeof(Status.ROI));
 	  }  
 	  if (PrevStatus.BoardID != Status.BoardID) {
-		IDService->updateService(&Status.BoardID, sizeof(Status.BoardID));
+		DIM_ID->updateService(&Status.BoardID, sizeof(Status.BoardID));
 	  }  
 	}
Index: fact/FADctrl/FADBoard.h
===================================================================
--- fact/FADctrl/FADBoard.h	(revision 10077)
+++ fact/FADctrl/FADBoard.h	(revision 10080)
@@ -28,9 +28,9 @@
 	pthread_t Thread;
 	pthread_mutex_t Mutex;
-	DimService *NameService;
-	DimService *IDService;
-	DimService *TempService;
-	DimService *ROIService;
-	DimService *DACService;
+	DimService *DIM_Name;
+	DimService *DIM_ID;
+	DimService *DIM_Temp;
+	DimService *DIM_ROI;
+	DimService *DIM_DAC;
 
 	void ReadLoop();
@@ -52,11 +52,11 @@
 	} Status;
 
-	unsigned short Data[NChips][NChannels][NBins];
-	double Baseline[NChips][NChannels][NBins];
+	short Data[NChips][NChannels][NBins];
+	short Baseline[NChips][NChannels][NBins];
 	double Gain[NChips][NChannels][NBins];
 	float ACalibTemp;
 	time_t ACalibTime;
 
-	double Sum[NChips][NChannels][NBins];
+	long int Sum[NChips][NChannels][NBins];
 	unsigned int NumForSum;
 	bool DoSum;
Index: fact/FADctrl/FADctrl.cc
===================================================================
--- fact/FADctrl/FADctrl.cc	(revision 10077)
+++ fact/FADctrl/FADctrl.cc	(revision 10080)
@@ -48,7 +48,6 @@
   sleep(1);
 
-  DimClient::sendCommand(SERVER_NAME"/Command", "dac 0 21000");
-  DimClient::sendCommand(SERVER_NAME"/Command", "dac 1 0");
-  DimClient::sendCommand(SERVER_NAME"/Command", "dac 2-3 5000");
+  DimClient::sendCommand(SERVER_NAME"/Command", "dac 0 25000");
+  DimClient::sendCommand(SERVER_NAME"/Command", "dac 1-3 0");
   DimClient::sendCommand(SERVER_NAME"/Command", "dac 4-7 28800");
   sleep (1);
@@ -105,6 +104,6 @@
 
   // Terminate thread for other sockets  
-  if ((Ret = pthread_cancel(Thread)) != 0) printf("Error: Could not request thread cancellation (%s)\n", strerror(Ret));
-  if ((Ret = pthread_join(Thread, NULL)) != 0) printf("pthread_join() failed (%s)\n", strerror(Ret));
+  if ((Ret = pthread_cancel(Thread)) != 0) printf("Error: Could not request thread cancellation in main() (%s)\n", strerror(Ret));
+  if ((Ret = pthread_join(Thread, NULL)) != 0) printf("pthread_join() failed in main () (%s)\n", strerror(Ret));
 }
 
@@ -169,5 +168,5 @@
       if(Ret == 0) printf("OtherSockets: Connection to port %d not existing anymore\n", List[i]);
       else if (Ret == -1) printf("OtherSockets: Error reading from port %d (%s)\n", List[i], strerror(errno));
-      else printf("OtherSockets: Read %d bytes from port %d\n", Ret, List[i]);
+      else ;//printf("OtherSockets: Read %d bytes from port %d\n", Ret, List[i]);
     }
   }
Index: fact/FADctrl/History.txt
===================================================================
--- fact/FADctrl/History.txt	(revision 10077)
+++ fact/FADctrl/History.txt	(revision 10080)
@@ -2,2 +2,3 @@
 
 22/10/2010	First check-in of FADctrl. Initial version derived from drsdaq revision 10007.
+5/1/2011	First version of amplitude calibration (no secondary calibration, yet)
