Re: moving a TDirectory from one TFile to another

From: stefan kluth (skluth@mh1.lbl.gov)
Date: Tue Dec 01 1998 - 00:39:36 MET


On Thu, 26 Nov 1998, Rene Brun wrote:
> TDirectory/TFile do not provide the functionality to copy/move
> directories between files. This could be implemented using
> the normal Unix semantics (say TDirectory::Mv and Cp).
> Currently you must loop yourself on all keys of a directory,
> import the object in memory and write it on the new directory.

Hi, here is some code which does almost what I want. It works fine on DEC
unix, but crashes at the end of the job on Sun. Appearently, my code
misses to fix something and ROOTs internal bookkeeping gets out of sync. 

...

  // Make sure we at the top of the current file, then save:
  checkFile();
  gDirectory->cd( "/" );
  rtfilep->Write();

  // Get list of root objects in memory, then create the new file. 
  // Iterate on list and transfer objects from old to new file. 
  TList* list1= gDirectory->GetList();
  TIter iter( list1 );
  TFile* filep= new TFile( file, "RECREATE", 
			   "Created for you again by RooTupleManager" );
  TList* list2= filep->GetList();
  TObject* obj= 0;
  while( obj= iter.Next() ) {
    list1->Remove( obj );
    list2->Add( obj );
    if( obj->InheritsFrom( "TH1" ) ) {
      ((TH1*)obj)->SetDirectory( gDirectory );
    }
    else if( strcmp( obj->ClassName(), "TDirectory" ) == 0 ) {
      ((TDirectory*)obj)->SetMother( gDirectory );
    }
  }

  // Now we can safely get rid of the old file:
  delete rtfilep;
  rtfilep= filep;

...

Here is a traceback of the crash on Sun:

...
signal SEGV (no mapping at the fault address) in TObjectTable::Delete at
line 190 in file "BASE_ObjectTable.cxx"
  190            delete fTable[i];
(dbx) where
=>[1] TObjectTable::Delete(this = 0x346d08, _ARG1 = 0xef14dd1c ""), line
190 in "BASE_ObjectTable.cxx"
  [2] TCollection::EmptyGarbageCollection(), line 337 in
"CONT_Collection.cxx"
  [3] TFile::Close(this = 0x347ac8, _ARG1 = 0xef5f0896 ""), line 486 in
"BASE_File.cxx"
  [4] TFile::~TFile(this = 0x347ac8, delete = 3), line 319 in
"BASE_File.cxx"
  [5] RooTupleManager::~RooTupleManager(this = 0x82ff8, delete = 3), line
39 in "RooTupleManager.cc"
  [6] main(), line 52 in "testRooTM3.cc"
...

Any ideas what I am doing wrong/forgetting to do?

cheers, Stefan

BTW, this wouldn't work with TTrees, because TTree does not have a member
function TTree::SetDirectory. I am not sure if it would be possible to
transfer TTrees between TDirectories/TFiles anyway.

---Stefan Kluth---------------Lynen Fellow----------------|\--|\-------
-  LBNL, MS 50A 2160       -  phone:  +1 510 495 2376  -  |/  |/      -
-  1 Cyclotron Rd.         -  fax:    +1 510 495 2957  -  |\/\|\/\|'  -
---Berkeley, CA94720, USA-----e-mail: SKluth@lbl.gov------|/\/|/\/|----



This archive was generated by hypermail 2b29 : Tue Jan 04 2000 - 00:34:40 MET