Index: /trunk/FACT++/src/Fits.cc
===================================================================
--- /trunk/FACT++/src/Fits.cc	(revision 11088)
+++ /trunk/FACT++/src/Fits.cc	(revision 11089)
@@ -299,5 +299,7 @@
     {
         ostringstream str;
-        str << "Inserting row into " << fFileName << " failed (fits_insert_rows, rc=" << status << ")";
+        char text[30];
+        fits_get_errstatus(status, text);
+        str << "Inserting row into " << fFileName << " failed (fits_insert_rows, rc=" << status << "), Message: " << text;
         fMess->Error(str);
         Close();
Index: /trunk/FACT++/src/datalogger.cc
===================================================================
--- /trunk/FACT++/src/datalogger.cc	(revision 11088)
+++ /trunk/FACT++/src/datalogger.cc	(revision 11089)
@@ -221,5 +221,5 @@
     ///run numbers
     list<RunNumberType> fRunNumber;
-    ///old run numbers time-out delay (in minutes)
+    ///old run numbers time-out delay (in seconds)
     long fRunNumberTimeout;
     ///previous run number. to check if changed while logging
@@ -362,7 +362,11 @@
     void AppendYearMonthDaytoPath(string& path);
     ///Form the files path
-    string CompileFileName(const string &path, const string &service, const string & extension, const Time &time=Time());
+    string CompileFileNameWithPath(const string &path, const string &service, const string & extension, const Time &time=Time());
+    ///Form the file names only
+    string CompileFileName(const string& service, const string& extension, const Time& time=Time());
     ///Form the files path
-    string CompileFileName(const string &path, uint32_t run, const string &service, const string & extension, const Time &time=Time());
+    string CompileFileNameWithPath(const string &path, const uint32_t run, const string &service, const string & extension, const Time &time=Time());
+    ///Form the file names only
+    string CompileFileName(const uint32_t run, const string& service, const string& extension);//, const Time& time=Time());
     ///Check whether service is in black and/or white list
     bool ShouldSubscribe(const string& server, const string& service);
@@ -376,5 +380,7 @@
     bool RememberFileOrigSizePlease(string& fileName, bool nightly);
     ///Checks if the input osftream is in error state, and if so close it.
-    void CheckForOfstreamError(ofstream& out);
+    bool CheckForOfstreamError(ofstream& out);
+    ///Goes to Write error state and also closes all opened files
+    void GoToWriteErrorState();
     ///Checks if a given path exist
     bool DoesPathExist(string path);
@@ -550,13 +556,16 @@
 //! @param out the ofstream that should be checked
 //
-void DataLogger::CheckForOfstreamError(ofstream& out)
+bool DataLogger::CheckForOfstreamError(ofstream& out)
 {
     if (out.good())
-        return;
+        return true;
 
     Error("An error occured while writing to a text file. Closing it");
-    if (out.is_open())
-        out.close();
-    SetCurrentState(kSM_WriteError);
+//    if (out.is_open())
+//        out.close();
+    GoToWriteErrorState();
+
+    return false;
+//    SetCurrentState(kSM_WriteError);
 }
 // --------------------------------------------------------------------------
@@ -648,29 +657,43 @@
 //! @param extension the extension to add, if any
 //
-string DataLogger::CompileFileName(const string &path, const string &service, const string & extension, const Time &time)
-{
-       ostringstream str;
-       //calculate time suitable for naming files.
-       const Time ftime(time-boost::posix_time::time_duration(12,0,0));
-
-       //output it
-       str << path << Time::fmt("/%Y/%m/%d") << ftime;
-
-       //check if target directory exist
-       if (!DoesPathExist(str.str()))
-           CreateDirectory(str.str());
-
-       //output base of file name
-       str << Time::fmt("/%Y_%m_%d") << ftime;
-
-       //output service name
-       if (!service.empty())
-           str  << "_" << service;
-
-       //output appropriate extension
-       if (!extension.empty())
-           str << "." << extension;
-
-       return str.str();
+//string DataLogger::CompileFileName(const string &path, const string &service, const string & extension, const Time &time)
+string DataLogger::CompileFileName(const string& service, const string& extension, const Time& time)
+{
+    ostringstream str;
+    //calculate time suitable for naming path.
+    const Time ftime(time-boost::posix_time::time_duration(12,0,0));
+
+    //output base of file name
+    str << Time::fmt("%Y_%m_%d") << ftime;
+
+    //output service name
+    if (!service.empty())
+        str  << "_" << service;
+
+    //output appropriate extension
+    if (!extension.empty())
+        str << "." << extension;
+
+    return str.str();
+}
+
+string DataLogger::CompileFileNameWithPath(const string& path, const string& service, const string& extension, const Time& time)
+{
+    ostringstream str;
+    //calculate time suitable for naming files.
+    const Time ftime(time-boost::posix_time::time_duration(12,0,0));
+
+    //output it
+    str << path << Time::fmt("/%Y/%m/%d") << ftime;
+
+    //check if target directory exist
+    if (!DoesPathExist(str.str()))
+        CreateDirectory(str.str());
+
+    str << '/' << CompileFileName(service, extension, time);
+
+    return str.str();
+
+
 }
 // --------------------------------------------------------------------------
@@ -683,16 +706,10 @@
 //! @param extension the extension to add, if any
 //
-string DataLogger::CompileFileName(const string &path, uint32_t run, const string &service, const string & extension, const Time &time)
+//string DataLogger::CompileFileName(const string &path, uint32_t run, const string &service, const string & extension, const Time &time)
+string DataLogger::CompileFileName(const uint32_t run, const string& service, const string& extension)//, const Time& time)
 {
        ostringstream str;
-       //calculate suitable time for naming files and output it
-       str << path << Time::fmt("/%Y/%m/%d") << (time-boost::posix_time::time_duration(12,0,0));
-
-       //check if target directory exist
-       if (!DoesPathExist(str.str()))
-           CreateDirectory(str.str());
-
        //output base of file name
-       str << '/' << setfill('0') << setw(8) << run;
+       str << setfill('0') << setw(8) << run;
 
        //output service name
@@ -706,4 +723,19 @@
 }
 
+string DataLogger::CompileFileNameWithPath(const string& path, const uint32_t run, const string& service, const string& extension, const Time& time)
+{
+    ostringstream str;
+    //calculate suitable time for naming files and output it
+    str << path << Time::fmt("/%Y/%m/%d") << (time-boost::posix_time::time_duration(12,0,0));
+
+    //check if target directory exist
+    if (!DoesPathExist(str.str()))
+        CreateDirectory(str.str());
+
+    str << '/' << CompileFileName(run, service, extension);//, time);
+
+    return str.str();
+
+}
 // --------------------------------------------------------------------------
 //
@@ -1037,5 +1069,5 @@
      fBaseSizeRun = 0;
      fDailyFileDayChangedAlready = true;
-     fRunNumberTimeout = 1;
+     fRunNumberTimeout = 60; //default run-timeout set to 1 minute
      if(fDebugIsOn)
      {
@@ -1114,8 +1146,8 @@
     const Time cTime = Time();
 
-    if ((cTime - fPreviousOldRunNumberCheck).total_seconds() < fRunNumberTimeout*60)
+    if ((cTime - fPreviousOldRunNumberCheck).total_seconds() < fRunNumberTimeout)
         return;
 
-    while (fRunNumber.size() > 1 && (cTime - fRunNumber.back().time) > boost::posix_time::minutes(fRunNumberTimeout))
+    while (fRunNumber.size() > 1 && (cTime - fRunNumber.back().time) > boost::posix_time::seconds(fRunNumberTimeout))
     {
          RemoveOldestRunNumber();
@@ -1230,5 +1262,5 @@
 
     // open report file
-    run.reportName = CompileFileName(fRunFilePath, run.runNumber, "", "rep");
+    run.reportName = CompileFileNameWithPath(fRunFilePath, run.runNumber, "", "rep");
     if (!OpenStream(run.reportFile, run.reportName))
         return -1;
@@ -1241,5 +1273,5 @@
 
     //TODO this notification scheme might be messed up now.... fix it !
-    const string baseFileName = CompileFileName(fRunFilePath, run.runNumber, "", "");
+    const string baseFileName = CompileFileNameWithPath(fRunFilePath, run.runNumber, "", "");
     NotifyOpenedFile(baseFileName, 3, fOpenedRunFiles);
     run.openedFits.clear();
@@ -1278,5 +1310,18 @@
         return;
     //open the log and report files
-    OpenRunFile(fRunNumber.back());
+    if (OpenRunFile(fRunNumber.back()) != 0)
+    {//an error occured. close current run files and go to error state
+        for (list<RunNumberType>::iterator it=fRunNumber.begin(); it != fRunNumber.end(); it++)
+        {
+            if (it->reportFile->is_open())
+                it->reportFile->close();
+#ifdef RUN_LOGS
+            if (it->logFile->is_open())
+                it->logFile->close();
+#endif
+        }
+        StopRunPlease();
+        SetCurrentState(kSM_BadRunConfig);
+    }
 }
 // --------------------------------------------------------------------------
@@ -1330,5 +1375,5 @@
     {
         if (fDebugIsOn)
-            Debug("Its Noon! Closing and reopening daily text files");
+            Debug("Its Noon! Closing and reopening nightly text files");
 
         fNightlyLogFile.close();
@@ -1338,11 +1383,19 @@
         Info("Closed: "+fFullNightlyReportFileName);
 
-        fFullNightlyLogFileName = CompileFileName(fNightlyFilePath, "", "log");
-        OpenTextFilePlease(fNightlyLogFile, fFullNightlyLogFileName);
-        //FIXME: Handle return code properly!
-
-        fFullNightlyReportFileName = CompileFileName(fNightlyFilePath, "", "rep");
-        OpenTextFilePlease(fNightlyReportFile, fFullNightlyReportFileName);
-        //FIXME: Handle return code properly!
+        fFullNightlyLogFileName = CompileFileNameWithPath(fNightlyFilePath, "", "log");
+        if (!OpenTextFilePlease(fNightlyLogFile, fFullNightlyLogFileName))
+        {
+            GoToReadyPlease();
+            SetCurrentState(kSM_BadNightlyConfig);
+            return;
+        }
+
+        fFullNightlyReportFileName = CompileFileNameWithPath(fNightlyFilePath, "", "rep");
+        if (!OpenTextFilePlease(fNightlyReportFile, fFullNightlyReportFileName))
+        {
+            GoToReadyPlease();
+            SetCurrentState(kSM_BadNightlyConfig);
+            return;
+        }
 
         fDailyFileDayChangedAlready = true;
@@ -1354,10 +1407,4 @@
     if ((!sub.fConv.get()) && isItaReport)
     {
-        //trick the converter in case of 'C'. why do I do this ? well simple: the converter checks that the right number
-        //of bytes was written. because I skip 'C' with fits, the bytes will not be allocated, hence the "size copied ckeck"
-        //of the converter will fail, hence throwing an exception.
-        string fakeFormat(I->getFormat());
-        if (fakeFormat[fakeFormat.size()-1] == 'C')
-            fakeFormat = fakeFormat.substr(0, fakeFormat.size()-1);
         sub.fConv = shared_ptr<Converter>(new Converter(Out(), I->getFormat()));
         if (!sub.fConv)
@@ -1449,5 +1496,6 @@
         {
             fNightlyReportFile << header.str() << text << endl;
-            CheckForOfstreamError(fNightlyReportFile);
+            if (!CheckForOfstreamError(fNightlyReportFile))
+                return;
         }
         //write entry to run-report
@@ -1455,5 +1503,6 @@
         {
             *targetRunFile << header.str() << text << endl;
-            CheckForOfstreamError(*targetRunFile);
+            if (!CheckForOfstreamError(*targetRunFile))
+                return;
         }
     }
@@ -1466,10 +1515,12 @@
         {
             MessageImp(fNightlyLogFile).Write(cTime, msg.str().c_str(), fQuality);
-            CheckForOfstreamError(fNightlyLogFile);
+            if (!CheckForOfstreamError(fNightlyLogFile))
+                return;
         }
         if (targetRunFile && targetRunFile->is_open())
         {
             MessageImp(*targetRunFile).Write(cTime, msg.str().c_str(), fQuality);
-            CheckForOfstreamError(*targetRunFile);
+            if (!CheckForOfstreamError(*targetRunFile))
+                return;
         }
     }
@@ -1522,5 +1573,5 @@
     //timeout value
     str.str("");
-    str << "Timeout delay for old run numbers: " << fRunNumberTimeout << " minute(s)";
+    str << "Timeout delay for old run numbers: " << fRunNumberTimeout << " seconds";
     Message(str);
 
@@ -1731,5 +1782,5 @@
 
     ostringstream str;
-    str  << "Timeout delay for old run numbers is now " << fRunNumberTimeout;
+    str  << "Timeout delay for old run numbers is now " << fRunNumberTimeout << " seconds";
     Message(str);
 
@@ -1846,13 +1897,15 @@
         Debug("Starting...");    
     }
-    fFullNightlyLogFileName = CompileFileName(fNightlyFilePath, "", "log");
+    fFullNightlyLogFileName = CompileFileNameWithPath(fNightlyFilePath, "", "log");
     if (!OpenTextFilePlease(fNightlyLogFile, fFullNightlyLogFileName))
         return kSM_BadNightlyConfig;
 
 
-    fFullNightlyReportFileName = CompileFileName(fNightlyFilePath, "", "rep");
+    fFullNightlyReportFileName = CompileFileNameWithPath(fNightlyFilePath, "", "rep");
     if (!OpenTextFilePlease(fNightlyReportFile, fFullNightlyReportFileName))
+    {
+        fNightlyLogFile.close();
         return kSM_BadNightlyConfig;
-
+    }
     //get the size of the newly opened file.
     fBaseSizeNightly = GetFileSize(fFullNightlyLogFileName);
@@ -1863,5 +1916,5 @@
 
     //notify that a new file has been opened.
-    const string baseFileName = CompileFileName(fNightlyFilePath, "", "");
+    const string baseFileName = CompileFileNameWithPath(fNightlyFilePath, "", "");
     NotifyOpenedFile(baseFileName, 3, fOpenedNightlyFiles);
 
@@ -1901,5 +1954,4 @@
         }
     }
