Search in sources :

Example 1 with Cell

use of au.gov.amsa.geo.model.Cell in project risky by amsa-code.

the class DistanceTravelledCalculator method calculateDistanceByCellFromFiles.

/**
 * Returns distinct cells and the the total nautical miles travelled in that
 * cell. Uses RxJava {@link Observable}s to maximize throughput and will
 * scale to use all available processors and to handle a large number of
 * files (number of open file handles should be limited by number of
 * available processors).
 *
 * @param files
 * @return
 */
public Observable<CellAndDistance> calculateDistanceByCellFromFiles(Observable<File> files) {
    // use a map-reduce approach where the parallel method shares out
    // ('maps') the fixes by craft to multiple threads (number determined by
    // available processors) and is passed the 'reduce'
    // calculateDistanceByCellFromFile() method to combine the results.
    int numFiles = files.count().toBlocking().single();
    log.info("numFiles=" + numFiles);
    AtomicLong fileCount = new AtomicLong();
    AtomicLong cellCount = new AtomicLong(1);
    return files.buffer(Math.max(1, (int) Math.round(Math.ceil(numFiles / Runtime.getRuntime().availableProcessors())))).flatMap(fileList -> extractCellDistances(fileCount, cellCount, fileList)).collect(bigMapFactory(), collectCellDistances()).flatMap(listCellDistances()).doOnNext(sumNauticalMiles());
}
Also used : SegmentOptions(au.gov.amsa.geo.model.SegmentOptions) Logging(com.github.davidmoten.rx.slf4j.Logging) LoggerFactory(org.slf4j.LoggerFactory) Preconditions(com.github.davidmoten.guavamini.Preconditions) HashMap(java.util.HashMap) Action1(rx.functions.Action1) Action2(rx.functions.Action2) ArrayList(java.util.ArrayList) Observable(rx.Observable) GridTraversor(au.gov.amsa.geo.model.GridTraversor) Func0(rx.functions.Func0) Func1(rx.functions.Func1) BinaryFixes(au.gov.amsa.risky.format.BinaryFixes) Bounds(au.gov.amsa.geo.model.Bounds) Map(java.util.Map) Fix(au.gov.amsa.risky.format.Fix) Schedulers(rx.schedulers.Schedulers) Variable(ucar.nc2.Variable) Cell(au.gov.amsa.geo.model.Cell) ArrayDouble(ucar.ma2.ArrayDouble) PrintWriter(java.io.PrintWriter) Index2D(ucar.ma2.Index2D) Logger(org.slf4j.Logger) Subscriber(rx.Subscriber) HasPosition(au.gov.amsa.risky.format.HasPosition) DataType(ucar.ma2.DataType) IOException(java.io.IOException) Position(au.gov.amsa.util.navigation.Position) Observer(rx.Observer) Array(ucar.ma2.Array) File(java.io.File) FileNotFoundException(java.io.FileNotFoundException) CellValue(au.gov.amsa.geo.model.CellValue) AtomicLong(java.util.concurrent.atomic.AtomicLong) List(java.util.List) InvalidRangeException(ucar.ma2.InvalidRangeException) Attribute(ucar.nc2.Attribute) Util(au.gov.amsa.geo.model.Util) OnSubscribe(rx.Observable.OnSubscribe) Entry(java.util.Map.Entry) Optional(java.util.Optional) Dimension(ucar.nc2.Dimension) NetcdfFileWriter(ucar.nc2.NetcdfFileWriter) VisibleForTesting(com.google.common.annotations.VisibleForTesting) Comparator(java.util.Comparator) Options(au.gov.amsa.geo.model.Options) AtomicLong(java.util.concurrent.atomic.AtomicLong)

Example 2 with Cell

use of au.gov.amsa.geo.model.Cell in project risky by amsa-code.

the class DistanceTravelledCalculator method saveCalculationResultAsNetcdf.

