Index: drsdaq/DAQReadout.cc
===================================================================
--- drsdaq/DAQReadout.cc	(revision 89)
+++ drsdaq/DAQReadout.cc	(revision 92)
@@ -12,5 +12,5 @@
 #include "SlowData.h"
 
-#define TMPNAME "/tmp/__tmp__drsdaq__"
+#define TMPNAME "/tmp/__tmp__drsdaq__"  // ..for log file truncation
 
 static const char* daq_state_str[] = {"active", "stopped"};
@@ -26,5 +26,5 @@
    {"status", &DAQReadout::cmd_status, false, "[daq|drs]", "Show DAQ/DRS status information"},
    {"freq", &DAQReadout::cmd_freq, true, "<GHz> [reg]", "Set DRS sampling frequency (regulated)"},
-   {"calib", &DAQReadout::cmd_calib, true, "<t_f> <c_f> [dir]", "Response calibration"},
+   {"calib", &DAQReadout::cmd_calib, true, "<t_f> <c_f>", "Response calibration"},
    {"trigger", &DAQReadout::cmd_trigger, true, "<on|off>", "Hardware trigger on or off"},
    {"delayed", &DAQReadout::cmd_delayed, true, "<on|off>", "Switch delayed start on or off"},
@@ -76,24 +76,30 @@
   LastBoard	     = -1;
   CmdFromSocket      = false;
-      
-  // Read configuration file
+  ConfigOK  	     = true;
+  
+  // Read configuration file (if any item missing, program will be terminated in main() routine)
   FILE *File;
   if ((File = fopen(Configfile,"r")) == NULL) {
     printf("Error: Could not open drsdaq configuration file '%s'\n", Configfile);
+    ConfigOK = false;
+    return;
   }
   else {
     printf("Reading drsdaq configuration file %s\n", Configfile);
-    ReadCard("LogFile",             fLogFile,           's', File);
-    ReadCard("MaxLogLines",        &fMaxLogLines,       'U', File);
-    ReadCard("RawDataPath",         fRawDataPath,       's', File);
-    ReadCard("FirstSample",        &fFirstSample,       'I', File);
-    ReadCard("Samples",     	   &fSamples,        	'U', File);
-    ReadCard("MinDiskSpaceMB",     &fMinDiskSpaceMB,    'U', File);
-    ReadCard("MaxFileSizeMB",      &fMaxFileSizeMB,     'I', File);
-    ReadCard("CCPort",             &fCCPort,            'I', File);
-    ReadCard("FirstVMESlot",       &fFirstVMESlot,      'I', File);
-    ReadCard("LastVMESlot",        &fLastVMESlot,       'I', File);
-    ReadCard("HVFeedbackConfig",    fHVFeedbackConfig,  's', File);
+    ConfigOK &= ReadCard("LogFile",             fLogFile,           's', File);
+    ConfigOK &= ReadCard("SlowDataPath",        fSlowDataPath,      's', File);
+    ConfigOK &= ReadCard("MaxLogLines",        &fMaxLogLines,       'U', File);
+    ConfigOK &= ReadCard("RawDataPath",         fRawDataPath,       's', File);
+    ConfigOK &= ReadCard("FirstSample",        &fFirstSample,       'I', File);
+    ConfigOK &= ReadCard("Samples",            &fSamples,           'U', File);
+    ConfigOK &= ReadCard("MinDiskSpaceMB",     &fMinDiskSpaceMB,    'U', File);
+    ConfigOK &= ReadCard("MaxFileSizeMB",      &fMaxFileSizeMB,     'I', File);
+    ConfigOK &= ReadCard("CCPort",             &fCCPort,            'I', File);
+    ConfigOK &= ReadCard("FirstVMESlot",       &fFirstVMESlot,      'I', File);
+    ConfigOK &= ReadCard("LastVMESlot",        &fLastVMESlot,       'I', File);
+    ConfigOK &= ReadCard("HVFeedbackConfig",    fHVFeedbackConfig,  's', File);
+    ConfigOK &= ReadCard("DefaultFrequency",   &fDefaultFrequency , 'd', File);
     fclose(File);
+    if (!ConfigOK) return;
   }
   if (fFirstSample < 0 || fFirstSample > kNumberOfBins || fSamples > kNumberOfBins) {
@@ -108,10 +114,8 @@
   if (system(ShellCmd) != 0) printf("Warning: Could not truncate log file '%s' to %u lines\n", fLogFile, fMaxLogLines);
 
-  // Open log file
+  // Open log file and log configuration
   if ((Logfile = fopen(fLogFile, "a")) == NULL) printf("Warning: Could not open log file '%s'\n", fLogFile);
   PrintMessage(MsgToLog,"********** Logging started **********\n");
-  
-  // Print configuration
-  cmd_config();
+  PrintConfig(MsgToLog);
 
   // Create DRS instance and perform initial scan
@@ -151,10 +155,9 @@
   
   // Create instance of slow data class for DAQ
-  char Filename[MAX_PATH];
-  snprintf(Filename,sizeof(Filename),"%s/SlowData/", fRawDataPath);
-  SlowDataClass = new SlowData("DAQ", Filename);
+  SlowDataClass = new SlowData("DAQ", fSlowDataPath);
   if(SlowDataClass->ErrorCode != 0) {
    PrintMessage("Warning: Could not open DAQ slowdata file (%s)\n", strerror(SlowDataClass->ErrorCode));
   }
+  SlowDataClass->NewEntry("Runinfo-Info", "Run information written after completion or termination of run (Status can be OK or Error): Runnumber Status Runtype Events Files Description ");
 }
 
