Index: trunk/MagicSoft/Mars/Changelog
===================================================================
--- trunk/MagicSoft/Mars/Changelog	(revision 1347)
+++ trunk/MagicSoft/Mars/Changelog	(revision 1348)
@@ -1,4 +1,28 @@
                                                                   -*-*- END -*-*-
- 2002/06/03: Thomas Bretz
+ 2002/06/05: Thomas Bretz
+
+   * mbase/MWriteAsciiFile.[h,cc]:
+     - changed the code completely to support rules (data chains), too.
+       the interface stayed the same.
+
+   * mdata/MDataChain.cc, mhist/MHMatrix.cc:
+     - added math.h for alpha compilers
+
+   * mbase/MParContainer.h:
+     - changes IsReadyToSave to const
+
+   * mdata/MData.[h,cc]:
+     - added AsciiWrite
+
+   * mdata/MDataChain.[h,cc], mdata/MDataList.[h,cc], mdata/MDataValue.h:
+     - added IsReadyToSave
+
+   * mdata/MDataMember.[h,cc]:
+     - added a new constructor
+     - added IsReadyToSave
+
+
+
+ 2002/06/04: Thomas Bretz
 
    * mhist/MHCompProb.[h,cc]:
@@ -10,4 +34,7 @@
    * mhist/Makefile:
      - added -I../mmc
+
+   * mbase/Makefile:
+     - added -I../mdata
 
    * mhist/MHHadroness.cc:
Index: trunk/MagicSoft/Mars/mbase/MParContainer.h
===================================================================
--- trunk/MagicSoft/Mars/mbase/MParContainer.h	(revision 1347)
+++ trunk/MagicSoft/Mars/mbase/MParContainer.h	(revision 1348)
@@ -64,5 +64,5 @@
     virtual void   SetLogStream(MLog *lg) { fLog = lg; }
     virtual void   Reset() { }
-    virtual Bool_t IsReadyToSave()                   { return fReadyToSave; }
+    virtual Bool_t IsReadyToSave() const             { return fReadyToSave; }
     virtual void   SetReadyToSave(Bool_t flag=kTRUE) { fReadyToSave=flag; }
 
Index: trunk/MagicSoft/Mars/mbase/MWriteAsciiFile.cc
===================================================================
--- trunk/MagicSoft/Mars/mbase/MWriteAsciiFile.cc	(revision 1347)
+++ trunk/MagicSoft/Mars/mbase/MWriteAsciiFile.cc	(revision 1348)
@@ -52,5 +52,9 @@
 #include <TClass.h>      // IsA
 #include <TMethodCall.h> // TMethodCall, AsciiWrite
-#include <TDataMember.h> // TDataMember, AsciiWrite
+
+#include "MDataList.h"   // MDataList
+#include "MDataChain.h"  // MDataChain
+#include "MDataValue.h"  // MDataValue
+#include "MDataMember.h" // MDataMember
 
 #include "MLog.h"
@@ -92,5 +96,5 @@
 
     if (contname)
-        AddContainer(contname);
+       AddContainer(contname);
 }
 
@@ -122,7 +126,5 @@
 MWriteAsciiFile::~MWriteAsciiFile()
 {
-    fContNames.SetOwner();
-    fMembers.SetOwner();
-
+    fAutoDel.SetOwner();
     delete fOut;
 }
@@ -130,88 +132,60 @@
 // --------------------------------------------------------------------------
 //
