Strange problem with plotting histograms

Hello,
I wrote a program to read in root files and plot some variables. Code compiles without any errors or even warning. Program also runs without errors, for the most part. From time to time (pretty random) I will get one of the two different errors (see below). The most strange part is that plots I obtain are not consistent. With every run I would something different. Some of them are correct, some don’t have all histograms and some are just empty. I have spent whole day to figure that out and I don’t have no idea. Please help! I include here the function that is responsible for plotting, but I also attach whole code.

class DrawingOptions {
	public:
		enum TYPE { MARK, FILL, HATCH };
		DrawingOptions(const char * fn);
		~DrawingOptions() {};
		void readOptions(const char * fileName);
		void applyOptions(TH1D * histo, string name);
		string getLegendOptions(const string & name);
		string getDrawOptions(const string & name, bool same);
		TYPE getHistogramType(const string & name);
		unsigned getStack(const string & name);
	private:
		struct HistOpt {
			string name_;
			TYPE type_;
			unsigned style_;
			float size_;
			unsigned color_;
			string leg_;
			string draw_;
			unsigned stack_;
		};
		vector<HistOpt> options_;
};

typedef pair<TH1D *, string> HS;

void makePlots(vector<HS> histograms, DrawingOptions drawOp, string outputDir) {
	bool logScale = true;
	bool setMin = true;
	bool setMax = true;

	if (!histograms.size()) {
		cout << "WARNING: No histograms to plot!" << endl;
		return;
	}

	gROOT->SetStyle( "Plain" );
	gStyle->SetOptStat( "" );
	TCanvas * canv = new TCanvas( "HZZ2l2nu", "HZZ2l2nu" );

	TLegend * leg = new TLegend( 0.7, 0.8, 0.95, 1.00 );
	double font_size = (( 0.2 / histograms.size() ) < 0.04 ) ? ( 0.2 / histograms.size() ) : 0.04;
	leg->SetTextSize( font_size );
	leg->SetFillColor( 0 );

	string stackName(histograms[0].first->GetName());
	THStack histoStack( "HistogramsStack", stackName.c_str() );
	for (unsigned i = 0; i < histograms.size(); ++i) {
		unsigned stack = drawOp.getStack( histograms[i].second );
		if (stack) {
			drawOp.applyOptions(histograms[i].first, histograms[i].second);
			Option_t * legOpt = drawOp.getLegendOptions(histograms[i].second).c_str();
			leg->AddEntry(histograms[i].first, histograms[i].second.c_str(), legOpt );
			histoStack.Add( histograms[i].first );
		}
	}
	if (!histoStack.GetStack())
		cout << "WARNING: Empty stack!" << endl;

	vector<HS> histos;
	for (unsigned i = 0; i < histograms.size(); ++i) {
		DrawingOptions::TYPE histType = drawOp.getHistogramType(histograms[i].second);
		unsigned stack = drawOp.getStack( histograms[i].second );
		if (!stack && histType == DrawingOptions::FILL )
			histos.push_back( histograms[i] );
	}
	for (unsigned i = 0; i < histograms.size(); ++i) {
		DrawingOptions::TYPE histType = drawOp.getHistogramType(histograms[i].second);
		unsigned stack = drawOp.getStack( histograms[i].second );
		if (!stack && histType == DrawingOptions::HATCH )
			histos.push_back( histograms[i] );
	}
	for (unsigned i = 0; i < histograms.size(); ++i) {
		DrawingOptions::TYPE histType = drawOp.getHistogramType(histograms[i].second);
		unsigned stack = drawOp.getStack( histograms[i].second );
		if (!stack && histType == DrawingOptions::MARK )
			histos.push_back( histograms[i] );
	}

	vector<TH1D *> histosP;
	for (unsigned i = 0; i < histograms.size(); ++i)
		histosP.push_back(histograms[i].first);
	const double min = findHistosNonZeroMinimum( histosP );
	const double max = findHistosMaximum( histosP, histoStack );

	canv->cd();
	if (logScale)
		gPad->SetLogy( 1 );
	else
		gPad->SetLogy( 0 );
	gPad->Update();

	bool same = false;
	
	if ( histoStack.GetStack() ) {
		if (setMin && logScale && min > 0)
			histoStack.SetMinimum( min );
		if (setMin && !logScale)
			histoStack.SetMinimum( 0 );
		if (setMax && logScale)
			histoStack.SetMaximum( 2 * max);
		if (setMax && !logScale)
			histoStack.SetMaximum( 1.1 * max);
		histoStack.Draw("");
		gPad->Update();
		same = true;
	}
	for (unsigned i = 0; i < histos.size(); ++i) {
		if (setMin && logScale && min > 0)
			histos[i].first->SetMinimum( min );
		if (setMin && !logScale)
			histos[i].first->SetMinimum( 0 );
		if (setMax && logScale)
			histos[i].first->SetMaximum( 2 * max);
		if (setMax && !logScale)
			histos[i].first->SetMaximum( 1.1 * max);
		drawOp.applyOptions(histos[i].first, histos[i].second);
		histos[i].first->Print();
		Option_t * drawOpt = drawOp.getDrawOptions(histos[i].second, same).c_str();
		histos[i].first->Draw( drawOpt );
		Option_t * legOpt = drawOp.getLegendOptions(histos[i].second).c_str();
		leg->AddEntry(histos[i].first, histos[i].second.c_str(), legOpt );
		gPad->Update();
		same = true;
	}
	leg->Draw( "same" );
	gPad->RedrawAxis();

	string mkdir = "mkdir -p " + outputDir;
	if( system( mkdir.c_str() ) )
		cout << "Problem with creating directory!" << endl;

	string fileName = outputDir + histos[0].first->GetName() + ".ps";
	canv->SaveAs( fileName.c_str() );

	delete canv;
	delete leg;
}