-    hasGrouping = true;
     for (unsigned int i=0;i<serviceName.size(); i++)
     {
@@ -1913,5 +1965,5 @@
     if (!sub.nightlyFile.IsOpen())
     {
-        string partialName = CompileFileName(fNightlyFilePath, serviceName, "fits");
+        string partialName = CompileFileNameWithPath(fNightlyFilePath, serviceName, "fits");
 
         const string fileNameOnly = partialName.substr(partialName.find_last_of('/')+1, partialName.size());
@@ -1928,9 +1980,10 @@
         if (!sub.nightlyFile.Open(partialName, serviceName, NULL, &fNumSubAndFitsData.numOpenFits, this, 0))
         {
-            SetCurrentState(kSM_WriteError);
+            GoToWriteErrorState();
+            //SetCurrentState(kSM_WriteError);
             return;
         }
         //notify the opening
-        const string baseFileName = CompileFileName(fNightlyFilePath, "", "");
+        const string baseFileName = CompileFileNameWithPath(fNightlyFilePath, "", "");
         NotifyOpenedFile(baseFileName, 7, fOpenedNightlyFiles);
         if (fNumSubAndFitsIsOn)
@@ -1944,10 +1997,10 @@
         if (hasGrouping)
         {
-            partialName = CompileFileName(fRunFilePath, sub.runNumber, "", "fits");
+            partialName = CompileFileNameWithPath(fRunFilePath, sub.runNumber, "", "fits");
             fileNameOnly = partialName.substr(partialName.find_last_of('/')+1, partialName.size());
         }
         else
         {
-            partialName = CompileFileName(fRunFilePath, sub.runNumber, serviceName, "fits");
+            partialName = CompileFileNameWithPath(fRunFilePath, sub.runNumber, serviceName, "fits");
             fileNameOnly = partialName.substr(partialName.find_last_of('/')+1, partialName.size());
         }
@@ -1973,7 +2026,10 @@
                 Error(str);
                 cRunNumber->runFitsFile = shared_ptr<CCfits::FITS>();//NULL;
+                GoToWriteErrorState();
+                //SetCurrentState(kSM_WriteError);
+                return;
             }
 
-        const string baseFileName = CompileFileName(fRunFilePath, sub.runNumber, "", "");
+        const string baseFileName = CompileFileNameWithPath(fRunFilePath, sub.runNumber, "", "");
         NotifyOpenedFile(baseFileName, 7, fOpenedRunFiles);// + '_' + serviceName, 4);
 
@@ -1986,5 +2042,6 @@
             if (!sub.runFile.Open(partialName, serviceName, (cRunNumber->runFitsFile).get(), &fNumSubAndFitsData.numOpenFits, this, sub.runNumber))
             {
-                SetCurrentState(kSM_WriteError);
+                GoToWriteErrorState();
+                //SetCurrentState(kSM_WriteError);
                 return;
             }
@@ -1994,5 +2051,6 @@
             if (sub.runFile.Open(partialName, serviceName, NULL, &fNumSubAndFitsData.numOpenFits, this, sub.runNumber))
             {
-                SetCurrentState(kSM_WriteError);
+                GoToWriteErrorState();
+                //SetCurrentState(kSM_WriteError);
                 return;
             }
@@ -2069,5 +2127,9 @@
         {
             if (!sub.nightlyFile.Write(sub.fConv.get()))
-                SetCurrentState(kSM_WriteError);
+            {
+                GoToWriteErrorState();
+                return;
+              //SetCurrentState(kSM_WriteError);
+            }
          }
 
@@ -2075,13 +2137,23 @@
         {
             if (!sub.runFile.Write(sub.fConv.get()))
-                SetCurrentState(kSM_WriteError);
+            {
+                GoToWriteErrorState();
+                return;
+                //SetCurrentState(kSM_WriteError);
+            }
         }
 }
 #endif //if has_fits
 
