Index: /trunk/FACT++/src/DataWriteFits2.cc
===================================================================
--- /trunk/FACT++/src/DataWriteFits2.cc	(revision 17230)
+++ /trunk/FACT++/src/DataWriteFits2.cc	(revision 17231)
@@ -6,22 +6,21 @@
 #include "FAD.h"
 
+#include "externals/factofits.h"
+#include "externals/DrsCalib.h"
+
 using namespace std;
 
-void DataWriteFits2::WriteDefaultKeys(ofits &file)
-{
-    const Time now;
-    file.SetStr(  "TELESCOP", "FACT",               "Telescope that acquired this data");
-    file.SetStr(  "PACKAGE",   PACKAGE_NAME,        "Package name");
-    file.SetStr(  "VERSION",   PACKAGE_VERSION,     "Package description");
-    file.SetStr(  "CREATOR",   "fadctrl",           "Program that wrote this file");
-    file.SetFloat("EXTREL",    1.0,                 "Release Number");
-    file.SetStr(  "COMPILED",  __DATE__" "__TIME__, "Compile time");
-    file.SetStr(  "REVISION",  REVISION,            "SVN revision");
-    file.SetStr(  "ORIGIN",   "FACT",               "Institution that wrote the file");
-    file.SetStr(  "DATE",     now.Iso(),            "File creation date");
-    file.SetInt(  "NIGHT",    now.NightAsInt(),     "Night as int");
-    file.SetStr(  "TIMESYS",  "UTC",                "Time system");
-    file.SetStr(  "TIMEUNIT", "d",                  "Time given in days w.r.t. to MJDREF");
-    file.SetInt(  "MJDREF",   40587,                "MJD to UNIX time (seconds since 1970/1/1)");
+DataWriteFits2::DataWriteFits2(const std::string path, uint64_t night, uint32_t runid, MessageImp &imp)
+    : DataProcessorImp(path, night, runid, imp)
+{
+    fFile = std::make_shared<std::ofits>();
+}
+
+DataWriteFits2::DataWriteFits2(const std::string path, uint64_t night, uint32_t runid, const DrsCalibration &cal, MessageImp &imp)
+    : DataProcessorImp(path, night, runid, imp)
+{
+    factofits *file = new factofits;
+    file->SetDrsCalibration(cal);
+    fFile = std::shared_ptr<std::ofits>(file);
 }
 
@@ -30,47 +29,55 @@
     const int16_t realRoiTM = (h.NroiTM >= 2*h.Nroi && h.Nroi<=512) ? h.Nroi : 0;
 
-    fFile.AddColumnInt("EventNum", "uint32", "FAD board event counter");
-    fFile.AddColumnInt("TriggerNum", "uint32", "FTM board trigger counter");
-    fFile.AddColumnShort("TriggerType", "uint16", "FTM board trigger type");
-    fFile.AddColumnInt("NumBoards", "uint32", "Number of connected boards");
-    fFile.AddColumnInt(2, "UnixTimeUTC", "uint32", "Unix time seconds and microseconds");
-    fFile.AddColumnInt(NBOARDS, "BoardTime", "uint32", "Board internal time counter");
-    fFile.AddColumnShort(NPIX, "StartCellData", "uint16", "DRS4 start cell of readout");
-    fFile.AddColumnShort(NTMARK, "StartCellTimeMarker", "uint16", "DRS4 start cell of readout time marker");
-    fFile.AddColumnShort(h.NPix*h.Nroi, "Data", "int16", "Digitized data");
-    fFile.AddColumnShort(h.NTm*realRoiTM, "TimeMarker", "int16", "Digitized time marker - if available");
+    fFile->AddColumnInt("EventNum", "uint32", "FAD board event counter");
+    fFile->AddColumnInt("TriggerNum", "uint32", "FTM board trigger counter");
+    fFile->AddColumnShort("TriggerType", "uint16", "FTM board trigger type");
+    fFile->AddColumnInt("NumBoards", "uint32", "Number of connected boards");
+    fFile->AddColumnInt(2, "UnixTimeUTC", "uint32", "Unix time seconds and microseconds");
+    fFile->AddColumnInt(NBOARDS, "BoardTime", "uint32", "Board internal time counter");
+    fFile->AddColumnShort(NPIX, "StartCellData", "uint16", "DRS4 start cell of readout");
+    fFile->AddColumnShort(NTMARK, "StartCellTimeMarker", "uint16", "DRS4 start cell of readout time marker");
+
+    vector<uint16_t> processing(2);
+    processing[0] = FITS::kFactSmoothing;
+    processing[1] = FITS::kFactHuffman16;
+
+    const Compression comp(processing, FITS::kOrderByRow);
+
+    fFile->AddColumnShort(comp, h.NPix*h.Nroi,   "Data",       "int16", "Digitized data");
+    fFile->AddColumnShort(comp, h.NTm*realRoiTM, "TimeMarker", "int16", "Digitized time marker - if available");
 
     const size_t sz = (h.NPix*h.Nroi + h.NTm*realRoiTM)*2;
-    if (fFile.GetBytesPerRow()-sz+4!=sizeof(EVENT))
+    if (fFile->GetBytesPerRow()-sz+4!=sizeof(EVENT))
     {
         ostringstream str;
         str << "The EVENT structure size (" << sizeof(EVENT) << ") doesn't match the described FITS row (";
-        str << fFile.GetBytesPerRow()-sz+4 << ")";
+        str << fFile->GetBytesPerRow()-sz+4 << ")";
         throw runtime_error(str.str());
     }
 
     // =============== Default keys for all files ================
-    WriteDefaultKeys(fFile);
+    fFile->SetDefaultKeys();
+    fFile->SetInt("NIGHT", GetNight(), "Night as int");
 
     // ================ Header keys for raw-data =================
-    fFile.SetInt("BLDVER",   h.Version,  "Builder version");
-    fFile.SetInt("RUNID",    GetRunId(),  "Run number");
-    fFile.SetInt("NBOARD",   h.NBoard,   "Number of acquisition boards");
-    fFile.SetInt("NPIX",     h.NPix,     "Number of pixels");
-    fFile.SetInt("NTMARK",   h.NTm,      "Number of time marker channels");
-    fFile.SetInt("NCELLS",   1024,        "Maximum number of slices per pixels");
-    fFile.SetInt("NROI",     h.Nroi,     "Number of slices per pixels");
-    fFile.SetInt("NROITM",   realRoiTM,   "Number of slices per time-marker");
+    fFile->SetInt("BLDVER",   h.Version,  "Builder version");
+    fFile->SetInt("RUNID",    GetRunId(),  "Run number");
+    fFile->SetInt("NBOARD",   h.NBoard,   "Number of acquisition boards");
+    fFile->SetInt("NPIX",     h.NPix,     "Number of pixels");
+    fFile->SetInt("NTMARK",   h.NTm,      "Number of time marker channels");
+    fFile->SetInt("NCELLS",   1024,        "Maximum number of slices per pixels");
+    fFile->SetInt("NROI",     h.Nroi,     "Number of slices per pixels");
+    fFile->SetInt("NROITM",   realRoiTM,   "Number of slices per time-marker");
 
     const uint16_t realOffset = (h.NroiTM > h.Nroi) ?  h.NroiTM - 2*h.Nroi : 0;
-    fFile.SetInt("TMSHIFT",  realOffset,  "Shift of marker readout w.r.t. to data");
+    fFile->SetInt("TMSHIFT",  realOffset,  "Shift of marker readout w.r.t. to data");
 
     //FIXME should we also put the start and stop time of the received data ?
     //now the events header related variables
-    fFile.SetStr("CAMERA",   "MGeomCamFACT", "MARS camera geometry class");
-    fFile.SetStr("DAQ",      "DRS4",         "Data acquisition type");
-    fFile.SetInt("ADCRANGE", 2000,        "Dynamic range in mV");
-    fFile.SetInt("ADC",      12,          "Resolution in bits");
-    fFile.SetStr("RUNTYPE",  d.name,      "File type according to FAD configuration");
+    fFile->SetStr("CAMERA",   "MGeomCamFACT", "MARS camera geometry class");
+    fFile->SetStr("DAQ",      "DRS4",         "Data acquisition type");
+    fFile->SetInt("ADCRANGE", 2000,        "Dynamic range in mV");
+    fFile->SetInt("ADC",      12,          "Resolution in bits");
+    fFile->SetStr("RUNTYPE",  d.name,      "File type according to FAD configuration");
 
     // Write a single key for:
@@ -82,5 +89,5 @@
     // Prescaler
 
-    // Write 40 kays for (?)
+    // Write 40 keys for (?)
     // Phaseshift
     // DAC
@@ -93,8 +100,10 @@
         sout << "Board " << setw(2) << i<< ": ";
 
+        const string num = to_string(i);
+
         // Header values whihc won't change during the run
-        fFile.SetInt("ID",    hh.board_id,   sout.str()+"Board ID");
-        fFile.SetInt("FWVER", hh.version_no, sout.str()+"Firmware Version");
-        fFile.SetHex("DNA",   hh.DNA,        sout.str()+"Unique FPGA device identifier (DNA)");
+        fFile->SetInt("ID"+num,    hh.board_id,   sout.str()+"Board ID");
+        fFile->SetInt("FWVER"+num, hh.version_no, sout.str()+"Firmware Version");
+        fFile->SetHex("DNA"+num,   hh.DNA,        sout.str()+"Unique FPGA device identifier (DNA)");
     }
 
