Index: trunk/Mars/mdrs/DrsLinkDef.h
===================================================================
--- trunk/Mars/mdrs/DrsLinkDef.h	(revision 14922)
+++ trunk/Mars/mdrs/DrsLinkDef.h	(revision 14922)
@@ -0,0 +1,19 @@
+#ifdef __CINT__
+
+#pragma link off all globals;
+#pragma link off all classes;
+#pragma link off all functions;
+
+#pragma link C++ class MDrsCalibApply+;
+#pragma link C++ class MDrsCalibResult+;
+
+#pragma link C++ class MDrsCalibration+;
+#pragma link C++ class MDrsCalibrationTime+;
+
+#pragma link C++ class MHDrsCalibration+;
+#pragma link C++ class MHDrsCalibrationTime+;
+#pragma link C++ class MHDrsCalibrationCheck+;
+
+#pragma link C++ class MCalibrateDrsTimes+;
+
+#endif
Index: trunk/Mars/mdrs/MCalibrateDrsTimes.cc
===================================================================
--- trunk/Mars/mdrs/MCalibrateDrsTimes.cc	(revision 14922)
+++ trunk/Mars/mdrs/MCalibrateDrsTimes.cc	(revision 14922)
@@ -0,0 +1,179 @@
+/* ======================================================================== *\
+!
+! *
+! * This file is part of MARS, the MAGIC Analysis and Reconstruction
+! * Software. It is distributed to you in the hope that it can be a useful
+! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
+! * It is distributed WITHOUT ANY WARRANTY.
+! *
+! * Permission to use, copy, modify and distribute this software and its
+! * documentation for any purpose is hereby granted without fee,
+! * provided that the above copyright notice appear in all copies and
+! * that both that copyright notice and this permission notice appear
+! * in supporting documentation. It is provided "as is" without express
+! * or implied warranty.
+! *
+!
+!
+!   Author(s): Thomas Bretz 2013 <mailto:thomas.bretz@epfl.ch>
+!
+!   Copyright: MAGIC Software Development, 2000-2013
+!
+!
+\* ======================================================================== */
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//   MCalibrateDrsTimes
+//
+//////////////////////////////////////////////////////////////////////////////
+#include "MCalibrateDrsTimes.h"
+
+#include "MParList.h"
+
+#include "MArrivalTimeCam.h"
+#include "MArrivalTimePix.h"
+
+#include "MBadPixelsCam.h"
+#include "MBadPixelsPix.h"
+
+#include "MSignalCam.h"
+
+#include "MRawRunHeader.h"
+#include "MRawEvtData.h"
+
+#include "MDrsCalibrationTime.h"
+
+ClassImp(MCalibrateDrsTimes);
+
+using namespace std;
+
+// --------------------------------------------------------------------------
+//
+// Default constructor. 
+//
+MCalibrateDrsTimes::MCalibrateDrsTimes(const char *name, const char *title) 
+    : fRunHeader(NULL), fCalib(NULL), fBadPixels(NULL), fSignals(NULL),
+    fArrivalTime(NULL), fArrivalTimeU(NULL), fNameArrivalTime("MArrivalTimeCam"),
+    fNameCalibrated("MSignalCam"), fNameUncalibrated(""), fIsTimeMarker(kFALSE)
+{
+    fName  = name  ? name  : "MCalibrateDrsTimes";
+    fTitle = title ? title : "Task to calculate the calibrated arrival times of photons in one event";
+}
+
+// --------------------------------------------------------------------------
+//
+// The PreProcess searches for the following input containers:
+//  - MGeomCam
+//  - MCalibrationRelTimesCam
+//  - MArrivalTimeCam
+//  - MBadPixelsCam
+//
+Int_t MCalibrateDrsTimes::PreProcess(MParList *pList)
+{
+    fSignals = (MArrivalTimeCam*)pList->FindObject(AddSerialNumber(fNameArrivalTime), "MArrivalTimeCam");
+    if (!fSignals)
+    {
+        *fLog << err << AddSerialNumber("MArrivalTimeCam") << " not found ... aborting" << endl;
+        return kFALSE;
+    }
+
+    fRaw = (MRawEvtData*)pList->FindObject(AddSerialNumber("MRawEvtData"));
+    if (!fRaw)
+    {
+        *fLog << err << AddSerialNumber("MRawEvtData") << " not found ... aborting" << endl;
+        return kFALSE;
+    }
+
+    fBadPixels = (MBadPixelsCam*)pList->FindObject(AddSerialNumber("MBadPixelsCam"));
+    if (!fBadPixels)
+        *fLog << warn << AddSerialNumber("MBadPixelsCam") << " not found ... ignoring." << endl;
+
+    fCalib = (MDrsCalibrationTime*)pList->FindObject("MDrsCalibrationTime");
+    if (!fCalib)
+        *fLog << warn << "MDrsCalibrationTime not found... no calibratuon will be applied." << endl;
+
+    fArrivalTime = (MSignalCam*)pList->FindCreateObj(AddSerialNumber("MSignalCam"), fNameCalibrated);
+    if (!fArrivalTime)
+        return kFALSE;
+
+    if (!fNameUncalibrated.IsNull())
+    {
+        fArrivalTimeU = (MSignalCam*)pList->FindCreateObj("MSignalCam", fNameUncalibrated);
+        if (!fArrivalTimeU)
+            return kFALSE;
+    }
+
+    return kTRUE;
+}
+
+Bool_t MCalibrateDrsTimes::ReInit(MParList *pList)
+{
+    fRunHeader = (MRawRunHeader*)pList->FindObject(AddSerialNumber("MRawRunHeader"));
+    if (!fRunHeader)
+    {
+        *fLog << err << AddSerialNumber("MRawRunHeader") << " not found ... aborting." << endl;
+        return kFALSE;
+    }
+
+    fFreq = fRunHeader->GetFreqSampling();
+
+    return kTRUE;
+}
+
+// --------------------------------------------------------------------------
+//
+// Apply the calibration factors to the extracted signal according to the 
+// selected calibration method
+//
+Int_t MCalibrateDrsTimes::Process()
+{
+    const UInt_t npix = fSignals->GetSize();
+
+    const UShort_t *idx = fRaw->GetPixelIds();
+    const int16_t  *start = reinterpret_cast<int16_t*>(fRaw->GetStartCells());
+
+    for (UInt_t hw=(fIsTimeMarker?8:0); hw<npix; hw+=(fIsTimeMarker?9:1))
+    //for (UInt_t hw=8; hw<npix; hw+=9)
+    {
+        const UInt_t sw = idx[hw];
+
+        if (start[hw]<0)
+        {
+            if (fBadPixels)
+                (*fBadPixels)[sw].SetUnsuitable(MBadPixelsPix::kUnsuitableEvt);
+            continue;
+        }
+
+        if (fBadPixels && !fIsTimeMarker && (*fBadPixels)[sw].IsUnsuitable(MBadPixelsPix::kUnsuitableRun))
+            continue;
+
+        const Float_t signal = (*fSignals)[sw].GetArrivalTime();
+        const Float_t offset = fCalib ? fCalib->GetOffset(hw, start[hw], signal) : 0;
+        const Float_t delay  = fCalib ? fCalib->GetDelay(sw) : 0;
+
+        //if (fIsTimeMarker)
+        //    offset = fCalib ? fCalib->GetDelay(hw, start[hw], signal) : 0;
+
+        // convert from slices to ns
+        const Float_t utime = 1000*(signal       )/fFreq-delay; // [ns]
+        const Float_t time  = 1000*(signal-offset)/fFreq-delay; // [ns]
+
+        /*
+        (*fArrivalTime)[sw].SetArrivalTime(time);
+        if (fArrivalTimeU)
+            (*fArrivalTimeU)[sw].SetArrivalTime(utime);
+            */
+
+        for (UInt_t j=hw-(fIsTimeMarker?8:0); j<=hw; j++)
+        {
+            (*fArrivalTime)[idx[j]].SetArrivalTime(time);
+            if (fArrivalTimeU)
+                (*fArrivalTimeU)[idx[j]].SetArrivalTime(utime);
+        }
+    }
+
+    fArrivalTime->SetReadyToSave();
+
+    return kTRUE;
+}
Index: trunk/Mars/mdrs/MCalibrateDrsTimes.h
===================================================================
--- trunk/Mars/mdrs/MCalibrateDrsTimes.h	(revision 14922)
+++ trunk/Mars/mdrs/MCalibrateDrsTimes.h	(revision 14922)
@@ -0,0 +1,52 @@
+#ifndef MARS_MCalibrateDrsTimes
+#define MARS_MCalibrateDrsTimes
+
+#ifndef MARS_MTask
+#include "MTask.h"
+#endif
+
+class MGeomCam;
+class MBadPixelsCam;
+class MDrsCalibrationTime;
+class MArrivalTimeCam;
+class MRawRunHeader;
+class MRawEvtData;
+class MSignalCam;
+
+class MCalibrateDrsTimes : public MTask
+{
+private:
+    MRawRunHeader       *fRunHeader;
+    MRawEvtData         *fRaw;
+    MDrsCalibrationTime *fCalib; // Calibration rel. time constants
+    MBadPixelsCam       *fBadPixels;    // Bad Pixels information
+    MArrivalTimeCam     *fSignals;      // Extracted Arrival Time
+    MSignalCam          *fArrivalTime;  // Calibrated arrival times
+    MSignalCam          *fArrivalTimeU; // Uncalibrated arrival times
+
+    UShort_t fFreq;                        //! [MHz] Sampling Frequency
+
+    TString fNameArrivalTime;
+    TString fNameCalibrated;
+    TString fNameUncalibrated;
+
+    Bool_t fIsTimeMarker;
+
+    Int_t  PreProcess(MParList *pList);
+    Bool_t ReInit(MParList *pList);
+    Int_t  Process();
+
+public:
+    MCalibrateDrsTimes(const char *name=NULL, const char *title=NULL);
+
+    void SetNameArrivalTime(const char *name) { fNameArrivalTime = name; }
+    void SetNameCalibrated(const char *name) { fNameCalibrated = name; }
+    void SetNameUncalibrated(const char *name) { fNameUncalibrated = name; }
+
+    void SetTimeMarker(Bool_t tm=kTRUE) { fIsTimeMarker = tm; }
+
+    ClassDef(MCalibrateDrsTimes, 0)   // Task to calculate calibrated relative arrival times
+};
+ 
+
+#endif
Index: trunk/Mars/mdrs/MDrsCalibApply.cc
===================================================================
--- trunk/Mars/mdrs/MDrsCalibApply.cc	(revision 14922)
+++ trunk/Mars/mdrs/MDrsCalibApply.cc	(revision 14922)
@@ -0,0 +1,247 @@
+/* ======================================================================== *\
+!
+! *
+! * This file is part of MARS, the MAGIC Analysis and Reconstruction
+! * Software. It is distributed to you in the hope that it can be a useful
+! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
+! * It is distributed WITHOUT ANY WARRANTY.
+! *
+! * Permission to use, copy, modify and distribute this software and its
+! * documentation for any purpose is hereby granted without fee,
+! * provided that the above copyright notice appear in all copies and
+! * that both that copyright notice and this permission notice appear
+! * in supporting documentation. It is provided "as is" without express
+! * or implied warranty.
+! *
+!
+!
+!   Author(s): Thomas Bretz, 2013<mailto:thomas.bretz@epfl.ch>
+!
+!   Copyright: MAGIC Software Development, 2013
+!
+!
+\* ======================================================================== */
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//   MDrsCalibApply
+//
+//////////////////////////////////////////////////////////////////////////////
+#include "MDrsCalibApply.h"
+
+#include "MLog.h"
+#include "MLogManip.h"
+
+#include "MParList.h"
+
+#include "MArrayB.h"
+
+#include "MRawRunHeader.h"
+#include "MRawEvtData.h"
+#include "MRawEvtPixelIter.h"
+
+#include "MPedestalCam.h"
+#include "MPedestalPix.h"
+
+#include "MDrsCalibration.h"
+#include "MPedestalSubtractedEvt.h"
+
+#include "MExtractedSignalCam.h"
+#include "MExtractedSignalPix.h"
+
+ClassImp(MDrsCalibApply);
+
+using namespace std;
+
+// --------------------------------------------------------------------------
+//
+// Default constructor. 
+//
+MDrsCalibApply::MDrsCalibApply(const char *name, const char *title)
+    : fRawEvt(NULL), fDrsCalib(NULL), fSignal(NULL), fResult(0),
+    fMaxNumPrevEvents(5), fRemoveSpikes(3), fSlidingAverage(0)
+{
+    fName  = name  ? name  : "MDrsCalibApply";
+    fTitle = title ? title : "Class to subtract pedestal";
+}
+
+// --------------------------------------------------------------------------
+//
+// The PreProcess searches for the following input containers:
+//  - MRawEvtData
+//  - MRawRunHeader
+//  - MPedestalCam
+//
+// The following output containers are also searched and created if
+// they were not found:
+//
+//  - MDrsCalibApplyedEvt
+//
+Int_t MDrsCalibApply::PreProcess(MParList *pList)
+{
+    fRawEvt = (MRawEvtData*)pList->FindObject(AddSerialNumber("MRawEvtData"));
+    if (!fRawEvt)
+    {
+        *fLog << err << AddSerialNumber("MRawEvtData") << " not found... aborting." << endl;
+        return kFALSE;
+    }
+
+    fDrsCalib = (MDrsCalibration*)pList->FindObject("MDrsCalibration");
+    if (!fDrsCalib)
+        *fLog << warn << "No DRS calibration container (MDrsCalibration) found... skipping." << endl;
+
+    else
+        *fLog << inf << "DRS calibration will be applied." << endl;
+
+    fResult = 0;
+    if (fMaxNumPrevEvents>0)
+    {
+        fPrevStart.clear();
+        fResult = (MDrsCalibResult*)pList->FindCreateObj("MDrsCalibResult");
+        if (!fResult)
+            return kFALSE;
+    }
+
+    fSignal = (MPedestalSubtractedEvt*)pList->FindCreateObj("MPedestalSubtractedEvt");//, AddSerialNumber(fNamePedestalSubtractedEvt));
+    if (!fSignal)
+        return kFALSE;
+
+    return kTRUE;
+}
+
+Bool_t MDrsCalibApply::ReInit(MParList *pList)
+{
+    fRunHeader = (MRawRunHeader*)pList->FindObject(AddSerialNumber("MRawRunHeader"));
+    if (!fRunHeader)
+    {
+        *fLog << err << AddSerialNumber("MRawRunHeader") << " not found... aborting." << endl;
+        return kFALSE;
+    }
+
+    if (!fDrsCalib)
+        return kTRUE;
+
+    if (fDrsCalib->fRoi>0 && fDrsCalib->fRoi != fRunHeader->GetNumSamplesHiGain())
+    {
+        *fLog << warn << "Slice number of DRS calibration " << fDrsCalib->fRoi << " and run-header " << fRunHeader->GetNumSamplesHiGain() << " don't match...\n";
+        *fLog << "secondary baseline correction will not be applied." << endl;
+        return kFALSE;
+    }
+
+    return kTRUE;
+}
+
+// --------------------------------------------------------------------------
+//
+//
+Int_t MDrsCalibApply::Process()
+{
+    // Please note:
+    //   - for data with only hi-gain samples numl is 0
+    //   - for data with hi- and lo-gain samples
+    //     numl is 0 if read from a raw-data file or a new MC root-file(?)
+    //     numl is not 0 if read from an old MC root-file
+
+    // Total number of samples
+    const Int_t roi = fRawEvt->GetNumHiGainSamples();
+
+    // Check if event is empty (presumably MC event -- sanity check)
+    if (roi==0)
+        return kCONTINUE;
+
+    // Check for consistency (our simulation can do weird things!)
+    if (roi!=fRunHeader->GetNumSamplesHiGain())
+    {
+        *fLog << err << "MDrsCalibApply::Process: ERROR - Number of samples in event ";
+        *fLog << "(hi=" << roi << ")" << endl << " doesn't match number in run-header ";
+        *fLog << "(" << fRunHeader->GetNumSamplesHiGain() << ")" << endl;
+        *fLog << " In case you are processing real data you have just found a bug." << endl;
+        *fLog << " If you process Monte Carlo data, it means probably that the length" << endl;
+        *fLog << " of the arrays in MRawEvtData are inconsistent with the run-header." << endl;
+        return kERROR;
+    }
+
+    if (fRawEvt->GetNumLoGainSamples()+fRunHeader->GetNumSamplesLoGain()>0)
+    {
+        *fLog << err << "MDrsCalibApply::Process: ERROR - Data must not contain lo gain slices." << endl;
+        return kERROR;
+    }
+
+    // initialize fSignal
+    fSignal->InitSamples(roi);
+
+    if (!fDrsCalib)  // FIXME: Do a fake (none) calibration
+        return kTRUE;
+
+    const int16_t *val = reinterpret_cast<int16_t*>(fRawEvt->GetSamples());
+
+    const int32_t *offset = fDrsCalib->fOffset.data();
+    const int64_t *gain   = fDrsCalib->fGain.data();
+    const int64_t *trgoff = fDrsCalib->fTrgOff.data();
+
+    const uint64_t scaleabs  = fDrsCalib->fNumOffset;
+    const uint64_t scalegain = fDrsCalib->fNumGain;
+    const uint64_t scalerel  = fDrsCalib->fNumTrgOff;
+
+    const int16_t *start = reinterpret_cast<int16_t*>(fRawEvt->GetStartCells());
+
+    Float_t *vec = fSignal->GetSamples(0);
+
+    const UShort_t *idx = fRawEvt->GetPixelIds();
+    for (size_t ch=0; ch<fRawEvt->GetNumPixels(); ch++)
+    {
+        const size_t drs = ch*1024;
+        const size_t hw  = ch*roi;
+        const size_t sw  = idx[ch]*roi;
+
+        DrsCalibrate::ApplyCh(vec+sw, val+hw, start[ch], roi,
+                              offset+drs, scaleabs,
+                              gain  +drs, scalegain,
+                              trgoff+hw,  scalerel);
+    }
+
+    if (fResult)
+    {
+        fResult->fData.resize(fPrevStart.size()*2);
+
+        deque<vector<Short_t>>::const_iterator it = fPrevStart.begin();
+
+        for (size_t i=0; i<fPrevStart.size()*2; i++)
+        {
+            fResult->fData[i] = DrsCalibrate::Step();
+
+            const int32_t off = i%2 ? 3 : roi+10;
+
+            fResult->fData[i] =
+                DrsCalibrate::CorrectStep(vec, fRawEvt->GetNumPixels(), roi,
+                                          it->data(), start, off, idx);
+
+            if (i%2==1)
+                it++;
+        }
+
+        fPrevStart.push_front(vector<Short_t>(start, start+fRawEvt->GetNumPixels()));
+        if (fPrevStart.size()>fMaxNumPrevEvents)
+            fPrevStart.pop_back();
+    }
+
+    switch (fRemoveSpikes)
+    {
+    case 1:
+        DrsCalibrate::RemoveSpikes(vec, roi);
+        break;
+    case 2:
+        DrsCalibrate::RemoveSpikes2(vec, roi);
+        break;
+    case 3:
+        DrsCalibrate::RemoveSpikes3(vec, roi);
+        break;
+    }
+
+
+    if (fSlidingAverage)
+        DrsCalibrate::SlidingAverage(vec, roi, fSlidingAverage);
+
+
+    return kTRUE;
+}
Index: trunk/Mars/mdrs/MDrsCalibApply.h
===================================================================
--- trunk/Mars/mdrs/MDrsCalibApply.h	(revision 14922)
+++ trunk/Mars/mdrs/MDrsCalibApply.h	(revision 14922)
@@ -0,0 +1,65 @@
+#ifndef MARS_MDrsCalibApply
+#define MARS_MDrsCalibApply
+
+#ifndef MARS_MTask
+#include "MTask.h"
+#endif
+
+#ifndef MARS_DrsCalib
+#include "DrsCalib.h"
+#endif
+
+#include <deque>
+
+class MRawRunHeader;
+class MRawEvtData;
+class MPedestalSubtractedEvt;
+class MDrsCalibration;
+
+class MDrsCalibResult: public MParContainer
+{
+    friend class MDrsCalibApply;
+
+public:
+    std::vector<DrsCalibrate::Step> fData;
+
+    MDrsCalibResult()
+    {
+        fName = "MDrsCalibResult";
+    }
+
+    const std::vector<DrsCalibrate::Step> &GetData() const { return fData; }
+
+    ClassDef(MDrsCalibResult, 0)
+};
+
+class MDrsCalibApply : public MTask
+{
+private:
+    MRawRunHeader          *fRunHeader;      //! Run Header
+    MRawEvtData            *fRawEvt;         //! Input Raw data
+    MDrsCalibration        *fDrsCalib;       //! DRS4 calibration data
+    MPedestalSubtractedEvt *fSignal;         //! Output container
+    MDrsCalibResult        *fResult;         //! Output container
+
+    std::deque<std::vector<Short_t>> fPrevStart; //! History for start cells of previous events
+
+    UShort_t fMaxNumPrevEvents;
+    UShort_t fRemoveSpikes;
+    UShort_t fSlidingAverage;
+
+    Int_t  PreProcess(MParList *pList);
+    Bool_t ReInit(MParList *pList);
+    Int_t  Process();
+
+public:
+    MDrsCalibApply(const char *name=NULL, const char *title=NULL);
+
+    void SetMaxNumPrevEvents(UShort_t n)  { fMaxNumPrevEvents = n; }
+    void SetRemoveSpikes(int typ=1) { fRemoveSpikes = typ; }
+    void SetSlidingAverage(UShort_t w) { fSlidingAverage = w; }
+
+    ClassDef(MDrsCalibApply, 0)   // Class to subtract pedestal including AB-noise
+};
+
+#endif
Index: trunk/Mars/mdrs/MDrsCalibration.cc
===================================================================
--- trunk/Mars/mdrs/MDrsCalibration.cc	(revision 14922)
+++ trunk/Mars/mdrs/MDrsCalibration.cc	(revision 14922)
@@ -0,0 +1,124 @@
+/* ======================================================================== *\
+!
+! *
+! * This file is part of MARS, the MAGIC Analysis and Reconstruction
+! * Software. It is distributed to you in the hope that it can be a useful
+! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
+! * It is distributed WITHOUT ANY WARRANTY.
+! *
+! * Permission to use, copy, modify and distribute this software and its
+! * documentation for any purpose is hereby granted without fee,
+! * provided that the above copyright notice appear in all copies and
+! * that both that copyright notice and this permission notice appear
+! * in supporting documentation. It is provided "as is" without express
+! * or implied warranty.
+! *
+!
+!
+!   Author(s): Thomas Bretz  07/2011 <mailto:thomas.bretz@epfl.ch>
+!
+!   Copyright: MAGIC Software Development, 2000-2013
+!
+!
+\* ======================================================================== */
+
+///////////////////////////////////////////////////////////////////////
+//
+// MHDrsCalibration
+//
+// This class contains a list of MHFadcPix.
+//
+///////////////////////////////////////////////////////////////////////
+#include "MDrsCalibration.h"
+
+#include <fstream>
+#include <sstream>
+#include <limits.h>
+
+#include "MH.h"
+
+#include "MLog.h"
+#include "MLogManip.h"
+
+#include "MParList.h"
+#include "MGeomCam.h"
+
+#include "MRawEvtData.h"
+#include "MRawRunHeader.h"
+#include "MHCamera.h"
+
+#include <TH2.h>
+
+ClassImp(MDrsCalibration);
+
+using namespace std;
+
+void MDrsCalibration::Plot()
+{
+    TVirtualPad *pad = gPad ? gPad : MH::MakeDefCanvas(this);
+    pad->SetBorderMode(0);
+
+    //AppendPad();
+
+    pad->Divide(2,2);
+
+    MH::SetPalette();
+
+    pad->cd(1);
+    gPad->SetBorderMode(0);
+    gPad->SetFrameBorderMode(0);
+    gPad->SetRightMargin(0.15);
+
+    TH2F h1("Physcial", "Primary baseline (physical pipeline)", 1440, -0.5, 1439.5, 1024, -0.5, 1023.5);
+    h1.SetStats(kFALSE);
+    h1.SetXTitle("Pixel");
+    h1.SetYTitle("Cell");
+    h1.SetZTitle("mV");
+    h1.GetYaxis()->SetTitleOffset(1.2);
+    h1.GetZaxis()->SetTitleOffset(1.2);
+    for (int p=0; p<1440; p++)
+        for (int c=0; c<1024; c++)
+            h1.SetBinContent(p+1, c+1, fOffset[p*1024+c]);
+    h1.Scale(125./fNumOffset/256);
+    h1.DrawCopy("colz");
+
+    pad->cd(2);
+    gPad->SetBorderMode(0);
+    gPad->SetFrameBorderMode(0);
+    gPad->SetRightMargin(0.15);
+
+    TH2F h2("Gain", "Gain measurement (physcial pipeline)", 1440, -0.5, 1439.5, 1024, -0.5, 1023.5);
+    h2.SetStats(kFALSE);
+    h2.SetXTitle("Pixel");
+    h2.SetYTitle("Cell");
+    h2.SetZTitle("mV");
+    h2.GetYaxis()->SetTitleOffset(1.2);
+    h2.GetZaxis()->SetTitleOffset(1.2);
+    for (int p=0; p<1440; p++)
+        for (int c=0; c<1024; c++)
+            h2.SetBinContent(p+1, c+1, fGain[p*1024+c]);
+    h2.Scale(125.*1953125/(fNumOffset*fNumGain)/256/1024);
+    h2.DrawCopy("colz");
+
+    pad->cd(3);
+    gPad->SetBorderMode(0);
+    gPad->SetFrameBorderMode(0);
+    gPad->SetRightMargin(0.15);
+
+    TH2F h3("Logical", "Secondary baseline (logical pipeline)", 1440, -0.5, 1439.5, fRoi, -0.5, fRoi-0.5);
+    h3.SetStats(kFALSE);
+    h3.SetXTitle("Pixel");
+    h3.SetYTitle("Channel");
+    h3.SetZTitle("mV");
+    h3.GetYaxis()->SetTitleOffset(1.2);
+    h3.GetZaxis()->SetTitleOffset(1.2);
+    for (int p=0; p<1440; p++)
+        for (int c=0; c<fRoi; c++)
+            h3.SetBinContent(p+1, c+1, fTrgOff[p*fRoi+c]);
+    h3.Scale(125./(fNumOffset*fNumTrgOff)/256);
+    h3.GetYaxis()->SetRangeUser(4, fRoi-4);
+    h3.DrawCopy("colz");
+
+    pad->cd(4);
+    gPad->SetFrameBorderMode(0);
+}
Index: trunk/Mars/mdrs/MDrsCalibration.h
===================================================================
--- trunk/Mars/mdrs/MDrsCalibration.h	(revision 14922)
+++ trunk/Mars/mdrs/MDrsCalibration.h	(revision 14922)
@@ -0,0 +1,40 @@
+#ifndef MARS_MDrsCalibration
+#define MARS_MDrsCalibration
+
+// -------------------------------------------------------------------
+
+#ifndef MARS_MParContainer
+#include "MParContainer.h"
+#endif
+
+#ifndef MARS_DrsCalib
+#include "DrsCalib.h"
+#endif
+
+class MDrsCalibration : public MParContainer, public DrsCalibration
+{
+public:
+    MDrsCalibration(const char *name=0, const char *title=0)
+    {
+        fName  = name  ? name  : "MDrsCalibration";
+        fTitle = title ? title : "";
+    }
+
+    bool ReadFits(TString str)
+    {
+        gSystem->ExpandPathName(str);
+
+        const std::string msg = ReadFitsImp(str.Data());
+        if (msg.empty())
+            return true;
+
+        *fLog << err << msg << std::endl;
+        return false;
+    }
+
+    void Plot();
+
+    ClassDef(MDrsCalibration, 1)
+};
+
+#endif
Index: trunk/Mars/mdrs/MDrsCalibrationTime.cc
===================================================================
--- trunk/Mars/mdrs/MDrsCalibrationTime.cc	(revision 14922)
+++ trunk/Mars/mdrs/MDrsCalibrationTime.cc	(revision 14922)
@@ -0,0 +1,49 @@
+/* ======================================================================== *\
+!
+! *
+! * This file is part of MARS, the MAGIC Analysis and Reconstruction
+! * Software. It is distributed to you in the hope that it can be a useful
+! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
+! * It is distributed WITHOUT ANY WARRANTY.
+! *
+! * Permission to use, copy, modify and distribute this software and its
+! * documentation for any purpose is hereby granted without fee,
+! * provided that the above copyright notice appear in all copies and
+! * that both that copyright notice and this permission notice appear
+! * in supporting documentation. It is provided "as is" without express
+! * or implied warranty.
+! *
+!
+!
+!   Author(s): Thomas Bretz  2013 <mailto:thomas.bretz@epfl.ch>
+!
+!   Copyright: MAGIC Software Development, 2000-2013
+!
+!
+\* ======================================================================== */
+
+///////////////////////////////////////////////////////////////////////
+//
+// MHDrsCalibration
+//
+///////////////////////////////////////////////////////////////////////
+#include "MDrsCalibrationTime.h"
+
+#include <TH1.h>
+
+ClassImp(MDrsCalibrationTime);
+
+using namespace std;
+
+bool MDrsCalibrationTime::SetDelays(const TH1 &cam)
+{
+    if (cam.GetDimension()!=1)
+        return false;
+
+    fDelays.assign(cam.GetNbinsX(), 0);
+
+    for (int i=0; i<cam.GetNbinsX(); i++)
+        fDelays[i] = cam.GetBinContent(i+1);
+
+    return true;
+}
Index: trunk/Mars/mdrs/MDrsCalibrationTime.h
===================================================================
--- trunk/Mars/mdrs/MDrsCalibrationTime.h	(revision 14922)
+++ trunk/Mars/mdrs/MDrsCalibrationTime.h	(revision 14922)
@@ -0,0 +1,48 @@
+#ifndef MARS_MDrsCalibrationTime
+#define MARS_MDrsCalibrationTime
+
+#include "DrsCalib.h"
+
+class TH1;
+
+class MDrsCalibrationTime : public MParContainer, public DrsCalibrateTime
+{
+    std::vector<double> fDelays;
+
+public:
+    MDrsCalibrationTime(const char *name=0, const char *title=0)
+    {
+        fName = name ? name : "MDrsCalibrationTime";
+        fTitle ="";
+    }
+
+    void InitSize(uint16_t channels, uint16_t samples)
+    {
+        //fDelays.clear();
+        //fDelays.resize(channels);
+
+        DrsCalibrateTime::InitSize(channels, samples);
+    }
+
+    void SetCalibration(const DrsCalibrateTime &cal)
+    {
+        *static_cast<DrsCalibrateTime*>(this) = cal;
+    }
+
+    bool SetDelays(const TH1 &cam);
+
+    double GetOffset(int hw, int spos, float tm) const
+    {
+        return Offset(hw/9, fmod(tm+spos, 1024)) - Offset(hw/9, spos);
+    }
+
+    double GetDelay(int sw) const
+    {
+        return fDelays.size()==0 ? 0 : fDelays[sw];
+    }
+
+    ClassDef(MDrsCalibrationTime, 2) // A list of histograms storing the Fadc spektrum of one pixel
+};
+
+#endif
+
Index: trunk/Mars/mdrs/MHDrsCalibration.cc
===================================================================
--- trunk/Mars/mdrs/MHDrsCalibration.cc	(revision 14922)
+++ trunk/Mars/mdrs/MHDrsCalibration.cc	(revision 14922)
@@ -0,0 +1,360 @@
+/* ======================================================================== *\
+!
+! *
+! * This file is part of MARS, the MAGIC Analysis and Reconstruction
+! * Software. It is distributed to you in the hope that it can be a useful
+! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
+! * It is distributed WITHOUT ANY WARRANTY.
+! *
+! * Permission to use, copy, modify and distribute this software and its
+! * documentation for any purpose is hereby granted without fee,
+! * provided that the above copyright notice appear in all copies and
+! * that both that copyright notice and this permission notice appear
+! * in supporting documentation. It is provided "as is" without express
+! * or implied warranty.
+! *
+!
+!
+!   Author(s): Thomas Bretz 2013 <mailto:thomas.bretz@epfl.ch>
+!
+!   Copyright: MAGIC Software Development, 2000-2013
+!
+!
+\* ======================================================================== */
+
+///////////////////////////////////////////////////////////////////////
+//
+// MHDrsCalibration
+//
+// This class contains a list of MHFadcPix.
+//
+///////////////////////////////////////////////////////////////////////
+#include "MHDrsCalibration.h"
+
+#include <fstream>
+#include <sstream>
+#include <limits.h>
+
+#include "MLog.h"
+#include "MLogManip.h"
+
+#include "MParList.h"
+#include "MGeomCam.h"
+#include "MBinning.h"
+
+#include "MRawEvtData.h"
+#include "MRawRunHeader.h"
+#include "MHCamera.h"
+#include "MDrsCalibration.h"
+
+#include <TH2.h>
+#include <TMath.h>
+
+ClassImp(MHDrsCalibration);
+
+using namespace std;
+
+// --------------------------------------------------------------------------
+//
+//  default constructor
+//  creates an a list of histograms for all pixels and both gain channels
+//
+MHDrsCalibration::MHDrsCalibration(const char *name, const char *title) : fRun(0),
+fEvt(0), fResult(0), fBuffer(1440*1024*6+160*1024*2+4),
+fStep(-1), fScale(0), fNumPixels(0), fNumSamples(0)
+{
+    //
+    // set the name and title of this object
+    //
+    fName  = name  ? name  : "MHDrsCalibration";
+    fTitle = title ? title : "Container for ADC spectra histograms";
+
+    for (int i=1024*1440*2+4; i<1024*1440*3+4; i++)
+        fBuffer[i] = 2000./4096; // Set mean to 0.5
+}
+
+// --------------------------------------------------------------------------
+//
+// To setup the object we get the number of pixels from a MGeomCam object
+// in the Parameter list.
+//
+Bool_t MHDrsCalibration::SetupFill(const MParList *pList)
+{
+    fRun = (MRawRunHeader*)pList->FindObject("MRawRunHeader");
+    if (!fRun)
+    {
+        *fLog << err << "MRawRunHeader not found... aborting." << endl;
+        return kFALSE;
+    }
+
+    switch (++fStep)
+    {
+    case 0:
+        SetTitle("DRS average baseline (physical pipeline);;ADC signal [mV];");
+        break;
+    case 1:
+        SetTitle("DRS average gain (baseline subtracted, physical pipeline);;ADC signal [mV];");
+        break;
+    case 2:
+        SetTitle("DRS average trigger offset (baseline subtracted, logical pipeline);;ADC signal [mV];");
+        break;
+    }
+
+    if (!MHCamEvent::SetupFill(pList))
+        return kFALSE;
+
+    fSum->ResetBit(MHCamera::kProfile);
+
+    fData.Reset();
+
+    fScale = 1;
+
+    *fLog << warn << "WARNING --- oulier detection needed!" << endl;
+
+    return kTRUE;
+}
+
+Bool_t MHDrsCalibration::ReInit(MParList *pList)
+{
+/*    fRun = (MRawRunHeader*)pList->FindObject("MRawRunHeader");
+    if (!fRun)
+    {
+        *fLog << err << "MRawRunHeader not found... aborting." << endl;
+        return kFALSE;
+    }*/
+
+    fEvt = (MRawEvtData*)pList->FindObject("MRawEvtData");
+    if (!fEvt)
+    {
+        *fLog << err << "MRawEvtData not found... aborting." << endl;
+        return kFALSE;
+    }
+
+    if (!fEvt->HasStartCells())
+    {
+        *fLog << err << "MRawEvtData has no start cells stored... aborting." << endl;
+        return kFALSE;
+    }
+
+    // FIXME: check consistency...?
+
+    if (fEvt->GetNumPixels()==0 || fEvt->GetNumSamples()==0)
+    {
+        *fLog << err << "MRawEvtData contains either no pixels or no samples... aborting." << endl;
+        return kFALSE;
+    }
+
+    if (fStep>=3)
+    {
+        *fLog << err << "DRS calibration already finished." << endl;
+        return kFALSE;
+    }
+
+
+    fData.InitSize(fEvt->GetNumPixels(), fEvt->GetNumSamples());
+
+    fResult = (MDrsCalibration*)pList->FindCreateObj("MDrsCalibration");
+    if (!fResult)
+        return kFALSE;
+
+    if (fStep==1 || fStep==2)
+        fScale = fResult->fNumOffset;
+
+    fNumPixels  = fEvt->GetNumPixels();
+    fNumSamples = fEvt->GetNumSamples();
+
+    if (fStep<2 && fNumSamples!=1024)
+    {
+        *fLog << err << "Only 1024 samples are supported for step " << fStep << "... file has " << fNumSamples << endl;
+        return kFALSE;
+    }
+
+    return kTRUE;
+}
+
+// --------------------------------------------------------------------------
+Int_t MHDrsCalibration::Fill(const MParContainer *par, const Stat_t w)
+{
+
+    if (fStep==0)
+    {
+        fData.AddRel(reinterpret_cast<int16_t*>(fEvt->GetSamples()),
+                     reinterpret_cast<int16_t*>(fEvt->GetStartCells()));
+    }
+    if (fStep==1)
+    {
+        fData.AddRel(reinterpret_cast<int16_t*>(fEvt->GetSamples()),
+                     reinterpret_cast<int16_t*>(fEvt->GetStartCells()),
+                     fResult->fOffset.data(),
+                     fResult->fNumOffset);
+    }
+    if (fStep==2)
+    {
+        fData.AddAbs(reinterpret_cast<int16_t*>(fEvt->GetSamples()),
+                     reinterpret_cast<int16_t*>(fEvt->GetStartCells()),
+                     fResult->fOffset.data(),
+                     fResult->fNumOffset);
+    }
+
+    /*
+    if (fStep==3)
+    {
+        fData.AddAbs(reinterpret_cast<int16_t*>(fEvt->GetSamples()),
+                     reinterpret_cast<int16_t*>(fEvt->GetStartCells()),
+                     fResult->fOffset.data(),
+                     fResult->fNumOffset);
+    }*/
+
+    return kTRUE;
+}
+
+void MHDrsCalibration::InitHistogram()
+{
+    if (!fEvt)
+        return;
+
+    // Be carefull: the contents of fData are not cloned!
+    pair<vector<double>,vector<double> > p = fData.GetSampleStats();
+
+    vector<double> &mean = p.first;
+    vector<double> &rms  = p.second;
+
+    if (mean.size()==0)
+        return;
+
+    fSum->Reset();
+
+    for (size_t ch=0; ch<fNumPixels; ch++)
+    {
+        double m = 0;
+        double r = 0;
+        for (size_t i=0; i<fNumSamples; i++)
+        {
+            m += mean[ch*fNumSamples+i];
+            r += rms [ch*fNumSamples+i];
+        }
+
+        fSum->AddBinContent(fEvt->GetPixelIds()[ch]+1, m);
+        fSum->SetBinError(fEvt->GetPixelIds()[ch]+1,   r);
+    }
+
+    fSum->Scale(1./fNumSamples/fScale*2000/4096);  // 0.5mV/ADC count
+    fSum->SetEntries(fData.GetNumEntries());
+    fSum->SetAllUsed();
+}
+
+template<typename T>
+Bool_t MHDrsCalibration::CopyData(vector<T> &dest) const
+{
+    const vector<int64_t> &sum = fData.GetSum();
+    dest.resize(sum.size());
+
+    for (size_t ch=0; ch<fNumPixels; ch++)
+        for (size_t i=0; i<fNumSamples; i++)
+        {
+            if (sum[ch*fNumSamples+i]>UINT_MAX)
+            {
+                *fLog << err << "ERROR - Sum over slices exceeded maximum allowed range." << endl;
+                return kFALSE;
+            }
+            dest[ch*fNumSamples+i] = sum[ch*fNumSamples+i];
+        }
+
+    return kTRUE;
+}
+
+Bool_t MHDrsCalibration::Finalize()
+{
+    if (!fResult)
+        return kTRUE;
+
+    fResult->fRoi   = fNumSamples;
+    fResult->fStep  = fStep;
+    fResult->fNumTm = 0;
+
+    // ==========================================================================
+    if (fStep==0)
+    {
+        fResult->fNumOffset = fData.GetNumEntries();
+        if (!CopyData(fResult->fOffset))
+            return kFALSE;
+
+        //--------------------------------------------
+        for (int i=0; i<1024*1440; i++)
+            fResult->fGain[i] = 4096*fData.GetNumEntries();
+
+        // Scale ADC data from 12bit to 2000mV
+        fData.GetSampleStats(fBuffer.data()+4, 2000./4096);
+        reinterpret_cast<uint32_t*>(fBuffer.data())[1] = fRun->GetRunNumber();
+    }
+
+    // ==========================================================================
+    if (fStep==1)
+    {
+        fResult->fNumGain = fData.GetNumEntries();//*fResult->fNumCellOffset;
+        if (!CopyData(fResult->fGain))
+            return kFALSE;
+
+        //---------------------------------------------
+        // 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;
+        fResult->fNumGain *= 1953125;
+        for (unsigned int i=0; i<fNumPixels*fNumSamples; i++)
+            fResult->fGain[i] *= 1024;
+
+        // Scale ADC data from 12bit to 2000mV
+        fData.GetSampleStats(fBuffer.data()+1024*1440*2+4, 2000./4096/fResult->fNumOffset);//0.5);
+        reinterpret_cast<uint32_t*>(fBuffer.data())[2] = fRun->GetRunNumber();
+    }
+
+    // ==========================================================================
+    if (fStep==2)
+    {
+        fResult->fNumTrgOff = fData.GetNumEntries();//*fResult->fNumCellOffset;
+        if (!CopyData(fResult->fTrgOff))
+            return kFALSE;
+
+        //--------------------------------------------
+        // Scale ADC data from 12bit to 2000mV
+        fData.GetSampleStats(fBuffer.data()+1024*1440*4+4, 2000./4096/fResult->fNumOffset);//0.5);
+        reinterpret_cast<uint32_t*>(fBuffer.data())[0] = fNumSamples;
+        reinterpret_cast<uint32_t*>(fBuffer.data())[3] = fRun->GetRunNumber();
+    }
+
+    // --------------------------------------
+
+    InitHistogram();
+
+    if (fOutputPath.IsNull())
+        return kTRUE;
+
+    const std::string fname(Form("%s/%d_%03d.drs.fits", fOutputPath.Data(),
+                                 fRun->GetRunStart().GetNightAsInt(), fRun->GetFileNumber()));
+
+    const Bool_t exists = !gSystem->AccessPathName(fname.c_str(), kFileExists);
+    if (exists)
+    {
+        *fLog << err << "File '" << fname << "' already exists." << endl;
+        return kFALSE;
+    }
+
+    std::string msg = fResult->WriteFitsImp(fname, fBuffer);
+
+    if (msg.empty())
+    {
+        *fLog << inf << "Wrote DRS calibration file " << fname << endl;
+        return kTRUE;
+    }
+
+    *fLog << err << "Error writing to " << fname << ": " << msg << endl;
+    return kFALSE;
+}
+
+void MHDrsCalibration::Paint(Option_t *o)
+{
+    InitHistogram();
+    MHCamEvent::Paint(o);
+}
Index: trunk/Mars/mdrs/MHDrsCalibration.h
===================================================================
--- trunk/Mars/mdrs/MHDrsCalibration.h	(revision 14922)
+++ trunk/Mars/mdrs/MHDrsCalibration.h	(revision 14922)
@@ -0,0 +1,68 @@
+#ifndef MARS_MHDrsCalibration
+#define MARS_MHDrsCalibration
+
+#ifndef MARS_MHCamEvent
+#include "MHCamEvent.h"
+#endif
+
+#ifndef MARS_DrsCalib
+#include "DrsCalib.h"
+#endif
+
+class MRawRunHeader;
+class MRawEvtData;
+struct MDrsCalibration;
+
+class MHDrsCalibration : public MHCamEvent
+{
+private:
+    MRawRunHeader   *fRun;      //!
+    MRawEvtData     *fEvt;      //!
+    MDrsCalibration *fResult;   //!
+
+    std::vector<float> fBuffer; //! Compilation bufer for writing output files
+    DrsCalibrate       fData;   //!
+
+    Short_t fStep;
+
+    Double_t fScale;
+
+    UInt_t fNumPixels;
+    UInt_t fNumSamples;
+
+    TString fOutputPath;
+
+    void InitHistogram();
+
+    template<typename T>
+        Bool_t CopyData(std::vector<T> &dest) const;
+
+public:
+    MHDrsCalibration(const char *name=NULL, const char *title=NULL);
+
+    Bool_t SetupFill(const MParList *pList);
+    Bool_t ReInit(MParList *);
+    Int_t  Fill(const MParContainer *par, const Stat_t w=1);
+    Bool_t Finalize();
+
+    Bool_t ResetSecondaryBaseline()
+    {
+        if (fStep!=2)
+            return kFALSE;
+
+        for (int i=1024*1440*4+4; i<1440*1024*6+160*1024*2+4; i++)
+            fBuffer[i] = 0;
+
+        fStep=1;
+
+        return kTRUE;
+    }
+
+    void SetOutputPath(const char *path) { fOutputPath = path; }
+
+    void Paint(Option_t *o="");
+
+    ClassDef(MHDrsCalibration, 1) // A list of histograms storing the Fadc spektrum of one pixel
+};
+
+#endif
Index: trunk/Mars/mdrs/MHDrsCalibrationCheck.cc
===================================================================
--- trunk/Mars/mdrs/MHDrsCalibrationCheck.cc	(revision 14922)
+++ trunk/Mars/mdrs/MHDrsCalibrationCheck.cc	(revision 14922)
@@ -0,0 +1,163 @@
+/* ======================================================================== *\
+!
+! *
+! * This file is part of MARS, the MAGIC Analysis and Reconstruction
+! * Software. It is distributed to you in the hope that it can be a useful
+! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
+! * It is distributed WITHOUT ANY WARRANTY.
+! *
+! * Permission to use, copy, modify and distribute this software and its
+! * documentation for any purpose is hereby granted without fee,
+! * provided that the above copyright notice appear in all copies and
+! * that both that copyright notice and this permission notice appear
+! * in supporting documentation. It is provided "as is" without express
+! * or implied warranty.
+! *
+!
+!
+!   Author(s): Thomas Bretz 2012 <mailto:thomas.bretz@epfl.ch>
+!
+!   Copyright: MAGIC Software Development, 2000-2013
+!
+!
+\* ======================================================================== */
+
+///////////////////////////////////////////////////////////////////////
+//
+// MHDrsCalibration
+//
+///////////////////////////////////////////////////////////////////////
+#include "MHDrsCalibrationCheck.h"
+
+#include "MLog.h"
+#include "MLogManip.h"
+
+#include "MParList.h"
+
+#include "MRawRunHeader.h"
+#include "MHCamera.h"
+#include "MPedestalSubtractedEvt.h"
+
+ClassImp(MHDrsCalibrationCheck);
+
+using namespace std;
+
+// --------------------------------------------------------------------------
+//
+//  default constructor
+//  creates an a list of histograms for all pixels and both gain channels
+//
+MHDrsCalibrationCheck::MHDrsCalibrationCheck(const char *name, const char *title) :
+    fEvt(0)
+{
+    //
+    // set the name and title of this object
+    //
+    fName  = name  ? name  : "MHDrsCalibrationCheck";
+    fTitle = title ? title : "Container for ADC spectra histograms";
+}
+
+// --------------------------------------------------------------------------
+//
+// To setup the object we get the number of pixels from a MGeomCam object
+// in the Parameter list.
+//
+Bool_t MHDrsCalibrationCheck::SetupFill(const MParList *pList)
+{
+    SetTitle("Noise (DRS calibration applied);;ADC signal [mV];");
+
+    if (!MHCamEvent::SetupFill(pList))
+        return kFALSE;
+
+    fSum->ResetBit(MHCamera::kProfile);
+
+    *fLog << warn << "WARNING --- oulier detection needed!" << endl;
+
+    return kTRUE;
+}
+
+Bool_t MHDrsCalibrationCheck::ReInit(MParList *pList)
+{
+    MRawRunHeader *h = (MRawRunHeader*)pList->FindObject("MRawRunHeader");
+    if (!h)
+    {
+        *fLog << err << "MRawRunHeader not found... aborting." << endl;
+        return kFALSE;
+    }
+
+    fNumSamples = h->GetNumSamples();
+    fNumPixels  = h->GetNumPixel();
+
+    fEvt = (MPedestalSubtractedEvt*)pList->FindObject("MPedestalSubtractedEvt");
+    if (!fEvt)
+    {
+        *fLog << err << "MPedestalSubtractedEvt not found... aborting." << endl;
+        return kFALSE;
+    }
+
+    fSum1.resize(fNumPixels*fNumSamples);
+    fSum2.resize(fNumPixels*fNumSamples);
+
+    return kTRUE;
+}
+
+// --------------------------------------------------------------------------
+
+Int_t MHDrsCalibrationCheck::Fill(const MParContainer *par, const Stat_t w)
+{
+    for (size_t ch=0; ch<fNumPixels*fNumSamples; ch++)
+    {
+        const double val = fEvt->GetSamples(0)[ch];
+
+        fSum1[ch] += val;
+        fSum2[ch] += val*val;
+    }
+
+    return kTRUE;
+}
+
+
+void MHDrsCalibrationCheck::InitHistogram()
+{
+    if (!fEvt)
+        return;
+
+    fSum->Reset();
+
+    for (size_t ch=0; ch<fNumPixels; ch++)
+    {
+        double m = 0;
+        double r = 0;
+        for (size_t i=0; i<fNumSamples; i++)
+        {
+            const int idx = i + ch*fNumSamples;
+
+            const double avg  = fSum1[idx] / GetNumExecutions();
+            const double avg2 = fSum2[idx] / GetNumExecutions();
+            const double rms  = sqrt(avg2 - avg*avg);
+
+            m += avg;
+            r += rms;
+        }
+
+        fSum->AddBinContent(ch+1, m);
+        fSum->SetBinError(ch+1,   r);
+    }
+
+    fSum->Scale(1./fNumSamples);  // 0.5mV/ADC count
+    fSum->SetEntries(GetNumExecutions());
+    fSum->SetAllUsed();
+}
+
+Bool_t MHDrsCalibrationCheck::Finalize()
+{
+    InitHistogram();
+
+    return kTRUE;
+}
+
+void MHDrsCalibrationCheck::Paint(Option_t *o)
+{
+    InitHistogram();
+    MHCamEvent::Paint(o);
+}
Index: trunk/Mars/mdrs/MHDrsCalibrationCheck.h
===================================================================
--- trunk/Mars/mdrs/MHDrsCalibrationCheck.h	(revision 14922)
+++ trunk/Mars/mdrs/MHDrsCalibrationCheck.h	(revision 14922)
@@ -0,0 +1,37 @@
+#ifndef MARS_MHDrsCalibrationCheck
+#define MARS_MHDrsCalibrationCheck
+
+#ifndef MARS_MHCamEvent
+#include "MHCamEvent.h"
+#endif
+
+class MPedestalSubtractedEvt;
+
+class MHDrsCalibrationCheck : public MHCamEvent
+{
+private:
+    MPedestalSubtractedEvt *fEvt;     //!
+
+    std::vector<double> fSum1;
+    std::vector<double> fSum2;
+
+    UInt_t fNumPixels;
+    UInt_t fNumSamples;
+
+    void InitHistogram();
+
+public:
+    MHDrsCalibrationCheck(const char *name=NULL, const char *title=NULL);
+
+    Bool_t SetupFill(const MParList *pList);
+    Bool_t ReInit(MParList *);
+    Int_t  Fill(const MParContainer *par, const Stat_t w=1);
+    Bool_t Finalize();
+
+    void Paint(Option_t *o="");
+
+    ClassDef(MHDrsCalibrationCheck, 1) // A list of histograms storing the Fadc spektrum of one pixel
+};
+
+#endif
+
Index: trunk/Mars/mdrs/MHDrsCalibrationTime.cc
===================================================================
--- trunk/Mars/mdrs/MHDrsCalibrationTime.cc	(revision 14922)
+++ trunk/Mars/mdrs/MHDrsCalibrationTime.cc	(revision 14922)
@@ -0,0 +1,229 @@
+/* ======================================================================== *\
+!
+! *
+! * This file is part of MARS, the MAGIC Analysis and Reconstruction
+! * Software. It is distributed to you in the hope that it can be a useful
+! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
+! * It is distributed WITHOUT ANY WARRANTY.
+! *
+! * Permission to use, copy, modify and distribute this software and its
+! * documentation for any purpose is hereby granted without fee,
+! * provided that the above copyright notice appear in all copies and
+! * that both that copyright notice and this permission notice appear
+! * in supporting documentation. It is provided "as is" without express
+! * or implied warranty.
+! *
+!
+!
+!   Author(s): Thomas Bretz 2013 <mailto:thomas.bretz@epfl.ch>
+!
+!   Copyright: MAGIC Software Development, 2000-2013
+!
+!
+\* ======================================================================== */
+
+///////////////////////////////////////////////////////////////////////
+//
+// MHDrsCalibrationTime
+//
+///////////////////////////////////////////////////////////////////////
+#include "MHDrsCalibrationTime.h"
+
+#include <TCanvas.h>
+
+#include "MStatusDisplay.h"
+
+#include "MPedestalSubtractedEvt.h"
+
+#include "MParList.h"
+#include "MRawEvtData.h"
+
+#include "MBinning.h"
+
+ClassImp(MHDrsCalibrationTime);
+
+using namespace std;
+
+MHDrsCalibrationTime::MHDrsCalibrationTime(const char *name, const char *title) :
+fRaw(0), fEvt(0), fCal(0)
+
+{
+    //
+    // set the name and title of this object
+    //
+    fName  = name  ? name  : "MHDrsCalibrationTime";
+    fTitle = title ? title : "Container for ADC spectra histograms";
+
+    MBinning bx( 160, -0.5,  159.5);
+    MBinning by(1023, -0.5, 1023.5);
+
+    MH::SetBinning(&fHist, &by, &bx);
+
+    fHist.SetName("Offset");
+    fHist.SetTitle("DRS cell time offset");
+
+    fHist.SetXTitle("Absolute position in pipeline");
+    fHist.SetYTitle("DRS time marker channel");
+    fHist.SetZTitle("\\Delta t / slices");
+
+    fHist.SetStats(kFALSE);
+    fHist.SetContour(99);
+    fHist.SetDirectory(0);
+}
+
+Bool_t MHDrsCalibrationTime::SetupFill(const MParList *pList)
+{
+    /*
+    SetTitle("DRS bla bla;;ADC signal [mV];");
+
+    if (!MHCamEvent::SetupFill(pList))
+        return kFALSE;
+
+    fSum->ResetBit(MHCamera::kProfile);
+    */
+
+
+    fData.Reset();
+
+    return kTRUE;
+}
+
+Bool_t MHDrsCalibrationTime::ReInit(MParList *pList)
+{
+    fRaw = (MRawEvtData*)pList->FindObject("MRawEvtData");
+    if (!fRaw)
+    {
+        *fLog << err << "MRawEvtData not found... aborting." << endl;
+        return kFALSE;
+    }
+
+    if (!fRaw->HasStartCells())
+    {
+        *fLog << err << "MRawEvtData has no start cells stored... aborting." << endl;
+        return kFALSE;
+    }
+
+    if (fRaw->GetNumPixels()==0 || fRaw->GetNumSamples()==0)
+    {
+        *fLog << err << "MRawEvtData contains either no pixels or no samples... aborting." << endl;
+        return kFALSE;
+    }
+
+    fEvt = (MPedestalSubtractedEvt*)pList->FindObject("MPedestalSubtractedEvt");
+    if (!fEvt)
+    {
+        *fLog << err << "MPedestalSubtractedEvt not found... aborting." << endl;
+        return kFALSE;
+    }
+
+    if (fRaw->GetNumSamples()!=1024)
+    {
+        *fLog << err << "Only 1024 samples are supported for the time calibration" << endl;
+        return kFALSE;
+    }
+
+    fCal = (MDrsCalibrationTime*)pList->FindCreateObj("MDrsCalibrationTime");
+    if (!fCal)
+        return kFALSE;
+
+    fData.InitSize(160, 1024);
+
+    return kTRUE;
+}
+
+Int_t MHDrsCalibrationTime::Fill(const MParContainer *par, const Stat_t w)
+{
+    fData.AddT(fEvt->GetSamples(0),
+               reinterpret_cast<int16_t*>(fRaw->GetStartCells()), +1);
+
+    return kTRUE;
+}
+
+void MHDrsCalibrationTime::InitHistogram()
+{
+    DrsCalibrateTime t = fData.GetResult();
+    if (t.fNumEntries==0)
+        return;
+
+    for (int p=0; p<160; p++)
+        for (int s=0; s<1024; s++)
+            fHist.SetBinContent(s+1, p+1, t.fStat[p*t.fNumSamples+s].first);
+}
+
+void MHDrsCalibrationTime::PlotAll()
+{
+    if (!fDisplay)
+        return;
+
+    InitHistogram();
+
+    for (int b=0; b<10; b++)
+    {
+        TCanvas &c = fDisplay->AddTab(Form("B%d", b));
+
+        c.Divide(2,2);
+
+        for (int i=0; i<4; i++)
+        {
+            c.cd(i+1);
+
+            gPad->SetGrid();
+            gPad->SetBorderMode(0);
+            gPad->SetFrameBorderMode(0);
+            gPad->SetRightMargin(0.01);
+
+            const int col[] = { kBlack, kRed, kBlue, kGreen };
+
+            for (int crate=0; crate<4; crate++)
+            {
+                TH1 *h = fHist.ProjectionX(Form("%d-%d-%d", crate, b, i), crate*40+b*4+i+1, crate*40+b*4+i+1);
+                h->SetName(Form("Crate%d", crate));
+                h->SetTitle(Form("Board %d, Chip %d (All four crates)", b, i));
+                h->SetXTitle("Slice");
+                h->SetYTitle("\\Delta t / slices");
+                h->SetMinimum(-10);
+                h->SetMaximum(10);
+                h->SetStats(kFALSE);
+                h->SetDirectory(0);
+                h->SetMarkerStyle(kFullDotMedium);
+                h->SetMarkerColor(col[crate]);
+                h->SetLineColor(col[crate]);
+                h->DrawCopy(crate==0 ? "hist p" : "hist P same");
+            }
+        }
+    }
+
+    // 4 crates
+    // 10 boards
+    // 4 chips
+}
+
+void MHDrsCalibrationTime::Draw(Option_t *o)
+{
+    TVirtualPad *pad = gPad ? gPad : MakeDefCanvas(this);
+
+    AppendPad("");
+
+    pad->Divide(1,1);
+
+    pad->cd(1);
+
+    gPad->SetBorderMode(0);
+    gPad->SetFrameBorderMode(0);
+
+    fHist.Draw("colz");
+}
+
+
+void MHDrsCalibrationTime::Paint(Option_t *o)
+{
+    MH::SetPalette();
+    InitHistogram();
+}
+
+Bool_t MHDrsCalibrationTime::Finalize()
+{
+    //    InitHistogram();
+    fCal->SetCalibration(fData.GetResult());
+    return kTRUE;
+}
Index: trunk/Mars/mdrs/MHDrsCalibrationTime.h
===================================================================
--- trunk/Mars/mdrs/MHDrsCalibrationTime.h	(revision 14922)
+++ trunk/Mars/mdrs/MHDrsCalibrationTime.h	(revision 14922)
@@ -0,0 +1,51 @@
+#ifndef MARS_MHDrsCalibrationTime
+#define MARS_MHDrsCalibrationTime
+
+#ifndef MARS_DrsCalibrationTime
+#include "MDrsCalibrationTime.h"
+#endif
+
+#ifndef MARS_MH
+#include "MH.h"
+#endif
+
+class MRawEvtData;
+class MDrsCalibrationTime;
+class MPedestalSubtractedEvt;
+
+class MHDrsCalibrationTime : public MH
+{
+private:
+    TH2F fHist;
+
+    MRawEvtData            *fRaw;     //!
+    MPedestalSubtractedEvt *fEvt;     //!
+    MDrsCalibrationTime    *fCal;     //!
+
+    MDrsCalibrationTime fData; //
+
+    void InitHistogram();
+
+    template<typename T>
+        Bool_t CopyData(std::vector<T> &dest) const;
+
+public:
+    MHDrsCalibrationTime(const char *name=NULL, const char *title=NULL);
+
+    Bool_t SetupFill(const MParList *pList);
+    Bool_t ReInit(MParList *);
+    Int_t  Fill(const MParContainer *par, const Stat_t w=1);
+    Bool_t Finalize();
+
+    void Draw(Option_t *o="");
+    void Paint(Option_t *o="");
+
+    void PlotAll();
+
+    //const MDrsCalibration &GetCalib() const { return fData; }
+
+    ClassDef(MHDrsCalibrationTime, 1) // A list of histograms storing the Fadc spektrum of one pixel
+};
+
+#endif
+
Index: trunk/Mars/mdrs/Makefile
===================================================================
--- trunk/Mars/mdrs/Makefile	(revision 14922)
+++ trunk/Mars/mdrs/Makefile	(revision 14922)
@@ -0,0 +1,39 @@
+##################################################################
+#
+#   makefile
+# 
+#   for the MARS software
+#
+##################################################################
+include ../Makefile.conf.general
+include ../Makefile.conf.$(OSTYPE)
+
+#------------------------------------------------------------------------------
+
+#
+# Handling name of the Root Dictionary Files
+#
+CINT  = Drs
+
+#
+#  connect the include files defined in the config.mk file
+#
+INCLUDES = \
+	-I. -I../mbase -I../mgeom -I../mbadpixels -I../mraw -I../msignal \
+	-I../mhbase -I../mcore -I../mhist -I../mgui -I../mpedestal
+
+SRCFILES = MCalibrateDrsTimes.cc \
+	   MDrsCalibApply.cc \
+	   MHDrsCalibration.cc \
+	   MDrsCalibration.cc \
+	   MDrsCalibrationTime.cc \
+	   MHDrsCalibrationCheck.cc \
+	   MHDrsCalibrationTime.cc
+
+############################################################
+
+all: $(OBJS)
+
+include ../Makefile.rules
+
+mrproper:	clean rmbak
