TH1 to ascii question

Dear Rooters,

I was wondering if there is an elegant way of dumping the contents of a histogramm to a plain ascii file.

I know about the TH1::Print() function, where I can get this, but there I always have the format of sumw[i]=…, x=…, y=… .

What I would like to have is a plain ascii print without any formatting.

Any hints appreciated.

Cheers,

Erik

Dear erik,

I was looking for exactly the same and finally wrote my own ASCII export function. It looks like this:

/**
 * \brief Export Single Histogram into ASCII file
 */
Bool_t TRemiHistExport::SingleExportAscii(TH1* hist, TString &filename, TString folder="", TString separator="\t") 
{
	Int_t i,j;
	Double_t xcenter, xwidth;
	Bool_t success=kFALSE;
	filename = folder + hist->GetName() + ".dat";
	ofstream file_out(filename);
	file_out << "# Output " << hist->ClassName() << ": " << hist->GetName() << " (" << hist->GetTitle() << ")\n";
	if (hist->GetDimension()==1)
	{
		file_out << "# BinCenter" << separator << "Content" << separator << "BinHalfWidth" << separator << "Error\n";
		for (i=1; i<=hist->GetNbinsX(); i++)
			file_out << hist->GetBinCenter(i) << separator << hist->GetBinContent(i) << separator << hist->GetBinWidth(i)/2 << separator << hist->GetBinError(i) << endl;
		if (i>1)
			success=kTRUE;
	}
	else if (hist->GetDimension()==2)
	{
		file_out << "# xBinCenter" << separator << "yBinCenter" << separator << "Content" << separator << "xBinHalfWidth" << separator << "yBinHalfWidth" << separator << "Error" << endl;
		for (i=1; i <= hist->GetNbinsX(); i++)
		{
			xcenter = hist->GetXaxis()->GetBinCenter(i);
			xwidth = hist->GetXaxis()->GetBinWidth(i)/2;
			for (j=1; j <= hist->GetNbinsY(); j++)
				file_out << xcenter << separator << hist->GetYaxis()->GetBinCenter(j) << separator << hist->GetBinContent(i,j) << separator << xwidth << separator << hist->GetYaxis()->GetBinWidth(j)/2 << separator << hist->GetBinError(i,j) << endl;
			if (j>1)
				file_out << endl; // produce a blank line after each set of Ybins for a certain Xbin. Gnuplot likes this.
		}
		if (i>1)
			success=kTRUE;
	}
	file_out.close();
	if (success == kTRUE)
		cout << "*** TRemiHistExport: Histogram " << hist->GetName() << " written to " << filename << endl;
	return success;
}

Hope this helps you1

Kind Regards,
Arne.

Hi Arne,

thanks for this, this does exactly what I want. Would be nice to have it as part of the TH1::Print() with option “plain” or something like this.

Cheers,

Erik

Sorry for such a newbie question but how do I use this piece of code? I cannot run it as a macro, so how is it used to convert the root histogram into an ascii file?

Many thanks in advance

see documentation of TH1::Print
root > myhist.Print(“all”); //print to terminal
root > myhist.Print(“all”); > myhist.dat print to file myhist.dat

Rene

Thanks for the reply but my question was how to execute Arne’s code described above.

I have used the myhist->Print(“all”) > output.txt before but it formats the text in an undesirable way. I would like plain columns with no descriptive text.

I would like to be without the “fsumw” etc

Hi Aspetts,

I don’t know while the given code should not work as a macro. However, use it as a member of a class handling the export of histograms.
If you remove “TRemiHistExport::” from the example and save it as SingleExportAscii.C it should also work as a macro.

Kind Regards,
Arne.

Thanks for reply.

SO lets day I have a root file with a histogram called hist1 in it.

After implementing your change so as it can be run as a macro are these set of commands correct?

.L SingleExportAscii

SingleExportAscii(hist1,MyChosenNameForHist,)

Not sure what to put for folder and separator arguments so I have left them blank.

Many thanks, apetts

Hi again,

actually the use of the “filename” argument for this function is not as input, but as output. I.e. the filename of the ascii file is generated from the histogram’s name and written to the “filename” string as a reference. Therefore you have to name a valid TString variable in the function call:

E.g.

TH1I *hist1 = new TH1I (...);
TString histfilename = "";
SingleExportAscii(hist1, histfilename);

The other arguments of the SingleExportAscii function are optional. If you leave them blank, the file will be written into the current folder and the data values will be separated by tabulators. The filename where hist1 was exported to will be contained in histfilename.

Kind Regards,
Arne.

[quote=“apetts”]Thanks for the reply but my question was how to execute Arne’s code described above.

I have used the myhist->Print(“all”) > output.txt before but it formats the text in an undesirable way. I would like plain columns with no descriptive text.

I would like to be without the “fsumw” etc[/quote]
I did
root> h->Print(“all”); > h.dat
bash> perl -ne ‘($a,$b)=($_=~/fSumw[(\d+)]=(\d+)/);print “$a $b\n”;’ h.dat > h.2col

In case you are looking for a c++ executable callable from the command line (outside of ROOT) that does the same job, try this! How to compile and use it is included in the file.

http://people.physics.tamu.edu/fenkerbb/convertTH1.cpp
convertTH1.cpp (2.55 KB)

1 Like

I am getting error while trying to write the output in a file. Output on terminal is working fine but not in a file. I am using ROOT 6.14 and a novice. Thanks

root [9] h2->Print(“all”) > ; “output.txt”
ROOT_prompt_9:1:20: error: expected expression
h2->Print(“all”) > ; “output.txt”

ROOT Forum -> Search -> “ROOT 6 redirect”

1 Like
root [0] .> output.txt
h2->Print(“all”) > ;
.>
root[3]