@@ -103,11 +112,10 @@
     {
         const PEVNT_HEADER &hh = h.FADhead[i];
-
         if (hh.start_package_flag==0)
             continue;
 
-        fFile.SetInt("BOARD", i, "Board number for RUN, PRESC, PHASE and DAC");
-        fFile.SetInt("PRESC", hh.trigger_generator_prescaler, "Trigger generator prescaler");
-        fFile.SetInt("PHASE", (int16_t)hh.adc_clock_phase_shift, "ADC clock phase shift");
+        fFile->SetInt("BOARD", i, "Board number for RUN, PRESC, PHASE and DAC");
+        fFile->SetInt("PRESC", hh.trigger_generator_prescaler, "Trigger generator prescaler");
+        fFile->SetInt("PHASE", (int16_t)hh.adc_clock_phase_shift, "ADC clock phase shift");
 
         for (int j=0; j<8; j++)
@@ -116,5 +124,5 @@
             dac << "DAC" << j;
             cmt << "Command value for " << dac.str();
-            fFile.SetInt(dac.str(), hh.dac[j], cmt.str());
+            fFile->SetInt(dac.str(), hh.dac[j], cmt.str());
         }
 
@@ -136,9 +144,9 @@
 
     // FIXME: I cannot write a double! WHY?
