Opened 13 years ago

Closed 13 years ago

Last modified 13 years ago

#334 closed defect (fixed)

Implement general getFractionInside method and tests

Reported by: Kevin Milner Owned by: Kevin Milner
Priority: major Milestone: OpenSHA 1.3
Component: commons Version:
Keywords: Cc:

Description

Various snippets from e-mails below:


As for % of gridded surface in a region, we already compute this in several different places, so we should make a general utility for this. The code is:

public double getFractionInside(Region region, EvenlyGriddedSurface? surface) {

int numInside=0;
ListIterator?<Location> it = surface.getAllByRowsIterator();
while (it.hasNext())

if (region.contains(it.next()))

numInside+=1;

return (double) numInside / (double)(surface.getNumCols()*surface.getNumRows())

}

The questions is where to put this. It shouldn't go in commons because EvenlyGriddedSurface? doesn't exist there.

I guess we could put it in commons.geo.RegionUtils? if the method took the ListIterator?<Location> rather than an EvenlyGriddedSurface?.


I'm fine with it going as a static method in RegionUtils?, although I'd use the more general Iterator<Location>.

Alternatively, it could be added as an instance method to Region:

public double containsPct(Iterator<Location> locs) or
public double containsFraction(Iterator<Location> locs)

pp


Either of those sounds good to me. Although you could also do Iterable<Location> which would result in less code. Containter2D<E> already implements Iterable<E>, so EvenlyGriddedSurface? implements Iterable<Location>. Then you could also simply give that method an ArrayList? or any other collection that implements Iterable<Location>.

This would be the new code:

public double getFractionInside(Region region, Iterable<Location> locs) {

int numInside=0;
int cnt=0
for (Location loc : locs) {

if (region.contains(loc))

numInside++;

cnt++

}
return (double)numInside / (double)cnt;

}

So you could call it like this:
ArrayList?<Location> list = new ArrayList?<Location>
... add points
getFractionInside(region, list);
EvenlyGriddedSurface? surf = new EvenlyGriddedSurface?(...)
getFractionInside(region, surf);

Morgan would still have to create a StirlingGriddedSurface? though to use this method as she's starting with just FaultSystemPrefData?.

Change History (2)

comment:1 Changed 13 years ago by Kevin Milner

Resolution: fixed
Status: newclosed

Implemented in [8127]. I put it as a static method in RegionUtils?, but it could be easily moved to Region if you want. Here's the JavaDoc?:

double org.opensha.commons.geo.RegionUtils.getFractionInside(Region region, Iterable<Location> locs) throws NullPointerException, IllegalArgumentException

The returns the fraction of points in the given collection of locations that is inside the given region. This will commonly be used with the EvenlyGriddedSurface class to determine the fraction of a fault surface that is inside of a region.

Parameters:
region - the region for which to test
locs - any instance of Iterable, for example, ArrayList or EvenlyGriddedSurface.
Returns:
fraction of locations inside the given region
Throws:
NullPointerException - if region or locs is null
IllegalArgumentException - if locs is empty

Is it worth adding containsPct?

comment:2 Changed 13 years ago by Peter Powers

nope. Looks good. I may move it to be an instance method at some point if I do that same for the KML utilities. The latter come with a lot of baggage methods though so I'm leaving it for now.

Note: See TracTickets for help on using tickets.