Index: trunk/FACT++/src/dataLogger.cc
===================================================================
--- trunk/FACT++/src/dataLogger.cc	(revision 10253)
+++ trunk/FACT++/src/dataLogger.cc	(revision 10264)
@@ -1,53 +1,58 @@
-
+//****************************************************************
+/** @class DataLogger
+  
+  @brief Logs all message and infos between the services
+  
+  This is the main logging class facility. 
+  It derives from StateMachineDim and DimInfoHandler. the first parent is here to enforce 
+  a state machine behaviour, while the second one is meant to make the dataLogger receive
+  dim services to which it subscribed from.
+  The possible states and transitions of the machine are:
+  \dot
+  digraph datalogger {
+  		node [shape=record, fontname=Helvetica, fontsize=10];
+  	e [label="Error" color="red"];
+   r [label="Ready"]
+   d [label="DailyOpen"]
+   w [label="WaitingRun"]
+  	l [label="Logging"]
+   b [label="BadDailyconfig" color="red"]
+   c [label="BadRunConfig" color="red"]
+  
+  e -> r
+  r -> e
+  r -> d
+  r -> b
+  d -> w
+  d -> r
+  w -> r
+  l -> r
+  l -> w
+  b -> d
+  w -> c
+  w -> l
+  b -> r
+  c -> r
+  c -> l
+  }
+  \enddot
+  
+  @todo
+  	- Retrieve also the messages, not only the infos
+ */
+ //****************************************************************
 #include "Event.h"
 #include "Time.h"
 #include "StateMachineDim.h"
 #include "ServiceList.h"
+#include "Converter.h"
+#include "MessageImp.h"
+
 #include <fstream>
 
 #include <boost/bind.hpp>
 
-//****************************************************************
-/** @class DataLogger
- * 
- * @brief Logs all message and infos between the services
- * 
- * This is the main logging class facility. 
- * It derives from StateMachineDim and DimInfoHandler. the first parent is here to enforce 
- * a state machine behaviour, while the second one is meant to make the dataLogger receive
- * dim services to which it subscribed from.
- * The possible states and transitions of the machine are:
- * \dot
- * digraph datalogger {
- * 		node [shape=record, fontname=Helvetica, fontsize=10];
- * 	e [label="Error" color="red"];
- *  r [label="Ready"]
- *  d [label="DailyOpen"]
- *  w [label="WaitingRun"]
- * 	l [label="Logging"]
- *  b [label="BadDailyconfig" color="red"]
- *  c [label="BadRunConfig" color="red"]
- * 
- * e -> r
- * r -> e
- * r -> d
- * r -> b
- * d -> w
- * d -> r
- * w -> r
- * l -> r
- * l -> w
- * b -> d
- * w -> c
- * w -> l
- * b -> r
- * c -> r
- * c -> l
- * }
- * \enddot
- * 
- * @todo
- * 	- A lot
- ****************************************************************/
+#include <astroroot.h>
+
 class DataLogger : public StateMachineDim, DimInfoHandler
 {
@@ -68,58 +73,167 @@
 private:
 	//Define all the data structure specific to the DataLogger here
-	std::ofstream fDailyFile; /// ofstream for the dailyfile
-	std::ofstream fRunFile; /// ofstream for the run-specific file
-	std::string fDailyFileName; /// base path of the dailyfile
-	std::string fRunFileName; ///base path of the run file
-	int runNumber; ///run number (-1 means no run number specified)
+ 	/// ofstream for the dailyLogfile
+	std::ofstream fDailyLogFile;
+	/// ofstream for the run-specific Log file
+	std::ofstream fRunLogFile; 
+
+	/// ofstream for the daily report file
+	std::ofstream fDailyReportFile;
+	/// ofstream for the run-specific report file
+	std::ofstream fRunReportFile;
+	/// base path of the dailyfile
+	std::string fDailyFileName; 
+	///base path of the run file
+	std::string fRunFileName; 
+	///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;
+	///Modified Julian Date
+	double fMjD;
 	
 	///Define all the static names
-	static const char* configDay;
-	static const char* configRun;
-	static const char* configRunNumber;
-	static const char* configLog;
-	static const char* transStart;
-	static const char* transStop;
-	static const char* transStartRun;
-	static const char* transStopRun;
-	static const char* transReset;
-	static const char* transWait;
-	static const char* runNumberInfo; ///< This is the name of the dimInfo received to specify the run number. It must be updated once the final name will be defined
-	
-	int Execute(); ///Inherited from state machine impl
-	
-	int Transition(const Event& evt); ///Inherited from state machine impl
-	
-	int Configure(const Event& evt); ///Inherited from state machine impl
+	static const char* fConfigDay;
+	static const char* fConfigRun;
+	static const char* fConfigRunNumber;
+	static const char* fConfigLog;
+	static const char* fTransStart;
+	static const char* fTransStop;
+	static const char* fTransStartRun;
+	static const char* fTransStopRun;
+	static const char* fTransReset;
+	static const char* fTransWait;
+	static const char* fRunNumberInfo; ///< This is the name of the dimInfo received to specify the run number. It must be updated once the final name will be defined
+	///Inherited from state machine impl
+	int Execute(); 
+	
+	///Inherited from state machine impl
+	int Transition(const Event& evt); 
+	
+	///Inherited from state machine impl
+	int Configure(const Event& evt); 
 	
 	//overloading of DIM's infoHandler function
-	void infoHandler(); ///Inherited from DimInfoHandler
-	
-	ServiceList fServiceList;///for obtaining the name of the existing services
-	
-	std::map<std::string, std::vector<DimStampedInfo> > fServiceSubscriptions; ///All the services to which we've subscribed to. Sorted by server name
-	
-	//internal methods
-	void LogPlease(DimInfo* I); ///Logging method for the services info received
-	std::string ToString(const char *format, const void *data, int size); ///Convertion from raw format to human-readable string
-	//configure methods
-	int ConfigureDailyFileName(const Event& evt); ///Configuration of the daily file path
-	int ConfigureRunFileName(const Event& evt); ///Configuration fo the file name
-	//TODO this will be given by an info, not a command.
-	int ConfigureRunNumber(const Event& evt); ///DEPREC - configuration of the run number
-	int LogMessagePlease(const Event& evt); ///logging method for the messages
-	void CheckForServicesUpdate(); ///checks with fServiceList whether or not the services got updated
-	void CheckForRunNumber(DimInfo* I); ///checks whether or not the current info being treated is a run number
-	//transitions methods
-	int StartPlease(); /// start transition
-	int StopPlease(); ///stop transition
-	int StartRunPlease(); ///from waiting to logging transition
-	int StopRunPlease(); /// from logging to waiting transition
-	int ResetPlease(); ///reset transition
-	int DailyToWaitRunPlease(); ///from dailyOpen to waiting transition
-
-	void InitServiceSubscription(); ///first subscription to the dim services.
-	
-
+	void infoHandler(); 
+	
+	///for obtaining the name of the existing services
+	ServiceList fServiceList;
+	
+	
+	///A std pair to store both the DimInfo name and the actual DimInfo pointer 
+//	typedef std::pair<std::string, DimStampedInfo*> subscriptionType; 
+	///All the services to which we've subscribed to. Sorted by server name
+//	std::map<const std::string, std::vector<subscriptionType > > fServiceSubscriptions; 
+
+	///A std pair to store both the DimInfo pointer and the corresponding outputted fits file
+	struct SubscriptionType
+	{ 
+		///daily FITS output file
+		AstroRootIo	dailyFile;
+		///run-specific FITS output file
+		AstroRootIo	runFile;
+		///the actual dimInfo pointer
+		DimStampedInfo* dimInfo;
+		///the number of existing handlers to this structure.
+		///This is required otherwise I MUST handle the deleting of dimInfo outside from the destructor
+		int* numCopies;
+		void operator = (const SubscriptionType& other)
+		{
+			dailyFile = other.dailyFile;
+			runFile = other.runFile;
+			dimInfo = other.dimInfo;	
+			numCopies = other.numCopies;
+			(*numCopies)++;
+		}
+		SubscriptionType(const SubscriptionType& other)
+		{
+			dailyFile = other.dailyFile;
+			runFile = other.runFile;
+			dimInfo = other.dimInfo;
+			numCopies = other.numCopies;
+			(*numCopies)++;	
+		}
+		SubscriptionType(DimStampedInfo* info)
+		{
+			dimInfo = info;	
+			numCopies = new int(1);
+		}
+		SubscriptionType()
+		{
+			dimInfo = NULL;
+			numCopies = new int(1);
+		}
+		~SubscriptionType()
+		{
+			if (numCopies)
+			(*numCopies)--;
+			if (numCopies)
+			if (*numCopies < 1)
+			{
+				if (dailyFile.IsOpen())
+					dailyFile.Close();
+				if (runFile.IsOpen())
+					runFile.Close();
+				if (dimInfo)
+				delete dimInfo;
+				if (numCopies)	
+				delete numCopies;
+				dimInfo = NULL;
+				numCopies = NULL;
+			}
+		}
+	};
+	typedef std::map<const std::string, std::map<std::string, SubscriptionType>> SubscriptionsListType;
+	///All the services to which we have subscribed to, sorted by server name.
+	SubscriptionsListType fServiceSubscriptions;
+
+
+	///Reporting method for the services info received
+	void ReportPlease(DimInfo* I, SubscriptionType& sub);  
+
+	///Configuration of the daily file path
+	int ConfigureDailyFileName(const Event& evt); 
+	///Configuration fo the file name
+	int ConfigureRunFileName(const Event& evt); 
+	///DEPREC - configuration of the run number
+	int ConfigureRunNumber(const Event& evt); 
+	///logging method for the messages
+	int LogMessagePlease(const Event& evt); 
+	///checks whether or not the current info being treated is a run number
+	void CheckForRunNumber(DimInfo* I); 
+
+	/// start transition
+	int StartPlease(); 
+	///from waiting to logging transition
+	int StartRunPlease(); 
+	/// from logging to waiting transition
+	int StopRunPlease(); 
+	///stop and reset transition
+	int GoToReadyPlease(); 
+	///from dailyOpen to waiting transition
+	int DailyToWaitRunPlease(); 
+	///Open fits files
+	void OpenFITSFilesPlease(SubscriptionType& sub);
+	///Write data to FITS files
+	void WriteToFITS(SubscriptionType& sub);
+	///Allocate the buffers required for fits
+	void AllocateFITSBuffers(SubscriptionType& sub);
+public:	
+	///checks with fServiceList whether or not the services got updated
+	void CheckForServicesUpdate(); 
 	
 }; //DataLogger