-// Check if the containers are ready for writing. If so write them.
-// The containers are written in one line, one after each other.
-// If not all containers are written (because of the IsReadyToSave-flag)
-// a warning message is print.
-//
-void MWriteAsciiFile::CheckAndWrite() const
-{
-    Bool_t written = kFALSE;
-
-    MParContainer *cont = NULL;
-
-    Int_t num = fContainer.GetEntries();
-
-    TIter NextCont(&fContainer);
-    TIter NextMemb(&fMembers);
-
-    while ((cont=(MParContainer*)NextCont()))
-    {
-        const MScale *memb = (MScale*)NextMemb();
-
-        if (!cont->IsReadyToSave())
-            continue;
-
-        if (memb->GetTitle()[0]=='\0')
-        {
-            if (!cont->AsciiWrite(*fOut))
-                continue;
-        }
-        else
-        {
-            if (!cont->WriteDataMember(*fOut, memb->GetTitle(), memb->GetScale()))
-                continue;
-        }
-
-        written = kTRUE;
-
-        num--;
-    }
-
-    if (!written)
+// Return open state of the file
+//
+Bool_t MWriteAsciiFile::IsFileOpen() const
+{
+    return (bool)(*fOut);
+}
+
+// --------------------------------------------------------------------------
+//
+// Add a rule to be written as a column to the ascii file.
+// For more information about rules see MDataChain.
+//
+void MWriteAsciiFile::AddRule(const char *rule)
+{
+    MDataChain *chain = new MDataChain(rule);
+    fList.Add(chain);
+}
+
+// --------------------------------------------------------------------------
+//
+// Add another container (by pointer) to be written to the ascii file.
+// The container will be output one after each other in one line.
+// If you want to write only one data member of the container
+// specify the name of the data member (eg. fAlpha) Make sure,
+// that a "GetteMethod" for this data type exists (strip the f and
+// replace it by Get)
+// If you specify a single data member you can add a scale-factor which
+// is (in case of the data member being a floating point value) multiplied
+// with the data member value. This is usefull if you are want to
+// change the scale (unit) of a data member for writing (eg.
+// writing degrees for the hillas parameters instead of the internally
+// used millimeters)
+//
+void MWriteAsciiFile::AddContainer(MParContainer *cont, const TString member, Double_t scale)
+{
+    if (member.IsNull())
+    {
+        fList.Add(cont);
         return;
-
-    *fOut << endl;
-
-    if (num!=0)
-        *fLog << warn << "Warning - given number of containers doesn't fit number of written containers." << endl;
-}
-
-// --------------------------------------------------------------------------
-//
-// Return open state of the file
-//
-Bool_t MWriteAsciiFile::IsFileOpen() const
-{
-    return (bool)(*fOut);
-}
-
-// --------------------------------------------------------------------------
-//
-// Tries to get all containers from the ParList which were given by name
-// adds them to the list of pointers to the container which should be
-// written to the ascii file.
-//
-Bool_t MWriteAsciiFile::GetContainer(MParList *pList)
-{
-    MScale *obj = NULL;
-
-    TIter Next(&fContNames);
-
-    while ((obj=(MScale*)Next()))
-    {
-        const char *name = obj->GetName();
-
-        MParContainer *cont = (MParContainer*)pList->FindObject(name, "MParContainer");
-        if (!cont)
-        {
-            *fLog << err << dbginf << "Cannot find parameter container '" << name << "'." << endl;
-            return kFALSE;
-        }
-
-        AddContainer(cont, obj->GetTitle(), obj->GetScale());
-    }
-
-    return kTRUE;
+    }
+
+    MData *data = new MDataMember(cont, member);
+
+    if (scale!=1)
+    {
+        MDataList  *list = new MDataList('*');
+        MDataValue *val  = new MDataValue(scale);
+
+        list->SetOwner();
+        list->AddToList(data);
+        list->AddToList(val);
+
+        data = list;
+    }
+    fList.Add(data);
+    fAutoDel.Add(data);
 }
 
@@ -231,53 +205,115 @@
 // used millimeters)
 //
-void MWriteAsciiFile::AddContainer(const char *cname, const char *member, Double_t scale)
-{
-    MScale *name = new MScale(cname, member, scale);
-    fContNames.AddLast(name);
-
-    if (member && member[0])
-        AddToBranchList(Form("%s.%s", cname, member));
-}
-
-// --------------------------------------------------------------------------
-//
-// Add another container (by pointer) to be written to the ascii file.
-// The container will be output one after each other in one line.
-// If you want to write only one data member of the container
-// specify the name of the data member (eg. fAlpha) Make sure,
-// that a "GetteMethod" for this data type exists (strip the f and
-// replace it by Get)
-// If you specify a single data member you can add a scale-factor which
-// is (in case of the data member being a floating point value) multiplied
-// with the data member value. This is usefull if you are want to
-// change the scale (unit) of a data member for writing (eg.
-// writing degrees for the hillas parameters instead of the internally
-// used millimeters)
-//
-void MWriteAsciiFile::AddContainer(MParContainer *cont, const char *member, Double_t scale)
-{
-    fContainer.AddLast(cont);
-
-    MScale *name = new MScale("", member, scale);
-    fMembers.AddLast(name);
-}
-
-/*
-Bool_t MWriteAsciiFile::PreProcess(MParList *plist)
-{
-    MDataChain *chain=NULL;
+void MWriteAsciiFile::AddContainer(const TString cont, const TString member, Double_t scale)
+{
+    if (member.IsNull())
+    {
+        TNamed *name = new TNamed(cont, cont);
+        fList.Add(name);
+        fAutoDel.Add(name);
+        return;
+    }
+
+    MData *data = new MDataMember(Form("%s.%s", (const char*)cont, (const char*)member));
+    if (scale!=1)
+    {
+        MDataList  *list = new MDataList('*');
+        MDataValue *val  = new MDataValue(scale);
+
+        list->SetOwner();
+        list->AddToList(data);
+        list->AddToList(val);
+
+        data = list;
+    }
+    fList.Add(data);
+    fAutoDel.Add(data);
+}
+
+// --------------------------------------------------------------------------
+//
+// Tries to get all containers from the ParList which were given by name
+// adds them to the list of pointers to the container which should be
+// written to the ascii file.
+//
+Bool_t MWriteAsciiFile::GetContainer(MParList *plist)
+{
+    TObject *obj=NULL;
 
     TIter Next(&fList);
-    while (((MDataChain*)chain=Next()))
-        if (!chain->PreProcess(plist))
+    while ((obj=Next()))
+    {
+        //
+        // MData is the highest class in the inheritance tree
+        //
+        if (obj->IsA()->InheritsFrom(MData::Class()))
+        {
+            if (!((MData*)obj)->PreProcess(plist))
+                return kFALSE;
+            continue;
+        }
+
+        //
+        // MParContainer is the next class in the inheritance tree
+        //
+        if (obj->IsA()->InheritsFrom(MParContainer::Class()))
+            continue;
+
+        //
+        // It is neither a MData nor a MParContainer, it must be a TNamed
+        //
+        TObject *o = plist->FindObject(obj->GetName());
+        if (!o)
             return kFALSE;
 
-    return MWriteFile::PreProcess(plist);
-}
-
-void MWriteAsciiFile::Add(const char *rule)
-{
-    MDataChain *chain = new MDataChain(rule);
-    fList.Add(chain);
-}
-*/
+        fList[fList.IndexOf(obj)] = o;
+    }
+    return kTRUE;
+}
+
+// --------------------------------------------------------------------------
+//
+// Check if the containers are ready for writing. If so write them.
+// The containers are written in one line, one after each other.
+// If not all containers are written (because of the IsReadyToSave-flag)
+// a warning message is print.
+//
+void MWriteAsciiFile::CheckAndWrite() const
+{
+    Bool_t written = kFALSE;
+
+    MParContainer *obj = NULL;
+
+    Int_t num = fList.GetEntries();
+
+    *fLog << all << "CHECK&WRITE " << num << endl;
+
+    TIter Next(&fList);
+    while ((obj=(MParContainer*)Next()))
+    {
+        *fLog << all << endl << obj->IsA()->GetName() << ": 0..." << flush;
+
+        if (!obj->IsReadyToSave())
+            continue;
+
+        *fLog << all << "1..." << flush;
+
+        if (!obj->AsciiWrite(*fOut))
+            continue;
+
+        *fLog << all << "2..." << flush;
+
+        written = kTRUE;
+
+        num--;
+    }
+
+    if (!written)
+        return;
+
+    *fOut << endl;
+
+    if (num!=0)
+        *fLog << warn << "Warning - given number of objects doesn't fit number of written objects." << endl;
+}
+
Index: trunk/MagicSoft/Mars/mbase/MWriteAsciiFile.h
===================================================================
--- trunk/MagicSoft/Mars/mbase/MWriteAsciiFile.h	(revision 1347)
+++ trunk/MagicSoft/Mars/mbase/MWriteAsciiFile.h	(revision 1348)
@@ -9,27 +9,16 @@
 #endif
 
