Index: /trunk/FACT++/src/DataCalib.cc
===================================================================
--- /trunk/FACT++/src/DataCalib.cc	(revision 12468)
+++ /trunk/FACT++/src/DataCalib.cc	(revision 12469)
@@ -11,5 +11,5 @@
 DrsCalibration DataCalib::fData;
 bool DataCalib::fProcessing = false;
-vector<float> DataCalib::fStats(1440*1024*6+3);
+vector<float> DataCalib::fStats(1440*1024*6+160*1024*2+4);
 
 void DataCalib::Restart()
@@ -20,11 +20,12 @@
     reinterpret_cast<uint32_t*>(fStats.data())[1] = 0;
     reinterpret_cast<uint32_t*>(fStats.data())[2] = 0;
+    reinterpret_cast<uint32_t*>(fStats.data())[3] = 0;
 
     int i=0;
-    while (i<1024*1440*2+3)  // Set mean and RMS to 0
+    while (i<1024*1440*2+4)  // Set mean and RMS to 0
         fStats[i++] = 0;
-    while (i<1024*1440*3+3)
+    while (i<1024*1440*3+4)
         fStats[i++] = 2000./4096; // Set mean to 0.5
-    while (i<1024*1440*6+3)
+    while (i<1440*1024*6+160*1024*2+4)
         fStats[i++] = 0;   // Set everything else to 0
 
@@ -34,5 +35,25 @@
 void DataCalib::Update(DimDescribedService &dim)
 {
-    dim.Update(fStats);
+    const uint16_t roi = fData.fRoi;
+    const uint16_t ntm = fData.fNumTm;
+
+    vector<float> buf(1440*1024*6+160*1024*2+4);
+
+    memcpy(buf.data(), fStats.data(), (4*1024*1440+4)*sizeof(float));
+
+    for (int i=0; i<1440; i++)
+    {
+        memcpy(buf.data()+4+1440*1024*4 + i*1024, fStats.data()+4 + 4*1024*1440 + roi*i,            roi*sizeof(float));
+        memcpy(buf.data()+4+1440*1024*5 + i*1024, fStats.data()+4 + 4*1024*1440 + roi*1440 + roi*i, roi*sizeof(float));
+    }
+
+    /*
+    for (int i=0; i<ntm; i++)
+    {
+        memcpy(buf.data()+4+1440*1024*6          + i*1024, fStats.data()+4 + 4*1024*1440 + 2*roi*1440,       roi*sizeof(float));
+        memcpy(buf.data()+4+1440*1024*6+160*1024 + i*1024, fStats.data()+4 + 4*1024*1440 + 2*roi*1440+i*roi, roi*sizeof(float));
+    }*/
+
+    dim.Update(buf);
 }
 
@@ -45,10 +66,4 @@
     }
 
-    if (h->Nroi != 1024)
-    {
-        fMsg.Error("Region of interest not 1024.");
-        return false;
-    }
-
     if (fProcessing)
     {
@@ -57,5 +72,5 @@
     }
 
-    if (fData.fStep==4)
+    if (fData.fStep==3)
     {
         fMsg.Warn("DRS Calibration already finished... please restart!");
@@ -63,8 +78,66 @@
     }
 
