Index: trunk/MagicSoft/Mars/Changelog
===================================================================
--- trunk/MagicSoft/Mars/Changelog	(revision 3572)
+++ trunk/MagicSoft/Mars/Changelog	(revision 3573)
@@ -99,5 +99,6 @@
      
    * mdata/MDataArray.[h,cc], mdata/MDataElement.h,
-     mdata/MDataList.[h,cc], mdata/MDataMember.h:
+     mdata/MDataList.[h,cc], mdata/MDataMember.h,
+     mfbase/MFDataMember.[h,cc], mfbase/MFilterList.[h,cc]:
      - added SetVariables
 
@@ -110,5 +111,17 @@
      - added support for an index
      - added SetVariables
-     
+
+   * mfbase/MF.[h,cc]:
+     - removed support for {}. This case is now detected
+       automatically
+     - added SetVariables
+     - added support for expressiond like 
+       "MHillas.fLength<2*MHillas.fWidth"
+
+   * mfbase/MFDataChain.[h,cc]:
+     - added fCond data member
+     - addednew constructor to support fCond
+     - added support for new condition type
+     - adapted Print and GetRule
 
 
Index: trunk/MagicSoft/Mars/NEWS
===================================================================
--- trunk/MagicSoft/Mars/NEWS	(revision 3572)
+++ trunk/MagicSoft/Mars/NEWS	(revision 3573)
@@ -1,4 +1,12 @@
                                                                -*-*- END -*-*-
  *** Version <cvs>
+  
+   - added support in MF for expressiond like 
+     "MHillas.fWidth<2*MHillas.fLength"
+
+   - MDataChain is now able to support variables like [0], [1], ...
+     which can be used in fit functions as parameters. The interface
+     is implemented through the new virtual function 
+     MParContainer::SetVariables
 
    - added new class MArrivalTimeCam/MArrivalTimePix:
Index: trunk/MagicSoft/Mars/mfbase/MF.cc
===================================================================
--- trunk/MagicSoft/Mars/mfbase/MF.cc	(revision 3572)
+++ trunk/MagicSoft/Mars/mfbase/MF.cc	(revision 3573)
@@ -71,9 +71,4 @@
 //
 //
-//  If you intend to use Data Chains in filters enclose the chains in
-//  this {}-parenthesis, eg.
-//
-//   "{MHillas.fSize*MHillas.fWidth}<0.5"
-//
 // FIXME: The possibility to use also complete filters is missing.
 //        Maybe we can use gInterpreter->Calc("") for this.
