Changeset 9580


Ignore:
Timestamp:
05/05/10 10:03:14 (15 years ago)
Author:
tbretz
Message:
*** empty log message ***
Location:
trunk/MagicSoft/Mars
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/MagicSoft/Mars/Changelog

    r9579 r9580  
    3838   * msimcamera/MSimCalibrationSignal.cc:
    3939     - changed distribution of signal from Gauss to Poissonian
     40
     41   * showplot.cc:
     42     - removed nonsense "-q" option
     43
     44   * mbase/MStatusArray.[h,cc]:
     45     - fixed/improved (once again) deleting of the array
     46
     47   * mbase/MStatusDisplay.cc:
     48     - removed the MAstroCatalog workaround - is it still necessary?
     49       (needs testing)
     50     - added UpdateMemory every here and there to get the memory
     51       consumption is more circumstances
    4052
    4153
  • trunk/MagicSoft/Mars/mbase/MStatusArray.cc

    r9571 r9580  
    5858#include "MStatusDisplay.h"
    5959
     60//#define DEBUG
     61
    6062ClassImp(MStatusArray);
    6163
     
    7375}
    7476
     77#ifdef DEBUG
     78static void *ptr = 0;
     79#endif
     80
    7581// --------------------------------------------------------------------------
    7682//
     
    7884// name) recuresively
    7985//
    80 void MStatusArray::RecursiveDelete(TVirtualPad *p, const char id) const
     86Bool_t MStatusArray::RecursiveDelete(TVirtualPad *p, const char id) const
    8187{
    8288    if (!p)
    83         return;
    84 
    85     TIter Next2(p->GetListOfPrimitives());
    86     TObject *o=0;
    87     while ((o=Next2()))
     89        return kTRUE;
     90
     91    // It seems that it is necessary to keep the ListOfPrimitve consistent
     92    // while deleting - reason unknown.
     93    TIter Next(p->GetListOfPrimitives());
     94    TObject *o=0;
     95    while ((o=Next()))
    8896    {
    8997        if (!dynamic_cast<TVirtualPad*>(o) && (o->ClassName()[0]==id || id==0))
     
    95103            // get removed from the pad if deleted, and therefore
    96104            // gets deleted twice (FIXME: To be investigated)
    97             if (dynamic_cast<TPaveText*>(o) && !o->TestBit(kCanDelete))
    98                 continue;
    99 
    100             /*
    101             // This is necessary because the histogram can get deleted
    102             // but is not treated in TGraph recursive remove. Unfortunately,
    103             // we have no possibility to find out whether it was already
    104             // deleted. Fortunately these histograms don't contain data
    105             // and threfore don't consume memory.
    106             TGraph *g = dynamic_cast<TGraph*>(o);
    107             if (g)
    108                 g->SetHistogram(0);
    109              */
    110 
     105            //if (dynamic_cast<TPaveText*>(o) && !o->TestBit(kCanDelete))
     106            //    continue;
     107
     108#ifdef DEBUG
     109            cout << "Start Delete " << o << " " << o->GetName() << " " << o->ClassName() << endl;
     110            ptr = o;
     111#endif
    111112            delete o;
    112113
    113             continue;
    114         }
    115 
    116         RecursiveDelete(dynamic_cast<TVirtualPad*>(o), id);
    117     }
    118 
     114#ifdef DEBUG
     115            ptr = 0;
     116            cout << "Done  Delete " << o<< endl;
     117#endif
     118            return kFALSE;
     119        }
     120
     121        while (!RecursiveDelete(dynamic_cast<TVirtualPad*>(o), id));
     122    }
     123
     124    return kTRUE;
    119125}
    120126
     
    136142        obj->ResetBit(kMustCleanup);
    137143    else
     144    {
     145        // If this is no pad or TCanvas set the kMustCleanup bit
     146        // to make sure that the object is not by chance deleted twice.
    138147        obj->SetBit(kMustCleanup);
     148
     149        // Unfortunately, this can still happen to the fHistogram and
     150        // fFunctions in a TGraph (because for some reason if a TGraph
     151        // is stored twice in a file they might later share the same
     152        // objects)
     153        TGraph *g = dynamic_cast<TGraph*>(obj);
     154        if (g)
     155        {
     156#ifdef DEBUG
     157            cout << "Found TGraph " << g->GetName() << " " << g << " while deleting " << ptr << endl;
     158#endif
     159            if (g->GetHistogram())
     160                g->GetHistogram()->SetBit(kMustCleanup);
     161            if (g->GetListOfFunctions())
     162                g->GetListOfFunctions()->SetBit(kMustCleanup);
     163        }
     164    }
    139165
    140166    if (!pad)
    141167        return;
    142168
     169    // If object was a pad go one layer deeper
    143170    TIter Next(pad->GetListOfPrimitives());
    144171    TObject *o=0;
     
    147174}
    148175
    149 // --------------------------------------------------------------------------
    150 //
    151 // This is a workaround to make sure that TH1 which are part of two TGraphs
    152 // (TGraph::GetHistogram) are not finally deleted twice. Unfortunately,
    153 // TGraph doesn't have it in RecursiveRemove.
    154 //
    155 void MStatusArray::RecursiveRemove(TVirtualPad *p, TObject *obj)
    156 {
    157     if (!p)
    158         return;
    159 
    160     TIter Next(p->GetListOfPrimitives());
    161     TObject *o=0;
    162     while ((o=Next()))
    163     {
    164         if (dynamic_cast<TGraph*>(o))
    165         {
    166             // FIXME: This should not be called for the TGraph
    167             // which is currently getting deleted.
    168             TGraph *g = static_cast<TGraph*>(o);
     176// This is a stupid C++ trick which allos us to access the
     177// protected data-mebers of TGraph
     178class MyGraph : public TGraph
     179{
     180public:
     181    void ResetListOfFunctions()
     182    {
     183        fFunctions = 0;
     184    }
     185};
     186
     187void MStatusArray::RecursiveRemove(TCollection *col, TObject *obj)
     188{
     189    // First remove the object from the collection as often as possible
     190    // (The collection is always a ListOfPrimitives(). This code is
     191    // based on TCollection::RecursiveRemove and TPad::RecursiveRemove)
     192    while (col->Remove(obj));
     193
     194    TObject *object=0;
     195
     196    // Loop over all objects in the collection
     197    TIter Next(col);
     198    while ((object=Next()))
     199    {
     200        // Check if this object is a pad. If it is a pad go one
     201        // layer deeper.
     202        TPad *pad = dynamic_cast<TPad*>(object);
     203        if (pad)
     204        {
     205#ifdef DEBUG
     206            cout << "Start RecursiveRemove in " << pad->GetName() << " " << pad << endl;
     207#endif
     208            RecursiveRemove(pad->GetListOfPrimitives(), obj);
     209#ifdef DEBUG
     210            cout << "Done  RecursiveRemove in " << pad->GetName() << " " << pad << endl;
     211#endif
     212            continue;
     213        }
     214
     215        // If it is not a TPad check if it is a TGraph
     216        TGraph *g = dynamic_cast<TGraph*>(object);
     217        if (g/* && g!=ptr*/)
     218        {
     219#ifdef DEBUG
     220            cout << "MStatusArray::RecursiveRemove " << obj << " from TGraph " << g << endl;
     221#endif
     222
     223            // If the object to be removed is the histogram from the
     224            // TGraph the histogram got already deleted so we have to
     225            // reset the pointer
    169226            if (g->GetHistogram()==obj)
     227            {
     228#ifdef DEBUG
     229                cout << "       SetHist(0)" << endl;
     230#endif
    170231                g->SetHistogram(0);
    171             else
    172                 g->GetHistogram()->SetBit(kMustCleanup);
    173 
    174             continue;
    175         }
    176 
    177         RecursiveRemove(dynamic_cast<TVirtualPad*>(o), obj);
    178     }
    179 
    180 }
    181 
    182 // --------------------------------------------------------------------------
    183 //
    184 // This is a workaround to make sure that TH1 which are part of two TGraphs
    185 // (TGraph::GetHistogram) are not finally deleted twice. Unfortunately,
    186 // TGraph doesn't have it in RecursiveRemove.
     232                continue;
     233            }
     234
     235            // If the object to be removed is the ListOfFunction from the
     236            // TGraph the ListOfFunction got already deleted so we have to
     237            // reset the pointer. This is done by a stupid C++ trick
     238            // (a derived class which can access the protected data mebers)
     239            if (g->GetListOfFunctions()==obj)
     240            {
     241#ifdef DEBUG
     242                cout << "       SetFunc(0)" << endl;
     243#endif
     244                static_cast<MyGraph*>(g)->ResetListOfFunctions();
     245                continue;
     246            }
     247        }
     248
     249#ifdef DEBUG
     250        cout << " Call RecursiveRemove for " << object->GetName() << " " << object << endl;
     251#endif
     252
     253        // Now we go on like TCollction would do calling the RecursiveRemove
     254        // of the objects (which are no pads)
     255        if (object->TestBit(TObject::kNotDeleted))
     256            object->RecursiveRemove(obj);
     257    }
     258}
     259
     260// --------------------------------------------------------------------------
     261//
     262// Use our own implementation of RecursiveRemove.
    187263//
    188264void MStatusArray::RecursiveRemove(TObject *obj)
    189265{
    190     TObjArray::RecursiveRemove(obj);
    191 
    192     // FIXME: Maybe we still have to call SetBit(kMustCleanup) ???
    193 #if ROOT_VERSION_CODE <= ROOT_VERSION(5,26,00)
    194     TObject *o = 0;
    195 
    196     TIter Next(this);
    197     while ((o=Next()))
    198         RecursiveRemove(dynamic_cast<TVirtualPad*>(o), obj);
    199 #endif
    200 }
    201 
    202 // --------------------------------------------------------------------------
    203 //
    204 // Try to do a delete of the whole list in a way which is less vulnarable
    205 // to double deletion due to wrongly set bits or other things
     266#ifdef DEBUG
     267    cout << "RecursiveRemove " << obj << endl;
     268#endif
     269    RecursiveRemove(this, obj);
     270}
     271
     272// --------------------------------------------------------------------------
     273//
     274// The problem is that our objects (e.g. MHRate) can own histograms and
     275// graphs (or other objects), which are data members rather than allocated
     276// objects (pointers), and which are drawn into a pad. If such a pad gets
     277// read from a file we have to set the kCanDelete bits for all objects
     278// in all pads to ensure that they are properly deleted (since we
     279// don't know who owns them). Unfortunately, this might result in the
     280// data member deleted first and then second in the destructor of the
     281// owning class. One simple workaround is to delete all our own objects
     282// ("M*") first without touching the root objects ("T*") and delete the
     283// remaining ones later. This might not work if teh owned objects are
     284// MARS classes. Fortunately, none of our classes yets owns another of
     285// our class not dynamically allocated. (This case is covered by
     286// the RecursiveRemove facility).
     287//
     288// Furthermore TGraphs which are read from a file as a data member
     289// of a class and which are drawn to a pad share the same fFunctions
     290// and fHistogram. To avoid double deleting (the second TGraph won't
     291// be signaled if the first one is deleted) we implement our own
     292// RecursiveRemove facility. (This gets a bit better in root 5.28
     293// because TGraph::RecursiveRemove will than also check fHistogram)
    206294//
    207295void MStatusArray::Delete(Option_t *)
     
    211299    gROOT->GetListOfCleanups()->Add(this);
    212300
    213     // First make sure that all kMustCleanup bits are se
     301    // First make sure that all kMustCleanup bits are set, esepcially
     302    // the ones of TGraph::fHistogram and TGraph::fFunctions
    214303    TIter Next(this);
    215304    TObject *o=0;
     
    221310    TIter Next2(this);
    222311    while ((o=Next2()))
    223         RecursiveDelete(dynamic_cast<TVirtualPad*>(o), 'M');
     312        while (!RecursiveDelete(dynamic_cast<TVirtualPad*>(o), 'M'));
    224313
    225314    // Now delete all root objects
    226315    TIter Next3(this);
    227316    while ((o=Next3()))
    228         RecursiveDelete(dynamic_cast<TVirtualPad*>(o));
     317        while (!RecursiveDelete(dynamic_cast<TVirtualPad*>(o)));
    229318
    230319    // And delete all the rest
  • trunk/MagicSoft/Mars/mbase/MStatusArray.h

    r9532 r9580  
    2020
    2121    void     SetCleanup(TObject *obj) const;
    22     void     RecursiveDelete(TVirtualPad *p, const char id=0) const;
     22    Bool_t   RecursiveDelete(TVirtualPad *p, const char id=0) const;
    2323
    2424    void     SetCanDelete(const TCollection *list) const;
     
    2727    void     PrintObjectsInPad(const TCollection *list, const TString &name, Int_t lvl=0) const;
    2828    TObject *FindObjectInPad(TVirtualPad *pad, const char *object, TClass *base) const;
     29    void     RecursiveRemove(TCollection *c, TObject *o);
    2930
    3031public:
     
    6263    void Delete(Option_t *option="");
    6364
    64     void RecursiveRemove(TVirtualPad *p, TObject *o);
    6565    void RecursiveRemove(TObject *o);
    6666
  • trunk/MagicSoft/Mars/mbase/MStatusDisplay.cc

    r9578 r9580  
    790790    MapWindow();
    791791
     792    UpdateMemory();
     793
    792794    // FIXME: This is a workaround, because TApplication::Run is not
    793795    //        thread safe against ProcessEvents. We assume, that if
     
    10101012    MapSubwindows();
    10111013    Layout();
     1014
     1015    UpdateMemory();
    10121016
    10131017    // display new tab in the main frame
     
    11641168    Layout();          // layout the embedded canvas in the frame
    11651169
     1170    UpdateMemory();
     1171
    11661172    // display new tab in the main frame
    11671173    // FIXME: This is a workaround, because TApplication::Run is not
     
    14421448    MapSubwindows();   // maps the TGCompositeFrame
    14431449    Layout();          // layout the embedded canvas in the frame
     1450
     1451    UpdateMemory();
    14441452
    14451453    // display new tab in the main frame
     
    22532261        // FIXME: This is a workaround for the problem with the MAstroCatalog in
    22542262        // MHFalseSource. It doesn't harm. We'll still try to find the reason
    2255         if (clone->IsA()==TPad::Class())
    2256             gROOT->GetListOfCleanups()->Add(clone);
     2263        //if (clone->IsA()==TPad::Class())
     2264        //    gROOT->GetListOfCleanups()->Add(clone);
    22572265
    22582266        // Add the clone and its draw-option to the current pad
  • trunk/MagicSoft/Mars/showplot.cc

    r9576 r9580  
    4141    gLog << " Options: "<< endl;
    4242    gLog.Usage();
    43     gLog << "   -q                        Quit when job is finished" << endl;
    4443    gLog << endl;
    4544    gLog << " General Output Options: "<< endl;
     
    9291    gLog << " showplot -b --print --print-cmd='cat %f' filename.root > filename.ps" << endl;
    9392    gLog << " showplot -b --save-as-ps filename.root" << endl;
    94     gLog << " showplot -q --save-as-gif=tab5.gif --tab=5 filename.root" << endl;
     93    gLog << " showplot -b --save-as-gif=tab5.gif --tab=5 filename.root" << endl;
    9594    gLog << " showplot -b --save-as-ps --print=lp2 filename.root" << endl;
    9695    gLog << endl;
     
    164163    }
    165164
    166     const Bool_t kQuit       = arg.HasOnlyAndRemove("-q");
    167165    const Bool_t kBatch      = arg.HasOnlyAndRemove("-b");
    168166    const Bool_t kRoot       = arg.HasOnlyAndRemove("-r");
     
    308306    gLog << endl;
    309307
    310     if (kBatch || kQuit || (arg.GetNumArguments()>0 && d->GetNumTabs()==0))
     308    if (kBatch || (arg.GetNumArguments()>0 && d->GetNumTabs()==0))
    311309    {
    312310        delete d;
Note: See TracChangeset for help on using the changeset viewer.