Creating a TH1 type branch error

Hi all, my program is throwing the error: Error in <TClass::New>: cannot create object of class TH1 but seems to be producing the expected output, which also behaves correctly. However, I believe this is causing some problems when I try to manipulate the output with a DataFrame (see my previous question here: Attaching vector as a branch to an existing TTree). Below are the lines I believe might have something to do with it, along with the line throwing the error commented.

TH1* pdfs[N];
    for(int ih = 0; ih < N; ih++){
        pdfs[ih] = nullptr;
    }
	for (unsigned int imodel = 0; imodel < N; imodel++) {
    _tree_pars->Branch(model_name.c_str(), &(pdfs[imodel]), 32000, 0); //This is the line creating the error. 
	}

Then an example where pdfs[imodel] is used later:

TH1D *curr_pdf = (TH1D *) array->FindObject(name.Data());
pdfs[imodel] = (TH1*) curr_pdf;

Thank you!
Best wishes,
Jaiden

In

_tree_pars->Branch(model_name.c_str(), &(pdfs[imodel]), 32000, 0);

the branch name does not depend on imodel. It looks like several branches are created with the same name, which might be the cause of the error.

1 Like

I apologise, the full bit of that code is:

 for (unsigned int imodel = 0; imodel < N; imodel++) {
                   GenericSingleSampleFitModel *this_model = (GenericSingleSampleFitModel *)(cm->GetSubModel(imodel));
                   conv::Detector_t d = this_model->GetDetector();
                   conv::BeamConf_t b = this_model->GetBeam();
                   conv::Sample_t s = this_model->GetSample();
                   conv::KineSpace_t ks = this_model->GetKineSpace();
                   std::string model_name = util::nm::MdlName(d, b, s, ks);
                   _tree_pars->Branch(model_name.c_str(), &(pdfs[imodel]), 32000, 0); //This is the line creating the error.
               }

model_name does change with imodel and I’ve checked that the branches do indeed have different names.

Could it be at when you call _tree_pars->Branch, pdfs[imodel] still points to nullptr? In this case, TTree only sees the abstract base class TH1 which, unlike the derived classes TH1D, TH1F, cannot be created in memory.

1 Like

That definitely seems sensible, do you have a suggested work around for this?

You could create a (possibly empty) histogram in pdfs[imodel] before calling TTree::Branch(). Or perhaps you can make pdfs[imodel] a vector of the concrete histogram classes, e.g. std::vector<TH1D *> instead of std::vector<TH1 *>.

1 Like

Thanks! I’ll try the first suggestion first. I think the second suggestion would be stopped by the fact I later fill it with both TH1D and TH2D objects.

Yep the first one worked! This was the exact solution:
EDIT: This caused some problems with later plotting of TH2D hists, experimenting around with a fix.

TH1* pdfs[N];
   TH1D* blankhist = new TH1D;
   for(int ih = 0; ih < N; ih++){
       pdfs[ih] = blankhist;
     //  pdfs[ih] = nullptr;
   }

So the problem was indeed it having a nullptr to the abstract base class TH1. Unfortunately as I needed the branches to interchange between TH1D and TH2D later on, just setting the array to be filled with an empty hist of either type caused problems. In the end I solved it by placing the construction of the branch after each entry was sorted into the object types, and created a bool to make sure that the loop did not repeatedly create the branches. Thank you for all your help!

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.