+class MData;
+
 class MWriteAsciiFile : public MWriteFile
 {
 private:
-    class MScale : public TNamed
-    {
-    private:
-        Double_t fScale;
-    public:
-        MScale(const char *name, const char *title, Double_t scale)
-            : TNamed(name, title), fScale(scale) {}
-        Double_t GetScale() const { return fScale; }
-    };
+    ofstream *fOut;     //! ascii file
 
-    ofstream *fOut;
+    TString fNameFile;  // name of the ascii file
 
-    TObjArray fContNames;
-    TObjArray fContainer;
-    TObjArray fMembers;
+    TObjArray fList;    // list of rules and containers to be written
+    TObjArray fAutoDel; //! List of object to be deleted in the destructor
 
-    TString fNameFile;
-/*
-    TList fList;
-*/
     virtual void   CheckAndWrite() const;
     virtual Bool_t IsFileOpen() const;
@@ -46,11 +35,8 @@
     ~MWriteAsciiFile();
 
-    void AddContainer(const char *cname, const char *member="", Double_t scale=1);
-    void AddContainer(MParContainer *cont, const char *member="", Double_t scale=1);
+    void AddContainer(const TString cname, const TString member="", Double_t scale=1);
+    void AddContainer(MParContainer *cont, const TString member="", Double_t scale=1);
 
-    /*
-     Bool_t PreProcess(MParList *plist);
-     void Add(const char *rule);
-     */
+    void AddRule(const char *rule);
 
     ClassDef(MWriteAsciiFile, 0) // Class to write one container to an ascii file
Index: trunk/MagicSoft/Mars/mbase/Makefile
===================================================================
--- trunk/MagicSoft/Mars/mbase/Makefile	(revision 1347)
+++ trunk/MagicSoft/Mars/mbase/Makefile	(revision 1348)
@@ -20,5 +20,5 @@
 # @endcode 
 
-INCLUDES = -I. -I../mraw -I../MRawFormat -I../mmc
+INCLUDES = -I. -I../mraw -I../MRawFormat -I../mmc -I../mdata
 
 # @code 
Index: trunk/MagicSoft/Mars/mdata/MData.cc
===================================================================
--- trunk/MagicSoft/Mars/mdata/MData.cc	(revision 1347)
+++ trunk/MagicSoft/Mars/mdata/MData.cc	(revision 1348)
@@ -48,3 +48,12 @@
 #include "MData.h"
 
+#include <ostream.h>
+
 ClassImp(MData);
+
+Bool_t MData::AsciiWrite(ostream &out) const
+{
+    out << GetValue() << " ";
+    return kTRUE;
+}
+
Index: trunk/MagicSoft/Mars/mdata/MData.h
===================================================================
--- trunk/MagicSoft/Mars/mdata/MData.h	(revision 1347)
+++ trunk/MagicSoft/Mars/mdata/MData.h	(revision 1348)
@@ -23,4 +23,6 @@
     Double_t operator()() { return GetValue(); }
 
+    Bool_t AsciiWrite(ostream &out) const;
+
     ClassDef(MData, 0) // A Base class for a generalized value
 };