+void DataLogger::GoToWriteErrorState()
+{
+    GoToReadyPlease();
+    SetCurrentState(kSM_WriteError);
+}
+
 std::string DataLogger::SetCurrentState(int state, const char *txt, const std::string &cmd)
 {
-    if (state == kSM_WriteError && GetCurrentState() == kSM_WriteError)
-        return "";
+//    if (state == kSM_WriteError && GetCurrentState() == kSM_WriteError)
+//        return "";
     return StateMachineImp::SetCurrentState(state, txt, cmd);
 }
@@ -2101,5 +2173,9 @@
     //open all the relevant run-files. i.e. all the files associated with run numbers.
     for (list<RunNumberType>::iterator it=fRunNumber.begin(); it != fRunNumber.end(); it++)
-        OpenRunFile(*it);
+        if (OpenRunFile(*it) != 0)
+        {
+            StopRunPlease();
+            return kSM_BadRunConfig;
+        }
 
     return kSM_Logging;
@@ -2129,8 +2205,17 @@
     CCfits::FITS* groupFile;
     unsigned int numFilesToGroup = 0;
+    unsigned int maxCharLength = 0;
     for (map<string, vector<string> >::const_iterator it=filesToGroup.begin(); it != filesToGroup.end(); it++)
     {
+        //add the number of tables in this file to the total number to group
         numFilesToGroup += it->second.size();
-    }
+        //check the length of all the strings to be written, to determine the max string length to write
+        if (it->first.size() > maxCharLength)
+            maxCharLength = it->first.size();
+        for (vector<string>::const_iterator jt=it->second.begin(); jt != it->second.end(); jt++)
+            if (jt->size() > maxCharLength)
+                maxCharLength = jt->size();
+    }
+
     if (fDebugIsOn)
     {
@@ -2146,12 +2231,12 @@
     string groupName;
     if (runNumber != 0)
-        groupName = CompileFileName(fRunFilePath, runNumber, "", "fits");
+        groupName = CompileFileNameWithPath(fRunFilePath, runNumber, "", "fits");
     else
-        groupName = CompileFileName(fNightlyFilePath, "", "fits");
+        groupName = CompileFileNameWithPath(fNightlyFilePath, "", "fits");
 
     Info("Creating FITS group in: "+groupName);
 
     CCfits::Table* groupTable;
-    const int maxCharLength = 50;//FILENAME_MAX;
+//    const int maxCharLength = FILENAME_MAX;
     try
     {
@@ -2224,5 +2309,6 @@
                 str << "Writing FITS row " << i << " in " << groupName << ": " << text << " (file_write_tblbytes, rc=" << status << ")";
                 Error(str);
-                // FIXME: What to do in case of error?
+                GoToWriteErrorState();
+                return;
             }
         }
@@ -2320,4 +2406,5 @@
     return kSM_Ready;
 }
+
 // --------------------------------------------------------------------------
 //
