- Timestamp:
- 05/05/10 10:03:14 (15 years ago)
- Location:
- trunk/MagicSoft/Mars
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/MagicSoft/Mars/Changelog
r9579 r9580 38 38 * msimcamera/MSimCalibrationSignal.cc: 39 39 - 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 40 52 41 53 -
trunk/MagicSoft/Mars/mbase/MStatusArray.cc
r9571 r9580 58 58 #include "MStatusDisplay.h" 59 59 60 //#define DEBUG 61 60 62 ClassImp(MStatusArray); 61 63 … … 73 75 } 74 76 77 #ifdef DEBUG 78 static void *ptr = 0; 79 #endif 80 75 81 // -------------------------------------------------------------------------- 76 82 // … … 78 84 // name) recuresively 79 85 // 80 voidMStatusArray::RecursiveDelete(TVirtualPad *p, const char id) const86 Bool_t MStatusArray::RecursiveDelete(TVirtualPad *p, const char id) const 81 87 { 82 88 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())) 88 96 { 89 97 if (!dynamic_cast<TVirtualPad*>(o) && (o->ClassName()[0]==id || id==0)) … … 95 103 // get removed from the pad if deleted, and therefore 96 104 // 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 111 112 delete o; 112 113 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; 119 125 } 120 126 … … 136 142 obj->ResetBit(kMustCleanup); 137 143 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. 138 147 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 } 139 165 140 166 if (!pad) 141 167 return; 142 168 169 // If object was a pad go one layer deeper 143 170 TIter Next(pad->GetListOfPrimitives()); 144 171 TObject *o=0; … … 147 174 } 148 175 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 178 class MyGraph : public TGraph 179 { 180 public: 181 void ResetListOfFunctions() 182 { 183 fFunctions = 0; 184 } 185 }; 186 187 void 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 169 226 if (g->GetHistogram()==obj) 227 { 228 #ifdef DEBUG 229 cout << " SetHist(0)" << endl; 230 #endif 170 231 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. 187 263 // 188 264 void MStatusArray::RecursiveRemove(TObject *obj) 189 265 { 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) 206 294 // 207 295 void MStatusArray::Delete(Option_t *) … … 211 299 gROOT->GetListOfCleanups()->Add(this); 212 300 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 214 303 TIter Next(this); 215 304 TObject *o=0; … … 221 310 TIter Next2(this); 222 311 while ((o=Next2())) 223 RecursiveDelete(dynamic_cast<TVirtualPad*>(o), 'M');312 while (!RecursiveDelete(dynamic_cast<TVirtualPad*>(o), 'M')); 224 313 225 314 // Now delete all root objects 226 315 TIter Next3(this); 227 316 while ((o=Next3())) 228 RecursiveDelete(dynamic_cast<TVirtualPad*>(o));317 while (!RecursiveDelete(dynamic_cast<TVirtualPad*>(o))); 229 318 230 319 // And delete all the rest -
trunk/MagicSoft/Mars/mbase/MStatusArray.h
r9532 r9580 20 20 21 21 void SetCleanup(TObject *obj) const; 22 voidRecursiveDelete(TVirtualPad *p, const char id=0) const;22 Bool_t RecursiveDelete(TVirtualPad *p, const char id=0) const; 23 23 24 24 void SetCanDelete(const TCollection *list) const; … … 27 27 void PrintObjectsInPad(const TCollection *list, const TString &name, Int_t lvl=0) const; 28 28 TObject *FindObjectInPad(TVirtualPad *pad, const char *object, TClass *base) const; 29 void RecursiveRemove(TCollection *c, TObject *o); 29 30 30 31 public: … … 62 63 void Delete(Option_t *option=""); 63 64 64 void RecursiveRemove(TVirtualPad *p, TObject *o);65 65 void RecursiveRemove(TObject *o); 66 66 -
trunk/MagicSoft/Mars/mbase/MStatusDisplay.cc
r9578 r9580 790 790 MapWindow(); 791 791 792 UpdateMemory(); 793 792 794 // FIXME: This is a workaround, because TApplication::Run is not 793 795 // thread safe against ProcessEvents. We assume, that if … … 1010 1012 MapSubwindows(); 1011 1013 Layout(); 1014 1015 UpdateMemory(); 1012 1016 1013 1017 // display new tab in the main frame … … 1164 1168 Layout(); // layout the embedded canvas in the frame 1165 1169 1170 UpdateMemory(); 1171 1166 1172 // display new tab in the main frame 1167 1173 // FIXME: This is a workaround, because TApplication::Run is not … … 1442 1448 MapSubwindows(); // maps the TGCompositeFrame 1443 1449 Layout(); // layout the embedded canvas in the frame 1450 1451 UpdateMemory(); 1444 1452 1445 1453 // display new tab in the main frame … … 2253 2261 // FIXME: This is a workaround for the problem with the MAstroCatalog in 2254 2262 // 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); 2257 2265 2258 2266 // Add the clone and its draw-option to the current pad -
trunk/MagicSoft/Mars/showplot.cc
r9576 r9580 41 41 gLog << " Options: "<< endl; 42 42 gLog.Usage(); 43 gLog << " -q Quit when job is finished" << endl;44 43 gLog << endl; 45 44 gLog << " General Output Options: "<< endl; … … 92 91 gLog << " showplot -b --print --print-cmd='cat %f' filename.root > filename.ps" << endl; 93 92 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; 95 94 gLog << " showplot -b --save-as-ps --print=lp2 filename.root" << endl; 96 95 gLog << endl; … … 164 163 } 165 164 166 const Bool_t kQuit = arg.HasOnlyAndRemove("-q");167 165 const Bool_t kBatch = arg.HasOnlyAndRemove("-b"); 168 166 const Bool_t kRoot = arg.HasOnlyAndRemove("-r"); … … 308 306 gLog << endl; 309 307 310 if (kBatch || kQuit ||(arg.GetNumArguments()>0 && d->GetNumTabs()==0))308 if (kBatch || (arg.GetNumArguments()>0 && d->GetNumTabs()==0)) 311 309 { 312 310 delete d;
Note:
See TracChangeset
for help on using the changeset viewer.