Index: trunk/MagicSoft/Mars/Changelog
===================================================================
--- trunk/MagicSoft/Mars/Changelog	(revision 5910)
+++ trunk/MagicSoft/Mars/Changelog	(revision 5911)
@@ -20,4 +20,26 @@
 
                                                  -*-*- END OF LINE -*-*-
+
+ 2005/01/20 Thomas Bretz
+
+   * mbase/MContinue.[h,cc]:
+     - added ReadEnv member function to support resource files
+
+   * mbase/MEvtLoop.[h,cc]:
+     - added a second arguemtn to reading of the resource file by name
+     - added some checks when reding the resource file and the
+       parameter list hasn't been setup
+
+   * mbase/MParList.cc:
+     - removed an obsolete output from ReadEnv
+
+   * mfbase/MF.[h,cc]:
+     - added ReadEnv member function to support resource files
+     - added kAllowEpty flag to support skipping by resource files
+
+   * mfbase/MFilterList.cc:
+     - added a comment
+
+
 
  2005/01/19 Thomas Bretz
Index: trunk/MagicSoft/Mars/mbase/MEvtLoop.cc
===================================================================
--- trunk/MagicSoft/Mars/mbase/MEvtLoop.cc	(revision 5910)
+++ trunk/MagicSoft/Mars/mbase/MEvtLoop.cc	(revision 5911)
@@ -972,4 +972,10 @@
     fLog->ReadEnv(env, prefix, print);
 
+    if (!fParList)
+    {
+        *fLog << warn << "WARNING - No parameter list to propagate resources to." << endl;
+        return kTRUE;
+    }
+
     if (fParList->ReadEnv(env, prefix, print)==kERROR)
     {
@@ -986,5 +992,5 @@
 // If 'config=0' kTRUE is returned.
 //
-Bool_t MEvtLoop::ReadEnv(const char *config)
+Bool_t MEvtLoop::ReadEnv(const char *config, Bool_t print)
 {
     if (!config)
@@ -998,5 +1004,5 @@
     }
 
-    return ReadEnv(TEnv(config));
+    return ReadEnv(TEnv(config), "", print);
 }
 
@@ -1033,4 +1039,13 @@
     *fLog << inf << "Writing resources: " << prefix /*TEnv::fRcName << " to " << env.GetRcName()*/ << endl;
 
+    fLog->WriteEnv(env, prefix, print);
+
+    if (!fParList)
+    {
+        *fLog << warn << "WARNING - No parameter list to get resources from." << endl;
+        return kTRUE;
+    }
+
+
     if (fParList->WriteEnv(env, prefix, print)!=kTRUE)
     {
@@ -1038,6 +1053,4 @@
         return kFALSE;
     }
-
-    fLog->WriteEnv(env, prefix, print);
 
     return kTRUE;
Index: trunk/MagicSoft/Mars/mbase/MEvtLoop.h
===================================================================
--- trunk/MagicSoft/Mars/mbase/MEvtLoop.h	(revision 5910)
+++ trunk/MagicSoft/Mars/mbase/MEvtLoop.h	(revision 5911)
@@ -85,5 +85,5 @@
     Bool_t WriteEnv(TEnv &env, TString prefix="", Bool_t print=kFALSE) const;
 
-    Bool_t ReadEnv(const char *config);
+    Bool_t ReadEnv(const char *config, Bool_t print=kFALSE);
 
     void RecursiveRemove(TObject *obj);
Index: trunk/MagicSoft/Mars/mbase/MParList.cc
===================================================================
--- trunk/MagicSoft/Mars/mbase/MParList.cc	(revision 5910)
+++ trunk/MagicSoft/Mars/mbase/MParList.cc	(revision 5911)
@@ -911,5 +911,5 @@
 {
     if (print)
-        *fLog << all << "MParList::ReadEnv: " << prefix << " (" << (int)print << ")" << endl;
+        *fLog << all << "MParList::ReadEnv: " << prefix << endl;
 
     MParContainer *cont = NULL;
Index: trunk/MagicSoft/Mars/mfbase/MF.cc
===================================================================
--- trunk/MagicSoft/Mars/mfbase/MF.cc	(revision 5910)
+++ trunk/MagicSoft/Mars/mfbase/MF.cc	(revision 5911)
@@ -350,4 +350,7 @@
     if (!fF)
     {
+        if (IsAllowEmpty())
+            return kTRUE;
+
         *fLog << err << dbginf << "No filter rule available." << endl;
         return kFALSE;
@@ -370,5 +373,5 @@
 Int_t MF::Process()
 {
-    return fF->CallProcess();
+    return fF ? fF->CallProcess() : kTRUE;
 }
 
@@ -379,14 +382,15 @@
 Int_t MF::PostProcess()
 {
-    return fF->CallPostProcess();
-}
-
-// --------------------------------------------------------------------------
-//
-// Return the result of the filter rule.
+    return fF ? fF->CallPostProcess() : kTRUE;
+}
+
+// --------------------------------------------------------------------------
+//
+// Return the result of the filter rule. If no filter available the
+// condition is always true
 //
 Bool_t MF::IsExpressionTrue() const
 {
-    return fF->IsConditionTrue();
+    return fF ? fF->IsConditionTrue() : kTRUE;
 }
 
@@ -398,5 +402,5 @@
 TString MF::GetDataMember() const
 {
-    return fF->GetDataMember();
+    return fF ? fF->GetDataMember() : "";
 }
 
@@ -422,8 +426,107 @@
 }
 
