Hi ROOTers
I am trying to write my own classes into XML files. I was successful at this using the following script and using TObjects:
{
TFile *file = TFile::Open("demo.xml","recreate");
TH1F *h = new TH1F("hwoow","test",1000,-2,2);
h->FillRandom("gaus");
//h->Write();
file->WriteObject(h,"h9585");
file->Close();
file=TFile::Open("demo.xml");
if(!file->IsZombie()){
TH1F *h2=(TH1F*) file->Get("h9585");
cout << "Test session started ******************************" << endl;
cout << "Name : " << h2->GetName() << endl;
cout << "Npars : " << h2->GetNdivisions() << endl;
file->Close();
}
I got the following output running this last script:
Now I want to do this same operation using my own class. So far, I have been able to generate the XML file (see attachment:calib.xml). However I am having problems reading the XML file. I do not know yet where is my mistake, what I am missing. So far, my classes do not derive from the TObject class. This could change if needed.
My class structure looks like this
CMName.h
CMBackGroundObj.h
CMSingletObj.h
TPeakFitter.h
CMMasterCalibObj.h
The relation between them is the following
CMBackGroundObj.h inherits from CMName.h
CMSingletObj.h inherits from CMName.h
TPeakFitter.h inherits from CMName.h
and it contains a vector<CMBackGroundObj*> and a vector<CMSingletObj*>
CMMasterCalibObj.h contains a vector<TPeakFitter*>
Now each include header file has the ClassDef(class_name,1) macro and
each source file has the ClassImp(class_name) macro.
My linkDef.h looks like this
My question is, reading from ROOT docs, do I need to generate my own streamers or is it enough to generate the root dictionary code?
Another question is that my vector<> member objects are private. Would that be a problem for the ROOT streamers? I like to think it is not a problem since I was able to generate an XML file from my CMMasterCalibObj class.
When I try to read my XML file of my custom class using the following partial code:
//Previously define in header file
vector<CMMasterCalibObj*> UsrCalibVector;
//...
//...
//...
//NOW the code
//SECOND STEP: Get Pointer to calibObj
int intPReqID=-1;
CMMasterCalibObj *selectedCal;
vector<CMMasterCalibObj*>::iterator it = UsrCalibVector.begin();
bool bFound=false;
while(it!=UsrCalibVector.end() && !bFound){
if((*it)->GetCalibID()==intPReqID){
selectedCal = (*it);
bFound=true;
}
}
//THIRD STEP: Save as a XML file
TFile *fOut = TFile::Open("calib.xml","recreate");
fOut->WriteObjectAny(selectedCal,"CMMasterCalibObj","mySelCalib");
fOut->Close();
//FOURTH STEP: Test by opening XML file
TFile *fileRead = TFile::Open("calib.xml");
if(!fileRead->IsZombie()){
selectedCal=(CMMasterCalibObj*)fileRead->Get("mySelCalib");
cout << "Name of calibration: " << selectedCal->GetName() << endl;
cout << "Number of calibration points: " << selectedCal->CountCalPeaks() << endl;
cout << selectedCal->PrintResults();
fileRead->Close();
}
else
cout << "Error opening XML" << endl;
I get the following output:
Hmmm… any suggestions?