+    if (fData.fStep!=2 && h->Nroi != 1024)
+    {
+        ostringstream msg;
+        msg << "Region of interest not 1024, but " << h->Nroi << " in step " << fData.fStep <<  " ... as it ought to be.";
+        fMsg.Error(msg);
+        return false;
+    }
+
+    vector<uint16_t> dac(8);
+/*
+    // We don't check consistency over several boards because this is done
+    // by the eventCheck routine already
+    for (int i=0; i<h->NBoard; i++)
+    {
+        const PEVNT_HEADER &hh = h->FADhead[i];
+
+        if (hh.start_package_flag==0)
+            continue;
+
+        for (int j=0; j<8; j++)
+            dac[j] = hh.dac[j];
+
+        break;
+    }
+
+    for (int i=1; i<7; i++)
+    {
+        if (i==3 || dac[i]==dac[i+1])
+            continue;
+
+        ostringstream msg;
+        msg << "Values of DAC" << i << " (" << dac[i] << ") and DAC" << i+1 <<" (" << dac[i+1] << ") do not match... cannot take DRS calibration!";
+        fMsg.Error(msg);
+        return false;
+    }
+
+    if (fData.fStep>0)
+    {
+        for (int j=0; j<8; j++)
+        {
+            if (fData.fDAC[j]==dac[j])
+                continue;
+
+            ostringstream msg;
+            msg << "DAC value from previous run (DAC" << j << "=" << fData.fDAC[j] << ") and current run ";
+            msg << "(DAC" << j << "=" << dac[j] << ") inconsistent... cannot take DRS calibration!";
+            fMsg.Error(msg);
+            return false;
+        }
+    }
+
+    memcpy(fData.fDAC, dac.data(), 8*sizeof(uint16_t));
+*/
     fProcessing = true;
 
+    const bool hastm = h->Nroi<=512 && h->NroiTM>=2*h->Nroi;
+
     Reset();
-    InitSize(1440, 1024);
+    InitSize(hastm ? 1600 : 1440, h->Nroi);
+
+    fData.fRoi   = fNumSamples;
+    fData.fNumTm = hastm ? 160 : 0;
 
     return DataWriteFits::Open(h);
@@ -115,18 +188,30 @@
 }
 
+void ReverseCopy(const void *src, void *dest)
+{
+    reverse_copy(reinterpret_cast<const char*>(src),
+                 reinterpret_cast<const char*>(src)+sizeof(float),
+                 reinterpret_cast<char*>(dest));
+}
+
 void DataCalib::WriteFits()
 {
 #ifdef HAVE_FITS
     FitsFile file(fMsg);
+
+    const uint16_t roi = fData.fRoi;
+    const uint16_t ntm = fData.fNumTm;
 
     file.AddColumn('I', "RunNumberBaseline");
     file.AddColumn('I', "RunNumberGain");
     file.AddColumn('I', "RunNumberTriggerOffset");
-    file.AddColumn('F', "BaselineMean",      1024*1440, "mV");
-    file.AddColumn('F', "BaselineRms",       1024*1440, "mV");
-    file.AddColumn('F', "GainMean",          1024*1440, "mV");
-    file.AddColumn('F', "GainRms",           1024*1440, "mV");
-    file.AddColumn('F', "TriggerOffsetMean", 1024*1440, "mV");
-    file.AddColumn('F', "TriggerOffsetRms",  1024*1440, "mV");
+    file.AddColumn('F', "BaselineMean",        1024*1440, "mV");
+    file.AddColumn('F', "BaselineRms",         1024*1440, "mV");
+    file.AddColumn('F', "GainMean",            1024*1440, "mV");
+    file.AddColumn('F', "GainRms",             1024*1440, "mV");
+    file.AddColumn('F', "TriggerOffsetMean",    roi*1440, "mV");
+    file.AddColumn('F', "TriggerOffsetRms",     roi*1440, "mV");
+    file.AddColumn('F', "TriggerOffsetTMMean",  roi*ntm,  "mV");
+    file.AddColumn('F', "TriggerOffsetTMRms",   roi*ntm,  "mV");
 
     const string filename = FormFileName("drs.fits");
@@ -146,18 +231,20 @@
         !file.WriteKeyNT("ADC",      12,               "Resolution of ADC in bits")      ||
         !file.WriteKeyNT("DAC",      16,               "Resolution of DAC in bits")      ||
-        !file.WriteKeyNT("DACLEVEL", 50000,            "Applied DAC level in counts")    ||
+//        !file.WriteKeyNT("DAC_A",    fData.fDAC[0],    "Level of DAC 0 in DAC counts")   ||
+//        !file.WriteKeyNT("DAC_B",    fData.fDAC[1],    "Leval of DAC 1-3 in DAC counts") ||
+//        !file.WriteKeyNT("DAC_C",    fData.fDAC[4],    "Leval of DAC 4-7 in DAC counts") ||
         !file.WriteKeyNT("NBOFFSET", fData.fNumOffset,       "Number of entries for offset calibration") ||
         !file.WriteKeyNT("NBGAIN",   fData.fNumGain/1953125, "Number of entries for gain calibration")   ||
         !file.WriteKeyNT("NBTRGOFF", fData.fNumTrgOff,       "Number of entries for trigger offset calibration") ||
         !file.WriteKeyNT("NPIX",     1440,             "Number of channels in the camera") ||
-        !file.WriteKeyNT("NROI",     1024,             "Region of interest")
+        !file.WriteKeyNT("NTM",      ntm,              "Number of time marker channels") ||
+        !file.WriteKeyNT("NROI",     roi,              "Region of interest")
        )
         return;
 
