Index: /trunk/FACT++/src/dataLogger.cc
===================================================================
--- /trunk/FACT++/src/dataLogger.cc	(revision 10473)
+++ /trunk/FACT++/src/dataLogger.cc	(revision 10474)
@@ -62,5 +62,6 @@
 #include <sys/stat.h>
 
-//#define HAS_FITS
+#define HAS_FITS
+//#define ONE_RUN_FITS_ONLY
 
 #include <fstream>
@@ -70,7 +71,18 @@
 
 #ifdef HAS_FITS
-//#include <astroroot.h>
 #include "Fits.h"
 #endif
+
+//Dim structures
+struct DataLoggerStats {
+	long long sizeWritten;
+	long long freeSpace;
+	long writingRate;
+};
+
+struct NumSubAndFitsType {
+	int numSubscriptions;
+	int numOpenFits;
+};
 
 class DataLogger : public StateMachineDim, DimInfoHandler
@@ -107,18 +119,4 @@
 	///run number (-1 means no run number specified)
 	int fRunNumber; 
-	///Current year
-//	short fYear;
-	///Current Month
-//	short fMonth;
-	///Current Day
-//	short fDay;
-	///Current Hour
-//	short fHour;
-	///Current Minute
-//	short fMin;
-	///Current Second
-//	short fSec;
-	///Current Milliseconds
-//	int fMs;
 	///Current Service Quality
 	int fQuality;
@@ -216,4 +214,6 @@
 			if (*numCopies < 1)
 			{
+				if (dimInfo)
+				delete dimInfo;
 #ifdef HAS_FITS
 				if (dailyFile.IsOpen())
@@ -222,6 +222,4 @@
 					runFile.Close();
 #endif
-				if (dimInfo)
-				delete dimInfo;
 				if (numCopies)	
 				delete numCopies;
@@ -268,10 +266,13 @@
 	///Allocate the buffers required for fits
 	void AllocateFITSBuffers(SubscriptionType& sub);
+		
+#ifdef ONE_RUN_FITS_ONLY
 	///FITS file for runs. only one, hence dealt with in the dataLogger itself
 	FITS* fRunFitsFile;
-#endif
+#endif //one_run_fits_only
+#endif//has_fits
 public:	
 	///checks with fServiceList whether or not the services got updated
-	void CheckForServicesUpdate(); 
+	bool CheckForServicesUpdate(); 
 
 private:	
@@ -292,7 +293,10 @@
 	long long fBaseSizeRun;
 	///Service for opened files
-	DimService* fOpenedFiles;
-	char* fDimBuffer;
-	inline void NotifyOpenedFile(std::string name, int type);
+	DimService* fOpenedDailyFiles;
+	DimService* fOpenedRunFiles;
+	DimService* fNumSubAndFits;
+	NumSubAndFitsType fNumSubAndFitsData;
+//	char* fDimBuffer;
+	inline void NotifyOpenedFile(std::string name, int type, DimService* service);
 	
 }; //DataLogger
@@ -312,18 +316,25 @@
 const char* DataLogger::fRunNumberInfo = "RUN_NUMBER";
 
+
 void DataLogger::ServicesMonitoring()
 {
 		//create the DIM service
 		int dataSize = 2*sizeof(long long) + sizeof(long);
-		char* data = new char[dataSize];
-		memset(data, 0, dataSize);
-                DimDescribedService srvc((GetName()+"/STATS").c_str(), "x:2;l:1", static_cast<void*>(data), dataSize,
-                                        "Add description here");
+
+		DataLoggerStats statVar;
+		statVar.sizeWritten = 0;
+		statVar.freeSpace = 0;
+		statVar.writingRate = 0;
+
+		struct statvfs vfs;
+		if (!statvfs(fDailyFileName.c_str(), &vfs))
+			statVar.freeSpace = vfs.f_bsize*vfs.f_bavail;
+		else
+			statVar.freeSpace = -1;
+//        DimDescribedService srvc((GetName()+"/STATS").c_str(), "x:2;l:1", &statVar, dataSize,//static_cast<void*>(data), dataSize,
+//                                        "Add description here");
+		DimService srvc ("DATA_LOGGER/STATS", "x:2;l:1", &statVar, dataSize);
 		double deltaT = 1;
 		fPreviousSize = 0;
-
-		long long& targetSize  = reinterpret_cast<long long*>(data)[0];
-		long long& targetFreeSpace  = reinterpret_cast<long long*>(data)[1];
-		long& targetRate = reinterpret_cast<long*>(data + 2*sizeof(long long))[0];
 		//loop-wait for broadcast
 		while (fContinueMonitoring)
@@ -371,28 +382,25 @@
 				fFileSizesMap[fFullRunReportFileName] = st.st_size;
 			}	