+// --------------------------------------------------------------------------
+//
+// Print the rule.
+// if now filter is set up '<n/a>' is printed.
+//
 void MF::Print(Option_t *opt) const
 {
     *fLog << all << underline << GetDescriptor() << endl;
-    fF->Print();
+    if (fF)
+        fF->Print();
+    else
+        *fLog << "<n/a>";
     *fLog << endl << endl;
 }
+
+// --------------------------------------------------------------------------
+//
+// Check for corresponding entries in resource file and setup filters.
+//
+// Assuming your MF-filter is called (Set/GetName): MyFilter
+//
+// First you can setup whether the filter is inverted or not:
+//     MyFilter.Inverted: yes, no  <default=no>
+//
+// Now setup the condition, eg:
+//     MyFilter.Condition: MHillas.fSize<1000
+// or
+//     MyFilter.Condition: MHillas.fSize>500 && MHillas.fSize<10000
+//
+// If you want to use more difficult filters you can split the
+// condition into subcondistions. Subcondistions are identified
+// by {}-brackets. Avoid trailing 0's! For example:
+//
+//     MyFilter.Condition: MHillas.fSize>500 && {0} && {1}
+//     MyFilter.0: MHillas.fSize>1000
+//     MyFilter.1: MHillas.fSize<10000
+//
+// The numbering must be continous and start with 0. You can use
+// a subcondition more than once. All {}-brackets are simply replaced
+// by the correspodning conditions. The rules how conditions can
+// be written can be found in the class description of MF and MDataChain.
+//
+Int_t MF::ReadEnv(const TEnv &env, TString prefix, Bool_t print)
+{
+    Bool_t rc = kFALSE;
+    if (IsEnvDefined(env, prefix, "Inverted", print))
+    {
+        rc = kTRUE;
+        SetInverted(GetEnvValue(env, prefix, "Inverted", IsInverted()));
+    }
+
+    if (!IsEnvDefined(env, prefix, "Condition", print))
+        return rc;
+
+    TString rule = GetEnvValue(env, prefix, "Condition", "");
+    rule.ReplaceAll(" ", "");
+
+    Int_t idx=0;
+    while (1)
+    {
+        TString cond;
+        if (IsEnvDefined(env, prefix, Form("%d", idx), print))
+        {
+            cond += "(";
+            cond += GetEnvValue(env, prefix, Form("%d", idx), "");
+            cond += ")";
+        }
+
+        if (cond.IsNull())
+            break;
+
+        rule.ReplaceAll(Form("{%d}", idx), cond);
+        idx++;
+    }
+
+    if (fF)
+    {
+        delete fF;
+        fF = 0;
+    }
+
+    if (rule.IsNull())
+    {
+        *fLog << warn << "MF::ReadEnv - WARNING: Empty condition found." << endl;
+        SetAllowEmpty();
+        return kTRUE;
+    }
+
+    SetAllowEmpty(kFALSE);
+
+    if (!(fF=ParseString(rule, 1)))
+    {
+        *fLog << err << "MF::ReadEnv - ERROR: Parsing '" << rule << "' failed." << endl;
+        return kERROR;
+    }
+
+    if (print)
+    {
+        *fLog << inf << "found: ";
+        fF->Print();
+        *fLog << endl;
+    }
+
+    return kTRUE;
+}
Index: trunk/MagicSoft/Mars/mfbase/MF.h
===================================================================
--- trunk/MagicSoft/Mars/mfbase/MF.h	(revision 5910)
+++ trunk/MagicSoft/Mars/mfbase/MF.h	(revision 5911)
@@ -32,4 +32,6 @@
     void StreamPrimitive(ofstream &out) const;
 
+    enum { kAllowEmpty = BIT(14) };
+
 public:
     MF();
@@ -37,4 +39,9 @@
     ~MF();
 
+    // MF
+    void SetAllowEmpty(Bool_t b=kTRUE) { b ? SetBit(kAllowEmpty) : ResetBit(kAllowEmpty); }
+    Bool_t IsAllowEmpty() const { return TestBit(kAllowEmpty); }
+
+    // MFilter
     TString GetRule() const { return fF ? fF->GetRule() : MFilter::GetRule(); }
     TString GetDataMember() const;
@@ -42,11 +49,15 @@
     Bool_t IsExpressionTrue() const;
 
+    // MTask
     Int_t PreProcess(MParList *pList);
     Int_t Process();
     Int_t PostProcess();
 
+    // TObject
     void Print(Option_t *opt="") const;
 
+    // MParContainer
     void SetVariables(const TArrayD &arr) { if (fF) fF->SetVariables(arr); }
+    Int_t ReadEnv(const TEnv &env, TString prefix, Bool_t print=kFALSE);
 
     ClassDef(MF, 0) // A Filter for cuts in any data member
Index: trunk/MagicSoft/Mars/mfbase/MFilterList.cc
===================================================================
--- trunk/MagicSoft/Mars/mfbase/MFilterList.cc	(revision 5910)
+++ trunk/MagicSoft/Mars/mfbase/MFilterList.cc	(revision 5911)
@@ -439,5 +439,10 @@
 }
 
-
+// --------------------------------------------------------------------------
+//
+// Loop over all set filters and distribute arr to their SetVariables.
+// Make sure, that the values are unique (not two filters using the
+// same index in the array with different meanings)
+//
 void MFilterList::SetVariables(const TArrayD &arr)
 {
