Home | News | Documentation | Download

Adding multiple weights variables to RooDataSet

I can easily add a weight variable to create a RooDataSet object using multiple constructors available for it. For ex:

RooDataSet (const char *name, const char *title, const RooArgSet &vars, const char *wgtVarName=0)

Here wgtVarName can be the weight variable name of the type RooRealVar.
I am in a situation where I have 2 weight variables in my input data(weight1, weight2). I want to create a RooDataSet object which contains both weight variables. How can I do that?

@jonas could you please take a look whenever you will have time? Thanks!

Hi @pkalbhor,

unfortunately there is currently no way to set multiple weight variables. Is it okay for you to create two different datasets with different weight variables? Or is the dataset so large that the limited memory on your machine prohibits doing that?

If it’s absolutely necessary to have different weight variables without duplicating the dataset, let me know and we can develop a solution for the next ROOT version, but for now I’m afraid duplicating is the only way.

Cheers,
Jonas

Hi @jonas,
Thank you for a reply.
My goal is to fit an observable after applying both weights on the same distribution. It’s like, apply both weights one after other on same distribution.
By creating 2 different datasets with different weight variables, I will have two different shapes of observable. Can I able to merge them to create a single dataset preserving both weight variables(Which then I can use for fitting)?

Hi @pkalbhor,

thanks for the clarification, I misunderstood what you wanted. So if I understand correctly, your question is actually the same one as asked here in 2013: Create RooDataSet with RooFormulaVar as weight

Since the RooDataSet doesn’t support non-fundamental variables, you can’t create a new derived variable like the product of your two weights and set it as the weight of the data set.

You’d have to calculate your final weight product before entering RooFit land and creating the DataSet. If you fill your dataset values in the macro, you can do it like this:

void example1() {
    using namespace RooFit;

    RooRealVar x("x","x",-10,10);
    RooRealVar s("s","s",1,1,10);
    RooRealVar m("m","m",0,-10,10);
    RooGaussian g("gauss","gauss(x,m,s)",x,m,s);

    RooRealVar w1("w1","w1",0,20);
    RooRealVar w2("w2","w2",0,20);
    RooRealVar w3("w3","w3",0,20);

    RooArgSet columns{x, w1, w2, w3};

    RooDataSet dataSet1("dataSet1","dataSet1",columns,WeightVar(w3));

    for (Int_t j=0; j<10000; ++j){

        x.setVal(gRandom->Gaus(0,1));

        w1.setVal(10 + gRandom->Gaus(0,1));
        w2.setVal((10 + gRandom->Gaus(0,1)) / 2.0);

        w3.setVal(w1.getVal() * w2.getVal());

        dataSet1.add(columns);
    }

    dataSet1.Print();
}

If you get your data from the TTree or from some file in general, it is probably more complicated. Let me know if this is the case and we can find a solution.

Cheers,
Jonas

1 Like

Hi @jonas,
Thanks for the solution. Yes, I get my data from TTree which is saved in a root file. I do it this way:

void Example(){
	TFile *_file0 = new TFile("InputFile.root", "READ");
	TTree *tree=(TTree*)_file0->Get("tree");
	RooRealVar x = RooRealVar("x", "x", 5.1, 5.6);
	RooRealVar weight1 = RooRealVar("weight1", "weight1", 0, 5);
	RooRealVar weight2 = RooRealVar("weight2", "weight2", 0, 100);
	RooRealVar NewWeight = RooRealVar("NewWeight", "NewWeight", 0, 20);
	RooArgSet columns{x, NewWeight};
	RooDataSet *tempData = new RooDataSet("tempData", "temporary dataset", RooArgSet(x, weight1, weight2), RooFit::Import(*tree), RooFit::Cut("1"));
	RooDataSet *finalDataset = new RooDataSet("finalDataset","finalDatset", columns, RooFit::WeightVar("NewWeight"));
	for(Int_t j=0; j<tempData->numEntries(); j++){ 
		    RooArgSet *args = (RooArgSet*)tempData->get(j);
		    Float_t xx = ((RooRealVar*)args->find("x"))->getVal();
		    Float_t myweight = ((RooRealVar*)args->find("weight1"))->getVal()*((RooRealVar*)args->find("weight2"))->getVal();
		    x.setVal(xx);
		    NewWeight.setVal(myweight);
		    finalDataset->add(columns, myweight);
		}
	finalDataset->Print();
}

Please let me know if I can reduce the number of lines from this code. Can there be a smarter implemention of this?

Hi @pkalbhor,

no, I don’t see a way to reduce the number of lines here in a meaningful way. Is it working for you? I hope it runs fast enough.

Cheers,
Jonas

Hi @jonas,
Yes, it is working fine. TTree I am working on is not very big, so it didn’t make much difference in terms of runtime.