-			if (fDailyLogFile.is_open())
-			{
-				struct statvfs vfs;
-				statvfs(fDailyFileName.c_str(), &vfs);
-				targetFreeSpace = vfs.f_bsize*vfs.f_bavail;
-			}
+
+			if (!statvfs(fDailyFileName.c_str(), &vfs))
+				statVar.freeSpace = vfs.f_bsize*vfs.f_bavail;
+			else
+				statVar.freeSpace = -1;
+			
 			//sum up all the file sizes. past and present
-			targetSize = 0;
+			statVar.sizeWritten = 0;
 			for (std::map<std::string, long long>::iterator it=fFileSizesMap.begin(); it != fFileSizesMap.end();  it++)
-				targetSize += it->second;
-			targetSize -= fBaseSizeDaily;
-			targetSize -= fBaseSizeRun;
+				statVar.sizeWritten += it->second;
+			statVar.sizeWritten -= fBaseSizeDaily;
+			statVar.sizeWritten -= fBaseSizeRun;
 			//FIXME get the actual time elapsed
-			targetRate = (targetSize - fPreviousSize)/deltaT;  
-			fPreviousSize = targetSize;
-//			if (targetRate != 0) //if data has been written
-			{
-std::cout << "fBaseSizeDaily: " << fBaseSizeDaily << " fBaseSizeRun: " << fBaseSizeRun << std::endl;
-//std::cout << "Written Size: " << targetSize << ", free space: " << targetFreeSpace << ", data rate: " << targetRate << " Bytes/s" << std::endl;
-
-				srvc.updateService(static_cast<void*>(data), dataSize);
+			statVar.writingRate = (statVar.sizeWritten - fPreviousSize)/deltaT;  
+			fPreviousSize = statVar.sizeWritten;
+			if (statVar.writingRate != 0) //if data has been written
+			{
+//std::cout << "rate: " << statVar.writingRate << std::endl;
+				srvc.updateService(&statVar, dataSize);//static_cast<void*>(data), dataSize);
 			}
 		}
-		delete[] data;
 }
 