public static void saveCalculationResultAsNetcdf(Options options, CalculationResult calculationResult, String filename) {
    List<CellValue> list = calculationResult.getCells().toList().toBlocking().single();
    int maxLonIndex = list.stream().map(cell -> options.getGrid().cellAt(cell.getCentreLat(), cell.getCentreLon())).filter(// 
    x -> x.isPresent()).map(x -> x.get().getLonIndex()).max(// 
    Comparator.<Long>naturalOrder()).get().intValue();
    int maxLatIndex = list.stream().map(cell -> options.getGrid().cellAt(cell.getCentreLat(), cell.getCentreLon())).filter(x -> x.isPresent()).map(x -> x.get().getLatIndex()).max(Comparator.<Long>naturalOrder()).get().intValue();
    File file = new File(filename);
    // Create the file.
    NetcdfFileWriter f = null;
    try {
        // Create new netcdf-3 file with the given filename
        f = NetcdfFileWriter.createNew(NetcdfFileWriter.Version.netcdf3, file.getPath());
        // In addition to the latitude and longitude dimensions, we will
        // also create latitude and longitude netCDF variables which will
        // hold the actual latitudes and longitudes. Since they hold data
        // about the coordinate system, the netCDF term for these is:
        // "coordinate variables."
        Dimension dimLat = f.addDimension(null, "latitude", maxLatIndex + 1);
        Dimension dimLon = f.addDimension(null, "longitude", maxLonIndex + 1);
        List<Dimension> dims = new ArrayList<Dimension>();
        dims.add(dimLat);
        dims.add(dimLon);
        // coordinate variables
        Variable vLat = f.addVariable(null, "latitude", DataType.DOUBLE, "latitude");
        Variable vLon = f.addVariable(null, "longitude", DataType.DOUBLE, "longitude");
        // value variables
        Variable vDensity = f.addVariable(null, "traffic_density", DataType.DOUBLE, dims);
        // Define units attributes for coordinate vars. This attaches a
        // text attribute to each of the coordinate variables, containing
        // the units.
        vLon.addAttribute(new Attribute("units", "degrees_east"));
        vLat.addAttribute(new Attribute("units", "degrees_north"));
        // Define units attributes for variables.
        vDensity.addAttribute(new Attribute("units", "nm-1"));
        vDensity.addAttribute(new Attribute("long_name", ""));
        // Write the coordinate variable data. This will put the latitudes
        // and longitudes of our data grid into the netCDF file.
        f.create();
        {
            Array dataLat = Array.factory(DataType.DOUBLE, new int[] { dimLat.getLength() });
            Array dataLon = Array.factory(DataType.DOUBLE, new int[] { dimLon.getLength() });
            // set latitudes
            for (int i = 0; i <= maxLatIndex; i++) {
                dataLat.setDouble(i, options.getGrid().centreLat(i));
            }
            // set longitudes
            for (int i = 0; i <= maxLonIndex; i++) {
                dataLon.setDouble(i, options.getGrid().centreLon(i));
            }
            f.write(vLat, dataLat);
            f.write(vLon, dataLon);
        }
        // write the value variable data
        {
            int[] iDim = new int[] { dimLat.getLength(), dimLon.getLength() };
            Array dataDensity = ArrayDouble.D2.factory(DataType.DOUBLE, iDim);
            Index2D idx = new Index2D(iDim);
            for (CellValue point : list) {
                Optional<Cell> cell = options.getGrid().cellAt(point.getCentreLat(), point.getCentreLon());
                if (cell.isPresent()) {
                    idx.set((int) cell.get().getLatIndex(), (int) cell.get().getLonIndex());
                    dataDensity.setDouble(idx, point.getValue());
                }
            }
            f.write(vDensity, dataDensity);
        }
    } catch (IOException | InvalidRangeException e) {
        throw new RuntimeException(e);
    } finally {
        if (f != null) {
            try {
                f.close();
            } catch (IOException ioe) {
                throw new RuntimeException(ioe);
            }
        }
    }
}
Also used : SegmentOptions(au.gov.amsa.geo.model.SegmentOptions) Logging(com.github.davidmoten.rx.slf4j.Logging) LoggerFactory(org.slf4j.LoggerFactory) Preconditions(com.github.davidmoten.guavamini.Preconditions) HashMap(java.util.HashMap) Action1(rx.functions.Action1) Action2(rx.functions.Action2) ArrayList(java.util.ArrayList) Observable(rx.Observable) GridTraversor(au.gov.amsa.geo.model.GridTraversor) Func0(rx.functions.Func0) Func1(rx.functions.Func1) BinaryFixes(au.gov.amsa.risky.format.BinaryFixes) Bounds(au.gov.amsa.geo.model.Bounds) Map(java.util.Map) Fix(au.gov.amsa.risky.format.Fix) Schedulers(rx.schedulers.Schedulers) Variable(ucar.nc2.Variable) Cell(au.gov.amsa.geo.model.Cell) ArrayDouble(ucar.ma2.ArrayDouble) PrintWriter(java.io.PrintWriter) Index2D(ucar.ma2.Index2D) Logger(org.slf4j.Logger) Subscriber(rx.Subscriber) HasPosition(au.gov.amsa.risky.format.HasPosition) DataType(ucar.ma2.DataType) IOException(java.io.IOException) Position(au.gov.amsa.util.navigation.Position) Observer(rx.Observer) Array(ucar.ma2.Array) File(java.io.File) FileNotFoundException(java.io.FileNotFoundException) CellValue(au.gov.amsa.geo.model.CellValue) AtomicLong(java.util.concurrent.atomic.AtomicLong) List(java.util.List) InvalidRangeException(ucar.ma2.InvalidRangeException) Attribute(ucar.nc2.Attribute) Util(au.gov.amsa.geo.model.Util) OnSubscribe(rx.Observable.OnSubscribe) Entry(java.util.Map.Entry) Optional(java.util.Optional) Dimension(ucar.nc2.Dimension) NetcdfFileWriter(ucar.nc2.NetcdfFileWriter) VisibleForTesting(com.google.common.annotations.VisibleForTesting) Comparator(java.util.Comparator) Options(au.gov.amsa.geo.model.Options) Variable(ucar.nc2.Variable) Optional(java.util.Optional) Attribute(ucar.nc2.Attribute) InvalidRangeException(ucar.ma2.InvalidRangeException) ArrayList(java.util.ArrayList) Index2D(ucar.ma2.Index2D) Dimension(ucar.nc2.Dimension) IOException(java.io.IOException) NetcdfFileWriter(ucar.nc2.NetcdfFileWriter) Array(ucar.ma2.Array) CellValue(au.gov.amsa.geo.model.CellValue) File(java.io.File)

