Index: fact/FADctrl/FAD.cc
===================================================================
--- fact/FADctrl/FAD.cc	(revision 11458)
+++ fact/FADctrl/FAD.cc	(revision 12891)
@@ -44,4 +44,5 @@
    {"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"},	  		  
+   {"dynrange", &FAD::cmd_dynrange, true, 0, "", "Determine dynamic range using calibration DAC"},
    {"exit", &FAD::cmd_exit, false, 0, "", "Exit program"},
    {"help", &FAD::cmd_help, false, 0, "", "Print help"}};
@@ -612,4 +613,20 @@
 
 //
+// Determine dynamic range
+//
+void FAD::cmd_dynrange() {
+
+  // Set number of events required for measurement
+  if (Parameter.size()==1 || !ConvertToInt(Parameter[1], &NumEventsRequested) || NumEventsRequested<=0) {
+	NumEventsRequested = DEFAULT_NUM_CALIB_EVENTS;
+  }
+
+  // Start calibration by setting mode
+  Mode = dynrange;
+  Message(INFO, "Starting determination of dynamic range with %d events", NumEventsRequested);
+}
+
+
+//
 // Print status
 //
@@ -650,4 +667,5 @@
 	else if (Mode == acalib) PrintMessage("Current mode is ACALIB (3x%d events, slowest board %d has %d events)\n", NumEventsRequested, SlowestBoard, MinCount);
 	else if (Mode == datarun) PrintMessage("Current mode is DATARUN (%d events requested, %d events taken)\n", NumEventsRequested, NumEvents);
+	else if (Mode == dynrange) PrintMessage("Current mode is DYNRANGE (%d events requested)\n", NumEventsRequested);
 	return;
   }    
@@ -784,5 +802,5 @@
   }
   
-  if (Mode == acalib) {
+  if (Mode == acalib || Mode == dynrange) {
 	Mode = idle;
 	Message(INFO, "Mode set to IDLE");
Index: fact/FADctrl/FAD.h
===================================================================
--- fact/FADctrl/FAD.h	(revision 11458)
+++ fact/FADctrl/FAD.h	(revision 12891)
@@ -31,5 +31,5 @@
 
   public:
-    enum ModeType {idle, datarun, acalib};
+    enum ModeType {idle, datarun, acalib, dynrange};
 	ModeType Mode;
 
@@ -81,5 +81,5 @@
 	void cmd_phase();		void cmd_send();
 	void cmd_stop();		void cmd_update();
-	void cmd_take();
+	void cmd_take();		void cmd_dynrange();
 
     void EnableDomino();
Index: fact/FADctrl/FADBoard.cc
===================================================================
--- fact/FADctrl/FADBoard.cc	(revision 11458)
+++ fact/FADctrl/FADBoard.cc	(revision 12891)
@@ -723,2 +723,111 @@
   }
 }
+
+
+
+//
+// Dynamic range determination
+//
+void FADBoard::DynamicRange() {
+
+  #if 0
+  vector<unsigned short> ROICmd;
+  unsigned short DACCmd[] = {htons(CMD_Write | (BADDR_DAC + 1)), 0, htons(CMD_Write | (BADDR_DAC + 2)), 0, htons(CMD_Write | (BADDR_DAC + 3)), 0, htons(CMD_Execute) };
+  string Message = string("ACALIBDONE")+Name+"\n";
+
+  switch (StateDR) {
+  // ====== Check if dynamic range measurement should start and initialise =====
+  case standbye:
+	if (m->Mode != m->dynrange) break;
+
+	// Save initial board status, and set all ROIs to 1024
+	InitialStatus = GetStatus();
+
+	for (unsigned int i=0; i<NChips*NChannels; i++) {
+	  ROICmd.push_back(htons(CMD_Write | (BADDR_ROI + i)));
+	  ROICmd.push_back(htons(NBins));
+	}
+	ROICmd.push_back(htons(CMD_Execute));
+	Send(&ROICmd[0], ROICmd.size()*sizeof(unsigned short));
+
+	// Start measurement
+	DAC_DR = 0;
+	StateDR = setdac;
+	SetStatus("Starting dynamic range measurement");
+	break;
+
+  // ====== Set calibration DAC =====
+  case setdac:
+	// Check for stopping
+	if (m->Mode != m->dynrange) {
+	  StateDR = cleanup;
+	  break;
+	}
+
+	if (DAC_DR > 66000) {
+	  StateDR = cleanup;
+	  break;
+	}
+
+	// Set new DAC values
+	DACCmd[1] = htons(DAC_DR);
+	DACCmd[3] = htons(DAC_DR);
+	DACCmd[5] = htons(DAC_DR);
+	Send(DACCmd, sizeof(DACCmd));
+
+	StateDR = measure;
+	break;
+
+  // ====== Determine mean and sigma =====
+  case measure:
+	// Check for stopping
+	if (m->Mode != m->dynrange) {
+	  StateDR = cleanup;
+	  break;
+	}
+
+	Mean = 0;
+	Sigma = 0;
+	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++) {
+		  Mean += Data[Chip][Chan][i];
+		  Sigma += Data[Chip][Chan][i]*Data[Chip][Chan][i];
+		}
+		Mean /= Status.ROI[Chip][Chan];
+		Sigma = sqrt(Status.ROI[Chip][Chan]/(Status.ROI[Chip][Chan]-1)*(Sigma/Status.ROI[Chip][Chan]-Mean*Mean));		
+	  }
+	}
+	
+	DAC_DR += 1000;
+
+	StateDR = setdac;
+	break;
+
+  // ====== Write back original ROI and DAC settings =====
+  case cleanup:
+    // ROI values
+	ROICmd.clear();
+	for (unsigned int i=0; i<NChips*NChannels; i++) {
+	  ROICmd.push_back(htons(CMD_Write | (BADDR_ROI + i)));
+	  ROICmd.push_back(htons(InitialStatus.ROI[i/NChannels][i%NChannels]));
+	}
+	ROICmd.push_back(htons(CMD_Execute));
+	Send(&ROICmd[0], ROICmd.size()*sizeof(unsigned short));
+
+	// DAC values
+	DACCmd[1] = htons(InitialStatus.DAC[1]);
+	DACCmd[3] = htons(InitialStatus.DAC[2]);
+	DACCmd[5] = htons(InitialStatus.DAC[3]);
+  	Send(DACCmd, sizeof(DACCmd));
+	
+	StateDR = wait;
+	break;
+
+  // ====== Wait for Mode not being idle =====
+  case wait:
+	if (m->Mode == m->idle) StateDR = standbye;
+	break;
+  }
+  #endif
+}  
Index: fact/FADctrl/FADBoard.h
===================================================================
--- fact/FADctrl/FADBoard.h	(revision 11458)
+++ fact/FADctrl/FADBoard.h	(revision 12891)
@@ -96,4 +96,5 @@
 	void Lock();
 	void Unlock();
+	void DynamicRange();
 
 	unsigned short Port;