@@ -408,9 +416,11 @@
 {	
 		//initialize member data
-		fDailyFileName = ".";
-		fRunFileName = ".";
+		fDailyFileName = "/home/lyard/log";//".";
+		fRunFileName = "/home/lyard/log";//".";
 		fRunNumber = 12345;
 #ifdef HAS_FITS
+#ifdef ONE_RUN_FITS_ONLY
 		fRunFitsFile = NULL;
+#endif
 #endif
 		//Give a name to this machine's specific states
@@ -422,24 +432,23 @@
 
         /*Add the possible transitions for this machine*/
-
                 AddTransition(kSM_DailyOpen, fTransStart, kSM_Ready, kSM_BadDailyConfig)
-                    (boost::bind(&DataLogger::StartPlease, this))
-                    ("start the daily logging. daily file location must be specified already");
+                    (boost::bind(&DataLogger::StartPlease, this));
+//                    ("start the daily logging. daily file location must be specified already");
 
 		AddTransition(kSM_Ready, fTransStop, kSM_DailyOpen, kSM_WaitingRun, kSM_Logging)
-                    (boost::bind(&DataLogger::GoToReadyPlease, this))
-                    ("stop the data logging");
+                    (boost::bind(&DataLogger::GoToReadyPlease, this));
+//                   ("stop the data logging");
 
                 AddTransition(kSM_Logging, fTransStartRun, kSM_WaitingRun, kSM_BadRunConfig)
-                    (boost::bind(&DataLogger::StartRunPlease, this))
-                    ("start the run logging. run file location must be specified already.");
+                    (boost::bind(&DataLogger::StartRunPlease, this));
+//                    ("start the run logging. run file location must be specified already.");
 
                 AddTransition(kSM_WaitingRun, fTransStopRun, kSM_Logging)
-                    (boost::bind(&DataLogger::StopRunPlease, this))
-                    ("");
+                    (boost::bind(&DataLogger::StopRunPlease, this));
+//                    ("");
 
                 AddTransition(kSM_Ready, fTransReset, kSM_Error, kSM_BadDailyConfig, kSM_BadRunConfig, kSM_Error)
-                    (boost::bind(&DataLogger::GoToReadyPlease, this))
-                    ("transition to exit error states. dunno if required or not, would close the daily file if already openned.");
+                    (boost::bind(&DataLogger::GoToReadyPlease, this));
+//                    ("transition to exit error states. dunno if required or not, would close the daily file if already openned.");
 
                 AddTransition(kSM_WaitingRun, fTransWait, kSM_DailyOpen)
@@ -449,10 +458,10 @@
         
                 AddConfiguration(fConfigDay, "C", kSM_Ready, kSM_BadDailyConfig)
-                    (boost::bind(&DataLogger::ConfigureDailyFileName, this, _1))
-                    ("configure the daily file location. cannot be done before the file is actually opened");
+                    (boost::bind(&DataLogger::ConfigureDailyFileName, this, _1));;
+//                    ("configure the daily file location. cannot be done before the file is actually opened");
 
                 AddConfiguration(fConfigRun, "C", kSM_Ready, kSM_BadDailyConfig, kSM_DailyOpen, kSM_WaitingRun, kSM_BadRunConfig)
-                    (boost::bind(&DataLogger::ConfigureRunFileName, this, _1))
-                    ("configure the run file location. cannot be done before the file is actually opened, and not in a dailly related error.");
+                    (boost::bind(&DataLogger::ConfigureRunFileName, this, _1));
+//                    ("configure the run file location. cannot be done before the file is actually opened, and not in a dailly related error.");
 
 		//Provide a logging command
@@ -464,5 +473,5 @@
                     (boost::bind(&DataLogger::LogMessagePlease, this, _1));
 
-		fServiceList.SetHandler(this);
+ 		fServiceList.SetHandler(this);
 		CheckForServicesUpdate();
 		
@@ -473,12 +482,20 @@
 		fBaseSizeRun = 0;
 		//start the open files service
-		fDimBuffer = new char[256];
-		memset(fDimBuffer, 0, sizeof(int));
-		fDimBuffer[sizeof(int)] = '\0';
+//		fDimBuffer = new char[256];
+//		memset(fDimBuffer, 0, sizeof(int));
+//		fDimBuffer[sizeof(int)] = '\0';
+
 		//gives the entire buffer size. Otherwise, dim overwrites memory at bizarre locations if smaller size is given at creation time.
-                fOpenedFiles = 	new DimDescribedService((GetName()+"/FILENAME").c_str(), "i:1;C", static_cast<void*>(fDimBuffer), 256,
-                                                        "Add description here");
-		
-		
+//        fOpenedFiles = 	new DimDescribedService((GetName()+"/FILENAME").c_str(), "i:1;C", static_cast<void*>(fDimBuffer), 256, "Add description here");
+		fOpenedDailyFiles = new DimService((GetName() + "/FILENAME_DAILY").c_str(), const_cast<char*>(""));//"i:1;C", static_cast<void*>(fDimBuffer), 256);
+		fOpenedRunFiles = new DimService((GetName() + "/FILENAME_RUN").c_str(), const_cast<char*>(""));
+		fOpenedDailyFiles->setQuality(0);
+		fOpenedRunFiles->setQuality(0);
+		fOpenedDailyFiles->updateService();
+		fOpenedRunFiles->updateService();
+		fNumSubAndFitsData.numSubscriptions = 0;
+		fNumSubAndFitsData.numOpenFits = 0;
+		fNumSubAndFits = new DimService((GetName() + "/NUM_SUBS").c_str(), "i:2", &fNumSubAndFitsData, sizeof(NumSubAndFitsType));
+
 }
 // --------------------------------------------------------------------------