Errors:

  1. Error in THistPainter::MakeChopt: options L,C,T,P are incompatible with options U and K
    *** Break *** segmentation violation
  2. *** buffer overflow detected ***: ./HZZ2l2nu terminated
    ======= Backtrace: =========
    /lib/libc.so.6(__fortify_fail+0x37)[0x7fb6d04fc537]
    /lib/libc.so.6(+0xfe3f0)[0x7fb6d04fb3f0]
    /lib/libc.so.6(+0xfd2a7)[0x7fb6d04fa2a7]
    /home/zablocki/CMS/root/lib/libHistPainter.so(_ZN12THistPainter9PaintHistEPKc+0xc90)[0x7fb6cee1e280]
    /home/zablocki/CMS/root/lib/libHistPainter.so(_ZN12THistPainter5PaintEPKc+0x845)[0x7fb6cee1ee55]
    /home/zablocki/CMS/root/lib/libGpad.so(_ZN4TPad13PaintModifiedEv+0x252)[0x7fb6d29562d2]
    /home/zablocki/CMS/root/lib/libGpad.so(_ZN7TCanvas6UpdateEv+0xd4)[0x7fb6d293bc64]
    ./HZZ2l2nu(_Z9makePlotsSt6vectorISt4pairIP4TH1DSsESaIS3_EE14DrawingOptionsSs+0xbc2)[0x407f33]
    ./HZZ2l2nu(main+0xdbf)[0x411ce7]
    /lib/libc.so.6(__libc_start_main+0xfe)[0x7fb6d041bd8e]
    ./HZZ2l2nu[0x405d79]
    ======= Memory map: ========
    00400000-0041a000 r-xp 00000000 08:02 4985534 /home/zablocki/C++/HZZ2l2nu_v2/HZZ2l2nu
    0061a000-0061b000 r–p 0001a000 08:02 4985534 /home/zablocki/C++/HZZ2l2nu_v2/HZZ2l2nu
    0061b000-0061c000 rw-p 0001b000 08:02 4985534 /home/zablocki/C++/HZZ2l2nu_v2/HZZ2l2nu
    0069f000-0188f000 rw-p 00000000 00:00 0 [heap]
    7fb6ce8a2000-7fb6cebc3000 rw-p 00000000 00:00 0
    7fb6cede1000-7fb6cee70000 r-xp 00000000 08:02 4460877 /home/zablocki/CMS/root/lib/libHistPainter.so
    7fb6cee70000-7fb6cf070000 —p 0008f000 08:02 4460877 /home/zablocki/CMS/root/lib/libHistPainter.so
    7fb6cf070000-7fb6cf072000 r–p 0008f000 08:02 4460877 /home/zablocki/CMS/root/lib/libHistPainter.so
    7fb6cf072000-7fb6cf074000 rw-p 00091000 08:02 4460877 /home/zablocki/CMS/root/lib/libHistPainter.so
    7fb6cf074000-7fb6cf075000 rw-p 00000000 00:00 0
    7fb6cf075000-7fb6cf081000 r-xp 00000000 08:01 1311436 /lib/libnss_files-2.12.1.so
    7fb6cf081000-7fb6cf280000 —p 0000c000 08:01 1311436 /lib/libnss_files-2.12.1.so
    7fb6cf280000-7fb6cf281000 r–p 0000b000 08:01 1311436 /lib/libnss_files-2.12.1.so
    7fb6cf281000-7fb6cf282000 rw-p 0000c000 08:01 1311436 /lib/libnss_files-2.12.1.so
    7fb6cf282000-7fb6cf28c000 r-xp 00000000 08:01 1311431 /lib/libnss_nis-2.12.1.so
    7fb6cf28c000-7fb6cf48b000 —p 0000a000 08:01 1311431 /lib/libnss_nis-2.12.1.so
    7fb6cf48b000-7fb6cf48c000 r–p 00009000 08:01 1311431 /lib/libnss_nis-2.12.1.so
    7fb6cf48c000-7fb6cf48d000 rw-p 0000a000 08:01 1311431 /lib/libnss_nis-2.12.1.so
    7fb6cf48d000-7fb6cf4a4000 r-xp 00000000 08:01 1311435 /lib/libnsl-2.12.1.so
    7fb6cf4a4000-7fb6cf6a3000 —p 00017000 08:01 1311435 /lib/libnsl-2.12.1.so
    7fb6cf6a3000-7fb6cf6a4000 r–p 00016000 08:01 1311435 /lib/libnsl-2.12.1.so
    7fb6cf6a4000-7fb6cf6a5000 rw-p 00017000 08:01 1311435 /lib/libnsl-2.12.1.so
    7fb6cf6a5000-7fb6cf6a7000 rw-p 00000000 00:00 0
    7fb6cf6a7000-7fb6cf6af000 r-xp 00000000 08:01 1311433 /lib/libnss_compat-2.12.1.so
    7fb6cf6af000-7fb6cf8ae000 —p 00008000 08:01 1311433 /lib/libnss_compat-2.12.1.so
    7fb6cf8ae000-7fb6cf8af000 r–p 00007000 08:01 1311433 /lib/libnss_compat-2.12.1.so
    7fb6cf8af000-7fb6cf8b0000 rw-p 00008000 08:01 1311433 /lib/libnss_compat-2.12.1.so
    7fb6cf8b0000-7fb6cf931000 r-xp 00000000 08:01 1188391 /usr/lib/libfreetype.so.6.6.0
    7fb6cf931000-7fb6cfb31000 —p 00081000 08:01 1188391 /usr/lib/libfreetype.so.6.6.0
    7fb6cfb31000-7fb6cfb36000 r–p 00081000 08:01 1188391 /usr/lib/libfreetype.so.6.6.0
    7fb6cfb36000-7fb6cfb37000 rw-p 00086000 08:01 1188391 /usr/lib/libfreetype.so.6.6.0
    7fb6cfb37000-7fb6cfb40000 r-xp 00000000 08:01 1311425 /lib/libcrypt-2.12.1.so
    7fb6cfb40000-7fb6cfd40000 —p 00009000 08:01 1311425 /lib/libcrypt-2.12.1.so
    7fb6cfd40000-7fb6cfd41000 r–p 00009000 08:01 1311425 /lib/libcrypt-2.12.1.so
    7fb6cfd41000-7fb6cfd42000 rw-p 0000a000 08:01 1311425 /lib/libcrypt-2.12.1.so
    7fb6cfd42000-7fb6cfd70000 rw-p 00000000 00:00 0
    7fb6cfd70000-7fb6cfda0000 r-xp 00000000 08:01 1310857 /lib/libpcre.so.3.12.1
    7fb6cfda0000-7fb6cff9f000 —p 00030000 08:01 1310857 /lib/libpcre.so.3.12.1
    7fb6cff9f000-7fb6cffa0000 r–p 0002f000 08:01 1310857 /lib/libpcre.so.3.12.1
    7fb6cffa0000-7fb6cffa1000 rw-p 00030000 08:01 1310857 /lib/libpcre.so.3.12.1
    7fb6cffa1000-7fb6cffe1000 r-xp 00000000 08:01 1310818 /lib/libncurses.so.5.7
    7fb6cffe1000-7fb6d01e0000 —p 00040000 08:01 1310818 /lib/libncurses.so.5.7
    7fb6d01e0000-7fb6d01e4000 r–p 0003f000 08:01 1310818 /lib/libncurses.so.5.7
    7fb6d01e4000-7fb6d01e5000 rw-p 00043000 08:01 1310818 /lib/libncurses.so.5.7
    7fb6d01e5000-7fb6d01fb000 r-xp 00000000 08:01 1310914 /lib/libz.so.1.2.3.4
    7fb6d01fb000-7fb6d03fb000 —p 00016000 08:01 1310914 /lib/libz.so.1.2.3.4
    7fb6d03fb000-7fb6d03fc000 r–p 00016000 08:01 1310914 /lib/libz.so.1.2.3.4
    7fb6d03fc000-7fb6d03fd000 rw-p 00017000 08:01 1310914 /lib/libz.so.1.2.3.4
    7fb6d03fd000-7fb6d0577000 r-xp 00000000 08:01 1311422 /lib/libc-2.12.1.so
    7fb6d0577000-7fb6d0776000 —p 0017a000 08:01 1311422 /lib/libc-2.12.1.so
    7fb6d0776000-7fb6d077a000 r–p 00179000 08:01 1311422 /lib/libc-2.12.1.so
    7fb6d077a000-7fb6d077b000 rw-p 0017d000 08:01 1311422 /lib/libc-2.12.1.so
    7fb6d077b000-7fb6d0780000 rw-p 00000000 00:00 0
    7fb6d0780000-7fb6d0798000 r-xp 00000000 08:01 1311424 /lib/libpthread-2.12.1.so
    7fb6d0798000-7fb6d0997000 —p 00018000 08:01 1311424 /lib/libpthread-2.12.1.so
    7fb6d0997000-7fb6d0998000 r–p 00017000 08:01 1311424 /lib/libpthread-2.12.1.so
    7fb6d0998000-7fb6d0999000 rw-p 00018000 08:01 1311424 /lib/libpthread-2.12.1.soAborted
    code.tgz (29.4 KB)

