Problem 1074 - GetPointOnSurface() returns non-uniform distribution for some classes
Summary: GetPointOnSurface() returns non-uniform distribution for some classes
Status: RESOLVED INVALID
Alias: None
Product: Geant4
Classification: Unclassified
Component: geometry/solids (show other problems)
Version: 9.1
Hardware: PC Linux
: P5 trivial
Assignee: Gabriele Cosmo
URL:
: 1294 1301 (view as problem list)
Depends on:
Blocks:
 
Reported: 2009-07-16 11:31 CEST by Cristovao
Modified: 2012-05-02 13:14 CEST (History)
4 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this problem.
Description Cristovao 2009-07-16 11:31:32 CEST
I noticed that the GetPointOnSurface method gives a non-uniform random distribution on the surfaces where polar coordinates are used for the generation of points.

These happens in the following classes: G4Tubs, G4Cons, G4Sphere, G4Torus.

The problem arises from generating a uniform distribution in r. Since the area element is proportional to r^2, the density of these random points will be higher for small r.
Eg. in G4Tubs.cc L1852:
rRand  = RandFlat::shoot(fRMin,fRMax);

This can be easily corrected by taking rRand to be the square root of a uniform distribution.

Thank you
Chris
Comment 1 Gabriele Cosmo 2009-07-29 15:26:51 CEST
Thanks for the remark. We'll see if we can do something about that.
It must be noticed however that the generation of random points in a uniform way is NOT the real purpose of GetPointOnSurface(); this cannot be guaranteed for all kind of solids. Moreover, performance is a requirement for the implementation of such function.
Comment 2 Michael Kelsey 2012-04-03 22:00:30 CEST
I disagree with some of this.  It is certainly true that generating truly uniform points for an arbitrary surface is difficult, and could be a substantial performance hit in general.  Trying to implement correct behaviour in general may not be worth the effort.

However, the bug reported here (and re-reported in #1294 and #1301) applies to simple analytic surfaces for which the correct uniform distribution is well-known.  Using the wrong distributionshould not be considered a "feature," it should be fixed, as documented in #1294.
Comment 3 Gabriele Cosmo 2012-04-04 09:43:54 CEST
*** Problem 1301 has been marked as a duplicate of this problem. ***
Comment 4 Gabriele Cosmo 2012-04-04 09:50:08 CEST
*** Problem 1294 has been marked as a duplicate of this problem. ***
Comment 5 Tobias Koettig 2012-04-04 10:43:35 CEST
However, I think it should be clearly pointed out in the Reference Manual that the generated points are not (or not guaranteed) to be uniformly distributed.

Cheers,

Tobias
Comment 6 Gabriele Cosmo 2012-04-04 10:49:01 CEST
This information will be added for sure. Thanks to point this out!
Comment 7 jasondet 2012-05-02 12:45:16 CEST
Please also perform an exhaustive search to remove all false claims of uniformity from the source code. For example, just above the clearly non-uniform implementation in G4BooleanSolid.cc we find:

> //////////////////////////////////////////////////////////////////////////
> //
> // Returns a point (G4ThreeVector) randomly and uniformly selected
> // on the solid surface
> //
> 
> G4ThreeVector G4BooleanSolid::GetPointOnSurface() const
> { ...

There are other places as well (e.g. G4ReflectedSolid.cc). It might help to actually insert comments pointing out when a generated distribution is not or may not be uniform. Another option would be to add a separate function like "GetUniformPointOnSurface()", which can be called by GetPointOnSurface() in cases where it is efficient.
Comment 8 Gabriele Cosmo 2012-05-02 12:51:57 CEST
We have recently added some modifications which will allow to have a better (but still not perfect!) distribution of random points. This will be available in the next release.
The text you refer is left-over from the original developer... but it is clearly wrong.
Thanks for pinging this out.
Comment 9 jasondet 2012-05-02 13:14:01 CEST
I wasn't aware of the modifications underway, but it is possible to get a perfectly uniform distribution for a generic G4VSolid by using its bounding radius and repeated calls to DistanceToIn/Out. My colleagues and I wrote a paper on it:

http://dx.doi.org/10.1109/TNS.2008.2001063

This could be implemented as

vector<G4ThreeVector> GetUniformPointsOnSurface()

and the user can use the entire set of returned points or select one as described in the paper to ensure not just uniformity but also non-correlation between successive points. Specific solids with a more efficient algorithm can overload this to just return a single point. Just a suggestion...