@@ -127,28 +241,29 @@
 //static members initialization
 //since I do not check the transition/config names any longer, indeed maybe these could be hard-coded... but who knows what will happen in the future ?
-const char* DataLogger::configDay = "CONFIG_DAY";
-const char* DataLogger::configRun = "CONFIG_RUN";
-const char* DataLogger::configRunNumber = "CONFIG_RUN_NUMBER";
-const char* DataLogger::configLog = "LOG";
-const char* DataLogger::transStart = "START";
-const char* DataLogger::transStop = "STOP";
-const char* DataLogger::transStartRun = "START_RUN";
-const char* DataLogger::transStopRun = "STOP_RUN";
-const char* DataLogger::transReset = "RESET";
-const char* DataLogger::transWait = "WAIT_RUN_NUMBER";
-const char* DataLogger::runNumberInfo = "RUN_NUMBER";
-
-/****************************************************************
- * 
- * DATA LOGGER CONSTRUCTOR
- *
- ****************************************************************/
- //! Default constructor
+const char* DataLogger::fConfigDay = "CONFIG_DAY";
+const char* DataLogger::fConfigRun = "CONFIG_RUN";
+const char* DataLogger::fConfigRunNumber = "CONFIG_RUN_NUMBER";
+const char* DataLogger::fConfigLog = "LOG";
+const char* DataLogger::fTransStart = "START";
+const char* DataLogger::fTransStop = "STOP";
+const char* DataLogger::fTransStartRun = "START_RUN";
+const char* DataLogger::fTransStopRun = "STOP_RUN";
+const char* DataLogger::fTransReset = "RESET";
+const char* DataLogger::fTransWait = "WAIT_RUN_NUMBER";
+const char* DataLogger::fRunNumberInfo = "RUN_NUMBER";
+
+// --------------------------------------------------------------------------
+//
+//! Default constructor. The name of the machine is given DATA_LOGGER
+//! and the state is set to kSM_Ready at the end of the function.
+//
+//!Setup the allows states, configs and transitions for the data logger
+//
 DataLogger::DataLogger() : StateMachineDim(std::cout, "DATA_LOGGER")
 {
 		//initialize member data
-		fDailyFileName = "";
-		fRunFileName = "";
-		runNumber = -1;
+		fDailyFileName = "/home/lyard/log";
+		fRunFileName = "/home/lyard/log";
+		fRunNumber = 12345;
 		//Give a name to this machine's specific states
 		AddStateName(kSM_DailyOpen, "Daily_File_Openened");
@@ -159,26 +274,21 @@
 
 		/*Add the possible transitions for this machine*/
-		AddTransition(kSM_DailyOpen, transStart, kSM_Ready, kSM_BadDailyConfig) //start the daily logging. daily file location must be specified already
+		AddTransition(kSM_DailyOpen, fTransStart, kSM_Ready, kSM_BadDailyConfig) //start the daily logging. daily file location must be specified already
 			->AssignFunction(boost::bind(&DataLogger::StartPlease, this)); 
-		AddTransition(kSM_Ready, transStop, kSM_DailyOpen, kSM_WaitingRun, kSM_Logging) //stop the data logging
-			->AssignFunction(boost::bind(&DataLogger::StopPlease, this));
-		AddTransition(kSM_Logging, transStartRun, kSM_WaitingRun, kSM_BadRunConfig) //start the run logging. run file location must be specified already.
+		AddTransition(kSM_Ready, fTransStop, kSM_DailyOpen, kSM_WaitingRun, kSM_Logging) //stop the data logging
+			->AssignFunction(boost::bind(&DataLogger::GoToReadyPlease, this));
+		AddTransition(kSM_Logging, fTransStartRun, kSM_WaitingRun, kSM_BadRunConfig) //start the run logging. run file location must be specified already.
 			->AssignFunction(boost::bind(&DataLogger::StartRunPlease, this));
-		AddTransition(kSM_WaitingRun, transStopRun, kSM_Logging)
+		AddTransition(kSM_WaitingRun, fTransStopRun, kSM_Logging)
 			->AssignFunction(boost::bind(&DataLogger::StopRunPlease, this));
-		AddTransition(kSM_Ready, transReset, kSM_Error, kSM_BadDailyConfig, kSM_BadRunConfig, kSM_Error) //transition to exit error states. dunno if required or not, would close the daily file if already openned.
-			->AssignFunction(boost::bind(&DataLogger::ResetPlease, this));
-		AddTransition(kSM_WaitingRun, transWait, kSM_DailyOpen)
+		AddTransition(kSM_Ready, fTransReset, kSM_Error, kSM_BadDailyConfig, kSM_BadRunConfig, kSM_Error) //transition to exit error states. dunno if required or not, would close the daily file if already openned.
+			->AssignFunction(boost::bind(&DataLogger::GoToReadyPlease, this));
+		AddTransition(kSM_WaitingRun, fTransWait, kSM_DailyOpen)
 			->AssignFunction(boost::bind(&DataLogger::DailyToWaitRunPlease, this));
 		/*Add the possible configurations for this machine*/
-		AddConfiguration(configDay, kSM_Ready, kSM_BadDailyConfig) //configure the daily file location. cannot be done before the file is actually opened
+		AddConfiguration(fConfigDay, "C", kSM_Ready, kSM_BadDailyConfig) //configure the daily file location. cannot be done before the file is actually opened
 			->AssignFunction(boost::bind(&DataLogger::ConfigureDailyFileName, this, _1));
-		AddConfiguration(configRun, kSM_Ready, kSM_BadDailyConfig, kSM_DailyOpen, kSM_WaitingRun, kSM_BadRunConfig) //configure the run file location. cannot be done before the file is actually opened, and not in a dailly related error.
+		AddConfiguration(fConfigRun, "C", kSM_Ready, kSM_BadDailyConfig, kSM_DailyOpen, kSM_WaitingRun, kSM_BadRunConfig) //configure the run file location. cannot be done before the file is actually opened, and not in a dailly related error.
 			->AssignFunction(boost::bind(&DataLogger::ConfigureRunFileName, this, _1));
-		/*wait for Dim to finish initializing*/
-		/*just a sleep for now. */
-		/*TODO: add a better way to wait: poll DIM for something I guess. Maybe get the configuration from conf server ? */
-
-		usleep(1000000); //10ms
 		
 		//Provide a logging command
@@ -187,48 +297,116 @@
 		//is already done in StateMachineImp.cc
 		//Thus I'll simply add a configuration, which I will treat as the logging command
-		AddConfiguration(configRun, kSM_DailyOpen, kSM_Logging, kSM_WaitingRun, kSM_BadRunConfig)
+		AddConfiguration(fConfigLog, "C", kSM_DailyOpen, kSM_Logging, kSM_WaitingRun, kSM_BadRunConfig)
 			->AssignFunction(boost::bind(&DataLogger::LogMessagePlease, this, _1));
-			
-		InitServiceSubscription();
+		
+		fServiceList.SetHandler(this);
+		CheckForServicesUpdate();
 
 		//All configuration done, callback funtions set, go to ready state and thus prevent the run loop from being executed
 		SetReady();
 }
