Index: /trunk/FACT++/src/EventBuilderWrapper.h
===================================================================
--- /trunk/FACT++/src/EventBuilderWrapper.h	(revision 10963)
+++ /trunk/FACT++/src/EventBuilderWrapper.h	(revision 10964)
@@ -31,98 +31,9 @@
     DataFileImp(uint32_t id) : fRunId(id) { }
 
-    virtual bool OpenFile(uint32_t runid, RUN_HEAD* h) = 0;
+    virtual bool OpenFile(RUN_HEAD* h) = 0;
     virtual bool Write(EVENT *) = 0;
     virtual bool Close(RUN_TAIL * = 0) = 0;
 
     uint32_t GetRunId() const { return fRunId; }
-};
-
-
-#include "FAD.h"
-
-class DataFileRaw : public DataFileImp
-{
-public:
-    DataFileRaw(uint32_t id) : DataFileImp(id)  { }
-    ~DataFileRaw() { Close(); }
-
-    virtual bool OpenFile(uint32_t, RUN_HEAD* ) { return true; }
-    virtual bool Write(EVENT *) { return true; }
-    virtual bool Close(RUN_TAIL * = 0) { return true; }
-};
-
-
-class DataFileFits : public DataFileImp
-{
-    CCfits::FITS*  fFile;        /// The pointer to the CCfits FITS file
-    CCfits::Table* fTable;       /// The pointer to the CCfits binary table
-
-    uint64_t fNumRows;                ///the number of rows that have been written already to the FITS file.
-    uint32_t fRoi;                ///the number of rows that have been written already to the FITS file.
-
-public:
-    DataFileFits(uint32_t runid) : DataFileImp(runid), fFile(0)
-    {
-    }
-
-    // --------------------------------------------------------------------------
-    //
-    //! Default destructor
-    //! The Fits file SHOULD have been closed already, otherwise the informations
-    //! related to the RUN_TAIL will NOT be written to the file.
-    //
-    ~DataFileFits() { Close(); }
-
-    // --------------------------------------------------------------------------
-    //
-    //! Add a new column to the vectors storing the column data.
-    //! @param names the vector of string storing the columns names
-    //! @param types the vector of string storing the FITS data format
-    //! @param numElems the number of elements in this column
-    //! @param type the char describing the FITS data format
-    //! @param name the name of the particular column to be added.
-    //
-    inline void AddColumnEntry(vector<string>& names, vector<string>& types, int numElems, char type, string name)
-    {
-        names.push_back(name);
-
-        ostringstream str;
-        if (numElems != 1)
-            str << numElems;
-        str << type;
-        types.push_back(str.str());
-    }
-
-    // --------------------------------------------------------------------------
-    //
-    //! Writes a single header key entry
-    //! @param name the name of the key
-    //! @param value its value
-    //! @param comment the comment associated to that key
-    //
-    //FIXME this function is a duplicate from the class Fits. should we try to merge it ?
-    template <typename T>
-    void WriteKey(const string &name, const T &value, const string &comment)
-    {
-        try
-        {
-            fTable->addKey(name, value, comment);
-        }
-        catch (CCfits::FitsException e)
-        {
-            ostringstream str;
-            str << "Could not add header key ";
-            //TODO pipe the error message somewhere
-        }
-    }
-
-    template <typename T>
-    void WriteKey(const string &name, const int idx, const T &value, const string &comment)
-    {
-        ostringstream str;
-        str << name << idx;
-
-        WriteKey(str.str(), value, comment);
-    }
 
     // --------------------------------------------------------------------------
@@ -133,16 +44,20 @@
     //! @param extension a string containing the extension to be appened to the file name
     //
-    string FormFileName(uint32_t runNumber, uint32_t runType, string extension)
+    string FormFileName(uint32_t runType, string extension)
     {
         //TODO where am I supposed to get the base directory from ?
         //TODO also, for creating subsequent directories, should I use the functions from the dataLogger ?
         string baseDirectory = "./Run";
+
         ostringstream result;
-        result << baseDirectory;
-        result << Time::fmt("/%Y/%m/%d/") << (Time() - boost::posix_time::time_duration(12,0,0));
-        result << setfill('0') << setw(8) << runNumber;
-        result << "_001_";
+//        result << baseDirectory;
+//        result << Time::fmt("/%Y/%m/%d/") << (Time() - boost::posix_time::time_duration(12,0,0));
+        result << setfill('0') << setw(8) << fRunId;
+        result << ".001_";
         switch (runType)
         {
+        case -1:
+            result << 'T';
+            break;
         case 0:
             result << 'D';
@@ -155,13 +70,263 @@
             break;
         case 3:
-            result << 'Y';
+            result << 'N';
             break;
         default:
-            //TODO pipe this error message to the appropriate error stream
-            cout << "Error unexpected event" << endl;
+            result << runType;
         };
-        result << "_data." << extension;
+        result << "." << extension;
 
         return result.str();
+    }
+
+};
+
+
+#include "FAD.h"
+
+class DataFileRaw : public DataFileImp
+{
+    ofstream fOut;
+
+    off_t fPosTail;
+
+    uint32_t fCounter;
+
+
+    // WRITE uint32_t 0xFAC77e1e  (FACT Tele)
+    // ===
+    // WRITE uint32_t TYPE(>0)          == 1
+    // WRITE uint32_t ID(>0)            == 0
+    // WRITE uint32_t VERSION(>0)       == 1
+    // WRITE uint32_t LENGTH
+    // -
+    // WRITE uint32_t TELESCOPE ID
+    // WRITE uint32_t RUNID
+    // ===
+    // WRITE uint32_t TYPE(>0)          == 2
+    // WRITE uint32_t ID(>0)            == 0
+    // WRITE uint32_t VERSION(>0)       == 1
+    // WRITE uint32_t LENGTH
+    // -
+    // WRITE          HEADER
+    // ===
+    // [ 40 TIMES
+    //    WRITE uint32_t TYPE(>0)       == 3
+    //    WRITE uint32_t ID(>0)         == 0..39
+    //    WRITE uint32_t VERSION(>0)    == 1
+    //    WRITE uint32_t LENGTH
+    //    -
+    //    WRITE          BOARD-HEADER
+    // ]
+    // ===
+    // WRITE uint32_t TYPE(>0)          == 4
+    // WRITE uint32_t ID(>0)            == 0
+    // WRITE uint32_t VERSION(>0)       == 1
+    // WRITE uint32_t LENGTH
+    // -
+    // WRITE          FOOTER (empty)
+    // ===
+    // [ N times
+    //    WRITE uint32_t TYPE(>0)       == 10
+    //    WRITE uint32_t ID(>0)         == counter
+    //    WRITE uint32_t VERSION(>0)    == 1
+    //    WRITE uint32_t LENGTH HEADER
+    //    -
+    //    WRITE          HEADER+DATA
+    // ]
+    // ===
+    // WRITE uint32_t TYPE   ==0
+    // WRITE uint32_t VERSION==0
+    // WRITE uint32_t LENGTH ==0
+    // ===
+    // Go back and write footer
+
+public:
+    DataFileRaw(uint32_t id) : DataFileImp(id)  { }
+    ~DataFileRaw() { Close(); }
+
+    void WriteBlockHeader(uint32_t type, uint32_t ver, uint32_t cnt, uint32_t len)
+    {
+        const uint32_t val[4] = { ver, type, cnt, len };
+
+        fOut.write(reinterpret_cast<const char*>(val), sizeof(val));
+    }
+
+    template<typename T>
+        void WriteValue(const T &t)
+    {
+        fOut.write(reinterpret_cast<const char*>(&t), sizeof(T));
+    }
+
+    enum
+    {
+        kIdentifier = 1,
+        kRunHeader,
+        kBoardHeader,
+        kRunSummary,
+        kEvent,
+    };
+
+    virtual bool OpenFile(RUN_HEAD *h)
+    {
+        const string name = FormFileName(h->RunType, "bin");
+
+        errno = 0;
+        fOut.open(name.c_str(), ios_base::out);
+        if (!fOut)
+        {
+            //ostringstream str;
+            //str << "Open file " << name << ": " << strerror(errno) << " (errno=" << errno << ")";
+            //Error(str);
+
+            return false;
+        }
+
+        fCounter = 0;
+
+        static uint32_t FACT = 0xFAC77e1e;
+
+        fOut.write(reinterpret_cast<char*>(&FACT), 4);
+
+        WriteBlockHeader(kIdentifier, 1, 0, 8);
+        WriteValue(uint32_t(0));
+        WriteValue(GetRunId());
+
+        WriteBlockHeader(kRunHeader, 1, 0, sizeof(RUN_HEAD)-sizeof(PEVNT_HEADER*));
+        fOut.write(reinterpret_cast<char*>(h), sizeof(RUN_HEAD)-sizeof(PEVNT_HEADER*));
+
+        for (int i=0; i<40; i++)
+        {
+            WriteBlockHeader(kBoardHeader, 1, i, sizeof(PEVNT_HEADER));
+            fOut.write(reinterpret_cast<char*>(h->FADhead+i), sizeof(PEVNT_HEADER));
+        }
+
+        const vector<char> block(sizeof(uint32_t)+sizeof(RUN_TAIL));
+        WriteBlockHeader(kRunSummary, 1, 0, block.size());
+
+        fPosTail = fOut.tellp();
+        fOut.write(block.data(), block.size());
+
+        if (!fOut)
+        {
+            //ostringstream str;
+            //str << "Open file " << name << ": " << strerror(errno) << " (errno=" << errno << ")";
+            //Error(str);
+
+            return false;
+        }
+
+        return true;
+    }
+    virtual bool Write(EVENT *evt)
+    {
+        const int sh = sizeof(PEVNT_HEADER)+(NPIX-1)*evt->Roi*2;
+
+        WriteBlockHeader(kEvent, 1, fCounter++, sh);
+        fOut.write(reinterpret_cast<char*>(evt)+2, sh-2);
+        return true;
+    }
+    virtual bool Close(RUN_TAIL *tail= 0)
+    {
+        fOut.seekp(fPosTail);
+
+        WriteValue(uint32_t(1));
+        fOut.write(reinterpret_cast<char*>(tail), sizeof(RUN_TAIL));
+
+        if (!fOut)
+        {
+            //ostringstream str;
+            //str << "Open file " << name << ": " << strerror(errno) << " (errno=" << errno << ")";
+            //Error(str);
+
+            return false;
+        }
+
+        fOut.close();
+
+        if (!fOut)
+        {
+            //ostringstream str;
+            //str << "Open file " << name << ": " << strerror(errno) << " (errno=" << errno << ")";
+            //Error(str);
+
+            return false;
+        }
+
+        return true;
+    }
+};
+
+
+class DataFileFits : public DataFileImp
+{
+    CCfits::FITS*  fFile;        /// The pointer to the CCfits FITS file
+    CCfits::Table* fTable;       /// The pointer to the CCfits binary table
+
+    uint64_t fNumRows;                ///the number of rows that have been written already to the FITS file.
+
+public:
+    DataFileFits(uint32_t runid) : DataFileImp(runid), fFile(0)
+    {
+    }
+
+    // --------------------------------------------------------------------------
+    //
+    //! Default destructor
+    //! The Fits file SHOULD have been closed already, otherwise the informations
+    //! related to the RUN_TAIL will NOT be written to the file.
+    //
+    ~DataFileFits() { Close(); }
+
+    // --------------------------------------------------------------------------
+    //
+    //! Add a new column to the vectors storing the column data.
+    //! @param names the vector of string storing the columns names
+    //! @param types the vector of string storing the FITS data format
+    //! @param numElems the number of elements in this column
+    //! @param type the char describing the FITS data format
+    //! @param name the name of the particular column to be added.
+    //
+    inline void AddColumnEntry(vector<string>& names, vector<string>& types, int numElems, char type, string name)
+    {
+        names.push_back(name);
+
+        ostringstream str;
+        if (numElems != 1)
+            str << numElems;
+        str << type;
+        types.push_back(str.str());
+    }
+
+    // --------------------------------------------------------------------------
+    //
+    //! Writes a single header key entry
+    //! @param name the name of the key
+    //! @param value its value
+    //! @param comment the comment associated to that key
+    //
+    //FIXME this function is a duplicate from the class Fits. should we try to merge it ?
+    template <typename T>
+    void WriteKey(const string &name, const T &value, const string &comment)
+    {
+        try
+        {
+            fTable->addKey(name, value, comment);
+        }
+        catch (CCfits::FitsException e)
+        {
+            ostringstream str;
+            str << "Could not add header key ";
+            //TODO pipe the error message somewhere
+        }
+    }
+
+    template <typename T>
+    void WriteKey(const string &name, const int idx, const T &value, const string &comment)
+    {
+        ostringstream str;
+        str << name << idx;
+
+        WriteKey(str.str(), value, comment);
     }
 
@@ -172,8 +337,8 @@
     //! @param h a pointer to the RUN_HEAD structure that contains the informations relative to this run
     //
-    bool OpenFile(uint32_t /*runid*/, RUN_HEAD* h)
+    bool OpenFile(RUN_HEAD* h)
     {
         //Form filename, based on runid and run-type
-        string fileName = FormFileName(h->FADhead[0].runnumber, h->RunType, "fits");
+        const string fileName = FormFileName(h->RunType, "fits");
 
         //create the FITS object
@@ -214,6 +379,4 @@
         AddColumnEntry(colNames, dataTypes, NPIX*h->Nroi,   'U', "Data");
 
-        fRoi = h->Nroi;
-
         //actually create the table
         try
@@ -228,5 +391,5 @@
             }
         }
-        catch(CCfits::FitsException e)
+        catch (const CCfits::FitsException &e)
         {
             ostringstream str;
@@ -356,9 +519,9 @@
         fNumRows++;
 
-        const int sh = sizeof(PEVNT_HEADER)-1;
+        const int sh = sizeof(PEVNT_HEADER)+(NPIX-1)*e->Roi*2;
 
         // column size pointer
         size_t col = 1;
-        if (!WriteColumns(col, sh + NPIX*fRoi*2, e))
+        if (!WriteColumns(col, sh, e))
             return true;
 
@@ -654,5 +817,5 @@
         try
         {
-            if (!file->OpenFile(runid, h))
+            if (!file->OpenFile(h))
                 return 0;
         }