Index: trunk/MagicSoft/Mars/mdata/MDataChain.cc
===================================================================
--- trunk/MagicSoft/Mars/mdata/MDataChain.cc	(revision 1347)
+++ trunk/MagicSoft/Mars/mdata/MDataChain.cc	(revision 1348)
@@ -81,4 +81,5 @@
 #include "MDataChain.h"
 
+#include <math.h>         // fabs on Alpha
 #include <ctype.h>        // isalnum, ...
 #include <stdlib.h>       // strtod, ...
@@ -131,4 +132,14 @@
 {
     return fMember ? fMember->PreProcess(pList) : kFALSE;
+}
+
+// --------------------------------------------------------------------------
+//
+// Checks whether at least one member has the ready-to-save flag.
+//
+Bool_t MDataChain::IsReadyToSave() const
+{
+    *fLog << all << "fM=" << fMember << "/" << (int)fMember->IsReadyToSave() << " " << endl;
+    return fMember ? fMember->IsReadyToSave() : kFALSE;
 }
 
Index: trunk/MagicSoft/Mars/mdata/MDataChain.h
===================================================================
--- trunk/MagicSoft/Mars/mdata/MDataChain.h	(revision 1347)
+++ trunk/MagicSoft/Mars/mdata/MDataChain.h	(revision 1348)
@@ -58,4 +58,5 @@
 
     Bool_t IsValid() const { return fMember ? kTRUE : kFALSE; }
+    Bool_t IsReadyToSave() const;
 
     void Print(Option_t *opt = "") const;