@@ -490,7 +507,7 @@
 //
 //FIXME The service must be udpated so that I get the first notification. This should not be
-void DataLogger::CheckForServicesUpdate()
+bool DataLogger::CheckForServicesUpdate()
 { 
-
+	bool serviceUpdated = false;
 	//get the current server list
 	const std::vector<std::string> serverList = fServiceList.GetServerList();
@@ -505,9 +522,12 @@
 				break;
 		if (givenServers == serverList.end())//server vanished. Remove it
+		{	
 			toBeDeleted.push_back(cListe->first);
+			serviceUpdated = true;
+		}
+			
 	}
 	for (std::vector<std::string>::const_iterator it = toBeDeleted.begin(); it != toBeDeleted.end(); it++)
 		fServiceSubscriptions.erase(*it);
-
 	//now crawl through the list of servers, and see if there was some updates
 	for (std::vector<std::string>::const_iterator i=serverList.begin(); i!=serverList.end();i++)
@@ -535,4 +555,5 @@
 				{
 					toBeDeleted.push_back(serverSubs->first);
+					serviceUpdated = true;
 				}	
 			}
@@ -547,4 +568,5 @@
 				{//service not found. Add it
 					cSubs->second[*givenSubs].dimInfo = new DimStampedInfo(((*i) + "/" + *givenSubs).c_str(), const_cast<char*>(""), this);
+					serviceUpdated = true;
 				}	
 			}
@@ -559,7 +581,9 @@
 					continue;
 				liste[*j].dimInfo = new DimStampedInfo(((*i) + "/" + (*j)).c_str(), const_cast<char*>(""), this);
+				serviceUpdated = true;
 			}
 		}	
 	}
+	return serviceUpdated;
 }
 // --------------------------------------------------------------------------
@@ -569,8 +593,9 @@
 DataLogger::~DataLogger()
 {
+	//release the services subscriptions
+	fServiceSubscriptions.clear();
 	//exit the monitoring loop
 	fContinueMonitoring = false;
-	delete[] fDimBuffer;
-	delete fOpenedFiles;
+//	delete[] fDimBuffer;
 	fMonitoringThread.join();
 	//close the files
@@ -583,10 +608,14 @@
 	if (fRunReportFile.is_open())
 		fRunReportFile.close();
-	//release the services subscriptions
-	fServiceSubscriptions.clear();
+	delete fOpenedDailyFiles;
+	delete fOpenedRunFiles;
+	delete fNumSubAndFits;
+//TODO notify that all files were closed
 #ifdef HAS_FITS
+#ifdef ONE_RUN_FITS_ONLY
 	if (fRunFitsFile != NULL)
 		delete fRunFitsFile;
 	fRunFitsFile = NULL;
+#endif
 #endif
 }
