Index: trunk/MagicSoft/Mars/mpedestal/MPedestalSubtract.cc
===================================================================
--- trunk/MagicSoft/Mars/mpedestal/MPedestalSubtract.cc	(revision 8153)
+++ trunk/MagicSoft/Mars/mpedestal/MPedestalSubtract.cc	(revision 8153)
@@ -0,0 +1,174 @@
+/* ======================================================================== *\
+!
+! *
+! * 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, 10/2006 <mailto:tbretz@astro.uni-wuerzburg.de>
+!
+!   Copyright: MAGIC Software Development, 2000-2006
+!
+!
+\* ======================================================================== */
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//   MPedestalSubtract
+//
+//  This class merges hi- and lo-gain samples into one array and
+//  subtracts the pedestal (including the AB-offset) from the
+//  data and stores the result in MPedestalSubtractedEvt.
+//
+// Input Containers:
+//   MRawEvtData
+//   MRawRunHeader
+//   MPedestalCam
+//
+// Output Containers:
+//   MPedestalSubtractedEvt
+//
+//////////////////////////////////////////////////////////////////////////////
+#include "MPedestalSubtract.h"
+
+#include "MLog.h"
+#include "MLogManip.h"
+
+#include "MParList.h"
+
+#include "MArrayB.h"
+
+#include "MRawEvtData.h"
+#include "MRawEvtPixelIter.h"
+
+#include "MPedestalCam.h"
+#include "MPedestalPix.h"
+
+#include "MPedestalSubtractedEvt.h"
+
+#include "MExtractedSignalCam.h"
+#include "MExtractedSignalPix.h"
+
+ClassImp(MPedestalSubtract);
+
+using namespace std;
+
+const TString MPedestalSubtract::fgNamePedestalCam           = "MPedestalCam";
+const TString MPedestalSubtract::fgNamePedestalSubtractedEvt = "MPedestalSubtractedEvt";
+
+// --------------------------------------------------------------------------
+//
+// Default constructor. 
+//
+MPedestalSubtract::MPedestalSubtract(const char *name, const char *title)
+    : fRawEvt(NULL), fPedestals(NULL), fSignal(NULL)
+{
+    fName  = name  ? name  : "MPedestalSubtract";
+    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:
+//
+//  - MPedestalSubtractedEvt
+//
+Int_t MPedestalSubtract::PreProcess(MParList *pList)
+{
+    fRawEvt = (MRawEvtData*)pList->FindObject(AddSerialNumber("MRawEvtData"));
+    if (!fRawEvt)
+    {
+        *fLog << err << AddSerialNumber("MRawEvtData") << " not found... aborting." << endl;
+        return kFALSE;
+    }
+
+    fSignal = (MPedestalSubtractedEvt*)pList->FindCreateObj("MPedestalSubtractedEvt");//, AddSerialNumber(fNamePedestalSubtractedEvt));
+    if (!fSignal)
+        return kFALSE;
+
+    if (fPedestals || fNamePedestalCam.IsNull())
+        return kTRUE;
+
+    fPedestals = (MPedestalCam*)pList->FindObject(AddSerialNumber(fNamePedestalCam), "MPedestalCam");
+    if (!fPedestals)
+    {
+        *fLog << err << AddSerialNumber(fNamePedestalCam) << " [MPedestalCam] not found... aborting" << endl;
+        return kFALSE;
+    }
+
+    return kTRUE;
+}
+
+// --------------------------------------------------------------------------
+//
+//
+Int_t MPedestalSubtract::Process()
+{
+    // Total number of samples
+    const Int_t numh = fRawEvt->GetNumHiGainSamples();
+    const Int_t numl = fRawEvt->GetNumLoGainSamples();
+
+    // initialize fSignal
+    fSignal->InitSamples(fRawEvt->GetNumPixels(), numh+numl);
+
+    // iterate over all pixels
+    MRawEvtPixelIter pixel(fRawEvt);
+    while (pixel.Next())
+    {
+        // Get index ofthis pixel
+        const Int_t pixidx = pixel.GetPixelId();
+
+        // Get pointer were to store merged raw data
+        Byte_t *sample = fSignal->GetSamplesRaw(pixidx);
+
+        // copy hi- and lo-gains samples together
+        memcpy(sample,      pixel.GetHiGainSamples(), numh);
+        memcpy(sample+numh, pixel.GetLoGainSamples(), numl);
+
+        // if no pedestals are given we are finished
+        if (!fPedestals)
+            continue;
+
+        // get pedestal information for this pixel
+        const MPedestalPix &pedpix = (*fPedestals)[pixidx];
+
+        // pedestal information
+        const Int_t   ab  = pixel.HasABFlag() ? 1 : 0;
+        const Float_t ped = pedpix.GetPedestal();
+
+        // start of destination array, end of hi-gain destination array
+        // and start of hi-gain samples
+        Float_t *beg = fSignal->GetSamples(pixidx);
+        Float_t *end = beg + fSignal->GetNumSamples();
+
+        // determine with which pedestal (+/- AB offset) to start
+        const Bool_t  swap    = (ab&1)==1;
+        const Float_t offh    = swap ? -pedpix.GetPedestalABoffset() : pedpix.GetPedestalABoffset();
+        const Float_t mean[2] = { ped + offh, ped - offh };
+
+        const Byte_t *src = sample;
+
+        // Copy hi-gains into array and substract pedestal
+        // FIXME: Shell we really subtract the pedestal from saturating slices???
+        for (Float_t *ptr=beg; ptr<end; ptr++)
+            *ptr = (Float_t)*src++ - mean[(ptr-beg)&1];
+    }
+
+    return kTRUE;
+}