@@ -170,5 +173,4 @@
   delete[] WaveForm;  delete[] TriggerCell;
   
-  PrintMessage(MsgToLog,"********** Logging ended **********\n\n");
   if(Logfile) {
     if(!fclose(Logfile)) printf("Closing logfile\n");
@@ -224,11 +226,5 @@
 // Print DAQ configuration
 void DAQReadout::cmd_config() {
-  PrintMessage("LogFile: %s\tMaxLogLines: %u\tRawDataPath: %s\n"
-      	       "FirstSample: %d\tSamples: %u\n"
-     	       "MinDiskSpaceMB: %u\tMaxFileSizeMB: %d\tCCPort: %d\n"
-      	       "FirstVMESlot: %d\t\tLastVMESlot: %d\n"
-	       "HVFeedbackConfig: %s\n",
-    fLogFile,fMaxLogLines,fRawDataPath,fFirstSample,fSamples,fMinDiskSpaceMB,
-    fMaxFileSizeMB,fCCPort,fFirstVMESlot,fLastVMESlot,fHVFeedbackConfig);
+  PrintConfig(CmdFromSocket ? MsgToSocket : MsgToConsole);
 }
 
@@ -241,5 +237,10 @@
       return;
     }
-    if (!IsDRSFreqSet()) return;
+    if (!IsDRSFreqSet()) {
+      PrintMessage("Setting default frequency\n");
+      SetDRSFrequency(fDefaultFrequency, false);
+      CalibrationRead = false;
+    }
+    
     if (!CalibrationRead && !ReadCalibration()) {
       PrintMessage("Cannot start run if response calibration not read.\n");
@@ -445,9 +446,44 @@
 // Do internal calibration
 void DAQReadout::cmd_calib() {
-  if (NParam==4 && atof(Param[1]) && atof(Param[2]))
-    CalibrateDRS((char *) Param[3],atof(Param[1]),atof(Param[2])); 
-  else if (NParam==3 && atof(Param[1]) && atof(Param[2]))
-    CalibrateDRS(NULL,atof(Param[1]),atof(Param[2])); 
-  else PrintUsage();
+  char str[MAX_COM_SIZE];
+
+  if (NParam!=3 || !atof(Param[1]) || !atof(Param[2])) {
+    PrintUsage();
+    return;
+  }
+      
+  getcwd(str, sizeof(str));
+  strcat(str,"/calib");
+  PrintMessage("Writing calibration data to directory '%s'\n",str);
+
+  for (int i=FirstBoard; i<=LastBoard; i++) {
+    drs->GetBoard(i)->Init();
+    drs->GetBoard(i)->SetFrequency(atof(Param[2]));
+    drs->GetBoard(i)->SoftTrigger();
+
+    PrintMessage("Creating calibration of board %d (%d)\n", i, drs->GetBoard(i)->GetCMCSerialNumber());
+
+    drs->GetBoard(i)->EnableTcal(1);
+    PrintMessage("Tcal enabled\n");
+
+    if (drs->GetBoard(i)->GetChipVersion() == 3) drs->GetBoard(i)->GetResponseCalibration()->SetCalibrationParameters(1,21,0,20,0,0,0,0,0);
+    else drs->GetBoard(i)->GetResponseCalibration()->SetCalibrationParameters(1,36,110,20,19,40,15,atof(Param[1]),0);
+    drs->GetBoard(i)->SetCalibrationDirectory(str);
+
+    for (int j=0; j<2; j++) {
+      drs->GetBoard(i)->GetResponseCalibration()->ResetCalibration();
+      PrintMessage("Calibration reset done.\n");
+
+      while (!drs->GetBoard(i)->GetResponseCalibration()->RecordCalibrationPoints(j)) {}
+      PrintMessage("Record calibration points done.\n");
+      while (!drs->GetBoard(i)->GetResponseCalibration()->FitCalibrationPoints(j)) {}
+      PrintMessage("Calibration points fitted.\n");
+      while (!drs->GetBoard(i)->GetResponseCalibration()->OffsetCalibration(j)) {}
+      PrintMessage("Offset calibration done.\n");
+
+      if (!drs->GetBoard(i)->GetResponseCalibration()->WriteCalibration(j)) break;
+    }        
+    drs->GetBoard(i)->Init(); // Reset linear range -0.2 ... 0.8 V
+  } // Loop over boards
 }
 
@@ -650,5 +686,5 @@
 // Print feedback configuration
 void DAQReadout::cmd_fconfig() {
-  HVFB->PrintConfig();
+  HVFB->PrintConfig(CmdFromSocket ? MsgToSocket : MsgToConsole);
 }
 
@@ -799,65 +835,4 @@
 }
 