-//! Initialization of the subscription to the services. 
-void DataLogger::InitServiceSubscription()
-{
-	//assign myself as the info handler
-	fServiceList.SetHandler(this);
-
-	//crawl through the list of services and subscribe to all of them
-	//TODO I still haven't figured out how the update of services shouldbe performed
-	//TODO: I don't think that the reference would work in this case because what is returned is a temporary. but should try anyway in case this works...
+// --------------------------------------------------------------------------
+//
+//! Checks for changes in the existing services.
+//! Any new service will be added to the service list, while the ones which disappeared are removed.
+//! @todo
+//! 	add the configuration (using the conf class ?)
+//
+void DataLogger::CheckForServicesUpdate()
+{ 
+
+	//get the current server list
 	const std::vector<std::string> serverList = fServiceList.GetServerList();
-	for (unsigned int i=0;i<serverList.size();i++)
-	{//get the service list associated with each server
-		if (strstr(serverList[i].c_str(), "DIS_DNS") || strstr(serverList[i].c_str(), "DATA_LOGGER"))
+	//first let's remove the servers that may have disapeared
+	//can't treat the erase on maps the same way as for vectors. Do it the safe way instead
+	std::vector<std::string> toBeDeleted;
+	for (SubscriptionsListType::iterator cListe = fServiceSubscriptions.begin(); cListe != fServiceSubscriptions.end(); cListe++)
+	{
+		std::vector<std::string>::const_iterator givenServers;
+		for (givenServers=serverList.begin(); givenServers!= serverList.end(); givenServers++)
+			if (cListe->first == *givenServers)
+				break;
+		if (givenServers == serverList.end())//server vanished. Remove it
+			toBeDeleted.push_back(cListe->first);
+	}
+	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++)
+	{
+		//skip the two obvious excluded services
+		if ((i->find("DIS_DNS") != std::string::npos) ||
+		    (i->find("DATA_LOGGER") != std::string::npos))
 			continue;
-		for (std::vector<std::string>::const_iterator j=fServiceList.begin(serverList[i]); j != fServiceList.end(serverList[i]); j++)
-		{//and subscribe to each service !
-			fServiceSubscriptions[serverList[i]].push_back(DimStampedInfo(j->c_str(), const_cast<char*>(""), this));
-		}
-	}
-}
-//! destructor
+		//find the current server in our subscription list	
+		SubscriptionsListType::iterator cSubs = fServiceSubscriptions.find(*i);
+		//get the service list of the current server
+		std::vector<std::string> cServicesList = fServiceList.GetServiceList(*i);
+		if (cSubs != fServiceSubscriptions.end())//if the current server already is in our subscriptions
+		{										 //then check and update our list of subscriptions
+			//first, remove the services that may have dissapeared.
+			std::map<std::string, SubscriptionType>::iterator serverSubs;
+			std::vector<std::string>::const_iterator givenSubs;
+			toBeDeleted.clear();
+			for (serverSubs=cSubs->second.begin(); serverSubs != cSubs->second.end(); serverSubs++)
+			{
+				for (givenSubs = cServicesList.begin(); givenSubs != cServicesList.end(); givenSubs++)
+					if (serverSubs->first == *givenSubs)
+						break;
+				if (givenSubs == cServicesList.end())
+				{
+					toBeDeleted.push_back(serverSubs->first);
+				}	
+			}
+			for (std::vector<std::string>::const_iterator it = toBeDeleted.begin(); it != toBeDeleted.end(); it++)
+				cSubs->second.erase(*it);
+			//now check for new services
+			for (givenSubs = cServicesList.begin(); givenSubs != cServicesList.end(); givenSubs++)
+			{
+				if (*givenSubs == "SERVICE_LIST")
+					continue;
+				if (cSubs->second.find(*givenSubs) == cSubs->second.end())
+				{//service not found. Add it
+					cSubs->second[*givenSubs].dimInfo = new DimStampedInfo(((*i) + "/" + *givenSubs).c_str(), const_cast<char*>(""), this);
+				}	
+			}
+		}
+		else //server not found in our list. Create its entry
+		{
+			fServiceSubscriptions[*i] = std::map<std::string, SubscriptionType>();
+			std::map<std::string, SubscriptionType>& liste = fServiceSubscriptions[*i];
+			for (std::vector<std::string>::const_iterator j = cServicesList.begin(); j!= cServicesList.end(); j++)
+			{
+				if (*j == "SERVICE_LIST")
+					continue;
+				liste[*j].dimInfo = new DimStampedInfo(((*i) + "/" + (*j)).c_str(), const_cast<char*>(""), this);
+			}
+		}	
+	}
+}
+// --------------------------------------------------------------------------
+//
+//! Destructor
+//
 DataLogger::~DataLogger()
 {
-	if (fDailyFile.is_open())
-		fDailyFile.close();
-	if (fRunFile.is_open())
-		fRunFile.close();
-;
-}
-/****************************************************************
- * 
- * DATA LOGGER'S EXECUTE
- * 
- ****************************************************************/
- //! Execute
- //! Shouldn't be run as we use callbacks instead
+	//close the files
+	if (fDailyLogFile.is_open())
+		fDailyLogFile.close();
+	if (fDailyReportFile.is_open())
+		fDailyReportFile.close();
+	if (fRunLogFile.is_open())
+		fRunLogFile.close();
+	if (fRunReportFile.is_open())
+		fRunReportFile.close();
+	//release the services subscriptions
+	fServiceSubscriptions.clear();
+}
+// --------------------------------------------------------------------------
+//
+//! Execute
+//! Shouldn't be run as we use callbacks instead
+//
 int DataLogger::Execute()
 {
@@ -246,16 +424,12 @@
 	case kSM_BadRunConfig:
 		return GetCurrentState();
-	
 	}
 	//this line below should never be hit. It here mainly to remove warnings at compilation
 	return kSM_FatalError;
 }
