Extract contours from plot

Hello,

I need to extract contours from a TH2D in order to plot them with labels. The following code fragment [code]
TH2D h2 = TH2D(“h2”,“landscape”,nbinsx,0,nbinsx,nbinsy,0,nbinsx);
for (int i = 0; i < points.size(); i++)
{
h2.Fill( points.at(i).x, points.at(i).y, points.at(i).z );
}
h2.Draw(“cont1”);

std::cout << LINE << std::endl;

TObjArray *contours = gROOT->GetListOfSpecials()->FindObject(“contours”);
Int_t ncontours = contours->GetSize();
[/code]

causes a compilation error:

contourXYZ.cxx:55:74: error: invalid conversion from ‘TObject*’ to ‘TObjArray*’ [-fpermissive]
TObjArray *contours = gROOT->GetListOfSpecials()->FindObject(“contours”);

I tried using:

TObjArray *contours = (TObjectArray*)gROOT->GetListOfSpecials()->FindObject("contours");

which compiles, but causes a seg fault.

I am compiling outside CINT with ROOT 5.34/09 using gcc version 4.8.2 on ArchLinux. The compile command used is:

g++ -Lroot-config --libdir -Iroot-config --incdir -o contour -lHist -lCore -lUtilityLibrary contourXYZ.cxx

Thanks for any help.

Roger

Can you provide the minimum code sample reproducing your problem?
What you demonstrated is not a valid macro/code.
Do you check that the pointer you have from gROOT->GetList… is not null before using it?

Thanks for your response. I upgraded to root v_5.34/15 and added a test for a NULL pointer.

Here is the complete code:

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>

#include "TApplication.h"
#include "TObjArray.h"
#include "TROOT.h"
#include "TH2D.h"
#include "TMath.h"
#include "TCanvas.h"

#include "UtilityLibrary.h" // definition for NumberFromString<double>(X).

struct Point_3 {
  double x;
  double y;
  double z;
} p;

int main (int argc, char *argv[])
{
  // If no TApplication, canvas disappears instantly.
  TApplication* theApp = new TApplication("App", &argc, argv);

  std::ifstream iFile;		// File stream for xyx file
  std::string X, Y, Z;
  std::vector<Point_3> points;
  iFile.open( "landscape.xyz" );
  while ( !iFile.eof() )
    {
      iFile >> X >> Y >> Z;	// strings

      p.x = NumberFromString<double>(X);
      p.y = NumberFromString<double>(Y);
      p.z = NumberFromString<double>(Z);
      points.push_back( p );
    }
  std::cout << "There are " << points.size() << " values in the file" << std::endl;
  Int_t nbinsx = TMath::Sqrt( points.size() );
  Int_t nbinsy = nbinsx;
  TH2D h2 = TH2D("h2","landscape",nbinsx,0,nbinsx,nbinsy,0,nbinsx);
  for (Size_t i = 0; i < points.size(); i++) 
    {
      h2.Fill( points.at(i).x, points.at(i).y, points.at(i).z );
    }
  h2.Draw("CONT LIST");

  std::cout << __LINE__ << std::endl;

  TObjArray *contours = (TObjArray *)gROOT->GetListOfSpecials()->FindObject("contours");
  if ( !contours ) {
    std::cout << "countours is NULL, quitting. " << std::endl;
    return 1;
  } else {
    std::cout << "*contours contains" << contours << std::endl;
  }

  Int_t ncontours = contours->GetSize();
  std::cout << "There are " << ncontours << " contour levels." << std::endl;

// Run the TApplication (not needed if you don't want to see the surface.)
  theApp->Run();

    return 0;
}

The pointer is indeed NULL. After the message "countours is NULL, quitting. ", the application crashes.

Thanks again for any help.
Roger