Index: trunk/MagicSoft/Mars/mdata/MDataChain.cc
===================================================================
--- trunk/MagicSoft/Mars/mdata/MDataChain.cc	(revision 2114)
+++ trunk/MagicSoft/Mars/mdata/MDataChain.cc	(revision 2117)
@@ -82,4 +82,19 @@
 //   randl(x)  returns gRandom->Landau(0, x)
 //
+//
+// Constants are implemented in ParseDataMember, namely:
+//   kPi:      TMath::Pi()
+//   kRad2Deg: 180/kPi
+//   kDeg2Rad: kPi/180
+//
+// You can also defined constants which are defined in TMath by:
+//   kLn10      for   static Double_t TMath::Ln10();
+//   kLogE      for   static Double_t TMath::LogE();
+//   kRadToDeg  for   static Double_t TMath::RadToDeg();
+//   kDegToRad  for   static Double_t TMath::DegToRad();
+// Remark: In older root versions only Pi() and E() are implemented in
+//         TMath.
+//
+//
 // REMARK:
 //         - All the random functions are returning 0 if gRandom==0
@@ -100,4 +115,5 @@
 
 #include <TRandom.h>
+#include <TMethodCall.h>
 
 #include "MLog.h"
@@ -126,21 +142,15 @@
 // --------------------------------------------------------------------------
 //
-//  Default constructor
-//
-MDataChain::MDataChain()
-    : fMember(NULL), fOperatorType(kENoop)
-{
-}
-
-// --------------------------------------------------------------------------
-//
 // Constructor taking a rule as an argument. For more details see
 // class description
 //
 MDataChain::MDataChain(const char *rule, const char *name, const char *title)
-    : fOperatorType(kENoop)
+    : fMember(NULL), fOperatorType(kENoop)
 {
     fName  = name  ? name  : "MDataChain";
     fTitle = title ? title : rule;
+
+    if (TString(rule).IsNull())
+        return;
 
     *fLog << inf << "Trying to resolve rule... " << flush;
@@ -259,4 +269,38 @@
 // --------------------------------------------------------------------------
 //
+// Here the names of data members are interpreted. This can be used to
+// check for constants.
+//
+MData *MDataChain::ParseDataMember(TString txt)
+{
+    //txt.ToLower();
+
+    if (txt=="kRad2Deg") return new MDataValue(kRad2Deg);
+    if (txt=="kDeg2Rad") return new MDataValue(1./kRad2Deg);
+
+    if (!txt.BeginsWith("k"))
+        return new MDataMember(txt.Data());
+
+    const TString name = txt(1, txt.Length());
+    TMethodCall call(TMath::Class(), name, "");
+    switch (call.ReturnType())
+    {
+    case TMethodCall::kLong:
+        Long_t l;
+        call.Execute(l);
+        return new MDataValue(l);
+    case TMethodCall::kDouble:
+        Double_t d;
+        call.Execute(d);
+        return new MDataValue(d);
+    default:
+        break;
+    }
+
+    return new MDataMember(txt.Data());
+}
+
+// --------------------------------------------------------------------------
+//
 // Core of the data chain. Here the chain is constructed out of the rule.
 //
@@ -418,5 +462,5 @@
             if ((txt.IsNull() || txt[0]!='(') && text[0]!='-' && text[0]!='+')
             {
-                newmember = new MDataMember(text.Data());
+                newmember = ParseDataMember(text.Data());
                 break;
             }
@@ -469,5 +513,5 @@
     if (!fMember)
     {
-        *fLog << warn << "MDataChain not valid." << endl;
+        //*fLog << warn << "MDataChain not valid." << endl;
         return 0;
     }
Index: trunk/MagicSoft/Mars/mdata/MDataChain.h
===================================================================
--- trunk/MagicSoft/Mars/mdata/MDataChain.h	(revision 2114)
+++ trunk/MagicSoft/Mars/mdata/MDataChain.h	(revision 2117)
@@ -59,10 +59,10 @@
 
     MData *ParseString(TString txt, Int_t level);
+    MData *ParseDataMember(TString txt);
 
     MDataChain(const char *rule, OperatorType_t op);
 
 public:
-    MDataChain();
-    MDataChain(const char *rule, const char *name=NULL, const char *title=NULL);
+    MDataChain(const char *rule=NULL, const char *name=NULL, const char *title=NULL);
     ~MDataChain();
 