-/****************************************************************
- * 
- * DATA LOGGER'S TRANSITION
- * 
- ****************************************************************/
-
- //! Shouldn't be run as we use callbacks instead
+// --------------------------------------------------------------------------
+//
+//! Shouldn't be run as we use callbacks instead
+//
  int DataLogger::Transition(const Event& evt)
 {
@@ -273,10 +447,10 @@
 				case kSM_BadRunConfig:
 				case kSM_Error:
-					return ResetPlease();
+					return GoToReadyPlease();
 					
 				case kSM_Logging:
 				case kSM_WaitingRun:
 				case kSM_DailyOpen:
-					return StopPlease();
+					return GoToReadyPlease();
 			}
 		break;
@@ -319,10 +493,8 @@
 	return kSM_FatalError;
 }
-/****************************************************************
- * 
- * DATA LOGGER'S CONFIGURE
- * 
- ****************************************************************/
+// --------------------------------------------------------------------------
+//
 //! Shouldn't be run as we use callbacks instead
+//
  int DataLogger::Configure(const Event& evt)
 {
@@ -344,5 +516,6 @@
 		case kSM_Logging:
 		case kSM_DailyOpen:
-				return LogMessagePlease(evt);	
+//TODO check that this is indeed correct
+				return 0;//LogMessagePlease(evt);	
 		break;
 
@@ -353,79 +526,115 @@
 	return kSM_FatalError;
 }