@@ -719,7 +748,16 @@
 {
 	DimInfo* I = getInfo();
+	SubscriptionsListType::iterator x;
+	std::map<std::string, SubscriptionType>::iterator y;
 	if (I==NULL)
 	{
-		CheckForServicesUpdate();
+		if (CheckForServicesUpdate())
+		{
+			//services were updated. Notify
+			fNumSubAndFitsData.numSubscriptions = 0;
+			for (x=fServiceSubscriptions.begin(); x != fServiceSubscriptions.end(); x++)
+				fNumSubAndFitsData.numSubscriptions += x->second.size();
+			fNumSubAndFits->updateService();
+		}
 		return;
 	}
@@ -727,6 +765,4 @@
 	//this is a fix for a bug that provides bad Infos when a server starts
 	bool found = false;
-	SubscriptionsListType::iterator x;
-	std::map<std::string, SubscriptionType>::iterator y;
 	for (x=fServiceSubscriptions.begin(); x != fServiceSubscriptions.end(); x++)
 	{//find current service is subscriptions
@@ -933,4 +969,5 @@
 int DataLogger::ConfigureDailyFileName(const Event& evt)
 {
+std::cout << "Configure Daily File Name" << std::endl;
 	if (evt.GetText() != NULL)
 		fDailyFileName = std::string(evt.GetText());	
@@ -949,4 +986,5 @@
 int DataLogger::ConfigureRunFileName(const Event& evt)
 {
+std::cout << "Configure Run File Name" << std::endl;
 	if (evt.GetText() != NULL)
 		fRunFileName = std::string(evt.GetText());
@@ -976,10 +1014,12 @@
 //!		this is not a problem though because file are not opened so often.
 //! @ param type the type of the opened file. 0 = none open, 1 = log, 2 = text, 4 = fits
-inline void DataLogger::NotifyOpenedFile(std::string name, int type)
+inline void DataLogger::NotifyOpenedFile(std::string name, int type, DimService* service)
 {
 //std::cout << "name: " << name << " size: " << name.size() << std::endl;
-	reinterpret_cast<int*>(fDimBuffer)[0] = type;
-	strcpy(&fDimBuffer[sizeof(int)], name.c_str());
-	fOpenedFiles->updateService(static_cast<void*>(fDimBuffer), name.size() + 1 + sizeof(int));
+//	reinterpret_cast<int*>(fDimBuffer)[0] = type;
+//	strcpy(&fDimBuffer[sizeof(int)], name.c_str());
+	service->setQuality(type);
+	service->updateService(const_cast<char*>(name.c_str()));
+//	fOpenedFiles->updateService(static_cast<void*>(fDimBuffer), name.size() + 1 + sizeof(int));
 }
 // --------------------------------------------------------------------------
@@ -1017,5 +1057,17 @@
 	fPreviousSize = 0;
 	//notify that files were opened
-	NotifyOpenedFile(sTime.str(), 3);
+	std::string actualTargetDir;
+	if (fDailyFileName == ".")
+	{
+		char currentPath[FILENAME_MAX];
+		getcwd(currentPath, sizeof(currentPath));
+		actualTargetDir = currentPath;
+	}
+	else
+	{
+		actualTargetDir = fDailyFileName;	
+	}
+std::cout << actualTargetDir << '/' << sTime.str() << std::endl;
+	NotifyOpenedFile(actualTargetDir + '/' + sTime.str(), 3, fOpenedDailyFiles);
 	
 	
@@ -1056,8 +1108,19 @@
 			fFileSizesMap[partialName] = 0;
 		}
-		sub.dailyFile.Open(partialName, serviceName, NULL);
+		sub.dailyFile.Open(partialName, serviceName, NULL, &fNumSubAndFitsData.numOpenFits);
 		//notify the opening
-		NotifyOpenedFile(sTime.str() + '_' + serviceName, 4);
-		
+		std::string actualTargetDir;
+		if (fDailyFileName == ".")
+		{
+			char currentPath[FILENAME_MAX];
+			getcwd(currentPath, sizeof(currentPath));
+			actualTargetDir = currentPath;
+		}
+		else
+		{
+			actualTargetDir = fDailyFileName;	
+		}		
+		NotifyOpenedFile(actualTargetDir + '/' + sTime.str(), 4, fOpenedDailyFiles);
+		fNumSubAndFits->updateService();
 	}
 	if (!sub.runFile.IsOpen() && (GetCurrentState() == kSM_Logging))
@@ -1065,7 +1128,11 @@
 		std::stringstream sRun;
 		sRun << fRunNumber;
+#ifdef ONE_RUN_FITS_ONLY
 		std::string partialName = fRunFileName + '/' + sRun.str() + ".fits";//'_' + serviceName + ".fits";
 		if (fRunFitsFile == NULL)
 		{
+#else
+		std::string partialName = fRunFileName + '/' + sRun.str() + '_' + serviceName + ".fits";
+#endif
 			//get the size of the file we're about to open
 			if (fFileSizesMap.find(partialName) == fFileSizesMap.end())
@@ -1078,7 +1145,9 @@
 				fFileSizesMap[partialName] = 0;	
 			}
+#ifdef ONE_RUN_FITS_ONLY
 			try
 			{
 				fRunFitsFile = new FITS(partialName, RWmode::Write);	
+				(fNumSubAndFitsData.numOpenFits)++;
 			}	
 			catch (CCfits::FitsError e)
@@ -1088,7 +1157,25 @@
 				throw runtime_error(err.str());	
 			}
-			NotifyOpenedFile(sRun.str(), 4);// + '_' + serviceName, 4);
+#endif
+			std::string actualTargetDir;
+			if (fRunFileName == ".")
+			{
+				char currentPath[FILENAME_MAX];
+				getcwd(currentPath, sizeof(currentPath));
+				actualTargetDir = currentPath;
+			}
+			else
+			{
+				actualTargetDir = fRunFileName;	
+			}		
+			NotifyOpenedFile(actualTargetDir + '/' + sRun.str(), 4, fOpenedRunFiles);// + '_' + serviceName, 4);
+#ifdef ONE_RUN_FITS_ONLY
 		}
