[ROOT] Collection Classes

From: Stanley Forrester (sforrest@lifshitz.ucdavis.edu)
Date: Thu Oct 03 2002 - 21:41:50 MEST


I have written a script which for a list of valid data files in a 
target directory "obtains" both a sequential number (probably 
unnecessary) and run number, both cast as Float_t and saved to an Ntuple 
and stored in a .root file.  Another script uses the Run Number and 
sprintf to recreate the file name  in order to access the required data.

Do to changes in the file naming convention, I now also need to store the 
actual file name. I could test two cases for old and new files, but this 
would not be robust in the case of future changes to the naming 
convention.

What is the best way to accomplish this, Trees or a Collection Class? It 
is proving deucedly difficult to save a simple string.  Could you possibly 
provide a simple example?

Also is there a way for Root to directly read file names from a target 
directory?  My script works but is hardly what one would call elegant as 
it depends on Unix system calls and is therefore platform dependent.

-- 
Thanks 
Stanley Forrester     

Script posted below

////////////////////////////////////////////////////////////////////////////
//
//       The following script requires that you provide an range of 
//    run numbers, both a minimum and a maximum.  You must also provide 
//    the exact path to the production files to be examined.
//
//    Purpouse:  Provide a persistant list of valid run numbers ( from 
//    which the file names can be reconstructed ) in the target directory.
//
//    The Function takes as arguments the min and max run numbers in the 
//    range.
//
//    Stan Forrester, UC Davis, 01 October 2002
//
/////////////////////////////////////////////////////////////////////////////

gROOT->Reset();



void KSimon(Int_t MinRunNumber, Int_t MaxRunNumber){ // begin function 
KSimon()


  // This section uses grep and other system calls to determine which
  // run numbers within the given range have valid data files.

  Int_t RunNumbers[2000];
  Int_t x, FileNumber, numberOfFilesFound = 0;
  Float_t y,z;


  char FileName[256];
  char GrepString[256];

  // Use system calls to remove any old temp file and then to create a new 
file called "file.list"
  // containing a listing of the files in the data directory.
  gSystem->Exec("rm file.list"); 
  gSystem->Exec("ls /cd .... /hist/sum_hist* 
> file.list"); 


  TFile *f = new TFile("file_list.root","RECREATE");
  TNtuple *ntuple = new TNtuple("ntuple","Valid Run 
Numbers","numberOfFilesFound:FileNumber");
  
  cout << "Now compliing a list of no more than 2000 valid run numbers \n 
from within the given range. Please wait. \n"; 

  for(int i = MinRunNumber; i <= MaxRunNumber; i++)
    {    // begin for loop to determine good run numbers.
      
      FileNumber = i; 
      
      //  This section reads the list of files and using a little 
      //  Unix script magic determines which ones are valid production 
      //  runs and stores the valid file name in a character array 
      //  FileName.
      
      // Create and execute a command line string.
      sprintf( GrepString ,"grep %i file.list > file.name", FileNumber); 
      gSystem->Exec("rm -rf file.name");  // remove old file.
      gSystem->Exec(GrepString);
      
      // open the resulting data file
      FILE *fp = fopen("./file.name","r");

      // Reset FileName Array.  Needed since I check the second entry 
      // to see if it is a valid part of the path name.
      for (int k = 0; k <= 255 ; k++){ FileName[k] = NULL;};
      
      // Read the file name into the Array FileName.  Could be all Null.
      for (int k = 0; k<= 255; k++)    fscanf(fp,"%c", &FileName[k]);
      
      // If the second character IS NOT a NULL character then I have a 
      // "valid" file name and a valid production run.
      if (  FileName[1] != NULL ) {
	cout << FileNumber << " is a Good file \n " ;
	
	RunNumbers[ numberOfFilesFound ] = FileNumber;
	y = numberOfFilesFound;  // cast both Int_t as Folat_t.
 	z = FileNumber;
	ntuple->Fill( y,z );
	numberOfFilesFound++;
	
	if ( numberOfFilesFound == 1999){
	  cout << " The Given Range may return more than 2000 files.  \n";
	  cout << " About to exceed array size. \n";
	  cout << " Last file number inspected is " << FileNumber << "\n";
	  break;
	}
		
      }
      // Clean up.  I close my file.
      fclose(fp);
      
    } // end for loop to determine good run numbers.
  cout << " The number of files found is " << numberOfFilesFound << ".\n";
  


  if ( numberOfFilesFound == 2000 ) cout << "Working with files found. 
Please wait. \n";
  cout << "Working \n";

  f->Write();

  f->Close();

}



This archive was generated by hypermail 2b29 : Sat Jan 04 2003 - 23:51:12 MET