-/****************************************************************
- * 
- * DATA LOGGER'S INFOHANDLER
- * 
- ****************************************************************/
+// --------------------------------------------------------------------------
+//
+//! Inherited from DimInfo. Handles all the Infos to which we subscribed, and log them
+//
 void DataLogger::infoHandler()
 {
 	DimInfo* I = getInfo();
-	//there I should get the services updates. It remains unclear whether I will be getting the new services or not through here
-//	CheckForServicesUpdate(); //in this function I will add/remove services subscription
+	if (I==NULL)
+	{
+		CheckForServicesUpdate();
+		return;
+	}
+	//check if the service pointer corresponds to something that we subscribed to
+	//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++)
+	{//instead of extracting the server and service names, I crawl through my records. dunno what's faster, but both should work
+		for (y=x->second.begin(); y!=x->second.end();y++)
+			if (y->second.dimInfo == I)
+			{
+				found = true;	
+				break;
+			}
+		if (found)
+			break;
+	}
+	if (!found)
+		return;
+	if (I->getSize() <= 0)
+		return;
+	//check that the message has been updated by something, i.e. must be different from its initial value
+	if (I->getTimestamp() == 0)
+		return;
+
 	CheckForRunNumber(I);
-	LogPlease(I);
-}
-//! Checks for changes in the existingn services
-//! @todo finish this function as most of it is still missing (plus what is already there isn't great)
-void DataLogger::CheckForServicesUpdate()
-{//TODO well... do it... 
- //TODO handle the cases were one server/service was removed and one was added
-	 const std::vector<std::string> serverList = fServiceList.GetServerList();
-	 if (serverList.size() != fServiceSubscriptions.size())
-	 {//some servers were added/deleted. Rebuild the list entirely
-std::cout << "Redoing the server list entirely " << serverList.size() << " " << fServiceSubscriptions.size() << std::endl;
-	 		std::map<std::string, std::vector<DimStampedInfo> >::iterator it;
-	 		for (it=fServiceSubscriptions.begin(); it != fServiceSubscriptions.end(); it++)
-	 			(*it).second.clear();	
-	 		fServiceSubscriptions.clear();
-	 		InitServiceSubscription();
-	 		return;
-	 }
-	 //TODO crawl the list to see if any of the servers has updated its service list
-	
-}
-//! Looks whether the currently being processed DimInfo indeed is a run number or not
+	ReportPlease(I, y->second);
+}
+
+// --------------------------------------------------------------------------
+//
+//! Checks whether or not the current info is a run number.
+//! If so, then remember it. A run number is required to open the run-log file
+//! @param I
+//!		the current DimInfo
+//
 void DataLogger::CheckForRunNumber(DimInfo* I)
 {
 	return;
-	if (strstr(I->getName(), runNumberInfo) != NULL)
+	if (strstr(I->getName(), fRunNumberInfo) != NULL)
 	{//assumes that the run number is an integer
 		//TODO check the format here
-		runNumber = I->getInt();	
-	}
-}
-/****************************************************************
- * 
- * DATA LOGGER'S RUN LOG
- * 
- * write info to run log. Go to error if anything goes wrong
- * 
- ****************************************************************/
- //! write info to logs. Go to error if anything goes wrong
-void DataLogger::LogPlease(DimInfo* I)
-{
-	if (I->getSize() == 0)
+		fRunNumber = I->getInt();	
+	}
+}
+// --------------------------------------------------------------------------
+//
+//! write infos to log files.
+//! @param I
+//! 	The current DimInfo 
+//
+void DataLogger::ReportPlease(DimInfo* I, SubscriptionType& sub)
+{
+	//should we log or report this info ? (i.e. is it a message ?)
+	bool isItaReport = ((strstr(I->getName(), "Message") == NULL) && (strstr(I->getName(), "MESSAGE") == NULL));
+	
+//	std::ofstream & dailyFile = fDailyReportFile;//isItaReport? fDailyReportFile : fDailyLogFile;
+//	std::ofstream & runFile = fRunReportFile;//isItaReport? fRunReportFile : fRunLogFile;
+
+	//TODO add service exclusion
+	if (!fDailyReportFile.is_open())
 		return;
-	//TODO add service exclusion
-	
-	if (!fDailyFile.is_open())
-		return;
+		
 	//construct the header
 	std::stringstream header;
-	Time cTime((time_t)(I->getTimestamp()), 0);
-	header << I->getName() << " " << cTime.Y() << " " << cTime.M() << " " << cTime.D() << " ";
-	header << cTime.h() << " " << cTime.m() << " " << cTime.s() << " ";
-	header << cTime.ms() << " " << I->getQuality() << " ";
-	
-	if (fDailyFile.is_open())
-		fDailyFile << header;
-	if (fRunFile.is_open())
-		fRunFile << header;
-	
-	
-	std::string text = ToString(I->getFormat(), I->getData(), I->getSize());
-	
-	if (!text.empty())
-	{//replace bizarre characters by white space
+	
+	Time cTime((time_t)(I->getTimestamp()), I->getTimestampMillisecs());
+
+	//Buffer them for FITS write
+	//TODO this has been replaced by MjD. So I guess that these member variables can go.
+	fYear = cTime.Y(); fMonth = cTime.M(); fDay = cTime.D();
+	fHour = cTime.h(); fMin = cTime.m(); fSec = cTime.s();
+	fMs = cTime.ms(); fQuality = I->getQuality();
+	
+	fMjD = cTime.Mjd();
+	
+	if (isItaReport)
+	{
+		//write text header
+		header << I->getName() << " " << fQuality << " ";
+		header << fYear << " " << fMonth << " " << fDay << " ";
+		header << fHour << " " << fMin << " " << fSec << " ";
+		header << fMs << " " << I->getTimestamp() << " ";
+
+		Converter conv(std::cout, I->getFormat(), I->getData(), I->getSize());
+
+		if (conv.Ptr() == NULL)
+			return;
+		
+		std::string text(conv.Ptr());
+	
+		if (text.empty())
+			return;
+	
+		if (fDailyReportFile.is_open())
+			fDailyReportFile << header.str();
+		if (fRunReportFile.is_open())
+			fRunReportFile << header.str();
+	
+		//replace bizarre characters by white space
 		for (unsigned int i=0; i<text.size(); i++)
 		{
@@ -436,71 +645,41 @@
 					text[i] = ' ';	
 		}
-		if (fDailyFile.is_open())
-			fDailyFile << text;
-		if (fRunFile.is_open())
-			fRunFile << text;
+		if (fDailyReportFile.is_open())
+			fDailyReportFile << text << std::endl;
+		if (fRunReportFile.is_open())
+			fRunReportFile << text << std::endl;
 	}
 	else
 	{
-		if (fDailyFile.is_open())
-			fDailyFile << "Cannot interpret service format" << std::endl;
-		if (fRunFile.is_open())
-			fRunFile << "Cannot interpret service format" << std::endl;
-	}
-}
-//! Translates DIM data safely to string (assures no invalid memory accesses are made)
-//! Was mostly copied from DColl.cc
-std::string DataLogger::ToString(const char *format, const void *data, int size) {
-
-  std::ostringstream Text;
-  
-  // Structure: print hex representation 
-  if (strlen(format) != 1) {
-	for (int i=0; i<size; i++) {
-	  Text << std::setw(2) << std::hex << *((char *) data + i) << " ";
-	} 
-	return Text.str();
-  }
-
-  // String if format "C" and terminated with \0
-  if (strcmp(format, "C") == 0 && size > 0 && *((char *) data+size-1)=='\0') {
-	return std::string((char *) data);
-  }
-
-  // Number array
-  int ElementSize;
-  switch (*format) {
-    case 'C': ElementSize = sizeof(char);		break;
-    case 'I':
-    case 'L': ElementSize = sizeof(int);		break;
-    case 'S': ElementSize = sizeof(short);		break;
-    case 'F': ElementSize = sizeof(float);		break;
-    case 'D': ElementSize = sizeof(double);		break;
-    case 'X': ElementSize = sizeof(long long);	break;
-    default: return std::string();
-  }
-
-  for (int i=0; i<size/ElementSize; i++) {
-	// Space between entries
-    if (i != 0) Text << " ";
-
-	// Translate data
-	switch (*format) {
-      case 'C': Text << *((char *) data + i);		break;
-      case 'I':
-      case 'L': Text << *((int *) data + i);		break;
-      case 'S': Text << *((short *) data + i);		break;
-      case 'F': Text << *((float *) data + i);		break;
-      case 'D': Text << *((double *) data + i);		break;
-      case 'X': Text << *((long long *) data + i);	break;
-	}
-  }
-  
-  return Text.str();
-}
-//! write messages to logs. Go to error if anything goes wrong
+		std::string n = I->getName();
+		std::stringstream msg;
+		msg << n.substr(0, n.find_first_of('/')) << ": " << I->getString();
+		MessageImp dailyMess(fDailyLogFile);
+		dailyMess.Write(cTime, msg.str().c_str(), fQuality);
+		if (fRunLogFile.is_open())
+		{
+			MessageImp runMess(fRunLogFile);
+			runMess.Write(cTime, msg.str().c_str(), fQuality);
+		}
+	}
+
+	if (!sub.dailyFile.IsOpen() || !sub.runFile.IsOpen())
+		OpenFITSFilesPlease(sub);	
+	WriteToFITS(sub);
+	
+
+}
+// --------------------------------------------------------------------------
+//
+//! write messages to logs. 
+//! @param evt
+//!		the current event to log
+//! @returns 
+//!		the new state. Currently, always the current state
+//
+//DEPREC I guess that this function should not be any longer
 int DataLogger::LogMessagePlease(const Event& evt)
 {
-	if (!fDailyFile.is_open())
+	if (!fDailyLogFile.is_open())
 		return GetCurrentState();
 	
@@ -510,14 +689,20 @@
 	header << cTime.h() << " " << cTime.m() << " " << cTime.s() << " ";
 	header << cTime.ms() << " ";
-	
-	if (fDailyFile.is_open())
-		fDailyFile << header;
-	if (fRunFile.is_open())
-		fRunFile << header;
-	
-	std::string text = ToString(evt.GetFormat().c_str(), evt.GetData(), evt.GetSize());
+		
+//	std::string text = ToString(evt.GetFormat().c_str(), evt.GetData(), evt.GetSize());
+	Converter conv(std::cout, evt.GetFormat().c_str(), evt.GetData(), evt.GetSize());
+	if (conv.Ptr() == NULL)
+		return GetCurrentState();
+		
+	std::string text(conv.Ptr());
 	
 	if (!text.empty())
-	{//replace bizarre characters by white space
+	{
+		if (fDailyLogFile.is_open())
+			fDailyLogFile << header;
+		if (fRunLogFile.is_open())
+			fRunLogFile << header;
+		
+		//replace bizarre characters by white space
 		for (unsigned int i=0; i<text.size(); i++)
 		{
@@ -528,66 +713,65 @@
 					text[i] = ' ';	
 		}
-		if (fDailyFile.is_open())
-			fDailyFile << text;
-		if (fRunFile.is_open())
-			fRunFile << text;
-	}
+		if (fDailyLogFile.is_open())
+			fDailyLogFile << text;
+		if (fRunLogFile.is_open())
+			fRunLogFile << text;
+	}
+	
+	return GetCurrentState();	
+}
+// --------------------------------------------------------------------------
+//
+//!	Sets the path to use for the daily log file.
+//! @param evt
+//! 	the event transporting the path
+//! @returns
+//!		currently only the current state.
+//
+int DataLogger::ConfigureDailyFileName(const Event& evt)
+{
+	if (evt.GetText() != NULL)
+		fDailyFileName = std::string(evt.GetText());	
 	else
-	{
-		if (fDailyFile.is_open())
-			fDailyFile << "Cannot interpret log message format" << std::endl;
-		if (fRunFile.is_open())
-			fRunFile << "Cannot interpret log message format" << std::endl;
-	}	
-	
-	return GetCurrentState();	
-}
-/****************************************************************
- * 
- * DATA LOGGER'S RUN LOG
- */
- //!Set the current daily file name. This will NOT close any file
- /* 
- ****************************************************************/
-int DataLogger::ConfigureDailyFileName(const Event& evt)
-{
-	fDailyFileName = std::string(evt.GetText());	
+		Error("Empty daily folder");
+
 	return GetCurrentState();
 }