-    fFile.SetFloat("REFCLK", avg/cnt*2.048, "Average reference clock frequency in Hz");
-
-    fFile.SetBool("DRSCALIB", GetDrsStep()>=0, "This file belongs to a DRS calibration");
+    fFile->SetFloat("REFCLK", avg/cnt*2.048, "Average reference clock frequency in Hz");
+
+    fFile->SetBool("DRSCALIB", GetDrsStep()>=0, "This file belongs to a DRS calibration");
     if (GetDrsStep()>=0)
-        fFile.SetInt("DRSSTEP", GetDrsStep(), "Step of the DRS calibration");
+        fFile->SetInt("DRSSTEP", GetDrsStep(), "Step of the DRS calibration");
 
     fTstart[0] = h.RunTime;
@@ -153,5 +161,5 @@
     WriteFooter(NULL);
 
-    fFile.WriteTableHeader("Events");
+    fFile->WriteTableHeader("Events");
 };
 
@@ -165,5 +173,5 @@
 {
     //Form filename, based on runid and run-type
-    fFileName = FormFileName("fits");
+    fFileName = FormFileName(dynamic_pointer_cast<factofits>(fFile)?"fits.fz":"fits");
 
     if (boost::filesystem::exists(fFileName))
@@ -175,5 +183,5 @@
     try
     {
-        fFile.open(fFileName.c_str());
+        fFile->open(fFileName.c_str());
     }
     catch (const exception &e)
@@ -183,5 +191,5 @@
     }
 
-    if (!fFile)
+    if (!(*fFile))
     {
         ostringstream str;
@@ -201,5 +209,5 @@
     }
 
-    if (!fFile)
+    if (!(*fFile))
     {
         ostringstream str;
@@ -244,5 +252,5 @@
     try
     {
-        fFile.WriteRow(reinterpret_cast<const char*>(&e)+4, sz-4);
+        fFile->WriteRow(reinterpret_cast<const char*>(&e)+4, sz-4);
     }
     catch (const exception &ex)
@@ -252,5 +260,5 @@
     }
 
