I am trying to fill a simple RooDataSet with, among other things, a RooRealVar that has an asymmetric error. I do this within the framework of a CMSSW analyzer. The basic idea is that I declare a pointer to a RooDataSet object, as well as pointers to the variables that define its dimension, as private data members of the CMSSW analyzer class; something like
class ParPlotter : public edm::EDAnalyzer {
public:
ParPlotter(const edm::ParameterSet& pset);
virtual ~ParPlotter();
void fillParDataset();
private:
virtual void analyze(const edm::Event& event, const edm::EventSetup& eventSetup) {};
virtual void endRun(const edm::Run &run, const edm::EventSetup &setup) {};
RooCategory* effVar_;
RooRealVar* binNumber_;
RooCategory* parName_;
RooRealVar* parVal_;
RooDataSet* parData_;
};
In the constructor for ParPlotter, I set up the RooDataSet:
ParPlotter::ParPlotter(const edm::ParameterSet& pset)
{
//define dimensions of RooDataSet
effVar_ = new RooCategory(“effVar”, “”);
for (VSTRING_IT iEffVar = effVars_.begin(); iEffVar != effVars_.end(); ++iEffVar) {
effVar_->defineType((*iEffVar).c_str());
}
binNumber_ = new RooRealVar(“binNumber”, “Bin number”, -1.0);
parName_ = new RooCategory(“parName”, “”);
for (VSTRING_IT iParName = parNames_.begin(); iParName != parNames_.end(); ++iParName) {
parName_->defineType((*iParName).c_str());
}
parVal_ = new RooRealVar(“parVal”, “”, -1.0);
parData_ = new RooDataSet(“parData”, “”, RooArgSet(*effVar_, *binNumber_, *parName_, *parVal_));
//go!
fillParDataset();
makePlots();
}
Then, I call a function called fillParDataset() to fill the RooDataSet with information I extract from a ROOT file. It looks like:
void ParPlotter::fillParDataset()
{
//open file
TFile* file = NULL;
bool fileErr = false;
try { file = new TFile(inputFile_.c_str()); }
catch (cms::Exception& ex) { fileErr = true; }
if (!fileErr && (file != NULL)) {
file->cd();
//loop over efficiency variables
for (VSTRING_IT iEffVar = effVars_.begin(); iEffVar != effVars_.end(); ++iEffVar) {
const unsigned int effVarIndex = iEffVar - effVars_.begin();
//loop over bins
int iBin = 0;
while (iBin != -1) {
file->cd();
stringstream name1;
name1 << "PhotonToID/" << *iEffVar << "/" << branchNames_[effVarIndex] << "_bin" << iBin;
name1 << "__gaussPlusLinear/";
//get RooFitResult for parameters and their errors
RooFitResult* fitRes = NULL;
file->GetObject(plotAux_.name(name1.str(), "fitresults").c_str(), fitRes);
if (fitRes != NULL) {
//loop over parameters in the RooFitResult
RooArgList pars = fitRes->floatParsFinal();
for (VSTRING_IT iParName = parNames_.begin(); iParName != parNames_.end(); ++iParName) {
const Int_t parIndex = iParName - parNames_.begin();
//fill RooDataSet
effVar_->setLabel((*iEffVar).c_str());
*binNumber_ = iBin;
parName_->setLabel((*iParName).c_str());
*parVal_ = ((RooRealVar&)pars[parIndex]).getVal();
parVal_->setAsymError(((RooRealVar&)pars[parIndex]).getErrorLo(),
((RooRealVar&)pars[parIndex]).getErrorHi());
//debug printout: does the error get set? answer: yes
cout << "error: (+" << parVal_->getErrorHi() << ", -" << parVal_->getErrorLo() << ")\n";
//RooDataSet filled here
parData_->add(RooArgSet(*effVar_, *binNumber_, *parName_, *parVal_));
/*********************************/
//debug printout: see that the error on "parVal" in row 0 is identical to the error on "parVal" in the last added row!
cout << "Row 0:\n";
const RooArgSet* row0 = parData_->get(0);
row0->Print("v");
cout << "Current row:\n";
const RooArgSet* row = parData_->get(parData_->numEntries() - 1);
row->Print("v");
/*********************************/
}//for (VSTRING_IT iParName = parNames_.begin(); iParName != parNames_.end(); ++iParName)
//increment iBin
++iBin;
}//if (fitRes != NULL)
else {
cout << "Error getting RooFitResult with name ";
cout << plotAux_.name(name1.str(), "fitresults") << ".\n";
iBin = -1;
}//else
}//while (iBin != -1)
}//for (VSTRING_IT iEffVar = effVars_.begin(); iEffVar != effVars_.end(); ++iEffVar)
file->Close();
}//if (!fileErr)
else cerr << "Error opening file " << inputFile_ << “.\n”;
delete file;
}
The problem is in setting the asymmetric error for the RooRealVar parVal_. The error correctly gets set for whatever the current (i.e. last added) row of the RooDataSet is, but then that same value also overwrites the error values on all previous rows. For example, when I run this code, I get a printout like (this is just a small sample of it)
width
error: (+1.84628, --1.84628)
Row 0:
- 0xc82b278 RooCategory:: effVar = pt “”
- 0xc82bf20 RooRealVar:: binNumber = 0 C L(-INF - +INF) “Bin number”
- 0xc82c510 RooCategory:: parName = cFail “”
- 0xc82d500 RooRealVar:: parVal = -0.056243 +/- (-1.84628,1.84628) C L(-INF - +INF) ""
Current row: - 0xc82b278 RooCategory:: effVar = run “”
- 0xc82bf20 RooRealVar:: binNumber = 0 C L(-INF - +INF) “Bin number”
- 0xc82c510 RooCategory:: parName = width “”
- 0xc82d500 RooRealVar:: parVal = 1 +/- (-1.84628,1.84628) C L(-INF - +INF) “”
cFail
error: (+0.0278142, --0.0278142)
Row 0:
- 0xc82b278 RooCategory:: effVar = pt “”
- 0xc82bf20 RooRealVar:: binNumber = 0 C L(-INF - +INF) “Bin number”
- 0xc82c510 RooCategory:: parName = cFail “”
- 0xc82d500 RooRealVar:: parVal = -0.056243 +/- (-0.0278142,0.0278142) C L(-INF - +INF) ""
Current row: - 0xc82b278 RooCategory:: effVar = run “”
- 0xc82bf20 RooRealVar:: binNumber = 1 C L(-INF - +INF) “Bin number”
- 0xc82c510 RooCategory:: parName = cFail “”
- 0xc82d500 RooRealVar:: parVal = 0.0333502 +/- (-0.0278142,0.0278142) C L(-INF - +INF) “”
The error in item 4 of the “current row” printout always matches the error in item 4 of the “row 0” printout. But the central values are different (as expected), as is the parName_ value. In fact, all of the variables are filled correctly in the RooDataSet, including the central value of parVal_. It’s just the asymmetric error on parVal_.
This is obviously a problem because at the end of filling the dataset, all the data points (rows) have the error of the last data point filled, when I would clearly like all the data points to have different (correct) errors. How can I fix this?
Thanks,
Rachel Yohay