I cannot build your program. I get:

pb-d-128-141-235-141:HZZ2l2nu_v2 couet$ make
g++ -g -O -ansi -Wall `/home/zablocki/CMS/root/bin/root-config --cflags` -c createplot.cpp
/bin/sh: /home/zablocki/CMS/root/bin/root-config: No such file or directory
etc...

Can you send code not depending on your own account (/home/zablocki/CMS/…) ?

The error message you get shows that the plotting option you give to Draw() is not valid. Can you verify it ?

Hello,
the only thing that dependent on specific location was root-config. I changed that and also I provided stripped root files with 100 events each so that you can reproduce fully my problem. I checked that on few machines so I don’t think it’s something system dependent. Also I have to add that with smaller root files code is much more dependable, so it rarely, if ever, crashes. But still you will see strange plots, with effects I mentioned before.

The code and root files can be found here (around 1MB):
cern.ch/zablocki/code.tgz

Thank you for help.

I tried your example, I ran it several times and it does not crash for me.

As I said you probably need much bigger files to see crashing (I’m using few GB files).

Have you looked at plots? They all should have the same style, and some of them don’t.

Anyway, I was working on that a bit and I was able to improve the situation. Here are 3 things that I noticed to have impact.

  1. I rewrote plotting function so that I draw and save everything at once, not just one plot as before. That helps a bit.
  2. So far I used
    histo->SetDirectory( 0 );
    after creating each of the histograms. Now I also added
    TH1::AddDirectory(kFALSE);
    at beginning of the method that created histograms. That improves situation dramatically. I suspect that since in my code I copy histograms quite a bit, maybe some of the references to them were not deleted and somehow they interfered since they might have been more than one histogram with the same name. I’m not sure.
  3. I noticed that when I draw less layers of histograms on canvas, less problems I have.

After all, given my observations, I’m lead to believe that there is some bug in ROOT libraries, either with the way it handles large numbers of histograms or the way it draws them on canvas.

Yes they look the same