-    vector<char> buf;
-    buf.reserve(fStats.size()*sizeof(float));
+    vector<char> buf(fStats.size()*sizeof(float));
 
     char *src  = reinterpret_cast<char*>(fStats.data());
-    char *end  = reinterpret_cast<char*>(fStats.data()+1024*1440*6+3);
+    char *end  = reinterpret_cast<char*>(fStats.data()+fStats.size());
     char *dest = buf.data();
 
@@ -172,9 +259,9 @@
         return;
 
-    if (!file.WriteData(buf.data(), 1024*1440*sizeof(float)*6+3))
+    if (!file.WriteData(buf.data(), (1440*1024*4 + 1440*roi*2 + ntm*roi*2 + 3)*sizeof(float)))
         return;
 
     ostringstream str;
-    str << "Wrote DRS calibration data (step=" << fData.fStep << ") to '" << filename << "'";
+    str << "Wrote DRS calibration data (step=" << fData.fStep << ", roi=" << roi << ") to '" << filename << "'";
     Info(str.str());
 #endif
@@ -192,5 +279,5 @@
 
         // Scale ADC data from 12bit to 2000mV
-        GetSampleStats(fStats.data()+3, 2000./4096);
+        GetSampleStats(fStats.data()+4, 2000./4096);
         reinterpret_cast<uint32_t*>(fStats.data())[0] = GetRunId();;
     }
@@ -200,7 +287,7 @@
         fData.fNumGain = fNumEntries;
 
-        // DAC:  0..2.5V == 0..65535
-        // V-mV: 1000
-        //fNumGain *= 2500*50000;
+        // DAC:  0..2.5V == 0..65535            2500*50000   625*50000  625*3125
+        // V-mV: 1000                           ----------   ---------  --------
+        //fNumGain *= 2500*50000;                  65536       16384      1024
         //for (int i=0; i<1024*1440; i++)
         //    fGain[i] *= 65536;
@@ -210,5 +297,5 @@
 
         // Scale ADC data from 12bit to 2000mV
-        GetSampleStats(fStats.data()+1024*1440*2+3, 2000./4096/fData.fNumOffset);//0.5);
+        GetSampleStats(fStats.data()+1024*1440*2+4, 2000./4096/fData.fNumOffset);//0.5);
         reinterpret_cast<uint32_t*>(fStats.data())[1] = GetRunId();;
     }
@@ -219,6 +306,7 @@
 
         // Scale ADC data from 12bit to 2000mV
-        GetSampleStats(fStats.data()+1024*1440*4+3, 2000./4096/fData.fNumOffset);//0.5);
-        reinterpret_cast<uint32_t*>(fStats.data())[2] = GetRunId();;
+        GetSampleStats(fStats.data()+1024*1440*4+4, 2000./4096/fData.fNumOffset);//0.5);
+        reinterpret_cast<uint32_t*>(fStats.data())[2] = GetRunId();
+        reinterpret_cast<uint32_t*>(fStats.data())[3] = fNumSamples;
     }
 
@@ -226,5 +314,5 @@
         WriteFits();
 
-    fDim.Update(fStats);
+    Update(fDim);
 
     fData.fStep++;
