Index: trunk/Mars/manalysis/MSoftwareTrigger.cc
===================================================================
--- trunk/Mars/manalysis/MSoftwareTrigger.cc	(revision 18476)
+++ trunk/Mars/manalysis/MSoftwareTrigger.cc	(revision 18476)
@@ -0,0 +1,192 @@
+/* ======================================================================== *\
+!
+! *
+! * 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, 2016 <mailto:tbretz@physik.rwth-aachen.de>
+!
+!   Copyright: MAGIC Software Development, 2016
+!
+!
+\* ======================================================================== */
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//   MSoftwareTrigger
+//
+//////////////////////////////////////////////////////////////////////////////
+#include "MSoftwareTrigger.h"
+
+#include <algorithm>
+
+#include "MLog.h"
+#include "MLogManip.h"
+
+#include "MParList.h"
+
+#include "MParameters.h"
+#include "MRawEvtData.h"
+#include "MPedestalSubtractedEvt.h"
+
+ClassImp(MSoftwareTrigger);
+
+using namespace std;
+
+// --------------------------------------------------------------------------
+//
+// Default constructor. 
+//
+MSoftwareTrigger::MSoftwareTrigger(const char *name, const char *title)
+    : fRawEvt(0), fSignal(0), fTriggerSignal(0), fTriggerBaseline(0)
+{
+    fName  = name  ? name  : "MSoftwareTrigger";
+    fTitle = title ? title : "Calculate the FACT trigger in software";
+}
+
+// --------------------------------------------------------------------------
+//
+Int_t MSoftwareTrigger::PreProcess(MParList *pList)
+{
+    fRawEvt = (MRawEvtData*)pList->FindObject("MRawEvtData");//, AddSerialNumber(fNamePedestalSubtractedEvt));
+    if (!fRawEvt)
+    {
+        *fLog << err << "MRawEvtData not found... aborting." << endl;
+        return kFALSE;
+    }
+
+    fSignal = (MPedestalSubtractedEvt*)pList->FindObject("MPedestalSubtractedEvt");//, AddSerialNumber(fNamePedestalSubtractedEvt));
+    if (!fSignal)
+    {
+        *fLog << err << "MPedestalSubtractedEvt not found... aborting." << endl;
+        return kFALSE;
+    }
+
+    fTriggerSignal = (MParameterD*)pList->FindCreateObj("MParameterD","SoftwareTriggerSignal");
+    if (!fTriggerSignal)
+        return kFALSE;
+
+    fTriggerBaseline = (MParameterD*)pList->FindCreateObj("MParameterD","SoftwareTriggerBaseline");
+    if (!fTriggerBaseline)
+        return kFALSE;
+
+    *fLog << flush << inf;
+    return kTRUE;
+}
+
+// --------------------------------------------------------------------------
+//
+Bool_t MSoftwareTrigger::ReInit(MParList *pList)
+{
+    return kTRUE;
+}
+
+// --------------------------------------------------------------------------
+//
+Int_t MSoftwareTrigger::Process()
+{
+    const UShort_t *idx = fRawEvt->GetPixelIds();
+
+    const int beg =  10;
+    const int end = std::min(UInt_t(200), fSignal->GetNumSamples());
+    const int num = end-beg;
+
+    MArrayF buf(160*num);
+
+    for (int hw=0; hw<1440; hw++)
+    {
+        // dead pixels
+        if (hw==927 || hw==80 || hw==873)                   // 3
+            continue;
+        // crazy pixels
+        if (hw==863 || hw==297 || hw==868)                  // 3
+            continue;
+        // broken DRS board
+        if (hw>=720 && hw<=728)                             // 9
+            continue;
+        // broken/suspicious bias channels
+        if ((hw>=171 && hw<=174) || (hw>=184 && hw<=188))   // 9
+            continue;
+
+        const UInt_t sw = idx[hw];
+
+        const Float_t *raw = fSignal->GetSamples(sw);
+
+        Float_t *sum = buf.GetArray()+(hw/9)*num;
+
+        for (const Float_t *ptr=raw+beg; ptr<raw+end; ptr++, sum++)
+            *sum += *ptr;
+    }
+
+    // apply correction factor for patches
+    // 927/9, 80/9, 873/9, 863/9, 297/9, 868/9
+
+    const int excl[] = { 8, 33, 95, 96, 97, 103, -1};
+    for (const int *e=excl; *e>=0; e++)
+    {
+        Float_t *raw = buf.GetArray() + *e * num;
+        for (Float_t *ptr=raw; ptr<raw+num; ptr++)
+            *ptr *= 1.125; // 9/8
+    }
+    {
+        Float_t *raw = buf.GetArray() + 19 * num;   // 171-174
+        for (Float_t *ptr=raw; ptr<raw+num; ptr++)
+            *ptr *= 1.8;   // 9/5 // 5 channels left
+    }
+    {
+        Float_t *raw = buf.GetArray() + 20 * num;   // 184-188
+        for (Float_t *ptr=raw; ptr<raw+num; ptr++)
+            *ptr *= 2.25;  // 9/4 // 4 channels left
+    }
+
+
+    Float_t max = 0;
+    double avg = 0;
+
+    const UInt_t nsum = buf.GetSize();
+    for (Float_t *sum=buf.GetArray(); sum<sum+nsum; sum+=num)
+    {
+        int idx = 0;
+        Float_t v[4] = { 0, 0, 0, 0 };
+
+        for (Float_t *ptr=sum+20; ptr<sum+num; ptr++)
+        {
+            *ptr -= 0.6 * ptr[-20];
+            avg += *ptr;
+            v[idx++%4] = *ptr;
+
+            const Float_t min = *std::min_element(v, v+4);
+            if (min>max)
+                max = min;
+        }
+    }
+
+    avg /= num*(1440-9);  // excluding the 0's from the broken DRS board
+
+    fTriggerSignal->SetVal(max);
+    fTriggerSignal->SetReadyToSave();
+
+    fTriggerBaseline->SetVal(avg);
+    fTriggerBaseline->SetReadyToSave();
+
+    return kTRUE;
+}
+
+// --------------------------------------------------------------------------
+//
+Int_t MSoftwareTrigger::ReadEnv(const TEnv &env, TString prefix, Bool_t print)
+{
+    return kTRUE;
+}
+
Index: trunk/Mars/manalysis/MSoftwareTrigger.h
===================================================================
--- trunk/Mars/manalysis/MSoftwareTrigger.h	(revision 18476)
+++ trunk/Mars/manalysis/MSoftwareTrigger.h	(revision 18476)
@@ -0,0 +1,33 @@
+#ifndef MARS_MSoftwareTrigger
+#define MARS_MSoftwareTrigger
+
+#ifndef MARS_MTask
+#include "MTask.h"
+#endif
+
+class MRawEvtData;
+class MParameterD;
+class MPedestalSubtractedEvt;
+
+class MSoftwareTrigger : public MTask
+{
+private:
+    MRawEvtData *fRawEvt;
+    MPedestalSubtractedEvt *fSignal;
+    MParameterD *fTriggerSignal;
+    MParameterD *fTriggerBaseline;
+
+    Int_t  PreProcess(MParList *pList);
+    Bool_t ReInit(MParList *pList);
+    Int_t  Process();
+    Int_t  ReadEnv(const TEnv &env, TString prefix, Bool_t print);
+
+public:
+    MSoftwareTrigger(const char *name=NULL, const char *title=NULL);
+
+    virtual Bool_t InitArrays(Int_t) { return kTRUE; }
+
+    ClassDef(MSoftwareTrigger, 0)   // Time And Charge Extractor Base Class
+};
+
+#endif
