Changeset 5692 for trunk/MagicSoft/Mars/mfileio
- Timestamp:
- 01/03/05 12:02:16 (20 years ago)
- Location:
- trunk/MagicSoft/Mars/mfileio
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/MagicSoft/Mars/mfileio/MReadTree.cc
r5160 r5692 18 18 ! Author(s): Thomas Bretz, 12/2000 <mailto:tbretz@astro.uni-wuerzburg.de> 19 19 ! 20 ! Copyright: MAGIC Software Development, 2000-200 320 ! Copyright: MAGIC Software Development, 2000-2005 21 21 ! 22 22 ! … … 24 24 25 25 ///////////////////////////////////////////////////////////////////////////// 26 // // 27 // MReadTree // 28 // // 29 // This tasks opens all branches in a specified tree and creates the // 30 // corresponding parameter containers if not already existing in the // 31 // parameter list. // 32 // // 33 // The Process function reads one events from the tree. To go through the // 34 // events of one tree make sure that the event number is increased from // 35 // outside. It makes also possible to go back by decreasing the number. // 36 // // 37 // If you don't want to start reading the first event you have to call // 38 // MReadTree::SetEventNum after instantiating your MReadTree-object. // 39 // // 40 // To make reading much faster (up to a factor of 10 to 20) you can // 41 // ensure that only the data you are really processing is enabled by // 42 // calling MReadTree::UseLeaf. // 43 // // 44 // If the chain switches from one file to another file all // 45 // TObject::Notify() functions are called of TObject objects which were // 46 // added to the Notifier list view MReadTree::AddNotify. If MReadTree // 47 // is the owner (viw MReadTree::SetOwner) all this objects are deleted // 48 // by the destructor of MReadTree // 49 // // 26 // 27 // MReadTree 28 // 29 // This tasks opens all branches in a specified tree and creates the 30 // corresponding parameter containers if not already existing in the 31 // parameter list. 32 // 33 // The Process function reads one events from the tree. To go through the 34 // events of one tree make sure that the event number is increased from 35 // outside. It makes also possible to go back by decreasing the number. 36 // 37 // If you don't want to start reading the first event you have to call 38 // MReadTree::SetEventNum after instantiating your MReadTree-object. 39 // 40 // To make reading much faster (up to a factor of 10 to 20) you can 41 // ensure that only the data you are really processing is enabled by 42 // calling MReadTree::UseLeaf. 43 // 44 // If the chain switches from one file to another file all 45 // TObject::Notify() functions are called of TObject objects which were 46 // added to the Notifier list view MReadTree::AddNotify. If MReadTree 47 // is the owner (viw MReadTree::SetOwner) all this objects are deleted 48 // by the destructor of MReadTree 49 // 50 // 51 // ToDo: 52 // ----- 53 // - Auto Scheme and Branch choosing doesn't work for memory trees 54 // 50 55 ///////////////////////////////////////////////////////////////////////////// 51 56 #include "MReadTree.h" … … 73 78 // -------------------------------------------------------------------------- 74 79 // 75 // Default constructor. Don't use it. 76 // 77 MReadTree::MReadTree() 80 // Default constructor. Use this constructor (ONLY) if you want to 81 // access a memory tree (a TTree not stored in a file) created by 82 // MWriteRootFile or manually. 83 // 84 MReadTree::MReadTree(TTree *tree) 78 85 : fNumEntry(0), fNumEntries(0), fBranchChoosing(kFALSE), fAutoEnable(kTRUE) 79 86 { … … 81 88 fTitle = "Task to loop over all events in one single tree"; 82 89 83 fVetoList = NULL; 84 fNotify = NULL; 90 fVetoList = new TList; 91 fVetoList->SetOwner(); 92 93 fNotify = new TList; 85 94 86 95 fChain = NULL; 96 97 fTree = tree; 98 SetBit(kChainWasChanged); 99 100 if (fTree) 101 fAutoEnable = kFALSE; 102 /* 103 if (!fTree) 104 return; 105 106 TIter Next(fTree->GetListOfBranches()); 107 TBranch *b=0; 108 while ((b=(TBranch*)Next())) 109 b->ResetAddress(); 110 */ 87 111 } 88 112 … … 114 138 // 115 139 fChain = new MChain(tname); 140 fTree = fChain; 116 141 117 142 // root 3.02: … … 122 147 if (fname) 123 148 AddFile(fname); 124 // if (fChain->Add(fname)>0)125 // SetBit(kChainWasChanged);126 149 } 127 150 … … 137 160 // creates a memory leak! 138 161 // 139 TIter Next(fChain->GetStatus()); 140 141 TChainElement *element = NULL; 142 while ((element=(TChainElement*)Next())) 143 if (element->GetBaddress()) 144 delete (MParContainer**)element->GetBaddress(); 145 146 // 147 // Delete the chain and the veto list 148 // 162 if (fChain) // FIXME: MEMORY LEAK for fTree!=0 163 { 164 TIter Next(fChain->GetStatus()); 165 166 TChainElement *element = NULL; 167 while ((element=(TChainElement*)Next())) 168 if (element->GetBaddress()) 169 delete (MParContainer**)element->GetBaddress(); 170 171 // 172 // Delete the chain and the veto list 173 // 149 174 #if ROOT_VERSION_CODE < ROOT_VERSION(3,03,00) 150 if (fChain->GetFile())151 delete fChain->GetFile();175 if (fChain->GetFile()) 176 delete fChain->GetFile(); 152 177 #endif 153 delete fChain; 178 delete fChain; 179 } 180 181 /* This is AND MUST be done in PostProcess. See there for more details 182 else 183 { 184 TIter Next(fTree->GetListOfBranches()); 185 186 TBranch *element = NULL; 187 while ((element=(TBranch*)Next())) 188 if (element->GetAddress()) 189 delete (MParContainer**)element->GetAddress(); 190 } 191 */ 154 192 155 193 delete fNotify; … … 179 217 Bool_t MReadTree::CheckBranchSize() 180 218 { 181 TArrayI entries(fChain->GetStatus()->GetSize()); 219 //if (!fChain) // >FIXME: fTree!=0 220 // return kTRUE; 221 222 TArrayI entries(fChain ? fChain->GetStatus()->GetSize() : fTree->GetListOfBranches()->GetSize()); 182 223 Int_t num=0; 183 224 184 225 // Loop over all branches which have a corresponding container 185 TIter Next(fChain->GetStatus()); 186 187 TChainElement *element = NULL; 188 while ((element=(TChainElement*)Next())) 189 { 190 // Get branch name and find pointer to corresponding branch 191 const TString name = element->GetName(); 192 const TBranch *b = fChain->FindBranch(name); 193 194 // Skip element without corresponding branches (like "*") 195 if (!b) 196 continue; 197 198 entries[num++] = (Int_t)b->GetEntries(); 226 /* 227 if (fChain) 228 { 229 TIter Next(fChain->GetStatus()); 230 231 TChainElement *element = NULL; 232 while ((element=(TChainElement*)Next())) 233 { 234 // Get branch name and find pointer to corresponding branch 235 const TString name = element->GetName(); 236 const TBranch *b = fChain->FindBranch(name); 237 238 // Skip element without corresponding branches (like "*") 239 if (!b) 240 continue; 241 242 entries[num++] = (Int_t)b->GetEntries(); 243 } 244 } 245 else */ 246 { 247 TIter Next(fTree->GetListOfBranches()); 248 249 TBranch *element = NULL; 250 while ((element=(TBranch*)Next())) 251 entries[num++] = (Int_t)element->GetEntries(); 199 252 } 200 253 … … 209 262 *fLog << " Due to several circumstances (such at a bug in MReadTree or wrong" << endl; 210 263 *fLog << " usage of the file UPDATE mode) you may have produced a file in which" << endl; 211 *fLog << " at least two branches in the same tree (" << f Chain->GetName() << ") have different" << endl;264 *fLog << " at least two branches in the same tree (" << fTree->GetName() << ") have different" << endl; 212 265 *fLog << " number of entries. Sorry, but this file (" << GetFileName() << ")" << endl; 213 266 *fLog << " is unusable." << endl; … … 278 331 Int_t MReadTree::AddFile(const char *fname, Int_t entries) 279 332 { 333 if (!fChain) 334 { 335 *fLog << err << "MReadTree::AddFile - ERROR: You cannot add a file, because MReadTree" << endl; 336 *fLog << " handles a memory based tree or its default" << endl; 337 *fLog << " constructor was called." << endl; 338 return 0; 339 } 340 280 341 #if ROOT_VERSION_CODE < ROOT_VERSION(3,03,01) 281 342 // … … 353 414 Int_t MReadTree::AddFiles(const MReadTree &read) 354 415 { 416 if (!fChain) 417 { 418 *fLog << err << "MReadTree::AddFiles - ERROR: You cannot add a file, because MReadTree" << endl; 419 *fLog << " handles a memory based tree or its default" << endl; 420 *fLog << " constructor was called." << endl; 421 return 0; 422 } 423 355 424 const Int_t rc = fChain->Add(read.fChain); 356 425 … … 376 445 void MReadTree::SortFiles() 377 446 { 378 fChain->GetListOfFiles()->Sort(); 447 if (fChain) 448 fChain->GetListOfFiles()->Sort(); 379 449 } 380 450 … … 392 462 393 463 *fLog << inf << GetDescriptor() << ": Branch choosing enabled (only enabled branches are read)." << endl; 394 f Chain->SetBranchStatus("*", kFALSE);464 fTree->SetBranchStatus("*", kFALSE); // *CHANGED-fChain-to-fTree* 395 465 fBranchChoosing = kTRUE; 396 466 } … … 405 475 void MReadTree::EnableBranch(const char *name) 406 476 { 477 if (!fChain) 478 { 479 *fLog << warn << "MReadTree::EnableBranch - WARNING: EnableBranch doesn't work with memory based trees... ignored." << endl; 480 return; 481 } 482 407 483 if (fChain->GetListOfFiles()->GetEntries()==0) 408 484 { … … 424 500 void MReadTree::SetBranchStatus(const char *name, Bool_t status) 425 501 { 426 f Chain->SetBranchStatus(name, status);502 fTree->SetBranchStatus(name, status); // *CHANGED-fChain-to-fTree* 427 503 428 504 *fLog << inf << (status ? "Enabled" : "Disabled"); … … 449 525 bn.Remove(bn.Length()-1); 450 526 451 if (f Chain->GetBranch(bn))527 if (fTree->GetBranch(bn)) // *CHANGED-fChain-to-fTree* 452 528 SetBranchStatus(name, status); 453 529 … … 461 537 return; 462 538 463 if (f Chain->GetBranch(dot+1))539 if (fTree->GetBranch(dot+1)) // *CHANGED-fChain-to-fTree* 464 540 SetBranchStatus(dot+1, status); 465 541 } … … 575 651 if (TestBit(kChainWasChanged)) 576 652 { 577 *fLog << inf << "Scanning chain " << fChain->GetName() << "... " << flush; 578 fNumEntries = (UInt_t)fChain->GetEntries(); 653 // *CHANGED-fChain-to-fTree* 654 *fLog << inf << "Scanning chain " << fTree->GetName() << "... " << flush; 655 fNumEntries = (UInt_t)fTree->GetEntries(); 579 656 *fLog << fNumEntries << " events found." << endl; 580 657 ResetBit(kChainWasChanged); … … 624 701 // tasks are not preprocessed. 625 702 // 626 f Chain->SetNotify(NULL);703 fTree->SetNotify(NULL); //*CHANGED-fChain-to-fTree* 627 704 628 705 // … … 633 710 // it crashes. ResetTree makes sure, that the tree number is -1 634 711 // 635 fChain->ResetTree(); 712 if (fChain) // *CHANGED-fChain-to-fTree* 713 fChain->ResetTree(); 636 714 // Maybe this would be enough, but the above might be safer... 637 715 //if (fChain->GetTreeNumber()==0) … … 641 719 // check for files and for the tree! 642 720 // 643 if ( !fChain->GetFile())721 if (fChain && !fChain->GetFile()) // *CHANGED-fChain-to-fTree* 644 722 { 645 723 *fLog << err << GetDescriptor() << ": No file or no tree with name " << fChain->GetName() << " in file." << endl; … … 665 743 // create the Iterator to loop over all branches 666 744 // 667 TIter Next(f Chain->GetListOfBranches());745 TIter Next(fTree->GetListOfBranches()); // *CHANGED-fChain-to-fTree* 668 746 TBranch *branch=NULL; 669 747 … … 728 806 // If we created one already, delete it. 729 807 // 730 TChainElement *element = (TChainElement*)fChain->GetStatus()->FindObject(bname); 731 if (element) 732 delete (MParContainer**)element->GetBaddress(); 808 // *CHANGED-fChain-to-fTree* 809 if (fChain) 810 { 811 TChainElement *element = (TChainElement*)fChain->GetStatus()->FindObject(bname); 812 if (element) 813 delete (MParContainer**)element->GetBaddress(); 814 } 815 /* This can't be done here for memory trees - see 816 PostProcess for more details. 817 else 818 { 819 TBranch *branch = (TBranch*)fTree->GetBranch(bname); 820 if (branch) 821 { 822 *fLog << bname << " " << (void*)branch->GetAddress() << " " << pcont << endl; 823 delete (MParContainer**)branch->GetAddress(); 824 } 825 } 826 */ 733 827 734 828 // … … 736 830 // the actual branch should be stored - enable branch. 737 831 // 738 f Chain->SetBranchAddress(bname, pcont);832 fTree->SetBranchAddress(bname, pcont); // *CHANGED-fChain-to-fTree* 739 833 740 834 *fLog << inf << "Master branch address '" << bname << "' ["; … … 762 856 // PreProcess-function. 763 857 // 764 fChain->ResetTree(); 765 fChain->SetNotify(this); 766 767 return GetSelector() ? GetSelector()->CallPreProcess(pList) : kTRUE; 858 if (fChain) 859 fChain->ResetTree(); // *CHANGED-fChain-to-fTree* 860 861 fTree->SetNotify(this); // *CHANGED-fChain-to-fTree* 862 863 const Int_t rc = GetSelector() ? GetSelector()->CallPreProcess(pList) : kTRUE; 864 if (rc!=kTRUE || fChain) 865 return rc; 866 867 return Notify(); 768 868 } 769 869 … … 775 875 void MReadTree::SetReadyToSave(Bool_t flag) 776 876 { 877 if (!fChain) 878 return; 879 777 880 TIter Next(fChain->GetStatus()); 778 881 … … 870 973 } 871 974 872 const Bool_t rc = f Chain->GetEntry(fNumEntry++) != 0;975 const Bool_t rc = fTree->GetEntry(fNumEntry++) != 0; // *CHANGED-fChain-to-fTree* 873 976 874 977 if (fTaskList) 875 fTaskList->SetStreamId(f Chain->GetName());978 fTaskList->SetStreamId(fTree->GetName()); // *CHANGED-fChain-to-fTree* 876 979 877 980 if (rc) … … 887 990 Int_t MReadTree::PostProcess() 888 991 { 992 // In the case of a memory tree I don't know how we can 993 // make a decision in PreProcess between a self allocated 994 // memory address or a pending address set long before. 995 // So we delete the stuff in PostProcess and not the destructor 996 // (which might seg faullt if PreProcess has never been called) 997 if (!fChain) 998 { 999 TIter Next(fTree->GetListOfBranches()); 1000 TBranch *b=0; 1001 while ((b=(TBranch*)Next())) 1002 { 1003 if (b->GetAddress()) 1004 { 1005 delete b->GetAddress(); 1006 b->ResetAddress(); 1007 } 1008 } 1009 } 1010 889 1011 return GetSelector() ? GetSelector()->CallPostProcess() : kTRUE; 890 1012 } … … 896 1018 Bool_t MReadTree::GetEvent() 897 1019 { 898 Bool_t rc = f Chain->GetEntry(fNumEntry) != 0;1020 Bool_t rc = fTree->GetEntry(fNumEntry) != 0; // *CHANGED-fChain-to-fTree* 899 1021 900 1022 if (rc) … … 981 1103 TString MReadTree::GetFileName() const 982 1104 { 983 const TFile *file = fChain ->GetFile();1105 const TFile *file = fChain ? fChain->GetFile() : fTree->GetCurrentFile(); 984 1106 985 1107 if (!file) … … 997 1119 Int_t MReadTree::GetFileIndex() const 998 1120 { 999 return fChain ->GetTreeNumber();1121 return fChain ? fChain->GetTreeNumber() : 0; 1000 1122 /* 1001 1123 const TString filename = fChain->GetFile()->GetName(); -
trunk/MagicSoft/Mars/mfileio/MReadTree.h
r5160 r5692 8 8 class MChain; 9 9 class TBranch; 10 class TTree; 10 11 class MTaskList; 11 12 … … 15 16 16 17 private: 17 MChain *fChain; // Pointer to tree 18 MChain *fChain; // Pointer to tree==fTree (only if fTree inherits from MChain) 19 TTree *fTree; // Pointer to tree 18 20 19 21 UInt_t fNumEntry; // Number of actual entry in chain … … 23 25 Bool_t fAutoEnable; // Flag for auto enabeling scheme 24 26 25 TList *fVetoList; // List of Branches which are not allowed to get enabled26 TList *fNotify; // List of TObjects to notify when switching files27 TList *fVetoList; //-> List of Branches which are not allowed to get enabled 28 TList *fNotify; //-> List of TObjects to notify when switching files 27 29 28 30 MTaskList *fTaskList; // Tasklist to set StreamId … … 47 49 48 50 public: 49 MReadTree( );51 MReadTree(TTree *tree=0); 50 52 MReadTree(const char *treename, const char *filename=NULL, const char *name=NULL, const char *title=NULL); 51 53 ~MReadTree(); -
trunk/MagicSoft/Mars/mfileio/MWriteRootFile.cc
r4826 r5692 18 18 ! Author(s): Thomas Bretz, 6/2001 <mailto:tbretz@astro.uni-wuerzburg.de> 19 19 ! 20 ! Copyright: MAGIC Software Development, 2000-200 420 ! Copyright: MAGIC Software Development, 2000-2005 21 21 ! 22 22 ! … … 37 37 // ReInit()) For more details se the corresponding constructor. 38 38 // 39 // Memory based trees 40 // ------------------ 41 // It is possible to store the data into memory (TTrees) instead of 42 // writing the data into a file. To do this either call the default 43 // constructor or specify 'memory' as option in the constructor. 44 // 45 // Afterwards the tree can be found using gROOT->FindObject("treename") 46 // 47 // Currently(!) the tree is not deleted at all! Please make sure to 48 // delete it if it is not used anymore - otherwise you could wast a LOT 49 // of memory. Please consider that this behaviour might change in the 50 // future. 51 // 52 // Such trees are usefull if you want to use more basic root-tools 53 // like TMultiLayerPerceptron or TEventList. 54 // 55 // If you want to process such memory based Trees using Mars make sure, 56 // that you don't need data from the RunHeader tree because you can 57 // only use MReadTree but not MReadMarsFile with such a tree. 58 // 39 59 ///////////////////////////////////////////////////////////////////////////// 40 60 #include "MWriteRootFile.h" … … 72 92 73 93 // 74 // Believing the root user guide, TTree instance dare owned by the94 // Believing the root user guide, TTree instances are owned by the 75 95 // directory (file) in which they are. This means we don't have to 76 96 // care about their destruction. … … 87 107 { 88 108 Init(); 89 90 //91 // Set the Arrays the owner of its entries. This means, that the92 // destructor of the arrays will delete all its entries.93 //94 fBranches.SetOwner();95 109 } 96 110 … … 133 147 // 134 148 MWriteRootFile::MWriteRootFile(const char *fname, 135 const Option_t *opt ,149 const Option_t *option, 136 150 const char *ftitle, 137 151 const Int_t comp, 138 152 const char *name, 139 const char *title) 153 const char *title) : fOut(NULL) 140 154 { 141 155 Init(name, title); 156 157 TString opt(option); 158 opt.ToLower(); 159 160 // 161 // Check if we are writing to memory 162 // 163 if (opt.Contains("memory")) 164 { 165 fSplitRule = fname; 166 return; 167 } 142 168 143 169 // … … 172 198 Print(); 173 199 174 // 175 // If the file is still open (no error) write the keys. This is necessary 176 // for appearance of the all trees and branches. 177 // 178 if (IsFileOpen()) 179 fOut->Write(); 180 181 // 182 // Delete the file. This'll also close the file (if open) 183 // 184 delete fOut; 185 fOut = 0; 200 if (fOut) 201 { 202 // 203 // If the file is still open (no error) write the keys. This is necessary 204 // for appearance of the all trees and branches. 205 // 206 if (IsFileOpen()) 207 fOut->Write(); 208 209 // 210 // Delete the file. This'll also close the file (if open) 211 // 212 delete fOut; 213 fOut = 0; 214 } 186 215 187 216 // … … 257 286 void MWriteRootFile::AddContainer(const char *cname, const char *tname, Bool_t must) 258 287 { 288 if (!fOut && !tname) 289 tname = fSplitRule; 290 259 291 TIter Next(&fBranches); 260 292 TObject *o=0; … … 262 294 if (TString(o->GetName())==TString(tname) && TString(o->GetTitle())==TString(cname)) 263 295 { 296 *fLog << warn; 264 297 *fLog << "WARNING - Container '" << cname << "' in Tree '" << tname << "' already scheduled... ignored." << endl; 265 298 return; … … 290 323 Bool_t must) 291 324 { 325 if (!fOut && !tname) 326 tname = fSplitRule; 327 292 328 TIter Next(&fBranches); 293 329 TObject *o=0; … … 296 332 static_cast<MRootFileBranch*>(o)->GetContainer()==cont) 297 333 { 334 *fLog << warn; 298 335 *fLog << "WARNING - Container " << cont << " in Tree '" << tname << "' already scheduled... ignored." << endl; 299 336 return; … … 378 415 379 416 // 380 // Check if the tree is already existing (part of the file) 381 // 382 TTree *tree = (TTree*)fOut->Get(tname); 417 // Check if the tree is already existing (part of the file or memory) 418 // 419 TTree *tree = fOut ? (TTree*)fOut->Get(tname) : dynamic_cast<TTree*>(gROOT->FindObject(tname)); 420 if (!fOut && tree) 421 { 422 if (tree->GetCurrentFile()) 423 { 424 *fLog << err; 425 *fLog << "ERROR - You are trying to write data into a memory stored root tree," << endl; 426 *fLog << " because you either called the default constructor or have" << endl; 427 *fLog << " instantiated MWriteRootFile using the write option 'memory'." << endl; 428 *fLog << " This tree '" << tname << "' is already existing in" << endl; 429 *fLog << " memory (gROOT->FindObject) and is already belonging to a" << endl; 430 *fLog << " file (" << tree->GetCurrentFile()->GetName() << ")." << endl; 431 *fLog << " This can - for example - happen if you are reading from a" << endl; 432 *fLog << " tree with the same name. The easiest solution in this case" << endl; 433 *fLog << " is to change the name of the tree you want to write to." << endl; 434 *fLog << endl; 435 return kFALSE; 436 } 437 *fLog << inf << "Tree '" << tname << "' found already in Memory... using." << endl; 438 } 439 383 440 if (!tree) 384 441 { … … 389 446 // 390 447 TDirectory *save = gDirectory; 391 fOut->cd(); 392 393 tree = new TTree(tname, ttitle); 448 if (fOut) 449 fOut->cd(); 450 else 451 gROOT->cd(); 452 453 tree = new TTree(tname, ttitle, fOut ? 99 : 1); 394 454 fTrees.AddLast(tree); 395 455 … … 567 627 568 628 // 629 // If we are writing into memory we don't split into seperate files 630 // 631 if (!fOut) 632 return kTRUE; 633 634 // 569 635 // For more information see TTree:ChangeFile() 570 636 // … … 774 840 // -------------------------------------------------------------------------- 775 841 // 776 // return open state of the root file. 842 // return open state of the root file. If the file is 'memory' kTRUE is 843 // returned. 777 844 // 778 845 Bool_t MWriteRootFile::IsFileOpen() const 779 846 { 847 if (!fOut) 848 return kTRUE; 849 780 850 const char *n = fOut->GetName(); 781 851 return n==0 || *n==0 ? kTRUE : fOut->IsOpen(); … … 784 854 // -------------------------------------------------------------------------- 785 855 // 786 // return name of the root-file 856 // return name of the root-file. If the file is "memory" "<memory>" is 857 // returned. 787 858 // 788 859 const char *MWriteRootFile::GetFileName() const 789 860 { 861 if (!fOut) 862 return "<memory>"; 863 790 864 const char *n = fOut->GetName(); 791 865 return n==0 || *n==0 ? "<dummy>" : n; … … 794 868 // -------------------------------------------------------------------------- 795 869 // 796 // cd into file. See TFile::cd() 870 // cd into file. See TFile::cd(). If the file is "memory" kTRUE is returned. 797 871 // 798 872 Bool_t MWriteRootFile::cd(const char *path) 799 873 { 800 return fOut ->cd(path);874 return fOut ? fOut->cd(path) : kTRUE; 801 875 } 802 876 … … 809 883 void MWriteRootFile::StreamPrimitive(ofstream &out) const 810 884 { 811 out << " MWriteRootFile " << GetUniqueName() << "(\""; 812 out << fOut->GetName() << "\", \""; 813 out << fOut->GetOption() << "\", \""; 814 out << fOut->GetTitle() << "\", "; 815 out << fOut->GetCompressionLevel(); 816 817 if (fName!=gsDefName || fTitle!=gsDefTitle) 818 { 819 out << ", \"" << fName << "\""; 820 if (fTitle!=gsDefTitle) 821 out << ", \"" << fTitle << "\""; 822 } 823 out << ");" << endl; 824 885 out << " MWriteRootFile " << GetUniqueName(); 886 if (fOut) 887 { 888 out << "(\""; 889 out << fOut->GetName() << "\", \""; 890 out << fOut->GetOption() << "\", \""; 891 out << fOut->GetTitle() << "\", "; 892 out << fOut->GetCompressionLevel(); 893 out << ")"; 894 } 895 out << ";" << endl; 896 897 if (fName!=gsDefName) 898 out << " " << GetUniqueName() << ".SetName(\"" << fName << "\");" << endl; 899 if (fTitle!=gsDefTitle) 900 out << " " << GetUniqueName() << ".SetTitle(\"" << fTitle << "\");" << endl; 825 901 826 902 MRootFileBranch *entry;
Note:
See TracChangeset
for help on using the changeset viewer.