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
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.
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.
*** Problem 1301 has been marked as a duplicate of this problem. ***
*** Problem 1294 has been marked as a duplicate of this problem. ***
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
This information will be added for sure. Thanks to point this out!
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.
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.
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...