-// Do internal calibration
-void DAQReadout::CalibrateDRS(char *dir, double trigfreq, double calibfreq) {
-
-  int i,j;
-  char str[MAX_COM_SIZE];
-  DIR *pdir;
-      
-  if (NumBoards) {
-    if(dir!=NULL) {
-      if ((pdir=opendir(str))==0){
-	PrintMessage("Error: target directory \"%s\" does not exist!\n",str);
-        return;
-      }
-      closedir(pdir);
-      snprintf(str,sizeof(str),"%s",dir);
-      PrintMessage("Target: \"%s\"\n",str);
-    }
-    else {
-      getcwd(str, sizeof(str));
-      strcat(str,"/calib");
-      PrintMessage("Taking default target: \"%s/\"\n",str);
-    }
-        
-    for (i=FirstBoard; i<=LastBoard; i++) {
-      drs->GetBoard(i)->Init();
-      drs->GetBoard(i)->SetFrequency(calibfreq);
-      drs->GetBoard(i)->SoftTrigger();
-            
-      PrintMessage("Creating calibration of board %d\n", drs->GetBoard(i)->GetCMCSerialNumber());
-
-      drs->GetBoard(i)->EnableTcal(1);
-      PrintMessage("Tcal enabled");
-
-      if (drs->GetBoard(i)->GetChipVersion() == 3)
-	drs->GetBoard(i)->GetResponseCalibration()->SetCalibrationParameters(1,21,0,20,0,0,0,0,0);
-      else
-	drs->GetBoard(i)->GetResponseCalibration()->SetCalibrationParameters(1,36,110,20,19,40,15,trigfreq,0);
-            
-      drs->GetBoard(i)->SetCalibrationDirectory(str);
-      PrintMessage("Storage directory \"%s\"\n",str);
-
-      for (j=0;j<2;j++) {
-	drs->GetBoard(i)->GetResponseCalibration()->ResetCalibration();
-	PrintMessage("Calibration reset done.\n");
-
-	while (!drs->GetBoard(i)->GetResponseCalibration()->RecordCalibrationPoints(j)) {}
-	PrintMessage("Record calibration points done.\n");
-	while (!drs->GetBoard(i)->GetResponseCalibration()->FitCalibrationPoints(j)) {}
-	PrintMessage("Calibration points fitted.\n");
-	while (!drs->GetBoard(i)->GetResponseCalibration()->OffsetCalibration(j)) {}
-	PrintMessage("Offset calibration done.\n");
-
-	if (!drs->GetBoard(i)->GetResponseCalibration()->WriteCalibration(j))
-	  break;
-      }        
-      drs->GetBoard(i)->Init(); // Reset linear range -0.2 ... 0.8 V
-    } // Loop over boards   
-  }
-  else PrintMessage("No DRS boards available\n");
-}
-
 // Check if DRS is sampling
 bool DAQReadout::IsDRSBusy() {
@@ -871,5 +846,5 @@
 bool DAQReadout::IsDRSFreqSet() {
 
-  for (int i=FirstBoard;i<=LastBoard;i++)
+  for (int i=FirstBoard; i<=LastBoard; i++)
     if (DRSFreq[i]==0) {
       PrintMessage("DRS sampling frequency of board %d not set!\n",i);
@@ -992,7 +967,8 @@
 }
 
-// Write event header
-bool DAQReadout::WriteEventHeader() {
-
+// Write event
+bool DAQReadout::WriteEvent() {
+
+  // Event header
   struct timeval Time;
 
@@ -1000,5 +976,5 @@
   
   EHeader->EventNumber = NumEvents;
-  EHeader->TriggerType = (daq_runtype == data) ? 1 : 0;
+  EHeader->TriggerType = daq_runtype==data ? 0 : 1;
   EHeader->Second = Time.tv_sec;
   EHeader->Microsecond = Time.tv_usec;
@@ -1010,11 +986,8 @@
     return false;
   }
-  return true;
-}
-
-// Write event data (It is required that at least three chunks can be written with writev(), therefore
-// IOV_MAX>=3 is checked at startup
-bool DAQReadout::WriteEventData() {
-
+  
+  // Event data (It is required that at least three chunks can be written with writev(), therefore
+  // IOV_MAX>=3 is checked at startup
+  
   unsigned int Start, Count = 0;
   ssize_t WriteResult, Size = 0;
@@ -1022,5 +995,5 @@
 
   // First chunk: trigger cells
-  DataPart[Count].iov_base = TriggerCell + FirstBoard*kNumberOfChips;
+  DataPart[Count].iov_base = (char *) TriggerCell + FirstBoard*kNumberOfChips*sizeof(int); // TriggerCell is without cast a pointer to an 8-byte unit (two ints) !
   DataPart[Count++].iov_len = RHeader->NBoards * kNumberOfChips * sizeof(int);
   Size += DataPart[Count-1].iov_len;
@@ -1054,5 +1027,17 @@
     } // Chips
   } // Boards
+  
   return true;
+}
+
+// Print configuration to target
+void DAQReadout::PrintConfig(int Target) {
+  PrintMessage(Target, "LogFile: %s\tMaxLogLines: %u\tRawDataPath: %s\n"
+      	       "DefaultFrequency: %.2f\tFirstSample: %d\tSamples: %u\n"
+     	       "MinDiskSpaceMB: %u\tMaxFileSizeMB: %d\tCCPort: %d\n"
+      	       "FirstVMESlot: %d\t\tLastVMESlot: %d\n"
+	       "SlowDataPath: %s\tHVFeedbackConfig: %s\n",
+    fLogFile,fMaxLogLines,fRawDataPath,fDefaultFrequency,fFirstSample,fSamples,fMinDiskSpaceMB,
+    fMaxFileSizeMB,fCCPort,fFirstVMESlot,fLastVMESlot,fSlowDataPath,fHVFeedbackConfig);
 }
 