Example 3 with Cell

use of au.gov.amsa.geo.model.Cell in project risky by amsa-code.

the class OperatorSumCellDistances method call.

@Override
public Subscriber<? super CellAndDistance> call(final Subscriber<? super Map<Cell, Double>> child) {
    Subscriber<CellAndDistance> parent = new Subscriber<CellAndDistance>(child) {

        @Override
        public void onCompleted() {
            try {
                child.onNext(Collections.unmodifiableMap(map));
                child.onCompleted();
            } catch (Throwable t) {
                onError(t);
            }
        }

        @Override
        public void onError(Throwable e) {
            child.onError(e);
        }

        @Override
        public void onNext(CellAndDistance cd) {
            Cell key = cd.getCell();
            Double val = map.putIfAbsent(key, cd.getDistanceNm());
            if (val != null) {
                map.put(key, val + cd.getDistanceNm());
                request(1);
            } else {
                if (map.size() == maxSize) {
                    Map<Cell, Double> m = map;
                    map = createMap();
                    child.onNext(Collections.unmodifiableMap(m));
                } else
                    request(1);
            }
        }
    };
    return parent;
}
Also used : Subscriber(rx.Subscriber) Cell(au.gov.amsa.geo.model.Cell)

Aggregations

Cell (au.gov.amsa.geo.model.Cell)3 Subscriber (rx.Subscriber)3 Bounds (au.gov.amsa.geo.model.Bounds)2 CellValue (au.gov.amsa.geo.model.CellValue)2 GridTraversor (au.gov.amsa.geo.model.GridTraversor)2 Options (au.gov.amsa.geo.model.Options)2 SegmentOptions (au.gov.amsa.geo.model.SegmentOptions)2 Util (au.gov.amsa.geo.model.Util)2 BinaryFixes (au.gov.amsa.risky.format.BinaryFixes)2 Fix (au.gov.amsa.risky.format.Fix)2 HasPosition (au.gov.amsa.risky.format.HasPosition)2 Position (au.gov.amsa.util.navigation.Position)2 Preconditions (com.github.davidmoten.guavamini.Preconditions)2 Logging (com.github.davidmoten.rx.slf4j.Logging)2 VisibleForTesting (com.google.common.annotations.VisibleForTesting)2 File (java.io.File)2 FileNotFoundException (java.io.FileNotFoundException)2 IOException (java.io.IOException)2 PrintWriter (java.io.PrintWriter)2 ArrayList (java.util.ArrayList)2