-    if (!fFile)
+    if (!(*fFile))
     {
         ostringstream str;
@@ -271,25 +279,25 @@
     const Time stop (fTstop[0],  fTstop[1]);
 
-    fFile.SetInt("TSTARTI",  uint32_t(floor(start.UnixDate())),
-                 "Time when first evt received (integral part)");
-    fFile.SetFloat("TSTARTF",  fmod(start.UnixDate(), 1),
-                   "Time when first evt received (fractional part)");
-    fFile.SetInt("TSTOPI",   uint32_t(floor(stop.UnixDate())),
-                 "Time when last evt received (integral part)");
-    fFile.SetFloat("TSTOPF",   fmod(stop.UnixDate(), 1),
-                   "Time when last evt received (fractional part)");
-    fFile.SetStr("DATE-OBS", start.Iso(),
-                 "Time when first event received");
-    fFile.SetStr("DATE-END", stop.Iso(),
-                 "Time when last event received");
-
-    fFile.SetInt("NTRG",     fTriggerCounter[0], "No of physics triggers written");
-    fFile.SetInt("NTRGPED",  fTriggerCounter[1], "No of pure pedestal triggers written");
-    fFile.SetInt("NTRGLPE",  fTriggerCounter[2], "No of external light pulser triggers written");
-    fFile.SetInt("NTRGTIM",  fTriggerCounter[3], "No of time calibration triggers written");
-    fFile.SetInt("NTRGLPI",  fTriggerCounter[4], "No of internal light pulser triggers written");
-    fFile.SetInt("NTRGEXT1", fTriggerCounter[5], "No of triggers from ext1 written");
-    fFile.SetInt("NTRGEXT2", fTriggerCounter[6], "No of triggers from ext2 written");
-    fFile.SetInt("NTRGMISC", fTriggerCounter[7], "No of all other triggers");
+    fFile->SetInt("TSTARTI",  uint32_t(floor(start.UnixDate())),
+                  "Time when first evt received (integral part)");
+    fFile->SetFloat("TSTARTF",  fmod(start.UnixDate(), 1),
+                    "Time when first evt received (fractional part)");
+    fFile->SetInt("TSTOPI",   uint32_t(floor(stop.UnixDate())),
+                  "Time when last evt received (integral part)");
+    fFile->SetFloat("TSTOPF",   fmod(stop.UnixDate(), 1),
+                    "Time when last evt received (fractional part)");
+    fFile->SetStr("DATE-OBS", start.Iso(),
+                  "Time when first event received");
+    fFile->SetStr("DATE-END", stop.Iso(),
+                  "Time when last event received");
+
+    fFile->SetInt("NTRG",     fTriggerCounter[0], "No of physics triggers written");
+    fFile->SetInt("NTRGPED",  fTriggerCounter[1], "No of pure pedestal triggers written");
+    fFile->SetInt("NTRGLPE",  fTriggerCounter[2], "No of external light pulser triggers written");
+    fFile->SetInt("NTRGTIM",  fTriggerCounter[3], "No of time calibration triggers written");
+    fFile->SetInt("NTRGLPI",  fTriggerCounter[4], "No of internal light pulser triggers written");
+    fFile->SetInt("NTRGEXT1", fTriggerCounter[5], "No of triggers from ext1 written");
+    fFile->SetInt("NTRGEXT2", fTriggerCounter[6], "No of triggers from ext2 written");
+    fFile->SetInt("NTRGMISC", fTriggerCounter[7], "No of all other triggers");
 }
 
@@ -301,5 +309,5 @@
 bool DataWriteFits2::Close(const RUN_TAIL *rt)
 {
-    if (!fFile.is_open())
+    if (!fFile->is_open())
     {
         Error("DataWriteFits2::Close() called but file '"+fFileName+"' not open.");
@@ -319,5 +327,5 @@
     try
     {
-        fFile.close();
+        fFile->close();
     }
     catch (const exception &e)
@@ -327,5 +335,5 @@
     }
 
-    if (!fFile)
+    if (!(*fFile))
     {
         ostringstream str;
Index: /trunk/FACT++/src/DataWriteFits2.h
===================================================================
--- /trunk/FACT++/src/DataWriteFits2.h	(revision 17230)
+++ /trunk/FACT++/src/DataWriteFits2.h	(revision 17231)
@@ -3,11 +3,17 @@
 
 #include "DataProcessorImp.h"
-#include "externals/ofits.h"
 
 #include <array>
 
+namespace std
+{
+    class ofits;
+}
+
+class DrsCalibration;
+
 class DataWriteFits2 : public DataProcessorImp
 {
-    std::ofits fFile;
+    std::shared_ptr<std::ofits> fFile;
 
     std::array<uint32_t, 8> fTriggerCounter;
@@ -22,8 +28,6 @@
 
 public:
-    DataWriteFits2(const std::string path, uint64_t night, uint32_t runid, MessageImp &imp) :
-        DataProcessorImp(path, night, runid, imp)
-    {
-    }
+    DataWriteFits2(const std::string path, uint64_t night, uint32_t runid, MessageImp &imp);
+    DataWriteFits2(const std::string path, uint64_t night, uint32_t runid, const DrsCalibration &cal, MessageImp &imp);
 
     bool Open(const RUN_HEAD &h, const FAD::RunDescription &d);
@@ -33,6 +37,4 @@
     Time GetTstart() const { return Time(fTstart[0], fTstart[1]); }
     Time GetTstop() const  { return Time(fTstop[0],  fTstop[1]);  }
-
-    static void WriteDefaultKeys(std::ofits &file);
 };
 