@@ -1238,7 +1223,4 @@
       else if (m->daq_runtype == pedestal) m->StopDRS();   // ..or for software trigger
 
-      EventsInFile++;      m->NumEvents++;	
-      WriteError |= !m->WriteEventHeader();
-
       // Read event data via VME or generate test data (for one board if no boards available)
       if (m->daq_runtype != test) {
@@ -1252,6 +1234,7 @@
       }
 
-      // Write data to disk and update file size
-      WriteError |= !m->WriteEventData();
+      // Write event to disk and update file size
+      EventsInFile++;      m->NumEvents++;	
+      WriteError |= !m->WriteEvent();
 
       if((FileSize = lseek(m->Rawfile, 0, SEEK_CUR)) == -1) {
@@ -1273,16 +1256,16 @@
   } while((m->NumEvents<m->NumEventsRequested || m->NumEventsRequested==0) && !m->Stop && !WriteError);
 
-  // Print run summary to slow data file and to screen
   m->StopDRS();
-  if(!WriteError) {
-    m->PrintMessage("\rRun #%d (%s) %s, %d events\n",m->RunNumber,daq_runtype_str[m->daq_runtype],(m->NumEvents == m->NumEventsRequested) ? "completed":"stopped",m->NumEvents);
-    m->SlowDataClass->NewEntry("Runinfo");
-    m->SlowDataClass->AddToEntry("%d %s %s %d %d", m->RunNumber, daq_runtype_str[m->daq_runtype], m->RHeader->Description, m->NumEvents, m->FileNumber);
-    if(m->SlowDataClass->ErrorCode != 0) {
-      m->PrintMessage("Error, could not write DAQ data to file (%s), file closed\n", strerror(m->SlowDataClass->ErrorCode));
-    }
-
-  }
+  
+  // Print run summary to screen
+  if(!WriteError) m->PrintMessage("\rRun #%d (%s) %s, %d events\n",m->RunNumber,daq_runtype_str[m->daq_runtype],(m->NumEvents == m->NumEventsRequested) ? "completed":"stopped",m->NumEvents);
   else m->PrintMessage("\rRun #%d (%s) aborted due to error after %d events\n",m->RunNumber,daq_runtype_str[m->daq_runtype],m->NumEvents);
+
+  // Write run summary to slow data file
+  m->SlowDataClass->NewEntry("Runinfo");
+  m->SlowDataClass->AddToEntry("%d %s %s %d %d %s", m->RunNumber, WriteError?"Error":"OK", daq_runtype_str[m->daq_runtype], m->NumEvents, m->FileNumber, m->RHeader->Description);
+  if(m->SlowDataClass->ErrorCode != 0) {
+    m->PrintMessage("Error, could not write DAQ data to file (%s), file closed\n", strerror(m->SlowDataClass->ErrorCode));
+  }
 
   // Print run statistics
