Filling a TH2D in map(pair<int, int>,TH2D)

Greetings,

I must use root 5.34.36 for the software.
In a code I make a map(pair<int, int>,TH2D)

When I try to fill the TH2D I get error

/Users/michaelkunkel/WORK/HADESPANDA/Analysis/./test.C:53:17: error: no matching member function for call to 'Fill'
    res->second.Fill(1.,2.);
    ~~~~~~~~~~~~^~~~
/usr/local/Cellar/root/5.34.36_2/include/root/TH2.h:70:21: note: candidate function not viable: no known conversion from 'const TH2D' to 'TH2' for
      object argument
   virtual Int_t    Fill(Double_t x, Double_t y);
                    ^
/usr/local/Cellar/root/5.34.36_2/include/root/TH2.h:63:13: note: candidate function not viable: no known conversion from 'const TH2D' to 'TH2' for
      object argument
...
...

I am not trying to save the map to a tree, just use it as a logical container. The Write() and GetTitle() methods work.

Here is a MWE

#include <iostream>
#include <map>

#include <TH2.h>
#include <TH2D.h>

#include <TH1.h>
#include <TF2.h>

std::map<pair<int, int>, TH2D> myMap;

void test(){
  double tdcmin = -850, tdcmax = -350;
  int ntdcbins = 250;
  
  TH2D *t_vs_t;
  
  for (int i = 1; i<=47; i=i+2) {
    
    t_vs_t = new TH2D (Form("t%d_vs_t%d",i,i+1), Form("t%d_vs_t%d",i,i+1),ntdcbins, tdcmin, tdcmax, ntdcbins, tdcmin, tdcmax);
    myMap[std::make_pair(i,i+1)] = *t_vs_t;

  }
  
  for(map<pair<int, int>, TH2D>::const_iterator it = myMap.begin(); it != myMap.end(); ++it)
  {
    std::cout << it->first.first << " " << it->first.second << " " << it->second.GetTitle() << "\n"; //works
    //it->second.Write();  //works
  }
  map<pair<int, int>, TH2D>::const_iterator res;
  res = myMap.find(std::make_pair(1,2));
  if(res != myMap.end()){
    res->second.Fill(1.,2.); //does not work
   cout << res->second.GetTitle()<< "\n"; //works
  }  
}

Any guidance is appreciated.

Why not use pointers and avoid the copy constructors?

#include <iostream>
#include <map>

#include <TH2D.h>

void test(){
  const double tdcmin = -850, tdcmax = -350;
  const int ntdcbins = 250;

  std::map<pair<int, int>, TH2D*> myMap;  
  
  for (int i = 1; i<=47; i=i+2) {
    myMap[std::make_pair(i,i+1)] = new TH2D (Form("t%d_vs_t%d",i,i+1), 
       Form("t%d_vs_t%d",i,i+1),ntdcbins, tdcmin, tdcmax, ntdcbins, tdcmin, tdcmax);
  }
  
  for(map<pair<int, int>, TH2D*>::const_iterator it = myMap.begin(); it != myMap.end(); ++it) {
    std::cout << it->first.first << " " << it->first.second << " " << it->second->GetTitle() << "\n"; 
  }
  map<pair<int, int>, TH2D*>::const_iterator res;
  res = myMap.find( std::make_pair(1,2) );
  if(res != myMap.end()) {
    res->second->Fill(1.,2.); 
   cout << res->second->GetTitle() << "\n"; 
  }  
}

EDIT @behrenhoff explains what is happening below.

You are using a const_iterator but Fill obviously isn’t const. That is also what your error message says: no known conversion from 'const TH2D' to 'TH2'.

Solutions:
a) (the obvious one) use a non-const iterator
b) (what I would suggest) change your map. Make the value a TH2* instead of a TH2D, i.e. std::map<pair<int, int>, TH2*> myMap; You can then remove the variable t_vs_t and your loop can look like this:

for (int i = 1; i<=47; i=i+2) {
    myMap[std::make_pair(i,i+1)] = new TH2D(Form("t%d_vs_t%d",i,i+1), Form("t%d_vs_t%d",i,i+1),
                                            ntdcbins, tdcmin, tdcmax,
                                            ntdcbins, tdcmin, tdcmax);
}

This will also get rid of the useless copy of the histogram you’re making in the myMap[...] = *t_vs_t line.

And finally the histograms in this map can also be filled using the map’s const_iterator because it will just make the pointer const, i.e. accessing it->second is accessing a TH2* const, not a const TH2*.

///

Final comment: I find it a bit strange that you have a pair as map key. At least in this code the pair is always (i,i+1), thus it would be sufficient to use i as key.

Edit: @ksmith: you obviously had the same idea and were a few seconds faster :slight_smile:

1 Like

Thanks everyone. Clears everything up.

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