-/****************************************************************
- * 
- * DATA LOGGER'S CONFIGURE RUN FILE NAME
- * 
- */
- //! Set the current run folder name. This will NOT close any file
- /* 
- ****************************************************************/
+// --------------------------------------------------------------------------
+//
+//! Sets the path to use for the run log file.
+//! @param evt
+//!		the event transporting the path
+//! @returns
+//! 	currently only the current state
 int DataLogger::ConfigureRunFileName(const Event& evt)
 {
-	fRunFileName = std::string(evt.GetText());
+	if (evt.GetText() != NULL)
+		fRunFileName = std::string(evt.GetText());
+	else
+		Error("Empty daily folder");
+
 	return GetCurrentState();
 }
-/****************************************************************
- * 
- * DATA LOGGER'S CONFIGURE RUN NUMBER
- * 
- */
- //! set the current run number. This will NOT close any file. 
- /* 
- ****************************************************************/
+// --------------------------------------------------------------------------
+//
+//! Sets the run number.
+//! @param evt
+//!		the event transporting the run number
+//! @returns
+//! 	currently only the current state
 int DataLogger::ConfigureRunNumber(const Event& evt)
 {
-	runNumber = evt.GetInt();
-	//TODO replace the run number in the filename if already exist. Otherwise just append it
+	fRunNumber = evt.GetInt();
+
 	return GetCurrentState();
 }
