Accessing FileHeader Information in ROOT Files
As of EngineeringModel v4r060302p13 and GlastRelease v6r6p0416, header information is written by default to the MC, Digi, and Recon ROOT files.
To see if your ROOT file includes header information:
- Start up ROOT and open your ROOT file:
- Enter:
TFile f("ldf_digi.root", "READ")
f.ls()
You have header information in your file if you see a response similar to:
TFile** |
|
ldf_digi.root |
|
|
TFile* |
|
ldf_digi.root |
|
|
|
KEY: TProcessID |
|
ProcessID0;1 |
0081d634-8eb2-1266-a022-3a564f86beef |
|
|
KEY: TTree |
Digi;2 |
GLAST Digitization Data |
|
|
KEY: FileHeader |
|
|
header;1 |
|
|
|
|
|
|
|
|
- To read the header, enter:
f.MakeProject("headerlib", "FileHeader", "recreate++");
FileHeader *header = (FileHeader*)f.Get("header");
Tip: If you know what version of commonRootData to use, you can load it and read in the FileHeader (thereby providing an easier interface to utilize the header information) by entering:
gSystem->Load("libcommonRootData.so");
FileHeader *h = (FileHeader*)f.Get("header");
Search the TKeys in a ROOT File for FileHeader
You can also search the TKeys in a ROOT file any occurances of FileHeader.
Where f is a TFile, enter:
gSystem->Load("libcommonRootData.so");
TFile f("myRootFile.root");
TList *keyList = f.GetListOfKeys( );
TIter keyIter(keyList);
FileHeader *header = 0;
while (TKey *key = (TKey*)keyIter.Next()) {
if (key->GetClassName( ) == "FileHeader") header = (FileHeader*)key->ReadObj( );
}
Default Contents of the FileHeader
GLAST's FileHeader class contains three TMaps, and each map has a name as its key. There is a map for integers, doubles, and strings. Each TMap can be searched or iterated over using ROOT's TMapIter class.
As of this writing, only the TMap of TStrings has content by default. This content includes:
Exercise:
The following code will search the TMap of Strings for the "CmtPackages" entry and find out what version of EngineeringModel package was used to generate this ROOT file.
Note: The following code snippet works "as is" only if you loaded commonRootData. If using Make Project, replace the bolded line: |
TString packages = header->getString(curName->GetName());
|
with: |
TObject* value = header->m_strings.GetValue(curName->GetName());
packages = value ? ((TObjString*)value)->GetString() : "";
|
TString searchStr("CmtPackages");
TMapIter &stringIter = TMapIter(&header.m_strings);
TNamed *curName = 0;
while (curName = (TNamed*)stringIter.Next()) {
if (searchStr.CompareTo(curName->GetName()) {
TString packages = header->getString(curName->GetName());
Ssiz_t ind = packages.Index("EngineeringModel ", 17, 0);
Int_t strLen = 35;
TString engModelStr = packages(ind, strLen);
TObjArray *engModelCol = engModelStr.Tokenize(" ");
TObjString *versionStr = (TObjString*)engModelCol->At(1);
cout << "EM Tag " << versionStr->GetString() << endl;
}
}
Notes:
The code curName->GetName( ) returns the name of the current TMap entry, which is the key. We can then use that key to retrieve the corresponding TString.
In this case, we searched for the key "CmtPackages" which should exist in all FileHeaders and contain the set of CMT packages that were in our CMTPATH when our application was running.
Once found, we use the knowledge that the cmt show packages command returns the list of packages and their tags in the form:
packageName tag path
Hence, we search for "EngineeringModel" and then, using the TString::Tokenize method, we construct an array of strings delimited using blank spaces.
Owned by: Heather Kelly
Last updated by: Chuck Patterson
05/24/2005 |
|
|