@@ -166,104 +161,44 @@
 MFilter *MF::ParseRule(TString &txt, MFilter *filter0, Int_t level) const
 {
-    TString text;
-
-    Bool_t isrule = kFALSE;
-
-    if (txt[0]=='{')
-    {
-        //
-        // Search for the corresponding bracket
-        //
-        Int_t first=1;
-        for (int cnt=0; first<txt.Length(); first++)
-        {
-            if (txt[first]=='{')
-                cnt++;
-            if (txt[first]=='}')
-                cnt--;
-
-            if (cnt==-1)
-                break;
-        }
-
-        if (first==txt.Length())
-        {
-            *fLog << err << dbginf << "Syntax Error: '}' missing." << endl;
-            return NULL;
-        }
-
-        //
-        // Make a copy of the 'interieur' and delete the substringä
-        // including the brackets
-        //
-        TString sub = txt(1, first-1);
-        txt.Remove(0, first+1);
-
-        text=sub;
-        isrule = kTRUE;
-    }
-    else
-    {
-        int i = IsAlNum(txt);
-
-        if (i==0)
-        {
-            *fLog << err << dbginf << "Syntax Error: Name of data member missing in '" << txt << "'" << endl;
-            return NULL;
-        }
-
-        text = txt(0, i);
-
-        txt.Remove(0, i);
-    }
-
-    txt = txt.Strip(TString::kBoth);
-
-    if (txt.IsNull())
-    {
-        *fLog << err << dbginf << "Syntax Error: No conditional in '" << text << "'" << endl;
+    // For backward compatibility
+    txt.ReplaceAll("{", "(");
+    txt.ReplaceAll("}", ")");
+
+    const Int_t fg = txt.First('>');
+    const Int_t lg = txt.First('>');
+    const Int_t fl = txt.First('<');
+    const Int_t ll = txt.First('<');
+
+    if (fg<0 && fl<0)
+    {
+        *fLog << err << dbginf << "Syntax Error: No coditional sign found in " << txt << endl;
         return NULL;
     }
-
-    char c;
-    switch (txt[0])
-    {
-    case '>':
-    case '<':
-        c = txt[0];
-        txt.Remove(0, 1);
-        break;
-
-    default:
-        *fLog << err << dbginf << "Syntax Error: Conditional '" << txt[0] << "' unknown." << endl;
+    if (fg>=0 && fl>=0)
+    {
+        *fLog << err << dbginf << "Syntax Error: Two coditional signs found in " << txt << endl;
+        *fLog << "Currently you have to enclose all conditions in brackets, like: \"(x<y) && (z<5)\"" << endl;
         return NULL;
     }
-
-    char *end;
-    Double_t num = strtod(txt.Data(), &end);
-    if (!end || txt.Data()==end)
-    {
-        *fLog << err << dbginf << "Error trying to convert '" << txt << "' to value." << endl;
+    if (fg!=lg || fl!=ll)
+    {
+        *fLog << err << dbginf << "Syntax Error: Coditional sign found twice " << txt << endl;
         return NULL;
     }
 
-    txt.Remove(0, end-txt.Data());
-
-    MFilter *newfilter;
-    if (isrule)
-    {
-        Int_t lvl = gLog.GetDebugLevel();
-        gLog.SetDebugLevel(1);
-        newfilter = new MFDataChain(text.Data(), c, num);
-        newfilter->SetName(Form("Chain%02d%c%f", level, c, num));
-        gLog.SetDebugLevel(lvl);
-    }
-    else
-    {
-        newfilter = new MFDataMember(text.Data(), c, num);
-        newfilter->SetName(Form("%s%c%f", text.Data(), c, num));
-    }
-
-    return newfilter;
+    const Int_t cond = fg<0 ? fl : fg;
+
+    const TString rule1 = txt(0, cond);
+    const TString rule2 = txt(cond+1, txt.Length());
+
+    Int_t lvl = gLog.GetDebugLevel();
+    gLog.SetDebugLevel(1);
+    MFilter *f = new MFDataChain(rule1.Data(), txt[cond], rule2.Data());
+    f->SetName(Form("Chain%02d%c", level, txt[cond]));
+    gLog.SetDebugLevel(lvl);
+
+    txt = "";
+
+    return f;
 }
 // --------------------------------------------------------------------------
Index: trunk/MagicSoft/Mars/mfbase/MF.h
===================================================================
--- trunk/MagicSoft/Mars/mfbase/MF.h	(revision 3572)
+++ trunk/MagicSoft/Mars/mfbase/MF.h	(revision 3573)
@@ -23,4 +23,6 @@
     MFilter *fF; // Filter
 
+    Int_t IsRule(TString &txt, TString &rule) const;
+    Int_t IsVal(const TString &txt) const;
     Int_t IsAlNum(TString txt) const;
 
@@ -43,4 +45,6 @@
     void Print(Option_t *opt="") const;
 
+    void SetVariables(const TArrayD &arr) { if (fF) fF->SetVariables(arr); }
+
     ClassDef(MF, 0) // A Filter for cuts in any data member
 };
Index: trunk/MagicSoft/Mars/mfbase/MFDataChain.cc
===================================================================
--- trunk/MagicSoft/Mars/mfbase/MFDataChain.cc	(revision 3572)
+++ trunk/MagicSoft/Mars/mfbase/MFDataChain.cc	(revision 3573)
@@ -40,4 +40,5 @@
 // For example:
 //   MFDataChain filter("sqr(MHillas.fLength)", '<', 150);
+//   MFDataChain filter("MHillas.fLength", '<', "MHillas.fWidth");
 //
 /////////////////////////////////////////////////////////////////////////////
@@ -50,4 +51,6 @@
 #include "MParList.h"
 
+#include "MDataValue.h"
+
 #include "MLog.h"
 #include "MLogManip.h"
@@ -57,9 +60,16 @@
 using namespace std;
 
+MFDataChain::MFDataChain(const char *name, const char *title)
+    : fCond(0)
+{
+    fName  = name  ? name  : "MFDataChain";
+    fTitle = title ? title : "Filter using any data member of a class";
+}
+
 // --------------------------------------------------------------------------
 //
-MFDataChain::MFDataChain(const char *member, const char type, const Double_t val,
+MFDataChain::MFDataChain(const char *rule, const char type, const Double_t val,
                          const char *name, const char *title)
-    : fData(member), fValue(val)
+    : fData(rule), fCond(new MDataValue(val))
 {
     fName  = name  ? name  : "MFDataChain";
@@ -74,9 +84,35 @@
 }
 
+MFDataChain::MFDataChain(const char *rule, const char type, const char *cond,
+                         const char *name, const char *title)
+    : fData(rule), fCond(new MDataChain(cond))
+{
+    fName  = name  ? name  : "MFDataChain";
+    fTitle = title ? title : "Filter using any data member of a class";
+
+    //AddToBranchList(member);
+
+    fFilterType = (type=='<' ? kELowerThan : kEGreaterThan);
+
+    if (type!='<' && type!='>')
+        *fLog << warn << dbginf << "Warning: Neither '<' nor '>' specified... using '>'." << endl;
+}
+
+MFDataChain::~MFDataChain()
+{
+    if (fCond)
+        delete fCond;
+}
+
 // --------------------------------------------------------------------------
 //
 Int_t MFDataChain::PreProcess(MParList *plist)
 {
-    return fData.PreProcess(plist);
+    if (!fCond)
+    {
+        *fLog << "No condition available - don't call default constructor!" << endl;
+        return kFALSE;
+    }
+    return fData.PreProcess(plist) && fCond->PreProcess(plist);
 }
 
@@ -85,11 +121,14 @@
 Int_t MFDataChain::Process()
 {
+    const Double_t data = fData.GetValue();
+    const Double_t cond = fCond->GetValue();
+
     switch (fFilterType)
     {
     case kELowerThan:
-        fResult = (fData.GetValue() < fValue);
+        fResult = (data < cond);
         return kTRUE;
     case kEGreaterThan:
-        fResult = (fData.GetValue() > fValue);
+        fResult = (data > cond);
         return kTRUE;
     }
@@ -108,19 +147,24 @@
     out << fData.GetRule() << "\", '";
     out << (fFilterType==kELowerThan?"<":">");
-    out << "', " << fValue << ");" << endl;
+    out << "', ";
+
+    if (fCond->InheritsFrom(MDataValue::Class()))
+        out << ((MDataValue*)fCond)->GetValue();
+    else
+        out << "\"" << fCond->GetRule() << "\"";
+
+    out << ");" << endl;
 }
 
 TString MFDataChain::GetRule() const
 {
-    TString ret = "{";
+    TString ret;// = "{";
     ret += fData.GetRule();
-    ret += "}";
+    //ret += "}";
     ret += fFilterType==kELowerThan?"<":">";
 
     TString str;
-    str += fValue;
-
+    str += fCond->GetRule();
     ret += str.Strip(TString::kBoth);
     return ret;
 }
-
Index: trunk/MagicSoft/Mars/mfbase/MFDataChain.h
===================================================================
--- trunk/MagicSoft/Mars/mfbase/MFDataChain.h	(revision 3572)
+++ trunk/MagicSoft/Mars/mfbase/MFDataChain.h	(revision 3573)
@@ -21,4 +21,5 @@
 private:
     MDataChain fData;
+    MData     *fCond;
 
     typedef enum { kELowerThan, kEGreaterThan } FilterType_t;
@@ -26,5 +27,4 @@
 
     Bool_t  fResult;           //!
-    Double_t fValue;
 
     void StreamPrimitive(ofstream &out) const;
@@ -34,6 +34,10 @@
 
 public:
-    MFDataChain(const char *member, const char type, const Double_t val,
+    MFDataChain(const char *name=NULL, const char *title=NULL);
+    MFDataChain(const char *rule, const char type, const Double_t val,
                 const char *name=NULL, const char *title=NULL);
+    MFDataChain(const char *rule, const char type, const char *cond,
+                const char *name=NULL, const char *title=NULL);
+    ~MFDataChain();
 
     Bool_t IsExpressionTrue() const { return fResult; }
@@ -42,4 +46,11 @@
     TString GetRule() const;
 
+    void SetVariables(const TArrayD &arr)
+    {
+        fData.SetVariables(arr);
+        if (fCond)
+            fCond->SetVariables(arr);
+    }
+
     ClassDef(MFDataChain, 1) // A Filter for cuts in any data member
 };
Index: trunk/MagicSoft/Mars/mfbase/MFDataMember.cc
===================================================================
--- trunk/MagicSoft/Mars/mfbase/MFDataMember.cc	(revision 3572)
+++ trunk/MagicSoft/Mars/mfbase/MFDataMember.cc	(revision 3573)
@@ -167,3 +167,2 @@
     return ret+str.Strip(TString::kBoth);
 }
-
Index: trunk/MagicSoft/Mars/mfbase/MFDataMember.h
===================================================================
--- trunk/MagicSoft/Mars/mfbase/MFDataMember.h	(revision 3572)
+++ trunk/MagicSoft/Mars/mfbase/MFDataMember.h	(revision 3573)
@@ -39,4 +39,6 @@
     TString GetRule() const;
 
+    void SetVariables(const TArrayD &arr) { fData.SetVariables(arr); }
+
     ClassDef(MFDataMember, 1) // A Filter for cuts in any data member
 };
Index: trunk/MagicSoft/Mars/mfbase/MFilterList.cc
===================================================================
--- trunk/MagicSoft/Mars/mfbase/MFilterList.cc	(revision 3572)
+++ trunk/MagicSoft/Mars/mfbase/MFilterList.cc	(revision 3573)
@@ -379,2 +379,7 @@
     return ret+")";
 }
+
+void MFilterList::SetVariables(const TArrayD &arr)
+{
+    fFilters.ForEach(MFilter, SetVariables)(arr);
+}
Index: trunk/MagicSoft/Mars/mfbase/MFilterList.h
===================================================================
--- trunk/MagicSoft/Mars/mfbase/MFilterList.h	(revision 3572)
+++ trunk/MagicSoft/Mars/mfbase/MFilterList.h	(revision 3573)
@@ -53,4 +53,6 @@
     Int_t PostProcess();
 
+    void SetVariables(const TArrayD &arr);
+
     ClassDef(MFilterList, 1)		// List to combine several filters logically
 };