-/****************************************************************
- * 
- * DATA LOGGER'S START PLEASE
- * 
- */
- //! Implements the start transition
- /* 
- ****************************************************************/
+// --------------------------------------------------------------------------
+//
+//! Implements the Start transition.
+//! Concatenates the given path for the daily file and the filename itself (based on the day), 
+//! and tries to open it.
+//! @returns 
+//!		kSM_DailyOpen if success, kSM_BadDailyConfig if failure
 int DataLogger::StartPlease()
 {
@@ -598,6 +782,8 @@
 	std::string fullName = fDailyFileName + '/' + sTime.str() + ".log"; 
 	
-	fDailyFile.open(fullName.c_str(), std::ios_base::out | std::ios_base::ate); //maybe should be "app" instead of "ate" ??
-	if (!fDailyFile.is_open())
+	fDailyLogFile.open(fullName.c_str(), std::ios_base::out | std::ios_base::app); //maybe should be "app" instead of "ate" ??
+	fullName = fDailyFileName + '/' + sTime.str() + ".rep";
+	fDailyReportFile.open(fullName.c_str(), std::ios_base::out | std::ios_base::app);
+	if (!fDailyLogFile.is_open() || !fDailyReportFile.is_open())
 	{
 		//TODO send an error message	
@@ -606,42 +792,176 @@
 	return kSM_DailyOpen; 	
 }
-/****************************************************************
- * 
- * DATA LOGGER'S STOP PLEASE
- * 
- */
- //! Implements the stop transition
- /* 
- ****************************************************************/
-int DataLogger::StopPlease()
-{
-	if (fDailyFile.is_open())
-		fDailyFile.close();
-		
-	if (fRunFile.is_open())
-	    fRunFile.close();	
-	    
-	return kSM_Ready;
-
-}
-/****************************************************************
- * 
- * DATA LOGGER'S START RUN PLEASE
- * 
- */
- //! Implements the start run transtition
- /* 
- ****************************************************************/
+// --------------------------------------------------------------------------
+//
+//! open if required a the FITS files corresponding to a given subscription
+//! @param sub
+//! 	the current DimInfo subscription being examined
+void DataLogger::OpenFITSFilesPlease(SubscriptionType& sub)
+{
+	std::string serviceName(sub.dimInfo->getName());
+	for (unsigned int i=0;i<serviceName.size(); i++)
+	{
+		if (serviceName[i] == '/')
+		{
+			serviceName[i] = '_';
+			break;	
+		}	
+	}
+	Time time;
+	std::stringstream sTime;
+	sTime << time.Y() << "_" << time.M() << "_" << time.D();
+	//we open the dailyFile anyway, otherwise this function shouldn't have been called.
+	if (!sub.dailyFile.IsOpen())
+	{
+		std::string partialName = fDailyFileName + '/' + sTime.str() + '_' + serviceName + ".fits";
+		std::string fullName = fDailyFileName + '/' + sTime.str() + '_' + serviceName + ".fits[" + serviceName + "]";
+
+		AllocateFITSBuffers(sub);
+		//currently, the FITS are written in the same directory as the text files. 
+		//thus the write permissions have already been checked by the text files. 
+		//if the target folder changes, then I should check the write permissions here
+		//now we only check whether the target file exists or not
+		std::ifstream readTest(partialName.c_str());
+		if (readTest.is_open())
+		{
+			readTest.close();
+			sub.dailyFile.Open(fullName.c_str(), "UPDATE");
+		}
+		else {
+			sub.dailyFile.Open(fullName.c_str(), "CREATE");	 
+		}
+		
+//TODO Write the header's attributes
+	}
+	if (!sub.runFile.IsOpen() && (GetCurrentState() == kSM_Logging))
+	{//buffer for the run file have already been allocated when doing the daily file
+		std::stringstream sRun;
+		sRun << fRunNumber;
+		std::string partialName = fRunFileName + '/' + sRun.str() + '_' + serviceName + ".fits";
+		std::string fullName = fRunFileName + '/' +  sRun.str() + '_' + serviceName + ".fits[" + serviceName + "]";
+		
+		std::ifstream readTest(partialName.c_str());
+		if (readTest.is_open())
+		{
+			readTest.close();
+			sub.runFile.Open(fullName.c_str(), "UPDATE");
+		}
+		else
+			sub.runFile.Open(fullName.c_str(), "CREATE");
+//TODO Write the header's attributes
+	}
+}	
+// --------------------------------------------------------------------------
+//
+void DataLogger::AllocateFITSBuffers(SubscriptionType& sub)
+{
+	 const char* format = sub.dimInfo->getFormat();
+	 const int size = sub.dimInfo->getSize();
+	 
+	 //Init the time columns of the file
+	 sub.dailyFile.InitCol("Date", "double", &fMjD);
+	 sub.runFile.InitCol("Date", "double", &fMjD);
+	 
+//	 sub.dailyFile.InitCol("Year", "short", &fYear);
+//	 sub.dailyFile.InitCol("Month", "short", &fMonth);
+//	 sub.dailyFile.InitCol("Day", "short", &fDay);
+//	 sub.dailyFile.InitCol("Hour", "short", &fHour);
+//	 sub.dailyFile.InitCol("Minute", "short", &fMin);
+//	 sub.dailyFile.InitCol("Second", "short", &fSec);
+//	 sub.dailyFile.InitCol("MilliSec", "int", &fMs);
+	 sub.dailyFile.InitCol("QoS", "int", &fQuality);
+
+//	 sub.runFile.InitCol("Year", "short", &fYear);
+//	 sub.runFile.InitCol("Month", "short", &fMonth);
+//	 sub.runFile.InitCol("Day", "short", &fDay);
+//	 sub.runFile.InitCol("Hour", "short", &fHour);
+//	 sub.runFile.InitCol("Minute", "short", &fMin);
+//	 sub.runFile.InitCol("Second", "short", &fSec);
+//	 sub.runFile.InitCol("MilliSec", "int", &fMs);
+	 sub.runFile.InitCol("QoS", "int", &fQuality);
+	 
+	 Converter::FormatList flist = Converter::Convert(std::cout, std::string(format));
+	 
+	 //we've got a nice structure describing the format of this service's messages.
+	 //Let's create the appropriate FITS columns
+	 for (unsigned int i=0;i<flist.size();i++)
+	 {
+	 	std::stringstream colName;
+	 	std::stringstream dataQualifier; 
+	 	void * dataPointer = static_cast<char*>(sub.dimInfo->getData()) + flist[i].second.second;
+	 	colName << "Data" << i;
+	 	dataQualifier << flist[i].second.first;
+	 	switch (flist[i].first.first)
+	 	{
+	 		case 'c':
+	 			dataQualifier <<  "S";
+	 		break;
+	 		case 's':
+	 			dataQualifier << "I";
+	 		break;
+	 		case 'i':
+	 			dataQualifier << "J";
+	 		break;
+	 		case 'l':
+	 			dataQualifier << "J";
+	 			//TODO triple check that in FITS, long = int
+	 		break;
+	 		case 'f':
+	 			dataQualifier << "E";
+	 		break;
+	 		case 'd':
+	 			dataQualifier << "D";
+	 		break;
+	 		case 'x':
+	 			dataQualifier << "K";
+	 		break;
+	 		case 'S':
+	 			//for strings, the number of elements I get is wrong. Correct it
+	 			dataQualifier.str(""); //clear
+	 			dataQualifier << size-1 <<  "A";
+	 		break;
+	 		
+	 		default:
+	 			Error("THIS SHOULD NEVER BE REACHED. dataLogger.cc ln 962.");
+	 	};
+	 	sub.dailyFile.InitCol(colName.str().c_str(), dataQualifier.str().c_str(), dataPointer);
+	 	sub.runFile.InitCol(colName.str().c_str(), dataQualifier.str().c_str(), dataPointer);
+	 }
+
+//TODO init the attributes
+}
+// --------------------------------------------------------------------------
+//
+//! write a dimInfo data to its corresponding FITS files
+//
+void DataLogger::WriteToFITS(SubscriptionType& sub)
+{
+		//dailyFile status (open or not) already checked
+		if (sub.dailyFile.IsOpen())
+			sub.dailyFile.Write();
+		if (sub.runFile.IsOpen())
+			sub.runFile.Write();
+}
+// --------------------------------------------------------------------------
+//
+//! Implements the StartRun transition.
+//! Concatenates the given path for the run file and the filename itself (based on the run number),
+//! and tries to open it.
+//! @returns
+//!		kSM_Logging if success, kSM_BadRunConfig if failure.
 int DataLogger::StartRunPlease()
 {
 	//attempt to open run file with current parameters
-	if (runNumber == -1)
+	if (fRunNumber == -1)
 		return kSM_BadRunConfig;
 	std::stringstream sRun;
-	sRun << runNumber;
+	sRun << fRunNumber;
 	std::string fullName = fRunFileName + '/' + sRun.str() + ".log";
-
-	fRunFile.open(fullName.c_str(), std::ios_base::out | std::ios_base::ate); //maybe should be app instead of ate
-	if (!fRunFile.is_open())
+	fRunLogFile.open(fullName.c_str(), std::ios_base::out | std::ios_base::app); //maybe should be app instead of ate
+
+	fullName = fRunFileName + '/' + sRun.str() + ".rep";
+	fRunReportFile.open(fullName.c_str(), std::ios_base::out | std::ios_base::app);
+	
+	if (!fRunLogFile.is_open() || !fRunReportFile.is_open())
 	{
 		//TODO send an error message
@@ -651,70 +971,77 @@
 	return kSM_Logging;
 }
-/****************************************************************
- * 
- * DATA LOGGER'S STOP RUN PLEASE
- * 
- */
- //! Implements the stop run transition
- /* 
- ****************************************************************/
+// --------------------------------------------------------------------------
+//
+//! Implements the StopRun transition.
+//! Attempts to close the run file.
+//! @returns
+//!		kSM_WaitingRun if success, kSM_FatalError otherwise
 int DataLogger::StopRunPlease()
 {
-	if (!fRunFile.is_open())
+	if (!fRunLogFile.is_open() || !fRunReportFile.is_open())
 		return kSM_FatalError;
 	
-	fRunFile.close();
-	
+	fRunLogFile.close();
+	fRunReportFile.close();
+	for (SubscriptionsListType::iterator i = fServiceSubscriptions.begin(); i != fServiceSubscriptions.end(); i++)
+		for (std::map<std::string, SubscriptionType>::iterator j = i->second.begin(); j != i->second.end(); j++)
+		{
+				if (j->second.runFile.IsOpen())
+					j->second.runFile.Close();	
+		}
 	return kSM_WaitingRun;
 
 }
-/****************************************************************
- * 
- * DATA LOGGER'S RESET PLEASE
- * 
- */
- //! Implements the reset transition
- /* 
- ****************************************************************/
-int DataLogger::ResetPlease()
-{
-	if (fDailyFile.is_open())
-		fDailyFile.close();
-
-	if (fRunFile.is_open())
-		fRunFile.close();
-			
+// --------------------------------------------------------------------------
+//
+//! Implements the Stop and Reset transitions.
+//! Attempts to close any openned file.
+//! @returns
+//! 	kSM_Ready
+int DataLogger::GoToReadyPlease()
+{
+	if (fDailyLogFile.is_open())
+		fDailyLogFile.close();
+	if (fDailyReportFile.is_open())
+		fDailyReportFile.close();
+
+	if (fRunLogFile.is_open())
+		fRunLogFile.close();
+	if (fRunReportFile.is_open())
+		fRunReportFile.close();
+		
+	for (SubscriptionsListType::iterator i = fServiceSubscriptions.begin(); i != fServiceSubscriptions.end(); i++)
+		for (std::map<std::string, SubscriptionType>::iterator j = i->second.begin(); j != i->second.end(); j++)
+		{
+				if (j->second.dailyFile.IsOpen())
+					j->second.dailyFile.Close();
+				if (j->second.runFile.IsOpen())
+					j->second.runFile.Close();	
+		}
 	return kSM_Ready;
 }
-//! Implements the Daily to WaitRun transition
+// --------------------------------------------------------------------------
+//
+//! Implements the transition towards kSM_WaitingRun
+//! Does nothing really.
+//!	@returns
+//!		kSM_WaitingRun
 int DataLogger::DailyToWaitRunPlease()
 {
 	return kSM_WaitingRun;	
 }
-/*
-bool DataLogger::ServiceOk(DimInfo* item)
-{
-	return !((item->getSize() == strlen(NO_LINK)+1) && (memcmp(item->getData(), NO_LINK, item->getSize()) == 0));	
-}*/
-/****************************************************************
- * 
- * MAIN
- * 
- ****************************************************************/
-extern bool CheckDim(bool=true);
- 
+
+// --------------------------------------------------------------------------
+// 
 int main()
 {
-	std::cout << "Data Logger Starting" << std::endl;
-	
-	if (!CheckDim())
-		return -1;
-	
-	std::cout << "Continuing" << std::endl;
+//No more Dim Checking ??
+//	if (!CheckDim())
+//		return -1;
+	
 	DataLogger log; 
-	std::cout << "DataLogger created. Starting main loop" << std::endl;
-	while (!log.IsRExitRequested())
-	{
-				usleep(1);
+	while (!log.fExitRequested)
+	{
+		usleep(10);
 	}
 	return 0;