-		sub.runFile.Open(partialName, serviceName, fRunFitsFile);
+		sub.runFile.Open(partialName, serviceName, fRunFitsFile, &fNumSubAndFitsData.numOpenFits);
+#else
+		sub.runFile.Open(partialName, serviceName, NULL, &fNumSubAndFitsData.numOpenFits);
+#endif //one_run_fits_only
+	   fNumSubAndFits->updateService();
+
 	}
 }	
@@ -1218,5 +1305,16 @@
 		fFileSizesMap[fFullRunReportFileName] = 0;
 	}
-	NotifyOpenedFile(sRun.str(), 3);
+	std::string actualTargetDir;
+	if (fRunFileName == ".")
+	{
+		char currentPath[FILENAME_MAX];
+		getcwd(currentPath, sizeof(currentPath));
+		actualTargetDir = currentPath;
+	}
+	else
+	{
+		actualTargetDir = fRunFileName;	
+	}		
+	NotifyOpenedFile(actualTargetDir + '/' + sRun.str(), 3, fOpenedRunFiles);
 	
 	return kSM_Logging;
@@ -1242,10 +1340,17 @@
 					j->second.runFile.Close();	
 		}
+#ifdef ONE_RUN_FITS_ONLY
 	if (fRunFitsFile != NULL)
 	{
 		delete fRunFitsFile;
 		fRunFitsFile = NULL;	
-	}
-#endif
+std::cout << "FNumSub2: " << fNumSubAndFitsData.numOpenFits << std::endl;
+		(fNumSubAndFitsData.numOpenFits)--;
+std::cout << "FNumSub3: " << fNumSubAndFitsData.numOpenFits << std::endl;
+	}
+#endif
+#endif
+	NotifyOpenedFile("None", 0, fOpenedRunFiles);
+	fNumSubAndFits->updateService();
 	return kSM_WaitingRun;
 
@@ -1278,10 +1383,22 @@
 					j->second.runFile.Close();	
 		}
+#ifdef ONE_RUN_FITS_ONLY
 	if (fRunFitsFile != NULL)
 	{
 		delete fRunFitsFile;
-		fRunFitsFile = NULL;	
-	}
-#endif
+		fRunFitsFile = NULL;
+		(fNumSubAndFitsData.numOpenFits)--;
+	}
+#endif
+#endif
+	if (GetCurrentState() == kSM_Logging)
+		NotifyOpenedFile("None", 0, fOpenedRunFiles);
+	if (GetCurrentState() == kSM_Logging || 
+	    GetCurrentState() == kSM_WaitingRun || 
+	    GetCurrentState() == kSM_DailyOpen)
+	{ 
+		NotifyOpenedFile("None", 0, fOpenedDailyFiles);
+		fNumSubAndFits->updateService();
+	}
 	return kSM_Ready;
 }
@@ -1333,5 +1450,5 @@
 
     logger.SetReady();
- //  logger.StartPlease();
+
     shell.Run();                 // Run the shell
      logger.SetNotReady();
