[ROOT-6220] Bug or feature in TH3::Project3DProfile (should be changed to to bug in TProfile3D::Project3DProfile and TProfile2D::ProfileX(Y) ) Created: 11/Apr/14  Updated: 12/Aug/15  Resolved: 07/May/14

Status: Closed
Project: ROOT
Component/s: Other
Affects Version/s: 5.34/00
Fix Version/s: None

Type: Bug Priority: Medium
Reporter: Patricia Liebing (Inactive) Assignee: Lorenzo Moneta
Resolution: Fixed Votes: 0
Labels: None


Attachments: PDF File Example_TH3Project3DProfile.pdf     File testProfileProjections.C    


The results of TH3::Project3DProfile() are not meaningful.

I believe I found the faulty line in this member function:
TProfile2D TH3::DoProjectProfile2D(const char name, const char * title, TAxis* projX, TAxis* projY,
bool originalRange, bool useUF, bool useOF)
(line 2707):
p2->Fill( projY->GetBinCenter(iybin) , projX->GetBinCenter(ixbin), outAxis->GetBinCenter(outbin), cont);

Could it be that this line should read:
p2->Fill( projY->GetBinCenter(iybin) , projX->GetBinCenter(ixbin), cont);

I am currently using Root 5.34/18, but this feature has occurred in previous versions as well. I would appreciate if this could be fixed in the next version.


Comment by Lorenzo Moneta [ 02/May/14 ]

Do you have a macro showing this problem ?
The code seems correct to me, when projecting to a Profile2D from a TH3 you should use the third histogram coordinate to compute the average to be shown as bin content for the TProfile2D


Comment by Patricia Liebing (Inactive) [ 02/May/14 ]

I don't have a specific macro, but it can be seen to go wrong with any TH3. I'm attaching a plot Example_TH3Project3DProfile.pdf, showing what I mean. On the top left ist what I would expect to get, the top right is what I get when doing
The bottom left shows the result for:
and the value of 0.5 displayed on the color axis just happens to be the bin center of the first bin of the z-axis of the original TH3. This result is exactly what I would expect from that code line in
TH3::DoProjectProfile2D, because instead of the bin content of the TH3 it fills the bin center value into the TProfile2D.

Best regards,

Comment by Patricia Liebing (Inactive) [ 02/May/14 ]

OK, now I get your point - you're saying that the result is intended to be the contents weighted average of the z-coordinate? If that is true, then of course I completely misunderstood the purpose of that function. I thought that, in analogy to a simple Project3D, which would give you the SUM of the bin contents of the TH3 over one axis, the Project3DProfile would give you the AVERAGE of the bin contents.
Then I'm sorry for the confusion, though I would suggest that the documentation should be a little clear on this. Also, would it be possible to implement a function that gives you the average of the bin contents in the future? I suppose it may be useful to many people.

Comment by Lorenzo Moneta [ 05/May/14 ]

Hi Patricia,

It could be the documentation is not 100% clear, but a Profile histogram represents one observable (e.g. x) vs the average of the other observable .
If I have understood you well, what you want is something different. You want to project a 3D histogram in a 2D histogram where instead of plotting the sum of the weights in all the bins in the projected coordinate (e.g. z), you would like the average on all the bins.
If this is really what you want, just do a normal projection to a 2D and then rescale the
content by the number of bins, so you get the average content/ z bins. You don't need to use the TProfile2D. For example you can do :

TH2 * h2 = h3->Project3D("yx");
h2->Scale(1./h3->GetZaxis()->GetNbins() );

If I have misunderstood you, please let me know


Comment by Patricia Liebing (Inactive) [ 05/May/14 ]

Hi Lorenzo,

yes, you understood me correctly. I'd say there's two ways of reducing the dimensionality, one is to average the coordinate, the other is to average the bin contents - both of which may be useful on some occasions. I realize now that ROOT doesn't have the latter functionality. Your suggestion to scale a simple projection won't work correctly of not all the z-bins are populated. In my case the x- and z- coordinate are correlated, so this method would not be applicable. Of course I can always write a macro and do the averaging myself, it would just be extremely convenient to have a function ready to use in the interactive mode.
Thanks so much for your advice and sorry for the inconvenience,

Comment by Lorenzo Moneta [ 05/May/14 ]

But I am missing the points of averaging the bin contents ? Why would you do only for the non-empty bins ?
It does not make much sense to me...
A projection make sense by integrating (summing all the bins), which is like combining all the bins together


Comment by Patricia Liebing (Inactive) [ 05/May/14 ]

In my case the x- and z- coordinate are correlated, meaning that for every x, I only have a few z-bins which are actually filled. I don't expect any events in the other z-bins, which means that when summing over all z-bins and then scaling by the number of all bins I get a much too low average value. It still make sense to average the data along z and plot them against just (x,y) if I ignore their dependence on z. Of course I can always fill a single 2D profile histogram (and I did), it's just that I obviously misunderstood the functionality of the Project3DProfile() and thought I could conveniently do it this way w/o generating additional output.

Comment by Lorenzo Moneta [ 05/May/14 ]

I am sorry, but still I do not understand what do you mean by averaging the data along z.
Is your data actually 3-dimensional (you have 3 observables) or you have 4-dimensional data and you use the 4-th dimension as bin content in your TH3 ?
Maybe by knowing what exactly your data are, it is easier to see what would you like to do, and maybe I can understand if something is missing in ROOT that needs to be implemented.
I suspect you should have a TProfile3D and you would like to reduce its dimensionality to a TProfile2D by integrating one of the coordinate, i.e. combining all the average in that coordinate.
This operation make sense and I think it is not in ROOT and probably it could be implemented.

Best Regards


Comment by Lorenzo Moneta [ 06/May/14 ]

Thinking more about this I realised that projections of profiles do not work correctly.
One needs to re-implement TProfile2D::ProfileX(Y) and TProfile3D::Project3DProfile

You cannot project a TProfile2D in a TProfile or a TProfile3D in a TProfile2D.
Attached is an example showing the problem and the possible workaround
If it is this what you want to do, I will fix this issue

Comment by Lorenzo Moneta [ 06/May/14 ]

Example showing that projections of TProfile;s to TProfile do not work

Comment by Lorenzo Moneta [ 07/May/14 ]

TProfile3D::Project3DProfile and TProfile2D::ProfileX(Y) have been implemented to correctly project profiles histogram and committed in 5.34 and master branches

Comment by Patricia Liebing (Inactive) [ 12/May/14 ]

Thanks for fixing this, I think that when I use TProfileXD now I'll get what I want.

Generated at Tue Aug 11 06:30:50 CEST 2020 using Jira 8.3.4#803005-sha1:1f96e09b3c60279a408a2ae47be3c745f571388b.