Index: trunk/MagicSoft/Mars/mdata/MDataList.cc
===================================================================
--- trunk/MagicSoft/Mars/mdata/MDataList.cc	(revision 1347)
+++ trunk/MagicSoft/Mars/mdata/MDataList.cc	(revision 1348)
@@ -142,4 +142,21 @@
 // --------------------------------------------------------------------------
 //
+// Checks whether at least one member has the ready-to-save flag.
+//
+Bool_t MDataList::IsReadyToSave() const
+{
+    TIter Next(&fMembers);
+
+    MData *data = NULL;
+
+    while ((data=(MData*)Next()))
+        if (data->IsReadyToSave())
+            return kTRUE;
+
+    return kFALSE;
+}
+
+// --------------------------------------------------------------------------
+//
 // If you want to add a new member to the list call this function with the
 // pointer to the member to be added. 
Index: trunk/MagicSoft/Mars/mdata/MDataList.h
===================================================================
--- trunk/MagicSoft/Mars/mdata/MDataList.h	(revision 1347)
+++ trunk/MagicSoft/Mars/mdata/MDataList.h	(revision 1348)
@@ -41,4 +41,5 @@
 
     Bool_t IsValid() const { return fMembers.GetSize() ? kTRUE : kFALSE; }
+    Bool_t IsReadyToSave() const;
 
     Double_t GetValue() const;
Index: trunk/MagicSoft/Mars/mdata/MDataMember.cc
===================================================================
--- trunk/MagicSoft/Mars/mdata/MDataMember.cc	(revision 1347)
+++ trunk/MagicSoft/Mars/mdata/MDataMember.cc	(revision 1348)
@@ -59,4 +59,17 @@
     fObject = obj;
     fCall   = call;
+}
+
+// --------------------------------------------------------------------------
+//
+//  obj is a pointer to the instance of your class from which the data
+//  should be requested. TMethodCall (s. root dox) is a pointer
+//  to a TMethodCall object which should be the getter function for
+//  the data you want to get.
+//
+MDataMember::MDataMember(MParContainer *obj, const TString call)
+{
+    fObject = obj;
+    fCall   = obj->GetterMethod(call);
 }
 
@@ -134,4 +147,13 @@
 // --------------------------------------------------------------------------
 //
+// Returns the ready-to-save flag of the data member container
+//
+Bool_t MDataMember::IsReadyToSave() const
+{
+    return IsValid() ? fObject->IsReadyToSave() : kFALSE;
+}
+
+// --------------------------------------------------------------------------
+//
 // Print the name of the data member without an CR.
 //
Index: trunk/MagicSoft/Mars/mdata/MDataMember.h
===================================================================
--- trunk/MagicSoft/Mars/mdata/MDataMember.h	(revision 1347)
+++ trunk/MagicSoft/Mars/mdata/MDataMember.h	(revision 1348)
@@ -24,4 +24,5 @@
     }
     MDataMember(MParContainer *obj, TMethodCall *call);
+    MDataMember(MParContainer *obj, const TString call);
 
     Double_t GetValue() const;
@@ -29,4 +30,5 @@
 
     Bool_t IsValid() const { return fCall ? kTRUE : kFALSE; }
+    Bool_t IsReadyToSave() const;
 
     void Print(Option_t *opt = "") const;
Index: trunk/MagicSoft/Mars/mdata/MDataValue.h
===================================================================
--- trunk/MagicSoft/Mars/mdata/MDataValue.h	(revision 1347)
+++ trunk/MagicSoft/Mars/mdata/MDataValue.h	(revision 1348)
@@ -26,4 +26,5 @@
 
     Bool_t IsValid() const { return kTRUE; }
+    Bool_t IsReadyToSave() const { return kFALSE; }
 
     void Print(Option_t *opt = "") const;
Index: trunk/MagicSoft/Mars/mhist/MHMatrix.cc
===================================================================
--- trunk/MagicSoft/Mars/mhist/MHMatrix.cc	(revision 1347)
+++ trunk/MagicSoft/Mars/mhist/MHMatrix.cc	(revision 1348)
@@ -45,4 +45,6 @@
 #include "MHMatrix.h"
 
+#include <math.h>     // fabs on Alpha
+
 #include <TList.h>
 #include <TArrayD.h>
